Compare commits

..
126 Commits
Author SHA1 Message Date
karajorma f475ae983e Sync with Trunk (Part IV) 2010-09-20 08:21:41 +00:00
karajorma 3be57f609e Sync with Trunk (Part III) 2010-09-20 08:06:39 +00:00
karajorma fc66e2f78b Sync with Trunk (Part II) - I knew I'd miss something. 2010-09-20 07:17:50 +00:00
karajorma 1afadaa142 Sync with Trunk (Part I) 2010-09-20 05:49:34 +00:00
karajorma 1583b74c9d Missed that somehow. 2010-03-04 09:53:05 +00:00
karajorma e8ba07ee43 Sync with trunk 2010-03-02 05:25:56 +00:00
karajorma 7f706d398f Revert the Toggle Behaviour When Crippled flag as it's not good enough really. I'll add a better solution later. 2010-03-01 14:57:43 +00:00
karajorma 7b50be4afb Sync with trunk 2010-02-24 03:27:01 +00:00
karajorma f690e124d0 These should have been removed. 2010-02-23 13:50:27 +00:00
karajorma df6e87f552 As promised, a much better fix for the issue of ships losing orders/getting protected as soon as something has disarm/disable orders. 2010-02-23 13:49:15 +00:00
karajorma 45305bf78f Sync with trunk 2010-02-19 04:44:25 +00:00
karajorma e6f640c53d Sync with trunk 2009-11-02 07:12:36 +00:00
karajorma 4f1d39ed0e Sync with trunk 2009-07-19 09:42:46 +00:00
karajorma a7570926c9 Some minor changes which appear to have slipped into one codebase but not the other. 2009-07-18 17:48:22 +00:00
karajorma aa481d7463 Sync with trunk 2009-07-18 17:26:06 +00:00
karajorma e79afa5b65 Fix a couple of typos other people made. One minor, one not so minor. 2009-07-15 21:50:23 +00:00
karajorma b69a80db90 Sync with trunk 2009-07-15 21:29:08 +00:00
karajorma 5f64b680f5 Sync with trunk 2009-07-10 17:20:11 +00:00
karajorma a3508be54a Sync with the right branch this time! 2009-07-05 20:55:42 +00:00
karajorma 0fede5f475 Revert last sync 2009-07-05 20:47:25 +00:00
karajorma a8c36b9654 Sync with trunk 2009-07-05 20:30:57 +00:00
karajorma 8c98287b39 Sync with trunk 2009-07-02 17:21:49 +00:00
karajorma 345fa9c3ac Sync with trunk again 2009-06-30 22:09:08 +00:00
karajorma cf483e0237 Sync with trunk 2009-06-30 07:20:30 +00:00
karajorma f40710f500 Mark Selected Ships via information in FRED too as this is more likely to still be used rather than the slow wireframe marking. 2009-06-27 12:34:25 +00:00
karajorma 9f162d813f Sync with trunk 2009-06-22 20:17:00 +00:00
karajorma 3edee14eea Sync with trunk 2009-06-14 16:09:49 +00:00
karajorma 82757763e6 Sync with trunk 2009-06-06 10:51:02 +00:00
karajorma 91346a814d Sync with trunk 2009-05-24 22:01:10 +00:00
karajorma 5f013ad41d Allow lua to send variable changes from client to server. 2009-05-24 15:42:19 +00:00
karajorma 00cd5490c4 Sync with trunk 2009-05-21 14:59:36 +00:00
karajorma a4542cf71b Fix a newline issue with skybox flags. 2009-05-21 14:02:40 +00:00
karajorma f4521da771 Sync with trunk 2009-05-21 13:50:06 +00:00
karajorma 6ba0f3622a Fix Mantis 1926 (Piranha submunitions home in on the ship that fired them in dogfight mode) 2009-05-18 21:41:20 +00:00
karajorma e3765e24e1 Sync with trunk 2009-05-17 12:08:06 +00:00
karajorma 7171bf1005 Sync with trunk 2009-05-16 12:36:06 +00:00
karajorma b85ee3217d A couple of minor corrections. 2009-05-15 20:31:01 +00:00
karajorma 12f137c645 Version Bump 2009-05-10 09:54:14 +00:00
karajorma f0eb798f7e Add the High Praise and Primaries Low builtin message types 2009-05-09 18:37:18 +00:00
karajorma 5c60351288 Sync with Trunk 2009-05-09 17:40:14 +00:00
karajorma 5895aca2c5 Warning level bump 2009-05-09 09:34:05 +00:00
karajorma cfd2469f8b Fix some minor warnings 2009-05-09 09:30:34 +00:00
karajorma 0094a5dba4 Sync with trunk 2009-05-08 17:19:10 +00:00
karajorma 94e84fc9b8 Switch a couple of Asserts to Assertions. 2009-05-08 17:18:46 +00:00
karajorma 35ad2c5cdc Add support for multiple builtins of the same type. 2009-05-08 17:17:40 +00:00
karajorma af7e0a700b Add support for new builtin message types 2009-05-08 17:08:01 +00:00
karajorma 8943449825 Switch network variables over to the SEXP packet except for when called from lua 2009-05-08 17:05:43 +00:00
karajorma 555488e0bb Add the Assertion Macro as an alternative to Assert. 2009-05-05 10:09:15 +00:00
karajorma c6cf9da861 Add the set-ambient-light SEXP 2009-05-05 10:07:00 +00:00
karajorma f11e9253b2 Allow multi-docking in multiplayer. 2009-05-04 12:19:34 +00:00
karajorma fac68e4838 Maybe fix a crash with voice recognition. 2009-05-01 17:01:29 +00:00
karajorma 17d8105c38 Fix an issue with calling up the options menu while waiting for popupdead to appear. 2009-05-01 09:54:26 +00:00
karajorma a31eed376c This one too. 2009-04-30 11:22:01 +00:00
karajorma e8abd881d2 Forgot to commit that. 2009-04-30 10:43:57 +00:00
karajorma 136b5c936d Add a ship and parse flag to lock all turrets initially. Fix the Lock Primary/Secondary checkboxes to work for multi-selection. Add a checkbox for lock afterburner. 2009-04-28 13:13:47 +00:00
karajorma 34855d000e Break up the status SEXPs into sub-categories. 2009-04-26 22:13:03 +00:00
karajorma b6eed01e41 Auto-expand branches after pasting, add-pasting or replacing SEXPs. I really don't know why someone didn't get rid of that petty annoyance years ago. 2009-04-26 21:56:59 +00:00
karajorma 9616fb4cd7 Fix an assertion that crops up when you have no selected message but click on delete message. Has the side effect of making the message editor much less annoying too. 2009-04-26 21:51:53 +00:00
karajorma 344d8ba217 Fix a bug where the order of SEXP arguments was reversed. 2009-04-25 18:21:28 +00:00
karajorma 7e5239aff0 An ounce of prevention with the multiplayer SEXP packet code. 2009-04-24 21:56:09 +00:00
karajorma 09d5225883 Fix Mantis 1371 (Can target target's target even if it is stealthed or hidden from sensors). 2009-04-24 21:54:12 +00:00
karajorma 7f3ba14cec Fix Mantis 1538 (special hitpoints not updated properly on deletion) 2009-04-24 21:17:10 +00:00
karajorma 850414b358 Fix Mantis 1909 (Can't paste variables in FRED) 2009-04-24 19:58:29 +00:00
karajorma f18fa672f2 Fix (part of) Mantis 1677 (cap-subsys-cargo-known-delay doesn't list the correct ships) 2009-04-24 16:43:09 +00:00
karajorma fcb62348b9 Fix Mantis 1813 (Negative number constants could be added in FRED for SEXPs which expected OPF_POSITIVE, often resulting in crashes). 2009-04-24 15:54:44 +00:00
karajorma fbbb31bc49 Previous fix makes this code unnecessary so it might as well be removed. 2009-04-24 13:08:29 +00:00
karajorma 4d0e574ba4 Fix Mantis 1911 (Add Data doesn't show the <argument> option) 2009-04-24 13:05:24 +00:00
karajorma ce5b56fdf7 Don't need to set that flag. 2009-04-24 10:33:17 +00:00
karajorma 04de7f7498 Fix Mantis 1913 (Characters after # are visible in the wings and reinforcements comms menu) 2009-04-23 18:46:29 +00:00
karajorma 46b2165312 Sync with trunk 2009-04-23 18:43:02 +00:00
karajorma 4182951b19 Fix Mantis 1884 (Entering the name of an invalid operator in any dialog other than events editor would crash FRED)
Fix a typo in disable-builtin-messages
2009-04-22 20:39:32 +00:00
karajorma cbd6f247d9 Fix Mantis 1916 (Can't change the dockpoint a ship is initial docked to without undocking it) 2009-04-21 18:00:03 +00:00
karajorma 73facc313e Fix Mantis 1907 (Error in the get-damage-caused description) 2009-04-21 08:18:02 +00:00
karajorma d2e3094544 Add SEXPs to set weapon, shield and afterburner energy. 2009-04-15 19:34:12 +00:00
karajorma 61512d5b8f First commit of the SEXP packet code. 2009-04-15 19:32:56 +00:00
karajorma 2b42038c09 Fix Mantis 1910 (Assist Percentage resets itself when ships are multi selected) 2009-04-09 14:36:48 +00:00
karajorma ad8f6ccda3 Some minor changes to the way the game uses the scoring features I added earlier. 2009-04-08 15:56:22 +00:00
karajorma a201c9b3f3 Move the repair penalty to an AI profile setting. 2009-04-05 16:55:08 +00:00
karajorma 7edde650a1 Add the validate-argument SEXP.
Fix a minor initialisation error with the ship-tag SEXP.
2009-04-05 16:48:07 +00:00
karajorma ae3b88f23b Sync with trunk 2009-04-02 17:37:42 +00:00
karajorma c86e58e5e8 Fix Mantis 1883 (spaces at the end of ship and wing names can cause errors) 2009-04-02 17:33:29 +00:00
karajorma f441432d57 Fix a bug which was causing FRED to choke on the ; and " replacement fix. 2009-04-02 17:30:10 +00:00
karajorma 417982862e Fix an issue with homing capship missiles not tracking correctly. 2009-04-01 11:17:48 +00:00
karajorma 158733df8f Apparently even the null terminator needs to be coloured. 2009-03-31 18:38:13 +00:00
karajorma 4b75870857 Sync with trunk 2009-03-29 21:31:50 +00:00
karajorma dbfe86f018 Allow wireframe for the targetbox to be set from hud_gauges.tbl. 2009-03-29 21:03:24 +00:00
karajorma f7d95acec8 Fix Mantis 1753 (Using " or ; in briefings and messages causes them to either vanish or truncate the message)
Fix a bug that prevented lcl_replace_stuff() working properly when a message had two or more replacements of the same type.
2009-03-29 17:56:32 +00:00
karajorma 506686cfb7 Fix Mantis 1859 (FRED crashes if an unknown ship type is detected in the loadout.) 2009-03-29 12:39:01 +00:00
karajorma 8415a591e1 Allow the boilerplate traitor debrief to be turned off even if the player did turn traitor. 2009-03-24 15:22:57 +00:00
karajorma 1f8644f059 Fix Mantis 1620 (Replace Number/String don't work in FRED) 2009-03-21 21:48:20 +00:00
karajorma f32f947b62 Sync with trunk 2009-03-20 14:01:12 +00:00
karajorma 99ce717f7e Allow beams on any player ship to count for kills. Not just fighters and bombers. 2009-03-20 13:49:14 +00:00
karajorma 28f32a2f6d Fix the FictionViewer truncating anything with more than 70 lines. 2009-03-17 18:01:59 +00:00
karajorma 3d5d730306 Sync with trunk. 2009-03-05 22:19:24 +00:00
karajorma 96426de56f Fix Mantis 1661 (Ships leaving via the fighter bay don't disappear on multiplayer clients). 2009-03-05 22:12:34 +00:00
karajorma b14b5e3622 Fix multiplayer for Inferno builds. 2009-03-02 09:28:08 +00:00
karajorma 35cd6ea336 Various fixes needed to allow multiplayer to use over 255 weapons. 2009-02-27 20:04:44 +00:00
karajorma 3332870e9e Bobboau's Skybox flags code (via Wanderer then me) 2009-02-27 11:53:20 +00:00
karajorma 944c4bb2f2 Add new sexps to determine the amount of afterburner and weapon energy remaining. Add a missing resource file. 2009-02-26 13:17:00 +00:00
karajorma 705faf4a78 Sync up project files with Trunk 2009-02-25 20:02:18 +00:00
karajorma 614eda3b08 Sync with Trunk 2009-02-25 19:56:10 +00:00
karajorma 593cf6a533 Sync with trunk 2009-02-14 23:38:11 +00:00
karajorma 17ddae5db4 Fix Mantis 1486 (Pressing F4 locks multiplayer). Since this fix breaks compatibility I'll save up a few similar breaks and commit them all to trunk at the same time. 2009-02-14 21:47:53 +00:00
karajorma d1b1eb65b6 Add Wanderer's Salvo Mode. Sync the 2008 project files up with Trunk. 2009-01-27 20:25:00 +00:00
karajorma 43ee74a2e0 Patch in Wanderer's subsystem flag 2009-01-13 17:43:09 +00:00
karajorma 20d33ac699 Sync with trunk 2009-01-09 18:29:01 +00:00
karajorma 1609e9211f Sync with Trunk 2008-12-15 19:08:07 +00:00
karajorma c8c05e9d0b Add support for cutscenes before the various briefing and debriefing sections (FRED support for this feature will come later.) 2008-12-15 18:43:43 +00:00
karajorma 35130122e4 Sync up with trunk 2008-12-14 18:44:06 +00:00
karajorma c1b549867a Sync with Trunk. 2008-11-17 18:27:02 +00:00
karajorma efea823ef1 Fix a bug where the log displays incorrect percentages for kills. 2008-11-17 15:12:41 +00:00
karajorma 91e375693c Sync with Trunk. 2008-10-15 19:28:40 +00:00
karajorma 022aa38ad1 KeldorKatarn's afterburner lock SEXPs 2008-09-12 21:54:57 +00:00
karajorma 40419fb891 Allow players to filter who they send messages to when using the chatbox 2008-09-10 17:36:09 +00:00
karajorma 25d4a3b439 Update branch to latest SVN 2008-09-10 15:10:32 +00:00
karajorma 968e8d3d66 Sync with trunk 2008-08-20 20:58:15 +00:00
karajorma 6610938b80 Sync with trunk 2008-08-04 19:18:47 +00:00
karajorma 4b2691f572 Might as well update the project files too 2008-07-25 17:43:21 +00:00
karajorma 0ac2532fe5 Metge branch with trunk 2008-07-25 17:40:17 +00:00
karajorma e42892cb90 Change the project file to add the new alt classes file. 2008-06-17 19:39:02 +00:00
karajorma 0d14a559eb FRED changes for team loadout. 2008-06-17 19:36:16 +00:00
karajorma 2a65fcb388 Commit the actual team loadout code. 2008-06-17 19:20:34 +00:00
karajorma a02b9d953a Get-Damage-Caused SEXP and a couple of functions for counting the number of variables of a certain type. 2008-06-17 19:17:55 +00:00
karajorma 53f8c36587 Changes to allow more data to be used from exited_ship. Make ship_exited dynamic too. 2008-06-17 19:10:28 +00:00
karajorma 8323f5b4ad A couple of new parsing functions for dealing with variables in fields that previously only accepted integers or strings. 2008-06-17 18:49:11 +00:00
Goober5000 6ef349a6d4 made a copy 2008-06-17 02:52:56 +00:00
124 changed files with 26570 additions and 10218 deletions

No files matched your search

-175
View File
@@ -712,178 +712,3 @@ int main ()
AC_SUBST(THEORA_LIBS)
rm -f conf.theoratest
])
dnl AM_PATH_OPENAL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
dnl Test for OpenAL, and define OPENAL_CFLAGS and OPENAL_LIBS
dnl
AC_DEFUN([AM_PATH_OPENAL],
[dnl
dnl Get the cflags and libraries
dnl
AC_ARG_WITH(openal,[ --with-openal=PFX Prefix where OpenAL is installed (optional)], openal_prefix="$withval", openal_prefix="")
AC_ARG_WITH(openal-libraries,[ --with-openal-libraries=DIR Directory where OpenAL library is installed (optional)], openal_libraries="$withval", openal_libraries="")
AC_ARG_WITH(openal-includes,[ --with-openal-includes=DIR Directory where OpenAL header files are installed (optional)], openal_includes="$withval", openal_includes="")
AC_ARG_ENABLE(openaltest, [ --disable-openaltest Do not try to compile and run a test OpenAL program],, enable_openaltest=yes)
if test "x$openal_libraries" != "x" ; then
OPENAL_LIBS="-L$openal_libraries"
elif test "x$openal_prefix" != "x" ; then
OPENAL_LIBS="-L$openal_prefix/lib"
elif test "x$prefix" != "xNONE"; then
OPENAL_LIBS="-L$libdir"
fi
OPENAL_LIBS="$OPENAL_LIBS -lopenal"
if test "x$openal_includes" != "x" ; then
OPENAL_CFLAGS="-I$openal_includes"
elif test "x$openal_prefix" != "x" ; then
OPENAL_CFLAGS="-I$openal_prefix/include"
elif test "x$prefix" != "xNONE"; then
OPENAL_CFLAGS=""
fi
AC_MSG_CHECKING(for OpenAL)
no_openal=""
if test "x$enable_openaltest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $OPENAL_CFLAGS"
LIBS="$LIBS $OPENAL_LIBS"
dnl
dnl Now check if the installed OpenAL is sufficiently new.
dnl
rm -f conf.openaltest
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <AL/al.h>
#include <AL/alc.h>
int main ()
{
#ifdef AL_VERSION_1_1
alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT");
system("touch conf.openaltest");
return 0;
#else
printf("\n*** OpenAL version 1.1 or greater is required.\n");
return 1;
#endif
}
],, no_openal=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
if test "x$no_openal" = "x" ; then
AC_MSG_RESULT(yes)
ifelse([$1], , :, [$1])
else
AC_MSG_RESULT(no)
if test -f conf.openaltest ; then
:
else
echo "*** Could not run OpenAL test program, checking why..."
CFLAGS="$CFLAGS $OPENAL_CFLAGS"
LIBS="$LIBS $OPENAL_LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include <AL/al.h>
], [ return 0; ],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding OpenAL or finding the wrong"
echo "*** version of OpenAL. If it is not finding OpenAL, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means OpenAL was incorrectly installed"
echo "*** or that you have moved OpenAL since it was installed." ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
OPENAL_CFLAGS=""
OPENAL_LIBS=""
ifelse([$2], , :, [$2])
fi
AC_SUBST(OPENAL_CFLAGS)
AC_SUBST(OPENAL_LIBS)
rm -f conf.openaltest
])
dnl AM_PATH_OPENGL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
dnl Test for OpenGL, and define OPENGL_CFLAGS and OPENGL_LIBS
dnl
AC_DEFUN([AM_PATH_OPENGL],
[dnl
dnl Get the cflags and libraries
dnl
AC_ARG_WITH(opengl,[ --with-opengl=PFX Prefix where OpenGL is installed (optional)], opengl_prefix="$withval", opengl_prefix="")
AC_ARG_WITH(opengl-libraries,[ --with-opengl-libraries=DIR Directory where OpenGL library is installed (optional)], opengl_libraries="$withval", opengl_libraries="")
AC_ARG_WITH(opengl-includes,[ --with-opengl-includes=DIR Directory where OpenGL header files are installed (optional)], opengl_includes="$withval", opengl_includes="")
AC_ARG_ENABLE(opengltest, [ --disable-opengltest Do not try to compile and run a test OpenGL program],, enable_opengltest=yes)
if test "x$opengl_libraries" != "x" ; then
OPENGL_LIBS="-L$opengl_libraries"
elif test "x$opengl_prefix" != "x" ; then
OPENGL_LIBS="-L$opengl_prefix/lib"
elif test "x$prefix" != "xNONE"; then
OPENGL_LIBS="-L$libdir"
fi
OPENGL_LIBS="$OPENGL_LIBS -lGL -lGLU"
if test "x$opengl_includes" != "x" ; then
OPENGL_CFLAGS="-I$opengl_includes"
elif test "x$opengl_prefix" != "x" ; then
OPENGL_CFLAGS="-I$opengl_prefix/include"
elif test "x$prefix" != "xNONE"; then
OPENGL_CFLAGS=""
fi
no_opengl=""
if test "x$enable_opengltest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $OPENGL_CFLAGS"
LIBS="$LIBS $OPENGL_LIBS"
AC_CHECK_LIB(GL, glPushMatrix,
[AC_CHECK_HEADER(GL/gl.h,
[AC_CHECK_LIB(GLU, gluPerspective,
[AC_CHECK_HEADER(GL/glu.h, ,
dnl NOTE: this is a failure
no_opengl=yes
)]
)]
)]
)
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
if test "x$no_opengl" = "x" ; then
ifelse([$1], , :, [$1])
else
OPENGL_CFLAGS=""
OPENGL_LIBS=""
ifelse([$2], , :, [$2])
fi
AC_SUBST(OPENGL_CFLAGS)
AC_SUBST(OPENGL_LIBS)
])
+1 -1
View File
@@ -88,7 +88,7 @@ char *ai_get_goal_ship_name(char *name, int *index)
}
Assert(Total_goal_ship_names < MAX_GOAL_SHIP_NAMES);
Assert(strlen(name) < NAME_LENGTH - 1);
Assertion(strlen(name) < NAME_LENGTH - 1, "Ship name %s is too long. Needs to be 31 characters or less.", name);
i = Total_goal_ship_names++;
strcpy_s(Goal_ship_names[i], name);
*index = i;
+6
View File
@@ -21,6 +21,7 @@
struct ship_weapon;
struct ship_subsys;
struct object;
struct ship_info;
#define AI_DEFAULT_CLASS 3 // default AI class for new ships (Fred)
@@ -639,6 +640,7 @@ extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, i
extern void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int dockee_index );
extern void ai_add_rearm_goal( object *requester_objp, object *support_objp );
extern void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_path=0);
extern int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 );
// Goober5000
extern void ai_do_safety(object *objp);
@@ -701,4 +703,8 @@ void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t
//SUSHI: Updating AI aim
void ai_update_aim(ai_info *aip, object* En_Objp);
//SUSHI: Random evasive sidethrust
void do_random_sidethrust(ai_info *aip, ship_info *sip);
#endif
+3 -1
View File
@@ -49,7 +49,6 @@ void set_flag(ai_profile_t *profile, char *name, int flag, int type)
void parse_ai_profiles_tbl(char *filename)
{
int i, rval;
bool no_create = false;
char profile_name[NAME_LENGTH];
ai_profile_t dummy_profile;
char *saved_Mp = NULL;
@@ -84,6 +83,7 @@ void parse_ai_profiles_tbl(char *filename)
{
ai_profile_t *profile = &dummy_profile;
ai_profile_t *previous_profile = NULL;
bool no_create = false;
// get the name
required_string("$Profile Name:");
@@ -393,6 +393,8 @@ void parse_ai_profiles_tbl(char *filename)
set_flag(profile, "$perform less checks for death screams:", AIPF2_PERFORM_LESS_SCREAM_CHECKS, AIP_FLAG2);
set_flag(profile, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
// if we've been through once already and are at the same place, force a move
if ( saved_Mp && (saved_Mp == Mp) )
Mp++;
+1
View File
@@ -54,6 +54,7 @@
#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0)
#define AIPF2_NO_SPECIAL_PLAYER_AVOID (1 << 1)
#define AIPF2_PERFORM_LESS_SCREAM_CHECKS (1 << 2)
#define AIPF2_ALL_SHIPS_MANAGE_SHIELDS (1 << 3)
#define MAX_AI_PROFILES 5
+15 -1
View File
@@ -694,7 +694,7 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
ship_weapon *tswp = &temp_shipp->weapons;
if ( tswp->num_primary_banks > 0 ) {
Assert(tswp->current_primary_bank < tswp->num_primary_banks);
Assertion(tswp->current_primary_bank < tswp->num_primary_banks, "AI tried to select primary bank %d. Might be a model error\n", tswp->current_primary_bank);
weapon_info *wip = &Weapon_info[tswp->primary_bank_weapons[tswp->current_primary_bank]];
if (dist_to_enemy < MIN((wip->max_speed * wip->lifetime), wip->weapon_range)){
@@ -1640,6 +1640,20 @@ void ai_big_strafe()
Int3(); // Illegal submode for AIM_STRAFE
break;
}
//Maybe apply random sidethrust, depending on the current submode
//The following are valid targets for random sidethrust (circle strafe uses it too, but that is handled separately)
if (aip->submode == AIS_STRAFE_ATTACK ||
aip->submode == AIS_STRAFE_AVOID ||
aip->submode == AIS_STRAFE_RETREAT1 ||
aip->submode == AIS_STRAFE_RETREAT2 ||
aip->submode == AIS_STRAFE_POSITION)
{
//Re-roll for random sidethrust every 2 seconds
if (static_randf((Missiontime + static_rand(aip->shipnum)) >> 17) < aip->ai_random_sidethrust_percent) {
do_random_sidethrust(aip, &Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index]);
}
}
}
// See if Pl_objp should enter strafe mode (This is called from maybe_evade_dumbfire_weapon(), and the
+196 -422
View File
@@ -304,6 +304,9 @@ typedef struct {
// Move to a position relative to a dock bay using thrusters.
float dock_orient_and_approach(object *docker_objp, int docker_index, object *dockee_objp, int dockee_index, int dock_mode, rotating_dockpoint_info *rdinfo = NULL);
// The object that is declared to be the leader of the group formation for
// the "autopilot"
object *Autopilot_flight_leader = NULL;
// ai_set_rearm_status takes a team (friendly, hostile, neutral) and a time. This function
// sets the timestamp used to tell is it is a good time for this team to rearm. Once the timestamp
@@ -766,6 +769,8 @@ void parse_ai_class()
set_aic_flag(aicp, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG);
set_aic_flag(aicp, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
set_aic_flag(aicp, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
}
void reset_ai_class_names()
@@ -1311,40 +1316,6 @@ if (!((objp->type == OBJ_WEAPON) && (Weapon_info[Weapons[objp->instance].weapon_
// If new target (objnum) is different than old target, reset target_time.
int set_target_objnum(ai_info *aip, int objnum)
{
/*
char old_name[32], new_name[32];
if (!timestamp_elapsed(aip->ok_to_target_timestamp))
return aip->target_objnum;
if (Player_ship && (Ships[aip->shipnum].team == Player_ship->team)) {
if (aip->target_objnum == -1)
strcpy_s(old_name, "none");
else
strcpy_s(old_name, Ships[Objects[aip->target_objnum].instance].ship_name);
if (objnum == -1)
strcpy_s(new_name, "none");
else
strcpy_s(new_name, Ships[Objects[objnum].instance].ship_name);
nprintf(("AI", "Ship %s changing target from %s to %s\n", Ships[aip->shipnum].ship_name, old_name, new_name));
}
*/
// AL 2-25-97: Ensure that a protected ship isn't being set as a target (for non-players only)
/*
if ( objnum >= 0 ) {
if ( !(Objects[Ships[aip->shipnum].objnum].flags & OF_PLAYER_SHIP) ) {
if ( Objects[objnum].flags & OF_PROTECTED ) {
// AL 2-26-97: removing Int3() until issue with setting OF_PROTECTED in ai_set_attack_subsystem()
//Int3(); // this should not happen
return aip->target_objnum; // don't change targets
}
}
}
*/
if ((aip != Player_ai) && (!timestamp_elapsed(aip->ok_to_target_timestamp))) {
return aip->target_objnum;
}
@@ -1446,7 +1417,6 @@ void adjust_accel_for_docking(ai_info *aip)
// make sure we at least some velocity
if (ratio < 0.1f) {
// Int3();
ratio = 0.1f;
}
@@ -1849,52 +1819,6 @@ float get_wing_lowest_max_speed(object *objp)
return lowest_max_speed;
}
/*
// Tell everyone to ignore object objnum.
void set_global_ignore_object(int objnum)
{
int i;
Assert(Objects[objnum].type == OBJ_SHIP);
nprintf(("AI", "Telling everyone to ignore object %s\n", Ships[Objects[objnum].instance].ship_name));
for (i=0; i<MAX_IGNORE_OBJECTS; i++) {
if (Ignore_objects[i].objnum == -1) {
Ignore_objects[i].objnum = objnum;
Ignore_objects[i].signature = Objects[objnum].signature;
break;
}
}
if (i == MAX_IGNORE_OBJECTS) {
// Couldn't find a free slot, but maybe one of these objects has died.
for (i=0; i<MAX_IGNORE_OBJECTS; i++) {
int o = Ignore_objects[i].objnum;
if (Objects[o].type != OBJ_SHIP)
break; // Not a ship, so use this slot.
if (Objects[o].signature != Ignore_objects[i].signature)
break; // Signatures don't match, so use this slot.
}
if (i != MAX_IGNORE_OBJECTS) {
Ignore_objects[i].objnum = objnum;
Ignore_objects[i].signature = Objects[objnum].signature;
} else {
nprintf(("Warning", "Ignore_objects buffer full. Stealing a slot to ignore object #%i\n"));
Int3();
int r;
r = objnum % MAX_IGNORE_OBJECTS;
Ignore_objects[r].objnum = objnum;
Ignore_objects[r].signature = Objects[objnum].signature;
}
}
}
*/
// Goober5000 - fixed up a bit
// Determine if object objnum is supposed to be ignored by object with ai_info *aip.
@@ -4174,13 +4098,13 @@ void ai_safety()
// --------------------------------------------------------------------------
// make Pl_objp fly tword a ship
// Goal created by Kazan
// code adapted from waypoints
void ai_fly_to_ship()
// make Pl_objp fly to its target's position
// optionally returns true if Pl_objp (pl_done_p) has reached the target position (can be NULL)
// optionally returns true if Pl_objp's (pl_treat_as_ship_p) fly to order was issued to him directly,
// or if the order was issued to his wing (returns false) (can be NULL, and result is only
// valid if Pl_done_p was not NULL and was set true by function.
void ai_fly_to_target_position(vec3d* target_pos, bool* pl_done_p=NULL, bool* pl_treat_as_ship_p=NULL)
{
vec3d *target_pos;
float dot, dist_to_goal, speed;
ship *shipp = &Ships[Pl_objp->instance];
ship_info *sip = &Ship_info[shipp->ship_info_index];
@@ -4190,30 +4114,25 @@ void ai_fly_to_ship()
float prev_dot_to_goal;
vec3d temp_vec;
vec3d *slop_vec;
int target_object=-1;
int j;
Assert( target_pos != NULL );
if ( pl_done_p != NULL ) {
// initialize this to false now incase we leave early so that that
// the caller of this function doesn't get any funny ideas about
// the status of the waypoint
*pl_done_p = false;
}
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
int i,j ;
for (i = 0; i < MAX_AI_GOALS && target_object == -1; i++)
{
if (aip->goals[i].ai_mode == AIM_FLY_TO_SHIP || aip->goals[i].ai_mode == AI_GOAL_FLY_TO_SHIP)
{
for (j = 0; j < MAX_SHIPS; j++)
{
if (Ships[j].objnum != -1 && !stricmp(aip->goals[i].ship_name, Ships[j].ship_name))
{
target_object = Ships[j].objnum;
break;
}
}
}
/* I shouldn't be flying to position for what ever called me any more.
Set mode to none so that default dynamic behaviour gets started up again. */
if ( (aip->active_goal == AI_GOAL_NONE) || (aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC) ) {
aip->mode = AIM_NONE;
}
target_pos = &Objects[target_object].pos;
speed = Pl_objp->phys_info.speed;
dist_to_goal = vm_vec_dist_quick(&Pl_objp->pos, target_pos);
@@ -4247,53 +4166,54 @@ void ai_fly_to_ship()
// If a wing leader, take turns more slowly, based on size of wing.
int scale;
if (Ai_info[Ships[Pl_objp->instance].ai_index].wing >= 0) {
scale = Wings[Ai_info[Ships[Pl_objp->instance].ai_index].wing].current_count;
if (aip->wing >= 0) {
scale = Wings[aip->wing].current_count;
scale = (int) ((scale+1)/2);
} else {
scale = 1;
}
// ----------------------------------------------
// if in autopilot mode make sure to not collide
// and "keep reasonable distance"
// this needs to be done for ALL SHIPS not just capships STOP CHANGING THIS
// ----------------------------------------------
object *wing_leader = get_wing_leader(aip->wing);
vec3d perp, goal_point;
bool carry_flag = ((shipp->flags2 & SF2_NAVPOINT_CARRY) || ((shipp->wingnum >= 0) && (Wings[shipp->wingnum].flags & WF_NAV_CARRY)));
if (AutoPilotEngaged && timestamp_elapsed(LockAPConv) && carry_flag
&& ((The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) || (Pl_objp != wing_leader)) )
if (AutoPilotEngaged
&& timestamp_elapsed(LockAPConv)
&& carry_flag
&& ((The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) || (Pl_objp != Autopilot_flight_leader)) )
{
Assertion( Autopilot_flight_leader != NULL, "When under autopilot there must be a flight leader" );
// snap wings into formation them into formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) {
if (aip->wing != -1) {
int wing_index = get_wing_index(Pl_objp, aip->wing);
object *wing_leader = get_wing_leader(aip->wing);
if (wing_leader != Pl_objp) {
// not leader.. get our position relative to leader
// not wing leader.. get my position relative to wing leader
get_absolute_wing_pos_autopilot(&goal_point, wing_leader, wing_index, aip->ai_flags & AIF_FORMATION_OBJECT);
} else {
// Am wing leader.. get the wings position relative to the flight leader
j = 1+int( (float)floor(double(autopilot_wings[aip->wing]-1)/2.0) );
switch (autopilot_wings[aip->wing] % 2) {
case 1: // back-left
vm_vec_copy_normalize(&perp, &Player_obj->orient.vec.rvec);
vm_vec_copy_normalize(&perp, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
default: //back-right
case 0:
vm_vec_copy_normalize(&perp, &Player_obj->orient.vec.rvec);
vm_vec_copy_normalize(&perp, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_scale(&perp, 166.0f*j);
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
}
@@ -4302,10 +4222,10 @@ void ai_fly_to_ship()
Pl_objp->pos = goal_point;
}
vm_vec_sub(&perp, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
vm_vec_sub(&perp, Navs[CurrentNav].GetPosition(), &Autopilot_flight_leader->pos);
vm_vector_2_matrix(&Pl_objp->orient, &perp, NULL, NULL);
} else {
vm_vec_scale_add(&perp, &Pl_objp->pos, &wing_leader->phys_info.vel, 1000.0f);
vm_vec_scale_add(&perp, &Pl_objp->pos, &Autopilot_flight_leader->phys_info.vel, 1000.0f);
ai_turn_towards_vector(&perp, Pl_objp, flFrametime, sip->srotation_time*3.0f*scale, slop_vec, NULL, 0.0f, 0);
}
} else {
@@ -4320,8 +4240,6 @@ void ai_fly_to_ship()
dot = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, target_pos);
aip->prev_dot_to_goal = dot;
// nprintf(("AI", "Wp #%i, dot = %6.3f, next dot = %6.3f, dist = %7.2f\n", wp_index, dot, dot_to_next, dist_to_goal));
if (Pl_objp->phys_info.speed < 0.0f) {
accelerate_ship(aip, 1.0f/32);
} else if (prev_dot_to_goal > dot+0.01f) {
@@ -4383,13 +4301,11 @@ void ai_fly_to_ship()
r = find_nearest_point_on_line(&nearest_point, &Pl_objp->last_pos, &Pl_objp->pos, target_pos);
if ( (vm_vec_dist_quick(&Pl_objp->pos, target_pos) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius) + vm_vec_dist_quick(&Pl_objp->pos, &Pl_objp->last_pos))) ||
((r >= 0.0f) && (r <= 1.0f)) && (vm_vec_dist_quick(&nearest_point, target_pos) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius)))) {
if ( (vm_vec_dist_quick(&Pl_objp->pos, target_pos) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius) + vm_vec_dist_quick(&Pl_objp->pos, &Pl_objp->last_pos)))
|| (((r >= 0.0f) && (r <= 1.0f)) && (vm_vec_dist_quick(&nearest_point, target_pos) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius)))))
{
int treat_as_ship;
// when not repeating waypoints -- mark the goal as done and put and entry into the mission log
// we must be careful when dealing with wings. A ship in a wing might be completing
// a waypoint for for the entire wing, or it might be completing a goal for itself. If
// for itself and in a wing, treat the completion as we would a ship
@@ -4397,15 +4313,6 @@ void ai_fly_to_ship()
if ( Ships[Pl_objp->instance].wingnum != -1 ) {
int type;
// I don't think that you can fly waypoints as dynamic goals!!!
// -- This is legal, just stupid. -- Assert( (aip->active_goal != AI_GOAL_NONE) && (aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC) );
// Clean up from above Assert, just in case we ship without fixing it. (Encountered by JimB on 2/9/98)
if ( (aip->active_goal == AI_GOAL_NONE) || (aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC) ) {
aip->mode = AIM_NONE;
Int3(); // Look at the ship, find out of it's supposed to be flying waypoints. -- MK.
}
type = aip->goals[aip->active_goal].type;
if ( (type == AIG_TYPE_EVENT_WING) || (type == AIG_TYPE_PLAYER_WING) ) {
treat_as_ship = 0;
@@ -4413,20 +4320,20 @@ void ai_fly_to_ship()
treat_as_ship = 1;
}
}
// if the ship is not in a wing, remove the goal and continue on
if ( treat_as_ship ) {
ai_mission_goal_complete( aip ); // this call should reset the AI mode
//mission_log_add_entry(LOG_WAYPOINTS_DONE, Ships[Pl_objp->instance].ship_name, wpl->name, -1 );
// setup out parameters
if ( pl_done_p != NULL ) {
*pl_done_p = true;
if ( pl_treat_as_ship_p != NULL ) {
if ( treat_as_ship ) {
*pl_treat_as_ship_p = true;
} else {
*pl_treat_as_ship_p = false;
}
}
} else {
// this ship is in a wing. We must mark the goal as being completed for all ships
// in the wing. We will also mark an entry in the log that the wing completed the goal
// not the individual ship.
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
//mission_log_add_entry( LOG_WAYPOINTS_DONE, Wings[Ships[Pl_objp->instance].wingnum].name, wpl->name, -1 );
Assertion( pl_treat_as_ship_p != NULL,
"pl_done_p cannot be NULL while pl_treat_as_ship_p is not NULL" );
}
//wp_index = wpl->count-1;
}
}
}
@@ -4436,18 +4343,8 @@ void ai_fly_to_ship()
void ai_waypoints()
{
int wp_index;
vec3d *wp_cur, *wp_next;
float dot, dist_to_goal, dist_to_next, speed, dot_to_next;
ship *shipp = &Ships[Pl_objp->instance];
ship_info *sip = &Ship_info[shipp->ship_info_index];
waypoint_list *wpl;
ai_info *aip;
vec3d nvel_vec;
float mag;
float prev_dot_to_goal;
vec3d temp_vec;
vec3d *slop_vec;
int j;
waypoint_list *wpl;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -4461,236 +4358,111 @@ void ai_waypoints()
wpl = &Waypoint_lists[aip->wp_list];
Assert(wpl->count); // What? Is this zero? Probably wp_index never got initialized!
Assert(wpl->count > 0); // What? Is this zero? Probably wp_index never got initialized!
wp_cur = &wpl->waypoints[wp_index];
wp_next = &wpl->waypoints[(wp_index+1) % wpl->count];
speed = Pl_objp->phys_info.speed;
bool done, treat_as_ship;
ai_fly_to_target_position(&(wpl->waypoints[wp_index]), &done, &treat_as_ship);
dist_to_goal = vm_vec_dist_quick(&Pl_objp->pos, wp_cur);
dist_to_next = vm_vec_dist_quick(&Pl_objp->pos, wp_next);
// Can't use fvec, need to use velocity vector because we aren't necessarily
// moving in the direction we're facing.
// AL 23-3-98: Account for very small velocities by checking result of vm_vec_mag().
// If we don't vm_vec_copy_normalize() will think it is normalizing a null vector.
// if (IS_VEC_NULL(&Pl_objp->phys_info.vel)) {
if ( vm_vec_mag_quick(&Pl_objp->phys_info.vel) < AICODE_SMALL_MAGNITUDE ) {
mag = 0.0f;
vm_vec_zero(&nvel_vec);
} else {
mag = vm_vec_copy_normalize(&nvel_vec, &Pl_objp->phys_info.vel);
}
// If moving not-very-slowly and sliding, then try to slide at goal, rather than
// point at goal.
slop_vec = NULL;
if (mag < 1.0f) {
nvel_vec = Pl_objp->orient.vec.fvec;
} else if (mag > 5.0f) {
float nv_dot;
nv_dot = vm_vec_dot(&Pl_objp->orient.vec.fvec, &nvel_vec);
if ((nv_dot > 0.5f) && (nv_dot < 0.97f)) {
slop_vec = &temp_vec;
vm_vec_sub(slop_vec, &nvel_vec, &Pl_objp->orient.vec.fvec);
}
}
// If a wing leader, take turns more slowly, based on size of wing.
int scale;
if (aip->wing >= 0) {
scale = Wings[aip->wing].current_count;
scale = (int) ((scale+1)/2);
} else {
scale = 1;
}
// ----------------------------------------------
// if in autopilot mode make sure to not collide
// and "keep reasonable distance"
// this needs to be done for ALL SHIPS not just capships STOP CHANGING THIS
// ----------------------------------------------
object *wing_leader = get_wing_leader(aip->wing);
vec3d perp, goal_point;
bool carry_flag = ((shipp->flags2 & SF2_NAVPOINT_CARRY) || ((shipp->wingnum >= 0) && (Wings[shipp->wingnum].flags & WF_NAV_CARRY)));
if (AutoPilotEngaged && timestamp_elapsed(LockAPConv) && carry_flag
&& ((The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) || (Pl_objp != wing_leader)) )
{
// snap wings into formation them into formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) {
if (aip->wing != -1) {
int wing_index = get_wing_index(Pl_objp, aip->wing);
if (wing_leader != Pl_objp) {
// not leader.. get our position relative to leader
get_absolute_wing_pos_autopilot(&goal_point, wing_leader, wing_index, aip->ai_flags & AIF_FORMATION_OBJECT);
} else {
j = 1+int( (float)floor(double(autopilot_wings[aip->wing]-1)/2.0) );
switch (autopilot_wings[aip->wing] % 2) {
case 1: // back-left
vm_vec_copy_normalize(&perp, &Player_obj->orient.vec.rvec);
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
break;
default: //back-right
case 0:
vm_vec_copy_normalize(&perp, &Player_obj->orient.vec.rvec);
vm_vec_scale(&perp, 166.0f*j);
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
break;
}
}
Pl_objp->pos = goal_point;
}
vm_vec_sub(&perp, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
vm_vector_2_matrix(&Pl_objp->orient, &perp, NULL, NULL);
} else {
if ( !wing_leader )
wing_leader = Pl_objp;
vm_vec_scale_add(&perp, &Pl_objp->pos, &wing_leader->phys_info.vel, 1000.0f);
ai_turn_towards_vector(&perp, Pl_objp, flFrametime, sip->srotation_time*3.0f*scale, slop_vec, NULL, 0.0f, 0);
}
} else {
if (dist_to_goal > 0.1f) {
ai_turn_towards_vector(wp_cur, Pl_objp, flFrametime, sip->srotation_time*3.0f*scale, slop_vec, NULL, 0.0f, 0);
}
}
// ----------------------------------------------
prev_dot_to_goal = aip->prev_dot_to_goal;
dot = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, wp_cur);
dot_to_next = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, wp_next);
aip->prev_dot_to_goal = dot;
// If there is no next point on the path, don't care about dot to next.
if (wp_index + 1 >= wpl->count) {
dot_to_next = dot;
}
// nprintf(("AI", "Wp #%i, dot = %6.3f, next dot = %6.3f, dist = %7.2f\n", wp_index, dot, dot_to_next, dist_to_goal));
if (Pl_objp->phys_info.speed < 0.0f) {
accelerate_ship(aip, 1.0f/32);
} else if (prev_dot_to_goal > dot+0.01f) {
// We are further from pointing at our goal this frame than last frame, so slow down.
set_accel_for_target_speed(Pl_objp, Pl_objp->phys_info.speed * 0.95f);
} else if (dist_to_goal < 100.0f) {
float slew_dot = vm_vec_dot(&Pl_objp->orient.vec.fvec, &nvel_vec);
if (fl_abs(slew_dot) < 0.9f) {
accelerate_ship(aip, 0.0f);
} else if (dot < 0.88f + 0.1f*(100.0f - dist_to_goal)/100.0f) {
accelerate_ship(aip, 0.0f);
} else {
accelerate_ship(aip, 0.5f * dot * dot);
}
} else {
float dot1;
if (dist_to_goal < 250.0f) {
dot1 = dot*dot*dot; // Very important to be pointing towards goal when nearby. Note, cubing preserves sign.
} else {
if (dot > 0.0f) {
dot1 = dot*dot;
if ( done ) {
aip->wp_index++; // go on to next waypoint in path
if ( (aip->wp_index >= wpl->count) ) {
// have reached the last waypoint. Do I?
if ( ((aip->wp_flags & WPF_REPEAT) > 0) ) {
aip->wp_index = 0; // go back to the start.
} else {
dot1 = dot;
}
}
if (dist_to_goal > 100.0f + Pl_objp->radius * 2) {
if (dot < 0.2f) {
dot1 = 0.2f;
}
}
if (sip->flags & SIF_SMALL_SHIP) {
set_accel_for_target_speed(Pl_objp, dot1 * dist_to_goal/5.0f);
} else {
set_accel_for_target_speed(Pl_objp, dot1 * dist_to_goal/10.0f);
}
}
// Make sure not travelling too fast for someone to keep up.
float max_allowed_speed = 9999.9f;
if (shipp->wingnum != -1) {
max_allowed_speed = 0.9f * get_wing_lowest_max_speed(Pl_objp);
}
// check if waypoint speed cap is set and adjust max speed
if (aip->waypoint_speed_cap > 0) {
max_allowed_speed = (float) aip->waypoint_speed_cap;
}
if (aip->prev_accel * shipp->current_max_speed > max_allowed_speed) {
accelerate_ship(aip, max_allowed_speed / shipp->current_max_speed);
}
if ( (dist_to_goal < MIN_DIST_TO_WAYPOINT_GOAL) || (vm_vec_dist_quick(&Pl_objp->last_pos, &Pl_objp->pos) > 0.1f) ) {
vec3d nearest_point;
float r;
r = find_nearest_point_on_line(&nearest_point, &Pl_objp->last_pos, &Pl_objp->pos, wp_cur);
if ( (vm_vec_dist_quick(&Pl_objp->pos, wp_cur) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius) + vm_vec_dist_quick(&Pl_objp->pos, &Pl_objp->last_pos))) ||
((r >= 0.0f) && (r <= 1.0f)) && (vm_vec_dist_quick(&nearest_point, wp_cur) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius)))) {
wp_index++;
if (wp_index >= wpl->count)
if (aip->wp_flags & WPF_REPEAT) {
wp_index = 0;
aip->wp_index = (wpl->count - 1); // stay on the last waypoint
// Log a message that the wing or ship reached his waypoint and
// remove the goal from the AI goals of the ship pr wing, respectively.
// Wether or not we should treat this as a ship or a wing is determined by
// ai_fly_to_target_position when it marks the AI directive as complete
if ( treat_as_ship ) {
ai_mission_goal_complete( aip ); // this call should reset the AI mode
mission_log_add_entry( LOG_WAYPOINTS_DONE, Ships[Pl_objp->instance].ship_name, wpl->name, -1 );
} else {
int treat_as_ship;
// when not repeating waypoints -- mark the goal as done and put and entry into the mission log
// we must be careful when dealing with wings. A ship in a wing might be completing
// a waypoint for for the entire wing, or it might be completing a goal for itself. If
// for itself and in a wing, treat the completion as we would a ship
treat_as_ship = 1;
if ( Ships[Pl_objp->instance].wingnum != -1 ) {
int type;
// I don't think that you can fly waypoints as dynamic goals!!!
// -- This is legal, just stupid. -- Assert( (aip->active_goal != AI_GOAL_NONE) && (aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC) );
// Clean up from above Assert, just in case we ship without fixing it. (Encountered by JimB on 2/9/98)
if ( (aip->active_goal == AI_GOAL_NONE) || (aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC) ) {
aip->mode = AIM_NONE;
//Int3(); // Look at the ship, find out of it's supposed to be flying waypoints. -- MK.
}
type = aip->goals[aip->active_goal].type;
if ( (type == AIG_TYPE_EVENT_WING) || (type == AIG_TYPE_PLAYER_WING) ) {
treat_as_ship = 0;
} else {
treat_as_ship = 1;
}
}
// if the ship is not in a wing, remove the goal and continue on
if ( treat_as_ship ) {
ai_mission_goal_complete( aip ); // this call should reset the AI mode
mission_log_add_entry(LOG_WAYPOINTS_DONE, Ships[Pl_objp->instance].ship_name, wpl->name, -1 );
} else {
// this ship is in a wing. We must mark the goal as being completed for all ships
// in the wing. We will also mark an entry in the log that the wing completed the goal
// not the individual ship.
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
mission_log_add_entry( LOG_WAYPOINTS_DONE, Wings[Ships[Pl_objp->instance].wingnum].name, wpl->name, -1 );
}
//wp_index = wpl->count-1;
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
mission_log_add_entry( LOG_WAYPOINTS_DONE, Wings[Ships[Pl_objp->instance].wingnum].name, wpl->name, -1 );
}
}
}
}
}
aip->wp_index = wp_index;
// --------------------------------------------------------------------------
// make Pl_objp fly toward a ship
void ai_fly_to_ship()
{
ai_info *aip;
object* target_p = NULL;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
if ( aip->mode != AIM_FLY_TO_SHIP ) {
Warning(LOCATION,
"ai_fly_to_ship called for '%s' when ai_info.mode not equal to AIM_FLY_TO_SHIP. Is actually '%d'",
Ships[Pl_objp->instance].ship_name,
aip->mode);
aip->mode = AIM_NONE;
return;
}
if ( aip->active_goal < 0 || aip->active_goal >= MAX_AI_GOALS ) {
Warning(LOCATION,
"'%s' is trying to fly-to a ship without an active AI_GOAL\n\n"
"Active ai mode is '%d'",
Ships[Pl_objp->instance].ship_name,
aip->active_goal);
aip->mode = AIM_NONE;
return;
}
Assert( aip->goals[aip->active_goal].ship_name != NULL );
if ( strlen(aip->goals[aip->active_goal].ship_name) == 0 ) {
Warning(LOCATION,
"'%s' is trying to fly-to a ship without a name for the ship",
Ships[Pl_objp->instance].ship_name);
aip->mode = AIM_NONE;
ai_remove_ship_goal( aip, aip->active_goal ); // function sets aip->active_goal to NONE for me
return;
}
for (int j = 0; j < MAX_SHIPS; j++)
{
if (Ships[j].objnum != -1 && !stricmp(aip->goals[aip->active_goal].ship_name, Ships[j].ship_name))
{
target_p = &Objects[Ships[j].objnum];
break;
}
}
if ( target_p == NULL ) {
#ifndef NDEBUG
for (int i = 0; i < MAX_AI_GOALS; i++)
{
if (aip->mode == AIM_FLY_TO_SHIP || aip->goals[i].ai_mode == AI_GOAL_FLY_TO_SHIP)
{
mprintf(("Ship '%s' told to fly to target ship '%s'",
Ships[Pl_objp->instance].ship_name,
aip->goals[i].ship_name));
}
}
#endif
Warning(LOCATION, "Ship '%s' told to fly to a ship but none of the ships it was told to fly to exist.\n"
"See log before this message for list of ships set as fly-to tagets",
Ships[Pl_objp->instance].ship_name);
aip->mode = AIM_NONE;
ai_remove_ship_goal( aip, aip->active_goal ); // function sets aip->active_goal to NONE for me
return;
} else {
bool done, treat_as_ship;
ai_fly_to_target_position(&(target_p->pos), &done, &treat_as_ship);
if ( done ) {
// remove the goal from the AI goals of the ship pr wing, respectively.
// Wether or not we should treat this as a ship or a wing is determined by
// ai_fly_to_target when it marks the AI directive as complete
if ( treat_as_ship ) {
ai_mission_goal_complete( aip ); // this call should reset the AI mode
} else {
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
}
}
}
}
@@ -5398,7 +5170,6 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
{
// this can be NULL in the case of a target death and attacker weapon
// change. using notification message instead of a fault
// Int3();
mprintf(("'other_objpp == NULL' in ai_select_primary_weapon()\n"));
return -1;
}
@@ -5450,7 +5221,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
// ##UnknownPlayer## - removed.
}
if ( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))
if ( (other_objp->type == OBJ_SHIP) && (Ship_info[Ships[other_objp->instance].ship_info_index].flags & (SIF_BIG_SHIP|SIF_HUGE_SHIP) ) )
{
//Check if we have a capital+ weapon on board
for (int i = 0; i < swp->num_primary_banks; i++)
@@ -5476,16 +5247,20 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
int i;
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
// Find the weapon with the highest hull * damage / fire delay factor
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
if (((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev) && (!(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) && !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))) )
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) )
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
}
}
}
}
@@ -5497,15 +5272,16 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
return i_hullfactor_prev_bank; // Return
}
//if the shields are above lets say 10% defanantly use a pierceing weapon if there are any-Bobboau
if (enemy_remaining_shield >= 0.10f){
//if the shields are above lets say 10% definitely use a pierceing weapon if there are any-Bobboau
if (enemy_remaining_shield >= 0.10f)
{
if (swp->current_primary_bank >= 0)
{
int bank_index;
bank_index = swp->current_primary_bank;
if ((Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)))
if ((Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_CAPITAL_PLUS))
{
return swp->current_primary_bank;
}
@@ -5518,7 +5294,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
if (weapon_info_index > -1)
{
if ((Weapon_info[weapon_info_index].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)))
if ((Weapon_info[weapon_info_index].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS))
{
swp->current_primary_bank = i;
return i;
@@ -5539,11 +5315,14 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
{
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
if (((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev ) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)))
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
// This weapon is the new candidate
i_hullfactor_prev = ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait));
i_hullfactor_prev_bank = i;
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) )
{
// This weapon is the new candidate
i_hullfactor_prev = ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait));
i_hullfactor_prev_bank = i;
}
}
}
}
@@ -5565,11 +5344,14 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
{
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
if (((((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev ) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)))
if ((((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) )
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
}
}
}
}
@@ -5738,7 +5520,7 @@ int ai_fire_primary_weapon(object *objp)
if (aip->target_objnum != -1){
enemy_objp = &Objects[aip->target_objnum];
enemy_sip = &Ship_info[Ships[enemy_objp->instance].ship_info_index];
enemy_sip = (enemy_objp->type == OBJ_SHIP) ? &Ship_info[Ships[enemy_objp->instance].ship_info_index] : NULL;
} else {
enemy_objp = NULL;
enemy_sip = NULL;
@@ -5775,7 +5557,7 @@ int ai_fire_primary_weapon(object *objp)
//SUSHI: Burst-fire for ballistic primaries.
if (The_mission.ai_profile->primary_ammo_burst_mult[Game_skill_level] > 0 && //Make sure we are using burst fire
enemy_objp != NULL && //We need a target, obviously
enemy_objp != NULL && enemy_sip != NULL && //We need a target, obviously
(enemy_objp->phys_info.speed >= 1.0f) && //Only burst for moving ships
(enemy_sip->flags & (SIF_SMALL_SHIP | SIF_TRANSPORT)) && //Only burst for small ships (transports count)
swp->primary_bank_start_ammo[swp->current_primary_bank] > 0 && //Prevent div by 0
@@ -6427,7 +6209,6 @@ float ai_get_weapon_dist(ship_weapon *swp)
// If weapon_num is illegal, return a reasonable value. A valid weapon
// will get selected when this ship tries to fire.
if (weapon_num == -1) {
// Int3();
return 1000.0f;
}
@@ -6445,7 +6226,6 @@ float ai_get_weapon_speed(ship_weapon *swp)
weapon_num = swp->primary_bank_weapons[bank_num];
if (weapon_num == -1) {
//Int3();
return 100.0f;
}
@@ -8099,14 +7879,6 @@ void ai_cruiser_chase()
ship *shipp = &Ships[Pl_objp->instance];
ai_info *aip = &Ai_info[shipp->ai_index];
//WMC - We don't need/want this anymore.
/*
if (!(sip->flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
Int3(); // Hmm, not a very big ship, how did we get in this function?
aip->mode = AIM_NONE;
return;
}*/
if (En_objp->type != OBJ_SHIP) {
Int3();
return;
@@ -8496,10 +8268,14 @@ void ai_chase()
aip->submode == SM_SUPER_ATTACK ||
aip->submode == SM_EVADE_SQUIGGLE ||
aip->submode == SM_EVADE ||
aip->submode == SM_GET_AWAY)
aip->submode == SM_GET_AWAY ||
aip->submode == AIS_CHASE_GLIDEATTACK)
{
//Re-roll for random sidethrust every 2 seconds
if (static_randf((Missiontime + static_rand(aip->shipnum)) >> 17) < aip->ai_random_sidethrust_percent)
//Also, only do this if we've recently been hit or are in current primary weapon range of target
float current_weapon_range = Weapon_info[swp->primary_bank_weapons[swp->current_primary_bank]].weapon_range;
if (static_randf((Missiontime + static_rand(aip->shipnum)) >> 17) < aip->ai_random_sidethrust_percent &&
((Missiontime - aip->last_hit_time < i2f(5) && aip->hitter_objnum >= 0) || dist_to_enemy < current_weapon_range))
{
do_random_sidethrust(aip, sip);
}
@@ -8577,8 +8353,7 @@ void ai_chase()
aip->submode_start_time = Missiontime;
aip->submode_parm0 = SM_SF_AHEAD;
} else if (dist_to_enemy < CIRCLE_STRAFE_MAX_DIST + En_objp->radius &&
(En_objp->phys_info.speed < MAX(sip->max_vel.xyz.x, sip->max_vel.xyz.y)) &&
(dot_to_enemy > 0.33) &&
(En_objp->phys_info.speed < MAX(sip->max_vel.xyz.x, sip->max_vel.xyz.y) * 1.5f) &&
(static_randf((Missiontime + static_rand(aip->shipnum)) >> 19) < aip->ai_circle_strafe_percent)) {
aip->submode = AIS_CHASE_CIRCLESTRAFE;
aip->submode_start_time = Missiontime;
@@ -8693,8 +8468,7 @@ void ai_chase()
aip->submode_start_time = Missiontime;
aip->submode_parm0 = SM_SF_AHEAD;
} else if (dist_to_enemy < CIRCLE_STRAFE_MAX_DIST + En_objp->radius &&
(En_objp->phys_info.speed < MAX(sip->max_vel.xyz.x, sip->max_vel.xyz.y)) &&
(dot_to_enemy > 0.33) &&
(En_objp->phys_info.speed < MAX(sip->max_vel.xyz.x, sip->max_vel.xyz.y) * 1.5f) &&
(static_randf((Missiontime + static_rand(aip->shipnum)) >> 19) < aip->ai_circle_strafe_percent)) {
aip->submode = AIS_CHASE_CIRCLESTRAFE;
aip->submode_start_time = Missiontime;
@@ -12459,7 +12233,7 @@ void ai_manage_shield(object *objp, ai_info *aip)
// set timestamp
aip->shield_manage_timestamp = timestamp((int) (delay * 1000.0f));
if (sip->flags & SIF_SMALL_SHIP) {
if (sip->flags & SIF_SMALL_SHIP || (aip->ai_profile_flags2 & AIPF2_ALL_SHIPS_MANAGE_SHIELDS)) {
if (Missiontime - aip->last_hit_time < F1_0*10)
ai_transfer_shield(objp, aip->last_hit_quadrant);
else
@@ -15263,7 +15037,7 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_
objp_hitter = &Objects[hitter_objnum];
// lets not check hits by ghosts any further either
if(objp_hitter->type & OBJ_GHOST)
if(objp_hitter->type == OBJ_GHOST)
return;
// Hit by a protected ship, don't attack it.
+1 -1
View File
@@ -1008,7 +1008,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
* Pass -1 in priority to ignore priority when searching
* Returns -1 if not found, or [0, MAX_AI_GOALS)
*/
int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 )
int ai_find_goal_index( ai_goal* aigp, int mode, int submode, int priority )
{
Assert( aigp != NULL );
for ( int i = 0; i < MAX_AI_GOALS; i++ )
+24 -24
View File
@@ -26,35 +26,35 @@ struct ai_goal;
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
// to worry about doing this. Also add it to list in Fred\Management.cpp, and let Hoffoss know!
// WMC - Oh and add them to Ai_goal_names plz. TY! :)
#define AI_GOAL_CHASE (1<<1)
#define AI_GOAL_DOCK (1<<2) // used for undocking as well
#define AI_GOAL_WAYPOINTS (1<<3)
#define AI_GOAL_WAYPOINTS_ONCE (1<<4)
#define AI_GOAL_WARP (1<<5)
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6)
#define AI_GOAL_FORM_ON_WING (1<<7)
#define AI_GOAL_UNDOCK (1<<8)
#define AI_GOAL_CHASE_WING (1<<9)
#define AI_GOAL_GUARD (1<<10)
#define AI_GOAL_DISABLE_SHIP (1<<11)
#define AI_GOAL_DISARM_SHIP (1<<12)
#define AI_GOAL_CHASE_ANY (1<<13)
#define AI_GOAL_IGNORE (1<<14)
#define AI_GOAL_GUARD_WING (1<<15)
#define AI_GOAL_EVADE_SHIP (1<<16)
#define AI_GOAL_CHASE (1<<1) // 0x00000002
#define AI_GOAL_DOCK (1<<2) // 0x00000004 // used for undocking as well
#define AI_GOAL_WAYPOINTS (1<<3) // 0x00000008
#define AI_GOAL_WAYPOINTS_ONCE (1<<4) // 0x00000010
#define AI_GOAL_WARP (1<<5) // 0x00000020
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6) // 0x00000040
#define AI_GOAL_FORM_ON_WING (1<<7) // 0x00000080
#define AI_GOAL_UNDOCK (1<<8) // 0x00000100
#define AI_GOAL_CHASE_WING (1<<9) // 0x00000200
#define AI_GOAL_GUARD (1<<10) // 0x00000400
#define AI_GOAL_DISABLE_SHIP (1<<11) // 0x00000800
#define AI_GOAL_DISARM_SHIP (1<<12) // 0x00001000
#define AI_GOAL_CHASE_ANY (1<<13) // 0x00002000
#define AI_GOAL_IGNORE (1<<14) // 0x00004000
#define AI_GOAL_GUARD_WING (1<<15) // 0x00008000
#define AI_GOAL_EVADE_SHIP (1<<16) // 0x00010000
// the next goals are for support ships only
#define AI_GOAL_STAY_NEAR_SHIP (1<<17)
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18)
#define AI_GOAL_REARM_REPAIR (1<<19)
#define AI_GOAL_STAY_NEAR_SHIP (1<<17) // 0x00020000
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18) // 0x00040000
#define AI_GOAL_REARM_REPAIR (1<<19) // 0x00080000
// resume regular goals
#define AI_GOAL_STAY_STILL (1<<20)
#define AI_GOAL_PLAY_DEAD (1<<21)
#define AI_GOAL_CHASE_WEAPON (1<<22)
#define AI_GOAL_STAY_STILL (1<<20) // 0x00100000
#define AI_GOAL_PLAY_DEAD (1<<21) // 0x00200000
#define AI_GOAL_CHASE_WEAPON (1<<22) // 0x00400000
#define AI_GOAL_FLY_TO_SHIP (1<<23) // kazan
#define AI_GOAL_IGNORE_NEW (1<<24) // Goober5000
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
// now the masks for ship types
+14 -6
View File
@@ -1905,8 +1905,8 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
if(num_valid < 1)
ss->turret_enemy_objnum = -1;
// Maybe pick a new enemy.
if ( turret_should_pick_new_target(ss) ) {
// Maybe pick a new enemy, unless targeting has been taken over by scripting
if ( turret_should_pick_new_target(ss) && !ss->scripting_target_override) {
Num_find_turret_enemy++;
int objnum = find_turret_enemy(ss, parent_objnum, &gpos, &gvec, ss->turret_enemy_objnum);
//Assert(objnum < 0 || is_target_beam_valid(tp, objnum));
@@ -2141,6 +2141,12 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
turret_fire_weapon(valid_weapons[0], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
else
turret_fire_weapon(valid_weapons[i], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
} else {
// make sure salvo fire mode does not turn into autofire
if ((tp->flags & MSS_FLAG_TURRET_SALVO) && ((i + 1) == number_of_firings)) {
ai_info *parent_aip = &Ai_info[Ships[Objects[parent_objnum].instance].ai_index];
turret_set_next_fire_timestamp(valid_weapons[0], wip, ss, parent_aip);
}
}
// moved this here so we increment the fire pos only after we have fired and not during it
ss->turret_next_fire_pos++;
@@ -2213,14 +2219,16 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
vec3d of_dst;
vm_vec_rotate( &of_dst, v2e, &ss->world_to_turret_matrix );
vm_vec_normalize(&of_dst);
if ((of_dst.xyz.x == 0) && (of_dst.xyz.y == 0)) {
return true;
} else {
of_dst.xyz.z = 0;
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
return true;
if (!IS_VEC_NULL_SQ_SAFE(&of_dst)) {
vm_vec_normalize(&of_dst);
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
return true;
}
}
}
return false;
+3 -5
View File
@@ -1085,11 +1085,9 @@ void anim_reverse_direction(anim_instance *ai)
{
int temp;
if(!(ai->parent->flags & ANF_ALL_KEYFRAMES)){
// you're not allowed to call anim_reverse_direction(...) unless every frame is a keyframe!!!!
// The God of Delta-RLE demands it be thus.
Int3();
}
// you're not allowed to call anim_reverse_direction(...) unless every frame is a keyframe!!!!
// The God of Delta-RLE demands it be thus.
Assertion( ai->parent->flags & ANF_ALL_KEYFRAMES, "Ani was set to play backwards. In order to enable this, all frames of the animation MUST be keyframes.");
// flip the animation direction
if(ai->direction == ANIM_DIRECT_FORWARD){
+1 -149
View File
@@ -168,154 +168,6 @@ ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap
return inst->frame;
}
// --------------------------------------------------------------------
// anim_get_frame()
//
// Get a bitmap id from the anim_instance for the specified frame_num
//
// input: *inst => pointer to anim instance
// frame_num => frame number to get (first frame is 0)
// xlate_pal => DEFAULT PARM (value 1): whether to translate the palette
// to the current game palette
//
int anim_get_frame(anim_instance *inst, int frame_num, int xlate_pal)
{
/*
int bm, bitmap_flags, key = 0, offset = 0;
int idx;
if ((frame_num < 0) || (frame_num >= inst->parent->total_frames)) // illegal frame number
return -1;
int need_reset = 0;
if ( anim_instance_is_streamed(inst) ) {
if ( inst->file_offset < 0 ) {
need_reset = 1;
}
} else {
if ( !inst->data ) {
need_reset = 1;
}
}
if (need_reset || (inst->frame_num >= inst->parent->total_frames)) { // reset to valid info
inst->data = inst->parent->data;
inst->file_offset = inst->parent->file_offset;
inst->frame_num = 0;
}
bitmap_flags = 0;
if (inst->parent->flags & ANF_XPARENT) {
// bitmap_flags = BMP_XPARENT;
bitmap_flags = 0;
}
if ( inst->frame_num == frame_num ) {
bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
bm_unload(bm);
return bm;
}
if (inst->parent->flags & ANF_XPARENT){
// bitmap_flags = BMP_XPARENT;
bitmap_flags = 0;
} else {
bitmap_flags = 0;
}
idx = 0;
key = 0;
while(idx < inst->parent->num_keys){
if (( (inst->parent->keys[idx].frame_num-1) <= frame_num) && ( (inst->parent->keys[idx].frame_num-1) > key)) { // find closest key
key = inst->parent->keys[idx].frame_num - 1;
offset = inst->parent->keys[idx].offset;
if ( key == frame_num )
break;
}
idx++;
}
if ( key == frame_num ) {
inst->frame_num = key;
if ( anim_instance_is_streamed(inst) ) {
inst->file_offset = inst->parent->file_offset + offset;
} else {
inst->data = inst->parent->data + offset;
}
anim_check_for_palette_change(inst);
if ( anim_instance_is_streamed(inst) ) {
if ( xlate_pal ){
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
} else {
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
}
} else {
if ( xlate_pal ){
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
} else {
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
}
}
goto create_bitmap;
}
if (key > inst->frame_num) // best key is closer than current position
{
inst->frame_num = key;
if ( anim_instance_is_streamed(inst) ) {
inst->file_offset = inst->parent->file_offset + offset;
} else {
inst->data = inst->parent->data + offset;
}
anim_check_for_palette_change(inst);
if ( anim_instance_is_streamed(inst) ) {
if ( xlate_pal )
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
else
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
} else {
if ( xlate_pal )
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
else
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
}
}
while (inst->frame_num != frame_num) {
anim_check_for_palette_change(inst);
if ( anim_instance_is_streamed(inst) ) {
if ( xlate_pal )
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
else
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
} else {
if ( xlate_pal )
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
else
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
}
inst->frame_num++;
}
create_bitmap:
bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
bm_unload(bm);
return bm;
*/
Int3();
return -1;
}
// frame = frame pixel data to pack
// save = memory to store packed data to
// size = number of bytes to pack
@@ -1173,7 +1025,7 @@ int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal
}
}
else {
// Int3(); // unknown packing method
// unknown packing method
return -1;
}
-1
View File
@@ -106,7 +106,6 @@ void anim_init();
anim_instance *init_anim_instance(anim *ptr, int bpp);
void free_anim_instance(anim_instance *inst);
int anim_get_next_frame(anim_instance *inst);
int anim_get_frame(anim_instance *inst, int frame_num, int xlate_pal=1);
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp);
void anim_set_palette(anim *a);
void anim_check_for_palette_change(anim_instance *inst);
+199 -142
View File
@@ -39,6 +39,7 @@ extern int Cmdline_autopilot_interruptable;
// Module variables
bool AutoPilotEngaged;
bool UseCutsceneBars;
bool LockWeaponsDuringAutopilot;
int CurrentNav;
float ramp_bias;
NavPoint Navs[MAX_NAVPOINTS];
@@ -55,6 +56,9 @@ bool CinematicStarted, CameraMoving;
vec3d cameraPos, cameraTarget;
std::map<int,int> autopilot_wings;
int AutopilotMinEnemyDistance;
int AutopilotMinAsteroidDistance;
// used for ramping time compression;
int start_dist;
@@ -149,12 +153,7 @@ char* NavPoint::GetInteralName()
}
// ********************************************************************************************
// Tell us if autopilot is allowed
// This needs:
// * Nav point selected
// * No enemies within X distance
// * Destination > 1,000 meters away
bool CanAutopilot(bool send_msg)
bool CanAutopilot(vec3d targetPos, bool send_msg)
{
if (CurrentNav == -1)
{
@@ -162,99 +161,69 @@ bool CanAutopilot(bool send_msg)
send_autopilot_msgID(NP_MSG_FAIL_NOSEL);
return false;
}
if (object_get_gliding(Player_obj))
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_GLIDING);
return false;
}
// You cannot autopilot if you're within 1000 meters of your destination nav point
if (vm_vec_dist_quick(&Player_obj->pos, Navs[CurrentNav].GetPosition()) < 1000)
{
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_TOCLOSE);
return false;
}
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO))
if ( AutopilotMinEnemyDistance > 0 ) {
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
// Cannot autopilot if enemy within 5,000 meters
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < 5000)
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
return false;
// Cannot autopilot if enemy within AutopilotMinEnemyDistance meters
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < AutopilotMinEnemyDistance) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
return false;
}
}
}
}
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// asteroid
if (Asteroids[n].flags & AF_USED)
{
// Cannot autopilot if asteroid within 1,000 meters
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Asteroids[n].objnum].pos) < 1000)
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
return false;
}
}
}
return true;
}
// ********************************************************************************************
// Tell us if autopilot is allowed at a certain position (only performs checks based on that position)
// This needs:
// * Nav point selected
// * No enemies within X distance
// * Destination > 1,000 meters away
bool CanAutopilotPos(vec3d targetPos)
{
// You cannot autopilot if you're within 1000 meters of your destination nav point
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000)
return false;
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
{
// Cannot autopilot if enemy within 5,000 meters
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < 5000)
return false;
}
}
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// asteroid
if (Asteroids[n].flags & AF_USED)
if ( AutopilotMinAsteroidDistance > 0 ) {
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// Cannot autopilot if asteroid within 1,000 meters
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < 1000)
return false;
// asteroid
if (Asteroids[n].flags & AF_USED)
{
// Cannot autopilot if asteroid within AutopilotMinAsteroidDistance meters
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < AutopilotMinAsteroidDistance) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
return false;
}
}
}
}
// check for support ships
// cannot autopilot if support ship present
if ( ship_find_repair_ship(Player_obj) != NULL ) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_PRESENT);
return false;
}
return true;
}
extern object* Autopilot_flight_leader;
// ********************************************************************************************
// Engages autopilot
// This does:
@@ -263,13 +232,54 @@ bool CanAutopilotPos(vec3d targetPos)
// * Lock time compression -WMC
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
void StartAutopilot()
bool StartAutopilot()
{
// Check for support ship and dismiss it if it is not doing anything.
// If the support ship is doing something then tell the user such.
bool done = false;
while (!done) {
object* support_ship_op = ship_find_repair_ship(Player_obj);
if ( support_ship_op == NULL ) {
// no more
done = true;
break;
}
Assert( support_ship_op->type == OBJ_SHIP );
Assert( support_ship_op->instance >= 0 );
Assert( support_ship_op->instance < MAX_SHIPS );
Assert( Ships[support_ship_op->instance].ai_index != -1 );
ai_info* support_ship_aip = &(Ai_info[Ships[support_ship_op->instance].ai_index]);
// is support ship trying to rearm-repair
if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
// no, so tell it to depart
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
} else {
// yes
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
return false;
}
}
if (!CanAutopilot())
return;
return false;
AutoPilotEngaged = true;
// find the ship that is "leading" all of the ships when the player starts
// autopilot
// by default the ship that is leading the autopilot session the player's
// wing leader (if the player is the wing leader then it will be the
// player).
// TODO:implement a way to allow a FREDer to say a different ship is leader
Autopilot_flight_leader = get_wing_leader(Player_ship->wingnum);
if ( Autopilot_flight_leader == NULL ) {
// force player to be the leader if he doesn't have a wing
Autopilot_flight_leader = Player_obj;
}
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
LockAPConv = timestamp(); // lock convergence instantly
else
@@ -328,10 +338,20 @@ void StartAutopilot()
}
}
// damp speed_cap to 90% of actual -- to make sure ships stay in formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
speed_cap = 0.90f * speed_cap;
if ( speed_cap < 1.0f ) {
/* We need to deal with this so that incorrectly flagged ships will not
cause the engine to fail to limit all the ships speeds correctly. */
Warning(LOCATION, "Ship speed cap is way too small (%f)!\n"
"This is normally caused by a ship that has nav-carry-status set, but cannot move itself (like a Cargo container).\n"
"Speed cap has been set to 1.0 m/s.",
speed_cap);
speed_cap = 1.0f;
}
ramp_bias = speed_cap/50.0f;
// assign ship goals
@@ -397,10 +417,10 @@ void StartAutopilot()
vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
}
// snap wings into formation them into formation
// snap wings into formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS && // only if using cinematics
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY) // only if in a wing
&& Player_obj != &Objects[Ships[i].objnum]) //only if not player object
&& Autopilot_flight_leader != &Objects[Ships[i].objnum]) //only if not flight leader's object
{
ai_info *aip = &Ai_info[Ships[i].ai_index];
int wingnum = aip->wing, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
@@ -419,33 +439,34 @@ void StartAutopilot()
switch (wcount % 2)
{
case 1: // back-left
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
vm_vec_normalize(&perp);
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
default: //back-right
case 0:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
vm_vec_normalize(&perp);
vm_vec_scale(&perp, 166.0f*j);
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
}
autopilot_wings[wingnum] = wcount;
wcount++;
}
Objects[Ships[i].objnum].pos = goal_point;
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
{
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
}
}
// lock primary and secondary weapons
//Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
if ( LockWeaponsDuringAutopilot )
Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
// clear the ship goals and cap the waypoint speed
ai_clear_ship_goals(&Ai_info[Ships[i].ai_index]);
@@ -540,9 +561,9 @@ void StartAutopilot()
vec3d right, front, up, offset;
for (i = 0; i < (int)capIndexes.size(); i++)
{
vm_vec_add(&right, &Player_obj->orient.vec.rvec, &zero);
vm_vec_add(&front, &Player_obj->orient.vec.fvec, &zero);
vm_vec_add(&up, &Player_obj->orient.vec.uvec, &zero);
vm_vec_add(&right, &Autopilot_flight_leader->orient.vec.rvec, &zero);
vm_vec_add(&front, &Autopilot_flight_leader->orient.vec.fvec, &zero);
vm_vec_add(&up, &Autopilot_flight_leader->orient.vec.uvec, &zero);
vm_vec_add(&offset, &zero, &zero);
if (Ship_info[Ships[capIndexes[i]].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
{
@@ -610,7 +631,7 @@ void StartAutopilot()
vm_vec_scale(&up, (1+((float)floor((float)capship_placed[1]/3))));
// move ourselves up and out of the way of the smaller ships
vm_vec_add(&perp, &Player_obj->orient.vec.uvec, &zero);
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.uvec, &zero);
vm_vec_scale(&perp, capship_spreads[2]);
vm_vec_add(&up, &up, &perp);
@@ -665,7 +686,7 @@ void StartAutopilot()
vm_vec_scale(&front, 2*(1+((float)floor((float)capship_placed[2]/3))));
// move "out" by 166*(wcount-1) so we don't bump into fighters
vm_vec_add(&perp, &Player_obj->orient.vec.rvec, &zero);
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.rvec, &zero);
vm_vec_scale(&perp, 166.0f*float(wcount-1));
if ( (capship_placed[2] % 2) == 0)
vm_vec_add(&right, &right, &perp);
@@ -687,16 +708,16 @@ void StartAutopilot()
// global scale the position by 50%
//vm_vec_scale(&offset, 1.5);
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Player_obj->pos, &offset);
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Autopilot_flight_leader->pos, &offset);
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
{
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
}
}
}
ftemp = floor(Player_obj->phys_info.max_vel.xyz.z/speed_cap);
ftemp = floor(Autopilot_flight_leader->phys_info.max_vel.xyz.z/speed_cap);
if (ftemp >= 2.0f && ftemp < 4.0f)
tc_factor = 2;
else if (ftemp >= 4.0f && ftemp < 8.0f)
@@ -708,11 +729,11 @@ void StartAutopilot()
tpos = *Navs[CurrentNav].GetPosition();
// determine distance toward nav at which camera will be
vm_vec_sub(&pos, &tpos, &Player_obj->pos);
vm_vec_sub(&pos, &tpos, &Autopilot_flight_leader->pos);
vm_vec_normalize(&pos); // pos is now a unit vector in the direction we will be moving the camera
//norm1 = pos;
vm_vec_scale(&pos, 5*speed_cap*tc_factor); // pos is now scaled by 5 times the speed (5 seconds ahead)
vm_vec_add(&pos, &pos, &Player_obj->pos); // pos is now 5*speed cap in front of player ship
vm_vec_add(&pos, &pos, &Autopilot_flight_leader->pos); // pos is now 5*speed cap in front of player ship
switch (myrand()%24)
// 8 different ways of getting perp points
@@ -723,74 +744,74 @@ void StartAutopilot()
case 9:
case 16:
if (capship_placed[0] == 0)
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
else
{ // become up-left
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
}
break;
case 2: // up
case 10:
case 23:
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
if (capshipPresent) // become up-right
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
break;
case 3: // left
case 11:
case 22:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
break;
case 4: // up-left
case 12:
case 21:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 5: // up-right
case 13:
case 20:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 6: // down-left
case 14:
case 19:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
if (capship_placed[0] < 2)
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
else
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 7: // down-right
case 15:
case 18:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
if (capship_placed[0] < 1)
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
else
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
default:
case 0: // right
case 8:
case 17:
perp = Player_obj->orient.vec.rvec;
perp = Autopilot_flight_leader->orient.vec.rvec;
break;
}
vm_vec_normalize(&perp);
//vm_vec_scale(&perp, 2*radius+distance);
vm_vec_scale(&perp, Player_obj->radius+radius);
vm_vec_scale(&perp, Autopilot_flight_leader->radius+radius);
// randomly scale up/down by up to 20%
j = 20-myrand()%40; // [-20,20]
@@ -830,16 +851,8 @@ void StartAutopilot()
camMovingTime = int(4.5*float(tc_factor));
set_time_compression((float)tc_factor);
}
}
// ********************************************************************************************
// Checks if autopilot should automatically die
// Returns true if:
// * Targetted waypoint < 10,000 meters away
// * Enemy < 10,000 meters
bool Autopilot_AutoDiable()
{
return !CanAutopilot();
return true;
}
// ********************************************************************************************
@@ -852,6 +865,8 @@ void EndAutoPilot()
{
AutoPilotEngaged = false;
Autopilot_flight_leader = NULL;
set_time_compression(1);
lock_time_compression(false);
Player_use_ai = 0;
@@ -899,8 +914,10 @@ void EndAutoPilot()
)
{
//unlock their weaponry
//Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
if ( LockWeaponsDuringAutopilot )
Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
Ai_info[Ships[i].ai_index].waypoint_speed_cap = -1; // uncap their speed
Ai_info[Ships[i].ai_index].mode = AIM_NONE; // make AI re-evaluate current ship mode
for (j = 0; j < MAX_AI_GOALS; j++)
{
@@ -975,34 +992,54 @@ camera* nav_get_set_camera()
void nav_warp(bool prewarp=false)
{
// ok... find our end distance - norm1 is still a unit vector in the direction from the player to the navpoint
vec3d targetPos, tpos=Player_obj->pos, pos;
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
/* ok... find our end distance - norm1 is still a unit vector in the
direction from the flight leader to the navpoint */
vec3d targetPos, tpos=Autopilot_flight_leader->pos, pos, velocity;
/* calculate a vector that we can use to make a path from the flight
leader's location to the nav point */
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Autopilot_flight_leader->pos);
vm_vec_normalize(&pos);
velocity = pos; // make a copy for later when we do setup veleocity vector
vm_vec_scale(&pos, 250.0f); // we move by increments of 250
while (CanAutopilotPos(tpos))
/* using the vector of the flight leaders's path, simulate moving the
flight along this path by checking the autopilot conditions as specific
intervals along the path*/
while (CanAutopilot(tpos))
{
vm_vec_add(&tpos, &tpos, &pos);
}
vm_vec_sub(&targetPos, &tpos, &Player_obj->pos); //targetPos is actually a projection in a the direction toward the nav
vm_vec_sub(&targetPos, &tpos, &Autopilot_flight_leader->pos);
/* targetPos is actually a vector that describes the exact 3D movement that
the flgith leader needs to execute to reach the location that the auto
pilot is to shut off */
// Check if we are actually just setting up for the cinimatic shot of the
// flight flying on autopilot. Only jump halfway. Also we also need to
// put the camera in the correct position to show the player this cinimatic
if (prewarp)
{
vm_vec_scale(&targetPos, 0.5);
vm_vec_add(&cameraPos, &cameraPos, &targetPos);
}
/* calcuate the speed that everyone is supposed to be going so that there
is no need for anyone to accelerate or decelerate (most obvious with
the player's fighter slowing down as it changes the camera pan speed). */
Assert( Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap > 0 );
vm_vec_scale(&velocity, (float)Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap);
// Find all ships that are supposed to autopilot with the player and move them
// to the cinimatic location or the final destination
for (int i = 0; i < MAX_SHIPS; i++)
{
if (Ships[i].objnum != -1 &&
(Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
)
)
if (Ships[i].objnum != -1
&& (Ships[i].flags2 & SF2_NAVPOINT_CARRY
|| (Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)))
{
vm_vec_add(&Objects[Ships[i].objnum].pos, &Objects[Ships[i].objnum].pos, &targetPos);
Objects[Ships[i].objnum].phys_info.vel = velocity;
}
}
@@ -1041,7 +1078,7 @@ void NavSystem_Do()
}
if (timestamp() >= EndAPCinematic || Autopilot_AutoDiable())
if (timestamp() >= EndAPCinematic || !CanAutopilot())
{
nav_warp();
EndAutoPilot();
@@ -1060,7 +1097,7 @@ void NavSystem_Do()
if(cam != NULL)
{
cam->set_position(&cameraPos);
cam->set_rotation_facing(&Player_obj->pos);
cam->set_rotation_facing(&Autopilot_flight_leader->pos);
}
CinematicStarted = true;
@@ -1068,7 +1105,7 @@ void NavSystem_Do()
}
else
{
if (Autopilot_AutoDiable())
if (!CanAutopilot())
EndAutoPilot();
}
@@ -1141,7 +1178,10 @@ void NavSystem_Do()
}
}
// autopilot linking
/* Link in any ships that need to be linked in when the player gets close
enough. Always done by the player because: "making sure the AI fighters
are where they're supposed to be at all times is like herding cats" -Woolie Wool
*/
for (int i = 0; i < MAX_SHIPS; i++)
{
if (Ships[i].objnum != -1 && Ships[i].flags2 & SF2_NAVPOINT_NEEDSLINK)
@@ -1191,7 +1231,7 @@ void send_autopilot_msg(char *msg, char *snd)
// send/play
if (audio_handle != -1)
{
audiostream_play(audio_handle, Master_event_music_volume, 0);
audiostream_play(audio_handle, (Master_event_music_volume * aav_music_volume), 0);
}
if (strlen(msg) != 0 && strcmp(msg, "none"))
@@ -1247,6 +1287,21 @@ void parse_autopilot_table(char *filename)
required_string("$Link Distance:");
stuff_int(&NavLinkDistance);
if (optional_string("$Interrupt autopilot if enemy within distance:"))
stuff_int(&AutopilotMinEnemyDistance);
else
AutopilotMinEnemyDistance = 5000;
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
stuff_int(&AutopilotMinAsteroidDistance);
else
AutopilotMinAsteroidDistance = 1000;
if (optional_string("$Lock Weapons During Autopilot:"))
stuff_boolean(&LockWeaponsDuringAutopilot);
else
LockWeaponsDuringAutopilot = false;
// optional no cutscene bars
if (optional_string("+No_Cutscene_Bars"))
UseCutsceneBars = false;
@@ -1255,7 +1310,9 @@ void parse_autopilot_table(char *filename)
Cmdline_autopilot_interruptable = 0;
// No Nav selected message
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:", "$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:" };
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
"$Support Present:", "$Support Working:" };
for (int i = 0; i < NP_NUM_MESSAGES; i++)
{
required_string(msg_tags[i]);
+17 -13
View File
@@ -8,6 +8,7 @@
#define _AUTOPILOT_H_
#include "globalincs/pstypes.h"
#include "object/object.h"
#include <map>
// milliseconds between updates
@@ -37,13 +38,15 @@ struct NavPoint
};
#define NP_NUM_MESSAGES 6
#define NP_MSG_FAIL_NOSEL 0
#define NP_MSG_FAIL_GLIDING 1
#define NP_MSG_FAIL_TOCLOSE 2
#define NP_MSG_FAIL_HOSTILES 3
#define NP_MSG_MISC_LINKED 4
#define NP_MSG_FAIL_HAZARD 5
#define NP_MSG_FAIL_SUPPORT_PRESENT 6
#define NP_MSG_FAIL_SUPPORT_WORKING 7
#define NP_NUM_MESSAGES 8
struct NavMessage
{
@@ -62,27 +65,28 @@ extern std::map<int,int> autopilot_wings;
bool Sel_NextNav();
// Tell us is autopilot is allow
// Tell us if autopilot is allowed
// This needs:
// * Nav point selected
// * No enemies within 5,000 meters
// * No enemies within AutopilotMinEnemyDistance meters
// * No asteroids within AutopilotMinAsteroidDistance meters
// * Destination > 1,000 meters away
bool CanAutopilot(bool send_msg=false);
bool CanAutopilotPos(vec3d targetPos);
// * Support ship not present or is actively leaving
bool CanAutopilot(vec3d targetPos, bool send_msg=false);
// Check if autopilot is allowed at player's current position
// See CanAutopilot(vec3d, bool) for more information
inline bool CanAutopilot(bool send_msg=false) { return CanAutopilot(Player_obj->pos, send_msg); }
// Engages autopilot
// This does:
// * Checks if Autopilot is allowed. See CanAutopilot() for conditions.
// * Control switched from player to AI
// * Time compression to 32x
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
void StartAutopilot();
// Checks if autopilot should automatically die
// Returns true if:
// * Targetted waypoint < 1,000 meters away
// * Enemy < 5,000 meters
bool Autopilot_AutoDiable();
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
// Returns false if autopilot cannot be started. True otherwise.
bool StartAutopilot();
// Disengages autopilot
// this does:
+5 -11
View File
@@ -534,7 +534,7 @@ int bm_load( char *real_filename )
}
if (free_slot < 0) {
Int3();
Assertion(free_slot < 0, "Could not find free BMPMAN slot for bitmap: %s", real_filename);
goto Done;
}
@@ -1046,7 +1046,7 @@ int bm_get_info( int handle, int *w, int * h, ubyte * flags, int *nframes, int *
}
#endif
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE!
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_info().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
if ( (bm_bitmaps[bitmapnum].type == BM_TYPE_NONE) || (bm_bitmaps[bitmapnum].handle != handle) ) {
if (w) *w = 0;
@@ -1089,7 +1089,7 @@ unsigned int bm_get_signature(int handle)
if ( !bm_inited ) bm_init();
int bitmapnum = handle % MAX_BITMAPS;
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_signature().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
return bm_bitmaps[bitmapnum].signature;
}
@@ -1100,7 +1100,7 @@ ubyte bm_get_type(int handle)
if ( !bm_inited ) bm_init();
int bitmapnum = handle % MAX_BITMAPS;
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_type().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
return bm_bitmaps[bitmapnum].type;
}
@@ -1597,13 +1597,7 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
int bitmapnum = handle % MAX_BITMAPS;
#ifndef NDEBUG
if(bm_bitmaps[bitmapnum].handle != handle) {
mprintf(("bm_lock - %s: bm_bitmaps[%d].handle = %d, handle = %d\n", bm_bitmaps[bitmapnum].filename, bitmapnum, bm_bitmaps[bitmapnum].handle, handle));
}
#endif
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid handle %d passed to bm_lock. This might be due to an animation elsewhere in the code being too short.\n", handle ); // INVALID BITMAP HANDLE
// flags &= (~BMP_RLE);
+7 -49
View File
@@ -147,9 +147,14 @@ int cfile_in_root_dir(char *exe_path)
token_count++;
tok = strtok(NULL, DIR_SEPARATOR_STR);
} while(tok != NULL);
// root directory if we have <= 1 slash
#ifdef SCP_UNIX
// /freespace works, / does not
if(token_count <= 1) {
#else
// C:/freespace works, C:/ does not
if(token_count <= 2){
#endif
return 1;
}
@@ -813,53 +818,6 @@ CFILE *cfopen_special(char *file_path, char *mode, const int size, const int off
// it's a normal file
return cf_open_fill_cfblock(fp, dir_type);
}
/* char longname[_MAX_PATH];
if ( !cfile_inited ) {
Int3();
return NULL;
}
//================================================
// Check that all the parameters make sense
Assert( file_path && strlen(file_path) );
Assert( mode != NULL );
if ( (ext_num <= 0) || (!ext_list) ) {
Int3();
return NULL;
}
// cfopen_ext() only supports reading files, not creating them
if ( strchr(mode, 'w') ) {
Int3();
return NULL;
}
//================================================
// Search for file on disk, on cdrom, or in a packfile
int offset, size;
char copy_file_path[MAX_PATH_LEN]; // FIX change in memory from cf_find_file_location
strcpy_s(copy_file_path, file_path);
if ( cf_find_file_location_ext(copy_file_path, ext_num, ext_list, dir_type, sizeof(longname) - 1, longname, &size, &offset, localize) ) {
// Fount it, now create a cfile out of it
FILE *fp = fopen( longname, "rb" );
if ( fp ) {
if ( offset ) {
// Found it in a pack file
return cf_open_packed_cfblock(fp, dir_type, offset, size );
} else {
// Found it in a normal file
return cf_open_fill_cfblock(fp, dir_type);
}
}
}
return NULL;*/
}
+4 -16
View File
@@ -136,8 +136,6 @@ Flag exe_params[] =
{ "-3dwarp", "Enable 3d warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
{ "-tbp", "Toggle features for The Babylon Project", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tbp", }, // TBP warp effects -Et1
{ "-wcsaga", "Toggle features for Wing Commander Saga", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-wcsaga", },
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
{ "-nosound", "Disable sound and music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
@@ -175,7 +173,7 @@ Flag exe_params[] =
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-timerbar", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-timerbar", },
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
@@ -335,10 +333,8 @@ int Cmdline_voice_recognition = 0;
// MOD related
cmdline_parm mod_arg("-mod", NULL, true); // Cmdline_mod -- DTP modsupport
cmdline_parm tbp("-tbp", NULL); // Cmdline_tbp -- TBP warp effects -Et1
char *Cmdline_mod = NULL; //DTP for mod arguement
int Cmdline_tbp = 0;
// Multiplayer/Network related
cmdline_parm almission_arg("-almission", NULL); // Cmdline_almission -- DTP for autoload Multi mission
@@ -920,7 +916,9 @@ bool SetCmdlineParams()
}
if (timerbar_arg.found()) {
Cmdline_timerbar = 1;
#ifdef WIN32
MessageBox(NULL, "the timerbar has been disabled in builds after August 31, 2010. Please remove the \"-timerbar\" command line from the launcher to prevent this message from appearing the the future.", "", MB_OK | MB_ICONINFORMATION);
#endif
}
if ( missioncrcspew_arg.found() ) {
@@ -1182,16 +1180,6 @@ bool SetCmdlineParams()
Cmdline_orb_radar = 1;
}
// TBP warp effects -Et1
// Chief1983 - Add 3d shockwave, ship choice 3d and weapon choice 3d if TBP is checked
if( tbp.found() )
{
Cmdline_tbp = 1;
Cmdline_enable_3d_shockwave = 1;
Cmdline_ship_choice_3d = 1;
Cmdline_weapon_choice_3d = 1;
}
if ( use_3dwarp.found() ) {
Cmdline_3dwarp = 1;
}
-2
View File
@@ -104,8 +104,6 @@ extern int Cmdline_voice_recognition;
// MOD related
extern char *Cmdline_mod; // DTP for mod support
extern int Cmdline_tbp;
// Multiplayer/Network related
extern char *Cmdline_almission; // DTP for autoload mission (for multi only)
extern int Cmdline_ingamejoin;
+3 -1
View File
@@ -922,7 +922,9 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
}
if ( fb->fireball_render_type == FIREBALL_WARP_EFFECT ) {
Assert( warp_lifetime > 4.0f ); // Warp lifetime must be at least 4 seconds!
Assert( warp_lifetime >= 4.0f ); // Warp lifetime must be at least 4 seconds!
if ( warp_lifetime < 4.0f )
warp_lifetime = 4.0f;
fb->total_time = warp_lifetime; // in seconds
} else {
fb->total_time = i2fl(fl->num_frames) / fl->fps; // in seconds
+37 -2
View File
@@ -28,6 +28,8 @@
#include "debugconsole/dbugfile.h"
#include "globalincs/mspdb_callstack.h"
#include "AFXADV.H"
#ifdef NDEBUG
#ifndef FRED
#error macro FRED is not defined when trying to build release Fred. Please define FRED macro in build settings in all Fred projects
@@ -80,12 +82,12 @@ window_data Mission_notes_wnd_data;
BEGIN_MESSAGE_MAP(CFREDApp, CWinApp)
//{{AFX_MSG_MAP(CFREDApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
@@ -236,9 +238,23 @@ BOOL CFREDApp::InitInstance()
*str_end = '\0';
// Goober5000 - figure out where the FRED file dialog should go
if ((m_pRecentFileList != NULL) && (m_pRecentFileList->GetSize() > 0))
{
// use the most recently opened file to supply the default folder
m_sInitialDir = m_pRecentFileList->operator[](0); // lol syntax
}
else
{
// use FRED's own directory to search for missions
m_sInitialDir = Fred_base_dir;
m_sInitialDir += "\\data\\missions";
}
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
ParseCommandLine(cmdInfo);
m_nCmdShow = Main_wnd_data.p.showCmd;
@@ -309,6 +325,25 @@ void CFREDApp::OnAppAbout()
aboutDlg.DoModal();
}
// G5K - from http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_20155824.html
void CFREDApp::OnFileOpen()
{
// use the initial dir the first time we prompt for a file
// name. after a successful open, the file name will be
// changed to be the empty string and the default dir
// will be supplied by the CFileDialog internal memory
if(!DoPromptFileName(m_sInitialDir, AFX_IDS_OPENFILE, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
{
// open cancelled
return;
}
AfxGetApp()->OpenDocumentFile(m_sInitialDir);
// if returns NULL, the user has already been alerted
// now erase the initial dir since we only want to use it once
m_sInitialDir.Empty();
}
/////////////////////////////////////////////////////////////////////////////
// CFREDApp commands
+2
View File
@@ -52,6 +52,7 @@ typedef struct window_data {
class CFREDApp : public CWinApp
{
int app_init;
CString m_sInitialDir;
public:
void record_window_data(window_data *wndd, CWnd *wnd);
@@ -75,6 +76,7 @@ public:
//{{AFX_MSG(CFREDApp)
afx_msg void OnAppAbout();
afx_msg void OnFileOpen();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
+9 -5
View File
@@ -2457,17 +2457,18 @@ BEGIN
WS_TABSTOP
LTEXT "Example",IDC_LBL_EXAMPLE,17,158,31,10
EDITTEXT IDC_EXAMPLE,49,156,77,12,ES_AUTOHSCROLL | ES_READONLY
CONTROL "Don't replace existing file names",IDC_NO_REPLACE,
CONTROL "Include sender name in filename",IDC_INCLUDE_SENDER,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,175,112,10
PUSHBUTTON "Generate File Names",IDC_GENERATE_FILE_NAMES,12,190,120,
14
CONTROL "Don't replace existing file names",IDC_NO_REPLACE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,186,112,10
PUSHBUTTON "Generate File Names",IDC_GENERATE_FILE_NAMES,12,198,120,14
GROUPBOX "Script Options",IDC_SCRIPT_OPTIONS,143,7,257,204
GROUPBOX "Script Entry Format",IDC_ENTRY,149,17,246,76
EDITTEXT IDC_ENTRY_FORMAT,154,28,109,56,ES_MULTILINE |
ES_AUTOHSCROLL | ES_WANTRETURN
LTEXT "$filename - name of the message file\r\n$message - text of the message\r\n$persona - persona of the sender\r\n$sender - name of the sender\r\n\r\nNote that $persona and $sender will only appear for the Message section.",
IDC_STATIC,270,28,120,58
GROUPBOX "Export",IDC_EXPORT,149,98,119,64
GROUPBOX "Export",IDC_EXPORT,149,98,119,83
CONTROL "Everything",IDC_EXPORT_EVERYTHING,"Button",
BS_AUTORADIOBUTTON,153,108,99,9
CONTROL "Just Command Briefings",IDC_EXPORT_COMMAND_BRIEFINGS,
@@ -2479,6 +2480,9 @@ BEGIN
CONTROL "Just Messages",IDC_EXPORT_MESSAGES,"Button",
BS_AUTORADIOBUTTON,153,148,99,9
PUSHBUTTON "Generate Script",IDC_GENERATE_SCRIPT,149,190,120,14
CONTROL "Group send-message-list messages before others",
IDC_GROUP_MESSAGES,"Button",BS_AUTOCHECKBOX | BS_TOP |
BS_MULTILINE | WS_TABSTOP,166,159,100,19
END
IDD_BRIEFING_PERSONAS DIALOG DISCARDABLE 0, 0, 320, 201
@@ -2559,7 +2563,7 @@ END
IDD_SOUND_ENVIRONMENT DIALOGEX 0, 0, 315, 89
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Sound Environment"
FONT 8, "MS Sans Serif"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
COMBOBOX IDC_SOUND_ENVIRONMENT,75,9,117,30,CBS_DROPDOWN |
WS_VSCROLL | WS_TABSTOP
-1
View File
@@ -188,7 +188,6 @@ int Framerate_delay;
void game_start_time(){}
void game_stop_time(){}
int game_get_default_skill_level(){return 0;}
void game_load_palette(){}
float FreeSpace_gamma;
int set_cdrom_path(int){return 0;}
int find_freespace_cd(char*){return 0;}
+3 -1
View File
@@ -1139,6 +1139,8 @@
#define IDC_SOUND_ENVIRONMENT_DECAY 1625
#define IDC_SOUND_ENVIRONMENT_BUTTON 1626
#define IDC_SOUND_ENVIRONMENT_TEST 1627
#define IDC_GROUP_MESSAGES 1628
#define IDC_INCLUDE_SENDER 1629
#define ID_FILE_MISSIONNOTES 32771
#define ID_DUPLICATE 32774
#define ID_VIEW_ROTATE 32775
@@ -1432,7 +1434,7 @@
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 320
#define _APS_NEXT_COMMAND_VALUE 33098
#define _APS_NEXT_CONTROL_VALUE 1628
#define _APS_NEXT_CONTROL_VALUE 1629
#define _APS_NEXT_SYMED_VALUE 105
#endif
#endif
+49 -1
View File
@@ -2576,6 +2576,11 @@ int sexp_tree::get_default_value(sexp_list_item *item, int op, int i)
case OPF_FONT:
str = Fonts[0].filename;
break;
case OPF_AUDIO_VOLUME_OPTION:
str = "Music";
break;
default:
str = "<new default required!>";
@@ -2660,6 +2665,9 @@ int sexp_tree::query_default_argument_available(int op, int i)
case OPF_HUD_ELEMENT:
case OPF_SOUND_ENVIRONMENT:
case OPF_SOUND_ENVIRONMENT_OPTION:
case OPF_EXPLOSION_OPTION:
case OPF_AUDIO_VOLUME_OPTION:
case OPF_WEAPON_BANK_NUMBER:
return 1;
case OPF_SHIP:
@@ -4369,6 +4377,18 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
list = get_listing_opf_sound_environment_option();
break;
case OPF_AUDIO_VOLUME_OPTION:
list = get_listing_opf_adjust_audio_volume();
break;
case OPF_EXPLOSION_OPTION:
list = get_listing_opf_explosion_option();
break;
case OPF_WEAPON_BANK_NUMBER:
list = get_listing_opf_weapon_banks();
break;
default:
Int3(); // unknown OPF code
list = NULL;
@@ -5234,6 +5254,26 @@ sexp_list_item *sexp_tree::get_listing_opf_sound_environment_option()
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_adjust_audio_volume()
{
sexp_list_item head;
for (int i = 0; i < Num_adjust_audio_options; i++)
head.add_data(Adjust_audio_options[i]);
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_explosion_option()
{
sexp_list_item head;
for (int i = 0; i < Num_explosion_options; i++)
head.add_data(Explosion_option[i]);
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_waypoint_path()
{
int i;
@@ -5464,7 +5504,7 @@ sexp_list_item *sexp_tree::get_listing_opf_string()
{
sexp_list_item head;
head.add_data("<any string>");
head.add_data(SEXP_ANY_STRING);
return head.next;
}
@@ -5731,6 +5771,14 @@ sexp_list_item *sexp_tree::get_listing_opf_hud_elements()
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_weapon_banks()
{
sexp_list_item head;
head.add_data(SEXP_ALL_BANKS_STRING);
return head.next;
}
// Deletes sexp_variable from sexp_tree.
// resets tree to not include given variable, and resets text and type
void sexp_tree::delete_sexp_tree_variable(const char *var_name)
+3
View File
@@ -260,6 +260,9 @@ public:
sexp_list_item *get_listing_opf_hud_elements();
sexp_list_item *get_listing_opf_sound_environment();
sexp_list_item *get_listing_opf_sound_environment_option();
sexp_list_item *get_listing_opf_explosion_option();
sexp_list_item *get_listing_opf_adjust_audio_volume();
sexp_list_item *get_listing_opf_weapon_banks();
int m_mode;
int item_index;
+317 -55
View File
@@ -2,14 +2,18 @@
//
#include "stdafx.h"
#include <string.h>
#include "fred.h"
#include "fred2/freddoc.h"
#include "VoiceActingManager.h"
#include "missionui/missioncmdbrief.h"
#include "mission/missionbriefcommon.h"
#include "mission/missionmessage.h"
#include "mission/missiongoals.h"
#include "hud/hudtarget.h"
#include "parse/sexp.h"
#include "iff_defs/iff_defs.h"
#include "mission/missiongoals.h"
#include <math.h>
#ifdef _DEBUG
@@ -18,6 +22,8 @@
static char THIS_FILE[] = __FILE__;
#endif
#define INVALID_MESSAGE ((MMessage*)0xFFFFFFFF)
// to keep track of data
char Voice_abbrev_briefing[NAME_LENGTH];
char Voice_abbrev_campaign[NAME_LENGTH];
@@ -28,6 +34,7 @@ char Voice_abbrev_mission[NAME_LENGTH];
bool Voice_no_replace_filenames;
char Voice_script_entry_format[NOTES_LENGTH];
int Voice_export_selection;
bool Voice_group_messages;
/////////////////////////////////////////////////////////////////////////////
@@ -44,6 +51,7 @@ VoiceActingManager::VoiceActingManager(CWnd* pParent /*=NULL*/)
m_abbrev_debriefing = _T("");
m_abbrev_message = _T("");
m_abbrev_mission = _T("");
m_use_sender_in_filename = FALSE;
m_example = _T("");
m_no_replace = FALSE;
m_script_entry_format = _T("");
@@ -52,6 +60,7 @@ VoiceActingManager::VoiceActingManager(CWnd* pParent /*=NULL*/)
m_export_briefings = FALSE;
m_export_debriefings = FALSE;
m_export_messages = FALSE;
m_group_messages = FALSE;
//}}AFX_DATA_INIT
}
@@ -68,12 +77,14 @@ void VoiceActingManager::DoDataExchange(CDataExchange* pDX)
DDX_Text(pDX, IDC_ABBREV_MISSION, m_abbrev_mission);
DDX_Text(pDX, IDC_EXAMPLE, m_example);
DDX_Check(pDX, IDC_NO_REPLACE, m_no_replace);
DDX_Check(pDX, IDC_INCLUDE_SENDER, m_use_sender_in_filename);
DDX_Text(pDX, IDC_ENTRY_FORMAT, m_script_entry_format);
DDX_Check(pDX, IDC_EXPORT_EVERYTHING, m_export_everything);
DDX_Check(pDX, IDC_EXPORT_COMMAND_BRIEFINGS, m_export_command_briefings);
DDX_Check(pDX, IDC_EXPORT_BRIEFINGS, m_export_briefings);
DDX_Check(pDX, IDC_EXPORT_DEBRIEFINGS, m_export_debriefings);
DDX_Check(pDX, IDC_EXPORT_MESSAGES, m_export_messages);
DDX_Check(pDX, IDC_GROUP_MESSAGES, m_group_messages);
//}}AFX_DATA_MAP
}
@@ -98,6 +109,12 @@ BEGIN_MESSAGE_MAP(VoiceActingManager, CDialog)
ON_BN_CLICKED(IDC_NO_REPLACE, OnChangeNoReplace)
ON_BN_CLICKED(IDC_GENERATE_FILE_NAMES, OnGenerateFileNames)
ON_BN_CLICKED(IDC_GENERATE_SCRIPT, OnGenerateScript)
ON_BN_CLICKED(IDC_EXPORT_EVERYTHING, OnExportEverything)
ON_BN_CLICKED(IDC_EXPORT_COMMAND_BRIEFINGS, OnExportCommandBriefings)
ON_BN_CLICKED(IDC_EXPORT_BRIEFINGS, OnExportBriefings)
ON_BN_CLICKED(IDC_EXPORT_DEBRIEFINGS, OnExportDebriefings)
ON_BN_CLICKED(IDC_EXPORT_MESSAGES, OnExportMessages)
ON_BN_CLICKED(IDC_INCLUDE_SENDER, OnBnClickedIncludeSender)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
@@ -133,6 +150,10 @@ BOOL VoiceActingManager::OnInitDialog()
m_export_messages = TRUE;
else
m_export_everything = TRUE;
m_group_messages = Voice_group_messages;
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(m_export_everything || m_export_messages);
UpdateData(FALSE);
@@ -150,7 +171,7 @@ void VoiceActingManager::OnClose()
strcpy_s(Voice_abbrev_debriefing, m_abbrev_debriefing);
strcpy_s(Voice_abbrev_message, m_abbrev_message);
strcpy_s(Voice_abbrev_mission, m_abbrev_mission);
Voice_no_replace_filenames = m_no_replace == TRUE ? true : false;
Voice_no_replace_filenames = (m_no_replace == TRUE) ? true : false;
// save data for script
strcpy_s(Voice_script_entry_format, m_script_entry_format);
@@ -164,6 +185,7 @@ void VoiceActingManager::OnClose()
Voice_export_selection = 4;
else
Voice_export_selection = 0;
Voice_group_messages = (m_group_messages == TRUE) ? true : false;
CDialog::OnClose();
}
@@ -213,10 +235,10 @@ void VoiceActingManager::build_example(CString section)
return;
}
m_example = generate_filename(section, 1, 2);
m_example = generate_filename(section, 1, 2, INVALID_MESSAGE);
}
CString VoiceActingManager::generate_filename(CString section, int number, int digits)
CString VoiceActingManager::generate_filename(CString section, int number, int digits, MMessage *message)
{
if (section == "")
return "none.wav";
@@ -241,9 +263,52 @@ CString VoiceActingManager::generate_filename(CString section, int number, int d
}
str = str + num;
const CString suffix = get_suffix();
// append sender name if supposed to and I have been passed a message
// to get the sender from
if ( message != NULL && m_use_sender_in_filename ) {
size_t allow_to_copy = NAME_LENGTH - suffix.GetLength() - str.GetLength();
char sender[NAME_LENGTH];
if ( message == INVALID_MESSAGE ) {
strcpy_s(sender, "Alpha 1");
} else {
get_valid_sender(sender, sizeof(sender), message);
}
// truncate sender to that we don't overflow filename
sender[allow_to_copy] = '\0';
size_t j;
for( j = 0; sender[j] != '\0'; j++ ) {
// lower case letter
sender[j] = (char)tolower(sender[j]);
// replace any non alpha numeric with a underscore
if ( !isalnum( sender[j] ) )
sender[j] = '_';
}
// flatten muliple underscores
j = 1;
while( sender[j] != '\0' ) {
if ( sender[j-1] == '_' && sender[j] == '_' ) {
size_t k;
for (k = j + 1; sender[k] != '\0'; k++ )
sender[k - 1] = sender[k];
sender[k - 1] = '\0';
} else {
// only increment on rounds when I am not moving the string down
j++;
}
}
str = str + sender;
}
// suffix
str = str + get_suffix();
Assert( str.GetLength() < NAME_LENGTH );
return str;
}
@@ -251,6 +316,7 @@ void VoiceActingManager::OnGenerateFileNames()
{
int i;
int digits;
size_t modified_filenames = 0;
// stuff data to variables
UpdateData(TRUE);
@@ -262,9 +328,10 @@ void VoiceActingManager::OnGenerateFileNames()
char *filename = Cmd_briefs[0].stage[i].wave_filename;
// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || !strnicmp(filename, "none.wav", 4) || message_filename_is_generic(filename))
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_command_briefing, i + 1, digits)));
modified_filenames++;
}
}
@@ -275,9 +342,10 @@ void VoiceActingManager::OnGenerateFileNames()
char *filename = Briefings[0].stages[i].voice;
// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || !strnicmp(filename, "none.wav", 4) || message_filename_is_generic(filename))
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_briefing, i + 1, digits)));
modified_filenames++;
}
}
@@ -288,9 +356,10 @@ void VoiceActingManager::OnGenerateFileNames()
char *filename = Debriefings[0].stages[i].voice;
// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || !strnicmp(filename, "none.wav", 4) || message_filename_is_generic(filename))
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_debriefing, i + 1, digits)));
modified_filenames++;
}
}
@@ -299,21 +368,30 @@ void VoiceActingManager::OnGenerateFileNames()
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
{
char *filename = Messages[i + Num_builtin_messages].wave_info.name;
MMessage *message = &Messages[i + Num_builtin_messages];
// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !filename || !strlen(filename) || !strnicmp(filename, "none.wav", 4) || message_filename_is_generic(filename))
if (!m_no_replace || !strlen(filename) || !strlen(filename) || message_filename_is_generic(filename))
{
// free existing filename
if (filename != NULL)
free(filename);
// allocate new filename
Messages[i + Num_builtin_messages].wave_info.name = strdup(LPCTSTR(generate_filename(m_abbrev_message, i + 1, digits)));
Messages[i + Num_builtin_messages].wave_info.name = strdup(LPCTSTR(generate_filename(m_abbrev_message, i + 1, digits, message)));
modified_filenames++;
}
}
// notify
MessageBox("File name generation complete.", "Woohoo!");
if ( modified_filenames > 0 ) {
// Tell FRED that we actually modified something
set_modified(TRUE);
}
// notify user that we are done and how many filenames were changed
char message[128] = { '\0' };
snprintf(message, sizeof(message), "File name generation complete. Modified %d messages.", modified_filenames);
MessageBox(message, "Woohoo!");
}
void VoiceActingManager::OnGenerateScript()
@@ -402,56 +480,27 @@ void VoiceActingManager::OnGenerateScript()
{
fout("\n\nMessages\n--------\n\n");
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
if (m_group_messages)
{
CString entry = m_script_entry_format;
entry.Replace("\r\n", "\n");
SCP_vector<int> message_indexes;
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
message_indexes.push_back(i + Num_builtin_messages);
MMessage *message = &Messages[i + Num_builtin_messages];
group_message_indexes(message_indexes);
// replace file name
entry.Replace("$filename", message->wave_info.name);
// determine and replace persona
entry.Replace("$message", message->message);
if (message->persona_index >= 0)
entry.Replace("$persona", Personas[message->persona_index].name);
else
entry.Replace("$persona", "<none>");
// determine sender
char sender[NAME_LENGTH+1];
strcpy_s(sender, get_message_sender(message->name));
int shipnum = ship_name_lookup(sender);
if (shipnum >= 0)
for (i = 0; i < message_indexes.size(); i++)
{
ship *shipp = &Ships[shipnum];
// we may have to use the callsign
if (*Fred_callsigns[shipnum])
{
hud_stuff_ship_callsign(sender, shipp);
}
// account for hidden ship names
else if ( ((Iff_info[shipp->team].flags & IFFF_WING_NAME_HIDDEN) && (shipp->wingnum != -1)) || (shipp->flags2 & SF2_HIDE_SHIP_NAME) )
{
hud_stuff_ship_class(sender, shipp);
}
// use the regular sender text
else
{
end_string_at_first_hash_symbol(sender);
}
MMessage *message = &Messages[message_indexes[i]];
export_one_message(message);
}
}
else
{
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
{
MMessage *message = &Messages[i + Num_builtin_messages];
export_one_message(message);
}
// replace sender (but print #Command as Command)
if (*sender == '#')
entry.Replace("$sender", &sender[1]);
else
entry.Replace("$sender", sender);
fout("%s\n\n\n", (char *) (LPCTSTR) entry);
}
}
@@ -461,6 +510,76 @@ void VoiceActingManager::OnGenerateScript()
MessageBox("Script generation complete.", "Woohoo!");
}
void VoiceActingManager::export_one_message(MMessage *message)
{
CString entry = m_script_entry_format;
entry.Replace("\r\n", "\n");
// replace file name
entry.Replace("$filename", message->wave_info.name);
// determine and replace persona
entry.Replace("$message", message->message);
if (message->persona_index >= 0)
entry.Replace("$persona", Personas[message->persona_index].name);
else
entry.Replace("$persona", "<none>");
// determine sender
char sender[NAME_LENGTH+1];
get_valid_sender(sender, sizeof(sender), message);
// replace sender (but print #Command as Command)
if (*sender == '#')
entry.Replace("$sender", &sender[1]);
else
entry.Replace("$sender", sender);
fout("%s\n\n\n", (char *) (LPCTSTR) entry);
}
/** Passed sender string will have either have the senders name
or '<none>'*/
void VoiceActingManager::get_valid_sender(char *sender, size_t sender_size, MMessage *message) {
Assert( sender != NULL );
Assert( message != NULL );
strncpy(sender, get_message_sender(message->name), sender_size);
// strip hash if present
if ( sender[0] == '#' ) {
size_t i = 1;
for(; sender[i] != '\0'; i++ ) {
sender[i-1] = sender[i];
}
sender[i-1] = '\0';
}
int shipnum = ship_name_lookup(sender, 1); // The player's ship is valid for this search.
if (shipnum >= 0)
{
ship *shipp = &Ships[shipnum];
// we may have to use the callsign
if (*Fred_callsigns[shipnum])
{
hud_stuff_ship_callsign(sender, shipp);
}
// account for hidden ship names
else if ( ((Iff_info[shipp->team].flags & IFFF_WING_NAME_HIDDEN) && (shipp->wingnum != -1)) || (shipp->flags2 & SF2_HIDE_SHIP_NAME) )
{
hud_stuff_ship_class(sender, shipp);
}
// use the regular sender text
else
{
end_string_at_first_hash_symbol(sender);
}
}
}
void VoiceActingManager::OnSetfocusAbbrevBriefing()
{
UpdateData(TRUE);
@@ -667,3 +786,146 @@ char *VoiceActingManager::get_message_sender(char *message)
return "<none>";
}
void VoiceActingManager::group_message_indexes(SCP_vector<int> &message_indexes)
{
int i;
#ifndef NDEBUG
int initial_size = message_indexes.size();
#endif
SCP_vector<int> temp_message_indexes = message_indexes;
message_indexes.clear();
// add all messages found in send-message-list or send-random-message node trees
for (i = 0; i < Num_mission_events; i++)
{
mission_event *event = &Mission_events[i];
group_message_indexes_in_tree(event->formula, temp_message_indexes, message_indexes);
}
// add remaining messages
for (i = 0; i < temp_message_indexes.size(); i++)
message_indexes.push_back(temp_message_indexes[i]);
#ifndef NDEBUG
if (initial_size > message_indexes.size())
{
Warning(LOCATION, "Initial size is greater than size after sorting!");
}
else if (initial_size < message_indexes.size())
{
Warning(LOCATION, "Initial size is less than size after sorting!");
}
#endif
}
void VoiceActingManager::group_message_indexes_in_tree(int node, SCP_vector<int> &source_list, SCP_vector<int> &destination_list)
{
int i, op, n;
if (node < 0)
return;
if (Sexp_nodes[node].type == SEXP_NOT_USED)
return;
// stuff
op = get_operator_const(Sexp_nodes[node].text);
n = CDR(node);
if (op == OP_SEND_MESSAGE_LIST)
{
// check the argument list
while (n != -1)
{
// the third argument is a message
char *message_name = Sexp_nodes[CDDR(n)].text;
// check source messages
for (i = 0; i < source_list.size(); i++)
{
if (!strcmp(message_name, Messages[source_list[i]].name))
{
// move it from source to destination
destination_list.push_back(source_list[i]);
source_list.erase(source_list.begin() + i);
break;
}
}
// iterate along the list
n = CDDDDR(n);
}
}
else if (op == OP_SEND_RANDOM_MESSAGE)
{
// check the argument list
n = CDDR(n);
while (n != -1)
{
// each argument from this point on is a message
char *message_name = Sexp_nodes[n].text;
// check source messages
for (i = 0; i < source_list.size(); i++)
{
if (!strcmp(message_name, Messages[source_list[i]].name))
{
// move it from source to destination
destination_list.push_back(source_list[i]);
source_list.erase(source_list.begin() + i);
break;
}
}
// iterate along the list
n = CDR(n);
}
}
// iterate on first element
group_message_indexes_in_tree(CAR(node), source_list, destination_list);
// iterate on rest of elements
group_message_indexes_in_tree(CDR(node), source_list, destination_list);
}
void VoiceActingManager::OnExportEverything()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(TRUE);
}
void VoiceActingManager::OnExportCommandBriefings()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(FALSE);
}
void VoiceActingManager::OnExportBriefings()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(FALSE);
}
void VoiceActingManager::OnExportDebriefings()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(FALSE);
}
void VoiceActingManager::OnExportMessages()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(TRUE);
}
void VoiceActingManager::OnBnClickedIncludeSender()
{
UpdateData(TRUE);
build_example();
UpdateData(FALSE);
}
+15 -1
View File
@@ -7,6 +7,8 @@
// VoiceActingManager.h : header file
//
#include "mission/missionmessage.h"
/////////////////////////////////////////////////////////////////////////////
// VoiceActingManager dialog
@@ -25,6 +27,7 @@ public:
CString m_abbrev_debriefing;
CString m_abbrev_message;
CString m_abbrev_mission;
BOOL m_use_sender_in_filename;
CString m_example;
BOOL m_no_replace;
CString m_script_entry_format;
@@ -33,6 +36,7 @@ public:
BOOL m_export_briefings;
BOOL m_export_debriefings;
BOOL m_export_messages;
BOOL m_group_messages;
//}}AFX_DATA
@@ -50,8 +54,12 @@ protected:
int calc_digits(int size);
void build_example();
void build_example(CString section);
CString generate_filename(CString section, int number, int digits);
CString generate_filename(CString section, int number, int digits, MMessage *message=NULL);
char *get_message_sender(char *message);
void export_one_message(MMessage *message);
void get_valid_sender(char *sender, size_t sender_size, MMessage *message);
void group_message_indexes(SCP_vector<int> &message_indexes);
void group_message_indexes_in_tree(int node, SCP_vector<int> &source_list, SCP_vector<int> &destination_list);
CFILE *fp;
int fout(char *format, ...);
@@ -77,6 +85,12 @@ protected:
afx_msg void OnChangeNoReplace();
afx_msg void OnGenerateFileNames();
afx_msg void OnGenerateScript();
afx_msg void OnExportEverything();
afx_msg void OnExportCommandBriefings();
afx_msg void OnExportBriefings();
afx_msg void OnExportDebriefings();
afx_msg void OnExportMessages();
afx_msg void OnBnClickedIncludeSender();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
+5 -39
View File
@@ -1132,8 +1132,7 @@ void game_level_init(int seed)
supernova_level_init();
cam_init();
subtitles_init();
snd_aav_init();
// multiplayer dogfight hack
dogfight_blown = 0;
@@ -1193,32 +1192,6 @@ void game_do_networking()
}
}
// Loads the best palette for this level, based
// on nebula color and hud color. You could just call palette_load_table with
// the appropriate filename, but who wants to do that.
void game_load_palette()
{
char palette_filename[1024];
// We only use 3 hud colors right now
// Assert( HUD_config.color >= 0 );
// Assert( HUD_config.color <= 2 );
Assert( Mission_palette >= 0 );
Assert( Mission_palette <= 98 );
// if ( The_mission.flags & MISSION_FLAG_SUBSPACE ) {
strcpy_s( palette_filename, NOX("gamepalette-subspace") );
// } else {
// sprintf( palette_filename, NOX("gamepalette%d-%02d"), HUD_config.color+1, Mission_palette+1 );
// }
mprintf(( "Loading palette %s\n", palette_filename ));
// palette_load_table(palette_filename);
}
// An estimate as to how high the count passed to game_loading_callback will go.
// This is just a guess, it seems to always be about the same. The count is
// proportional to the code being executed, not the time, so this works good
@@ -1265,7 +1238,7 @@ void game_loading_callback(int count)
game_do_networking();
Assert( Game_loading_callback_inited==1 );
Assert( Game_loading_ani.num_frames > 0 );
Assertion( Game_loading_ani.num_frames > 0, "Load Screen animation %s not found, or corrupted. Needs to be an animation with at least 1 frame.", Game_loading_ani.filename );
int do_flip = 0;
@@ -1382,7 +1355,7 @@ void game_loading_callback_init()
strcpy(Game_loading_ani.filename, Game_loading_ani_fname[gr_screen.res]);
generic_anim_init(&Game_loading_ani, Game_loading_ani.filename);
generic_anim_load(&Game_loading_ani);
Assert( Game_loading_ani.num_frames > 0 );
Assertion( Game_loading_ani.num_frames > 0, "Load Screen animation %s not found, or corrupted. Needs to be an animation with at least 1 frame.", Game_loading_ani.filename );
Game_loading_callback_inited = 1;
Mouse_hidden = 1;
@@ -1617,14 +1590,6 @@ int game_start_mission()
extern void stop_parse();
stop_parse();
//WMC - *sigh* more mprintf clutter. It was commented out when I got here
/*
// the standalone server in multiplayer doesn't do any rendering, so we will not even bother loading the palette
if ( !(Game_mode & GM_STANDALONE_SERVER) ) {
mprintf(( "=================== LOADING GAME PALETTE ================\n" ));
// game_load_palette();
}*/
game_busy( NOX("** starting game_post_level_init() **") );
load_post_level_init = (uint) time(NULL);
game_post_level_init();
@@ -5022,7 +4987,7 @@ void game_set_frametime(int state)
}
#endif
Assert( Framerate_cap > 0 );
Assertion( Framerate_cap > 0, "Framerate cap %d is too low. Needs to be a positive, non-zero number", Framerate_cap );
// Cap the framerate so it doesn't get too high.
if (!Cmdline_NoFPSCap)
@@ -6095,6 +6060,7 @@ void game_leave_state( int old_state, int new_state )
if ( (Game_mode & GM_MULTIPLAYER) && (new_state == GS_STATE_MAIN_MENU) ){
multi_quit_game(PROMPT_NONE);
}
snd_aav_init();
freespace_stop_mission();
}
-5
View File
@@ -192,11 +192,6 @@ void big_explosion_flash(float flash);
// flash effect to 0.
void game_flash_diminish();
// Loads the best palette for this level, based
// on nebula color and hud color. You could just call palette_load_table with
// the appropriate filename, but who wants to do that.
void game_load_palette();
//================================================================
// Call at the beginning of each frame
+75 -38
View File
@@ -66,7 +66,8 @@ static bool do_full_packet = true;
static int Local_timeout = -1;
static int Next_gameserver_update = -1;
static int Last_pong = -1;
static int Ping_timestamp = -1;
static int Last_activity = -1;
static int Login_retry_time = -1;
static SCP_vector<file_record> FS2NetD_file_list;
@@ -92,7 +93,8 @@ static void fs2netd_reset_state()
do_full_packet = true;
Local_timeout = -1;
Next_gameserver_update = -1;
Last_pong = -1;
Last_activity = -1;
Ping_timestamp = -1;
Duplicate_login_detected = false;
Login_retry_time = -1;
}
@@ -167,19 +169,38 @@ void fs2netd_reset_connection()
FS2NetD_Disconnect();
// wait a little to allow for the port to clear
Sleep(250);
fs2netd_reset_state();
// wait a little to allow for the port to clear
Sleep(500);
// try to reinit the server connection
fs2netd_login();
if (reset_gameserver) {
Sleep(250);
if ( reset_gameserver && fs2netd_is_online() ) {
fs2netd_gameserver_start();
}
}
void fs2netd_disconnect()
{
if ( !Is_connected ) {
return;
}
if (Net_player->flags & NETINFO_FLAG_MT_CONNECTED) {
fs2netd_gameserver_disconnect();
}
FS2NetD_Disconnect();
fs2netd_reset_state();
Sleep(500);
}
static int fs2netd_connect_do()
{
int retval = FS2NetD_ConnectToServer(Multi_options_g.game_tracker_ip, Multi_options_g.tracker_port);
@@ -307,6 +328,10 @@ int fs2netd_login_do()
return 2;
}
if (do_full_packet) {
ml_printf("FS2NetD MSG: Requesting login pilot stats for '%s' ...", Players[Player_num].callsign);
}
int rescode = FS2NetD_GetPlayerData(Players[Player_num].callsign, &Players[Player_num], true, do_full_packet);
do_full_packet = false;
@@ -469,6 +494,9 @@ bool fs2netd_login()
if (retval) {
Logged_in = true;
sprintf(Multi_tracker_id_string, "%d", Multi_tracker_id);
} else {
// clear and reset connection, for the next time we try...
fs2netd_disconnect();
}
if (Is_standalone) {
@@ -480,11 +508,13 @@ bool fs2netd_login()
static void fs2netd_handle_ping()
{
static int Next_ping = -1;
bool reset = false;
static int CONN_check = -1;
// if we didn't get a pong within 30 seconds of a ping then assume that the
// server connection must of have dropped or is otherwise unresponsive
if ( (Ping_timestamp != -1) && ((timer_get_seconds() - Ping_timestamp) > 30) ) {
Ping_timestamp = -1;
// if we didn't get a PONG within 4 minutes the server connection must have dropped
if ( (Last_pong != -1) && ((Next_ping - Last_pong) > 240) ) {
ml_string("FS2NetD WARNING: Lost connection to server!");
fs2netd_reset_connection();
@@ -496,11 +526,11 @@ static void fs2netd_handle_ping()
}
ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!");
FS2NetD_Disconnect();
fs2netd_reset_state();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 30 minutes...");
Login_retry_time = timer_get_seconds() + 1800;
fs2netd_disconnect();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes...");
Login_retry_time = timer_get_seconds() + 300;
return;
} else {
@@ -508,24 +538,24 @@ static void fs2netd_handle_ping()
}
}
// send out ping every 90 seconds
if ( (Next_ping == -1) || (timer_get_seconds() >= Next_ping) ) {
// if we have seen a long period of time between pings then reset the pong time too
if ( (timer_get_seconds() - Next_ping) > 120 ) {
reset = true;
}
Next_ping = timer_get_seconds() + 90;
// we go ahead and set the initial Last_pong here, even though we haven't gotten a pong yet
if ( (Last_pong == -1) || reset ) {
Last_pong = Next_ping;
reset = false;
}
// send out a ping after 5 minutes of no other activity to make sure the server
// is still responding (probably not though)
if ( (Ping_timestamp == -1) && (timer_get_seconds() >= (Last_activity + 300)) ) {
Ping_timestamp = timer_get_seconds();
FS2NetD_Ping();
ml_string("FS2NetD sent PING");
// also send out a ID check to keep our login verified
if (Last_activity < 0) {
Last_activity = timer_get_seconds();
}
}
// check for a valid connection (SID, duplicate login, etc.)
if ( (CONN_check == -1) || (timer_get_seconds() >= CONN_check) ) {
// every 3 minutes
CONN_check = timer_get_seconds() + 180;
// session ID check
if ( FS2NetD_CheckValidID() < 0 ) {
ml_string("FS2NetD WARNING: Unable to validate login!");
fs2netd_reset_connection();
@@ -538,11 +568,11 @@ static void fs2netd_handle_ping()
}
ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!");
FS2NetD_Disconnect();
fs2netd_reset_state();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 30 minutes...");
Login_retry_time = timer_get_seconds() + 1800;
fs2netd_disconnect();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes...");
Login_retry_time = timer_get_seconds() + 300;
return;
} else {
@@ -555,7 +585,7 @@ static void fs2netd_handle_ping()
FS2NetD_CheckDuplicateLogin();
}
ml_string("FS2NetD sent PING/IDENT");
ml_string("FS2NetD sent IDENT check");
}
}
@@ -584,6 +614,8 @@ static void fs2netd_handle_messages()
return;
}
Last_activity = timer_get_seconds();
buffer_offset = 0;
while (buffer_offset+BASE_PACKET_SIZE <= bytes_read) {
@@ -612,7 +644,8 @@ static void fs2netd_handle_messages()
ml_printf("FS2NetD PONG: %d ms", timer_get_milliseconds() - itemp);
Last_pong = timer_get_seconds();
// reset timestamp, since the ping was successful
Ping_timestamp = -1;
break;
}
@@ -739,8 +772,8 @@ void fs2netd_do_frame()
fs2netd_login();
if ( !Logged_in ) {
// bah! try again in another 30 minutes
Login_retry_time = timer_get_seconds() + 1800;
// bah! try again in another 5 minutes
Login_retry_time = timer_get_seconds() + 300;
} else {
Login_retry_time = -1;
}
@@ -1550,6 +1583,10 @@ int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_cal
In_process = true;
}
if (first_call) {
ml_printf("FS2NetD MSG: Requesting pilot stats for '%s' ...", callsign);
}
int rc = FS2NetD_GetPlayerData(callsign, &new_plr, false, first_call);
// some sort of failure
+1
View File
@@ -47,6 +47,7 @@ extern tracker_game_data Multi_tracker_game_data;
bool fs2netd_is_online();
void fs2netd_reset_connection();
void fs2netd_disconnect();
void fs2netd_close();
+2 -2
View File
@@ -265,8 +265,8 @@ int FS2NetD_GetPlayerData(const char *player_name, player *pl, bool can_create,
PXO_GET_DATA( reply_type );
// if we weren't retrieved or created then bail out now
if (reply_type > 1) {
// if we weren't retrieved then bail out now
if (reply_type != 0) {
return (int)reply_type;
}
+4 -8
View File
@@ -368,17 +368,13 @@ void help_overlay_init()
{
// load right_bracket bitmap
help_right_bracket_bitmap = bm_load("right_bracket");
if(help_right_bracket_bitmap < 0){
// we failed to load the bitmap - this is very bad
Int3();
}
// we failed to load the bitmap - this is very bad
Assertion( help_right_bracket_bitmap >= 0, "Failed to load bitmap right_bracket for help overlay\n");
// load left_bracket bitmap
help_left_bracket_bitmap = bm_load("left_bracket");
if(help_left_bracket_bitmap < 0){
// we failed to load the bitmap - this is very bad
Int3();
}
// we failed to load the bitmap - this is very bad
Assertion( help_left_bracket_bitmap >= 0, "Failed to load bitmap left_bracket for help overlay\n");
atexit(close_help);
// parse help.tbl
+7 -11
View File
@@ -407,7 +407,7 @@ void event_music_force_switch()
return; // invalid pattern
Assert(new_pattern >= 0 && new_pattern < MAX_PATTERNS);
audiostream_play(Patterns[new_pattern].handle, Master_event_music_volume, 0); // no looping
audiostream_play(Patterns[new_pattern].handle, (Master_event_music_volume * aav_music_volume), 0); // no looping
audiostream_set_sample_cutoff(Patterns[new_pattern].handle, fl2i(Patterns[new_pattern].num_measures * Patterns[new_pattern].samples_per_measure) );
Patterns[Current_pattern].next_pattern = Patterns[Current_pattern].default_next_pattern;
Patterns[Current_pattern].force_pattern = FALSE;
@@ -440,7 +440,7 @@ void event_music_do_frame()
if ( Current_pattern != -1 && Patterns[Current_pattern].handle >= 0) {
//WMC - removed in favor of if
//Assert(Patterns[Current_pattern].handle >= 0 );
audiostream_play(Patterns[Current_pattern].handle, Master_event_music_volume, 0); // no looping
audiostream_play(Patterns[Current_pattern].handle, (Master_event_music_volume * aav_music_volume), 0); // no looping
audiostream_set_sample_cutoff(Patterns[Current_pattern].handle, fl2i(Patterns[Current_pattern].num_measures * Patterns[Current_pattern].samples_per_measure) );
}
}
@@ -462,7 +462,7 @@ void event_music_do_frame()
audiostream_stop(pat->handle); // stop current and rewind
pat->loop_for--;
if ( pat->loop_for > 0 ) {
audiostream_play(pat->handle, Master_event_music_volume, 0); // no looping
audiostream_play(pat->handle, (Master_event_music_volume * aav_music_volume), 0); // no looping
audiostream_set_sample_cutoff(Patterns[Current_pattern].handle, fl2i(Patterns[Current_pattern].num_measures * Patterns[Current_pattern].samples_per_measure) );
}
else {
@@ -924,7 +924,7 @@ int event_music_friendly_arrival()
// Goober5000 - I didn't touch this part... for some reason, FS2 only has one
// arrival music pattern, and this is it
Assert(Patterns[SONG_AARV_1].handle >= 0 );
audiostream_play(Patterns[SONG_AARV_1].handle, Master_event_music_volume, 0); // no looping
audiostream_play(Patterns[SONG_AARV_1].handle, (Master_event_music_volume * aav_music_volume), 0); // no looping
audiostream_set_sample_cutoff(Patterns[SONG_AARV_1].handle, fl2i(Patterns[SONG_AARV_1].num_measures * Patterns[SONG_AARV_1].samples_per_measure) );
}
// don't overlay
@@ -1198,9 +1198,7 @@ void parse_soundtrack()
}
//Track doesn't exist and has nocreate, so don't create it
if ( !skip_to_start_of_string_either("#SoundTrack Start", "#Menu Music Start") && !skip_to_string("#SoundTrack End")) {
Int3();
}
Assertion(skip_to_start_of_string_either("#SoundTrack Start", "#Menu Music Start") || skip_to_string("#SoundTrack End"), "Couldn't find #Soundtrack Start, #Menu Music Start or #Soundtrack End. Music.tbl or -mus.tbm is invalid.\n");
return;
}
@@ -1336,9 +1334,7 @@ void parse_menumusic()
Warning(LOCATION, "Could not load spooled music file after '%s' as maximum number of spooled music was reached (Max is %d)", Spooled_music[Num_music_files - 1].name, MAX_SPOOLED_MUSIC);
}
if(!skip_to_start_of_string_either("$Name:", "#Menu Music End")) {
Int3();
}
Assertion(skip_to_start_of_string_either("$Name:", "#Menu Music End"), "Couldn't find $Name or #Menu Music End. Music.tbl or -mus.tbm is invalid.\n");
return;
}
@@ -1591,7 +1587,7 @@ void event_music_unpause()
Assert( Current_pattern >= 0 && Current_pattern < MAX_PATTERNS );
if ( audiostream_is_paused(Patterns[Current_pattern].handle) == TRUE ) {
audiostream_play(Patterns[Current_pattern].handle, Master_event_music_volume, 0); // no looping
audiostream_play(Patterns[Current_pattern].handle, (Master_event_music_volume * aav_music_volume), 0); // no looping
audiostream_set_sample_cutoff(Patterns[Current_pattern].handle, fl2i(Patterns[Current_pattern].num_measures * Patterns[Current_pattern].samples_per_measure) );
}
}
+84 -68
View File
@@ -14,14 +14,13 @@
#include "species_defs/species_defs.h"
#include "parse/parselo.h"
#include "sound/ds.h"
#include <limits.h>
int Num_game_sounds = 0;
game_snd *Snds = NULL;
SCP_vector<game_snd> Snds;
int Num_iface_sounds = 0;
game_snd *Snds_iface = NULL;
int *Snds_iface_handle = NULL;
SCP_vector<game_snd> Snds_iface;
SCP_vector<int> Snds_iface_handle;
#define GAME_SND 0
#define IFACE_SND 1
@@ -39,7 +38,8 @@ void gamesnd_play_iface(int n)
//WMC - now ignores file extension.
int gamesnd_get_by_name(char* name)
{
for(int i = 0; i < Num_game_sounds; i++)
Assert( Snds.size() <= INT_MAX );
for(int i = 0; i < (int)Snds.size(); i++)
{
char *p = strrchr( Snds[i].filename, '.' );
if(p == NULL)
@@ -57,6 +57,31 @@ int gamesnd_get_by_name(char* name)
return -1;
}
int gamesnd_get_by_tbl_index(int index)
{
Assert( Snds.size() <= INT_MAX );
for(int i = 0; i < (int)Snds.size(); i++) {
if ( Snds[i].sig == index )
{
return i;
}
}
return -1;
}
int gamesnd_get_by_iface_tbl_index(int index)
{
Assert( Snds_iface.size() <= INT_MAX );
Assert( Snds_iface.size() == Snds_iface_handle.size() );
for(int i = 0; i < (int)Snds_iface.size(); i++) {
if ( Snds_iface[i].sig == index )
{
return i;
}
}
return -1;
}
//Takes a tag, a sound index destination, and the object name being parsed
//tag and object_name are mostly so that we can debug stuff
//This also means you shouldn't use optional_string or required_string,
@@ -74,12 +99,18 @@ void parse_sound(char* tag, int *idx_dest, char* object_name)
if(idx != -1)
(*idx_dest) = idx;
else
(*idx_dest) = atoi(buf);
//Ensure sound is in range
if((*idx_dest) < -1 || (*idx_dest) >= Num_game_sounds)
{
Warning(LOCATION, "%s sound index out of range on '%s'. Must be between 0 and %d. Forcing to -1 (Nonexistant sound).\n", tag, object_name, Num_game_sounds);
idx = gamesnd_get_by_tbl_index(atoi(buf));
if (idx != -1)
(*idx_dest) = idx;
}
Assert( Snds.size() <= INT_MAX );
//Ensure sound is in range
if((*idx_dest) < -1 || (*idx_dest) >= (int)Snds.size())
{
(*idx_dest) = -1;
Warning(LOCATION, "%s sound index out of range on '%s'. Must be between 0 and %d. Forcing to -1 (Nonexistant sound).\n", tag, object_name, Snds.size());
}
}
}
@@ -97,7 +128,8 @@ void gamesnd_preload_common_sounds()
if ( !Sound_enabled )
return;
for ( i = 0; i < Num_game_sounds; i++ ) {
Assert( Snds.size() <= INT_MAX );
for ( i = 0; i < (int)Snds.size(); i++ ) {
gs = &Snds[i];
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
if ( gs->preload ) {
@@ -121,7 +153,8 @@ void gamesnd_load_gameplay_sounds()
if ( !Sound_enabled )
return;
for ( i = 0; i < Num_game_sounds; i++ ) {
Assert( Snds.size() <= INT_MAX );
for ( i = 0; i < (int)Snds.size(); i++ ) {
gs = &Snds[i];
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
if ( !gs->preload ) { // don't try to load anything that's already preloaded
@@ -142,7 +175,8 @@ void gamesnd_unload_gameplay_sounds()
int i;
game_snd *gs;
for ( i = 0; i < Num_game_sounds; i++ ) {
Assert( Snds.size() <= INT_MAX );
for ( i = 0; i < (int)Snds.size(); i++ ) {
gs = &Snds[i];
if ( gs->id != -1 ) {
snd_unload( gs->id );
@@ -164,7 +198,8 @@ void gamesnd_load_interface_sounds()
if ( !Sound_enabled )
return;
for ( i = 0; i < Num_iface_sounds; i++ ) {
Assert( Snds_iface.size() < INT_MAX );
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
gs = &Snds_iface[i];
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
gs->id = snd_load(gs);
@@ -182,7 +217,8 @@ void gamesnd_unload_interface_sounds()
int i;
game_snd *gs;
for ( i = 0; i < Num_iface_sounds; i++ ) {
Assert( Snds_iface.size() < INT_MAX );
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
gs = &Snds_iface[i];
if ( gs->id != -1 ) {
snd_unload( gs->id );
@@ -256,7 +292,8 @@ void gamesnd_parse_soundstbl()
// Parse the gameplay sounds section
required_string("#Game Sounds Start");
while (required_string_either("#Game Sounds End","$Name:")) {
Assert( num_game_sounds < Num_game_sounds);
Assert( Snds.size() < INT_MAX );
Assert( num_game_sounds < (int)Snds.size() );
gamesnd_parse_line( &Snds[num_game_sounds], "$Name:" );
num_game_sounds++;
gamesnd_add_sound_slot( GAME_SND, num_game_sounds );
@@ -266,7 +303,8 @@ void gamesnd_parse_soundstbl()
// Parse the interface sounds section
required_string("#Interface Sounds Start");
while (required_string_either("#Interface Sounds End","$Name:")) {
Assert( num_iface_sounds < Num_iface_sounds);
Assert( Snds_iface_handle.size() < INT_MAX );
Assert( num_iface_sounds < (int)Snds_iface.size() );
gamesnd_parse_line(&Snds_iface[num_iface_sounds], "$Name:");
num_iface_sounds++;
gamesnd_add_sound_slot( IFACE_SND, num_iface_sounds );
@@ -467,6 +505,7 @@ void gamesnd_parse_soundstbl()
//
void gamesnd_init_struct(game_snd *gs)
{
gs->sig = -1;
gs->filename[0] = 0;
gs->id = -1;
gs->id_sig = -1;
@@ -482,33 +521,26 @@ void gamesnd_init_sounds()
{
int i;
if (Snds == NULL) {
Snds = (game_snd *) vm_malloc (sizeof(game_snd) * MIN_GAME_SOUNDS);
Verify( Snds != NULL );
Num_game_sounds = MIN_GAME_SOUNDS;
}
Snds.clear();
Snds.resize(MIN_GAME_SOUNDS);
Assert( Num_game_sounds > 0 );
Assert( Snds.size() > 0 );
Assert( Snds.size() <= INT_MAX );
// init the gameplay sounds
for ( i = 0; i < Num_game_sounds; i++ ) {
for ( i = 0; i < (int)Snds.size(); i++ ) {
gamesnd_init_struct(&Snds[i]);
}
if (Snds_iface == NULL) {
Snds_iface = (game_snd *) vm_malloc (sizeof(game_snd) * MIN_INTERFACE_SOUNDS);
Verify( Snds_iface != NULL );
Num_iface_sounds = MIN_INTERFACE_SOUNDS;
Assert( Snds_iface_handle == NULL );
Snds_iface_handle = (int *) vm_malloc (sizeof(int) * Num_iface_sounds);
Verify( Snds_iface_handle != NULL );
}
Assert( Num_iface_sounds > 0 );
Snds_iface.clear();
Snds_iface.resize(MIN_INTERFACE_SOUNDS);
Snds_iface_handle.resize(MIN_INTERFACE_SOUNDS);
Assert( Snds_iface.size() > 0 );
Assert( Snds_iface.size() < INT_MAX );
// init the interface sounds
for ( i = 0; i < Num_iface_sounds; i++ ) {
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
gamesnd_init_struct(&Snds_iface[i]);
Snds_iface_handle[i] = -1;
}
@@ -517,20 +549,9 @@ void gamesnd_init_sounds()
// close out gamesnd, ONLY CALL FROM game_shutdown()!!!!
void gamesnd_close()
{
if (Snds != NULL) {
vm_free(Snds);
Snds = NULL;
}
if (Snds_iface != NULL) {
vm_free(Snds_iface);
Snds_iface = NULL;
}
if (Snds_iface_handle != NULL) {
vm_free(Snds_iface_handle);
Snds_iface_handle = NULL;
}
Snds.clear();
Snds_iface.clear();
Snds_iface_handle.clear();
}
// callback function for the UI code to call when the mouse first goes over a button.
@@ -552,16 +573,14 @@ void gamesnd_add_sound_slot(int type, int num)
switch (type) {
case GAME_SND:
{
Assert( Snds != NULL );
Assert( num < (Num_game_sounds + increase_by) );
Assert( Snds.size() <= INT_MAX );
Assert( num < ((int)Snds.size() + increase_by) );
if (num >= Num_game_sounds) {
Snds = (game_snd *) vm_realloc (Snds, sizeof(game_snd) * (Num_game_sounds + increase_by));
Verify( Snds != NULL );
Num_game_sounds += increase_by;
if (num >= (int)Snds.size()) {
Snds.resize(Snds.size() + increase_by);
// default all new entries
for (i = (Num_game_sounds - increase_by); i < Num_game_sounds; i++) {
for (i = ((int)Snds.size() - increase_by); i < (int)Snds.size(); i++) {
gamesnd_init_struct(&Snds[i]);
}
}
@@ -570,20 +589,17 @@ void gamesnd_add_sound_slot(int type, int num)
case IFACE_SND:
{
Assert( Snds_iface != NULL );
Assert( num < (Num_game_sounds + increase_by) );
Assert( Snds_iface.size() < INT_MAX );
Assert( num < ((int)Snds_iface.size() + increase_by) );
if (num >= Num_iface_sounds) {
Snds_iface = (game_snd *) vm_realloc (Snds_iface, sizeof(game_snd) * (Num_iface_sounds + increase_by));
Verify( Snds_iface != NULL );
Num_iface_sounds += increase_by;
if (num >= (int)Snds_iface.size()) {
Snds_iface.resize(Snds_iface.size() + increase_by);
Assert( Snds_iface_handle != NULL );
Snds_iface_handle = (int *) vm_realloc (Snds_iface_handle, sizeof(int) * Num_iface_sounds);
Verify( Snds_iface_handle != NULL );
Snds_iface_handle.resize(Snds_iface.size());
Assert( Snds_iface.size() < INT_MAX );
// default all new entries
for (i = (Num_iface_sounds - increase_by); i < Num_iface_sounds; i++) {
for (i = ((int)Snds_iface_handle.size() - increase_by); i < (int)Snds_iface_handle.size(); i++) {
gamesnd_init_struct(&Snds_iface[i]);
Snds_iface_handle[i] = -1;
}
+4 -5
View File
@@ -27,6 +27,8 @@ void gamesnd_preload_common_sounds();
void gamesnd_play_iface(int n);
void gamesnd_play_error_beep();
int gamesnd_get_by_name(char* name);
int gamesnd_get_by_tbl_index(int index);
int gamesnd_get_by_iface_tbl_index(int index);
//This should handle NO_SOUND just fine since it doesn't directly access lowlevel code
//Does all parsing for a sound
@@ -40,11 +42,8 @@ void common_play_highlight_sound();
#define MIN_GAME_SOUNDS 202
#define MIN_INTERFACE_SOUNDS 70
extern int Num_game_sounds;
extern int Num_iface_sounds;
extern game_snd *Snds;
extern game_snd *Snds_iface;
extern SCP_vector<game_snd> Snds;
extern SCP_vector<game_snd> Snds_iface;
// symbolic names for misc. game sounds. The order here must match the order in
+1 -1
View File
@@ -30,7 +30,7 @@ color *Color_netplayer[20] = {
&Color_bright_blue,
&Color_green,
&Color_bright_green,
&Color_black,
&Color_pink,
&Color_grey,
&Color_silver,
&Color_white,
+10
View File
@@ -990,6 +990,10 @@ $no extra collision avoidance vs player: NO \n\
;; before making it give a death scream \n\
$perform less checks for death screams: NO \n\
\n\
;; If set, allows shield management for all ships \n\
;; (including capships). \n\
$all ships manage shields: NO \n\
\n\
#End \n\
";
@@ -1021,6 +1025,12 @@ $Linked: \n\
+Snd File: none \n\
$Hazard: \n\
+Msg: Cannot engage autopilot: Hazard Near \n\
+Snd File: none \n\
$Support Present: \n\
+Msg: Cannot engage autopilot: Support Ship Present \n\
+Snd File: none \n\
$Support Working: \n\
+Msg: Cannot engage autopilot: Support Ship is rearming or repairing a ship \n\
+Snd File: none \n\
\n\
#END \n\
+1 -1
View File
@@ -230,7 +230,7 @@ extern int Global_error_count;
// Assertion can only use its proper fuctionality in compilers that support variadic macro
# ifndef _MSC_VER // non MS compilers
# define Assertion(x, y, ...) do { if (!(x)){ WinAssert(#x,__FILE__,__LINE__, y, __VA_ARGS__ ); } } while (0)
# define Assertion(x, y, ...) do { if (!(x)){ WinAssert(#x,__FILE__,__LINE__, y , ##__VA_ARGS__ ); } } while (0)
# else
# if _MSC_VER >= 1400 // VC 2005 or greater
# define Assertion(x, y, ...) do { if (!(x)){ WinAssert(#x,__FILE__,__LINE__, y, __VA_ARGS__ ); } ASSUME(x); } while (0)
+49
View File
@@ -1,4 +1,5 @@
#include "globalincs/pstypes.h"
#include "globalincs/globals.h"
#include "bmpman/bmpman.h"
#include "graphics/generic.h"
#include "graphics/2d.h"
@@ -19,6 +20,54 @@
//we check background type to avoid messed up colours for ANI
#define ANI_BPP_CHECK (ga->ani.bg_type == BM_TYPE_PCX) ? 16 : 32
// Goober5000
int generic_anim_init_and_stream(generic_anim *anim, char *anim_filename, ubyte bg_type, bool attempt_hi_res)
{
int stream_result = -1;
char filename[NAME_LENGTH];
char *p;
Assert(anim != NULL);
Assert(anim_filename != NULL);
// hi-res support
if (attempt_hi_res && (gr_screen.res == GR_1024)) {
// attempt to load a hi-res animation
memset(filename, 0, NAME_LENGTH);
strcpy_s(filename, "2_");
strncat(filename, anim_filename, NAME_LENGTH - 3);
// remove extension
p = strchr(filename, '.');
if(p) {
*p = '\0';
}
// attempt to stream the hi-res ani
generic_anim_init(anim, filename);
anim->ani.bg_type = bg_type;
stream_result = generic_anim_stream(anim);
}
// we failed to stream hi-res, or we aren't running in hi-res, so try low-res
if (stream_result < 0) {
strcpy_s(filename, anim_filename);
// remove extension
p = strchr(filename, '.');
if(p) {
*p = '\0';
}
// attempt to stream the low-res ani
generic_anim_init(anim, filename);
anim->ani.bg_type = bg_type;
stream_result = generic_anim_stream(anim);
}
return stream_result;
}
// Goober5000
void generic_anim_init(generic_anim *ga, char *filename)
{
+1 -1
View File
@@ -52,7 +52,7 @@ typedef struct generic_bitmap {
int bitmap_id;
} generic_bitmap;
int generic_anim_init_and_stream(generic_anim *anim, char *anim_filename, ubyte bg_type, bool attempt_hi_res);
void generic_anim_init(generic_anim *ga, char *filename = NULL);
void generic_bitmap_init(generic_bitmap *gb, char *filename = NULL);
int generic_anim_load(generic_anim *ga);
+2 -2
View File
@@ -11,7 +11,7 @@
#include "graphics/2d.h"
#include "cmdline/cmdline.h"
#include "render/3d.h"
#include "bmpman/bmpman.h"
geometry_batcher::~geometry_batcher()
{
@@ -618,7 +618,7 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float
int index = find_good_batch_item(texture);
Assert( index >= 0 );
Assert( geometry_map[index].laser == false );
Assertion( (geometry_map[index].laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
geometry_map[index].tmap_flags = tmap_flags;
geometry_map[index].alpha = alpha;
+2 -2
View File
@@ -147,7 +147,7 @@ ogl_extension GL_Extensions[NUM_OGL_EXTENSIONS] =
{ false, false, 1, { "GL_ARB_fragment_shader" }, 0, { NULL } },
// shader version 3.0 detection extensions (if any of these extensions exist then we should have a SM3.0 compatible card, hopefully)
{ false, false, 3, { "GL_ARB_shader_texture_lod", "GL_NV_vertex_program3", "GL_ATI_shader_texture_lod" }, 0, { NULL } }
{ false, false, 2, { "GL_ARB_shader_texture_lod", "GL_NV_vertex_program" }, 0, { NULL } }
};
// ogl_funcion is:
@@ -370,7 +370,7 @@ void opengl_extensions_init()
// }
if ( !Cmdline_noglsl && Is_Extension_Enabled(OGL_ARB_SHADER_OBJECTS) && Is_Extension_Enabled(OGL_ARB_FRAGMENT_SHADER)
&& Is_Extension_Enabled(OGL_ARB_VERTEX_SHADER) && Is_Extension_Enabled(OGL_SM30) )
&& Is_Extension_Enabled(OGL_ARB_VERTEX_SHADER) /*&& Is_Extension_Enabled(OGL_SM30)*/ )
{
Use_GLSL = 1;
}
-3
View File
@@ -687,7 +687,6 @@ void hud_config_synch_sliders(int i)
// reset some ui components based on HUD config data
void hud_config_synch_ui()
{
// game_load_palette();
HUD_init_hud_color_array();
// HC_sliders[gr_screen.res][HC_BRIGHTNESS_SLIDER].slider.pos = HUD_color_alpha-3; // convert to value from 0-10
@@ -1014,8 +1013,6 @@ void hud_config_set_color(int color)
hud_config_record_color(color);
// game_load_palette();
HUD_init_hud_color_array();
// apply the color to all gauges
+6
View File
@@ -12,6 +12,7 @@
#include "graphics/2d.h"
#include "localization/localize.h"
#include "hud/hud.h"
#include "mission/missiontraining.h" //for Max_directives
#include "hud/hudescort.h"
//#include "weapon/emp.h"
#include "hud/hudparse.h" //Duh.
@@ -523,6 +524,11 @@ void parse_hud_gauges_tbl(char *filename)
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
if(optional_string("$Max Directives:"))
{
stuff_int(&Max_directives);
}
if(optional_string("$Max Escort Ships:"))
{
stuff_int(&Max_escort_ships);
+27 -2
View File
@@ -2026,7 +2026,7 @@ void hud_squadmsg_call_reinforcement(int reinforcement_num, int player_num)
// function to display a list of reinforcements available to the player
void hud_squadmsg_reinforcement_select()
{
int i, k;
int i, k, wingnum;
reinforcements *rp;
if ( Num_menu_items == -1 ) {
@@ -2042,7 +2042,32 @@ void hud_squadmsg_reinforcement_select()
// don't put items which are not on my team
if((Player_ship != NULL) && (ship_get_reinforcement_team(i) != Player_ship->team)){
continue;
}
}
// check the arrival cue sexpression of the ship/wing of this reinforcement.
// Goober5000 - if it can't arrive, it doesn't count. This should check
// for SEXP_FALSE as well as SEXP_KNOWN_FALSE, otherwise you end up with
// a reinforcement menu containing no valid selections.
if ( (wingnum = wing_name_lookup(rp->name, 1)) != -1 ) {
Assert ( Wings[wingnum].arrival_cue >= 0 );
if ( Sexp_nodes[Wings[wingnum].arrival_cue].value == SEXP_FALSE
|| Sexp_nodes[Wings[wingnum].arrival_cue].value == SEXP_KNOWN_FALSE ){
continue;
}
} else {
p_object *p_objp;
p_objp = mission_parse_get_arrival_ship( rp->name );
if ( p_objp != NULL ) {
if ( Sexp_nodes[p_objp->arrival_cue].value == SEXP_FALSE
|| Sexp_nodes[p_objp->arrival_cue].value == SEXP_KNOWN_FALSE ){
continue;
}
} else {
Int3(); // allender says bogus! reinforcement should be here since it wasn't a wing!
continue;
}
}
Assert ( Num_menu_items < MAX_MENU_ITEMS );
strcpy_s( MsgItems[Num_menu_items].text, rp->name );
+2 -2
View File
@@ -1809,8 +1809,8 @@ void hud_target_live_turret(int next_flag, int auto_advance, int only_player_tar
} else if (turret_weapon_has_subtype(&A->weapons, WP_LASER)) {
ent[num_live_turrets].type = TYPE_FACING_LASER;
} else {
Int3();
ent[num_live_turrets].type = TYPE_FACING_LASER;
//Turret not live, bail
continue;
}
}
+3 -7
View File
@@ -1671,13 +1671,13 @@ void game_process_keys()
}
//If topdown view in non-2D mission, go back to cockpit view.
if ( (Viewer_mode & VM_TOPDOWN) && !(The_mission.flags & MISSION_FLAG_2D_MISSION)) {
if ( (Viewer_mode & VM_TOPDOWN) && !(The_mission.flags & MISSION_FLAG_2D_MISSION) && !(Perspective_locked) ) {
Viewer_mode &= ~VM_TOPDOWN;
break;
}
// if in external view or chase view, go back to cockpit view
if ( Viewer_mode & (VM_EXTERNAL|VM_CHASE|VM_OTHER_SHIP) ) {
if ( (Viewer_mode & (VM_EXTERNAL|VM_CHASE|VM_OTHER_SHIP)) && !(Perspective_locked) ) {
Viewer_mode &= ~(VM_EXTERNAL|VM_CHASE|VM_OTHER_SHIP);
break;
}
@@ -2846,11 +2846,7 @@ int button_function(int n)
}
else
{
if (CanAutopilot(true))
{
StartAutopilot();
}
else
if (!StartAutopilot())
gamesnd_play_iface(SND_GENERAL_FAIL);
}
}
+2
View File
@@ -25,6 +25,7 @@
#include "mission/missionparse.h"
#include "species_defs/species_defs.h"
#include "playerman/managepilot.h"
#include "object/objectsnd.h"
// flags
#define LAB_FLAG_NORMAL (0) // default
@@ -1848,6 +1849,7 @@ void labviewer_change_ship_lod(Tree* caller)
The_mission.ai_profile = &Ai_profiles[Default_ai_profile];
int test_idx = ship_create(&vmd_identity_matrix, &vmd_zero_vector, ship_index);
obj_delete(test_idx);
obj_snd_level_close();
}
Lab_last_selected_ship = Lab_selected_index;
+3
View File
@@ -35,6 +35,9 @@ int static_rand(int num)
{
int a, b, c;
if (num < 0)
num *= -1;
if (!Semirand_inited)
init_semirand();
+5 -1
View File
@@ -1630,7 +1630,11 @@ void vm_matrix_to_rot_axis_and_angle(matrix *m, float *theta, vec3d *rot_axis)
rot_axis->xyz.x = (m->vec.uvec.xyz.z - m->vec.fvec.xyz.y);
rot_axis->xyz.y = (m->vec.fvec.xyz.x - m->vec.rvec.xyz.z);
rot_axis->xyz.z = (m->vec.rvec.xyz.y - m->vec.uvec.xyz.x);
vm_vec_normalize(rot_axis);
if (IS_VEC_NULL_SQ_SAFE(rot_axis)) {
vm_vec_make(rot_axis, 1.0f, 0.0f, 0.0f);
} else {
vm_vec_normalize(rot_axis);
}
} else { // angle is PI within limits
*theta = PI;
+33 -30
View File
@@ -33,41 +33,42 @@
// This is the fs2_open credit list, please only add yourself if you have actually contributed code
// Rules!
char *fs2_open_credit_text =
"SOURCE CODE PROJECT STAFF:\n"
"SOURCE CODE PROJECT STAFF:\n"
"\n"
"Project Leaders:\n"
"\n"
"Ian \"Goober5000\" Warfield\n"
"Cliff \"chief1983\" Gordon"
"\n"
"Senior Advisors:\n"
"\n"
"Taylor Richards\n"
"\n"
"Senior Advisor\n"
"\n"
"Ian \"Goober5000\" Warfield\n"
"Edward \"Inquisitor\" Gardner\n"
"\n"
"Programmers:\n"
"\n"
"Mike \"Bobboau\" Abegg\n"
"Dennis \"DTP\" Pedersen\n"
"\"EdrickV\"\n"
"Derek \"Kazan\" Meek\n"
"Ian \"Goober5000\" Warfield\n"
"\"Mysterial\"\n"
"Joe \"Righteous1\" Dowd\n"
"Jon \"Sesquipedalian\" Stovell\n"
"Matt \"Sticks\" Nischan\n"
"Mike \"penguin\" Harris\n"
"Nick \"phreak\" Iannetta\n"
"Thomas \"RandomTiger\" Whittaker\n"
"Taylor Richards\n"
"Will \"##Unknown Player##\" Rousnel\n"
"\"WMCoolmon\"\n"
"Hassan \"Karajorma\" Kazmi\n"
"Derek \"Kazan\" Meek\n"
"Nick \"phreak\" Iannetta\n"
"Mike \"Bobboau\" Abegg\n"
"Backslash\n"
"Echelon9\n"
"Flaming_Sword\n"
"FUBAR\n"
"Iss Mneur\n"
"kkmic\n"
"Michael \"Zacam\" LaFleur\n"
"Shade\n"
"Soulstorm\n"
"Sushi\n"
"Swifty\n"
"Wanderer\n"
"Fabian \"The E\" Woltermann\n"
"\n"
"\n"
"Readme Staff:\n"
"\n"
"\"Bottomfan\"\n"
"Peter \"Flipside\" Dibble\n"
"Jonathan \"Redmenace\" Willsher\n"
"\n"
"Web Support:\n"
"\n"
@@ -77,12 +78,10 @@ char *fs2_open_credit_text =
"\n"
"Special thanks to:\n"
"\n"
"\"Maeglamor\"\n"
"for donating a graphics card!\n"
"\n"
"\"Lightspeed\"\n"
"\"DaBrain\"\n"
"for helping out with the graphics enhancements\n"
"portej05\n"
"Hery\n"
"QuantumDelta\n"
"Fury\n"
"\n"
"Linux and OSX version with the support of\n"
"the icculus.org FreeSpace2 project:\n"
@@ -102,8 +101,12 @@ char *fs2_open_credit_text =
"\n"
"Ogg Vorbis - (C) 2005, Xiph.Org Foundation\n"
"JPEG - Independent JPEG Group, (C) 1991-1998, Thomas G. Lane\n"
"\n\n"
"\n\n";
"libpng - Copyright (C) 1998-2010 Glenn Randers-Pehrson\n"
"liblua - Copyright (C) 1994–2008 Lua.org, PUC-Rio\n"
"zlib - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler\n"
"\n"
"\n"
"\n";
char *unmodified_credits = "ORIGINAL VOLITION STAFF:\n\n\n";
char *mod_check = "Design:";
+8 -7
View File
@@ -50,11 +50,7 @@ static char *Demo_title_bitmap_filename = NOX("DemoTitle1");
// PLAYER SELECT defines
//
//#define MAX_PLAYER_SELECT_LINES 8 // max # of pilots displayed at once
int Player_select_max_lines[GR_NUM_RESOLUTIONS] = { // max # of pilots displayed at once
8, // GR_640
15 // GR_1024
};
int Max_lines; //Max number of pilots displayed in Window. Gets set in player_select_draw_list()
// button control defines
#define NUM_PLAYER_SELECT_BUTTONS 8 // button control defines
@@ -918,7 +914,7 @@ void player_select_scroll_list_down()
gamesnd_play_iface(SND_GENERAL_FAIL);
}
if (Player_select_pilot >= (Player_select_list_start + Player_select_max_lines[gr_screen.res])){
if (Player_select_pilot >= (Player_select_list_start + Max_lines)){
Player_select_list_start++;
}
}
@@ -1064,7 +1060,12 @@ void player_select_draw_list()
{
int idx;
for (idx=0; idx<Player_select_max_lines[gr_screen.res]; idx++) {
if (gr_screen.res == 1)
Max_lines = 145/gr_get_font_height(); //Make the max number of lines dependent on the font height. 145 and 85 are magic numbers, based on the window size in retail.
else
Max_lines = 85/gr_get_font_height();
for (idx=0; idx<Max_lines; idx++) {
// only draw as many pilots as we have
if ((idx + Player_select_list_start) == Player_select_num_pilots)
break;
+9 -11
View File
@@ -244,7 +244,6 @@ static int Techroom_ship_modelnum;
static float Techroom_ship_rot;
static UI_BUTTON List_buttons[LIST_BUTTONS_MAX]; // buttons for each line of text in list
//static int Anim_playing_id = -1;
//static int anim_done = 0;
static int Palette_bmp;
//static int ShipWin01;
//static int ShipWin02;
@@ -393,12 +392,14 @@ void techroom_select_new_entry()
Techroom_ship_modelnum = -1;
Trackball_mode = 0;
//load animation here, we now only have one loaded
generic_anim_init(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename);
Current_list[Cur_entry].animation.ani.bg_type = bm_get_type(Tech_background_bitmap);
if(generic_anim_stream(&Current_list[Cur_entry].animation) != -1){
// load animation here, we now only have one loaded
int stream_result = generic_anim_init_and_stream(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
if (stream_result >= 0) {
Current_list[Cur_entry].has_anim = 1;
} else {
// we've failed to load any animation
// load an image and treat it like a 1 frame animation
Current_list[Cur_entry].bitmap = bm_load(Current_list[Cur_entry].tech_anim_filename);
}
}
@@ -728,7 +729,7 @@ void tech_ship_scroll_capture()
techroom_unload_animation();
techroom_select_new_entry();
}
}
void techroom_anim_render(float frametime)
{
@@ -808,7 +809,7 @@ void techroom_change_tab(int num)
Ship_list[Ship_list_size].index = i;
Ship_list[Ship_list_size].animation.num_frames = 0; // no anim for ships
Ship_list[Ship_list_size].has_anim = 0; // no anim for ships
Ship_list[Ship_list_size].name = (Ship_info[i].alt_name[0]) ? Ship_info[i].alt_name : Ship_info[i].name;
Ship_list[Ship_list_size].name = *Ship_info[i].tech_title ? Ship_info[i].tech_title : (*Ship_info[i].alt_name ? Ship_info[i].alt_name : Ship_info[i].name);
Ship_list[Ship_list_size].desc = Ship_info[i].tech_desc;
Ship_list[Ship_list_size].model_num = -1;
Ship_list[Ship_list_size].textures_loaded = 0;
@@ -871,14 +872,11 @@ void techroom_change_tab(int num)
Weapon_list[Weapon_list_size].index = i;
Weapon_list[Weapon_list_size].desc = Weapon_info[i].tech_desc;
Weapon_list[Weapon_list_size].has_anim = 1;
Weapon_list[Weapon_list_size].name = Weapon_info[i].tech_title;
Weapon_list[Weapon_list_size].name = *Weapon_info[i].tech_title ? Weapon_info[i].tech_title : Weapon_info[i].name;
Weapon_list[Weapon_list_size].bitmap = -1;
Weapon_list[Weapon_list_size].animation.num_frames = 0;
Weapon_list[Weapon_list_size].model_num = -1;
Weapon_list[Weapon_list_size].textures_loaded = 0;
if (Weapon_list[Weapon_list_size].name[0] == 0) {
Weapon_list[Weapon_list_size].name = Weapon_info[i].name;
}
// copy the weapon animation filename
strncpy(Weapon_list[Weapon_list_size].tech_anim_filename, Weapon_info[i].tech_anim_filename, MAX_FILENAME_LEN - 1);
+81 -25
View File
@@ -181,6 +181,11 @@ char *Persona_type_names[MAX_PERSONA_TYPES] =
int Default_command_persona;
// Goober5000
// NOTE - these are truncated filenames, i.e. without extensions
SCP_vector<SCP_string> generic_message_filenames;
///////////////////////////////////////////////////////////////////
// used to distort incoming messages when comms are damaged
///////////////////////////////////////////////////////////////////
@@ -419,7 +424,6 @@ void message_parse(bool importing_from_fsm)
void parse_msgtbl()
{
char *p1, *p2, *p3;
int i, j;
// open localization
@@ -435,27 +439,19 @@ void parse_msgtbl()
Num_messages = 0;
Num_personas = 0;
// Goober5000 - ugh, nasty nasty hack to fix the FS2 retail tables
p1 = strstr(Mp, "#End");
*(p1+4)=0;
p1 = strstr(Mp, "2926");
if (p1)
// Goober5000 - ugh, ugly hack to fix the FS2 retail tables
char *pVawacs25 = strstr(Mp, "Vawacs25.wav");
if (pVawacs25)
{
p2 = strstr(p1, "Vawacs25.wav");
p3 = strstr(p1, "$Name");
if (p2 && p3 && (p2 < p3))
char *pAwacs75 = strstr(pVawacs25, "Awacs75.wav");
if (pAwacs75)
{
replace_one(p2, "Vawacs25.wav", "Awacs25.wav", 500);
}
}
p1 = strstr(Mp, "2927");
if (p1)
{
p2 = strstr(p1, "Awacs75.wav");
p3 = strstr(p1, "$Name");
if (p2 && p3 && (p2 < p3))
{
replace_one(p2, "Awacs75.wav", "Vawacs75.wav", 500);
// move the 'V' from the first filename to the second, and adjust the 'A' case
*pVawacs25 = 'A';
for (i = 1; i < (pAwacs75 - pVawacs25) - 1; i++)
pVawacs25[i] = pVawacs25[i+1];
pAwacs75[-1] = 'V';
pAwacs75[0] = 'a';
}
}
@@ -489,6 +485,50 @@ void parse_msgtbl()
}
}
// additional table part!
generic_message_filenames.clear();
generic_message_filenames.push_back("none");
generic_message_filenames.push_back("cuevoice");
generic_message_filenames.push_back("emptymsg");
generic_message_filenames.push_back("generic");
generic_message_filenames.push_back("msgstart");
if (optional_string("#Simulated Speech Overrides"))
{
char filename[MAX_FILENAME_LEN];
while (required_string_either("#End", "$File Name:"))
{
required_string("$File Name:");
stuff_string(filename, F_NAME, MAX_FILENAME_LEN);
// get extension
char *ptr = strchr(filename, '.');
if (ptr == NULL)
{
Warning(LOCATION, "Simulated speech override file '%s' was provided with no extension!", filename);
continue;
}
// test extension
if (stricmp(ptr, ".ogg") && stricmp(ptr, ".wav"))
{
Warning(LOCATION, "Simulated speech override file '%s' was provided with an extension other than .wav or .ogg!", filename);
continue;
}
// truncate extension
*ptr = '\0';
// add truncated file name
generic_message_filenames.push_back(filename);
}
required_string("#End");
}
// close localization
lcl_ext_close();
}
@@ -859,10 +899,26 @@ void message_load_wave(int index, const char *filename)
// Goober5000
bool message_filename_is_generic(char *filename)
{
if (!strnicmp(filename, "cuevoice.wav", 8)) return true;
if (!strnicmp(filename, "emptymsg.wav", 8)) return true;
if (!strnicmp(filename, "generic.wav", 7)) return true;
if (!strnicmp(filename, "msgstart.wav", 8)) return true;
int i;
char truncated_filename[MAX_FILENAME_LEN];
// truncate any file extension
strcpy(truncated_filename, filename);
char *ptr = strchr(truncated_filename, '.');
// extension must be a recognized sound file
if ((ptr == NULL) || (stricmp(ptr, ".ogg") && stricmp(ptr, ".wav")))
return false;
// truncate it
*ptr = '\0';
// test against the list
for (i = 0; i < generic_message_filenames.size(); i++)
{
if (!stricmp(generic_message_filenames[i].c_str(), truncated_filename))
return true;
}
return false;
}
@@ -1970,7 +2026,7 @@ void message_maybe_distort()
snd_set_volume(Playing_messages[i].wave, 0.0f);
} else {
if ( was_muted )
snd_set_volume(Playing_messages[i].wave, Master_sound_volume);
snd_set_volume(Playing_messages[i].wave, (Master_sound_volume * aav_voice_volume));
}
}
}
+14 -6
View File
@@ -74,6 +74,7 @@ typedef struct {
char Training_buf[TRAINING_MESSAGE_LENGTH];
char *Training_lines[MAX_TRAINING_MESSAGE_LINES]; // Training message split into lines
char Training_voice_filename[NAME_LENGTH];
int Max_directives = TRAINING_OBJ_DISPLAY_LINES;
int Training_message_timestamp;
int Training_line_sizes[MAX_TRAINING_MESSAGE_LINES];
int Training_message_method = 1;
@@ -173,8 +174,8 @@ void training_obj_display()
offset = 0;
end = Training_obj_num_lines;
if (end > TRAINING_OBJ_DISPLAY_LINES) {
end = TRAINING_OBJ_DISPLAY_LINES;
if (end > Max_directives) {
end = Max_directives;
offset = Training_obj_num_lines - end;
}
@@ -302,6 +303,9 @@ void training_mission_init()
Training_obj_num_lines = 0;
Training_message_queue_count = 0;
Training_failure = 0;
if (Max_directives > TRAINING_OBJ_LINES) {
Max_directives = TRAINING_OBJ_LINES;
}
for (i=0; i<TRAINING_OBJ_LINES; i++)
Training_obj_lines[i] = -1;
@@ -361,7 +365,7 @@ void sort_training_objectives()
// get the index of the first directive that will be displayed
// if less than 0, display all lines
offset = Training_obj_num_lines - TRAINING_OBJ_DISPLAY_LINES;
offset = Training_obj_num_lines - Max_directives;
if (offset <= 0) {
return;
@@ -447,7 +451,7 @@ void sort_training_objectives()
// find first slot that can be bumped
// look at the last (N-4 to N) positions
for (slot_idx=0; slot_idx<TRAINING_OBJ_DISPLAY_LINES; slot_idx++) {
for (slot_idx=0; slot_idx<Max_directives; slot_idx++) {
if ( Training_obj_lines[i+offset] & TRAINING_OBJ_STATUS_KNOWN ) {
break;
}
@@ -726,7 +730,7 @@ int message_play_training_voice(int index)
Training_voice_type = 1;
if (Training_voice_handle >= 0)
audiostream_play(Training_voice_handle, Master_voice_volume, 0);
audiostream_play(Training_voice_handle, (Master_voice_volume * aav_voice_volume), 0);
Training_voice = index;
return Training_voice;
@@ -914,7 +918,11 @@ void message_training_display()
Training_message_visible = 0;
message_training_queue_check();
training_obj_display();
if ( !hud_disabled_except_messages() ) {
training_obj_display();
}
if (Training_failure){
return;
+1
View File
@@ -9,6 +9,7 @@
extern int Max_directives;
extern int Training_message_method;
extern int Training_num_lines;
extern int Training_message_visible;
+2 -43
View File
@@ -193,7 +193,6 @@ static int Voice_ended_time;
//static anim_instance *Cur_anim_instance = NULL;
static generic_anim Cur_Anim;
static char *Cur_anim_filename = "~~~~";
static int anim_done = 0;
static int Cmd_brief_last_voice;
static int Cmd_brief_paused = 0;
@@ -320,9 +319,6 @@ void cmd_brief_stop_anim(int id)
void cmd_brief_new_stage(int stage)
{
char *p;
char filename[NAME_LENGTH];
if (stage < 0) {
cmd_brief_stop_anim(-1);
Cur_stage = -1;
@@ -338,11 +334,6 @@ void cmd_brief_new_stage(int stage)
// load a new animation if it's different to what's already playing
if (strcmp(Cur_anim_filename, Cur_cmd_brief->stage[stage].ani_filename) != 0) {
// set stuff up
int stream_result = -1;
ubyte bg_type = bm_get_type(Cmd_brief_background_bitmap);
anim_done = 0;
// unload the previous anim
if(Cur_Anim.num_frames > 0) {
generic_anim_unload(&Cur_Anim);
@@ -351,40 +342,8 @@ void cmd_brief_new_stage(int stage)
// save new filename
Cur_anim_filename = Cur_cmd_brief->stage[stage].ani_filename;
// hi-res support
if (gr_screen.res == GR_1024) {
// attempt to load a hi-res animation
memset(filename, 0, NAME_LENGTH);
strcpy_s(filename, "2_");
strncat(filename, Cur_anim_filename, NAME_LENGTH - 3);
// remove extension
p = strchr(filename, '.');
if(p) {
*p = '\0';
}
// attempt to stream the hi-res ani
generic_anim_init(&Cur_Anim, filename);
Cur_Anim.ani.bg_type = bg_type;
stream_result = generic_anim_stream(&Cur_Anim);
}
// we failed to stream hi-res, or we aren't running in hi-res, so try low-res
if (stream_result < 0) {
strcpy_s(filename, Cur_anim_filename);
// remove extension
p = strchr(filename, '.');
if(p) {
*p = '\0';
}
// attempt to stream the low-res ani
generic_anim_init(&Cur_Anim, filename);
Cur_Anim.ani.bg_type = bg_type;
stream_result = generic_anim_stream(&Cur_Anim);
}
// try to load the new anim in either high or low res
int stream_result = generic_anim_init_and_stream(&Cur_Anim, Cur_anim_filename, bm_get_type(Cmd_brief_background_bitmap), true);
// we've failed to load any animation
if (stream_result < 0) {
+4 -4
View File
@@ -2728,11 +2728,11 @@ void ss_load_icons(int ship_class)
{
int first_frame, num_frames, i;
first_frame = bm_load_animation(sip->icon_filename, &num_frames);
if ( first_frame == -1 ) {
Int3(); // Could not load in icon frames.. get Alan
Assertion(first_frame != -1, "Failed to load icon %s\n", sip->icon_filename); // Could not load in icon frames.. get Alan
if (first_frame == -1)
return;
}
for ( i = 0; i < num_frames; i++ ) {
icon->icon_bmaps[i] = first_frame+i;
}
+4 -4
View File
@@ -601,10 +601,10 @@ void red_alert_store_subsys_status(red_alert_ship_status *ras, ship *shipp)
ss = GET_FIRST(&shipp->subsys_list);
while ( ss != END_OF_LIST( &shipp->subsys_list ) ) {
if ( count >= MAX_RED_ALERT_SUBSYSTEMS ) {
Int3(); // ran out of subsystems
break;
}
Assertion((count < MAX_RED_ALERT_SUBSYSTEMS), "Too many subsystems in ship %s with red-alert-carry status. Tried to store %d, maximum is %d\n", shipp->ship_name, count, MAX_RED_ALERT_SUBSYSTEMS);
if ( count >= MAX_RED_ALERT_SUBSYSTEMS )
break; //Ran out of systems, better bail
ras->subsys_current_hits[count] = ss->current_hits;
+3 -2
View File
@@ -107,6 +107,7 @@ typedef struct submodel_instance_info {
#define MSS_FLAG_TURRET_ALT_MATH (1 << 18) // tells the game to use additional calculations should turret have a defined y fov
#define MSS_FLAG_DUM_ROTATES (1 << 19) // Bobboau
#define MSS_FLAG_CARRY_SHOCKWAVE (1 << 20) // subsystem - even with 'carry no damage' flag - will carry shockwave damage to the hull
#define MSS_FLAG_ALLOW_LANDING (1 << 21) // This subsystem can be landed on
// definition of stepped rotation struct
typedef struct stepped_rotation {
@@ -398,8 +399,8 @@ typedef struct model_path {
} model_path;
typedef struct model_tmap_vert {
short vertnum;
short normnum;
ushort vertnum;
ushort normnum;
float u,v;
} model_tmap_vert;
+4 -1
View File
@@ -1593,6 +1593,9 @@ void standalone_main_init()
// if this is a tracker game then we have some extra tasks to perform
if (MULTI_IS_TRACKER_GAME) {
// disconnect and prepare for reset if we are already connected
fs2netd_disconnect();
// login (duh!)
if ( fs2netd_login() ) {
// validate missions
@@ -1659,7 +1662,7 @@ void multi_standalone_reset_all()
delete_player( idx );
}
}
// make sure we go to the proper state.
if(gameseq_get_state() == GS_STATE_STANDALONE_MAIN){
standalone_main_init();
+1 -1
View File
@@ -1901,7 +1901,7 @@ void multi_join_send_join_request(int as_observer)
return;
}
nprintf(("Password : %s\n",Multi_join_request.passwd));
nprintf(("Network", "Password : %s\n", Multi_join_request.passwd));
}
// fill out the join request struct
+2 -2
View File
@@ -61,7 +61,7 @@ int collide_debris_ship( obj_pair * pair )
vec3d hitpos;
// create and initialize ship_ship_hit_info struct
collision_info_struct debris_hit_info;
memset( &debris_hit_info, -1, sizeof(collision_info_struct) );
init_collision_info_struct(&debris_hit_info);
if ( pdebris->phys_info.mass > pship->phys_info.mass ) {
debris_hit_info.heavy = pdebris;
@@ -218,7 +218,7 @@ int collide_asteroid_ship( obj_pair * pair )
vec3d hitpos;
// create and initialize ship_ship_hit_info struct
collision_info_struct asteroid_hit_info;
memset( &asteroid_hit_info, -1, sizeof(collision_info_struct) );
init_collision_info_struct(&asteroid_hit_info);
if ( pasteroid->phys_info.mass > pship->phys_info.mass ) {
asteroid_hit_info.heavy = pasteroid;
+173 -54
View File
@@ -22,20 +22,16 @@
#include "io/joy_ff.h"
#include "io/timer.h"
#include "asteroid/asteroid.h"
#include "debris/debris.h"
#include "playerman/player.h"
#include "object/objectdock.h"
#include "object/objectshield.h"
#include "parse/scripting.h"
//#pragma optimize("", off)
//#pragma auto_inline(off)
#define COLLISION_FRICTION_FACTOR 0.0
#define COLLISION_ROTATION_FACTOR 0.2
#define SEP_VEL 5.0f // separation velocity between two ships that collide on same team.
#define COLLIDE_DEBUG
#undef COLLIDE_DEBUG
@@ -124,6 +120,9 @@ int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *
ship *heavy_shipp = &Ships[heavy_obj->instance];
ship *light_shipp = &Ships[light_obj->instance];
ship_info *heavy_sip = &Ship_info[heavy_shipp->ship_info_index];
ship_info *light_sip = &Ship_info[light_shipp->ship_info_index];
// AL 12-4-97: we use the player_involved flag to ensure collisions are always
// done with the player, regardless of team.
if ( heavy_obj == Player_obj || light_obj == Player_obj ) {
@@ -181,11 +180,11 @@ int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *
}
// If either of these objects doesn't get collision checks, abort.
if (Ship_info[heavy_shipp->ship_info_index].flags & SIF_NO_COLLIDE) {
if (heavy_sip->flags & SIF_NO_COLLIDE) {
return 0;
}
if (Ship_info[light_shipp->ship_info_index].flags & SIF_NO_COLLIDE) {
if (light_sip->flags & SIF_NO_COLLIDE) {
return 0;
}
@@ -196,7 +195,7 @@ int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *
// vec3d submodel_hit;
// Do in heavy object RF
mc.model_num = Ship_info[heavy_shipp->ship_info_index].model_num; // Fill in the model to check
mc.model_num = heavy_sip->model_num; // Fill in the model to check
mc.orient = &heavy_obj->orient; // The object's orient
vec3d zero, p0, p1;
@@ -228,7 +227,7 @@ int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *
// Set up collision info
mc.pos = &zero; // The object's position
mc.p1 = &p1; // Point 2 of ray to check
mc.radius = model_get_core_radius(Ship_info[light_shipp->ship_info_index].model_num);
mc.radius = model_get_core_radius(light_sip->model_num);
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE); // flags
// Only check invisible face polygons for ship:ship of different teams.
@@ -475,7 +474,7 @@ int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *
if (heavy_shipp->team == light_shipp->team) {
// If a couple of small ships, just move them apart.
if ((Ship_info[heavy_shipp->ship_info_index].flags & SIF_SMALL_SHIP) && (Ship_info[light_shipp->ship_info_index].flags & SIF_SMALL_SHIP)) {
if ((heavy_sip->flags & SIF_SMALL_SHIP) && (light_sip->flags & SIF_SMALL_SHIP)) {
if ((heavy_obj->flags & OF_PLAYER_SHIP) || (light_obj->flags & OF_PLAYER_SHIP)) {
/*
vec3d h2l_vec;
@@ -527,8 +526,10 @@ int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *
vm_vec_scale_add(&perp_rel_vel, &rel_vel_h, &h_to_l_vec, -mag);
vm_vec_normalize(&perp_rel_vel);
vm_vec_scale_add2(&heavy_obj->phys_info.vel, &perp_rel_vel, SEP_VEL * light_obj->phys_info.mass / mass_sum);
vm_vec_scale_add2(&light_obj->phys_info.vel, &perp_rel_vel, -SEP_VEL * heavy_obj->phys_info.mass / mass_sum);
vm_vec_scale_add2(&heavy_obj->phys_info.vel, &perp_rel_vel,
heavy_sip->collision_physics.both_small_bounce * light_obj->phys_info.mass / mass_sum);
vm_vec_scale_add2(&light_obj->phys_info.vel, &perp_rel_vel,
-(light_sip->collision_physics.both_small_bounce) * heavy_obj->phys_info.mass / mass_sum);
vm_vec_rotate( &heavy_obj->phys_info.prev_ramp_vel, &heavy_obj->phys_info.vel, &heavy_obj->orient );
vm_vec_rotate( &light_obj->phys_info.prev_ramp_vel, &light_obj->phys_info.vel, &light_obj->orient );
@@ -541,9 +542,11 @@ int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *
rel_vel = 1.0f;
}
float mass_sum = heavy_obj->phys_info.mass + light_obj->phys_info.mass;
vm_vec_scale_add2( &heavy_obj->phys_info.vel, &ship_ship_hit_info->light_rel_vel, SEP_VEL*light_obj->phys_info.mass/(mass_sum*rel_vel) );
vm_vec_scale_add2( &heavy_obj->phys_info.vel, &ship_ship_hit_info->light_rel_vel,
heavy_sip->collision_physics.bounce*light_obj->phys_info.mass/(mass_sum*rel_vel) );
vm_vec_rotate( &heavy_obj->phys_info.prev_ramp_vel, &heavy_obj->phys_info.vel, &heavy_obj->orient );
vm_vec_scale_add2( &light_obj->phys_info.vel, &ship_ship_hit_info->light_rel_vel, -SEP_VEL*heavy_obj->phys_info.mass/(mass_sum*rel_vel) );
vm_vec_scale_add2( &light_obj->phys_info.vel, &ship_ship_hit_info->light_rel_vel,
-(light_sip->collision_physics.bounce)*heavy_obj->phys_info.mass/(mass_sum*rel_vel) );
vm_vec_rotate( &light_obj->phys_info.prev_ramp_vel, &light_obj->phys_info.vel, &light_obj->orient );
}
}
@@ -602,6 +605,21 @@ int check_special_cruiser_asteroid_collision(object *heavy, object *light, float
return 0;
}
//Find the subobject corresponding to the submodel hit
bool check_subsystem_landing_allowed(ship_info *heavy_sip, collision_info_struct *ship_ship_hit_info) {
if (!(heavy_sip->flags2 & SIF2_ALLOW_LANDINGS))
return false;
for (int i = 0; i < heavy_sip->n_subsystems; i++) {
if (heavy_sip->subsystems[i].flags & MSS_FLAG_ALLOW_LANDING &&
heavy_sip->subsystems[i].subobj_num == ship_ship_hit_info->submodel_num)
{
return true;
}
}
return false;
}
// ------------------------------------------------------------------------------------------------
// input: ship_ship_hit => structure containing ship_ship hit info
// (includes) A, B => objects colliding
@@ -625,6 +643,13 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
object *heavy = ship_ship_hit_info->heavy;
object *light = ship_ship_hit_info->light;
// gurgh... this includes asteroids and debris too
Assert(heavy->type == OBJ_SHIP || heavy->type == OBJ_ASTEROID || heavy->type == OBJ_DEBRIS);
Assert(light->type == OBJ_SHIP || light->type == OBJ_ASTEROID || light->type == OBJ_DEBRIS);
ship_info *light_sip = (light->type == OBJ_SHIP) ? &Ship_info[Ships[light->instance].ship_info_index] : NULL;
ship_info *heavy_sip = (heavy->type == OBJ_SHIP) ? &Ship_info[Ships[heavy->instance].ship_info_index] : NULL;
// make cruiser/asteroid collision softer on cruisers.
int special_cruiser_asteroid_collision;
int cruiser_light = 0;
@@ -669,7 +694,18 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
if (ship_ship_hit_info->submodel_rot_hit == 1) {
bool set_model = false;
polymodel *pm = model_get(Ship_info[Ships[heavy->instance].ship_info_index].model_num);
polymodel *pm;
if (heavy->type == OBJ_SHIP) {
pm = model_get(heavy_sip->model_num);
} else if (heavy->type == OBJ_ASTEROID) {
pm = Asteroid_info[Asteroids[heavy->instance].asteroid_type].modelp[Asteroids[heavy->instance].asteroid_subtype];
} else if (heavy->type == OBJ_DEBRIS) {
pm = model_get(Debris[heavy->instance].model_num);
} else {
// we should have caught this already
Int3();
pm = NULL;
}
// be sure model is set
if (pm->submodel[ship_ship_hit_info->submodel_num].sii == NULL) {
@@ -745,6 +781,31 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
v_rel_normal_m = -v_rel_normal_m;
}
//Maybe treat the current collision as a landing
vec3d light_local_vel;
float light_uvec_dot_norm;
float light_fvec_dot_norm;
float light_rvec_dot_norm;
bool subsys_landing_allowed = light->type == OBJ_SHIP && heavy->type == OBJ_SHIP && check_subsystem_landing_allowed(heavy_sip, ship_ship_hit_info);
if (subsys_landing_allowed) {
vm_vec_rotate(&light_local_vel, &ship_ship_hit_info->light_rel_vel, &light->orient);
light_uvec_dot_norm = vm_vec_dot(&ship_ship_hit_info->collision_normal, &light->orient.vec.uvec);
light_fvec_dot_norm = vm_vec_dot(&ship_ship_hit_info->collision_normal, &light->orient.vec.fvec);
light_rvec_dot_norm = vm_vec_dot(&ship_ship_hit_info->collision_normal, &light->orient.vec.rvec);
}
if (subsys_landing_allowed &&
light_local_vel.xyz.z < light_sip->collision_physics.landing_max_z &&
light_local_vel.xyz.z > light_sip->collision_physics.landing_min_z &&
light_local_vel.xyz.y > light_sip->collision_physics.landing_min_y &&
abs(light_local_vel.xyz.x) < light_sip->collision_physics.landing_max_x &&
light_uvec_dot_norm > 0 &&
light_fvec_dot_norm < light_sip->collision_physics.landing_max_angle &&
light_fvec_dot_norm > light_sip->collision_physics.landing_min_angle &&
abs(light_rvec_dot_norm) < light_sip->collision_physics.landing_max_rot_angle)
{
ship_ship_hit_info->is_landing = true;
}
vec3d rotational_impulse_heavy, rotational_impulse_light, delta_rotvel_heavy, delta_rotvel_light;
vec3d delta_vel_from_delta_rotvel_heavy, delta_vel_from_delta_rotvel_light, impulse;
float impulse_mag, heavy_denom, light_denom;
@@ -758,7 +819,8 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
impulse = ship_ship_hit_info->collision_normal;
vm_vec_projection_onto_plane(&v_rel_parallel_m, &v_rel_m, &ship_ship_hit_info->collision_normal);
collision_speed_parallel = vm_vec_normalize_safe(&v_rel_parallel_m);
parallel_mag = float(-COLLISION_FRICTION_FACTOR) * collision_speed_parallel / vm_vec_mag(&v_rel_m);
float friction = (light->type == OBJ_SHIP) ? light_sip->collision_physics.friction : COLLISION_FRICTION_FACTOR;
parallel_mag = float(-friction) * collision_speed_parallel / vm_vec_mag(&v_rel_m);
vm_vec_scale_add2(&impulse, &v_rel_parallel_m, parallel_mag);
// calculate the effect on the velocity of the collison point per unit impulse
@@ -771,7 +833,8 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
vm_vec_crossprod(&rotational_impulse_heavy, &ship_ship_hit_info->r_heavy, &impulse);
get_I_inv(&heavy_I_inv, &heavy->phys_info.I_body_inv, &heavy->orient);
vm_vec_rotate(&delta_rotvel_heavy, &rotational_impulse_heavy, &heavy_I_inv);
vm_vec_scale(&delta_rotvel_heavy, float(COLLISION_ROTATION_FACTOR)); // hack decrease rotation (delta_rotvel)
float rotation_factor = (heavy->type == OBJ_SHIP) ? heavy_sip->collision_physics.rotation_factor : COLLISION_ROTATION_FACTOR;
vm_vec_scale(&delta_rotvel_heavy, rotation_factor); // hack decrease rotation (delta_rotvel)
vm_vec_crossprod(&delta_vel_from_delta_rotvel_heavy, &delta_rotvel_heavy , &ship_ship_hit_info->r_heavy);
heavy_denom = vm_vec_dotprod(&delta_vel_from_delta_rotvel_heavy, &ship_ship_hit_info->collision_normal);
if (heavy_denom < 0) {
@@ -791,7 +854,8 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
vm_vec_crossprod(&rotational_impulse_light, &ship_ship_hit_info->r_light, &impulse);
get_I_inv(&light_I_inv, &light->phys_info.I_body_inv, &light->orient);
vm_vec_rotate(&delta_rotvel_light, &rotational_impulse_light, &light_I_inv);
vm_vec_scale(&delta_rotvel_light, float(COLLISION_ROTATION_FACTOR)); // hack decrease rotation (delta_rotvel)
float rotation_factor = (light->type == OBJ_SHIP) ? light_sip->collision_physics.rotation_factor : COLLISION_ROTATION_FACTOR;
vm_vec_scale(&delta_rotvel_light, rotation_factor); // hack decrease rotation (delta_rotvel)
vm_vec_crossprod(&delta_vel_from_delta_rotvel_light, &delta_rotvel_light, &ship_ship_hit_info->r_light);
light_denom = vm_vec_dotprod(&delta_vel_from_delta_rotvel_light, &ship_ship_hit_info->collision_normal);
if (light_denom < 0) {
@@ -809,17 +873,43 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
nprintf(("Physics", "negative impulse mag -- Get Dave A if not Descent Physics\n"));
impulse_mag = -impulse_mag;
}
// update the physics info structs for heavy and light objects
// since we have already calculated delta rotvel for heavy and light in world coords
// physics should not have to recalculate this, just change into body coords (done in collide_whack)
vm_vec_scale(&impulse, impulse_mag);
//Assert(impulse_mag < 20e6);
vm_vec_scale(&delta_rotvel_light, impulse_mag);
physics_collide_whack(&impulse, &delta_rotvel_light, &light->phys_info, &light->orient);
physics_collide_whack(&impulse, &delta_rotvel_light, &light->phys_info, &light->orient, ship_ship_hit_info->is_landing);
vm_vec_negate(&impulse);
vm_vec_scale(&delta_rotvel_heavy, -impulse_mag);
physics_collide_whack(&impulse, &delta_rotvel_heavy, &heavy->phys_info, &heavy->orient);
physics_collide_whack(&impulse, &delta_rotvel_heavy, &heavy->phys_info, &heavy->orient, true);
// If within certain bounds, we want to add some more rotation towards the "resting orientation" of the ship
// These bounds are defined separately from normal "landing" bounds so that they can be more generous:
// we can have crash landings that still re-orient the ship.
if (subsys_landing_allowed &
light_local_vel.xyz.z < light_sip->collision_physics.reorient_max_z &&
light_local_vel.xyz.z > light_sip->collision_physics.reorient_min_z &&
light_local_vel.xyz.y > light_sip->collision_physics.reorient_min_y &&
abs(light_local_vel.xyz.x) < light_sip->collision_physics.reorient_max_x &&
light_uvec_dot_norm > 0 &&
light_fvec_dot_norm < light_sip->collision_physics.reorient_max_angle &&
light_fvec_dot_norm > light_sip->collision_physics.reorient_min_angle &&
abs(light_rvec_dot_norm) < light_sip->collision_physics.reorient_max_rot_angle)
{
vec3d landing_delta_rotvel;
landing_delta_rotvel.xyz.x = (light_fvec_dot_norm * light_sip->collision_physics.reorient_mult)
- light_sip->collision_physics.landing_rest_angle;
// For yaw, use the dot product between vel vector (normalized) and orientation on the xz plane
// This reduces to the following math
// We also clamp to reduce huge nose swings at low speeds
float xzVelMag = sqrt(light_local_vel.xyz.x * light_local_vel.xyz.x + light_local_vel.xyz.z * light_local_vel.xyz.z);
float xzVelDotOrient = MIN(MAX((xzVelMag > 0 ? (light_local_vel.xyz.x / xzVelMag) : 0), -0.5f), 0.5f);
landing_delta_rotvel.xyz.y = (xzVelMag > 2) ? (xzVelDotOrient * light_sip->collision_physics.reorient_mult) : 0;
landing_delta_rotvel.xyz.z = light_rvec_dot_norm * light_sip->collision_physics.reorient_mult * -1;
vm_vec_add2( &light->phys_info.rotvel, &landing_delta_rotvel );
}
// Find final positions
// We will try not to worry about the left over time in the frame
@@ -835,11 +925,18 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
Assert( !vm_is_vec_nan(&direction_light) );
vm_vec_scale_add2(&heavy->pos, &direction_light, 0.2f * light->phys_info.mass / (heavy->phys_info.mass + light->phys_info.mass));
vm_vec_scale_add2(&light->pos, &direction_light, -0.2f * heavy->phys_info.mass / (heavy->phys_info.mass + light->phys_info.mass));
vm_vec_scale_add2(&heavy->pos, &ship_ship_hit_info->collision_normal, -0.1f * light->phys_info.mass / (heavy->phys_info.mass + light->phys_info.mass));
vm_vec_scale_add2(&light->pos, &ship_ship_hit_info->collision_normal, 0.1f * heavy->phys_info.mass / (heavy->phys_info.mass + light->phys_info.mass));
//For landings, we want minimal movement on the light ship (just enough to keep the collision detection honest)
//TODO: Solution that works reliably landing on a moving ship
if (ship_ship_hit_info->is_landing) {
vm_vec_scale_add2(&light->pos, &ship_ship_hit_info->collision_normal, LANDING_POS_OFFSET);
}
else {
vm_vec_scale_add2(&light->pos, &direction_light, -0.2f * heavy->phys_info.mass / (heavy->phys_info.mass + light->phys_info.mass));
vm_vec_scale_add2(&light->pos, &ship_ship_hit_info->collision_normal, 0.1f * heavy->phys_info.mass / (heavy->phys_info.mass + light->phys_info.mass));
}
// restore mass in case of special cruuiser / asteroid collision
// restore mass in case of special cruiser / asteroid collision
if (special_cruiser_asteroid_collision) {
if (cruiser_light) {
light->phys_info.mass = copy_mass;
@@ -1123,11 +1220,13 @@ int collide_ship_ship( obj_pair * pair )
}
}
ship_info *light_sip = &Ship_info[Ships[LightOne->instance].ship_info_index];
// create ship_ship_or_debris_hit
// inputs obj A, obj B
// outputs hitpos, impulse (for damage), shield hit tri (for quadrant)
collision_info_struct ship_ship_hit_info;
memset(&ship_ship_hit_info, -1, sizeof(collision_info_struct));
init_collision_info_struct(&ship_ship_hit_info);
ship_ship_hit_info.heavy = HeavyOne; // heavy object, generally slower moving
ship_ship_hit_info.light = LightOne; // light object, generally faster moving
@@ -1214,7 +1313,8 @@ int collide_ship_ship( obj_pair * pair )
// }
// }
#endif
if ( player_involved ) {
//Only flash the "Collision" text if not landing
if ( player_involved && !ship_ship_hit_info.is_landing) {
hud_start_text_flash(XSTR("Collision", 1431), 2000);
}
}
@@ -1223,7 +1323,23 @@ int collide_ship_ship( obj_pair * pair )
// vm_vec_add(&world_hit_pos, &ship_ship_hit_info.heavy->pos, &ship_ship_hit_info.hit_pos);
collide_ship_ship_do_sound(&world_hit_pos, A, B, player_involved);
//If this is a landing, play a different sound
if (ship_ship_hit_info.is_landing) {
if (vm_vec_mag(&ship_ship_hit_info.light_rel_vel) > MIN_LANDING_SOUND_VEL) {
if ( player_involved ) {
if ( !snd_is_playing(Player_collide_sound) ) {
Player_collide_sound = snd_play_3d( &Snds[light_sip->collision_physics.landing_sound_idx], &world_hit_pos, &View_position );
}
} else {
if ( !snd_is_playing(AI_collide_sound) ) {
AI_collide_sound = snd_play_3d( &Snds[light_sip->collision_physics.landing_sound_idx], &world_hit_pos, &View_position );
}
}
}
}
else {
collide_ship_ship_do_sound(&world_hit_pos, A, B, player_involved);
}
// check if we should do force feedback stuff
if (player_involved && (ship_ship_hit_info.impulse > 0)) {
@@ -1258,35 +1374,38 @@ int collide_ship_ship( obj_pair * pair )
// nprintf(("AI", "Ship:ship collision: %s and %s.\n", Ships[A->instance].ship_name, Ships[B->instance].ship_name));
// Scale damage based on skill level for player.
if ((LightOne->flags & OF_PLAYER_SHIP) || (HeavyOne->flags & OF_PLAYER_SHIP)) {
damage *= (float) (Game_skill_level*Game_skill_level+1)/(NUM_SKILL_LEVELS+1);
} else if (Ships[LightOne->instance].team == Ships[HeavyOne->instance].team) {
// Decrease damage if non-player ships and not large.
// Looks dumb when fighters are taking damage from bumping into each other.
if ((LightOne->radius < 50.0f) && (HeavyOne->radius <50.0f)) {
damage /= 4.0f;
//Only do damage if not a landing
if (!ship_ship_hit_info.is_landing) {
// Scale damage based on skill level for player.
if ((LightOne->flags & OF_PLAYER_SHIP) || (HeavyOne->flags & OF_PLAYER_SHIP)) {
damage *= (float) (Game_skill_level*Game_skill_level+1)/(NUM_SKILL_LEVELS+1);
} else if (Ships[LightOne->instance].team == Ships[HeavyOne->instance].team) {
// Decrease damage if non-player ships and not large.
// Looks dumb when fighters are taking damage from bumping into each other.
if ((LightOne->radius < 50.0f) && (HeavyOne->radius <50.0f)) {
damage /= 4.0f;
}
}
float dam2 = (100.0f * damage/LightOne->phys_info.mass);
int quadrant_num = get_ship_quadrant_from_global(&world_hit_pos, ship_ship_hit_info.heavy);
//nprintf(("AI", "Ship %s hit in quad #%i\n", Ships[ship_ship_hit_info.heavy->instance].ship_name, quadrant_num));
if ((ship_ship_hit_info.heavy->flags & OF_NO_SHIELDS) || !ship_is_shield_up(ship_ship_hit_info.heavy, quadrant_num) ) {
quadrant_num = -1;
}
ship_apply_local_damage(ship_ship_hit_info.heavy, ship_ship_hit_info.light, &world_hit_pos, 100.0f * damage/HeavyOne->phys_info.mass, quadrant_num, CREATE_SPARKS, ship_ship_hit_info.submodel_num, &ship_ship_hit_info.collision_normal);
hud_shield_quadrant_hit(ship_ship_hit_info.heavy, quadrant_num);
//nprintf(("AI", "Ship %s hit in quad #%i\n", Ships[ship_ship_hit_info.light->instance].ship_name, quadrant_num));
// don't draw sparks (using sphere hitpos)
ship_apply_local_damage(ship_ship_hit_info.light, ship_ship_hit_info.heavy, &world_hit_pos, dam2, MISS_SHIELDS, NO_SPARKS, -1, &ship_ship_hit_info.collision_normal);
hud_shield_quadrant_hit(ship_ship_hit_info.light, quadrant_num);
maybe_push_little_ship_from_fast_big_ship(ship_ship_hit_info.heavy, ship_ship_hit_info.light, ship_ship_hit_info.impulse, &ship_ship_hit_info.collision_normal);
//nprintf(("AI", "Damage to %s = %7.3f\n", Ships[LightOne->instance].ship_name, dam2));
}
float dam2 = (100.0f * damage/LightOne->phys_info.mass);
int quadrant_num = get_ship_quadrant_from_global(&world_hit_pos, ship_ship_hit_info.heavy);
//nprintf(("AI", "Ship %s hit in quad #%i\n", Ships[ship_ship_hit_info.heavy->instance].ship_name, quadrant_num));
if ((ship_ship_hit_info.heavy->flags & OF_NO_SHIELDS) || !ship_is_shield_up(ship_ship_hit_info.heavy, quadrant_num) ) {
quadrant_num = -1;
}
ship_apply_local_damage(ship_ship_hit_info.heavy, ship_ship_hit_info.light, &world_hit_pos, 100.0f * damage/HeavyOne->phys_info.mass, quadrant_num, CREATE_SPARKS, ship_ship_hit_info.submodel_num, &ship_ship_hit_info.collision_normal);
hud_shield_quadrant_hit(ship_ship_hit_info.heavy, quadrant_num);
//nprintf(("AI", "Ship %s hit in quad #%i\n", Ships[ship_ship_hit_info.light->instance].ship_name, quadrant_num));
// don't draw sparks (using sphere hitpos)
ship_apply_local_damage(ship_ship_hit_info.light, ship_ship_hit_info.heavy, &world_hit_pos, dam2, MISS_SHIELDS, NO_SPARKS, -1, &ship_ship_hit_info.collision_normal);
hud_shield_quadrant_hit(ship_ship_hit_info.light, quadrant_num);
maybe_push_little_ship_from_fast_big_ship(ship_ship_hit_info.heavy, ship_ship_hit_info.light, ship_ship_hit_info.impulse, &ship_ship_hit_info.collision_normal);
//nprintf(("AI", "Damage to %s = %7.3f\n", Ships[LightOne->instance].ship_name, dam2));
}
if(!(b_override && !a_override))
+9
View File
@@ -1071,3 +1071,12 @@ void set_hit_struct_info(collision_info_struct *hit, mc_info *mc, int submodel_r
hit->submodel_rot_hit = submodel_rot_hit;
}
//Previously, this was done with
//memset(&ship_ship_hit_info, -1, sizeof(collision_info_struct));
//All those -1s are to replicate that logic
void init_collision_info_struct(collision_info_struct *cis)
{
memset(cis, -1, sizeof(collision_info_struct));
cis->is_landing = false;
}
+7
View File
@@ -35,8 +35,14 @@ typedef struct collision_info_struct {
int submodel_num; // submodel of heavy object that is hit
int edge_hit; // if edge is hit, need to change collision normal
int submodel_rot_hit; // if collision is against rotating submodel
bool is_landing; //SUSHI: Maybe treat current collision as a landing
} collision_info_struct;
//Collision physics constants
#define COLLISION_FRICTION_FACTOR 0.0f //Default value if not set in ships.tbl
#define COLLISION_ROTATION_FACTOR 0.2f //Default value if not set in ships.tbl
#define MIN_LANDING_SOUND_VEL 2.0f
#define LANDING_POS_OFFSET 0.05f
//===============================================================================
// GENERAL COLLISION DETECTION HELPER FUNCTIONS
@@ -138,4 +144,5 @@ int get_ship_quadrant_from_global(vec3d *global_pos, object *objp);
int reject_due_collision_groups(object *A, object *B);
void init_collision_info_struct(collision_info_struct *cis);
#endif
+2 -2
View File
@@ -779,8 +779,8 @@ void obj_move_call_physics(object *objp, float frametime)
if (shipp->weapons.num_secondary_banks > 0) {
polymodel *pm = model_get(Ship_info[shipp->ship_info_index].model_num);
Assert( pm != NULL );
Assert( pm->missile_banks != NULL );
Assertion( pm != NULL, "No polymodel found for ship %s", Ship_info[shipp->ship_info_index].name );
Assertion( pm->missile_banks != NULL, "Ship %s has %d secondary banks, but no missile banks could be found.\n", Ship_info[shipp->ship_info_index].name, shipp->weapons.num_secondary_banks );
for (int i = 0; i < shipp->weapons.num_secondary_banks; i++) {
//if there are no missles left don't bother
+4
View File
@@ -673,6 +673,10 @@ int obj_snd_assign(int objnum, int sndnum, vec3d *pos, int main, int flags, ship
if ( Obj_snd_enabled == FALSE )
return -1;
//Initialize object sound list, if not initialized
if (!Obj_snd_level_inited)
obj_snd_level_init();
obj_snd *snd = NULL;
object *objp = &Objects[objnum];
int idx, sound_index;
+123 -4
View File
@@ -3248,6 +3248,17 @@ ADE_FUNC(getScreenCoords, l_Vector, NULL, "Gets screen cordinates of a world vec
return ade_set_args(L, "ff", vtx.sx, vtx.sy);
}
ADE_FUNC(getNormalized, l_Vector, NULL, "Returns a normalized version of the vector", "vector", "Normalized Vector, or NIL if invalid")
{
vec3d v3;
if(!ade_get_args(L, "o", l_Vector.Get(&v3)))
return ADE_RETURN_NIL;
vm_vec_normalize(&v3);
return ade_set_args(L, "o", l_Vector.Set(v3));
}
//**********HANDLE: material
static const int THT_INDEPENDENT = 0;
static const int THT_OBJECT = 1;
@@ -4091,6 +4102,69 @@ ADE_VIRTVAR(CollisionGroups, l_Object, "number", "Collision group data", "number
return ade_set_args(L, "i", objh->objp->collision_group_id);
}
ADE_FUNC(getfvec, l_Object, "[boolean normalize]", "Returns the objects' current fvec.", "vector", "Objects' forward vector, or nil if invalid. If called with a true argument, vector will be normalized.")
{
object_h *objh = NULL;
object *obj = NULL;
bool normalize = false;
if (!ade_get_args(L, "o|b", l_Object.GetPtr(&objh), &normalize)) {
return ADE_RETURN_NIL;
}
if(!objh->IsValid())
return ADE_RETURN_NIL;
obj = objh->objp;
vec3d v1 = obj->orient.vec.fvec;
if (normalize)
vm_vec_normalize(&v1);
return ade_set_args(L, "o", l_Vector.Set(v1));
}
ADE_FUNC(getuvec, l_Object, "[boolean normalize]", "Returns the objects' current uvec.", "vector", "Objects' up vector, or nil if invalid. If called with a true argument, vector will be normalized.")
{
object_h *objh = NULL;
object *obj = NULL;
bool normalize = false;
if (!ade_get_args(L, "o|b", l_Object.GetPtr(&objh), &normalize)) {
return ADE_RETURN_NIL;
}
if(!objh->IsValid())
return ADE_RETURN_NIL;
obj = objh->objp;
vec3d v1 = obj->orient.vec.uvec;
if (normalize)
vm_vec_normalize(&v1);
return ade_set_args(L, "o", l_Vector.Set(v1));
}
ADE_FUNC(getrvec, l_Object, "[boolean normalize]", "Returns the objects' current rvec.", "vector", "Objects' rvec, or nil if invalid. If called with a true argument, vector will be normalized.")
{
object_h *objh = NULL;
object *obj = NULL;
bool normalize = false;
if (!ade_get_args(L, "o|b", l_Object.GetPtr(&objh), &normalize)) {
return ADE_RETURN_NIL;
}
if(!objh->IsValid())
return ADE_RETURN_NIL;
obj = objh->objp;
vec3d v1 = obj->orient.vec.fvec;
if (normalize)
vm_vec_normalize(&v1);
return ade_set_args(L, "o", l_Vector.Set(v1));
}
ADE_FUNC(checkRayCollision, l_Object, "vector Start Point, vector End Point, [boolean Local]", "Checks the collisions between the polygons of the current object and a ray", "vector Position", "World collision point (local if boolean is set to true), nil if no collisions")
{
object_h *objh = NULL;
@@ -4105,20 +4179,27 @@ ADE_FUNC(checkRayCollision, l_Object, "vector Start Point, vector End Point, [bo
return ADE_RETURN_NIL;
obj = objh->objp;
int flags = 0;
int submodel = -1;
switch(obj->type) {
case OBJ_SHIP:
model_num = Ship_info[Ships[obj->instance].ship_info_index].model_num;
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
break;
case OBJ_WEAPON:
model_num = Weapon_info[Weapons[obj->instance].weapon_info_index].model_num;
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
break;
case OBJ_DEBRIS:
model_num = Debris[obj->instance].model_num;
flags = (MC_CHECK_MODEL | MC_CHECK_RAY | MC_SUBMODEL);
submodel = Debris[obj->instance].submodel_num;
break;
case OBJ_ASTEROID:
temp = Asteroids[obj->instance].asteroid_subtype;
model_num = Asteroid_info[Asteroids[obj->instance].asteroid_type].model_num[temp];
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
break;
default:
return ADE_RETURN_NIL;
@@ -4130,11 +4211,12 @@ ADE_FUNC(checkRayCollision, l_Object, "vector Start Point, vector End Point, [bo
mc_info hull_check;
hull_check.model_num = model_num;
hull_check.submodel_num = submodel;
hull_check.orient = &obj->orient;
hull_check.pos = &obj->pos;
hull_check.p0 = v3a;
hull_check.p1 = v3b;
hull_check.flags = MC_CHECK_MODEL | MC_CHECK_RAY;
hull_check.flags = flags;
if ( !model_collide(&hull_check) ) {
return ADE_RETURN_NIL;
@@ -5521,7 +5603,7 @@ ADE_VIRTVAR(SecondaryBanks, l_Subsystem, "weaponbanktype", "Array of secondary w
}
ADE_VIRTVAR(Target, l_Subsystem, "object", "Object targetted by this subsystem", "object", "Targeted object, or invalid object handle if subsystem handle is invalid")
ADE_VIRTVAR(Target, l_Subsystem, "object", "Object targetted by this subsystem. If used to set a new target, AI targeting will be switched off.", "object", "Targeted object, or invalid object handle if subsystem handle is invalid")
{
ship_subsys_h *sso;
object_h *objh;
@@ -5538,11 +5620,28 @@ ADE_VIRTVAR(Target, l_Subsystem, "object", "Object targetted by this subsystem",
ss->turret_enemy_objnum = OBJ_INDEX(objh->objp);
ss->turret_enemy_sig = objh->sig;
ss->targeted_subsys = NULL;
ss->scripting_target_override = true;
}
return ade_set_object_with_breed(L, ss->turret_enemy_objnum);
}
ADE_FUNC(targetingOverride, l_Subsystem, "boolean", "If set to true, AI targeting for this turret is switched off. If set to false, the AI will take over again.", "boolean", "Returns true if successful, false otherwise")
{
bool targetOverride = false;
ship_subsys_h *sso;
if(!ade_get_args(L, "ob", l_Subsystem.GetPtr(&sso), &targetOverride))
return ADE_RETURN_FALSE;
if(!sso->IsValid())
return ADE_RETURN_FALSE;
ship_subsys *ss = sso->ss;
ss->scripting_target_override = targetOverride;
return ADE_RETURN_TRUE;
}
ADE_FUNC(hasFired, l_Subsystem, NULL, "Determine if a subsystem has fired", "boolean", "true if if fired, false if not fired, or nil if invalid. resets fired flag when called.")
{
ship_subsys_h *sso;
@@ -6247,6 +6346,7 @@ ADE_FUNC(hasShipExploded, l_Ship, NULL, "Checks if the ship explosion event has
if (shipp->pre_death_explosion_happened == 1) {
return ade_set_args(L, "i", 1);
}
return ade_set_args(L, "i", 3);
}
return ade_set_args(L, "i", 0);
@@ -6706,6 +6806,25 @@ ADE_FUNC(isWarpingIn, l_Ship, NULL, "Checks if ship is warping in", "boolean", "
return ADE_RETURN_FALSE;
}
ADE_FUNC(getEMP, l_Ship, NULL, "Returns the current emp effect strength acting on the object", "number", "Current EMP effect strength or NIL if object is invalid")
{
object_h *objh = NULL;
object *obj = NULL;
if (!ade_get_args(L, "o", l_Ship.GetPtr(&objh))) {
return ADE_RETURN_NIL;
}
if(!objh->IsValid())
return ADE_RETURN_NIL;
obj = objh->objp;
ship *shipp = &Ships[obj->instance];
return ade_set_args(L, "f", shipp->emp_intensity);
}
//**********HANDLE: Weapon
ade_obj<object_h> l_Weapon("weapon", "Weapon handle", &l_Object);
@@ -8140,7 +8259,7 @@ ADE_FUNC(playGameSound, l_Audio, "Sound index, [Panning (-1.0 left to 1.0 right)
if(vol > 100.0f)
vol = 100.0f;
idx = snd_play(&Snds[idx], pan, vol*0.01f, pri, voice_msg);
idx = snd_play(&Snds[gamesnd_get_by_tbl_index(idx)], pan, vol*0.01f, pri, voice_msg);
return ade_set_args(L, "b", idx > -1);
}
@@ -8151,7 +8270,7 @@ ADE_FUNC(playInterfaceSound, l_Audio, "Sound index", "Plays a sound from #Interf
if(!ade_get_args(L, "i", &idx))
return ade_set_error(L, "b", false);
gamesnd_play_iface(idx);
gamesnd_play_iface(gamesnd_get_by_iface_tbl_index(idx));
return ade_set_args(L, "b", idx > -1);
}
+3 -1
View File
@@ -2365,7 +2365,9 @@ int stuff_loadout_list (int *ilp, int max_ints, int lookup_type)
}
else if ((lookup_type == MISSION_LOADOUT_WEAPON_LIST) && (!(Weapon_info[index].wi_flags & WIF_PLAYER_ALLOWED)) ) {
clean_loadout_list_entry();
Warning(LOCATION, "Weapon type \"%s\" found in loadout of mission file. This class is not marked as a player allowed weapon...skipping", str);
nprintf(("Warning", "Warning: Weapon type %s found in loadout of mission file. This class is not marked as a player allowed weapon...skipping\n", str));
if ( !Is_standalone )
Warning(LOCATION, "Weapon type \"%s\" found in loadout of mission file. This class is not marked as a player allowed weapon...skipping", str);
continue;
}
+814 -121
View File
File diff suppressed because it is too large. Load diff
+25 -6
View File
@@ -117,6 +117,9 @@ struct ship;
#define OPF_HUD_ELEMENT 71 // A magic name of a specific HUD element
#define OPF_SOUND_ENVIRONMENT 72 // Goober5000 - one of EFX_presets, per Taylor
#define OPF_SOUND_ENVIRONMENT_OPTION 73 // Goober5000 - one of Taylor's options
#define OPF_EXPLOSION_OPTION 74 // Goober5000
#define OPF_AUDIO_VOLUME_OPTION 75 // The E
#define OPF_WEAPON_BANK_NUMBER 76 // Karajomra - The number of a primary/secondary/tertiary weapon bank or all of them
// Operand return types
#define OPR_NUMBER 1 // returns number
@@ -338,6 +341,8 @@ struct ship;
#define OP_GET_THROTTLE_SPEED (0x003a | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Karajorma
#define OP_HITS_LEFT_SUBSYSTEM_GENERIC (0x003b | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_HITS_LEFT_SUBSYSTEM_SPECIFIC (0x003c | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_HAS_PRIMARY_WEAPON (0x003d | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Karajorma
#define OP_HAS_SECONDARY_WEAPON (0x003e | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Karajorma
// conditional sexpressions
@@ -468,7 +473,7 @@ struct ship;
#define OP_CLOSE_SOUND_FROM_FILE (0x0064 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_HUD_DISABLE (0x0065 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_KAMIKAZE (0x0066 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) //-Sesquipedalian
#define OP_NOT_KAMIKAZE (0x0067 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) //-Sesquipedalian
#define OP_MISSION_SET_SUBSPACE (0x0067 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG)
#define OP_TURRET_TAGGED_SPECIFIC (0x0068 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) //phreak
#define OP_TURRET_TAGGED_CLEAR_SPECIFIC (0x0069 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) //phreak
#define OP_LOCK_ROTATING_SUBSYSTEM (0x006a | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
@@ -584,10 +589,13 @@ struct ship;
#define OP_SET_ARMOR_TYPE (0x00d2 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
#define OP_CUTSCENES_SHOW_SUBTITLE_TEXT (0x00d3 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_CUTSCENES_SHOW_SUBTITLE_IMAGE (0x00d4 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_MISSION_SET_SUBSPACE (0x00d5 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG)
#define OP_HUD_DISPLAY_GAUGE (0x00d6 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG)
#define OP_SET_SOUND_ENVIRONMENT (0x00d7 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Taylor
#define OP_UPDATE_SOUND_ENVIRONMENT (0x00d8 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Taylor
#define OP_HUD_DISPLAY_GAUGE (0x00d5 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG)
#define OP_SET_SOUND_ENVIRONMENT (0x00d6 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Taylor
#define OP_UPDATE_SOUND_ENVIRONMENT (0x00d7 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Taylor
#define OP_SET_EXPLOSION_OPTION (0x00d8 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_ADJUST_AUDIO_VOLUME (0x00d9 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // The E
#define OP_SHIP_CHANGE_CALLSIGN (0x00da | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
#define OP_IS_FACING (0x00db | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // The E
/* made obsolete by Goober5000
// debugging sexpressions
@@ -687,11 +695,13 @@ struct ship;
// defines for string constants
#define SEXP_HULL_STRING "Hull"
#define SEXP_SIM_HULL_STRING "Simulated Hull"
#define SEXP_SHIELD_STRING "Shields"
#define SEXP_ALL_ENGINES_STRING "<all engines>"
#define SEXP_ALL_TURRETS_STRING "<all turrets>"
#define SEXP_ARGUMENT_STRING "<argument>"
#define SEXP_NONE_STRING "<none>"
#define SEXP_SHIELD_STRING "Shields"
#define SEXP_ANY_STRING "<any string>"
#define SEXP_ALL_BANKS_STRING "<all weapon banks>"
// macros for accessing sexpression atoms
#define CAR(n) ((n < 0) ? -1 : Sexp_nodes[n].first)
@@ -856,6 +866,7 @@ char *CTEXT(int n);
#define SEXP_CHECK_INVALID_HUD_ELEMENT -143
#define SEXP_CHECK_INVALID_SOUND_ENVIRONMENT -144
#define SEXP_CHECK_INVALID_SOUND_ENVIRONMENT_OPTION -145
#define SEXP_CHECK_INVALID_EXPLOSION_OPTION -146
#define TRAINING_CONTEXT_SPEED (1<<0)
#define TRAINING_CONTEXT_FLY_PATH (1<<1)
@@ -1061,6 +1072,14 @@ void multi_sexp_eval();
extern int Num_sound_environment_options;
extern char *Sound_environment_option[];
// Goober5000
extern int Num_explosion_options;
extern char *Explosion_option[];
//The E
extern int Num_adjust_audio_options;
extern char *Adjust_audio_options[];
/** Global state variables for the hud-display-gauge sexp.
They all should be named Sexp_hud_display_*;
They all should follow the following symantics for the value of the
+6 -4
View File
@@ -1074,7 +1074,7 @@ void physics_apply_shock(vec3d *direction_vec, float pressure, physics_info *pi,
// Warning: Do not change ROTVEL_COLLIDE_WHACK_CONST. This will mess up collision physics.
// If you need to change the rotation, change COLLISION_ROTATION_FACTOR in collide_ship_ship.
#define ROTVEL_COLLIDE_WHACK_CONST 1.0
void physics_collide_whack( vec3d *impulse, vec3d *world_delta_rotvel, physics_info *pi, matrix *orient )
void physics_collide_whack( vec3d *impulse, vec3d *world_delta_rotvel, physics_info *pi, matrix *orient, bool is_landing )
{
vec3d body_delta_rotvel;
@@ -1095,9 +1095,11 @@ void physics_collide_whack( vec3d *impulse, vec3d *world_delta_rotvel, physics_i
update_reduced_damp_timestamp( pi, vm_vec_mag(impulse) );
// find time for shake from weapon to end
int dtime = timestamp_until(pi->afterburner_decay);
if (dtime < WEAPON_SHAKE_TIME) {
pi->afterburner_decay = timestamp( WEAPON_SHAKE_TIME );
if (!is_landing) {
int dtime = timestamp_until(pi->afterburner_decay);
if (dtime < WEAPON_SHAKE_TIME) {
pi->afterburner_decay = timestamp( WEAPON_SHAKE_TIME );
}
}
pi->flags |= PF_REDUCED_DAMP;
+1 -1
View File
@@ -132,7 +132,7 @@ extern void physics_sim_vel(vec3d * position, physics_info * pi, float sim_time,
extern void physics_sim_rot(matrix * orient, physics_info * pi, float sim_time );
extern void physics_apply_whack(vec3d *force, vec3d *pos, physics_info *pi, matrix *orient, float mass);
extern void physics_apply_shock(vec3d *direction_vec, float pressure, physics_info *pi, matrix *orient, vec3d *min, vec3d *max, float radius);
extern void physics_collide_whack(vec3d *impulse, vec3d *delta_rotvel, physics_info *pi, matrix *orient);
extern void physics_collide_whack(vec3d *impulse, vec3d *delta_rotvel, physics_info *pi, matrix *orient, bool is_landing);
int check_rotvel_limit( physics_info *pi );
+1 -1
View File
@@ -1498,7 +1498,7 @@ int player_inspect_cargo(float frametime, char *outstr)
Assert ( cargo_sip->flags & (SIF_CARGO|SIF_TRANSPORT) );
if ( cargo_name[0] == '#' )
sprintf(outstr, XSTR( "passengers:\n %s", 83), cargo_name+1 );
sprintf(outstr, XSTR( "passengers: %s", 83), cargo_name+1 );
else
sprintf(outstr,XSTR( "cargo: %s", 84), cargo_name );
} else {
+7 -7
View File
@@ -100,7 +100,7 @@ int png_read_header(char *real_filename, CFILE *img_cfp, int *w, int *h, int *bp
{
mprintf(("png_read_header: error creating info struct\n"));
cfclose(png_file);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return PNG_ERROR_READING;
}
@@ -108,7 +108,7 @@ int png_read_header(char *real_filename, CFILE *img_cfp, int *w, int *h, int *bp
{
mprintf(("png_read_header: something went wrong\n"));
/* Free all of the memory associated with the png_ptr and info_ptr */
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
cfclose(png_file);
/* If we get here, we had a problem reading the file */
return PNG_ERROR_READING;
@@ -128,7 +128,7 @@ int png_read_header(char *real_filename, CFILE *img_cfp, int *w, int *h, int *bp
png_file = NULL;
}
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return PNG_ERROR_NONE;
}
@@ -183,7 +183,7 @@ int png_read_bitmap(char *real_filename, ubyte *image_data, ubyte *bpp, int dest
{
mprintf(("png_read_bitmap: info_ptr went wrong\n"));
cfclose(png_file);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return PNG_ERROR_READING;
}
@@ -191,7 +191,7 @@ int png_read_bitmap(char *real_filename, ubyte *image_data, ubyte *bpp, int dest
{
mprintf(("png_read_bitmap: something went wrong\n"));
/* Free all of the memory associated with the png_ptr and info_ptr */
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
cfclose(png_file);
/* If we get here, we had a problem reading the file */
return PNG_ERROR_READING;
@@ -199,7 +199,7 @@ int png_read_bitmap(char *real_filename, ubyte *image_data, ubyte *bpp, int dest
png_set_read_fn(png_ptr, &png_file, png_scp_read_data);
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR | PNG_TRANSFORM_EXPAND, png_voidp_NULL);
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR | PNG_TRANSFORM_EXPAND, NULL);
len = png_get_rowbytes(png_ptr, info_ptr);
row_pointers = png_get_rows(png_ptr, info_ptr);
@@ -212,7 +212,7 @@ int png_read_bitmap(char *real_filename, ubyte *image_data, ubyte *bpp, int dest
memcpy(&image_data[i * len], row_pointers[i], len);
}
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
cfclose(png_file);
return PNG_ERROR_NONE;
+5 -1
View File
@@ -312,7 +312,11 @@ void radar_plot_object_orb( object *objp )
return;
}
vm_vec_normalize(&pos);
if (IS_VEC_NULL_SQ_SAFE(&pos)) {
vm_vec_make(&pos, 1.0f, 0.0f, 0.0f);
} else {
vm_vec_normalize(&pos);
}
float scale = dist / Radar_bright_range;
if (scale > 1.25f) scale = 1.25f;
+1 -1
View File
@@ -112,7 +112,7 @@ void load_shield_hit_bitmap()
if ( Shield_ani[i].first_frame < 0 )
Int3();
*/
Assert(Species_info[i].shield_anim.first_frame >= 0);
Assertion((Species_info[i].shield_anim.first_frame >= 0), "Error while loading shield hit ani: %s for species: %s\n", Species_info[i].shield_anim.filename, Species_info[i].species_name);
}
#endif
+247 -57
View File
@@ -72,7 +72,9 @@
#include "iff_defs/iff_defs.h"
#include "network/multiutil.h"
#include "network/multimsgs.h"
#include "autopilot/autopilot.h"
#include "cmdline/cmdline.h"
#include "object/objcollide.h"
@@ -105,8 +107,6 @@ extern void fs2netd_add_table_validation(char *tblname);
//#define MIN_COLLISION_MOVE_DIST 5.0
//#define COLLISION_VEL_CONST 0.1
#define COLLISION_FRICTION_FACTOR 0.0 // ratio of maximum friction impulse to repulsion impulse
#define COLLISION_ROTATION_FACTOR 1.0 // increase in rotation from collision
#define SHIP_REPAIR_SUBSYSTEM_RATE 0.01f
int Ai_render_debug_flag=0;
@@ -235,7 +235,8 @@ flag_def_list Subsystem_flags[] = {
{ "no subsystem targeting", MSS_FLAG_NO_SS_TARGETING, 0 },
{ "fire on target", MSS_FLAG_FIRE_ON_TARGET, 0 },
{ "reset when idle", MSS_FLAG_TURRET_RESET_IDLE, 0 },
{ "carry shockwave", MSS_FLAG_CARRY_SHOCKWAVE, 0 }
{ "carry shockwave", MSS_FLAG_CARRY_SHOCKWAVE, 0 },
{ "allow landing", MSS_FLAG_ALLOW_LANDING, 0 }
};
int Num_subsystem_flags = sizeof(Subsystem_flags)/sizeof(flag_def_list);
@@ -283,6 +284,7 @@ flag_def_list Ship_flags[] = {
{ "no thruster geometry noise", SIF2_NO_THRUSTER_GEO_NOISE, 1 },
{ "intrinsic no shields", SIF2_INTRINSIC_NO_SHIELDS, 1 },
{ "no primary linking", SIF2_NO_PRIMARY_LINKING, 1 },
{ "no pain flash", SIF2_NO_PAIN_FLASH, 1 },
// to keep things clean, obsolete options go last
{ "ballistic primaries", -1, 255 }
@@ -565,6 +567,8 @@ void parse_engine_wash(bool replace)
char *Warp_types[] = {
"Default",
"Knossos",
"Babylon5",
"Galactica",
"Homeworld",
"Hyperspace",
@@ -625,6 +629,7 @@ void init_ship_entry(ship_info *sip)
sip->type_str = sip->maneuverability_str = sip->armor_str = sip->manufacturer_str = NULL;
sip->desc = NULL;
sip->tech_title[0] = 0;
sip->tech_desc = NULL;
sip->ship_length = NULL;
sip->gun_mounts = NULL;
@@ -698,6 +703,30 @@ void init_ship_entry(ship_info *sip)
strcpy_s(sip->shockwave_name,"");*/
sip->collision_damage_type_idx = -1;
sip->collision_physics.both_small_bounce = 5.0; //Retail default collision physics
sip->collision_physics.bounce = 5.0;
sip->collision_physics.friction = COLLISION_FRICTION_FACTOR;
sip->collision_physics.rotation_factor = COLLISION_ROTATION_FACTOR;
// Default landing parameters
sip->collision_physics.landing_max_z = 0.0f;
sip->collision_physics.landing_min_z = 0.0f;
sip->collision_physics.landing_min_y = 0.0f;
sip->collision_physics.landing_max_x = 0.0f;
sip->collision_physics.landing_max_angle = 0.0f;
sip->collision_physics.landing_min_angle = 0.0f;
sip->collision_physics.landing_max_rot_angle = 0.0f;
sip->collision_physics.reorient_max_z = 0.0f;
sip->collision_physics.reorient_min_z = 0.0f;
sip->collision_physics.reorient_min_y = 0.0f;
sip->collision_physics.reorient_max_x = 0.0f;
sip->collision_physics.reorient_max_angle = 0.0f;
sip->collision_physics.reorient_min_angle = 0.0f;
sip->collision_physics.reorient_max_rot_angle = 0.0f;
sip->collision_physics.reorient_mult = 1.0f;
sip->collision_physics.landing_rest_angle = 0.0f;
sip->collision_physics.landing_sound_idx = -1;
sip->debris_min_lifetime = -1.0f;
sip->debris_max_lifetime = -1.0f;
sip->debris_min_speed = -1.0f;
@@ -1134,6 +1163,10 @@ int parse_ship_values(ship_info* sip, bool isTemplate, bool first_time, bool rep
}
if (optional_string("+Tech Title:")) {
stuff_string(sip->tech_title, F_NAME, NAME_LENGTH);
}
if (optional_string("+Tech Description:")) {
stuff_malloc_string(&sip->tech_desc, F_MULTITEXT, NULL, SHIP_MULTITEXT_LENGTH);
}
@@ -1329,6 +1362,88 @@ int parse_ship_values(ship_info* sip, bool isTemplate, bool first_time, bool rep
}
}
if(optional_string("$Collision Physics:"))
{
if(optional_string("+Bounce:")) {
stuff_float(&sip->collision_physics.bounce);
}
if(optional_string("+Both Small Bounce:")) {
stuff_float(&sip->collision_physics.both_small_bounce);
}
if(optional_string("+Friction:")) {
stuff_float(&sip->collision_physics.friction);
}
if(optional_string("+Rotation Factor:")) {
stuff_float(&sip->collision_physics.friction);
}
if(optional_string("+Landing Max Forward Vel:")) {
stuff_float(&sip->collision_physics.landing_max_z);
}
if(optional_string("+Landing Min Forward Vel:")) {
stuff_float(&sip->collision_physics.landing_min_z);
}
if(optional_string("+Landing Max Descent Vel:")) {
stuff_float(&sip->collision_physics.landing_min_y);
sip->collision_physics.landing_min_y *= -1;
}
if(optional_string("+Landing Max Horizontal Vel:")) {
stuff_float(&sip->collision_physics.landing_max_x);
}
if(optional_string("+Landing Max Angle:")) {
float degrees;
stuff_float(&degrees);
sip->collision_physics.landing_max_angle = cos(ANG_TO_RAD(90 - degrees));
}
if(optional_string("+Landing Min Angle:")) {
float degrees;
stuff_float(&degrees);
sip->collision_physics.landing_min_angle = cos(ANG_TO_RAD(90 - degrees));
}
if(optional_string("+Landing Max Rotate Angle:")) {
float degrees;
stuff_float(&degrees);
sip->collision_physics.landing_max_rot_angle = cos(ANG_TO_RAD(90 - degrees));
}
if(optional_string("+Reorient Max Forward Vel:")) {
stuff_float(&sip->collision_physics.reorient_max_z);
}
if(optional_string("+Reorient Min Forward Vel:")) {
stuff_float(&sip->collision_physics.reorient_min_z);
}
if(optional_string("+Reorient Max Descent Vel:")) {
stuff_float(&sip->collision_physics.reorient_min_y);
sip->collision_physics.reorient_min_y *= -1;
}
if(optional_string("+Reorient Max Horizontal Vel:")) {
stuff_float(&sip->collision_physics.reorient_max_x);
}
if(optional_string("+Reorient Max Angle:")) {
float degrees;
stuff_float(&degrees);
sip->collision_physics.reorient_max_angle = cos(ANG_TO_RAD(90 - degrees));
}
if(optional_string("+Reorient Min Angle:")) {
float degrees;
stuff_float(&degrees);
sip->collision_physics.reorient_min_angle = cos(ANG_TO_RAD(90 - degrees));
}
if(optional_string("+Reorient Max Rotate Angle:")) {
float degrees;
stuff_float(&degrees);
sip->collision_physics.reorient_max_rot_angle = cos(ANG_TO_RAD(90 - degrees));
}
if(optional_string("+Reorient Speed Mult:")) {
stuff_float(&sip->collision_physics.reorient_mult);
}
if(optional_string("+Landing Rest Angle:")) {
float degrees;
stuff_float(&degrees);
sip->collision_physics.landing_rest_angle = cos(ANG_TO_RAD(90 - degrees));
}
parse_sound("+Landing Sound:", &sip->collision_physics.landing_sound_idx, sip->name);
}
if(optional_string("$Debris:"))
{
if(optional_string("+Min Lifetime:")) {
@@ -2827,7 +2942,7 @@ strcpy_s(parse_error_text, temp_error);
sp->engine_wash_pointer = get_engine_wash_pointer(name_tmp);
if(sp->engine_wash_pointer == NULL)
Warning(LOCATION,"Invalid engine wash name %s specified for subsystem %s in ship class %s", name_tmp, sp->subobj_name, sip->name);
WarningEx(LOCATION,"Invalid engine wash name %s specified for subsystem %s in ship class %s", name_tmp, sp->subobj_name, sip->name);
}
parse_sound("$AliveSnd:", &sp->alive_snd, sp->subobj_name);
@@ -2911,6 +3026,10 @@ strcpy_s(parse_error_text, temp_error);
if (optional_string("$Flags:")) {
parse_string_flag_list((int*)&sp->flags, Subsystem_flags, Num_subsystem_flags);
//If we've set any subsystem as landable, set a ship-info flag as a shortcut for later
if (sp->flags & MSS_FLAG_ALLOW_LANDING)
sip->flags2 |= SIF2_ALLOW_LANDINGS;
}
if (optional_string("+non-targetable")) {
@@ -3661,7 +3780,7 @@ void ship_parse_post_cleanup()
// ultra stupid compatbility handling for the once broken "generate hud" flag.
// it was previously testing the afterburner flag, so that's what we check for that
if ( (sip->shield_icon_index == 255) && (sip->flags & SIF_AFTERBURNER)
&& !(sip->flags2 & SIF2_GENERATE_HUD_ICON) )
&& !(sip->flags2 & SIF2_GENERATE_HUD_ICON) && (sip->flags & SIF_PLAYER_SHIP) )
{
Warning(LOCATION, "Compatibility warning:\nNo shield icon specified for '%s' but the \"generate icon\" flag is not specified.\nEnabling flag by default.\n", sip->name);
sip->flags2 |= SIF2_GENERATE_HUD_ICON;
@@ -4130,6 +4249,8 @@ void ship_set_warp_effects(object *objp, ship_info *sip)
switch(sip->warpin_type)
{
case WT_DEFAULT:
case WT_KNOSSOS:
case WT_DEFAULT_THEN_KNOSSOS:
shipp->warpin_effect = new WE_Default(objp, WD_WARP_IN);
break;
case WT_IN_PLACE_ANIM:
@@ -4151,6 +4272,8 @@ void ship_set_warp_effects(object *objp, ship_info *sip)
switch(sip->warpout_type)
{
case WT_DEFAULT:
case WT_KNOSSOS:
case WT_DEFAULT_THEN_KNOSSOS:
shipp->warpout_effect = new WE_Default(objp, WD_WARP_OUT);
break;
case WT_IN_PLACE_ANIM:
@@ -4850,6 +4973,7 @@ int subsys_set(int objnum, int ignore_subsys_info)
ship_system->turret_time_enemy_in_range = 0.0f;
ship_system->disruption_timestamp=timestamp(0);
ship_system->turret_pick_big_attack_point_timestamp = timestamp(0);
ship_system->scripting_target_override = false;
vm_vec_zero(&ship_system->turret_big_attack_point);
for(j = 0; j < NUM_TURRET_ORDER_TYPES; j++)
{
@@ -5404,13 +5528,14 @@ void ship_render(object * obj)
//it is specified
//it isn't assigned already
//start sound doesn't exist or has finished
if(mtp->loop_snd >= 0
&& shipp->thrusters_sounds[i] < 0
&& (mtp->start_snd < 0 || (snd_get_duration(mtp->start_snd) < timestamp() - shipp->thrusters_start[i]))
)
{
shipp->thrusters_sounds[i] = obj_snd_assign(OBJ_INDEX(obj), mtp->loop_snd, &mtp->pos, 1);
}
if (!Cmdline_freespace_no_sound)
if(mtp->loop_snd >= 0
&& shipp->thrusters_sounds[i] < 0
&& (mtp->start_snd < 0 || (snd_get_duration(mtp->start_snd) < timestamp() - shipp->thrusters_start[i]))
)
{
shipp->thrusters_sounds[i] = obj_snd_assign(OBJ_INDEX(obj), mtp->loop_snd, &mtp->pos, 1);
}
//Draw graphics
//Skip invalid ones
@@ -7671,9 +7796,9 @@ void ship_set_default_weapons(ship *shipp, ship_info *sip)
for ( i = sip->num_primary_banks; i < pm->n_guns; i++ ) {
// Make unspecified weapon for bank be a laser
for ( j = 0; j < Num_player_weapon_precedence; j++ ) {
Assert(Player_weapon_precedence[j] > 0);
Assertion((Player_weapon_precedence[j] > 0), "Error reading player weapon precedence list. Check weapons.tbl for $Player Weapon Precedence entry, and correct as necessary.\n");
int weapon_id = Player_weapon_precedence[j];
if (Weapon_info[weapon_id].subtype & (WP_LASER || WP_BEAM)) {
if ( (Weapon_info[weapon_id].subtype == WP_LASER) || (Weapon_info[weapon_id].subtype == WP_BEAM) ) {
swp->primary_bank_weapons[i] = weapon_id;
break;
}
@@ -7696,7 +7821,7 @@ void ship_set_default_weapons(ship *shipp, ship_info *sip)
for ( j = 0; j < Num_player_weapon_precedence; j++ ) {
Assert(Player_weapon_precedence[j] > 0);
int weapon_id = Player_weapon_precedence[j];
if (Weapon_info[weapon_id].subtype & WP_MISSILE) {
if (Weapon_info[weapon_id].subtype == WP_MISSILE) {
swp->secondary_bank_weapons[i] = weapon_id;
break;
}
@@ -8229,6 +8354,7 @@ void change_ship_type(int n, int ship_type, int by_sexp)
ship_info *sip_orig;
ship *sp;
ship_weapon *swp;
ship_subsys *ss;
object *objp;
p_object *p_objp;
float hull_pct, shield_pct;
@@ -8240,37 +8366,71 @@ void change_ship_type(int n, int ship_type, int by_sexp)
swp = &sp->weapons;
sip_orig = &Ship_info[sp->ship_info_index];
objp = &Objects[sp->objnum];
ph_inf = objp->phys_info;
// Goober5000 - maintain the original hull and shield percentages when called by sexp
if (by_sexp)
// Goober5000 - maintain the original hull, shield, and subsystem percentages... gah
// hull
if (sp->special_hitpoints) {
hull_pct = objp->hull_strength / sp->ship_max_hull_strength;
} else {
Assert( Ship_info[sp->ship_info_index].max_hull_strength > 0.0f );
hull_pct = objp->hull_strength / Ship_info[sp->ship_info_index].max_hull_strength;
}
// extra check
Assert(hull_pct > 0.0f && hull_pct <= 1.0f);
if (hull_pct <= 0.0f) hull_pct = 0.1f;
if (hull_pct > 1.0f) hull_pct = 1.0f;
// shield
if (sp->special_shield > 0) {
shield_pct = shield_get_strength(objp) / sp->ship_max_shield_strength;
} else if (Ship_info[sp->ship_info_index].max_shield_strength > 0.0f) {
shield_pct = shield_get_strength(objp) / Ship_info[sp->ship_info_index].max_shield_strength;
} else {
shield_pct = 0.0f;
}
// extra check
Assert(shield_pct >= 0.0f && shield_pct <= 1.0f);
if (shield_pct < 0.0f) shield_pct = 0.0f;
if (shield_pct > 1.0f) shield_pct = 1.0f;
// subsystems
int num_saved_subsystems = 0;
char **subsys_names = new char *[sip_orig->n_subsystems];
float *subsys_pcts = new float[sip_orig->n_subsystems];
ss = GET_FIRST(&sp->subsys_list);
while ( ss != END_OF_LIST(&sp->subsys_list) )
{
// hull
if (sp->special_hitpoints) {
hull_pct = objp->hull_strength / sp->ship_max_hull_strength;
} else {
Assert( Ship_info[sp->ship_info_index].max_hull_strength > 0.0f );
hull_pct = objp->hull_strength / Ship_info[sp->ship_info_index].max_hull_strength;
if (num_saved_subsystems == sip_orig->n_subsystems)
{
Error(LOCATION, "Subsystem mismatch while changing ship class from '%s' to '%s'!", sip_orig->name, sip->name);
break;
}
// shield
if (sp->special_shield > 0) {
shield_pct = shield_get_strength(objp) / sp->ship_max_shield_strength;
} else if (Ship_info[sp->ship_info_index].max_shield_strength > 0.0f) {
shield_pct = shield_get_strength(objp) / Ship_info[sp->ship_info_index].max_shield_strength;
} else {
shield_pct = 0.0f;
}
// save subsys information
subsys_names[num_saved_subsystems] = new char[NAME_LENGTH];
strcpy(subsys_names[num_saved_subsystems], ss->system_info->subobj_name);
// physics
ph_inf = objp->phys_info;
if (ss->max_hits > 0.0f)
subsys_pcts[num_saved_subsystems] = ss->current_hits / ss->max_hits;
else
subsys_pcts[num_saved_subsystems] = ss->max_hits;
// extra check
Assert(subsys_pcts[num_saved_subsystems] >= 0.0f && subsys_pcts[num_saved_subsystems] <= 1.0f);
if (subsys_pcts[num_saved_subsystems] < 0.0f) subsys_pcts[num_saved_subsystems] = 0.0f;
if (subsys_pcts[num_saved_subsystems] > 1.0f) subsys_pcts[num_saved_subsystems] = 1.0f;
num_saved_subsystems++;
ss = GET_NEXT(ss);
}
// set to 100% otherwise
else
{
hull_pct = 1.0f;
shield_pct = 1.0f;
}
// make sure that shields are disabled/enabled if they need to be - Chief1983
if (!Fred_running) {
p_objp = mission_parse_get_parse_object(sp->ship_name);
@@ -8286,15 +8446,6 @@ void change_ship_type(int n, int ship_type, int by_sexp)
}
}
// Goober5000 - extra checks
Assert(hull_pct > 0.0f && hull_pct <= 1.0f);
Assert(shield_pct >= 0.0f && shield_pct <= 1.0f);
if (hull_pct <= 0.0f) hull_pct = 0.1f;
if (hull_pct > 1.0f) hull_pct = 1.0f;
if (shield_pct < 0.0f) shield_pct = 0.0f;
if (shield_pct > 1.0f) shield_pct = 1.0f;
// point to new ship data
ship_model_change(n, ship_type);
sp->ship_info_index = ship_type;
@@ -8346,8 +8497,36 @@ void change_ship_type(int n, int ship_type, int by_sexp)
// fix up the subsystems
subsys_set( sp->objnum );
sp->afterburner_fuel = MAX(0, sip->afterburner_fuel_capacity - (sip_orig->afterburner_fuel_capacity - sp->afterburner_fuel));
// Goober5000 - restore the subsystem percentages
ss = GET_FIRST(&sp->subsys_list);
while ( ss != END_OF_LIST(&sp->subsys_list) )
{
for (i = 0; i < num_saved_subsystems; i++)
{
if (!subsystem_stricmp(ss->system_info->subobj_name, subsys_names[i]))
{
ss->current_hits = ss->max_hits * subsys_pcts[i];
break;
}
}
ss = GET_NEXT(ss);
}
ship_recalc_subsys_strength(sp);
// now free the memory
for (i = 0; i < sip_orig->n_subsystems; i++)
delete[] subsys_names[i];
delete [] subsys_names;
delete [] subsys_pcts;
// DONE WITH PERCENTAGE STUFF
sp->afterburner_fuel = MAX(0, sip->afterburner_fuel_capacity - (sip_orig->afterburner_fuel_capacity - sp->afterburner_fuel));
sp->cmeasure_count = MAX(0, sip->cmeasure_max - (sip_orig->cmeasure_max - sp->cmeasure_count));
// avoid cases where either of these are 0
@@ -10925,7 +11104,7 @@ void ship_model_start(object *objp)
case SUBSYSTEM_ACTIVATION:
break;
case SUBSYSTEM_TURRET:
Assert( !(psub->flags & MSS_FLAG_ROTATES) ); // Turrets can't rotate!!! See John!
Assertion( !(psub->flags & MSS_FLAG_ROTATES), "Turret %s on ship %s has the $rotate or $triggered subobject property defined. Please fix the model.\n", psub->name, Ship_info[shipp->ship_info_index].name ); // Turrets can't rotate!!! See John!
break;
default:
Error(LOCATION, "Illegal subsystem type.\n");
@@ -11867,6 +12046,7 @@ int ship_do_rearm_frame( object *objp, float frametime )
// function which is used to find a repair ship to repair requester_obj. the way repair ships will work
// is:
// if repair ship present and ordered to depart, return NULL.
// if repair ship present and available, return pointer to that object.
// If repair ship present and busy, possibly return that object if he can satisfy the request soon enough.
// If repair ship present and busy and cannot satisfy request, return NULL to warp a new one in if below max number
@@ -11915,6 +12095,14 @@ object *ship_find_repair_ship( object *requester_obj )
continue;
}
/* Ship has been ordered to warpout but has not had a chance to
process the order.*/
Assert( Ships[objp->instance].ai_index != -1 );
ai_info* aip = &(Ai_info[Ships[objp->instance].ai_index]);
if ( ai_find_goal_index( aip->goals, AI_GOAL_WARP ) != -1 ) {
continue;
}
dist = vm_vec_dist_quick(&objp->pos, &requester_obj->pos);
if (!(Ai_info[shipp->ai_index].ai_flags & AIF_REPAIRING))
@@ -12854,12 +13042,10 @@ int ship_return_subsys_path_normal(ship *shipp, ship_subsys *ss, vec3d *gsubpos,
pm = model_get(Ship_info[shipp->ship_info_index].model_num);
Assert( pm != NULL );
if (ss->system_info->path_num > pm->n_paths) {
// possibly a bad model?
mprintf(("WARNING: Too many paths in '%s'! Max is %i and the requested path was %i for subsystem '%s'!\n", pm->filename, pm->n_paths, ss->system_info->path_num, ss->system_info->subobj_name));
// Int3();
// possibly a bad model?
Assertion(ss->system_info->path_num <= pm->n_paths, "Too many paths in '%s'! Max is %i and the requested path was %i for subsystem '%s'!\n", pm->filename, pm->n_paths, ss->system_info->path_num, ss->system_info->subobj_name);
if (ss->system_info->path_num > pm->n_paths)
return 1;
}
mp = &pm->paths[ss->system_info->path_num];
if ( mp->nverts >= 2 ) {
@@ -14731,6 +14917,10 @@ int is_support_allowed(object *objp)
{
// check updated mission conditions to allow support
// If running under autopilot support is not allowed
if ( AutoPilotEngaged )
return 0;
// none allowed
if (The_mission.support_ships.max_support_ships == 0)
return 0;
+53 -7
View File
@@ -259,6 +259,7 @@ typedef struct ship_subsys {
float optimum_range;
float favor_current_facing;
ship_subsys *targeted_subsys; // subsystem this turret is attacking
bool scripting_target_override;
int turret_pick_big_attack_point_timestamp; // Next time to pick an attack point for this turret
vec3d turret_big_attack_point; // local coordinate of point for this turret to attack on enemy
@@ -815,8 +816,10 @@ extern int ship_find_exited_ship_by_signature( int signature);
#define SIF2_NO_THRUSTER_GEO_NOISE (1 << 8) // Echelon9 - No thruster geometry noise.
#define SIF2_INTRINSIC_NO_SHIELDS (1 << 9) // Chief - disables shields for this ship even without No Shields in mission.
#define SIF2_NO_PRIMARY_LINKING (1 << 10) // Chief - slated for 3.7 originally, but this looks pretty simple to implement.
#define MAX_SHIP_FLAGS 11 // Number of distinct flags for flags field in ship_info struct
#define SIF2_NO_PAIN_FLASH (1 << 11) // The E - disable red pain flash
#define SIF2_ALLOW_LANDINGS (1 << 12) // SUSHI: Automatically set if any subsystems allow landings (as a shortcut)
// !!! IF YOU ADD A FLAG HERE BUMP MAX_SHIP_FLAGS !!!
#define MAX_SHIP_FLAGS 13 // Number of distinct flags for flags field in ship_info struct
#define SIF_DEFAULT_VALUE 0
#define SIF2_DEFAULT_VALUE 0
@@ -979,10 +982,51 @@ typedef struct man_thruster {
} man_thruster;
//Warp type defines
#define WT_DEFAULT 0
#define WT_IN_PLACE_ANIM 1
#define WT_SWEEPER 2
#define WT_HYPERSPACE 3
#define WT_DEFAULT 0
#define WT_KNOSSOS 1
#define WT_DEFAULT_THEN_KNOSSOS 2
#define WT_IN_PLACE_ANIM 3
#define WT_SWEEPER 4
#define WT_HYPERSPACE 5
// Holds variables for collision physics (Gets its own struct purely for clarity purposes)
// Most of this only really applies properly to small ships
typedef struct ship_collision_physics {
// Collision physics definitions: how a ship responds to collisions
float both_small_bounce; // Bounce factor when both ships are small
// This currently only comes into play if one ship is the player...
// blame retail for that.
float bounce; // Bounce factor for all other cases
float friction; // Controls lateral velocity lost when colliding with a large ship
float rotation_factor; // Affects the rotational energy of collisions... TBH not sure how.
// Speed & angle constraints for a smooth landing
// Note that all angles are stored as a dotproduct between normalized vectors instead. This saves us from having
// to do a lot of dot product calculations later.
float landing_max_z;
float landing_min_z;
float landing_min_y;
float landing_max_x;
float landing_max_angle;
float landing_min_angle;
float landing_max_rot_angle;
// Speed & angle constraints for a "rough" landing (one with normal collision consequences, but where
// the ship is still reoriented towards its resting orientation)
float reorient_max_z;
float reorient_min_z;
float reorient_min_y;
float reorient_max_x;
float reorient_max_angle;
float reorient_min_angle;
float reorient_max_rot_angle;
// Landing response parameters
float reorient_mult; // How quickly the ship will reorient towards it's resting position
float landing_rest_angle; // The vertical angle where the ship's orientation comes to rest
int landing_sound_idx; //Sound to play on successful landing collisions
} ship_collision_physics;
// The real FreeSpace ship_info struct.
typedef struct ship_info {
@@ -998,6 +1042,7 @@ typedef struct ship_info {
char *manufacturer_str; // string used by tooltips
char *desc; // string used by tooltips
char *tech_desc; // string used by tech database
char tech_title[NAME_LENGTH]; // ship's name (in tech database)
char *ship_length; // string used by multiplayer ship desc
char *gun_mounts; // string used by multiplayer ship desc
@@ -1053,7 +1098,8 @@ typedef struct ship_info {
float max_speed, min_speed, max_accel;
//Collision
int collision_damage_type_idx;
int collision_damage_type_idx;
ship_collision_physics collision_physics;
// ship explosion info
shockwave_create_info shockwave;
+13 -13
View File
@@ -3853,18 +3853,14 @@ int WE_Default::warpStart()
HUD_printf(NOX("Subspace drive engaged"));
}
int portal_objnum;
if (direction == WD_WARP_IN)
portal_objnum = shipp->special_warpin_objnum;
else if (direction == WD_WARP_OUT)
portal_objnum = shipp->special_warpout_objnum;
else
portal_objnum = -1;
portal_objp = NULL;
if(portal_objnum >= 0 && shipfx_special_warp_objnum_valid(portal_objnum))
if ((direction == WD_WARP_IN) && shipfx_special_warp_objnum_valid(shipp->special_warpin_objnum))
{
portal_objp = &Objects[portal_objnum];
portal_objp = &Objects[shipp->special_warpin_objnum];
}
else if ((direction == WD_WARP_OUT) && shipfx_special_warp_objnum_valid(shipp->special_warpout_objnum))
{
portal_objp = &Objects[shipp->special_warpout_objnum];
}
float warpout_speed = 0.0f;
@@ -3896,7 +3892,7 @@ int WE_Default::warpStart()
if (direction == WD_WARP_OUT)
{
// maybe special warpout
int fireball_type = ((portal_objp != NULL) || Cmdline_tbp) ? FIREBALL_KNOSSOS : FIREBALL_WARP;
int fireball_type = ((portal_objp != NULL) || (sip->warpout_type == WT_KNOSSOS) || (sip->warpout_type == WT_DEFAULT_THEN_KNOSSOS)) ? FIREBALL_KNOSSOS : FIREBALL_WARP;
// create fireball
warp_objnum = fireball_create(&pos, fireball_type, FIREBALL_WARP_EFFECT, OBJ_INDEX(objp), radius, 1, NULL, warp_time, shipp->ship_info_index, NULL, 0, 0, sip->warpout_snd_start, sip->warpout_snd_end);
@@ -3904,7 +3900,7 @@ int WE_Default::warpStart()
else if (direction == WD_WARP_IN)
{
// maybe special warpin
int fireball_type = (portal_objp != NULL) ? FIREBALL_KNOSSOS : FIREBALL_WARP;
int fireball_type = ((portal_objp != NULL) || (sip->warpin_type == WT_KNOSSOS)) ? FIREBALL_KNOSSOS : FIREBALL_WARP;
// create fireball
warp_objnum = fireball_create(&pos, fireball_type, FIREBALL_WARP_EFFECT, OBJ_INDEX(objp), radius, 0, NULL, warp_time, shipp->ship_info_index, NULL, 0, 0, sip->warpin_snd_start, sip->warpin_snd_end);
@@ -3922,8 +3918,11 @@ int WE_Default::warpStart()
return 0;
}
// maybe negate if special warp effect
fvec = Objects[warp_objnum].orient.vec.fvec;
// G5K 6/26/2010 this should no longer be needed
/*
// maybe negate if special warp effect
if (portal_objp != NULL)
{
float dot = vm_vec_dotprod(&fvec, &objp->orient.vec.fvec);
@@ -3934,6 +3933,7 @@ int WE_Default::warpStart()
vm_vec_negate(&fvec);
}
}
*/
stage_time_start = total_time_start = timestamp();
if(direction == WD_WARP_IN)
+1 -1
View File
@@ -1910,7 +1910,7 @@ static void ship_do_damage(object *ship_obj, object *other_obj, vec3d *hitpos, f
// apply pain to me
// Goober5000: make sure other_obj doesn't cause a read violation!
if (other_obj)
if (other_obj && !(Ship_info[Ships[Player_obj->instance].ship_info_index].flags2 & SIF2_NO_PAIN_FLASH))
{
// For the record, ship_hit_pain seems to simply be the red flash that appears
// on the screen when you're hit.
+110 -9
View File
@@ -14,6 +14,7 @@
#include "sound/audiostr.h"
#include "cmdline/cmdline.h"
#include "osapi/osapi.h"
#include "globalincs/vmallocator.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/alphacolors.h"
@@ -55,6 +56,20 @@ float Master_voice_volume = 0.7f; // range is 0 -> 1, used for all voice playbac
unsigned int SND_ENV_DEFAULT = 0;
//For the adjust-audio-volume sexp
float aav_voice_volume = 1.0f;
float aav_music_volume = 1.0f;
float aav_effect_volume = 1.0f;
struct aav {
float start_volume;
float delta;
float start_time;
int delta_time;
};
aav aav_data[3];
// min volume to play a sound after all volume processing (range is 0.0 -> 1.0)
#define MIN_SOUND_VOLUME 0.05f
@@ -122,6 +137,8 @@ int snd_init()
mprintf(("Could not initialize the OGG vorbis converter.\n"));
}
snd_aav_init();
// Init the audio streaming stuff
audiostream_init();
@@ -180,7 +197,7 @@ void snd_spew_debug_info()
int message_sounds = 0;
int interface_sounds = 0;
int done = 0;
int s_idx;
size_t s_idx;
if(!Sound_spew){
return;
@@ -195,7 +212,7 @@ void snd_spew_debug_info()
done = 0;
// what kind of sound is this
for(s_idx=0; s_idx<Num_game_sounds; s_idx++){
for(s_idx=0; s_idx < Snds.size(); s_idx++){
if(!stricmp(Snds[s_idx].filename, Sounds[idx].filename)){
game_sounds++;
done = 1;
@@ -203,7 +220,7 @@ void snd_spew_debug_info()
}
if(!done){
for(s_idx=0; s_idx<Num_game_sounds; s_idx++){
for(s_idx=0; s_idx < Snds.size(); s_idx++){
if(!stricmp(Snds_iface[s_idx].filename, Sounds[idx].filename)){
interface_sounds++;
done = 1;
@@ -495,9 +512,9 @@ int snd_play( game_snd *gs, float pan, float vol_scale, int priority, bool is_vo
volume = gs->default_volume * vol_scale;
if ( gs->flags&GAME_SND_VOICE ) {
volume *= Master_voice_volume;
volume *= (Master_voice_volume * aav_voice_volume);
} else {
volume *= Master_sound_volume;
volume *= (Master_sound_volume * aav_effect_volume);
}
if ( volume > 1.0f )
volume = 1.0f;
@@ -617,7 +634,7 @@ int snd_play_3d(game_snd *gs, vec3d *source_pos, vec3d *listen_pos, float radius
}
}
volume *= Master_sound_volume;
volume *= (Master_sound_volume * aav_effect_volume);
if ( (volume < MIN_SOUND_VOLUME) && !force) {
return -1;
}
@@ -635,7 +652,7 @@ int snd_play_3d(game_snd *gs, vec3d *source_pos, vec3d *listen_pos, float radius
handle = ds_play(snd->sid, gs->id_sig, ds_priority(priority), volume / gs->default_volume, pan, looping);
} else {
handle = ds3d_play(snd->sid, gs->id_sig, source_pos, source_vel, min_range, max_range, looping, (max_volume*Master_sound_volume), volume, ds_priority(priority));
handle = ds3d_play(snd->sid, gs->id_sig, source_pos, source_vel, min_range, max_range, looping, (max_volume*Master_sound_volume*aav_effect_volume), volume, ds_priority(priority));
}
return handle;
@@ -784,7 +801,7 @@ int snd_play_looping( game_snd *gs, float pan, int start_loop, int stop_loop, fl
return -1;
volume = gs->default_volume * vol_scale;
volume *= Master_sound_volume;
volume *= (Master_sound_volume * aav_effect_volume);
if ( volume > 1.0f )
volume = 1.0f;
@@ -841,7 +858,7 @@ void snd_set_volume( int sig, float volume )
return;
}
new_volume = volume * Master_sound_volume;
new_volume = volume * (Master_sound_volume * aav_effect_volume);
ds_set_volume( channel, new_volume );
}
@@ -1020,6 +1037,11 @@ int snd_get_duration(int snd_id)
if ( snd_id < 0 )
return 0;
Assert( !Sounds.empty() );
if ( Sounds.empty() )
return 0;
return Sounds[snd_id].duration;
}
@@ -1324,8 +1346,13 @@ int sound_env_supported()
// Called once per game frame
//
void adjust_volume_on_frame(float* volume_now, aav* data);
void snd_do_frame()
{
adjust_volume_on_frame(&aav_music_volume, &aav_data[AAV_MUSIC]);
adjust_volume_on_frame(&aav_voice_volume, &aav_data[AAV_VOICE]);
adjust_volume_on_frame(&aav_effect_volume, &aav_data[AAV_EFFECTS]);
ds_do_frame();
}
@@ -1366,3 +1393,77 @@ int snd_get_samples_per_measure(char *filename, float num_measures)
// ok, now return the samples per measure (which is half of bytes_per_measure)
return (bytes_per_measure / 2);
}
void snd_adjust_audio_volume(int type, float percent, int time)
{
Assert( type >= 0 && type < 4 );
switch (type) {
case AAV_MUSIC:
aav_data[type].start_volume = aav_music_volume;
if (percent < aav_music_volume)
aav_data[type].delta = (aav_music_volume - percent) * -1.0f;
else
aav_data[type].delta = percent - aav_music_volume;
break;
case AAV_VOICE:
aav_data[type].start_volume = aav_voice_volume;
if (percent < aav_voice_volume)
aav_data[type].delta = (aav_voice_volume - percent) * -1.0f;
else
aav_data[type].delta = percent - aav_voice_volume;
break;
case AAV_EFFECTS:
aav_data[type].start_volume = aav_effect_volume;
if (percent < aav_effect_volume)
aav_data[type].delta = (aav_effect_volume - percent) * -1.0f;
else
aav_data[type].delta = percent - aav_effect_volume;
break;
}
aav_data[type].delta_time = time;
aav_data[type].start_time = (f2fl(Missiontime) * 1000);
}
void adjust_volume_on_frame(float* volume_now, aav* data)
{
if (Missiontime == 0){
return;
}
if (*volume_now == (data->start_volume + data->delta))
return;
float msMissiontime = (f2fl(Missiontime) * 1000);
if ( msMissiontime > ( data->start_time + data->delta_time) ) {
*volume_now = data->start_volume + data->delta;
return;
}
float done = 0.0f;
//How much change do we need?
if (data->delta_time == 0)
done = 1.0f;
else
done =(float) (msMissiontime - data->start_time)/data->delta_time;
//apply change
*volume_now = data->start_volume + (data->delta * done);
CLAMP(*volume_now, 0.0f, 1.0f);
}
void snd_aav_init()
{
aav_music_volume = 1.0f;
aav_voice_volume = 1.0f;
aav_effect_volume = 1.0f;
for (int i = 0; i < 3; i++) {
aav_data[i].delta = 0.0f;
aav_data[i].start_volume = 1.0f;
aav_data[i].delta_time = 0;
aav_data[i].start_time = 0.0f;
}
}
+14 -2
View File
@@ -28,9 +28,14 @@
#define SND_PRIORITY_DOUBLE_INSTANCE 2
#define SND_PRIORITY_TRIPLE_INSTANCE 3
//For the adjust-audio-volume sexp
#define AAV_MUSIC 0
#define AAV_VOICE 1
#define AAV_EFFECTS 2
typedef struct game_snd
{
int sig; // number of sound in sounds.tbl (not used)
int sig; // index number of sound in as specified in sounds.tbl
char filename[MAX_FILENAME_LEN];
float default_volume; // range: 0.0 -> 1.0
int min, max; // min: distance at which sound will stop getting louder max: distance at which sound is inaudible
@@ -62,6 +67,9 @@ extern float Master_sound_volume; // 0 -> 1.0
extern float Master_voice_volume; // 0 -> 1.0
extern int Snd_sram; // System memory consumed by sound data
extern int Snd_hram; // Soundcard memory consumed by sound data
extern float aav_voice_volume;
extern float aav_music_volume;
extern float aav_effect_volume;
//int snd_load( char *filename, int hardware=0, int three_d=0, int *sig=NULL );
int snd_load( game_snd *gs, int allow_hardware_load = 0);
@@ -137,6 +145,7 @@ int snd_num_playing();
int snd_get_data(int handle, char *data);
int snd_size(int handle, int *size);
void snd_do_frame();
void snd_adjust_audio_volume(int type, float percent, int time);
// repositioning of the sound buffer pointer
void snd_rewind(int snd_handle, game_snd *sg, float seconds); // rewind N seconds from the current position
@@ -160,4 +169,7 @@ int sound_env_get(sound_env *se, int preset = -1);
int sound_env_disable();
int sound_env_supported();
#endif
// adjust-audio-volume
void snd_aav_init();
#endif
+2 -2
View File
@@ -424,9 +424,9 @@ int targa_read_header(char *real_filename, CFILE *img_cfp, int *w, int *h, int *
cfclose(targa_file);
targa_file = NULL;
}
if ( (header.pixel_depth != 16) && (header.pixel_depth != 24) && (header.pixel_depth != 32) ) {
Int3();
Assertion( (header.pixel_depth != 16) && (header.pixel_depth != 24) && (header.pixel_depth != 32), "Invalid colour depth (%d) in header of tga file %s\n", header.pixel_depth, real_filename );
return TARGA_ERROR_READING;
}
+1 -1
View File
@@ -2763,7 +2763,7 @@ void beam_handle_collisions(beam *b)
}
if (wi->wi_flags & WIF_HUGE) {
if (Objects[target].type & OBJ_SHIP) {
if (Objects[target].type == OBJ_SHIP) {
ship_type_info *sti;
sti = ship_get_type_info(&Objects[target]);
if (sti->weapon_bools & STI_WEAP_NO_HUGE_IMPACT_EFF)
+2 -2
View File
@@ -184,8 +184,8 @@ void mflash_page_in(bool load_all)
// blobs
for ( idx = 0; idx < Mflash_info[i].blobs.size(); idx++) {
Mflash_info[i].blobs[idx].anim_id = bm_load_animation(Mflash_info[i].blobs[idx].name, &num_frames, &fps, NULL, 1);
Assert( Mflash_info[i].blobs[idx].anim_id >= 0 );
Mflash_info[i].blobs[idx].anim_id = bm_load_either(Mflash_info[i].blobs[idx].name, &num_frames, &fps, NULL, 1);
Assertion( (Mflash_info[i].blobs[idx].anim_id >= 0), "Failed to load muzzle flash animation %s\n", Mflash_info[i].blobs[idx].name );
bm_page_in_xparent_texture( Mflash_info[i].blobs[idx].anim_id );
}
}
+17 -1
View File
@@ -350,10 +350,19 @@ void shockwave_move(object *shockwave_objp, float frametime)
}
// blast ships and asteroids
// And (some) weapons
for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
if ( (objp->type != OBJ_SHIP) && (objp->type != OBJ_ASTEROID) ) {
if ( (objp->type != OBJ_SHIP) && (objp->type != OBJ_ASTEROID) && (objp->type != OBJ_WEAPON)) {
continue;
}
if ( objp->type == OBJ_WEAPON ) {
// only apply to missiles with hitpoints
weapon_info* wip = &Weapon_info[Weapons[objp->instance].weapon_info_index];
if (wip->weapon_hitpoints <= 0 || !(wip->wi_flags2 & WIF2_TAKES_SHOCKWAVE_DAMAGE))
continue;
}
if ( objp->type == OBJ_SHIP ) {
// don't blast navbuoys
@@ -392,6 +401,13 @@ void shockwave_move(object *shockwave_objp, float frametime)
case OBJ_ASTEROID:
asteroid_hit(objp, NULL, NULL, damage);
break;
case OBJ_WEAPON:
objp->hull_strength -= damage;
if (objp->hull_strength < 0.0f) {
Weapons[objp->instance].lifeleft = 0.01f;
Weapons[objp->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
}
break;
default:
Int3();
break;
+2
View File
@@ -104,6 +104,8 @@ extern int Num_weapon_subtypes;
#define WIF2_CAPITAL_PLUS (1 << 23) // AI will not use this weapon on fighters or bombers
#define WIF2_EXTERNAL_WEAPON_FP (1 << 24) // will try to use external models FPs if possible
#define WIF2_EXTERNAL_WEAPON_LNCH (1 << 25) // render external secondary as a launcher
#define WIF2_TAKES_BLAST_DAMAGE (1 << 26) // This weapon can take blast damage
#define WIF2_TAKES_SHOCKWAVE_DAMAGE (1 << 27) // This weapon can take shockwave damage
#define WIF_HOMING (WIF_HOMING_HEAT | WIF_HOMING_ASPECT | WIF_HOMING_JAVELIN)
#define WIF_LOCKED_HOMING (WIF_HOMING_ASPECT | WIF_HOMING_JAVELIN)
+21 -7
View File
@@ -632,6 +632,10 @@ void parse_wi_flags(weapon_info *weaponp, int wi_flags, int wi_flags2)
weaponp->wi_flags2 |= WIF2_EXTERNAL_WEAPON_FP;
else if (!stricmp(NOX("external model launcher"), weapon_strings[i]))
weaponp->wi_flags2 |= WIF2_EXTERNAL_WEAPON_LNCH;
else if (!stricmp(NOX("takes blast damage"), weapon_strings[i]))
weaponp->wi_flags2 |= WIF2_TAKES_BLAST_DAMAGE;
else if (!stricmp(NOX("takes shockwave damage"), weapon_strings[i]))
weaponp->wi_flags2 |= WIF2_TAKES_SHOCKWAVE_DAMAGE;
else
Warning(LOCATION, "Bogus string in weapon flags: %s\n", weapon_strings[i]);
}
@@ -5379,11 +5383,6 @@ int weapon_area_calc_damage(object *objp, vec3d *pos, float inner_rad, float out
{
float dist, max_dist, min_dist;
// only blast ships and asteroids
if ( (objp->type != OBJ_SHIP) && (objp->type != OBJ_ASTEROID)) {
return -1;
}
max_dist = objp->radius + outer_rad;
dist = vm_vec_dist_quick(&objp->pos, pos);
if ( (dist > max_dist) || (dist > (limit+objp->radius)) ) {
@@ -5477,11 +5476,19 @@ void weapon_do_area_effect(object *wobjp, shockwave_create_info *sci, vec3d *pos
Assert(sci->inner_rad != 0);
// only blast ships and asteroids
// And (some) weapons
for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
if ( (objp->type != OBJ_SHIP) && (objp->type != OBJ_ASTEROID) ) {
if ( (objp->type != OBJ_SHIP) && (objp->type != OBJ_ASTEROID) && (objp->type != OBJ_WEAPON) ) {
continue;
}
if ( objp->type == OBJ_WEAPON ) {
// only apply to missiles with hitpoints
weapon_info* wip = &Weapon_info[Weapons[objp->instance].weapon_info_index];
if (wip->weapon_hitpoints <= 0 || !(wip->wi_flags2 & WIF2_TAKES_BLAST_DAMAGE))
continue;
}
if ( objp->type == OBJ_SHIP ) {
// don't blast navbuoys
if ( ship_get_SIF(objp->instance) & SIF_NAVBUOY ) {
@@ -5504,6 +5511,13 @@ void weapon_do_area_effect(object *wobjp, shockwave_create_info *sci, vec3d *pos
case OBJ_ASTEROID:
asteroid_hit(objp, NULL, NULL, damage);
break;
case OBJ_WEAPON:
objp->hull_strength -= damage;
if (objp->hull_strength < 0.0f) {
Weapons[objp->instance].lifeleft = 0.01f;
Weapons[objp->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
}
break;
default:
Int3();
break;
@@ -5883,7 +5897,7 @@ void weapons_page_in()
}
default:
Int3(); // Invalid weapon rendering type.
Assertion(wip->render_type != WRT_POF && wip->render_type != WRT_LASER, "Weapon %s does not have a valid rendering type. Type passed: %d\n", wip->name, wip->render_type); // Invalid weapon rendering type.
}
wip->external_model_num = -1;
+2 -1
View File
@@ -11,6 +11,7 @@
// Goober5000 - now these warnings will only be disabled when compiling with MSVC :)
#if defined _MSC_VER
// 4002 is too many actual parameters for macro 'Assertion'
// 4100 is unreferenced formal parameters,
// 4127 is constant conditional (assert)
// 4201 nonstandard extension used: nameless struct/union (happens a lot in Windows include headers)
@@ -28,7 +29,7 @@
// So to disable this, I add in a stub function at the top of each module that does nothing.
// 4786 is identifier truncated to 255 characters (happens all the time in Microsoft #includes) -- Goober5000
// 4996 deprecated strcpy, strcat, sprintf, etc. (from MSVC 2005) - taylor
#pragma warning(disable: 4100 4127 4201 4390 4410 4511 4512 4514 4611 4663 4710 4711 4725 4786 4996)
#pragma warning(disable: 4002 4100 4127 4201 4390 4410 4511 4512 4514 4611 4663 4710 4711 4725 4786 4996)
#endif
+23257 -4034
View File
File diff suppressed because it is too large. Load diff
+86
View File
@@ -0,0 +1,86 @@
## libjpeg/Makefile.am for fs2_open
##
## $Id: Makefile.am,v 1.4 2005-07-07 16:36:58 taylor Exp $
EXTRA_DIST = README
# D_ variants are defaults and should always be used
AM_CFLAGS = @D_CFLAGS@ -Wno-main
AM_LDFLAGS = @D_LDFLAGS@
noinst_LIBRARIES = libjpeg.a
###############################################################################
##
## Begin JPEG library
##
libjpeg_a_SOURCES = \
cderror.h \
cdjpeg.h \
jcapimin.c \
jcapistd.c \
jccoefct.c \
jccolor.c \
jcdctmgr.c \
jchuff.c \
jchuff.h \
jcinit.c \
jcmainct.c \
jcmarker.c \
jcmaster.c \
jconfig_lnx.h \
jconfig_vc.h \
jcomapi.c \
jcparam.c \
jcphuff.c \
jcprepct.c \
jcsample.c \
jctrans.c \
jdapimin.c \
jdapistd.c \
jdatadst.c \
jdatasrc.c \
jdcoefct.c \
jdcolor.c \
jdct.h \
jddctmgr.c \
jdhuff.c \
jdhuff.h \
jdinput.c \
jdmainct.c \
jdmarker.c \
jdmaster.c \
jdmerge.c \
jdphuff.c \
jdpostct.c \
jdsample.c \
jdtrans.c \
jerror.c \
jerror.h \
jfdctflt.c \
jfdctfst.c \
jfdctint.c \
jidctflt.c \
jidctfst.c \
jidctint.c \
jidctred.c \
jinclude.h \
jmemansi.c \
jmemmgr.c \
jmemsys.h \
jmorecfg.h \
jpegint.h \
jpeglib.h \
jquant1.c \
jquant2.c \
jutils.c \
jversion.h \
transupp.h
##
## End JPEG library
##
###############################################################################
+77
View File
@@ -0,0 +1,77 @@
## lua/Makefile.am for fs2_open
##
## $Id: Makefile.am,v 1.2 2007-01-07 12:39:30 taylor Exp $
# D_ variants are defaults and should always be used
AM_CFLAGS = @D_CFLAGS@
AM_LDFLAGS = @D_LDFLAGS@
noinst_LIBRARIES = liblua.a
###############################################################################
##
## Begin Lua library
##
liblua_a_SOURCES = \
lapi.c \
lapi.h \
lauxlib.c \
lauxlib.h \
lbaselib.c \
lcode.c \
lcode.h \
ldblib.c \
ldebug.c \
ldebug.h \
ldo.c \
ldo.h \
ldump.c \
lfunc.c \
lfunc.h \
lgc.c \
lgc.h \
linit.c \
liolib.c \
llex.c \
llex.h \
llimits.h \
lmathlib.c \
lmem.c \
lmem.h \
loadlib.c \
lobject.c \
lobject.h \
lopcodes.c \
lopcodes.h \
loslib.c \
lparser.c \
lparser.h \
lstate.c \
lstate.h \
lstring.c \
lstring.h \
lstrlib.c \
ltable.c \
ltable.h \
ltablib.c \
ltests.c \
ltm.c \
ltm.h \
luaconf.h \
lua.h \
lua.c \
lualib.h \
lundump.c \
lundump.h \
lvm.c \
lvm.h \
lzio.c \
lzio.h \
print.c
##
## End Lua library
##
###############################################################################
+15 -9
View File
@@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
** $Id: lcode.c,v 2.25.1.4 2009/06/15 14:12:25 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -544,15 +544,18 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
pc = NO_JUMP; /* always true; do nothing */
break;
}
case VFALSE: {
pc = luaK_jump(fs); /* always jump */
break;
}
case VJMP: {
invertjump(fs, e);
pc = e->u.s.info;
break;
}
case VFALSE: {
if (!hasjumps(e)) {
pc = luaK_jump(fs); /* always jump */
break;
}
/* else go through */
}
default: {
pc = jumponcond(fs, e, 0);
break;
@@ -572,14 +575,17 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) {
pc = NO_JUMP; /* always false; do nothing */
break;
}
case VTRUE: {
pc = luaK_jump(fs); /* always jump */
break;
}
case VJMP: {
pc = e->u.s.info;
break;
}
case VTRUE: {
if (!hasjumps(e)) {
pc = luaK_jump(fs); /* always jump */
break;
}
/* else go through */
}
default: {
pc = jumponcond(fs, e, 1);
break;
+2 -1
View File
@@ -1,5 +1,5 @@
/*
** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $
** $Id: ldblib.c,v 1.104.1.4 2009/08/04 18:50:18 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -45,6 +45,7 @@ static int db_setmetatable (lua_State *L) {
static int db_getfenv (lua_State *L) {
luaL_checkany(L, 1);
lua_getfenv(L, 1);
return 1;
}
+5 -2
View File
@@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $
** $Id: liolib.c,v 2.73.1.4 2010/05/14 15:33:51 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -276,7 +276,10 @@ static int read_number (lua_State *L, FILE *f) {
lua_pushnumber(L, d);
return 1;
}
else return 0; /* read fails */
else {
lua_pushnil(L); /* "result" to be removed */
return 0; /* read fails */
}
}
Loaded 100 of 124 files, more files were not shown because too many files have changed in this diff. Show more