Compare commits

...
82 Commits
Author SHA1 Message Date
Fabian 42e618e330 - Fixed mix of friendly vs. non-friendly.
- Added testwise coward mode, so that friendly AI fighters and bombers do depart when taking too much hits. ;-)
2008-08-15 01:10:23 +00:00
Fabian 3e1b9c173b Added ai/newai/newai.cpp to Windows projects. 2008-08-05 17:28:23 +00:00
Fabian 3e61b43b31 Moved newai to below ai/. 2008-08-05 17:25:14 +00:00
Fabian 918a805080 Added defined compilation to distiguish between call from module and call from static library. 2008-08-05 17:23:32 +00:00
Fabian 75f5273c0e Oops, forgot to remove debugging code. 2008-08-02 12:25:46 +00:00
Fabian e130b74231 - Added newai.cpp to Makefile.am.
- Changed ai_module_init to newai_ai_module_init due to new naming scheme.
2008-08-02 12:16:12 +00:00
Fabian 3a6f03a984 - Added possibility to fallback to program image if library or symbol in library cannot be found.
- Added doxygen documentation.
- Added dummy function for included AI implementations.
2008-08-02 12:13:56 +00:00
Fabian 0287e166df Added an example AI implementation.
Under linux the following works to build it:

g++ -I. -I /usr/include/SDL newai/newai.cpp -shared -o newai.so

Then you need to use:

LD_LIBRARY_PATH=$(pwd) ./fs2_open_r

And add a newai-aip.tbm file:

#AI Profiles

$Profile Name: FS2 RETAIL
+nocreate
$AI Module: newai
#End
2008-08-02 00:23:37 +00:00
Fabian 1fb5f9cd9b Added aimodular.cpp aimodular.h also to MSVC++ project files. 2008-07-29 18:27:31 +00:00
Fabian 92d8507c12 - Added modular files to Makefile.am.
- Added -rdynamic to be able to use global variables from the main program in the NewAI DLL file.
2008-07-29 18:16:43 +00:00
Fabian 914ed7a2f5 Added modular system to load a new AI on the fly via a DLL or SO file:
The DLL file needs to do:

extern "C" {
	void ai_module_init(void);
}

and override the table functions it wants to override.
2008-07-29 18:13:15 +00:00
Fabian 9dca3f22db - Added global references to the default tables.
- Fixed missing includes for aiinternal.h.
2008-07-29 17:12:18 +00:00
Fabian 42ad6cba7c Added optional string $AI Module to AI Profiles. 2008-07-29 17:09:56 +00:00
Fabian 12b153fd73 Oops, I completely forgot the call table for aicode as I was using the wrong diff ...
Anyway, now aicode_ is calltabled also and can be used in modularized form.
2008-06-21 01:47:18 +00:00
Fabian 7a7eb3b711 Added calltables for most ai_* functions so the AI can be replaced without breaking compatibility with retail. 2008-06-20 18:35:31 +00:00
taylor d18277e2ba make copy of trunk for AI work 2008-05-25 13:59:05 +00:00
WMCoolmon f035cd2b6e Fix a null vec_normalize bug from additive weapons 2008-05-25 06:29:59 +00:00
Backslash 245aefcb44 More end_string_at_first_hash_symbol stuff -- targetbox orders, docked ships, message senders 2008-05-25 02:55:56 +00:00
Backslash 3fb37e85b0 Whoops, wrong repository. Quick correction. 2008-05-24 06:55:19 +00:00
Backslash 1086be9eba bump MAX_ALT_TYPE_NAMES 2008-05-24 06:44:29 +00:00
karajorma 41bbd6cc16 Fix bug where wings with only one ship would ignore orders 2008-05-23 20:24:47 +00:00
phreak 1dda11f9ec remove references to cloaking code. 2008-05-17 17:35:55 +00:00
phreak 0ca63f3c96 Mantis #1462
non-local SSMs home in on objects instead of points to they can track moving targets.

ship_apply_tag and ssm_create take "team" arguments now to indicate which team fired the ssm strike.

ship-tag sexp also has an optional team argument added.  Team 0 is used if the team is not defined.

missiles that are fired without a parent and are locked will travel at their max velocity and not 1/4 of their max.

bugfixes where sometimes an animation may sometimes have a duration of zero and cause an infinite loop.
2008-05-16 01:29:19 +00:00
karajorma cefb883d55 Fix a crash when using <argument> with a numeric variable (Mantis 1656) 2008-05-15 22:42:38 +00:00
karajorma a711c256b4 Fix various crashes, assertions and Int3s caused by SEXPs unable to find subsystems after the player changes class during loadout. 2008-05-14 19:36:17 +00:00
taylor 82561d3b27 hopefully fix order issue from future wing waves (Mantis #1683) 2008-05-06 00:13:52 +00:00
taylor 25d6129168 damn, that was pretty stupid of me (Mantis #1684) 2008-05-03 19:38:00 +00:00
taylor b57a68c0eb remove old warning messages, that stuff should be added on an as-needed basis when debugging only 2008-05-03 04:47:51 +00:00
taylor 14d88eef33 make table crc spew use the proper table list 2008-05-03 04:46:42 +00:00
taylor f7422e1aee add missing break statement to get rid of unidentified packet message 2008-05-03 04:45:17 +00:00
taylor 8103398fbf some stats fixage 2008-05-03 04:44:22 +00:00
Backslash a387a68a5a Lock turrets on ships that have already split apart. This way firepoints don't go with the 'wrong ship half'. Nice work, Wanderer.
Good idea, blowfish -- this is a much better solution than locking during deathroll (which was proposed by _argv[-1] ages ago).
2008-04-30 07:36:29 +00:00
Backslash 251e565593 Add "orders hidden", "orders shown", and "wing name hidden" to iff_defs.tbl flags.
Use these flags instead of wcsaga command line for certain HUD displays.
2008-04-29 05:26:34 +00:00
Backslash 549589bdd2 One more little change involving #. Stupid pointers... 2008-04-24 02:16:10 +00:00
karajorma 604faf652f Nope. I don't know why I thought that would work either. 2008-04-22 10:13:43 +00:00
karajorma 77f6c1bc9c Fix ship-subsys-guardian-threshold so it can be used with ships in loadout.
Add the set-persona SEXP
2008-04-20 18:31:47 +00:00
Backslash 2d05da8f31 Whoops, apparently we missed a bit of the turret fix. Working now. 2008-04-17 04:34:54 +00:00
Backslash 759872d98b A few more tweaks for ship name end_string_at_first_hash_symbol support.
Make FPS and status displays hide when hud is toggled with shift-O.
2008-04-16 03:21:37 +00:00
phreak c53f86384b Use the weapon object and not the weapon_info object when determining when a flak shell should detonate. Mantis #1662 2008-04-16 02:51:26 +00:00
taylor e4cb3479a7 remove libreadline dependency since we don't need it and can't use it anyway 2008-04-12 22:18:01 +00:00
karajorma a8fae4465f Fix the Stars slider so you can have none. Fix a problem with the SEXP argument numbering fix. 2008-04-12 20:18:44 +00:00
taylor 40f8d02425 make SEXP argument numbering go by 5's, and change to bitmaps to try and be a bit more readable (Mantis #1517) 2008-04-07 22:07:06 +00:00
taylor a988f5eab2 try and handle FSO version comments better (should fix Mantis #1284 and #1639) 2008-04-07 22:01:30 +00:00
Backslash 0e86ab07b4 Whoops. Don't actually change the name, just the displayed name.
Also, don't forget the alternate type name.
2008-04-07 00:18:19 +00:00
Goober5000 2f23ea485f remove obsolete ship flag 2008-04-06 23:37:21 +00:00
Goober5000 dfa4206d02 merge the selectable Command feature (from 1/2007) into the stable branch
rearrange the Mission Specs dialog while we're at it
2008-04-06 23:26:33 +00:00
Backslash 364e644cf0 Apply end_string_at_first_hash_symbol to ship names now.
This way people can use # to name duplicates of ships for fake nanojumps and other stuff like that, instead of Unicode characters.
2008-04-06 23:00:20 +00:00
phreak df5d78f07b Added support for multiple child weapons per parent weapon. 2008-04-06 21:56:08 +00:00
karajorma cd2afc57f4 Fix Mantis 1649 2008-04-06 18:53:01 +00:00
taylor 42a84a2a88 keep track of primary weapons properly for multiplayer (Mantis #1094) 2008-04-05 13:39:21 +00:00
Backslash c8d5f8678d Guess this had only been committed to the former HEAD.
Make max_speed based on max_vel.xyz.z, so that we don't have a strange maxmimum throttle when the ship is capable of x/y movement.
2008-04-04 15:15:06 +00:00
taylor 6c856eb341 make background import from FSO missions work if there is only one list (Mantis #1640) 2008-04-04 13:46:37 +00:00
taylor 1aef19ab7f be sure to properly update shields, afterburner energy, max speed, cm count and set initial
model_anim state through change_ship_type()   (Mantis #1512, #1594, #1645)
2008-04-04 03:17:01 +00:00
taylor 7f2de46f30 be sure to apply special explosion to all selected ships (Mantis #1634) 2008-04-04 03:10:45 +00:00
taylor c040093c68 disable PBO support for the time being (causes hangs under OS X for some reason) 2008-04-03 22:01:47 +00:00
taylor 1b2c251be6 add back Bobboau's "check hull" turret subsystem flag support 2008-04-03 16:47:03 +00:00
Backslash e26c2a7487 Whoops, that beam chargeup particle fix only worked with certain table settings. This should work for everything. 2008-04-03 15:33:03 +00:00
taylor b6fceca721 fix sorting of create list so that it properly sorts mission names
add CTRL+SHIFT+S hotkey to switch bewteen mission and file name sorting
2008-04-03 03:39:13 +00:00
taylor 39f5113405 remove all special_ship hack and just handle it all properly: keep wing order correct regardless of object order 2008-04-03 03:37:56 +00:00
taylor 2899799bfa add a timeout for getting pilot info (part of Mantis #1652) 2008-04-03 03:35:26 +00:00
taylor f7cf34487a make mission/campaign list dynamic (Mantis #1203) 2008-04-02 23:54:56 +00:00
taylor babcedc220 /strchr/strrchr/, for mission filenames (Mantis #1629) 2008-04-02 23:54:25 +00:00
karajorma 86c74f9211 Add the is-player SEXP 2008-04-02 18:38:12 +00:00
Backslash 6f1932987d Tweak the lead indicator code to not just work with primaries -- now, dumbfire secondaries show the correct position.
Also, make it work when the target is stationary but "$use additive weapon velocity" is set.
Fix a couple typos and warnings.
2008-04-02 14:19:06 +00:00
taylor 32c5fa6d1d remove multi_elements thingy since it caused problems for some ATI users, and it was kinda crazy anyway 2008-04-01 22:06:17 +00:00
taylor 0a06e62093 make sure not to carry swarm/corkscrew missile fire to another bank when the first one is out of ammo (Mantis #464) 2008-04-01 20:04:04 +00:00
taylor e90acd5b5d bah, that flag check was wrong since the initial commit to the unstable tree 2008-04-01 10:00:09 +00:00
taylor c99874389c skip .svn directories when packing (for sanity sake when packing versioned data)
just skip files that have names too long rather than bailing
2008-04-01 06:31:55 +00:00
taylor 6d085d6d22 be sure to skip filenames that are too long in cf_get_file_list() too, since we still need them to be of a certain size later 2008-04-01 06:30:05 +00:00
taylor eb468ff25c add missing check for "use multiple guns" so that it actually does something (Mantis #867) 2008-03-31 19:42:33 +00:00
taylor 7ed32a9525 fix subtitle centering for non-1024x768 resolutions (Mantis #1630) 2008-03-31 13:51:39 +00:00
taylor c7b3ad7aaf fix the "carry no damage" stuff to actually work right and distribute the proper amount of damage (Mantis #1638) 2008-03-31 13:08:45 +00:00
taylor 677a285bcf if no paths then don't try to allocate memory for them (avoids Int3() check in vm_malloc from requesting a size of 0) 2008-03-31 12:59:10 +00:00
taylor 3090cd74b0 fix "generate icon" flag check for hud shield icons and add some compatibility handling for old data (Mantis #1646)
clean up ballistic primary fixage so that it doesn't run more than it needs to and doesn't end up "fixing" it's own mess
2008-03-31 12:57:34 +00:00
taylor d8c2926962 bring OS X stuff up to date 2008-03-31 01:39:17 +00:00
taylor 04df95e8c9 line sizes are figured at EOL breaks, so be sure that we account for those when splitting too (Mantis #1152) 2008-03-31 00:02:54 +00:00
Backslash 2d5b4119a5 Pretty sure it was agreed we could bump MAX_MISSION_MESSAGES until the dynamic code was finished. WCSaga and BtRL can't work on some missions without this. 2008-03-30 20:06:14 +00:00
Backslash 11d8505cdf Add $Max Turret Target Ownage and $Max Turret Player Ownage to ai_profiles.tbl
This is to customize the number of turrets on a ship allowed to fire at the same thing.
2008-03-30 19:49:42 +00:00
taylor 75baeadbed crap, that did need to be a float to work properly (fixes wobbly hud from r4561)
also be sure to handle the overflow case in HUD_get_nose_coordinates()
2008-03-30 08:53:50 +00:00
taylor c2bc245f81 don't mess with mainhall sounds directly in the movie code (should fix Mantis #1539)
be sure to stop the ambient mainhall sound when playing a movie through the cutscene viewer
2008-03-29 20:25:07 +00:00
taylor 88693b7388 fix various compiler warnings 2008-03-29 06:30:20 +00:00
taylor 94d2357dd4 some minor optimization and cleanup 2008-03-29 05:22:28 +00:00
130 changed files with 5589 additions and 1812 deletions

No files matched your search

+5
View File
@@ -211,6 +211,9 @@ FS2_SOURCES = \
ai/aiturret.cpp \
ai/ai_profiles.cpp \
ai/ai_profiles.h \
ai/aimodular.h \
ai/aimodular.cpp \
ai/newai/newai.cpp \
anim/animplay.cpp \
anim/animplay.h \
anim/packunpack.cpp \
@@ -822,6 +825,8 @@ fs2_open_r_SOURCES = \
fs2_open_d_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a
fs2_open_r_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a
fs2_open_d_LDFLAGS = -rdynamic
fs2_open_r_LDFLAGS = -rdynamic
##
## End MAIN binary
+10
View File
@@ -235,6 +235,10 @@ void parse_ai_profiles_tbl(char *filename)
// fill in any and all settings; they're all optional and can be in any order
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
{
strcpy(profile->ai_module, "retail");
if (optional_string("$AI Module:"))
stuff_string(profile->ai_module, F_NAME, NAME_LENGTH);
if (optional_string("$Player Afterburner Recharge Scale:"))
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
@@ -310,6 +314,12 @@ void parse_ai_profiles_tbl(char *filename)
if (optional_string("$Player Weapon Recharge Scale:"))
parse_float_list(profile->weapon_energy_scale, NUM_SKILL_LEVELS);
if (optional_string("$Max Turret Target Ownage:"))
parse_int_list(profile->max_turret_ownage_target, NUM_SKILL_LEVELS);
if (optional_string("$Max Turret Player Ownage:"))
parse_int_list(profile->max_turret_ownage_player, NUM_SKILL_LEVELS);
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS);
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION);
+6
View File
@@ -80,6 +80,8 @@
typedef struct ai_profile_t {
char profile_name[NAME_LENGTH];
char ai_module[NAME_LENGTH];
int flags;
@@ -115,6 +117,10 @@ typedef struct ai_profile_t {
float ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS];
float ship_fire_delay_scale_friendly[NUM_SKILL_LEVELS];
// Maximum turrets of one ship allowed to shoot the same target
int max_turret_ownage_target[NUM_SKILL_LEVELS];
int max_turret_ownage_player[NUM_SKILL_LEVELS];
} ai_profile_t;
+179 -24
View File
@@ -482,13 +482,141 @@ extern int model_which_octant_distant_many( vec3d *pnt, int model_num,matrix *mo
extern void compute_desired_rvec(vec3d *rvec, vec3d *goal_pos, vec3d *cur_pos);
extern void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal);
// FF 14-06-07
// AI Big Table Wrapper
struct aibig_call_table *aibig_table = &AIBigDefaultTable;
void ai_big_evade_ship ()
{
aibig_table->ai_big_evade_ship();
}
void ai_big_chase_attack (ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
{
aibig_table->ai_big_chase_attack(aip, sip, enemy_pos, dist_to_enemy, modelnum);
}
void ai_big_avoid_ship ()
{
aibig_table->ai_big_avoid_ship();
}
int ai_big_maybe_follow_subsys_path (int do_dot_check)
{
return aibig_table->ai_big_maybe_follow_subsys_path(do_dot_check);
}
void ai_bpap (object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
{
aibig_table->ai_bpap(objp, attacker_objp_pos, attacker_objp_fvec, attack_point, local_attack_point, fov, weapon_travel_dist, surface_normal);
}
void ai_big_pick_attack_point_turret (object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
{
aibig_table->ai_big_pick_attack_point_turret(objp, ssp, gpos, gvec, attack_point, fov, weapon_travel_dist);
}
void ai_big_pick_attack_point (object *objp, object *attacker_objp, vec3d *attack_point, float fov)
{
aibig_table->ai_big_pick_attack_point(objp, attacker_objp, attack_point, fov);
}
void ai_big_subsys_path_cleanup (ai_info *aip)
{
aibig_table->ai_big_subsys_path_cleanup(aip);
}
int ai_big_maybe_start_strafe (ai_info *aip, ship_info *sip)
{
return aibig_table->ai_big_maybe_start_strafe(aip, sip);
}
void ai_big_chase_ct ()
{
aibig_table->ai_big_chase_ct();
}
void ai_big_maybe_fire_weapons (float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
{
aibig_table->ai_big_maybe_fire_weapons(dist_to_enemy, dot_to_enemy, firing_pos, enemy_pos, enemy_vel);
}
void ai_big_switch_to_chase_mode (ai_info *aip)
{
aibig_table->ai_big_switch_to_chase_mode(aip);
}
int ai_big_strafe_maybe_retreat (float dist, vec3d *target_pos)
{
return aibig_table->ai_big_strafe_maybe_retreat(dist, target_pos);
}
void ai_big_chase ()
{
aibig_table->ai_big_chase();
}
void ai_big_ship (object *objp)
{
aibig_table->ai_big_ship(objp);
}
void ai_big_attack_get_data (vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
{
aibig_table->ai_big_attack_get_data(enemy_pos, dist_to_enemy, dot_to_enemy);
}
void ai_big_strafe_attack ()
{
aibig_table->ai_big_strafe_attack();
}
void ai_big_strafe_avoid ()
{
aibig_table->ai_big_strafe_avoid();
}
void ai_big_strafe_retreat1 ()
{
aibig_table->ai_big_strafe_retreat1();
}
void ai_big_strafe_retreat2 ()
{
aibig_table->ai_big_strafe_retreat2();
}
void ai_big_strafe_position ()
{
aibig_table->ai_big_strafe_position();
}
void ai_big_strafe ()
{
aibig_table->ai_big_strafe();
}
int ai_big_maybe_enter_strafe_mode (object *pl_objp, int weapon_objnum, int consider_target_only)
{
return aibig_table->ai_big_maybe_enter_strafe_mode(pl_objp, weapon_objnum, consider_target_only);
}
void ai_big_strafe_maybe_attack_turret (object *ship_objp, object *weapon_objp)
{
aibig_table->ai_big_strafe_maybe_attack_turret(ship_objp, weapon_objp);
}
// AI Big Default implementation
// Called by ai_big_pick_attack_point.
// Generates a random attack point.
// If truly_random flag set (haha), then generate a pretty random number. Otherwise, generate a static rand which
// tends to not change from frame to frame.
// Try four times and choose nearest point to increase chance of getting a good point.
void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
void aibig_ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
{
float nearest_dist;
vec3d result_point, best_point;
@@ -607,7 +735,7 @@ done_1:
//
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
void aibig_ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
{
if (!timestamp_elapsed(ssp->turret_pick_big_attack_point_timestamp)) {
vec3d result_point;
@@ -627,7 +755,7 @@ void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
// Note, attacker_objp can be a ship or a weapon.
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
void aibig_ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
{
Assert(objp->instance > -1);
Assert(objp->type == OBJ_SHIP);
@@ -696,7 +824,7 @@ void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack
}
// Handler for SM_EVADE submode ( called from ai_big_chase() )
void ai_big_evade_ship()
void aibig_ai_big_evade_ship()
{
vec3d player_pos, enemy_pos;
float dist;
@@ -744,13 +872,13 @@ void ai_big_evade_ship()
}
// Handler for SM_AVOID submode ( called from ai_big_chase() )
void ai_big_avoid_ship()
void aibig_ai_big_avoid_ship()
{
ai_big_evade_ship();
}
// reset path following information
void ai_big_subsys_path_cleanup(ai_info *aip)
void aibig_ai_big_subsys_path_cleanup(ai_info *aip)
{
if ( aip->ai_flags & AIF_ON_SUBSYS_PATH ) {
aip->ai_flags &= ~AIF_ON_SUBSYS_PATH;
@@ -765,7 +893,7 @@ void ai_big_subsys_path_cleanup(ai_info *aip)
// input: do_dot_check => default value 0, flag to indicate whether check should be done to ensure
// subsystem is within certain field of view. We don't want to check fov when
// strafing, since ship is weaving to avoid turret fire
int ai_big_maybe_follow_subsys_path(int do_dot_check)
int aibig_ai_big_maybe_follow_subsys_path(int do_dot_check)
{
ai_info *aip;
float dot = 1.0f, min_dot;
@@ -899,7 +1027,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
// 0 => ship should not change ai mode, no fighter/bomber threats are near
//
// NOTE: uses SCAN_FIGHTERS_INTERVAL and ENTER_STRAFE_THREAT_DIST_SQUARED which are defined in AiBig.h
int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
int aibig_ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
{
// if moving slowly (or stopped), and SIF_SMALL_SHIP, then enter STRAFE mode if enemy fighter/bombers
// are near
@@ -934,7 +1062,7 @@ int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
}
// ATTACK submode handler for chase mode.
void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
void aibig_ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
{
int start_bank;
float dot_to_enemy, time_to_hit;
@@ -1051,7 +1179,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
}
// Handler for submode SM_CONTINUOUS_TURN
void ai_big_chase_ct()
void aibig_ai_big_chase_ct()
{
ai_chase_ct();
}
@@ -1068,7 +1196,7 @@ extern void maybe_cheat_fire_synaptic(object *objp, ai_info *aip);
// dist_to_enemy => distance (in m) to attack point on current target
// dot_to_enemy => dot product between fvec of Pl_objp and vector from Pl_objp to attack point
//
void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
void aibig_ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
{
ai_info *aip;
ship_weapon *swp;
@@ -1173,7 +1301,7 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
}
// switch ai ship into chase mode
void ai_big_switch_to_chase_mode(ai_info *aip)
void aibig_ai_big_switch_to_chase_mode(ai_info *aip)
{
aip->previous_mode = aip->mode;
aip->mode = AIM_CHASE;
@@ -1184,7 +1312,7 @@ void ai_big_switch_to_chase_mode(ai_info *aip)
extern int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos);
// Make object Pl_objp chase object En_objp, which is a big ship, not a small ship.
void ai_big_chase()
void aibig_ai_big_chase()
{
float dist_to_enemy, dot_to_enemy;
vec3d player_pos, enemy_pos, vec_to_enemy;
@@ -1474,7 +1602,7 @@ void ai_big_chase()
aip->time_enemy_in_range *= (1.0f - flFrametime);
}
void ai_big_ship(object *objp)
void aibig_ai_big_ship(object *objp)
{
// do nothing
}
@@ -1485,7 +1613,7 @@ void ai_big_ship(object *objp)
// dist => distance from Pl_objp front to attack point
// dot => dot of Pl_objp fvec and vector to attack point
// fire_pos => world pos from which firing
void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
void aibig_ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
{
vec3d player_pos, vec_to_enemy, predicted_enemy_pos;
ship *shipp = &Ships[Pl_objp->instance];
@@ -1544,7 +1672,7 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
// check to see if Pl_objp has gotten too close to attacking point.. if so, break off by entering
// AIS_STRAFE_RETREAT
int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
int aibig_ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
{
ai_info *aip;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -1601,7 +1729,7 @@ int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
}
// attack directly to the turret and fire weapons
void ai_big_strafe_attack()
void aibig_ai_big_strafe_attack()
{
ai_info *aip;
vec3d target_pos;
@@ -1704,7 +1832,7 @@ void ai_big_strafe_attack()
}
// pick a new attack point when entering this state, and keep using it
void ai_big_strafe_avoid()
void aibig_ai_big_strafe_avoid()
{
ai_info *aip;
vec3d target_pos;
@@ -1730,7 +1858,7 @@ void ai_big_strafe_avoid()
}
// move towards aip->goal_point in an evasive manner
void ai_big_strafe_retreat1()
void aibig_ai_big_strafe_retreat1()
{
float dist;
ai_info *aip;
@@ -1776,7 +1904,7 @@ void ai_big_strafe_retreat1()
accelerate_ship(aip, 1.0f);
}
void ai_big_strafe_retreat2()
void aibig_ai_big_strafe_retreat2()
{
float dist;
ai_info *aip;
@@ -1815,7 +1943,7 @@ void ai_big_strafe_retreat2()
}
// reposition self to begin another strafing run
void ai_big_strafe_position()
void aibig_ai_big_strafe_position()
{
ai_info *aip;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -1833,7 +1961,7 @@ void ai_big_strafe_position()
// #define AIS_STRAFE_RETREAT1 204 // fly away from attack point (on an avoid vector)
// #define AIS_STRAFE_POSITION 205 // re-position to resume strafing attack
//
void ai_big_strafe()
void aibig_ai_big_strafe()
{
ai_info *aip;
@@ -1883,7 +2011,7 @@ void ai_big_strafe()
//
// Check if weapon_objnum was fired by Pl_objp's target, and whether Pl_objp's target is a big ship, if
// so, enter AIM_STRAFE
int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
int aibig_ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
{
ai_info *aip;
ship_info *sip;
@@ -1957,7 +2085,7 @@ int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consi
// Consider attacking a turret, if a turret actually fired the weapon
// input: ship_objp => ship that will attack the turret
// weapon_objp =>
void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
void aibig_ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
{
ai_info *aip;
object *parent_objp;
@@ -2006,3 +2134,30 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
// attack the turret
set_targeted_subsys(aip, Weapons[weapon_objp->instance].turret_subsys, OBJ_INDEX(parent_objp));
}
struct aibig_call_table AIBigDefaultTable = {
aibig_ai_big_evade_ship,
aibig_ai_big_chase_attack,
aibig_ai_big_avoid_ship,
aibig_ai_big_maybe_follow_subsys_path,
aibig_ai_bpap,
aibig_ai_big_pick_attack_point_turret,
aibig_ai_big_pick_attack_point,
aibig_ai_big_subsys_path_cleanup,
aibig_ai_big_maybe_start_strafe,
aibig_ai_big_chase_ct,
aibig_ai_big_maybe_fire_weapons,
aibig_ai_big_switch_to_chase_mode,
aibig_ai_big_strafe_maybe_retreat,
aibig_ai_big_chase,
aibig_ai_big_ship,
aibig_ai_big_attack_get_data,
aibig_ai_big_strafe_attack,
aibig_ai_big_strafe_avoid,
aibig_ai_big_strafe_retreat1,
aibig_ai_big_strafe_retreat2,
aibig_ai_big_strafe_position,
aibig_ai_big_strafe,
aibig_ai_big_maybe_enter_strafe_mode,
aibig_ai_big_strafe_maybe_attack_turret
};
+38 -1
View File
@@ -102,6 +102,43 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp);
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov=1.0f);
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
// AI Big Table Wrapper
#include "ship/ship.h"
struct aibig_call_table
{
void (*ai_big_evade_ship) ();
void (*ai_big_chase_attack) (ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum);
void (*ai_big_avoid_ship) ();
int (*ai_big_maybe_follow_subsys_path) (int do_dot_check=1);
void (*ai_bpap) (object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal);
void (*ai_big_pick_attack_point_turret) (object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist);
void (*ai_big_pick_attack_point) (object *objp, object *attacker_objp, vec3d *attack_point, float fov);
void (*ai_big_subsys_path_cleanup) (ai_info *aip);
int (*ai_big_maybe_start_strafe) (ai_info *aip, ship_info *sip);
void (*ai_big_chase_ct) ();
void (*ai_big_maybe_fire_weapons) (float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel);
void (*ai_big_switch_to_chase_mode) (ai_info *aip);
int (*ai_big_strafe_maybe_retreat) (float dist, vec3d *target_pos);
void (*ai_big_chase) ();
void (*ai_big_ship) (object *objp);
void (*ai_big_attack_get_data) (vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy);
void (*ai_big_strafe_attack) ();
void (*ai_big_strafe_avoid) ();
void (*ai_big_strafe_retreat1) ();
void (*ai_big_strafe_retreat2) ();
void (*ai_big_strafe_position) ();
void (*ai_big_strafe) ();
int (*ai_big_maybe_enter_strafe_mode) (object *pl_objp, int weapon_objnum, int consider_target_only);
void (*ai_big_strafe_maybe_attack_turret) (object *ship_objp, object *weapon_objp);
};
// Set new pointer to override ai_big* function calls
// possibly copying the old function calls first
extern struct aibig_call_table *aibig_table;
extern struct aibig_call_table AIBigDefaultTable;
#endif
+1414 -212
View File
File diff suppressed because it is too large. Load diff
+233 -32
View File
@@ -772,11 +772,176 @@ ai_goal_list Ai_goal_names[] =
int Num_ai_goals = sizeof(Ai_goal_names) / sizeof(ai_goal_list);
// FF 04-06-07
// AI Goal Table Wrapper
struct aigoal_call_table *aigoal_table = &AIGoalDefaultTable;
char* Ai_goal_text (int goal)
{
return aigoal_table->Ai_goal_text(goal);
}
void ai_maybe_add_form_goal (wing *wingp)
{
aigoal_table->ai_maybe_add_form_goal(wingp);
}
void ai_post_process_mission ()
{
aigoal_table->ai_post_process_mission();
}
int ai_query_goal_valid (int ship, int ai_goal)
{
return aigoal_table->ai_query_goal_valid(ship, ai_goal);
}
void ai_remove_ship_goal (ai_info *aip, int index)
{
aigoal_table->ai_remove_ship_goal(aip, index);
}
void ai_clear_ship_goals (ai_info *aip)
{
aigoal_table->ai_clear_ship_goals(aip);
}
void ai_clear_wing_goals (int wingnum)
{
aigoal_table->ai_clear_wing_goals(wingnum);
}
void ai_mission_wing_goal_complete (int wingnum, ai_goal *remove_goalp)
{
aigoal_table->ai_mission_wing_goal_complete(wingnum, remove_goalp);
}
void ai_mission_goal_complete (ai_info *aip)
{
aigoal_table->ai_mission_goal_complete(aip);
}
int ai_get_subsystem_type (char *subsystem)
{
return aigoal_table->ai_get_subsystem_type(subsystem);
}
void ai_goal_purge_invalid_goals (ai_goal *aigp, ai_goal *goal_list)
{
aigoal_table->ai_goal_purge_invalid_goals(aigp, goal_list);
}
void ai_goal_purge_all_invalid_goals (ai_goal *aigp)
{
aigoal_table->ai_goal_purge_all_invalid_goals(aigp);
}
int ai_goal_find_dockpoint (int shipnum, int dock_type)
{
return aigoal_table->ai_goal_find_dockpoint(shipnum, dock_type);
}
void ai_goal_fixup_dockpoints (ai_info *aip, ai_goal *aigp)
{
aigoal_table->ai_goal_fixup_dockpoints(aip, aigp);
}
void ai_add_goal_sub_player (int type, int mode, int submode, char *shipname, ai_goal *aigp)
{
aigoal_table->ai_add_goal_sub_player(type, mode, submode, shipname, aigp);
}
int ai_goal_find_empty_slot (ai_goal *goals, int active_goal)
{
return aigoal_table->ai_goal_find_empty_slot(goals, active_goal);
}
void ai_add_ship_goal_player (int type, int mode, int submode, char *shipname, ai_info *aip)
{
aigoal_table->ai_add_ship_goal_player(type, mode, submode, shipname, aip);
}
void ai_add_wing_goal_player (int type, int mode, int submode, char *shipname, int wingnum)
{
aigoal_table->ai_add_wing_goal_player(type, mode, submode, shipname, wingnum);
}
void ai_add_goal_sub_sexp (int sexp, int type, ai_goal *aigp, char *actor_name)
{
aigoal_table->ai_add_goal_sub_sexp(sexp, type, aigp, actor_name);
}
void ai_add_ship_goal_sexp (int sexp, int type, ai_info *aip)
{
aigoal_table->ai_add_ship_goal_sexp(sexp, type, aip);
}
void ai_add_wing_goal_sexp (int sexp, int type, int wingnum)
{
aigoal_table->ai_add_wing_goal_sexp(sexp, type, wingnum);
}
void ai_add_goal_ship_internal (ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate)
{
aigoal_table->ai_add_goal_ship_internal(aip, goal_type, name, docker_point, dockee_point, immediate);
}
void ai_add_goal_wing_internal (wing *wingp, int goal_type, char *name, int immediate)
{
aigoal_table->ai_add_goal_wing_internal(wingp, goal_type, name, immediate);
}
void ai_copy_mission_wing_goal (ai_goal *aigp, ai_info *aip)
{
aigoal_table->ai_copy_mission_wing_goal(aigp, aip);
}
int ai_mission_goal_achievable (int objnum, ai_goal *aigp)
{
return aigoal_table->ai_mission_goal_achievable(objnum, aigp);
}
int ai_goal_priority_compare (const void *a, const void *b)
{
return aigoal_table->ai_goal_priority_compare(a, b);
}
void prioritize_goals (int objnum, ai_info *aip)
{
aigoal_table->prioritize_goals(objnum, aip);
}
void validate_mission_goals (int objnum, ai_info *aip)
{
aigoal_table->validate_mission_goals(objnum, aip);
}
void ai_process_mission_orders (int objnum, ai_info *aip)
{
aigoal_table->ai_process_mission_orders(objnum, aip);
}
void ai_update_goal_references (ai_goal *goals, int type, char *old_name, char *new_name)
{
aigoal_table->ai_update_goal_references(goals, type, old_name, new_name);
}
int query_referenced_in_ai_goals (ai_goal *goals, int type, char *name)
{
return aigoal_table->query_referenced_in_ai_goals(goals, type, name);
}
char* ai_add_dock_name (char *str)
{
return aigoal_table->ai_add_dock_name(str);
}
// AL 11-17-97: A text description of the AI goals. This is used for printing out on the
// HUD what a ship's current orders are. If the AI goal doesn't correspond to something that
// ought to be printable, then NULL is used.
// JAS: Converted to a function in order to externalize the strings
char *Ai_goal_text(int goal)
char *aigoal_Ai_goal_text(int goal)
{
switch(goal) {
case 1:
@@ -815,7 +980,7 @@ char *Ai_goal_text(int goal)
// function to maybe add the form on my wing goal for a player's starting wing. Called when a player wing arrives.
// Goober5000 - made more generic
void ai_maybe_add_form_goal( wing *wingp )
void aigoal_ai_maybe_add_form_goal( wing *wingp )
{
int j;
char *wing_leader;
@@ -853,7 +1018,7 @@ void ai_maybe_add_form_goal( wing *wingp )
}
}
void ai_post_process_mission()
void aigoal_ai_post_process_mission()
{
object *objp;
@@ -907,7 +1072,7 @@ void ai_post_process_mission()
}
// function which determines is a goal is valid for a particular type of ship
int ai_query_goal_valid( int ship, int ai_goal )
int aigoal_ai_query_goal_valid( int ship, int ai_goal )
{
int accepted;
@@ -930,7 +1095,7 @@ int ai_query_goal_valid( int ship, int ai_goal )
}
// remove an ai goal from it's list. Uses the active_goal member as the goal to remove
void ai_remove_ship_goal( ai_info *aip, int index )
void aigoal_ai_remove_ship_goal( ai_info *aip, int index )
{
// only need to set the ai_mode for the particular goal to AI_GOAL_NONE
// reset ai mode to default behavior. Might get changed next time through
@@ -950,7 +1115,7 @@ void ai_remove_ship_goal( ai_info *aip, int index )
//ai_do_default_behavior( &Objects[Ships[aip->shipnum].objnum] );
}
void ai_clear_ship_goals( ai_info *aip )
void aigoal_ai_clear_ship_goals( ai_info *aip )
{
int i;
@@ -969,7 +1134,7 @@ void ai_clear_ship_goals( ai_info *aip )
}
}
void ai_clear_wing_goals( int wingnum )
void aigoal_ai_clear_wing_goals( int wingnum )
{
int i;
wing *wingp = &Wings[wingnum];
@@ -999,7 +1164,7 @@ void ai_clear_wing_goals( int wingnum )
// structure of the goal to be removed. This process is slightly tricky since some member of the wing
// might be pursuing a different goal. We will have to compare based on mode, submode, priority,
// and name.. This routine is only currently called from waypoint code!!!
void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
void aigoal_ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
{
int mode, submode, priority, i;
char *name;
@@ -1059,7 +1224,7 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
// routine which is called with an ai object complete it's goal. Do some action
// based on the goal what was just completed
void ai_mission_goal_complete( ai_info *aip )
void aigoal_ai_mission_goal_complete( ai_info *aip )
{
// if the active goal is dynamic or none, just return. (AI_GOAL_NONE is probably an error, but
// I don't think that this is a problem)
@@ -1071,7 +1236,7 @@ void ai_mission_goal_complete( ai_info *aip )
}
int ai_get_subsystem_type( char *subsystem )
int aigoal_ai_get_subsystem_type( char *subsystem )
{
if ( strstr(subsystem, "engine") ) {
return SUBSYSTEM_ENGINE;
@@ -1107,7 +1272,7 @@ int ai_get_subsystem_type( char *subsystem )
// which are destroy, etc, should get removed. goal list is the list of goals to purge. It is
// always MAX_AI_GOALS in length. This function will only get called when the goal which causes
// purging becomes valid.
void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
void aigoal_ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
{
int i;
ai_goal *purge_goal;
@@ -1173,7 +1338,7 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
}
// function to purge the goals of *all* ships in the game based on the incoming goal structure
void ai_goal_purge_all_invalid_goals(ai_goal *aigp)
void aigoal_ai_goal_purge_all_invalid_goals(ai_goal *aigp)
{
int i;
ship_obj *sop;
@@ -1196,7 +1361,7 @@ void ai_goal_purge_all_invalid_goals(ai_goal *aigp)
}
// Goober5000
int ai_goal_find_dockpoint(int shipnum, int dock_type)
int aigoal_ai_goal_find_dockpoint(int shipnum, int dock_type)
{
int dock_index = -1;
int loop_count = 0;
@@ -1247,7 +1412,7 @@ int ai_goal_find_dockpoint(int shipnum, int dock_type)
// passed are the pointer to goal we are working with. aip if the ai_info pointer
// of the ship with the order. aigp is a pointer to the goal (of aip) of which we are
// fixing up the docking points
void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
void aigoal_ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
{
int shipnum, docker_index, dockee_index;
@@ -1318,7 +1483,7 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
// from the mission goals (i.e. those goals which come from events) in that we don't
// use sexpressions for goals from the player...so we enumerate all the parameters
void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
void aigoal_ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
{
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
@@ -1359,7 +1524,7 @@ void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_
// friendlies want to rearm at the same time. The support ship forgets what it's doing and flies
// off to repair somebody while still docked. I reproduced this with retail, so it's not a bug in
// my new docking code. :)
int ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
int aigoal_ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
{
int gindex, oldest_index;
@@ -1389,7 +1554,7 @@ int ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
// is issued to ship or wing (from player), mode is AI_GOAL_*. submode is the submode the
// ship should go into. shipname is the object of the action. aip is the ai_info pointer
// of the ship receiving the order
void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip )
void aigoal_ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip )
{
int empty_index;
ai_goal *aigp;
@@ -1415,7 +1580,7 @@ void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, a
// adds a goal from the player to the given wing (which in turn will add it to the proper
// ships in the wing
void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum )
void aigoal_ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum )
{
int i, empty_index;
wing *wingp = &Wings[wingnum];
@@ -1439,7 +1604,7 @@ void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, i
// common routine to add a sexpression mission goal to the appropriate goal structure.
void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
void aigoal_ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
{
int node, dummy, op;
char *text;
@@ -1630,7 +1795,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
// adds an ai goal for an individual ship
// type determines who has issues this ship a goal (i.e. the player/mission event/etc)
void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
void aigoal_ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
{
int gindex;
@@ -1639,7 +1804,7 @@ void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
}
// code to add ai goals to wings.
void ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
void aigoal_ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
{
int i;
wing *wingp = &Wings[wingnum];
@@ -1673,7 +1838,7 @@ void ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
// this name can be a shipname or a wingname)
// docker_point and dockee_point are used for the AI_GOAL_DOCK command to tell two ships where to dock
// immediate means to process this order right away
void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate )
void aigoal_ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate )
{
int gindex;
ai_goal *aigp;
@@ -1753,7 +1918,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int doc
// across waves of the wing so we merely need to add the goal to each ship in the wing. Certain
// goal are simply not valid for wings (like dock, undock). Immediate parameter gets passed to add_ship_goal
// to say whether or not we should process this goal right away
void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
void aigoal_ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
{
int i;
@@ -1769,7 +1934,7 @@ void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int imme
}
// this function copies goals from a wing to an ai_info * from a ship.
void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
void aigoal_ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
{
int j;
@@ -1790,7 +1955,7 @@ void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
// function to determine if an ai goal is achieveable or not. Will return
// one of the AI_GOAL_* values. Also determines is a goal was successful.
int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
int aigoal_ai_mission_goal_achievable( int objnum, ai_goal *aigp )
{
int status;
char *ai_shipname;
@@ -2269,7 +2434,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// Compare function for sorting ai_goals based on priority.
// Return values set to sort array in _decreasing_ order.
int ai_goal_priority_compare(const void *a, const void *b)
int aigoal_ai_goal_priority_compare(const void *a, const void *b)
{
ai_goal *ga, *gb;
@@ -2318,7 +2483,7 @@ int ai_goal_priority_compare(const void *a, const void *b)
// Then sort on time for goals of equivalent priority.
// objnum The object number to act upon. Redundant with *aip.
// *aip The AI info to act upon. Goals are stored at aip->goals
void prioritize_goals(int objnum, ai_info *aip)
void aigoal_prioritize_goals(int objnum, ai_info *aip)
{
// First sort based on priority field.
insertion_sort(aip->goals, MAX_AI_GOALS, sizeof(ai_goal), ai_goal_priority_compare);
@@ -2328,7 +2493,7 @@ void prioritize_goals(int objnum, ai_info *aip)
// Remove obsolete goals.
// objnum Object of interest. Redundant with *aip.
// *aip contains goals at aip->goals.
void validate_mission_goals(int objnum, ai_info *aip)
void aigoal_validate_mission_goals(int objnum, ai_info *aip)
{
int i;
@@ -2403,7 +2568,7 @@ extern char *Mode_text[MAX_AI_BEHAVIORS];
// code to process ai "orders". Orders include those determined from the mission file and those
// given by the player to a ship that is under his control. This function gets called for every
// AI object every N seconds through the ai loop.
void ai_process_mission_orders( int objnum, ai_info *aip )
void aigoal_ai_process_mission_orders( int objnum, ai_info *aip )
{
object *objp = &Objects[objnum];
object *other_obj;
@@ -2724,7 +2889,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
}
void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
void aigoal_ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
{
int i, mode, flag, dummy;
@@ -2791,7 +2956,7 @@ void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *n
}
}
int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
int aigoal_query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
{
int i, mode, flag;
@@ -2856,7 +3021,7 @@ int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
return 0;
}
char *ai_add_dock_name(char *str)
char *aigoal_ai_add_dock_name(char *str)
{
char *ptr;
int i;
@@ -2871,3 +3036,39 @@ char *ai_add_dock_name(char *str)
strcpy(ptr, str);
return ptr;
}
struct aigoal_call_table AIGoalDefaultTable = {
aigoal_Ai_goal_text,
aigoal_ai_maybe_add_form_goal,
aigoal_ai_post_process_mission,
aigoal_ai_query_goal_valid,
aigoal_ai_remove_ship_goal,
aigoal_ai_clear_ship_goals,
aigoal_ai_clear_wing_goals,
aigoal_ai_mission_wing_goal_complete,
aigoal_ai_mission_goal_complete,
aigoal_ai_get_subsystem_type,
aigoal_ai_goal_purge_invalid_goals,
aigoal_ai_goal_purge_all_invalid_goals,
aigoal_ai_goal_find_dockpoint,
aigoal_ai_goal_fixup_dockpoints,
aigoal_ai_add_goal_sub_player,
aigoal_ai_goal_find_empty_slot,
aigoal_ai_add_ship_goal_player,
aigoal_ai_add_wing_goal_player,
aigoal_ai_add_goal_sub_sexp,
aigoal_ai_add_ship_goal_sexp,
aigoal_ai_add_wing_goal_sexp,
aigoal_ai_add_goal_ship_internal,
aigoal_ai_add_goal_wing_internal,
aigoal_ai_copy_mission_wing_goal,
aigoal_ai_mission_goal_achievable,
aigoal_ai_goal_priority_compare,
aigoal_prioritize_goals,
aigoal_validate_mission_goals,
aigoal_ai_process_mission_orders,
aigoal_ai_update_goal_references,
aigoal_query_referenced_in_ai_goals,
aigoal_ai_add_dock_name
};
+44
View File
@@ -292,4 +292,48 @@ extern int ai_query_goal_valid( int ship, int ai_goal );
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
extern void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate = 1 );
// AI Goal Table Wrapper
struct aigoal_call_table
{
char* (*Ai_goal_text) (int goal);
void (*ai_maybe_add_form_goal) (wing *wingp);
void (*ai_post_process_mission) ();
int (*ai_query_goal_valid) (int ship, int ai_goal);
void (*ai_remove_ship_goal) (ai_info *aip, int index);
void (*ai_clear_ship_goals) (ai_info *aip);
void (*ai_clear_wing_goals) (int wingnum);
void (*ai_mission_wing_goal_complete) (int wingnum, ai_goal *remove_goalp);
void (*ai_mission_goal_complete) (ai_info *aip);
int (*ai_get_subsystem_type) (char *subsystem);
void (*ai_goal_purge_invalid_goals) (ai_goal *aigp, ai_goal *goal_list);
void (*ai_goal_purge_all_invalid_goals) (ai_goal *aigp);
int (*ai_goal_find_dockpoint) (int shipnum, int dock_type);
void (*ai_goal_fixup_dockpoints) (ai_info *aip, ai_goal *aigp);
void (*ai_add_goal_sub_player) (int type, int mode, int submode, char *shipname, ai_goal *aigp);
int (*ai_goal_find_empty_slot) (ai_goal *goals, int active_goal);
void (*ai_add_ship_goal_player) (int type, int mode, int submode, char *shipname, ai_info *aip);
void (*ai_add_wing_goal_player) (int type, int mode, int submode, char *shipname, int wingnum);
void (*ai_add_goal_sub_sexp) (int sexp, int type, ai_goal *aigp, char *actor_name);
void (*ai_add_ship_goal_sexp) (int sexp, int type, ai_info *aip);
void (*ai_add_wing_goal_sexp) (int sexp, int type, int wingnum);
void (*ai_add_goal_ship_internal) (ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate);
void (*ai_add_goal_wing_internal) (wing *wingp, int goal_type, char *name, int immediate);
void (*ai_copy_mission_wing_goal) (ai_goal *aigp, ai_info *aip);
int (*ai_mission_goal_achievable) (int objnum, ai_goal *aigp);
int (*ai_goal_priority_compare) (const void *a, const void *b);
void (*prioritize_goals) (int objnum, ai_info *aip);
void (*validate_mission_goals) (int objnum, ai_info *aip);
void (*ai_process_mission_orders) (int objnum, ai_info *aip);
void (*ai_update_goal_references) (ai_goal *goals, int type, char *old_name, char *new_name);
int (*query_referenced_in_ai_goals) (ai_goal *goals, int type, char *name);
char* (*ai_add_dock_name) (char *str);
};
// Set new pointer to override ai_goal* function calls
// possibly copying the old function calls first
extern struct aigoal_call_table *aigoal_table;
extern struct aigoal_call_table AIGoalDefaultTable;
#endif
+255
View File
@@ -10,6 +10,22 @@
#ifndef _AIINTERNAL_H
#define _AIINTERNAL_H
#include "weapon/weapon.h"
#include "weapon/swarm.h"
#include "object/objectdock.h"
typedef struct eval_nearest_objnum {
int objnum;
object *trial_objp;
int enemy_team_mask;
int enemy_wing;
float range;
int max_attackers;
int nearest_objnum;
float nearest_dist;
int check_danger_weapon_objnum;
} eval_nearest_objnum;
//Returns true if the specified object is a stealth ship, false if not
bool is_object_stealth_ship(object* objp);
@@ -28,4 +44,243 @@ int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip);
//Does all the stuff needed to aim and fire a turret.
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum);
// AI Turret Table Wrapper
struct eval_enemy_obj_struct;
struct aiturret_call_table
{
int (*turret_select_best_weapon) (ship_subsys *turret, object *target);
int (*valid_turret_enemy) (object *objp, object *turret_parent);
void (*evaluate_obj_as_target) (object *objp, eval_enemy_obj_struct *eeo);
int (*get_nearest_turret_objnum) (int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag);
int (*find_turret_enemy) (ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov);
int (*turret_should_pick_new_target) (ship_subsys *turret);
void (*turret_set_next_fire_timestamp) (int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip);
int (*turret_should_fire_aspect) (ship_subsys *turret, float dot, weapon_info *wip);
bool (*turret_fire_weapon) (int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos, float flak_range_override);
void (*turret_swarm_fire_from_turret) (turret_swarm_info *tsi);
void (*ai_fire_from_turret) (ship *shipp, ship_subsys *ss, int parent_objnum);
};
// Set new pointer to override ai_goal* function calls
// possibly copying the old function calls first
extern struct aiturret_call_table *aiturret_table;
extern struct aiturret_call_table AITurretDefaultTable;
// AI Code Table Wrapper
struct aicode_call_table
{
void (*ai_set_rearm_status) (int team, int time);
int (*ai_good_time_to_rearm) (object *objp);
void (*ai_good_secondary_time) (int team, int weapon_index, int max_fire_count, char *shipname);
int (*is_preferred_weapon) (int weapon_num, object *firer_objp, object *target_objp);
void (*ai_init_secondary_info) ();
void (*free_ai_stuff) ();
void (*parse_ai_class) ();
void (*reset_ai_class_names) ();
void (*parse_aitbl) ();
void (*ai_init) ();
void (*ai_level_init) ();
int (*ai_is_stealth_visible) (object *viewer_objp, object *stealth_objp);
void (*update_ai_stealth_info_with_error) (ai_info *aip);
void (*ai_update_danger_weapon) (int attacked_objnum, int weapon_objnum);
void (*ai_turn_towards_vector) (vec3d *dest, object *objp, float frametime, float turn_time, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec, int sexp_flags);
void (*init_ship_info) ();
int (*set_target_objnum) (ai_info *aip, int objnum);
ship_subsys* (*set_targeted_subsys) (ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
void (*ai_object_init) (object *obj, int ai_index);
void (*adjust_accel_for_docking) (ai_info *aip);
void (*accelerate_ship) (ai_info *aip, float accel);
void (*change_acceleration) (ai_info *aip, float delta_accel);
void (*set_accel_for_target_speed) (object *objp, float tspeed);
void (*turn_towards_point) (object *objp, vec3d *point, vec3d *slide_vec, float bank_override);
void (*turn_away_from_point) (object *objp, vec3d *point, float bank_override);
float (*turn_towards_tangent) (object *objp, vec3d *point, float radius);
float (*turn_toward_tangent_with_axis) (object *objp, object *center_objp, float radius);
int (*object_is_targetable) (object *target, ship *viewer);
int (*num_enemies_attacking) (int objnum);
float (*get_wing_lowest_max_speed) (object *objp);
int (*is_ignore_object_sub) (int *ignore_objnum, int *ignore_signature, int objnum);
int (*find_ignore_new_object_index) (ai_info *aip, int objnum);
int (*is_ignore_object) (ai_info *aip, int objnum, int just_the_original=0);
int (*get_nearest_bbox_point) (object *ship_obj, vec3d *start, vec3d *box_pt);
void (*evaluate_object_as_nearest_objnum) (eval_nearest_objnum *eno);
int (*get_nearest_objnum) (int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers);
int (*find_nearby_threat) (int objnum, int enemy_team_mask, float range, int *count);
int (*num_turrets_attacking) (object *turret_parent, int target_objnum);
int (*get_enemy_timestamp) ();
int (*find_enemy) (int objnum, float range, int max_attackers);
void (*ai_set_goal_maybe_abort_dock) (object *objp, ai_info *aip);
void (*force_avoid_player_check) (object *objp, ai_info *aip);
void (*ai_attack_object) (object *attacker, object *attacked, int priority, ship_subsys *ssp);
void (*ai_attack_wing) (object *attacker, int wingnum, int priority);
void (*ai_evade_object) (object *evader, object *evaded, int priority);
int (*compact_ignore_new_objects) (ai_info *aip, int force=0);
void (*ai_ignore_object) (object *ignorer, object *ignored, int priority, int ignore_new);
void (*ai_ignore_wing) (object *ignorer, int wingnum, int priority);
void (*create_model_path) (object *pl_objp, object *mobjp, int path_num, int subsys_path);
void (*create_model_exit_path) (object *pl_objp, object *mobjp, int path_num, int count);
void (*ai_find_path) (object *pl_objp, int objnum, int path_num, int exit_flag, int subsys_path);
int (*maybe_avoid_player) (object *objp, vec3d *goal_pos);
void (*ai_stay_still) (object *still_objp, vec3d *view_pos);
void (*ai_do_objects_docked_stuff) (object *docker, int docker_point, object *dockee, int dockee_point);
void (*ai_do_objects_undocked_stuff) (object *docker, object *dockee);
void (*ai_dock_with_object) (object *docker, int docker_index, object *dockee, int dockee_index, int priority, int dock_type);
void (*ai_start_fly_to_ship) (object *objp, int shipnum);
void (*ai_start_waypoints) (object *objp, int waypoint_list_index, int wp_flags);
void (*ai_do_stay_near) (object *objp, object *other_objp, float dist);
void (*ai_do_safety) (object *objp);
void (*ai_form_on_wing) (object *objp, object *goal_objp);
int (*ai_formation_object_get_slotnum) (int objnum, object *objp);
float (*compute_time_to_enemy) (float dist_to_enemy, object *pobjp, object *eobjp);
void (*ai_set_positions) (object *pl_objp, object *en_objp, ai_info *aip, vec3d *player_pos, vec3d *enemy_pos);
float (*maybe_recreate_path) (object *objp, ai_info *aip, int force_recreate_flag, int override_hash=0);
void (*set_accel_for_docking) (object *objp, ai_info *aip, float dot, float dot_to_next, float dist_to_next, float dist_to_goal, ship_info *sip);
float (*ai_path) ();
void (*ai_safety_pick_spot) (object *objp);
float (*ai_safety_goto_spot) (object *objp);
void (*ai_safety_circle_spot) (object *objp);
void (*ai_safety) ();
void (*ai_fly_to_ship) ();
void (*ai_waypoints) ();
void (*avoid_ship) ();
int (*maybe_resume_previous_mode) (object *objp, ai_info *aip);
int (*ai_maybe_fire_afterburner) (object *objp, ai_info *aip);
void (*maybe_afterburner_after_ship_hit) (object *objp, ai_info *aip, object *en_objp);
int (*is_instructor) (object *objp);
void (*evade_weapon) ();
void (*slide_face_ship) ();
void (*evade_ship) ();
void (*ai_evade) ();
int (*ai_select_primary_weapon_OLD) (object *objp, object *other_objp, int flags);
int (*ai_select_primary_weapon) (object *objp, object *other_objp, int flags);
void (*set_primary_weapon_linkage) (object *objp);
int (*ai_fire_primary_weapon) (object *objp);
void (*ai_select_secondary_weapon) (object *objp, ship_weapon *swp, int priority1=-1, int priority2=-1);
void (*ai_maybe_announce_shockwave_weapon) (object *firing_objp, int weapon_index);
int (*check_ok_to_fire) (int objnum, int target_objnum, weapon_info *wip);
int (*ai_fire_secondary_weapon) (object *objp, int priority1, int priority2);
void (*set_predicted_enemy_pos_turret) (vec3d *predicted_enemy_pos, vec3d *gun_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
void (*set_predicted_enemy_pos) (vec3d *predicted_enemy_pos, object *pobjp, object *eobjp, ai_info *aip);
void (*ai_chase_ct) ();
void (*ai_chase_eb) (ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy);
float (*ai_endangered_time) (object *ship_objp, object *weapon_objp);
float (*ai_endangered_by_weapon) (ai_info *aip);
int (*ai_near_full_strength) (object *objp);
void (*attack_set_accel) (ai_info *aip, float dist_to_enemy, float dot_to_enemy, float dot_from_enemy);
void (*get_behind_ship) (ai_info *aip, ship_info *sip, float dist_to_enemy);
int (*avoid_player) (object *objp, vec3d *goal_pos);
int (*maybe_avoid_big_ship) (object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time);
void (*ai_stealth_find) ();
void (*ai_stealth_sweep) ();
void (*ai_chase_attack) (ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy, int modelnum);
void (*ai_chase_es) (ai_info *aip, ship_info *sip);
void (*ai_chase_ga) (ai_info *aip, ship_info *sip);
int (*ai_set_attack_subsystem) (object *objp, int subnum);
void (*ai_set_guard_vec) (object *objp, object *guard_objp);
void (*ai_set_guard_wing) (object *objp, int wingnum);
void (*ai_set_evade_object) (object *objp, object *other_objp);
void (*ai_set_guard_object) (object *objp, object *other_objp);
void (*update_aspect_lock_information) (ai_info *aip, vec3d *vec_to_enemy, float dist_to_enemy, float enemy_radius);
void (*ai_chase_fly_away) (object *objp, ai_info *aip);
int (*has_preferred_secondary) (object *objp, object *en_objp, ship_weapon *swp);
void (*ai_choose_secondary_weapon) (object *objp, ai_info *aip, object *en_objp);
float (*set_secondary_fire_delay) (ai_info *aip, ship *shipp, weapon_info *swip);
void (*ai_chase_big_approach_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
void (*ai_chase_big_circle_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
void (*ai_chase_big_get_separations) (object *attack_objp, object *target_objp, vec3d *horz_vec_to_target, float *desired_separation, float *cur_separation);
void (*ai_chase_big_parallel_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
void (*ai_cruiser_chase_set_goal_pos) (vec3d *goal_pos, object *pl_objp, object *en_objp);
int (*maybe_hack_cruiser_chase_abort) ();
void (*ai_cruiser_chase) ();
void (*ai_chase) ();
int (*num_ships_attacking) (int target_objnum);
void (*remove_farthest_attacker) (int objnum);
int (*ai_maybe_limit_attackers) (int attacked_objnum);
void (*guard_object_was_hit) (object *guard_objp, object *hitter_objp);
void (*maybe_update_guard_object) (object *hit_objp, object *hitter_objp);
int (*ai_guard_find_nearby_bomb) (object *guarding_objp, object *guarded_objp);
void (*ai_guard_find_nearby_ship) (object *guarding_objp, object *guarded_objp);
void (*ai_guard_find_nearby_asteroid) (object *guarding_objp, object *guarded_objp);
void (*ai_guard_find_nearby_object) ();
void (*ai_big_guard) ();
void (*ai_guard) ();
void (*ai_do_objects_repairing_stuff) (object *repaired_objp, object *repair_objp, int how);
void (*ai_cleanup_dock_mode_subjective) (object *objp);
void (*ai_cleanup_dock_mode_objective) (object *objp);
void (*ai_cleanup_rearm_mode) (object *objp);
void (*ai_still) ();
void (*ai_stay_near) ();
int (*maybe_dock_obstructed) (object *cur_objp, object *goal_objp, int big_only_flag);
void (*ai_dock) ();
void (*process_subobjects) (int objnum);
void (*ai_fly_in_formation) (int wingnum);
void (*ai_disband_formation) (int wingnum);
int (*formation_is_leader_chaotic) (object *objp);
void (*ai_most_massive_object_of_its_wing_of_all_docked_objects_helper) (object *objp, dock_function_info *infop);
int (*ai_formation) ();
void (*ai_do_repair_frame) (object *objp, ai_info *aip, float frametime);
void (*call_doa) (object *child, object *parent);
void (*ai_maybe_launch_cmeasure) (object *objp, ai_info *aip);
void (*ai_preprocess_ignore_objnum) (object *objp, ai_info *aip);
void (*ai_chase_circle) (object *objp);
void (*ai_transfer_shield) (object *objp, int quadrant_num);
void (*ai_balance_shield) (object *objp);
void (*ai_manage_shield) (object *objp, ai_info *aip);
void (*ai_maybe_evade_locked_missile) (object *objp, ai_info *aip);
void (*maybe_evade_dumbfire_weapon) (ai_info *aip);
int (*ai_acquire_emerge_path) (object *pl_objp, int parent_objnum, int allowed_path_mask, vec3d *pos, vec3d *fvec);
void (*ai_emerge_bay_path_cleanup) (ai_info *aip);
void (*ai_bay_emerge) ();
int (*ai_find_closest_depart_path) (ai_info *aip, polymodel *pm, int allowed_path_mask);
int (*ai_acquire_depart_path) (object *pl_objp, int parent_objnum, int allowed_path_mask);
void (*ai_bay_depart) ();
void (*ai_sentrygun) ();
void (*ai_execute_behavior) (ai_info *aip);
int (*maybe_request_support) (object *objp);
void (*ai_set_mode_warp_out) (object *objp, ai_info *aip);
void (*ai_maybe_depart) (object *objp);
void (*ai_warp_out) (object *objp);
void (*ai_announce_ship_dying) (object *dying_objp);
int (*aas_1) (object *objp, ai_info *aip, vec3d *safe_pos);
int (*ai_avoid_shockwave) (object *objp, ai_info *aip);
int (*ai_await_repair_frame) (object *objp, ai_info *aip);
void (*ai_maybe_self_destruct) (object *objp, ai_info *aip);
int (*ai_need_new_target) (object *pl_objp, int target_objnum);
int (*maybe_big_ship_collide_recover_frame) (object *objp, ai_info *aip);
void (*validate_mode_submode) (ai_info *aip);
void (*ai_frame) (int objnum);
void (*ai_process) (object *obj, int ai_index, float frametime);
void (*init_ai_object) (int objnum);
void (*init_ai_objects) ();
void (*init_ai_system) ();
void (*ai_set_default_behavior) (object *obj, int classnum);
void (*ai_do_default_behavior) (object *obj);
void (*process_friendly_hit_message) (int message, object *objp);
void (*maybe_process_friendly_hit) (object *objp_hitter, object *objp_hit, object *objp_weapon);
void (*maybe_set_dynamic_chase) (ai_info *aip, int hitter_objnum);
void (*big_ship_collide_recover_start) (object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal);
void (*ai_update_lethality) (object *ship_obj, object *other_obj, float damage);
void (*ai_ship_hit) (object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal);
void (*ai_ship_destroy) (int shipnum, int method);
void (*ai_deathroll_start) (object *dying_objp);
int (*ai_abort_rearm_request) (object *requester_objp);
void (*ai_add_rearm_goal) (object *requester_objp, object *support_objp);
int (*ai_issue_rearm_request) (object *requester_objp);
void (*ai_rearm_repair) (object *objp, int docker_index, object *goal_objp, int dockee_index, int priority);
void (*cheat_fire_synaptic) (object *objp, ship *shipp, ai_info *aip);
void (*maybe_cheat_fire_synaptic) (object *objp, ai_info *aip);
};
// Set new pointer to override ai_code* function calls
// possibly copying the old function calls first
extern struct aicode_call_table *aicode_table;
extern struct aicode_call_table AICodeDefaultTable;
#endif
+185
View File
@@ -0,0 +1,185 @@
/**
* @file aimodular.cpp
* @brief Modular loading of new AI code based on name in AI Profile.
*
* The ai_module_init function should be called by ai_init.
*
* @author Fabian Franz <[email protected]>
*
*/
#include "ai/aibig.h"
#include "ai/aigoals.h"
#include "ai/aiinternal.h"
#ifdef _WIN32
#include <Windows.h>
/** @brief Wrapper for the dlopen functions for Windows */
#define dlopen(x,y) ((x==NULL)?GetModuleHandle(x):LoadLibrary(x))
#define dlsym GetProcAddress
#define dlclose FreeLibrary
static HINSTANCE handle = NULL; /**< @brief Handle for the loaded library */
#else
#include <dlfcn.h>
static void* handle = NULL; /**< @brief Handle for the loaded library */
#endif
/** @brief ai_module_init_function prototype */
typedef void (*ai_module_init_function)(void);
void ai_module_dlclose(void);
/**
* @brief Fallback function to load new AI from same process image.
*
* This function is used if no dynamic library with the name can be found
* or it does not contain the correct symbol.
*
* @param func_name The symbol to look for in handle
* @return Returns 0 on success and -1,-2 on errors
*
*/
int ai_module_dlopen_process(char* func_name)
{
ai_module_init_function ai_module_init_func;
// Maybe close handle first
ai_module_dlclose();
handle = dlopen(NULL, RTLD_NOW);
if (handle == NULL)
return -1;
ai_module_init_func=(ai_module_init_function)dlsym(handle, func_name);
#ifdef _WIN32
// Under WIN32 GetModuleHandle is not
// incrementing the reference counter
// so we need to "free" the handle directly
handle=NULL;
#endif
if (ai_module_init_func == NULL)
return -2;
ai_module_init_func();
return 0;
}
/**
* @brief Loads new AI from dynamic library
*
* This function looks for dllname.dll or dllname.so
* tries to load it into memory and if it finds the
* dllname_ai_module_init function it starts it.
*
* If it does not find the library or symbol it falls
* back to ai_module_dlopen_process.
*
* @param dllname The name of the library to load
* @return Returns 0 on success and -1,-2 on errors
*
*/
int ai_module_dlopen(char* dllname)
{
char buf[PATH_MAX+1];
char init_func_name[PATH_MAX+1];
ai_module_init_function ai_module_init_func;
#ifdef _WIN32
snprintf(buf, PATH_MAX, "%s.dll", dllname);
#else
snprintf(buf, PATH_MAX, "%s.so", dllname);
#endif
snprintf(init_func_name, PATH_MAX, "%s_ai_module_init", dllname);
handle = dlopen(buf, RTLD_NOW);
if (handle == NULL)
return ai_module_dlopen_process(init_func_name);
ai_module_init_func=(ai_module_init_function)dlsym(handle, init_func_name);
if (ai_module_init_func == NULL)
return ai_module_dlopen_process(init_func_name);
ai_module_init_func();
return 0;
}
/**
* @brief Closes the library handle
*
* This function closes the library handle.
*
*/
void ai_module_dlclose(void)
{
if (handle != NULL)
{
dlclose(handle);
handle=NULL;
}
}
/**
* @brief Inits or resets the AI code tables
*
* This function first resets the AI code tables,
* then closes any open libraries from before.
*
* Then it ooks if the ai_module is not "retail"
* and if that is the case it loads a library with this name.
*
*/
void ai_module_init(void)
{
// First Reset values
aibig_table = &AIBigDefaultTable;
aicode_table = &AICodeDefaultTable;
aigoal_table = &AIGoalDefaultTable;
aiturret_table = &AITurretDefaultTable;
ai_module_dlclose();
if (The_mission.ai_profile == NULL)
return;
if (strncmp(The_mission.ai_profile->ai_module, "retail", 6) != 0)
{
if (ai_module_dlopen(The_mission.ai_profile->ai_module) != 0)
{
char err[1024];
snprintf(err, sizeof(err), "AI_module_init(%s) failed: %s\n", The_mission.ai_profile->ai_module, dlerror());
mprintf(err);
}
}
}
extern "C" {
void newai_ai_module_init(void);
}
/**
* @brief Dummy function
*
* This dummy functions calls all AI implementations
* that should be statically included.
*
*/
void ai_module_dummy()
{
newai_ai_module_init();
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef _AIMODULAR_H
#define _AIMODULAR_H
void ai_module_init(void);
#endif
+117 -23
View File
@@ -233,6 +233,69 @@ typedef struct eval_enemy_obj_struct {
int nearest_objnum;
} eval_enemy_obj_struct;
// FF 17-06-07
// AI Turret Table Wrapper
struct aiturret_call_table *aiturret_table = &AITurretDefaultTable;
int turret_select_best_weapon (ship_subsys *turret, object *target)
{
return aiturret_table->turret_select_best_weapon(turret, target);
}
int valid_turret_enemy (object *objp, object *turret_parent)
{
return aiturret_table->valid_turret_enemy(objp, turret_parent);
}
void evaluate_obj_as_target (object *objp, eval_enemy_obj_struct *eeo)
{
aiturret_table->evaluate_obj_as_target(objp, eeo);
}
int get_nearest_turret_objnum (int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
{
return aiturret_table->get_nearest_turret_objnum(turret_parent_objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag);
}
int find_turret_enemy (ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
{
return aiturret_table->find_turret_enemy(turret_subsys, objnum, tpos, tvec, current_enemy, fov);
}
int turret_should_pick_new_target (ship_subsys *turret)
{
return aiturret_table->turret_should_pick_new_target(turret);
}
void turret_set_next_fire_timestamp (int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
{
aiturret_table->turret_set_next_fire_timestamp(weapon_num, wip, turret, aip);
}
int turret_should_fire_aspect (ship_subsys *turret, float dot, weapon_info *wip)
{
return aiturret_table->turret_should_fire_aspect(turret, dot, wip);
}
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
{
return aiturret_table->turret_fire_weapon(weapon_num, turret, parent_objnum, turret_pos, turret_fvec, predicted_pos, flak_range_override);
}
void turret_swarm_fire_from_turret (turret_swarm_info *tsi)
{
aiturret_table->turret_swarm_fire_from_turret(tsi);
}
void ai_fire_from_turret (ship *shipp, ship_subsys *ss, int parent_objnum)
{
aiturret_table->ai_fire_from_turret(shipp, ss, parent_objnum);
}
// AI Turret default implementation
// return 1 if objp is in fov of the specified turret, tp. Otherwise return 0.
// dist = distance from turret to center point of object
int object_in_turret_fov(object *objp, model_subsystem *tp, vec3d *tvec, vec3d *tpos, float dist)
@@ -274,7 +337,7 @@ int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
//Note that all non-negative return values are expressed in
//what I like to call "widx"s.
//Returns -1 if unable to find a weapon for the target at all.
int turret_select_best_weapon(ship_subsys *turret, object *target)
int aiturret_turret_select_best_weapon(ship_subsys *turret, object *target)
{
//TODO: Fill this out with extraodinary gun-picking algorithms
if(turret->weapons.num_primary_banks > 0)
@@ -441,7 +504,7 @@ float longest_turret_weapon_range(ship_weapon *swp)
// input: objp => object that turret is considering as an enemy
// turret_parent => object index for ship that turret sits on
// turret => turret pointer
int valid_turret_enemy(object *objp, object *turret_parent)
int aiturret_valid_turret_enemy(object *objp, object *turret_parent)
{
if ( objp == turret_parent ) {
return 0;
@@ -505,7 +568,7 @@ int valid_turret_enemy(object *objp, object *turret_parent)
}
extern int Player_attacking_enabled;
void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
void aiturret_evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
{
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
ship *shipp;
@@ -632,7 +695,11 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
dist *= (1.0f + 0.1f*num_att_turrets);
// return if we're over the cap
int max_turrets = 3 + Game_skill_level * Game_skill_level;
// int max_turrets = 3 + Game_skill_level * Game_skill_level;
int max_turrets = The_mission.ai_profile->max_turret_ownage_target[Game_skill_level];
if (objp->flags & OF_PLAYER_SHIP) {
max_turrets = The_mission.ai_profile->max_turret_ownage_player[Game_skill_level];
}
if (num_att_turrets > max_turrets) {
return;
}
@@ -712,7 +779,7 @@ int is_target_beam_valid(ship_weapon *swp, object *objp)
// tpos => position of turret (world coords)
// tvec => forward vector of turret (world coords)
// current_enemy => objnum of current turret target
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
int aiturret_get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
{
//float weapon_travel_dist;
int weapon_system_ok;
@@ -853,7 +920,7 @@ DCF_BOOL(use_parent_target, Use_parent_target)
// tpos => position of turret (world coords)
// tvec => forward vector of turret (world coords)
// current_enemy => objnum of current turret target
int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
int aiturret_find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
{
int enemy_team_mask, enemy_objnum;
model_subsystem *tp;
@@ -1197,7 +1264,7 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
}
// return !0 if the specified target should scan for a new target, otherwise return 0
int turret_should_pick_new_target(ship_subsys *turret)
int aiturret_turret_should_pick_new_target(ship_subsys *turret)
{
// int target_type;
@@ -1220,7 +1287,7 @@ int turret_should_pick_new_target(ship_subsys *turret)
}
// Set the next fire timestamp for a turret, based on weapon type and ai class
void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
void aiturret_turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
{
Assert(weapon_num < MAX_SHIP_WEAPONS);
float wait = wip->fire_wait * 1000.0f;
@@ -1276,7 +1343,7 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
}
// Decide if a turret should launch an aspect seeking missile
int turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
int aiturret_turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
{
if ( (dot > AICODE_TURRET_DUMBFIRE_ANGLE) && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
return 1;
@@ -1300,7 +1367,7 @@ void turret_update_enemy_in_range(ship_subsys *turret, float seconds)
}
// Fire a weapon from a turret
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
bool aiturret_turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
{
matrix turret_orient;
int weapon_objnum;
@@ -1351,11 +1418,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
// fire a beam weapon
beam_fire(&fire_info);
if (parent_ship->cloak_stage == 2) {
beam_weapon_info *bip=&wip->b_info;
shipfx_start_cloak(parent_ship,bip->beam_warmup + bip->beam_warmdown + (int)(bip->beam_life*1000.0f) + 1000);
}
return true;
}
// don't fire swam, but set up swarm info instead
@@ -1422,11 +1484,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
}
}
}
if ((parent_ship->cloak_stage > 0) && (parent_ship->cloak_stage < 3))
{
shipfx_start_cloak(parent_ship,500);
}
}
// reset any animations if we need to
@@ -1445,8 +1502,8 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
return true;
}
//void turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
//void aiturret_turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
void aiturret_turret_swarm_fire_from_turret(turret_swarm_info *tsi)
{
int weapon_objnum;
matrix turret_orient;
@@ -1510,7 +1567,7 @@ int Num_find_turret_enemy = 0;
int Num_turrets_fired = 0;
// Given a turret tp and its parent parent_objnum, fire from the turret at its enemy.
extern int Nebula_sec_range;
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
void aiturret_ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
{
float weapon_firing_range;
@@ -1636,6 +1693,10 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
int secnum = 0;
for(i = 0; i < (MAX_SHIP_WEAPONS); i++)
{
//WMC - Only fire more than once if we have multiple guns flag set.
if(num_valid > 0 && !(tp->flags & MSS_FLAG_USE_MULTIPLE_GUNS))
break;
if(i < MAX_SHIP_PRIMARY_BANKS)
{
if(i >= swp->num_primary_banks)
@@ -1903,6 +1964,25 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
}
}
if ( ok_to_fire && (tp->flags & MSS_FLAG_TURRET_HULL_CHECK) ) {
int model_num = Ship_info[shipp->ship_info_index].model_num;
mc_info hull_check;
vec3d end;
vm_vec_scale_add(&end, &gpos, &gvec, model_get_radius(model_num));
hull_check.model_num = model_num;
hull_check.orient = &objp->orient;
hull_check.pos = &objp->pos;
hull_check.p0 = &gpos;
hull_check.p1 = &end;
hull_check.flags = MC_CHECK_MODEL | MC_CHECK_RAY;
if ( model_collide(&hull_check) ) {
ok_to_fire = false;
}
}
if ( ok_to_fire )
{
something_was_ok_to_fire = true;
@@ -1958,3 +2038,17 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
ss->turret_time_enemy_in_range = 0.0f;
}
}
struct aiturret_call_table AITurretDefaultTable = {
aiturret_turret_select_best_weapon,
aiturret_valid_turret_enemy,
aiturret_evaluate_obj_as_target,
aiturret_get_nearest_turret_objnum,
aiturret_find_turret_enemy,
aiturret_turret_should_pick_new_target,
aiturret_turret_set_next_fire_timestamp,
aiturret_turret_should_fire_aspect,
aiturret_turret_fire_weapon,
aiturret_turret_swarm_fire_from_turret,
aiturret_ai_fire_from_turret
};
+122
View File
@@ -0,0 +1,122 @@
#include "ai/aibig.h"
#include "ai/aigoals.h"
#include "ai/aiinternal.h"
struct aicode_call_table AICodeNewAITable;
#include "iff_defs/iff_defs.h"
#define DEPARTURE_HULL_PERCENT 0.3 // Departure if 15% to 30% hull strength left
void newai_ai_maybe_depart(object* objp_ship)
{
ship *shipp = &Ships[objp_ship->instance];
// Coward mode:
//
// Depart if:
// * not player and
// * same team as player and player not traitor and
// * fighter or bomber
// * hull multiplied with random value below critical
if (objp_ship->flags & OF_PLAYER_SHIP)
return;
// make sure player is on their team and not a traitor
if ((Player_ship->team != shipp->team) || (Player_ship->team == Iff_traitor))
return;
if ((Ship_info[shipp->ship_info_index].flags & (SIF_FIGHTER|SIF_BOMBER)) == 0)
return;
if (objp_ship->hull_strength*(frand()+1) < DEPARTURE_HULL_PERCENT * shipp->ship_max_hull_strength)
mission_do_departure(objp_ship);
}
// Object *objp_ship was hit by either weapon *objp_weapon or collided into by ship hit_objp at point *hitpos.
void newai_aicode_ai_ship_hit (object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal)
{
// Call the default implementation
AICodeDefaultTable.ai_ship_hit(objp_ship, hit_objp, hitpos, shield_quadrant, hit_normal);
if (hit_objp->parent >= 0)
{
object *objp_hitter = &Objects[hit_objp->parent];
if ( objp_hitter->type == OBJ_SHIP )
{
ship *shipp_hitter = &Ships[objp_hitter->instance];
ship *shipp_hit = &Ships[objp_ship->instance];
fprintf(stderr, "Ship %s hit %s\n", shipp_hitter->ship_name, shipp_hit->ship_name);
}
}
newai_ai_maybe_depart(objp_ship);
}
void newai_aicode_maybe_process_friendly_hit(object *objp_hitter, object *objp_hit, object *objp_weapon)
{
AICodeDefaultTable.maybe_process_friendly_hit(objp_hitter, objp_hit, objp_weapon);
if (obj_team(objp_hitter) == obj_team(objp_hit))
{
if ( objp_hitter->type != OBJ_SHIP )
return;
ship *shipp_hitter = &Ships[objp_hitter->instance];
ship *shipp_hit = &Ships[objp_hit->instance];
fprintf(stderr, "Ship %s friendly hit %s\n", shipp_hitter->ship_name, shipp_hit->ship_name);
}
}
int newai_aicode_ai_fire_primary_weapon(object *objp)
{
int fired = AICodeDefaultTable.ai_fire_primary_weapon(objp);
if (fired)
{
ship *shipp = &Ships[objp->instance];
fprintf(stderr, "Ship %s fired primary weapon\n", shipp->ship_name);
}
}
void newai_aicode_init_ship_info()
{
static int called=0;
if (called == 0)
{
fprintf(stderr, "Init ship info was called\n");
called=1;
}
AICodeDefaultTable.init_ship_info();
}
extern "C" {
void newai_ai_module_init();
}
void newai_ai_module_init()
{
#ifdef PACKAGE_NAME
fprintf(stderr, "ai_module_init() called\n");
#else
fprintf(stderr, "ai_module_init() modular called\n");
#endif
// First make a copy
memcpy(&AICodeNewAITable, &AICodeDefaultTable, sizeof(AICodeNewAITable));
// Now set up our overridden functions
aicode_table = &AICodeNewAITable;
aicode_table->init_ship_info=newai_aicode_init_ship_info;
aicode_table->ai_ship_hit=newai_aicode_ai_ship_hit;
//aicode_table->ai_fire_primary_weapon=newai_aicode_ai_fire_primary_weapon;
//aicode_table->maybe_process_friendly_hit=newai_aicode_maybe_process_friendly_hit;
}
+18 -8
View File
@@ -421,18 +421,27 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
if(image_id != -1)
{
text_pos[0] = image_pos[0] + w; //Still set from bm_get_info call
deltax = text_pos[0] / 1024.0f; //MikeStar;
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
if (!center_x)
{
deltax = text_pos[0] / 1024.0f; //MikeStar;
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
}
}
else
{
text_pos[0] = image_pos[0];
deltax = text_pos[0] / 1024.0f; //MikeStar;
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
if (!center_x)
{
deltax = text_pos[0] / 1024.0f; //MikeStar;
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
}
}
text_pos[1] = image_pos[1];
deltay = text_pos[1] / 768.0f; //MikeStar;
text_pos[1] = gr_screen.max_h * deltay; //MikeStar;
if (!center_y)
{
deltay = text_pos[1] / 768.0f; //MikeStar;
text_pos[1] = gr_screen.max_h * deltay; //MikeStar;
}
time_displayed = 0.0f;
time_displayed_end = 2.0f*fade_time + display_time;
@@ -462,11 +471,12 @@ void subtitle::do_frame(float frametime)
gr_set_color_fast(&text_color);
int font_height = gr_get_font_height();
int y = text_pos[1];
int x = fl2i(text_pos[0]);
int y = fl2i(text_pos[1]);
for(unsigned int i = 0; i < text_lines.size(); i++)
{
gr_string(text_pos[0], y, (char*)text_lines[i].c_str(), false);
gr_string(x, y, (char*)text_lines[i].c_str(), false);
y += font_height;
}
+7 -1
View File
@@ -1660,9 +1660,11 @@ int cf_get_file_list( int max, char **list, int pathtype, char *filter, int sort
if (find_handle != -1) {
do {
if (num_files >= max)
break;
if ( strlen(find.name) >= MAX_FILENAME_LEN )
continue;
if (!(find.attrib & _A_SUBDIR)) {
if ( !Get_file_list_filter || (*Get_file_list_filter)(find.name) ) {
ptr = strrchr(find.name, '.');
@@ -1699,6 +1701,10 @@ int cf_get_file_list( int max, char **list, int pathtype, char *filter, int sort
if (num_files >= max)
break;
if ( strlen(dir->d_name) >= MAX_FILENAME_LEN ) {
continue;
}
if (fnmatch(filter, dir->d_name, 0) != 0)
continue;
+8 -4
View File
@@ -162,8 +162,8 @@ void pack_file( char *filespec, char *filename, int filesize, _fs_time_t time_wr
}
if ( strlen(filename) > 31 ) {
printf( "Filename '%s' too long\n", filename );
exit(1);
printf( "Filename '%s' too long! Skipping...\n", filename );
return;
}
memset( path, 0, sizeof(path) );
@@ -255,7 +255,7 @@ void pack_directory( char * filespec)
find_handle = _findfirst( tmp1, &find );
if( find_handle != -1 ) {
if ( find.attrib & _A_SUBDIR ) {
if (strcmp( "..", find.name) && strcmp( ".", find.name)) {
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
strcpy( tmp, filespec );
strcat( tmp, "\\" );
strcat( tmp, find.name );
@@ -267,7 +267,7 @@ void pack_directory( char * filespec)
while( !_findnext( find_handle, &find ) ) {
if ( find.attrib & _A_SUBDIR ) {
if (strcmp( "..", find.name) && strcmp( ".", find.name)) {
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
strcpy( tmp, filespec );
strcat( tmp, "\\" );
strcat( tmp, find.name );
@@ -300,6 +300,10 @@ void pack_directory( char * filespec)
continue;
}
if ( (strcmp(dir->d_name, ".svn") == 0) ) {
continue;
}
if (S_ISDIR(buf.st_mode)) {
strcpy( tmp, filespec );
strcat( tmp, "/" );
+1
View File
@@ -560,6 +560,7 @@ void cutscenes_screen_play()
// full_name = cf_add_ext(name, NOX(".mve"));
main_hall_stop_music();
main_hall_stop_ambient();
int rval = movie_play(name);
main_hall_start_music();
+1 -6
View File
@@ -117,7 +117,6 @@
#include "cutscene/cutscenes.h" // cutscene_mark_viewable()
#include "cutscene/mvelib.h"
#include "cutscene/oggplayer.h"
#include "menuui/mainhallmenu.h"
extern int Game_mode;
@@ -196,9 +195,6 @@ bool movie_play(char *name)
return false;
}
// kill all background sounds
main_hall_pause();
// clear the screen and hide the mouse cursor
Mouse_hidden++;
gr_reset_clip();
@@ -251,9 +247,8 @@ bool movie_play(char *name)
}
}
// show the mouse cursor again, and unpause the mainhall music
// show the mouse cursor again
Mouse_hidden--;
main_hall_unpause();
return true;
}
+10 -7
View File
@@ -374,7 +374,7 @@ void bg_bitmap_dlg::create()
box->AddString(Nebula_colors[i]);
}
m_slider.SetRange(100, MAX_STARS);
m_slider.SetRange(0, MAX_STARS);
m_slider.SetPos(Num_stars);
sprintf(buf, "%d", Num_stars);
GetDlgItem(IDC_TOTAL)->SetWindowText(buf);
@@ -1384,15 +1384,18 @@ void bg_bitmap_dlg::OnImportBackground()
Mp = saved_mp;
// pick one (if count is 0, it's retail with just one background)
if (count > 1)
if (count > 0)
{
int i, which;
int i, which = 0;
BackgroundChooser dlg(count);
if (dlg.DoModal() == IDCANCEL)
return;
if (count > 1)
{
BackgroundChooser dlg(count);
if (dlg.DoModal() == IDCANCEL)
return;
which = dlg.GetChosenBackground();
which = dlg.GetChosenBackground();
}
for (i = 0; i < which + 1; i++)
skip_to_string("$Bitmap List:");
+143 -131
View File
@@ -90,21 +90,26 @@ IDB_CHAINED_DIRECTIVE BITMAP MOVEABLE PURE "res\\chained_directive.bmp"
IDB_GREEN_DOT BITMAP MOVEABLE PURE "res\\green_do.bmp"
IDB_BLACK_DOT BITMAP MOVEABLE PURE "res\\black_do.bmp"
IDB_VARIABLE BITMAP MOVEABLE PURE "res\\variable.bmp"
IDB_DATA_12 BITMAP MOVEABLE PURE "res\\data12.bmp"
IDB_DATA_02 BITMAP MOVEABLE PURE "res\\data02.bmp"
IDB_DATA_03 BITMAP MOVEABLE PURE "res\\data03.bmp"
IDB_DATA_04 BITMAP MOVEABLE PURE "res\\data04.bmp"
IDB_DATA_05 BITMAP MOVEABLE PURE "res\\data05.bmp"
IDB_DATA_06 BITMAP MOVEABLE PURE "res\\data06.bmp"
IDB_DATA_07 BITMAP MOVEABLE PURE "res\\data07.bmp"
IDB_DATA_08 BITMAP MOVEABLE PURE "res\\data08.bmp"
IDB_DATA_09 BITMAP MOVEABLE PURE "res\\data09.bmp"
IDB_DATA_00 BITMAP MOVEABLE PURE "res\\data00.bmp"
IDB_DATA_10 BITMAP MOVEABLE PURE "res\\data10.bmp"
IDB_DATA_11 BITMAP MOVEABLE PURE "res\\data11.bmp"
IDB_DATA_01 BITMAP MOVEABLE PURE "res\\data01.bmp"
IDB_DATA_15 BITMAP MOVEABLE PURE "res\\data15.bmp"
IDB_DATA_14 BITMAP MOVEABLE PURE "res\\data14.bmp"
IDB_DATA_13 BITMAP MOVEABLE PURE "res\\data13.bmp"
IDB_DATA_20 BITMAP MOVEABLE PURE "res\\data20.bmp"
IDB_DATA_25 BITMAP MOVEABLE PURE "res\\data25.bmp"
IDB_DATA_30 BITMAP MOVEABLE PURE "res\\data30.bmp"
IDB_DATA_35 BITMAP MOVEABLE PURE "res\\data35.bmp"
IDB_DATA_40 BITMAP MOVEABLE PURE "res\\data40.bmp"
IDB_DATA_45 BITMAP MOVEABLE PURE "res\\data45.bmp"
IDB_DATA_50 BITMAP MOVEABLE PURE "res\\data50.bmp"
IDB_DATA_55 BITMAP MOVEABLE PURE "res\\data55.bmp"
IDB_DATA_60 BITMAP MOVEABLE PURE "res\\data60.bmp"
IDB_DATA_65 BITMAP MOVEABLE PURE "res\\data65.bmp"
IDB_DATA_70 BITMAP MOVEABLE PURE "res\\data70.bmp"
IDB_DATA_75 BITMAP MOVEABLE PURE "res\\data75.bmp"
IDB_DATA_80 BITMAP MOVEABLE PURE "res\\data80.bmp"
IDB_DATA_85 BITMAP MOVEABLE PURE "res\\data85.bmp"
IDB_DATA_90 BITMAP MOVEABLE PURE "res\\data90.bmp"
IDB_DATA_95 BITMAP MOVEABLE PURE "res\\data95.bmp"
/////////////////////////////////////////////////////////////////////////////
//
@@ -873,13 +878,19 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,355,184,50,14
END
IDD_MISSION_NOTES DIALOGEX 0, 0, 464, 324
IDD_MISSION_NOTES DIALOG DISCARDABLE 0, 0, 479, 327
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Mission Specs"
FONT 8, "MS Sans Serif"
BEGIN
RTEXT "Title",IDC_STATIC,7,10,29,8
EDITTEXT IDC_MISSION_TITLE,41,7,109,14,ES_AUTOHSCROLL
RTEXT "Designer",IDC_STATIC,7,25,29,8
EDITTEXT IDC_DESIGNER_NAME,41,23,109,14,ES_AUTOHSCROLL
RTEXT "Created:",IDC_STATIC,23,42,28,8
LTEXT "xx/xx/xx",IDC_CREATED,57,42,91,8
RTEXT "Last Modified:",IDC_STATIC,7,51,45,8
LTEXT "xx/xx/xx",IDC_MODIFIED,57,51,92,8
CONTROL "Single Player",IDC_SINGLE,"Button",BS_AUTORADIOBUTTON |
WS_GROUP,7,63,57,10
CONTROL "Multi Player",IDC_MULTI,"Button",BS_AUTORADIOBUTTON,7,
@@ -892,100 +903,100 @@ BEGIN
BS_AUTORADIOBUTTON,76,72,66,10
CONTROL "Dogfight",IDC_DOGFIGHT,"Button",BS_AUTORADIOBUTTON,76,
81,43,10
EDITTEXT IDC_RESPAWNS,92,94,50,14,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Max Respawns",IDC_STATIC,8,97,52,8
EDITTEXT IDC_RESPAWNS,86,94,50,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_RESPAWN_SPIN,"msctls_updown32",
UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
UDS_ARROWKEYS,142,94,11,14
PUSHBUTTON "Custom Wing Names",IDC_CUSTOM_WING_NAMES,13,115,136,14
EDITTEXT IDC_SQUAD_NAME,356,124,98,14,ES_AUTOHSCROLL
PUSHBUTTON "Logo",IDC_SQUAD_LOGO_BUTTON,316,139,31,14
EDITTEXT IDC_SQUAD_LOGO,356,139,98,14,ES_AUTOHSCROLL |
ES_READONLY
PUSHBUTTON "640x480",IDC_LOADING_SCREEN_BUTTON640,317,284,40,14
EDITTEXT IDC_LOADING_SCREEN640,357,284,97,14,ES_AUTOHSCROLL
PUSHBUTTON "1024x768",IDC_LOADING_SCREEN_BUTTON1024,317,300,40,16
EDITTEXT IDC_LOADING_SCREEN1024,357,300,97,16,ES_AUTOHSCROLL
CONTROL "All Teams at War",IDC_FULL_WAR,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,165,22,72,10
CONTROL "Red Alert Mission",IDC_RED_ALERT,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,165,33,78,10
CONTROL "Scramble Mission",IDC_SCRAMBLE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,165,42,72,10
CONTROL "No Briefing",IDC_NO_BRIEFING,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,165,52,72,10
CONTROL "No Debriefing",IDC_NO_DEBRIEFING,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,165,62,72,10
CONTROL "Disallow Promotions/Badges",IDC_NO_PROMOTION,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,165,73,106,10
CONTROL "Disable Built-in Messages",IDC_DISABLE_BUILTIN_MSGS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,165,82,123,10
CONTROL "Disable Built-in Command Messages",
IDC_DISABLE_BUILTIN_COMMAND_MSGS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,165,92,129,10
CONTROL "No Traitor",IDC_NO_TRAITOR,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,165,102,123,10
CONTROL "All Ships Beam-Freed By Default",
IDC_BEAM_FREE_ALL_BY_DEFAULT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,304,38,123,10
CONTROL "Allow Daisy-Chained Docking",IDC_ALLOW_DOCK_TREES,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,304,47,123,10
UDS_ARROWKEYS,136,94,11,14
PUSHBUTTON "Custom Wing Names",IDC_CUSTOM_WING_NAMES,10,115,128,14
GROUPBOX "Squadron Reassign",IDC_STATIC,2,136,148,44
LTEXT "Name",IDC_STATIC,14,147,28,8
EDITTEXT IDC_SQUAD_NAME,48,147,98,14,ES_AUTOHSCROLL
PUSHBUTTON "Logo",IDC_SQUAD_LOGO_BUTTON,8,161,31,14
EDITTEXT IDC_SQUAD_LOGO,48,161,98,14,ES_AUTOHSCROLL | ES_READONLY
GROUPBOX "Loading Screen",IDC_STATIC,2,185,148,46
PUSHBUTTON "640x480",IDC_LOADING_SCREEN_BUTTON640,7,197,40,14
EDITTEXT IDC_LOADING_SCREEN640,47,197,97,14,ES_AUTOHSCROLL
PUSHBUTTON "1024x768",IDC_LOADING_SCREEN_BUTTON1024,7,213,40,16
EDITTEXT IDC_LOADING_SCREEN1024,47,213,97,16,ES_AUTOHSCROLL
GROUPBOX "Support Ships",IDC_STATIC,160,6,152,71
CONTROL "Disallow Support Ships",IDC_SUPPORT_ALLOWED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,309,168,95,10
BS_AUTOCHECKBOX | WS_TABSTOP,164,16,95,10
CONTROL "Support Ships Repair Hull",IDC_SUPPORT_REPAIRS_HULL,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,179,123,10
EDITTEXT IDC_MAX_HULL_REPAIR_VAL,389,193,59,14,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_SUBSYS_REPAIR_VAL,389,211,59,14,ES_AUTOHSCROLL
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,164,27,123,10
LTEXT "Hull Repair Ceiling",IDC_STATIC,164,43,60,8
EDITTEXT IDC_MAX_HULL_REPAIR_VAL,244,41,49,14,ES_AUTOHSCROLL
LTEXT "%",IDC_STATIC,298,46,8,8
LTEXT "Subsytem Repair Ceiling",IDC_STATIC,164,64,75,8
EDITTEXT IDC_MAX_SUBSYS_REPAIR_VAL,244,59,49,14,ES_AUTOHSCROLL
LTEXT "%",IDC_STATIC,298,60,8,8
GROUPBOX "Ship Trails",IDC_STATIC,160,81,154,41
CONTROL "Toggle (off in nebula; on elsewhere)",
IDC_SPECS_TOGGLE_TRAILS,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,309,242,141,10
WS_TABSTOP,162,92,141,10
CONTROL "Minimium speed to display",IDC_CONTRAIL_THRESHOLD_CHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,253,93,10
EDITTEXT IDC_CONTRAIL_THRESHOLD,411,252,48,14,ES_READONLY
COMBOBOX IDC_AI_PROFILE,59,134,93,140,CBS_DROPDOWNLIST |
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,103,93,10
EDITTEXT IDC_CONTRAIL_THRESHOLD,262,102,48,14,ES_READONLY
GROUPBOX "Built-in Command Messages",IDC_STATIC,158,131,154,46
LTEXT "Sender",IDC_STATIC,165,145,40,8
COMBOBOX IDC_COMMAND_SENDER,209,143,99,140,CBS_DROPDOWN |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_EVENT_MUSIC,211,134,93,140,CBS_DROPDOWNLIST |
LTEXT "Persona",IDC_STATIC,165,161,40,8
COMBOBOX IDC_COMMAND_PERSONA,209,160,99,140,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_SUBSTITUTE_EVENT_MUSIC,211,150,93,140,CBS_DROPDOWN |
GROUPBOX "Mission Music",IDC_STATIC,157,188,154,47
LTEXT "Default",IDC_STATIC,161,200,40,8
COMBOBOX IDC_EVENT_MUSIC,207,199,99,140,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MISSION_DESC,0,182,299,57,ES_MULTILINE |
ES_AUTOVSCROLL | ES_WANTRETURN
EDITTEXT IDC_MISSION_NOTES,1,254,297,57,ES_MULTILINE |
ES_AUTOVSCROLL | ES_WANTRETURN
DEFPUSHBUTTON "OK",IDOK,347,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,403,7,50,14
LTEXT "Max Respawns",IDC_STATIC,8,97,52,8
RTEXT "Title",IDC_STATIC,7,10,29,8
RTEXT "Designer Notes",IDC_STATIC,1,243,50,8
LTEXT "xx/xx/xx",IDC_MODIFIED,57,51,101,8
RTEXT "Designer",IDC_STATIC,7,25,29,8
RTEXT "Created:",IDC_STATIC,23,42,28,8
LTEXT "xx/xx/xx",IDC_CREATED,57,42,103,8
RTEXT "Last Modified:",IDC_STATIC,7,51,45,8
LTEXT "Mission Description",IDC_STATIC,0,170,62,8
LTEXT "Music",IDC_STATIC,153,137,32,8
GROUPBOX "Squadron Reassign",IDC_STATIC,310,114,150,44
LTEXT "Name",IDC_STATIC,322,125,28,8
GROUPBOX "Loading Screen",IDC_STATIC,309,274,151,46
GROUPBOX "Support Ships",IDC_STATIC,305,158,154,71
LTEXT "Hull Repair Ceiling",IDC_STATIC,309,195,60,8
LTEXT "Subsytem Repair Ceiling",IDC_STATIC,309,216,75,8
LTEXT "%",IDC_STATIC,452,196,8,8
LTEXT "%",IDC_STATIC,452,210,8,8
GROUPBOX "Ship Trails",IDC_STATIC,306,231,154,41
LTEXT "Substitute Music",IDC_STATIC,153,153,52,8
LTEXT "AI Profile",IDC_STATIC,1,137,32,8
CONTROL "Player Starts under AI Control (NO MULTI)",
IDC_PLAYER_START_AI,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,3,153,149,10
LTEXT "If music pack is present",IDC_STATIC,161,213,43,16
COMBOBOX IDC_SUBSTITUTE_EVENT_MUSIC,207,215,99,140,CBS_DROPDOWN |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Flags",IDC_STATIC,321,20,154,198
CONTROL "All Teams at War",IDC_FULL_WAR,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,326,31,72,10
CONTROL "Red Alert Mission",IDC_RED_ALERT,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,326,41,78,10
CONTROL "Scramble Mission",IDC_SCRAMBLE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,326,51,72,10
CONTROL "Disallow Promotions/Badges",IDC_NO_PROMOTION,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,326,61,106,10
CONTROL "Disable Built-in Messages",IDC_DISABLE_BUILTIN_MSGS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,71,123,10
CONTROL "Disable Built-in Command Messages",
IDC_DISABLE_BUILTIN_COMMAND_MSGS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,326,81,129,10
CONTROL "No Traitor",IDC_NO_TRAITOR,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,326,91,123,10
CONTROL "All Ships Beam-Freed By Default",
IDC_BEAM_FREE_ALL_BY_DEFAULT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,326,101,123,10
CONTROL "Allow Daisy-Chained Docking",IDC_ALLOW_DOCK_TREES,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,111,123,10
CONTROL "No Briefing",IDC_NO_BRIEFING,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,326,121,72,10
CONTROL "No Debriefing",IDC_NO_DEBRIEFING,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,326,131,72,10
CONTROL "Use Autopilot Cinematics",IDC_USE_AUTOPILOT_CINEMATICS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,304,58,123,10
CONTROL "2D Mission",IDC_2D_MISSION,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,304,70,123,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,141,123,10
CONTROL "Deactivate Hardcoded Autopilot",
IDC_DEACTIVATE_AUTOPILOT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,304,81,123,10
LTEXT "Retail Flags:",IDC_STATIC,167,7,40,8
LTEXT "FS2 Open Flags",IDC_STATIC,304,25,52,8
WS_TABSTOP,326,151,123,10
CONTROL "Player Starts under AI Control (NO MULTI)",
IDC_PLAYER_START_AI,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,326,161,146,10
CONTROL "2D Mission",IDC_2D_MISSION,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,326,171,123,10
LTEXT "AI Profile",IDC_STATIC,320,229,32,8
COMBOBOX IDC_AI_PROFILE,378,226,93,140,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Mission Description",IDC_STATIC,4,238,62,8
EDITTEXT IDC_MISSION_DESC,4,250,471,29,ES_MULTILINE |
ES_AUTOVSCROLL | ES_WANTRETURN
RTEXT "Designer Notes",IDC_STATIC,2,284,50,8
EDITTEXT IDC_MISSION_NOTES,3,294,472,29,ES_MULTILINE |
ES_AUTOVSCROLL | ES_WANTRETURN
DEFPUSHBUTTON "OK",IDOK,368,0,50,14
PUSHBUTTON "Cancel",IDCANCEL,424,0,50,14
END
IDD_PREFERENCES DIALOG DISCARDABLE 0, 0, 333, 81
@@ -1917,11 +1928,11 @@ BEGIN
ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
END
IDD_BRIEFING_EDITOR DIALOGEX 0, 0, 258, 407
IDD_BRIEFING_EDITOR DIALOGEX 0, 0, 258, 417
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Briefing Editor"
MENU IDR_PLAYER_EDIT_MENU
FONT 8, "MS Sans Serif", 0, 0, 0x1
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Prev",IDC_PREV,147,7,23,14,0,WS_EX_STATICEDGE
PUSHBUTTON "Next",IDC_NEXT,173,7,23,14,0,WS_EX_STATICEDGE
@@ -1943,57 +1954,58 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,7,38,69,10
CONTROL "Cut to previous stage",IDC_CUT_PREV,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,47,83,10
EDITTEXT IDC_TEXT,7,75,244,40,ES_MULTILINE | ES_AUTOVSCROLL |
EDITTEXT IDC_TEXT,7,72,244,40,ES_MULTILINE | ES_AUTOVSCROLL |
ES_WANTRETURN
EDITTEXT IDC_VOICE,63,118,83,13,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BROWSE,150,118,42,14,0,WS_EX_STATICEDGE
PUSHBUTTON "IDB_PLAY",IDC_PLAY,194,118,13,14,BS_BITMAP,
EDITTEXT IDC_VOICE,63,115,83,13,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BROWSE,150,115,42,14,0,WS_EX_STATICEDGE
PUSHBUTTON "IDB_PLAY",IDC_PLAY,194,115,13,14,BS_BITMAP,
WS_EX_TRANSPARENT | WS_EX_STATICEDGE
COMBOBOX IDC_BRIEFING_MUSIC,63,134,83,135,CBS_DROPDOWNLIST |
COMBOBOX IDC_BRIEFING_MUSIC,70,142,83,135,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_SUBSTITUTE_BRIEFING_MUSIC,63,151,83,135,CBS_DROPDOWN |
COMBOBOX IDC_SUBSTITUTE_BRIEFING_MUSIC,70,159,83,135,CBS_DROPDOWN |
WS_VSCROLL | WS_TABSTOP
CONTROL "Tree1",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS |
TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS |
WS_BORDER | WS_TABSTOP,7,181,244,71,WS_EX_CLIENTEDGE
WS_BORDER | WS_TABSTOP,7,190,244,71,WS_EX_CLIENTEDGE
CONTROL "Draw lines between marked icons",IDC_LINES,"Button",
BS_3STATE | WS_TABSTOP,129,255,122,10
EDITTEXT IDC_ICON_LABEL,51,277,75,14,ES_AUTOHSCROLL
COMBOBOX IDC_ICON_IMAGE,52,293,75,135,CBS_DROPDOWNLIST |
BS_3STATE | WS_TABSTOP,129,264,122,10
EDITTEXT IDC_ICON_LABEL,51,288,75,14,ES_AUTOHSCROLL
COMBOBOX IDC_ICON_IMAGE,52,304,75,135,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_SHIP_TYPE,52,309,75,145,CBS_DROPDOWNLIST |
COMBOBOX IDC_SHIP_TYPE,52,320,75,145,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_TEAM,52,325,75,84,CBS_DROPDOWNLIST | WS_VSCROLL |
COMBOBOX IDC_TEAM,52,336,75,84,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
EDITTEXT IDC_ID,151,273,30,12,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_ID,151,284,30,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Highlight",IDC_HILIGHT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,135,291,43,10
WS_TABSTOP,135,302,43,10
CONTROL "Change locally",IDC_LOCAL,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,135,308,62,10
WS_TABSTOP,135,319,62,10
CONTROL "Flip Icon",IDC_FLIP_ICON,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,136,324,43,10
PUSHBUTTON "Make Icon",IDC_MAKE_ICON,197,272,50,14,0,
WS_TABSTOP,136,335,43,10
PUSHBUTTON "Make Icon",IDC_MAKE_ICON,197,283,50,14,0,
WS_EX_STATICEDGE
PUSHBUTTON "Delete Icon",IDC_DELETE_ICON,197,289,50,14,0,
PUSHBUTTON "Delete Icon",IDC_DELETE_ICON,197,300,50,14,0,
WS_EX_STATICEDGE
PUSHBUTTON "Propagate",IDC_PROPAGATE_ICONS,197,306,50,14,0,
PUSHBUTTON "Propagate",IDC_PROPAGATE_ICONS,197,317,50,14,0,
WS_EX_STATICEDGE
EDITTEXT IDC_ICON_TEXT,14,352,230,40,ES_MULTILINE |
EDITTEXT IDC_ICON_TEXT,14,363,230,40,ES_MULTILINE |
ES_AUTOVSCROLL | ES_WANTRETURN
LTEXT "Stage 1 of 9",IDC_STAGE_TITLE,7,7,53,8
GROUPBOX "Current Icon Info",IDC_STATIC,7,264,244,136
LTEXT "Label",IDC_STATIC,13,280,18,8
LTEXT "Icon image",IDC_STATIC,13,296,36,8
LTEXT "Text",IDC_STATIC,7,65,15,8
GROUPBOX "Current Icon Info",IDC_STATIC,7,274,244,136
LTEXT "Label",IDC_STATIC,13,291,18,8
LTEXT "Icon image",IDC_STATIC,13,307,36,8
LTEXT "Text",IDC_STATIC,7,62,15,8
LTEXT "Camera Transition Time (ms)",IDC_STATIC,7,25,90,8
LTEXT "Voice Wave File",IDC_STATIC,7,120,53,8
LTEXT "Text",IDC_STATIC,14,341,15,8
LTEXT "Team",IDC_STATIC,13,328,19,8
LTEXT "Ship Type",IDC_STATIC,13,312,33,8
LTEXT "ID",IDC_STATIC,137,275,8,8
LTEXT "Briefing Music",IDC_STATIC,7,137,45,8
LTEXT "Usage Formula",IDC_STATIC,7,171,48,8
LTEXT "Substitute Music",IDC_STATIC,7,154,53,8
LTEXT "Voice Wave File",IDC_STATIC,7,117,53,8
LTEXT "Text",IDC_STATIC,14,352,15,8
LTEXT "Team",IDC_STATIC,13,339,19,8
LTEXT "Ship Type",IDC_STATIC,13,323,33,8
LTEXT "ID",IDC_STATIC,137,286,8,8
LTEXT "Default",IDC_STATIC,14,144,24,8
LTEXT "Usage Formula",IDC_STATIC,7,180,48,8
LTEXT "If music pack is present",IDC_STATIC,14,157,44,17
GROUPBOX "Briefing Music",IDC_STATIC,7,132,150,44
END
IDD_IGNORE_ORDERS DIALOG DISCARDABLE 0, 0, 120, 217
@@ -2556,8 +2568,8 @@ BEGIN
IDD_MISSION_NOTES, DIALOG
BEGIN
RIGHTMARGIN, 460
BOTTOMMARGIN, 320
RIGHTMARGIN, 475
BOTTOMMARGIN, 323
END
IDD_PREFERENCES, DIALOG
@@ -2731,7 +2743,7 @@ BEGIN
RIGHTMARGIN, 251
VERTGUIDE, 136
TOPMARGIN, 7
BOTTOMMARGIN, 400
BOTTOMMARGIN, 410
END
IDD_IGNORE_ORDERS, DIALOG
+4
View File
@@ -1572,6 +1572,10 @@ void clear_mission()
The_mission.contrail_threshold = CONTRAIL_THRESHOLD_DEFAULT;
// Goober5000
The_mission.command_persona = Default_command_persona;
strcpy(The_mission.command_sender, DEFAULT_COMMAND);
// Goober5000: reset ALL mission flags, not just nebula!
The_mission.flags = 0;
The_mission.support_ships.max_support_ships = -1; // negative means infinite
+36 -2
View File
@@ -266,6 +266,7 @@
#include "gamesnd/eventmusic.h"
#include "cfile/cfile.h"
#include "mission/missionparse.h"
#include "mission/missionmessage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -297,6 +298,8 @@ CMissionNotesDlg::CMissionNotesDlg(CWnd* pParent /*=NULL*/) : CDialog(CMissionNo
m_ai_profile = -1;
m_event_music = -1;
m_substitute_event_music = _T("");
m_command_persona = -1;
m_command_sender = _T("");
m_full_war = FALSE;
m_red_alert = FALSE;
m_scramble = FALSE;
@@ -341,6 +344,8 @@ void CMissionNotesDlg::DoDataExchange(CDataExchange* pDX)
DDX_CBIndex(pDX, IDC_AI_PROFILE, m_ai_profile);
DDX_CBIndex(pDX, IDC_EVENT_MUSIC, m_event_music);
DDX_Text(pDX, IDC_SUBSTITUTE_EVENT_MUSIC, m_substitute_event_music);
DDX_CBIndex(pDX, IDC_COMMAND_PERSONA, m_command_persona);
DDX_Text(pDX, IDC_COMMAND_SENDER, m_command_sender);
DDX_Check(pDX, IDC_FULL_WAR, m_full_war);
DDX_Check(pDX, IDC_RED_ALERT, m_red_alert);
DDX_Check(pDX, IDC_SCRAMBLE, m_scramble);
@@ -609,6 +614,12 @@ void CMissionNotesDlg::OnOK()
MODIFY(Current_soundtrack_num, m_event_music - 1);
strcpy(The_mission.substitute_event_music_name, m_substitute_event_music);
MODIFY(The_mission.command_persona, ((CComboBox *) GetDlgItem(IDC_COMMAND_PERSONA))->GetItemData(m_command_persona));
if (m_command_sender.GetAt(0) == '#')
strcpy(The_mission.command_sender, m_command_sender.Mid(1));
else
strcpy(The_mission.command_sender, m_command_sender);
MODIFY(Mission_all_attack, m_full_war);
if (query_modified()){
set_modified();
@@ -633,7 +644,7 @@ void CMissionNotesDlg::OnCancel()
BOOL CMissionNotesDlg::OnInitDialog()
{
int i;
int i, box_index = 0, mission_command_persona_box_index = -1;
CComboBox *box;
CEdit *edit;
@@ -650,6 +661,7 @@ BOOL CMissionNotesDlg::OnInitDialog()
m_mission_desc_orig = m_mission_desc = convert_multiline_string(The_mission.mission_desc);
m_red_alert = (The_mission.flags & MISSION_FLAG_RED_ALERT) ? 1 : 0;
m_scramble = (The_mission.flags & MISSION_FLAG_SCRAMBLE) ? 1 : 0;
m_full_war = Mission_all_attack;
m_daisy_chained_docking = (The_mission.flags & MISSION_FLAG_ALLOW_DOCK_TREES) ? 1 : 0;
m_disallow_support = (The_mission.support_ships.max_support_ships == 0) ? 1 : 0;
m_no_promotion = (The_mission.flags & MISSION_FLAG_NO_PROMOTION) ? 1 : 0;
@@ -688,6 +700,25 @@ BOOL CMissionNotesDlg::OnInitDialog()
box->AddString(Soundtracks[i].name);
}
box = (CComboBox *) GetDlgItem(IDC_COMMAND_PERSONA);
for (i=0; i<Num_personas; i++){
if (Personas[i].flags & PERSONA_FLAG_COMMAND){
box->AddString(Personas[i].name);
box->SetItemData(box_index, i);
if (i == The_mission.command_persona)
mission_command_persona_box_index = box_index;
box_index++;
}
}
box = (CComboBox *) GetDlgItem(IDC_COMMAND_SENDER);
box->AddString(DEFAULT_COMMAND);
for (i=0; i<MAX_SHIPS; i++){
if (Ships[i].objnum >= 0)
if (Ship_info[Ships[i].ship_info_index].flags & SIF_HUGE_SHIP)
box->AddString(Ships[i].ship_name);
}
// squad info
if(strlen(The_mission.squad_name) > 0){
m_squad_name = _T(The_mission.squad_name);
@@ -699,9 +730,12 @@ BOOL CMissionNotesDlg::OnInitDialog()
m_type = The_mission.game_type;
m_ai_profile = (The_mission.ai_profile - Ai_profiles);
m_event_music = Current_soundtrack_num + 1;
m_substitute_event_music = The_mission.substitute_event_music_name;
m_full_war = Mission_all_attack;
m_command_persona = mission_command_persona_box_index;
m_command_sender = The_mission.command_sender;
// set up the game type checkboxes accoring to m_type
if ( m_type & MISSION_TYPE_SINGLE ){
+2
View File
@@ -211,6 +211,8 @@ public:
int m_ai_profile;
int m_event_music;
CString m_substitute_event_music;
int m_command_persona;
CString m_command_sender;
BOOL m_full_war;
BOOL m_red_alert;
BOOL m_scramble;
+662 -339
View File
File diff suppressed because it is too large. Load diff
+9 -2
View File
@@ -141,11 +141,15 @@
#include "ship/ship.h"
#include "object/waypoint.h"
#include <string>
#include <vector>
#define BACKUP_DEPTH 9
class CFred_mission_save {
private:
char *raw_ptr;
std::vector<std::string> fso_ver_comment;
int err;
CFILE *fp;
@@ -183,15 +187,18 @@ public:
int save_reinforcements();
void save_ai_goals(ai_goal *goalp, int ship);
int fout(char *format, ...);
int fout_ext(char *format, ...);
int fout_version(char *format, ...);
int fout_ext(char *pre_str, char *format, ...);
void parse_comments(int = 1);
CFred_mission_save() : err(0), raw_ptr(Mission_text_raw) { }
int save_mission_file(char *pathname);
int autosave_mission_file(char *pathname);
int save_campaign_file(char *pathname);
void fso_comment_push(char *ver);
void fso_comment_pop(bool pop_all = false);
// Goober5000
int fout_and_bypass(char *format, ...);
void bypass_comment(char *comment);
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

+23 -16
View File
@@ -1,6 +1,6 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by fred.rc
// Microsoft Developer Studio generated include file.
// Used by FRED.rc
//
#define IDC_SAVE_DEFAULT_PREFS 3
#define ID_DELETE_VARIABLE 3
@@ -101,21 +101,26 @@
#define IDD_CUSTOM_WING_NAMES 267
#define IDD_RESTRICT_PATHS 270
#define IDD_BACKGROUND_CHOOSER 272
#define IDB_DATA_02 274
#define IDB_DATA_03 275
#define IDB_DATA_04 276
#define IDB_DATA_05 277
#define IDB_DATA_06 278
#define IDB_DATA_07 279
#define IDB_DATA_08 280
#define IDB_DATA_09 281
#define IDB_DATA_01 285
#define IDB_DATA_10 286
#define IDB_DATA_11 287
#define IDB_DATA_12 288
#define IDB_DATA_15 289
#define IDB_DATA_14 290
#define IDB_DATA_13 291
#define IDB_DATA_15 296
#define IDB_DATA_00 297
#define IDB_DATA_20 300
#define IDB_DATA_25 301
#define IDB_DATA_30 302
#define IDB_DATA_35 303
#define IDB_DATA_40 304
#define IDB_DATA_45 305
#define IDB_DATA_50 306
#define IDB_DATA_55 307
#define IDB_DATA_60 308
#define IDB_DATA_65 309
#define IDB_DATA_70 310
#define IDB_DATA_75 311
#define IDB_DATA_80 312
#define IDB_DATA_85 313
#define IDB_DATA_90 314
#define IDB_DATA_95 315
#define IDC_SHIP_CLASS 1003
#define IDC_SHIP_WING 1004
#define IDC_SOUND_CLIP_NAME 1007
@@ -573,6 +578,8 @@
#define IDC_LIST3 1208
#define IDC_FILELIST 1208
#define IDC_YES_MESSAGE_LIST 1208
#define IDC_COMMAND_SENDER 1209
#define IDC_COMMAND_PERSONA 1210
#define IDC_FILTER_WAYPOINTS 1211
#define IDC_FILTER_STARTS 1212
#define IDC_FILTER_SHIPS 1213
@@ -1362,7 +1369,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 292
#define _APS_NEXT_RESOURCE_VALUE 316
#define _APS_NEXT_COMMAND_VALUE 33091
#define _APS_NEXT_CONTROL_VALUE 1595
#define _APS_NEXT_SYMED_VALUE 105
+80 -22
View File
@@ -820,6 +820,7 @@
#include "weapon/weapon.h"
#include "hud/hudartillery.h"
#include "iff_defs/iff_defs.h"
#include "mission/missionmessage.h"
#define TREE_NODE_INCREMENT 100
@@ -3139,6 +3140,7 @@ int sexp_tree::get_default_value(sexp_list_item *item, int op, int i)
case OPF_SUBSYSTEM:
case OPF_AWACS_SUBSYSTEM:
case OPF_ROTATING_SUBSYSTEM:
case OPF_SUBSYS_OR_GENERIC:
str = "<name of subsystem>";
break;
@@ -3191,6 +3193,10 @@ int sexp_tree::get_default_value(sexp_list_item *item, int op, int i)
str = "<any data>";
break;
case OPF_PERSONA:
str = "<persona name>";
break;
default:
str = "<new default required!>";
break;
@@ -3259,6 +3265,7 @@ int sexp_tree::query_default_argument_available(int op, int i)
case OPF_SKYBOX_MODEL_NAME:
case OPF_SHIP_OR_NONE:
case OPF_SUBSYSTEM_OR_NONE:
case OPF_SUBSYS_OR_GENERIC:
case OPF_BACKGROUND_BITMAP:
case OPF_SUN_BITMAP:
case OPF_NEBULA_STORM_TYPE:
@@ -3288,6 +3295,12 @@ int sexp_tree::query_default_argument_available(int op, int i)
return 0;
case OPF_PERSONA:
if (Num_personas)
return 1;
return 0;
case OPF_POINT:
case OPF_WAYPOINT_PATH:
if (Num_waypoint_lists)
@@ -4241,21 +4254,26 @@ void sexp_tree::OnLButtonUp(UINT nFlags, CPoint point)
}
const static UINT Numbered_data_bitmaps[] = {
IDB_DATA_01,
IDB_DATA_02,
IDB_DATA_03,
IDB_DATA_04,
IDB_DATA_00,
IDB_DATA_05,
IDB_DATA_06,
IDB_DATA_07,
IDB_DATA_08,
IDB_DATA_09,
IDB_DATA_10,
IDB_DATA_11,
IDB_DATA_12,
IDB_DATA_13,
IDB_DATA_14,
IDB_DATA_15,
IDB_DATA_20,
IDB_DATA_25,
IDB_DATA_30,
IDB_DATA_35,
IDB_DATA_40,
IDB_DATA_45,
IDB_DATA_50,
IDB_DATA_55,
IDB_DATA_60,
IDB_DATA_65,
IDB_DATA_70,
IDB_DATA_75,
IDB_DATA_80,
IDB_DATA_85,
IDB_DATA_90,
IDB_DATA_95
};
void sexp_tree::setup(CEdit *ptr)
@@ -4816,6 +4834,10 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
list = get_listing_opf_subsystem_or_none(parent_node, arg_index);
break;
case OPF_SUBSYS_OR_GENERIC:
list = get_listing_opf_subsys_or_generic(parent_node, arg_index);
break;
case OPF_JUMP_NODE_NAME:
list = get_listing_opf_jump_nodes();
break;
@@ -4856,6 +4878,10 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
list = get_listing_opf_turret_target_order();
break;
case OPF_PERSONA:
list = get_listing_opf_persona();
break;
default:
Int3(); // unknown OPF code
list = NULL;
@@ -4866,15 +4892,12 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
// every-time-argument... meaning if either w_arg or e_arg is >= 1, we can continue
w_arg = find_ancestral_argument_number(OP_WHEN_ARGUMENT, current_node);
e_arg = find_ancestral_argument_number(OP_EVERY_TIME_ARGUMENT, current_node);
if (w_arg < 1 && e_arg < 1 /* && the same for any future _ARGUMENT sexps */ )
{
if (w_arg < 1 && e_arg < 1 /* && the same for any future _ARGUMENT sexps */ ) {
return list;
}
// also skip if the list is empty, and *also* skip for OPF_NULL, because
// it takes no data (though it can take plenty of operators)
if (list == NULL || opf == OPF_NULL)
{
// also skip for OPF_NULL, because it takes no data (though it can take plenty of operators)
if (opf == OPF_NULL) {
return list;
}
@@ -4946,15 +4969,25 @@ int sexp_tree::find_ancestral_argument_number(int parent_op, int child_node)
*/
int sexp_tree::get_data_image(int node)
{
int count = get_sibling_place(node);
int count = get_sibling_place(node) + 1;
if(count < 0)
if (count <= 0) {
return BITMAP_DATA;
}
if(count > NUM_BITMAP_NUMBERED_DATA)
if (count % 5) {
return BITMAP_DATA;
}
return BITMAP_NUMBERED_DATA + count;
int idx = (count % 100) / 5;
int num = sizeof(Numbered_data_bitmaps)/sizeof(UINT);
if (idx > num) {
return BITMAP_DATA;
}
return BITMAP_NUMBERED_DATA + idx;
}
int sexp_tree::get_sibling_place(int node)
@@ -5551,6 +5584,20 @@ sexp_list_item *sexp_tree::get_listing_opf_message()
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_persona()
{
int i;
sexp_list_item head;
for (i = 0; i < Num_personas; i++) {
if (Personas[i].flags & PERSONA_FLAG_WINGMAN) {
head.add_data (Personas[i].name);
}
}
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_who_from()
{
object *ptr;
@@ -5889,6 +5936,17 @@ sexp_list_item *sexp_tree::get_listing_opf_subsystem_or_none(int parent_node, in
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_subsys_or_generic(int parent_node, int arg_index)
{
sexp_list_item head;
head.add_data(SEXP_ALL_ENGINES_STRING);
head.add_data(SEXP_ALL_TURRETS_STRING);
head.add_list(get_listing_opf_subsystem(parent_node, arg_index));
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_jump_nodes()
{
sexp_list_item head;
+2 -1
View File
@@ -55,7 +55,6 @@
#define BITMAP_BLUE_DOT BITMAP_ROOT
#define BITMAP_RED_DOT BITMAP_ROOT_DIRECTIVE
#define BITMAP_NUMBERED_DATA 9
#define NUM_BITMAP_NUMBERED_DATA 15
//Therefore NEXT DEFINE should be 9+12 or 21
@@ -247,7 +246,9 @@ public:
sexp_list_item *get_listing_opf_flexible_argument();
sexp_list_item *get_listing_opf_ship_or_none();
sexp_list_item *get_listing_opf_subsystem_or_none(int parent_node, int arg_index);
sexp_list_item *get_listing_opf_subsys_or_generic(int parent_node, int arg_index);
sexp_list_item *get_listing_opf_turret_target_order();
sexp_list_item *get_listing_opf_persona();
// ---------------------------------------------------------
int m_mode;
+28 -9
View File
@@ -132,6 +132,7 @@ BOOL ShipSpecialDamage::OnInitDialog()
m_special_exp_enabled = TRUE;
}
CDialog::OnInitDialog();
// maybe gray out lots of stuff
@@ -163,6 +164,25 @@ void ShipSpecialDamage::OnOK()
{
UpdateData(TRUE);
object *objp;
objp = GET_FIRST(&obj_used_list);
while (objp != END_OF_LIST(&obj_used_list)) {
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
if (objp->flags & OF_MARKED)
update_ship(objp->instance);
}
objp = GET_NEXT(objp);
}
CDialog::OnOK();
}
void ShipSpecialDamage::update_ship(int shipnum)
{
ship *shipp = &Ships[shipnum];
// TODO: Add extra validation here
if (m_special_exp_enabled) {
@@ -173,17 +193,17 @@ void ShipSpecialDamage::OnOK()
return;
}
if (Ships[m_ship_num].special_exp_index == -1) {
if (shipp->special_exp_index == -1) {
// get free sexp_variables
start = sexp_variable_allocate_block(Ships[m_ship_num].ship_name, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_EXP);
start = sexp_variable_allocate_block(shipp->ship_name, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_EXP);
if (start == -1) {
MessageBox("Unable to allocate storage, try deleting Sexp variables");
return;
} else {
Ships[m_ship_num].special_exp_index = start;
shipp->special_exp_index = start;
}
} else {
start = Ships[m_ship_num].special_exp_index;
start = shipp->special_exp_index;
}
// set to update
set_modified();
@@ -197,17 +217,16 @@ void ShipSpecialDamage::OnOK()
sprintf(Sexp_variables[start+SHOCK_SPEED].text, "%d", m_shock_speed);
} else {
if (Ships[m_ship_num].special_exp_index != -1) {
if (shipp->special_exp_index != -1) {
// set to update
set_modified();
// free block
sexp_variable_block_free(Ships[m_ship_num].ship_name, Ships[m_ship_num].special_exp_index, SEXP_VARIABLE_BLOCK |SEXP_VARIABLE_BLOCK_EXP);
sexp_variable_block_free(shipp->ship_name, Ships[m_ship_num].special_exp_index, SEXP_VARIABLE_BLOCK |SEXP_VARIABLE_BLOCK_EXP);
// set index to no exp block
Ships[m_ship_num].special_exp_index = -1;
shipp->special_exp_index = -1;
}
}
CDialog::OnOK();
}
+1
View File
@@ -24,6 +24,7 @@ class ShipSpecialDamage : public CDialog
// Construction
public:
ShipSpecialDamage(CWnd* pParent = NULL); // standard constructor
void update_ship(int ship);
// Dialog Data
//{{AFX_DATA(ShipSpecialDamage)
+1 -1
View File
@@ -124,7 +124,7 @@ BOOL starfield_editor::OnInitDialog()
CDialog::OnInitDialog();
theApp.init_window(&Starfield_wnd_data, this);
m_slider.SetRange(100, MAX_STARS);
m_slider.SetRange(0, MAX_STARS);
m_slider.SetPos(Num_stars);
sprintf(buf, "%d", Num_stars);
GetDlgItem(IDC_TOTAL)->SetWindowText(buf);
+15 -15
View File
@@ -1833,6 +1833,7 @@
#include "osapi/osregistry.h"
#include "parse/encrypt.h"
#include "parse/lua.h"
#include "parse/parselo.h"
#include "parse/scripting.h"
#include "parse/sexp.h"
#include "particle/particle.h"
@@ -1899,7 +1900,7 @@ extern int Om_tracker_flag; // needed for FS2OpenPXO config
// This function is defined in code\network\multiutil.cpp so will be linked from multiutil.obj
// it's required fro the -missioncrcs command line option - Kazan
void multi_spew_pxo_checksums(int max_files, char *outfile);
void multi_spew_table_checksums(int max_files, char *outfile);
void fs2netd_spew_table_checksums(char *outfile);
extern bool frame_rate_display;
@@ -4168,7 +4169,7 @@ void game_show_framerate()
#endif
if (Show_framerate) {
if (Show_framerate && HUD_draw) {
gr_set_color_fast(&HUD_color_debug);
if (frametotal != 0.0f)
@@ -4190,7 +4191,7 @@ void game_show_framerate()
// MONITOR_INC(BmpNew, bitmaps_new_this_frame);
#ifdef _WIN32
if (Cmdline_show_stats) {
if (Cmdline_show_stats && HUD_draw) {
char mem_buffer[50];
#ifndef NO_DIRECT3D
@@ -4394,7 +4395,7 @@ void game_show_framerate()
void game_show_eye_pos(vec3d *eye_pos, matrix* eye_orient)
{
if(!Cmdline_show_pos)
if ( !Cmdline_show_pos && HUD_draw )
return;
//Do stuff
@@ -4976,19 +4977,17 @@ void say_view_target()
if (!(Game_mode & GM_DEAD_DIED) && ((Game_mode & (GM_DEAD_BLEW_UP)) || ((Last_view_target != NULL) && (Last_view_target != view_target)))) {
if (view_target != Player_obj){
char *view_target_name = NULL;
char view_target_name[128] = "";
switch(Objects[Player_ai->target_objnum].type) {
case OBJ_SHIP:
view_target_name = Ships[Objects[Player_ai->target_objnum].instance].ship_name;
strcpy(view_target_name, Ships[Objects[Player_ai->target_objnum].instance].ship_name);
break;
case OBJ_WEAPON:
view_target_name = Weapon_info[Weapons[Objects[Player_ai->target_objnum].instance].weapon_info_index].name;
strcpy(view_target_name, Weapon_info[Weapons[Objects[Player_ai->target_objnum].instance].weapon_info_index].name);
Viewer_mode &= ~VM_OTHER_SHIP;
break;
case OBJ_JUMP_NODE: {
char jump_node_name[128];
strcpy(jump_node_name, XSTR( "jump node", 184));
view_target_name = jump_node_name;
strcpy(view_target_name, XSTR( "jump node", 184));
Viewer_mode &= ~VM_OTHER_SHIP;
break;
}
@@ -4998,6 +4997,7 @@ void say_view_target()
break;
}
end_string_at_first_hash_symbol(view_target_name);
if ( view_target_name ) {
HUD_fixed_printf(0.0f, XSTR( "Viewing %s%s\n", 185), (Viewer_mode & VM_OTHER_SHIP) ? XSTR( "from ", 186) : "", view_target_name);
Show_viewing_from_self = 1;
@@ -5575,7 +5575,7 @@ void game_render_frame( vec3d *eye_pos, matrix *eye_orient )
// maybe offset the HUD (jitter stuff) and measure the 2D displacement between the player's view and ship vector
dont_offset = ((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_OBSERVER));
HUD_set_offsets(Viewer_obj, !dont_offset, &eye_no_jitter);
// for multiplayer clients, call code in Shield.cpp to set up the Shield_hit array. Have to
// do this becaues of the disjointed nature of this system (in terms of setup and execution).
// must be done before ships are rendered
@@ -6423,7 +6423,7 @@ void game_frame(int paused)
popupdead_start();
}
}
}
}
DEBUG_GET_TIME( render3_time2 )
DEBUG_GET_TIME( render2_time1 )
@@ -7940,7 +7940,7 @@ void game_leave_state( int old_state, int new_state )
}
break;
case GS_STATE_MULTI_MISSION_SYNC:
case GS_STATE_MULTI_MISSION_SYNC:
common_select_close();
// if we're moving into the options menu we don't need to do anything else
@@ -9104,7 +9104,7 @@ int game_main(char *cmdline)
multi_spew_pxo_checksums(1024, "mission_crcs.txt");
if (Cmdline_spew_table_crcs) {
multi_spew_table_checksums(50, "table_crcs.txt");
fs2netd_spew_table_checksums("table_crcs.txt");
}
game_shutdown();
@@ -9113,7 +9113,7 @@ int game_main(char *cmdline)
if (Cmdline_spew_table_crcs) {
multi_spew_table_checksums(50, "table_crcs.txt");
fs2netd_spew_table_checksums("table_crcs.txt");
game_shutdown();
return 0;
}
+154 -6
View File
@@ -46,6 +46,8 @@
#include "graphics/font.h"
#include "globalincs/alphacolors.h"
#include "network/multi_options.h"
#include "cmdline/cmdline.h"
#include "cfile/cfilesystem.h"
#ifdef WIN32
//#include <windows.h>
@@ -603,6 +605,8 @@ void fs2netd_do_frame()
Logged_in = false;
PXO_SID = -1;
}
break;
}
default: {
@@ -765,6 +769,99 @@ int fs2netd_load_servers()
return 0;
}
static char Chk_mission_name[NAME_LENGTH+1];
static uint Chk_mission_crc = 0;
int fs2netd_check_mission_do()
{
if (timeout == -1) {
timeout = timer_get_fixed_seconds() + (15 * F1_0);
}
// if timeout passes then bail on stats failure
if ( timer_get_fixed_seconds() > timeout ) {
timeout = -1;
return 4;
}
int rescode = FS2NetD_CheckSingleMission(Chk_mission_name, Chk_mission_crc, do_full_packet);
do_full_packet = 0;
if (rescode) {
timeout = -1;
return rescode;
}
return 0;
}
bool fs2netd_check_mission(char *mission_name)
{
int rc = 0;
// don't bother with this if we aren't on FS2NetD
if ( !Om_tracker_flag ) {
return 0;
}
if ( !(Game_mode & GM_MULTIPLAYER) ) {
return 0;
}
if ( !Is_connected ) {
return 0;
}
strcpy(Chk_mission_name, mission_name);
cf_chksum_long(Chk_mission_name, &Chk_mission_crc);
do_full_packet = 1;
In_process = true;
if (Is_standalone) {
do { rc = fs2netd_check_mission_do(); } while (!rc);
} else {
rc = popup_till_condition(fs2netd_check_mission_do, XSTR("&Cancel", 779), XSTR("Sending stats...", -1));
}
In_process = false;
switch (rc) {
// operation canceled, or invalid
case 0:
return false;
// successful, but invalid
case 1:
return false;
// successful and valid
case 2:
return true;
// failed to send request packet
case 3:
if ( !Is_standalone ) {
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Server request failed!", -1));
}
return false;
// it timed out
case 4:
if ( !Is_standalone ) {
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Server request timed out!", -1));
}
return false;
}
return false;
}
void fs2netd_debrief_init()
{
if ( !(Game_mode & GM_MULTIPLAYER) ) {
@@ -780,12 +877,7 @@ void fs2netd_debrief_init()
}
uint CurrentMissionChsum;
bool mValidStatus = false;
cf_chksum_long(Netgame.mission_name, &CurrentMissionChsum);
mValidStatus = FS2NetD_CheckSingleMission(Netgame.mission_name, CurrentMissionChsum);
bool mValidStatus = fs2netd_check_mission(Netgame.mission_name);
if ( ((multi_num_players() > 1) || (Multi_num_players_at_start > 1)) && !game_hacked_data() && mValidStatus ) {
// verify that we are logged in before doing anything else
@@ -1326,12 +1418,15 @@ int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_cal
strncpy( new_plr.callsign, callsign, CALLSIGN_LEN );
memset( out_plr, 0, sizeof(player) );
timeout = timer_get_fixed_seconds() + (30 * F1_0);
}
int rc = FS2NetD_GetPlayerData(-2, callsign, &new_plr, false, (int)first_call );
// some sort of failure
if (rc > 0) {
timeout = -1;
return -2;
}
@@ -1339,6 +1434,12 @@ int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_cal
memcpy( out_plr, &new_plr, sizeof(player) );
}
// if timeout passes then bail on failure
if ( timer_get_fixed_seconds() > timeout ) {
timeout = -1;
return -2;
}
// we should only be returning -1 (processing) or 0 (got data successfully)
return rc;
}
@@ -1392,3 +1493,50 @@ void fs2netd_update_game_count(char *chan_name)
FS2NetD_GameCountUpdate(chan_name);
}
void fs2netd_spew_table_checksums(char *outfile)
{
char full_name[MAX_PATH_LEN];
int count, idx;
FILE *out = NULL;
char modname[128];
time_t my_time = 0;
if ( Table_valid_status.empty() ) {
return;
}
cf_create_default_path_string(full_name, sizeof(full_name) - 1, CF_TYPE_ROOT, outfile);
// open the outfile
out = fopen(full_name, "wt");
if (out == NULL) {
return;
}
memset( modname, 0, sizeof(modname) );
strcpy( modname, Cmdline_spew_table_crcs );
my_time = time(NULL);
fprintf(out, "-- Table CRCs generated on %s \n", ctime(&my_time));
fprintf(out, "LOCK TABLES `fstables` WRITE;\n");
fprintf(out, "INSERT INTO `fstables` VALUES ");
count = (int)Table_valid_status.size();
// do all the checksums
for (idx = 0; idx < count; idx++) {
if (idx == 0) {
fprintf(out, "('%s',%u,'%s')", Table_valid_status[idx].name, Table_valid_status[idx].crc32, modname);
} else {
fprintf(out, ",('%s',%u,'%s')", Table_valid_status[idx].name, Table_valid_status[idx].crc32, modname);
}
}
fprintf(out, ";\n");
fprintf(out, "UNLOCK TABLES;\n");
fclose(out);
}
+7 -5
View File
@@ -175,7 +175,7 @@
extern std::vector<crc_valid_status> Table_valid_status;
bool FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout)
int FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout)
{
int rc, buffer_size, buffer_offset;
bool my_packet = false;
@@ -197,7 +197,7 @@ bool FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout)
DONE_PACKET();
if ( FS2NetD_SendData(buffer, buffer_size) == -1 )
return false;
return 3;
Recieve_Only:
@@ -207,12 +207,12 @@ Recieve_Only:
if ( (rc = FS2NetD_GetData(buffer, sizeof(buffer))) != -1 ) {
if (rc < BASE_PACKET_SIZE)
return false;
return 0;
VRFY_PACKET2( PCKT_MCHECK_REPLY );
if (!my_packet)
return false;
return 0;
PXO_GET_DATA( status );
Assert( (status == 0) || (status == 1) );
@@ -220,9 +220,11 @@ Recieve_Only:
// anything beyond 'true' is considered a failure of some kind
if (status > 1)
status = 0;
return status+1;
}
return (status == 1);
return 0;
}
int FS2NetD_SendPlayerData(int SID, const char *player_name, const char *user, player *pl, int timeout)
+1 -1
View File
@@ -96,7 +96,7 @@ struct netgame_info;
int FS2NetD_SendPlayerData(int SID, const char* player_name, const char* user, player *pl, int timeout = 15);
int FS2NetD_GetPlayerData(int SID, const char* player_name, player *pl, bool CanCreate = false, int timeout = 15);
bool FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout = 15);
int FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout = 15);
int FS2NetD_CheckValidSID(int SID);
int FS2NetD_GetServerList(int timeout = 15);
void FS2NetD_Ping();
+8
View File
@@ -771,6 +771,14 @@ $Player Shield Recharge Scale: 4, 2, 1.5, 1.25, 1 \n\
;; factor applied to the speed at which the player's weapons recharge \n\
$Player Weapon Recharge Scale: 10, 4, 2.5, 2, 1.5 \n\
\n\
;; maximum number of turrets on one ship allowed to be attacking a \n\
;; target at a given time \n\
$Max Turret Target Ownage: 3, 4, 7, 12, 19 \n\
\n\
;; maximum number of turrets on one ship allowed to be attacking the \n\
;; player at a given time \n\
$Max Turret Player Ownage: 3, 4, 7, 12, 19 \n\
\n\
\n\
;; General AI-related flags. These were previously all lumped together \n\
;; under the New AI mission flag. \n\
+2
View File
@@ -1400,6 +1400,8 @@ void gr_init_res(int res, int mode, int max_w, int max_h)
gr_screen.clip_width = gr_screen.clip_width_unscaled = gr_screen.max_w;
gr_screen.clip_height = gr_screen.clip_height_unscaled = gr_screen.max_h;
gr_screen.clip_aspect = i2fl(gr_screen.clip_width) / i2fl(gr_screen.clip_height);
gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
if (gr_screen.custom_size >= 0) {
gr_unsize_screen_pos( &gr_screen.max_w_unscaled, &gr_screen.max_h_unscaled );
+2
View File
@@ -874,6 +874,8 @@ typedef struct screen {
int clip_left, clip_right, clip_top, clip_bottom;
// same as above except in 1024x768 or 640x480 dimensions
int clip_left_unscaled, clip_right_unscaled, clip_top_unscaled, clip_bottom_unscaled;
// center of clip area
float clip_center_x, clip_center_y;
int current_alphablend_mode; // See GR_ALPHABLEND defines above
int current_bitblt_mode; // See GR_BITBLT_MODE defines above
+8 -2
View File
@@ -1755,6 +1755,9 @@ void gr_opengl_set_clip(int x, int y, int w, int h, bool resize)
gr_screen.clip_aspect = i2fl(w) / i2fl(h);
gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
// just return early if we aren't actually going to need the scissor test
if ( (x == 0) && (y == 0) && (w == max_w) && (h == max_h) ) {
glDisable(GL_SCISSOR_TEST);
@@ -1783,6 +1786,9 @@ void gr_opengl_reset_clip()
gr_screen.clip_aspect = i2fl(gr_screen.clip_width) / i2fl(gr_screen.clip_height);
gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
glDisable(GL_SCISSOR_TEST);
}
@@ -4815,8 +4821,8 @@ void gr_opengl_init(int reinit)
if ( !Cmdline_nohtl && !Cmdline_novbo && Is_Extension_Enabled(OGL_ARB_VERTEX_BUFFER_OBJECT) )
VBO_ENABLED = 1;
if ( Is_Extension_Enabled(OGL_ARB_PIXEL_BUFFER_OBJECT) )
Use_PBOs = 1;
//if ( Is_Extension_Enabled(OGL_ARB_PIXEL_BUFFER_OBJECT) )
// Use_PBOs = 1;
// setup the best fog function found
// start with NV Radial Fog (GeForces only) -- needs t&l, will have to wait
+3 -32
View File
@@ -563,34 +563,10 @@ void gr_opengl_destroy_buffer(int idx)
#define DO_RENDER() { \
if ( (ibuffer != NULL) || (sbuffer != NULL) ) { \
if ( multiple_elements ) { \
start_tmp = 0; \
end_tmp = (GL_max_elements_indices - 1); \
count_tmp = (end_tmp - start_tmp + 1); \
\
if (ibuffer) { \
vglDrawRangeElements(GL_TRIANGLES, start_tmp, end_tmp, count_tmp, GL_UNSIGNED_INT, ibuffer + start_tmp); \
} else { \
vglDrawRangeElements(GL_TRIANGLES, start_tmp, end_tmp, count_tmp, GL_UNSIGNED_SHORT, sbuffer + start_tmp); \
} \
\
while (end_tmp < end) { \
start_tmp += (GL_max_elements_indices - 1); \
end_tmp = MIN( (start_tmp + GL_max_elements_indices - 1), end ); \
count_tmp = (end_tmp - start_tmp + 1); \
\
if (ibuffer) { \
vglDrawRangeElements(GL_TRIANGLES, start_tmp, end_tmp, count_tmp, GL_UNSIGNED_INT, ibuffer + start_tmp); \
} else { \
vglDrawRangeElements(GL_TRIANGLES, start_tmp, end_tmp, count_tmp, GL_UNSIGNED_SHORT, sbuffer + start_tmp); \
} \
} \
if (ibuffer) { \
vglDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_INT, ibuffer + start); \
} else { \
if (ibuffer) { \
vglDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_INT, ibuffer + start); \
} else { \
vglDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, sbuffer + start); \
} \
vglDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, sbuffer + start); \
} \
} else { \
glDrawArrays(GL_TRIANGLES, 0, vbp->n_verts); \
@@ -620,7 +596,6 @@ void gr_opengl_render_buffer(int start, int n_prim, ushort *sbuffer, uint *ibuff
int end = ((n_prim * 3) - 1);
int count = (end - start + 1); //(n_prim * 3);
int start_tmp, end_tmp, count_tmp, multiple_elements = 0;
int textured = (flags & TMAP_FLAG_TEXTURED);
@@ -631,10 +606,6 @@ void gr_opengl_render_buffer(int start, int n_prim, ushort *sbuffer, uint *ibuff
// disable all arbs before we start
opengl_switch_arb(-1, 0);
// see if we need to optimize glDrawRangeElements
if ( count > GL_max_elements_indices )
multiple_elements = 1;
if ( glIsEnabled(GL_CULL_FACE) )
glFrontFace(GL_CW);
+16 -9
View File
@@ -1986,7 +1986,7 @@ void HUD_render_2d(float frametime)
}
if ( show_gauge_flag ) {
hud_show_cmeasure_gague();
hud_show_cmeasure_gauge();
}
}
@@ -3498,7 +3498,7 @@ void HUD_set_offsets(object *viewer_obj, int wiggedy_wack, matrix *eye_orient)
flags = g3_rotate_vertex(&pt,&tmp);
g3_project_vertex(&pt);
g3_project_vertex(&pt);
gr_unsize_screen_posf( &pt.sx, &pt.sy );
HUD_offset_x -= 0.45f * (i2fl(gr_screen.clip_width_unscaled)*0.5f - pt.sx);
@@ -3538,8 +3538,8 @@ void HUD_get_nose_coordinates(int *x, int *y)
vertex v0;
vec3d p0;
int x_nose;
int y_nose;
float x_nose;
float y_nose;
vm_vec_scale_add(&p0, &Player_obj->pos, &Player_obj->orient.vec.fvec, 100.0f);
g3_rotate_vertex(&v0, &p0);
@@ -3547,9 +3547,16 @@ void HUD_get_nose_coordinates(int *x, int *y)
if (v0.codes == 0) {
g3_project_vertex(&v0);
if (! (v0.codes & PF_OVERFLOW)) {
x_nose = fl2i(v0.sx);
y_nose = fl2i(v0.sy);
if ( !(v0.codes & PF_OVERFLOW) ) {
x_nose = v0.sx;
y_nose = v0.sy;
} else {
// Means that the ship forward vector is not going through the frame buffer.
// We're assigning a high negative value so that the the bitmaps will be drawn offscreen so that
// we can give the illusion that the player is looking away from the slewable HUD reticle.
*x = -100000;
*y = -100000;
return;
}
} else {
// Means that the ship forward vector is not going through the frame buffer.
@@ -3560,8 +3567,8 @@ void HUD_get_nose_coordinates(int *x, int *y)
return;
}
*x = x_nose - SCREEN_CENTER_X;
*y = y_nose - SCREEN_CENTER_Y;
*x = fl2i(x_nose - gr_screen.clip_center_x);
*y = fl2i(y_nose - gr_screen.clip_center_y);
return;
}
+1 -3
View File
@@ -338,9 +338,6 @@
#include "graphics/2d.h"
#include "hud/hudparse.h"
#define SCREEN_CENTER_X ((gr_screen.clip_left + gr_screen.clip_right) / 2.0f)
#define SCREEN_CENTER_Y ((gr_screen.clip_top + gr_screen.clip_bottom) / 2.0f)
struct object;
typedef struct hud_anim {
@@ -358,6 +355,7 @@ typedef struct hud_frames {
int num_frames;
} hud_frames;
extern int HUD_draw;
extern int HUD_contrast;
+16 -7
View File
@@ -231,7 +231,7 @@ void ssm_level_init()
}
// start a subspace missile effect
void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *override)
void ssm_create(object *target, vec3d *start, int ssm_index, ssm_firing_info *override, int team)
{
ssm_strike *ssm;
matrix dir;
@@ -280,13 +280,17 @@ void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *ove
else {
// forward orientation
vec3d temp;
vm_vec_sub(&temp, target, start);
vm_vec_normalize(&temp);
vm_vec_sub(&temp, &target->pos, start);
vm_vec_normalize(&temp);
vm_vector_2_matrix(&dir, &temp, NULL, NULL);
// stuff info
ssm->sinfo.ssm_index = ssm_index;
ssm->sinfo.target = *target;
ssm->sinfo.target = target;
ssm->sinfo.ssm_team = team;
for(idx=0; idx<Ssm_info[ssm_index].count; idx++){
ssm->sinfo.delay_stamp[idx] = timestamp(200 + (int)frand_range(-199.0f, 1000.0f));
ssm_get_random_start_pos(&ssm->sinfo.start_pos[idx], start, &dir, ssm_index);
@@ -326,6 +330,7 @@ void ssm_process()
int idx, finished;
ssm_strike *moveup, *next_one;
ssm_info *si;
int weapon_objnum;
// process all strikes
moveup=GET_FIRST(&Ssm_used_list);
@@ -351,12 +356,16 @@ void ssm_process()
vec3d temp;
matrix orient;
vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
vm_vec_sub(&temp, &moveup->sinfo.target->pos, &moveup->sinfo.start_pos[idx]);
vm_vec_normalize(&temp);
vm_vector_2_matrix(&orient, &temp, NULL, NULL);
// fire the missile and flash the screen
weapon_create(&moveup->sinfo.start_pos[idx], &orient, si->weapon_info_index, -1, -1, 1);
weapon_objnum = weapon_create(&moveup->sinfo.start_pos[idx], &orient, si->weapon_info_index, -1, -1, 1);
Weapons[Objects[weapon_objnum].instance].team = moveup->sinfo.ssm_team;
Weapons[Objects[weapon_objnum].instance].homing_object = moveup->sinfo.target;
Weapons[Objects[weapon_objnum].instance].target_sig = moveup->sinfo.target->signature;
// this makes this particular missile done
moveup->done_flags[idx] = 1;
@@ -368,7 +377,7 @@ void ssm_process()
vec3d temp;
matrix orient;
vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
vm_vec_sub(&temp, &moveup->sinfo.target->pos, &moveup->sinfo.start_pos[idx]);
vm_vec_normalize(&temp);
vm_vector_2_matrix(&orient, &temp, NULL, NULL);
moveup->fireballs[idx] = fireball_create(&moveup->sinfo.start_pos[idx], FIREBALL_WARP_EFFECT, -1, si->warp_radius, 0, &vmd_zero_vector, si->warp_time, 0, &orient);
+6 -5
View File
@@ -82,11 +82,12 @@ typedef struct ssm_info {
// creation info for the strike (useful for multiplayer)
typedef struct ssm_firing_info {
int delay_stamp[MAX_SSM_COUNT]; // timestamps
vec3d start_pos[MAX_SSM_COUNT]; // start positions
int delay_stamp[MAX_SSM_COUNT]; // timestamps
vec3d start_pos[MAX_SSM_COUNT]; // start positions
int ssm_index; // index info ssm_info array
vec3d target; // target for the strike
int ssm_index; // index info ssm_info array
struct object* target; // target for the strike
int ssm_team; // team that fired the ssm.
} ssm_firing_info;
// the strike itself
@@ -119,7 +120,7 @@ void hud_artillery_update();
void hud_artillery_render();
// start a subspace missile effect
void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *override);
void ssm_create(object *target, vec3d *start, int ssm_index, ssm_firing_info *override, int team);
// Goober5000
extern int ssm_info_lookup(char *name);
+12 -12
View File
@@ -753,7 +753,7 @@ void draw_bounding_brackets(int x1, int y1, int x2, int y2, int w_correction, in
( y1 > gr_screen.clip_height && y2 > gr_screen.clip_height ) )
return;
// *** everything blow is taken care of with this unsize ***
// *** everything below is taken care of with this unsize ***
gr_unsize_screen_pos(&x1, &y1);
gr_unsize_screen_pos(&x2, &y2);
@@ -837,23 +837,24 @@ void draw_bounding_brackets(int x1, int y1, int x2, int y2, int w_correction, in
object* t_objp = &Objects[target_objnum];
char* tinfo_name = NULL;
char* tinfo_class = NULL;
char temp[NAME_LENGTH];
char buffer[NAME_LENGTH];
char empty='\0';
switch(t_objp->type)
{
case OBJ_SHIP:
if ( Cmdline_wcsaga &&
(Ships[t_objp->instance].wingnum >= 0) &&
(iff_x_attacks_y(Player_ship->team, Ships[t_objp->instance].team)) )
{
// if ( Cmdline_wcsaga &&
// (Ships[t_objp->instance].wingnum >= 0) &&
// (iff_x_attacks_y(Player_ship->team, Ships[t_objp->instance].team)) )
// Backslash - Instead of rely on command line, let's use a flag in Iff_defs.tbl
if ( (Iff_info[Ships[t_objp->instance].team].flags & IFFF_WING_NAME_HIDDEN) && (Ships[t_objp->instance].wingnum != -1) ) {
tinfo_name = &empty;
} else {
strcpy(temp, Ships[t_objp->instance].ship_name);
end_string_at_first_hash_symbol(temp);
tinfo_name = temp;
}
else
{
tinfo_name = Ships[t_objp->instance].ship_name;
}
tinfo_class = Ship_info[Ships[t_objp->instance].ship_info_index].name;
@@ -862,9 +863,8 @@ void draw_bounding_brackets(int x1, int y1, int x2, int y2, int w_correction, in
mission_parse_lookup_alt_index(Ships[t_objp->instance].alt_type_index, buffer);
} else {
strcpy(buffer, Ship_info[Ships[t_objp->instance].ship_info_index].name);
end_string_at_first_hash_symbol(buffer);
}
end_string_at_first_hash_symbol(buffer);
tinfo_class = buffer;
break;
+13 -23
View File
@@ -820,7 +820,6 @@ void hud_do_lock_indicator(float frametime)
object *tobjp = &Objects[Player_ai->target_objnum];
vec3d dir_to_target;
vm_vec_normalized_dir(&dir_to_target, &tobjp->pos, &Player_obj->pos);
float dot_target_orient = vm_vec_dot(&tobjp->orient.vec.fvec, &dir_to_target);
if ( !(wip->wi_flags & WIF_LOCKED_HOMING) ) {
hud_lock_reset();
@@ -1223,20 +1222,20 @@ void hud_calculate_lock_start_pos()
double delta_x;
double target_mag, target_x, target_y;
delta_x = Player->current_target_sx - SCREEN_CENTER_X;
delta_y = Player->current_target_sy - SCREEN_CENTER_Y;
delta_x = Player->current_target_sx - gr_screen.clip_center_x;
delta_y = Player->current_target_sy - gr_screen.clip_center_y;
if (!delta_x && !delta_y) {
Players[Player_num].lock_indicator_start_x = fl2i(SCREEN_CENTER_X + Lock_start_dist);
Players[Player_num].lock_indicator_start_y = fl2i(SCREEN_CENTER_Y);
if ( (delta_x == 0.0) && (delta_y == 0.0) ) {
Players[Player_num].lock_indicator_start_x = fl2i(gr_screen.clip_center_x + Lock_start_dist);
Players[Player_num].lock_indicator_start_y = fl2i(gr_screen.clip_center_y);
return;
}
hypotenuse = _hypot(delta_y, delta_x);
if (hypotenuse >= Lock_start_dist) {
Players[Player_num].lock_indicator_start_x = fl2i(SCREEN_CENTER_X);
Players[Player_num].lock_indicator_start_y = fl2i(SCREEN_CENTER_Y);
Players[Player_num].lock_indicator_start_x = fl2i(gr_screen.clip_center_x);
Players[Player_num].lock_indicator_start_y = fl2i(gr_screen.clip_center_y);
return;
}
@@ -1244,20 +1243,11 @@ void hud_calculate_lock_start_pos()
target_x = target_mag * (delta_x / hypotenuse);
target_y = target_mag * (delta_y / hypotenuse);
Players[Player_num].lock_indicator_start_x = fl2i(SCREEN_CENTER_X - target_x);
Players[Player_num].lock_indicator_start_y = fl2i(SCREEN_CENTER_Y - target_y);
Players[Player_num].lock_indicator_start_x = fl2i(gr_screen.clip_center_x - target_x);
Players[Player_num].lock_indicator_start_y = fl2i(gr_screen.clip_center_y - target_y);
if (Players[Player_num].lock_indicator_start_x > gr_screen.clip_right)
Players[Player_num].lock_indicator_start_x = gr_screen.clip_right;
if (Players[Player_num].lock_indicator_start_y > gr_screen.clip_bottom)
Players[Player_num].lock_indicator_start_y = gr_screen.clip_bottom;
if (Players[Player_num].lock_indicator_start_x < gr_screen.clip_left)
Players[Player_num].lock_indicator_start_x = gr_screen.clip_left;
if (Players[Player_num].lock_indicator_start_y < gr_screen.clip_top)
Players[Player_num].lock_indicator_start_y = gr_screen.clip_top;
CLAMP(Players[Player_num].lock_indicator_start_x, gr_screen.clip_left, gr_screen.clip_right);
CLAMP(Players[Player_num].lock_indicator_start_y, gr_screen.clip_top, gr_screen.clip_bottom);
}
// hud_stop_looped_locking_sounds() will terminate any hud related looping sounds that are playing
@@ -1421,8 +1411,8 @@ void hud_lock_determine_lock_point(vec3d *lock_world_pos_out)
if ( lock_local_pos.xyz.z > 0.0f ) {
// Get the location of our target in the "virtual frame" where the locking computation will be done
float w = 1.0f / lock_local_pos.xyz.z;
float sx = ((SCREEN_CENTER_X*2) + (lock_local_pos.xyz.x*(SCREEN_CENTER_X*2)*w))*0.5f;
float sy = ((SCREEN_CENTER_Y*2) - (lock_local_pos.xyz.y*(SCREEN_CENTER_Y*2)*w))*0.5f;
float sx = ((gr_screen.clip_center_x*2.0f) + (lock_local_pos.xyz.x*(gr_screen.clip_center_x*2.0f)*w))*0.5f;
float sy = ((gr_screen.clip_center_y*2.0f) - (lock_local_pos.xyz.y*(gr_screen.clip_center_y*2.0f)*w))*0.5f;
Player->current_target_sx = (int)sx;
Player->current_target_sy = (int)sy;
+1 -1
View File
@@ -552,7 +552,7 @@ void hud_shield_show(object *objp)
sip = &Ship_info[sp->ship_info_index];
// bool digitus_improbus = (fod_model != -2 && strstr(sp->ship_name, "Sathanas") != NULL);
if ( sip->shield_icon_index == 255 && !(sip->flags & SIF2_GENERATE_HUD_ICON) /*&& !digitus_improbus*/) {
if ( sip->shield_icon_index == 255 && !(sip->flags2 & SIF2_GENERATE_HUD_ICON) /*&& !digitus_improbus*/) {
return;
}
+1 -1
View File
@@ -1472,7 +1472,7 @@ void hud_squadmsg_send_to_all_fighters( int command, int player_num )
continue;
// send the command to the wing
if ( Wings[i].current_count > 1 ) {
if ( Wings[i].current_count > 0 ) {
if ( hud_squadmsg_send_wing_command(i, command, send_message, player_num) ) {
send_message = 0;
}
+31 -21
View File
@@ -1094,7 +1094,7 @@ typedef struct homing_beep_info
float precalced_interp; // a precalculated value used in a linear interpretation
} homing_beep_info;
homing_beep_info Homing_beep = { -1, 0, 150, 1000, 30.0f, 1500.0f };
homing_beep_info Homing_beep = { -1, 0, 150, 1000, 30.0f, 1500.0f, 1.729412f };
// Set at the start of a mission, used to decide how to draw the separation for the warning missile indicators
float Min_warning_missile_dist;
@@ -4449,7 +4449,7 @@ int hud_get_best_primary_bank(float *range)
//
// Called by the draw lead indicator code to predict where the enemy is going to be
//
void polish_predicted_target_pos(object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps)
void polish_predicted_target_pos(weapon_info *wip, object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps)
{
int iteration;
vec3d player_pos = Player_obj->pos;
@@ -4458,8 +4458,8 @@ void polish_predicted_target_pos(object *targetp, vec3d *enemy_pos, vec3d *predi
ship *shipp;
shipp = &Ships[Player_obj->instance];
Assert(shipp->weapons.current_primary_bank < shipp->weapons.num_primary_banks);
weapon_info *wip = &Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]];
// Assert(shipp->weapons.current_primary_bank < shipp->weapons.num_primary_banks);
// weapon_info *wip = &Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]];
float weapon_speed = wip->max_speed;
@@ -4598,12 +4598,9 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
{
int bank = swp->current_secondary_bank;
tmp = &Weapon_info[swp->secondary_bank_weapons[bank]];
if ( tmp->wi_flags & WIF_LOCKED_HOMING )
{
if ( !Player->target_in_lock_cone )
{
srange = -1.0f;
}
if ( !(tmp->wi_flags & WIF_HOMING) && !(tmp->wi_flags & WIF_LOCKED_HOMING && Player->target_in_lock_cone) ) {
//The secondary lead indicator is handled farther below if it is a non-locking type
srange = -1.0f;
}
}
@@ -4660,14 +4657,17 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
// if we've reached here, the lead target indicator will be displayed
Players[Player_num].lead_indicator_active = 1;
if(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY)
vm_vec_sub2(&target_moving_direction, &Player_obj->phys_info.vel);
// test if the target is moving at all
if ( vm_vec_mag_quick(&targetp->phys_info.vel) < 0.1f) // Find distance!
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
Players[Player_num].lead_target_pos = *target_world_pos;
else {
vm_vec_normalize(&target_moving_direction);
vm_vec_scale(&target_moving_direction,target_moved_dist);
vm_vec_add(&Players[Player_num].lead_target_pos, target_world_pos, &target_moving_direction );
polish_predicted_target_pos(targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
polish_predicted_target_pos(wip, targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
}
g3_rotate_vertex(&lead_target_vertex,&Players[Player_num].lead_target_pos);
@@ -4729,14 +4729,17 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
// if we've reached here, the lead target indicator will be displayed
Players[Player_num].lead_indicator_active = 1;
if(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY)
vm_vec_sub2(&target_moving_direction, &Player_obj->phys_info.vel);
// test if the target is moving at all
if ( vm_vec_mag_quick(&targetp->phys_info.vel) < 0.1f) // Find distance!
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
Players[Player_num].lead_target_pos = *target_world_pos;
else {
vm_vec_normalize(&target_moving_direction);
vm_vec_scale(&target_moving_direction,target_moved_dist);
vm_vec_add(&Players[Player_num].lead_target_pos, target_world_pos, &target_moving_direction );
polish_predicted_target_pos(targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
polish_predicted_target_pos(wip, targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
}
g3_rotate_vertex(&lead_target_vertex,&Players[Player_num].lead_target_pos);
@@ -4778,7 +4781,6 @@ void hud_show_lead_indicator_quick(vec3d *target_world_pos, object *targetp)
polymodel *pm;
ship_weapon *swp;
weapon_info *wip;
weapon_info *tmp=NULL;
float dist_to_target, time_to_target, target_moved_dist, prange;
int bank_to_fire, indicator_frame, frame_offset;
float sx, sy;
@@ -4860,14 +4862,17 @@ void hud_show_lead_indicator_quick(vec3d *target_world_pos, object *targetp)
// if we've reached here, the lead target indicator will be displayed
Players[Player_num].lead_indicator_active = 1;
if(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY)
vm_vec_sub2(&target_moving_direction, &Player_obj->phys_info.vel);
// test if the target is moving at all
if ( vm_vec_mag_quick(&targetp->phys_info.vel) < 0.1f) // Find distance!
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
Players[Player_num].lead_target_pos = *target_world_pos;
else {
vm_vec_normalize(&target_moving_direction);
vm_vec_scale(&target_moving_direction,target_moved_dist);
vm_vec_add(&Players[Player_num].lead_target_pos, target_world_pos, &target_moving_direction );
polish_predicted_target_pos(targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
polish_predicted_target_pos(wip, targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
vm_vec_add2(&Players[Player_num].lead_target_pos, rel_pos );
}
@@ -5079,7 +5084,7 @@ void hud_target_change_check()
//
// draws the offscreen target indicator
//
void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float distance)
void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float distance, int draw_solid)
{
char buf[32];
int w = 0, h = 0;
@@ -5327,8 +5332,13 @@ void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float dista
}
}
hud_tri(x3,y3,x2,y2,x1,y1);
hud_tri(x4,y4,x5,y5,x6,y6);
if (draw_solid) {
hud_tri(x3,y3,x2,y2,x1,y1);
hud_tri(x4,y4,x5,y5,x6,y6);
} else {
hud_tri_empty(x3,y3,x2,y2,x1,y1);
hud_tri_empty(x4,y4,x5,y5,x6,y6);
}
if (on_right || on_bottom){
gr_line(fl2i(x2),fl2i(y2),fl2i(x5),fl2i(y5));
} else if (on_left) {
@@ -5631,7 +5641,7 @@ void hud_maybe_flash_weapon(int index)
}
// render the coutermeasure HUD gauge
void hud_show_cmeasure_gague()
void hud_show_cmeasure_gauge()
{
if ( Cmeasure_gauge.first_frame == -1) {
Int3(); // failed to load coutermeasure gauge background
+6 -5
View File
@@ -329,6 +329,7 @@
struct ship;
struct ship_subsys;
struct object;
struct weapon_info;
#define INCREASING 0
#define DECREASING 1
@@ -344,7 +345,7 @@ struct object;
// structure and defines used for hotkey targeting
//WMC - bumped from 50 to 150; 10/24/2005
#define MAX_HOTKEY_TARGET_ITEMS 150 // maximum number of ships that can be targeted on *all* keys
#define SELECTION_SET 0x5000 // variable used for drawing brackets. The bracketinng code uses
#define SELECTION_SET 0x5000 // variable used for drawing brackets. The bracketing code uses
// TEAM_* values. I picked this value to be totally out of that
// range. Only used for drawing selection sets
#define MESSAGE_SENDER 0x5001 // variable used for drawing brackets around a message sender.
@@ -391,7 +392,7 @@ void hud_target_missile(object *source_obj, int next_flag);
void hud_target_next_list(int hostile=1, int next_flag=1);
int hud_target_closest_repair_ship(int goal_objnum=-1);
void hud_target_auto_target_next();
void hud_show_remote_detonate_missile();
void hud_show_remote_detonate_missile();
void hud_target_uninspected_object(int next_flag);
void hud_target_newest_ship();
@@ -423,9 +424,9 @@ void hud_show_weapons();
void hud_start_flash_weapon(int index);
void hud_show_auto_icons();
void hud_show_weapon_energy_gauge();
void hud_show_cmeasure_gague();
void hud_show_cmeasure_gauge();
void hud_show_brackets(object *targetp, vertex *projected_v);
void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float distance=0.0f);
void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float distance=0.0f, int draw_solid=1);
void hud_show_homing_missiles(void);
int hud_sensors_ok(ship *sp, int show_msg = 1);
@@ -454,6 +455,6 @@ void hud_tri_empty(float x1,float y1,float x2,float y2,float x3,float y3);
float hud_find_target_distance( object *targetee, object *targeter );
extern void polish_predicted_target_pos(object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps);
extern void polish_predicted_target_pos(weapon_info *wip, object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps);
#endif
+17 -12
View File
@@ -952,7 +952,8 @@ void hud_targetbox_show_extra_ship_info(ship *target_shipp, object *target_objp)
if ( not_training && (hud_gauge_active(HUD_TARGET_MONITOR_EXTRA_DATA)) && (Targetbox_show_extra_info) ) {
// Print out current orders if the targeted ship is friendly
// AL 12-26-97: only show orders and time to target for friendly ships
if ( (Player_ship->team == target_shipp->team) && !(ship_get_SIF(target_shipp) & SIF_NOT_FLYABLE) ) {
// Backslash: actually let's consult the IFF table. Maybe we want to show orders for certain teams, or hide orders for friendlies
if ( ((Player_ship->team == target_shipp->team) || ((Iff_info[target_shipp->team].flags & IFFF_ORDERS_SHOWN) && !(Iff_info[target_shipp->team].flags & IFFF_ORDERS_HIDDEN)) ) && !(ship_get_SIF(target_shipp) & SIF_NOT_FLYABLE) ) {
extra_data_shown=1;
if ( ship_return_orders(outstr, target_shipp) ) {
gr_force_fit_string(outstr, 255, 162);
@@ -984,6 +985,7 @@ void hud_targetbox_show_extra_ship_info(ship *target_shipp, object *target_objp)
if (dock_count == 1)
{
sprintf(outstr, XSTR("Docked: %s", 339), Ships[dock_get_first_docked_object(target_objp)->instance].ship_name);
end_string_at_first_hash_symbol(outstr);
}
// docked to multiple objects
else
@@ -1050,6 +1052,9 @@ void hud_render_target_jump_node(object *target_objp)
emp_hud_string(Targetbox_coords[gr_screen.res][TBOX_NAME][0], Targetbox_coords[gr_screen.res][TBOX_NAME][1], EG_TBOX_NAME, target_objp->jnp->get_name_ptr());
dist = vm_vec_dist_quick(&target_objp->pos, &Player_obj->pos);
if ( Hud_unit_multiplier > 0.0f ) { // use a different displayed distance scale
dist = dist * Hud_unit_multiplier;
}
// account for hud shaking
hx = fl2i(HUD_offset_x);
@@ -1218,15 +1223,15 @@ void hud_render_target_ship_info(object *target_objp)
target_shipp = &Ships[target_objp->instance];
target_sip = &Ship_info[target_shipp->ship_info_index];
if (Cmdline_wcsaga &&
(target_shipp->wingnum != -1) &&
(target_shipp->team != Player_ship->team))
{
// if (Cmdline_wcsaga &&
// (target_shipp->wingnum != -1) &&
// (target_shipp->team != Player_ship->team))
// Backslash - Instead of rely on command line, let's use a flag in Iff_defs.tbl
if ( (Iff_info[target_shipp->team].flags & IFFF_WING_NAME_HIDDEN) && (target_shipp->wingnum != -1) ) {
strcpy( outstr, "");
}
else
{
} else {
strcpy( outstr, target_shipp->ship_name );
end_string_at_first_hash_symbol(outstr);
}
if ( hud_gauge_maybe_flash(HUD_TARGET_MONITOR) == 1 ) {
@@ -1250,12 +1255,12 @@ void hud_render_target_ship_info(object *target_objp)
char temp_name[NAME_LENGTH+2] = "";
// if this ship has an alternate type name
if(target_shipp->alt_type_index >= 0){
if (target_shipp->alt_type_index >= 0) {
mission_parse_lookup_alt_index(target_shipp->alt_type_index, temp_name);
} else {
strcpy(temp_name, Ship_info[target_shipp->ship_info_index].name);
end_string_at_first_hash_symbol(temp_name);
strcpy(temp_name, Ship_info[target_shipp->ship_info_index].name);
}
end_string_at_first_hash_symbol(temp_name);
if (Lcl_gr) {
lcl_translate_targetbox_name(temp_name);
@@ -1421,7 +1426,7 @@ void hud_blit_target_integrity(int disabled,int force_obj_num)
}
}
// determine if the subsystem is in line-of sight, without taking into accout whether the player ship is
// determine if the subsystem is in line-of sight, without taking into account whether the player ship is
// facing the subsystem
int hud_targetbox_subsystem_in_view(object *target_objp, int *sx, int *sy)
{
+6
View File
@@ -268,6 +268,12 @@ void iff_init()
iff->flags |= IFFF_SUPPORT_ALLOWED;
else if (!stricmp(NOX("exempt from all teams at war"), flag_strings[i]))
iff->flags |= IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR;
else if (!stricmp(NOX("orders hidden"), flag_strings[i]))
iff->flags |= IFFF_ORDERS_HIDDEN;
else if (!stricmp(NOX("orders shown"), flag_strings[i]))
iff->flags |= IFFF_ORDERS_SHOWN;
else if (!stricmp(NOX("wing name hidden"), flag_strings[i]))
iff->flags |= IFFF_WING_NAME_HIDDEN;
else
Warning(LOCATION, "Bogus string in iff flags: %s\n", flag_strings[i]);
}
+4 -1
View File
@@ -55,7 +55,10 @@
// iff flags
#define IFFF_SUPPORT_ALLOWED (1 << 0) // this IFF can call for support
#define IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR (1 << 1) // self-explanatory
#define MAX_IFF_FLAGS 2
#define IFFF_ORDERS_HIDDEN (1 << 2) // the HUD will not show a targeted ship's orders
#define IFFF_ORDERS_SHOWN (1 << 3) // the HUD will show a targeted ship's orders (friendly has by default)
#define IFFF_WING_NAME_HIDDEN (1 << 4) // the HUD will not show a targeted ship's name if it is in a wing
#define MAX_IFF_FLAGS 5
// Goober5000
typedef struct iff_info {
+6 -2
View File
@@ -661,9 +661,13 @@ float key_down_timef(uint scancode)
uint time_down, time;
uint delta_time;
if ( !key_inited ) return 0.0f;
if ( !key_inited ) {
return 0.0f;
}
if ((scancode<0)|| (scancode>=NUM_KEYS)) return 0.0f;
if (scancode >= NUM_KEYS) {
return 0.0f;
}
ENTER_CRITICAL_SECTION( key_lock );
+45 -32
View File
@@ -2354,7 +2354,49 @@ int button_function_critical(int n, net_player *p = NULL)
return 0;
}
switch (n) {
switch (n) {
// cycle to next primary weapon
case CYCLE_NEXT_PRIMARY:
if (at_self) {
control_used(CYCLE_NEXT_PRIMARY);
}
hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
if (ship_select_next_primary(Player_obj, CYCLE_PRIMARY_NEXT)) {
ship* shipp = &Ships[objp->instance];
if ( timestamp_elapsed(shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank]) ) {
shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250); // 1/4 second delay until can fire
}
// multiplayer server should maintain bank/link status here
if ( (Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) ) {
Assert(npl != NULL);
multi_server_update_player_weapons(npl,shipp);
}
}
break;
// cycle to previous primary weapon
case CYCLE_PREV_PRIMARY:
if (at_self) {
control_used(CYCLE_PREV_PRIMARY);
}
hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
if (ship_select_next_primary(objp, CYCLE_PRIMARY_PREV)) {
ship* shipp = &Ships[objp->instance];
if ( timestamp_elapsed(shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank]) ) {
shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250); // 1/4 second delay until can fire
}
// multiplayer server should maintain bank/link status here
if ( (Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) ) {
Assert(npl != NULL);
multi_server_update_player_weapons(npl,shipp);
}
}
break;
// cycle to next secondary weapon
case CYCLE_SECONDARY:
if(at_self)
@@ -2821,41 +2863,12 @@ int button_function(int n)
switch (n) {
// cycle to next primary weapon
case CYCLE_NEXT_PRIMARY:
// bogus?
if((Player_obj == NULL) || (Player_ship == NULL)){
break;
}
hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
if (ship_select_next_primary(Player_obj, CYCLE_PRIMARY_NEXT)) {
ship* shipp = Player_ship;
shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250); // 1/4 second delay until can fire
// multiplayer server should maintain bank/link status here
// if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
// Assert(npl != NULL);
// multi_server_update_player_weapons(npl,shipp);
// }
}
return button_function_critical(CYCLE_NEXT_PRIMARY);
break;
// cycle to previous primary weapon
case CYCLE_PREV_PRIMARY:
// bogus?
if((Player_obj == NULL) || (Player_ship == NULL)){
break;
}
hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
if (ship_select_next_primary(Player_obj, CYCLE_PRIMARY_PREV)) {
ship* shipp = Player_ship;
shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250); // 1/4 second delay until can fire
// multiplayer server should maintain bank/link status here
// if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
// Assert(npl != NULL);
// multi_server_update_player_weapons(npl,shipp);
// }
}
return button_function_critical(CYCLE_PREV_PRIMARY);
break;
// cycle to next secondary weapon
+1 -1
View File
@@ -126,7 +126,7 @@ public:
//Setting
void set_alphacolor(int r, int g, int b, int alpha);
void set_model(char *model_name, bool show_polys=false);
void show(bool show){if(show){m_flags&=~JN_HIDE;}else{m_flags|=JN_HIDE;}}
void show(bool enabled){if(enabled){m_flags&=~JN_HIDE;}else{m_flags|=JN_HIDE;}}
//Rendering
void render(vec3d *pos, vec3d *view_pos = NULL);
+2
View File
@@ -233,6 +233,7 @@
#include "globalincs/alphacolors.h"
#include "weapon/beam.h"
#include "iff_defs/iff_defs.h"
#include "parse/parselo.h"
static int Key_sets[MAX_KEYED_TARGETS] = {
@@ -1464,6 +1465,7 @@ void mission_hotkey_do_frame(float frametime)
// draw ship/wing name
strcpy(buf, Hotkey_lines[line].label);
end_string_at_first_hash_symbol(buf);
if (Hotkey_lines[line].type == HOTKEY_LINE_SUBSHIP) {
// indent
gr_force_fit_string(buf, 255, Hotkey_list_coords[gr_screen.res][0] + Hotkey_list_coords[gr_screen.res][2] - (Hotkey_ship_x[gr_screen.res]+20));
+1 -1
View File
@@ -299,7 +299,7 @@ int mission_load(char *filename_ext)
mprintf(("MISSION LOAD: '%s'\n", filename_ext));
strncpy(filename, filename_ext, 127);
ext = strchr(filename, '.');
ext = strrchr(filename, '.');
if (ext) {
mprintf(( "Hmmm... Extension passed to mission_load...\n" ));
*ext = 0; // remove any extension!
+1
View File
@@ -1060,6 +1060,7 @@ void mission_log_scrollback(int line, int list_x, int list_y, int list_w, int li
else
gr_force_fit_string(buf, 256, list_w - seg->x);
end_string_at_first_hash_symbol(buf);
gr_string(list_x + seg->x, list_y + y, buf);
// possibly "print" some symbols for interesting log entries
+25 -17
View File
@@ -796,7 +796,7 @@ char *Persona_type_names[MAX_PERSONA_TYPES] =
//XSTR:ON
};
int Command_persona;
int Default_command_persona;
///////////////////////////////////////////////////////////////////
// used to distort incoming messages when comms are damaged
@@ -870,10 +870,10 @@ void persona_parse()
Personas[Num_personas].flags |= (1<<i);
// save the Terran Command persona in a global
// save the Command persona in a global
if ( Personas[Num_personas].flags & PERSONA_FLAG_COMMAND ) {
// Assert ( Command_persona == -1 );
Command_persona = Num_personas;
if (Default_command_persona < 0)
Default_command_persona = Num_personas;
}
break;
@@ -1091,7 +1091,7 @@ void messages_init()
static int table_read = 0;
if ( !table_read ) {
Command_persona = -1;
Default_command_persona = -1;
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "messages.tbl", rval));
@@ -1604,7 +1604,7 @@ void message_play_anim( message_q *q )
// attached to it. Deal with munging the name
// support ships use a wingman head.
// terran command uses it's own set of heads.
// terran command uses its own set of heads.
int subhead_selected = FALSE;
if ( (q->message_num < Num_builtin_messages) || !(_strnicmp(HEAD_PREFIX_STRING, ani_name, strlen(HEAD_PREFIX_STRING)-1)) ) {
persona_index = m->persona_index;
@@ -1612,7 +1612,7 @@ void message_play_anim( message_q *q )
// if this ani should be converted to a terran command, set the persona to the command persona
// so the correct head plays.
if ( q->flags & MQF_CONVERT_TO_COMMAND ) {
persona_index = Command_persona;
persona_index = The_mission.command_persona;
strcpy( ani_name, COMMAND_HEAD_PREFIX );
}
@@ -1990,7 +1990,9 @@ void message_queue_process()
// if this is a ship do we use name or alt name?
if ( Message_shipnum != -1 && (Ships[Message_shipnum].flags2 & SF2_USE_ALT_NAME_AS_CALLSIGN) ) {
mission_parse_lookup_alt_index(Ships[Message_shipnum].alt_type_index, who_from);
}
}
end_string_at_first_hash_symbol(who_from);
HUD_sourced_printf( q->source, NOX("%s: %s"), who_from, buf );
@@ -2071,7 +2073,7 @@ void message_queue_message( int message_num, int priority, int timing, char *who
// to this message, then set a bit to tell the wave/anim playing code to play the command version
// of the wave and head
MessageQ[i].flags = 0;
if ( !stricmp(who_from, TERRAN_COMMAND) && (m_persona != -1) && (Personas[m_persona].flags & PERSONA_FLAG_WINGMAN) ) {
if ( !stricmp(who_from, The_mission.command_sender) && (m_persona != -1) && (Personas[m_persona].flags & PERSONA_FLAG_WINGMAN) ) {
MessageQ[i].flags |= MQF_CONVERT_TO_COMMAND;
MessageQ[i].source = HUD_SOURCE_TERRAN_CMD;
}
@@ -2239,7 +2241,7 @@ void message_send_unique_to_player( char *id, void *data, int m_source, int prio
// if the ship is NULL and special_who is not NULL, then this is from special_who
// otherwise, message is from ship.
if ( m_source == MESSAGE_SOURCE_COMMAND ) {
who_from = TERRAN_COMMAND;
who_from = The_mission.command_sender;
source = HUD_SOURCE_TERRAN_CMD;
} else if ( m_source == MESSAGE_SOURCE_SPECIAL ) {
who_from = (char *)data;
@@ -2260,7 +2262,7 @@ void message_send_unique_to_player( char *id, void *data, int m_source, int prio
// if the ship_index is -1, then make the message come from Terran command
if ( ship_index == -1 ) {
who_from = TERRAN_COMMAND;
who_from = The_mission.command_sender;
source = HUD_SOURCE_TERRAN_CMD;
} else {
who_from = Ships[ship_index].ship_name;
@@ -2335,7 +2337,7 @@ void message_send_builtin_to_player( int type, ship *shipp, int priority, int ti
// be sure that this ship can actually send a message!!! (i.e. not-not-flyable -- get it!)
Assert( !(Ship_info[shipp->ship_info_index].flags & SIF_NOT_FLYABLE) ); // get allender or alan
} else {
persona_index = Command_persona; // use the terran command persona
persona_index = The_mission.command_persona; // use the terran command persona
}
// try to find a builtin message with the given type for the given persona
@@ -2359,17 +2361,23 @@ void message_send_builtin_to_player( int type, ship *shipp, int priority, int ti
}
// get who this message is from -- kind of a hack since we assume Terran Command in the
// absense of a ship. This will be fixed later
// absence of a ship. This will be fixed later
if ( shipp ) {
source = HUD_team_get_source( shipp->team );
who_from = shipp->ship_name;
source = HUD_team_get_source( shipp->team );
} else {
source = HUD_SOURCE_TERRAN_CMD;
who_from = TERRAN_COMMAND;
who_from = The_mission.command_sender;
// Goober5000 - if Command is a ship that is present, change the source accordingly
int shipnum = ship_name_lookup(who_from);
if (shipnum >= 0)
source = HUD_team_get_source( Ships[shipnum].team );
else
source = HUD_SOURCE_TERRAN_CMD;
}
// maybe change the who from here for special rearm cases (always seems like that is the case :-) )
if ( !stricmp(who_from, TERRAN_COMMAND) && (type == MESSAGE_REARM_ON_WAY) ){
if ( !stricmp(who_from, The_mission.command_sender) && (type == MESSAGE_REARM_ON_WAY) ){
who_from = SUPPORT_NAME;
}
+3 -2
View File
@@ -268,7 +268,7 @@
struct ship;
#define MAX_MISSION_MESSAGES 500
#define MAX_MISSION_MESSAGES 1000
//Bumped to 500 from 300 06/15/2004 -C
// keep seperate lists of AVI's and wav files. I suspect that many messages will have
@@ -306,7 +306,7 @@ extern message_extra Message_waves[MAX_MESSAGE_WAVES];
#define MESSAGE_SOURCE_SPECIAL 4
// define used for sender of a message when you want it to be Terran Command
#define TERRAN_COMMAND "Command"
#define DEFAULT_COMMAND "Command"
// defines for message id's used in FreeSpace code. Callers to message_send_to_player() should
// probably use these defines.
@@ -408,6 +408,7 @@ typedef struct persona_s {
extern Persona *Personas;
extern int Num_personas;
extern int Default_command_persona;
// function to parse a message from either messages.tbl or the mission file. Both files have the
// exact same format, so this function just gets reused in both instances.
+84 -15
View File
@@ -1701,7 +1701,7 @@ void parse_mission_info(mission *pm, bool basic = false)
//
// NOTE: this can be dangerous so be sure that any get_mission_info() call (defaults to basic info) will
// only reference data parsed before this point!! (like current FRED2 and game code does)
if (basic == true)
if (basic)
return;
@@ -1811,6 +1811,7 @@ void parse_mission_info(mission *pm, bool basic = false)
}
}
// wing stuff by Goober5000 ------------------------------------------
// the wing name arrays are initialized in ship_level_init
if (optional_string("$Starting wing names:"))
@@ -1835,6 +1836,7 @@ void parse_mission_info(mission *pm, bool basic = false)
}
// end of wing stuff -------------------------------------------------
// set up the Num_teams variable accoriding to the game_type variable'
Num_teams = 1; // assume 1
@@ -3811,10 +3813,28 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
if (optional_string("+Group:"))
stuff_int(&p_objp->group);
if (optional_string("+Score:"))
stuff_int(&p_objp->score);
else
bool table_score = false;
if (optional_string("+Use Table Score:")) {
table_score = true;
}
if (optional_string("+Score:")) {
if (!table_score) {
stuff_int(&p_objp->score);
}
// throw away the value the mission file has and use the table value.
else {
int temp_score;
stuff_int(&temp_score);
}
}
else {
table_score = true;
}
if (table_score) {
p_objp->score = Ship_info[p_objp->ship_class].score;
}
// parse the persona index if present
p_objp->persona_index = -1;
@@ -4111,8 +4131,8 @@ void swap_parse_object(p_object *p_obj, int new_ship_class)
Assert (p_obj->ship_max_hull_strength > 0);
Assert (old_ship_info->max_hull_strength > 0);
float hp_multiplier = p_obj->ship_max_hull_strength / i2fl(old_ship_info->max_hull_strength);
p_obj->ship_max_hull_strength = fl2i(new_ship_info->max_hull_strength * hp_multiplier);
float hp_multiplier = p_obj->ship_max_hull_strength / old_ship_info->max_hull_strength;
p_obj->ship_max_hull_strength = new_ship_info->max_hull_strength * hp_multiplier;
// Shields
@@ -4383,6 +4403,8 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, int force, int spec
if (p_objp->wingnum != wingnum)
continue;
Assert( (p_objp->pos_in_wing >= 0) && (p_objp->pos_in_wing < MAX_SHIPS_PER_WING) );
// when ingame joining, we need to create a specific ship out of the list of ships for a
// wing. specific_instance is a 0 based integer which specified which ship in the wing
// to create. So, only create the ship we actually need to.
@@ -4434,16 +4456,17 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, int force, int spec
aip->ai_flags |= AIF_NO_DYNAMIC;
// update housekeeping variables
wingp->ship_index[wingp->current_count] = Objects[objnum].instance;
// since wing order and object order aren't necessarily the same thing
// be sure to reset the special ship to the correct ship_index[] offset
if (p_objp->special_ship) {
wingp->special_ship = wingp->current_count;
// NOTE: for the initial wing setup we use actual position to get around
// object order isses, but ships in all following waves just get
// tacked onto the end of the list
if (wingp->current_wave == 1) {
wingp->ship_index[p_objp->pos_in_wing] = Objects[objnum].instance;
} else {
wingp->ship_index[wingp->current_count] = Objects[objnum].instance;
}
// set up wingman status index
hud_wingman_status_set_index(wingp->ship_index[wingp->current_count]);
hud_wingman_status_set_index(Objects[objnum].instance);
p_objp->wing_status_wing_index = Ships[Objects[objnum].instance].wing_status_wing_index;
p_objp->wing_status_wing_pos = Ships[Objects[objnum].instance].wing_status_wing_pos;
@@ -4497,6 +4520,24 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, int force, int spec
// we should always have enough ships in the list!!!
Assert (num_to_create == 0);
// wing current_count needs to match the end of the ship_index[] list, but there
// is a very off chance it could have holes in it, so make sure to compact the list
for (i = 0; i < (MAX_SHIPS_PER_WING-1); i++) {
if (wingp->ship_index[i] == -1) {
j = i;
while ( j < (MAX_SHIPS_PER_WING-1) ) {
wingp->ship_index[j] = wingp->ship_index[j+1];
// update "special" ship too
if (wingp->special_ship == j+1) {
wingp->special_ship--;
}
j++;
}
}
}
// possibly play some event driven music here. Send a network packet indicating the wing was
// created. Only do this stuff if actually in the mission.
if ( (objnum != -1) && (Game_mode & GM_IN_MISSION) ) { // if true, we have created at least one new ship.
@@ -4861,7 +4902,6 @@ void parse_wing(mission *pm)
p_objp->wingnum = wingnum;
p_objp->pos_in_wing = i;
p_objp->special_ship = (i == wingp->special_ship) ? true : false;
assigned++;
}
@@ -5237,6 +5277,35 @@ void parse_messages(mission *pm, int flags)
{
required_string("#Messages");
// command stuff by Goober5000 ---------------------------------------
strcpy(pm->command_sender, DEFAULT_COMMAND);
if (optional_string("$Command Sender:"))
{
char temp[NAME_LENGTH];
stuff_string(temp, F_NAME, NAME_LENGTH);
if (*temp == '#')
strcpy(pm->command_sender, &temp[1]);
else
strcpy(pm->command_sender, temp);
}
pm->command_persona = Default_command_persona;
if (optional_string("$Command Persona:"))
{
int idx;
char temp[NAME_LENGTH];
stuff_string(temp, F_NAME, NAME_LENGTH);
idx = message_persona_name_lookup(temp);
if (idx >= 0)
pm->command_persona = idx;
else
Warning(LOCATION, "Supplied Command Persona is invalid! Defaulting to %s.", Personas[Default_command_persona].name);
}
// end of command stuff ----------------------------------------------
mprintf(("Starting mission message count : %d\n", Num_message_waves));
// the message_parse function can be found in MissionMessage.h. The format in the
@@ -6062,7 +6131,7 @@ int get_mission_info(char *filename, mission *mission_p, bool basic)
{
char real_fname[MAX_FILENAME_LEN];
strcpy(real_fname, filename);
char *p = strchr(real_fname, '.');
char *p = strrchr(real_fname, '.');
if (p) *p = 0; // remove any extension
strcat(real_fname, FS_MISSION_FILE_EXT); // append mission extension
+5 -2
View File
@@ -692,6 +692,10 @@ typedef struct mission {
int contrail_threshold;
int ambient_light_level;
// Goober5000
int command_persona;
char command_sender[NAME_LENGTH];
// Goober5000
char event_music_name[NAME_LENGTH];
char briefing_music_name[NAME_LENGTH];
@@ -738,7 +742,7 @@ extern char Mission_filename[80]; // filename of mission in The_mission (Fred o
#define MAX_GOAL_TYPE_NAMES 3
// alternate ship type names
#define MAX_ALT_TYPE_NAMES 25
#define MAX_ALT_TYPE_NAMES 100
extern char Mission_alt_types[MAX_ALT_TYPE_NAMES][NAME_LENGTH];
extern int Mission_alt_type_count;
@@ -862,7 +866,6 @@ typedef struct p_object {
int wingnum; // set to -1 if not in a wing -- Wing array index otherwise
int pos_in_wing; // Goober5000 - needed for FRED with the new way things work
bool special_ship; // what "$Special Ship:" actually points to in the wing array (for later cleanup)
int flags; // mission savable flags
int flags2; // Goober5000
+1
View File
@@ -765,6 +765,7 @@ typedef struct submodel_instance_info {
#define MSS_FLAG_CARRY_NO_DAMAGE (1 << 9) // WMC
#define MSS_FLAG_USE_MULTIPLE_GUNS (1 << 10) // WMC
#define MSS_FLAG_FIRE_ON_NORMAL (1 << 11) // forces a turret to fire down its normal vecs
#define MSS_FLAG_TURRET_HULL_CHECK (1 << 12) // makes the turret check to see if it's going to shoot through it's own hull before fireing - Bobboau
// definition of stepped rotation struct
typedef struct stepped_rotation {
+5 -5
View File
@@ -156,7 +156,7 @@ triggered_rotation::~triggered_rotation()
{
}
void triggered_rotation::add_queue(queued_animation *the_queue, int direction)
void triggered_rotation::add_queue(queued_animation *the_queue, int dir)
{
int i;
queued_animation new_queue;
@@ -164,7 +164,7 @@ void triggered_rotation::add_queue(queued_animation *the_queue, int direction)
memcpy( &new_queue, the_queue, sizeof(queued_animation) );
if (direction == -1) {
if (dir == -1) {
new_queue.start = new_queue.reverse_start;
vm_vec_negate( &new_queue.angle );
}
@@ -208,9 +208,9 @@ void triggered_rotation::add_queue(queued_animation *the_queue, int direction)
if (new_queue.instance == instance) {
// same animation is playing that we are about to think about playing some point in the future
if ( (this->direction.xyz.x * rot_vel.xyz.x) == new_queue.vel.xyz.x &&
(this->direction.xyz.y * rot_vel.xyz.y) == new_queue.vel.xyz.y &&
(this->direction.xyz.z * rot_vel.xyz.z) == new_queue.vel.xyz.z)
if ( (direction.xyz.x * rot_vel.xyz.x) == new_queue.vel.xyz.x &&
(direction.xyz.y * rot_vel.xyz.y) == new_queue.vel.xyz.y &&
(direction.xyz.z * rot_vel.xyz.z) == new_queue.vel.xyz.z)
{
// they're going in opposite directions, one of them is a reversal!
// so this means thata there is some sort of delay that's getting fubared becase of other queue items getting removed due to reversal
+1 -1
View File
@@ -113,7 +113,7 @@ class triggered_rotation
void start(queued_animation *q);
void set_to_end(queued_animation *q);
void add_queue(queued_animation *new_queue, int direction);
void add_queue(queued_animation *new_queue, int dir);
void process_queue();
vec3d current_ang;
+35 -18
View File
@@ -4718,9 +4718,7 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
vec3d pnt = gpt->pnt;
vec3d norm = gpt->norm;
if (bank->submodel_parent > 0) { //this is were it rotates for the submodel parent-Bobboau
matrix m;
if (bank->submodel_parent > 0) { //this is where it rotates for the submodel parent-Bobboau
if (pm->submodel[bank->submodel_parent].blown_off)
continue;
@@ -4740,14 +4738,15 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
matrix inv_orientation;
vm_copy_transpose_matrix(&inv_orientation, &pm->submodel[bank->submodel_parent].orientation);
vm_matrix_x_matrix(&m, &rotation_matrix, &inv_orientation);
matrix submodel_matrix;
vm_matrix_x_matrix(&submodel_matrix, &rotation_matrix, &inv_orientation);
vec3d offset = pm->submodel[bank->submodel_parent].offset;
vm_vec_sub(&pnt, &pnt, &offset);
vec3d p = pnt;
vec3d n = norm;
vm_vec_rotate(&pnt, &p, &m);
vm_vec_rotate(&norm, &n, &m);
vm_vec_rotate(&pnt, &p, &submodel_matrix);
vm_vec_rotate(&norm, &n, &submodel_matrix);
vm_vec_add2(&pnt, &offset);
}
@@ -4884,7 +4883,7 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
vm_vec_zero(&controle_rotval);
cull = gr_set_cull(0);
cull = gr_set_cull(0);
// Draw the thruster subobjects
if (is_outlines_only_htl) {
@@ -6187,20 +6186,38 @@ void model_render_children_buffers(bsp_info *model, polymodel *pm, int mn, int d
return;
}
if (model->gun_rotation) {
if (pm->gun_submodel_rotation > PI2 )
pm->gun_submodel_rotation -= PI2;
else if (pm->gun_submodel_rotation < 0.0f )
pm->gun_submodel_rotation += PI2;
angles ang = pm->submodel[mn].angs;
ang.b += pm->gun_submodel_rotation;
// Get submodel rotation data and use submodel orientation matrix
// to put together a matrix describing the final orientation of
// the submodel relative to its parent
angles ang = pm->submodel[mn].angs;
g3_start_instance_angles(&pm->submodel[mn].offset, &ang);
} else {
g3_start_instance_angles(&pm->submodel[mn].offset, &pm->submodel[mn].angs);
// Add barrel rotation if needed
if (model->gun_rotation) {
if ( pm->gun_submodel_rotation > PI2 ) {
pm->gun_submodel_rotation -= PI2;
} else if ( pm->gun_submodel_rotation < 0.0f ) {
pm->gun_submodel_rotation += PI2;
}
ang.b += pm->gun_submodel_rotation;
}
// Compute final submodel orientation by using the orientation matrix
// and the rotation angles.
// By using this kind of computation, the rotational angles can always
// be computed relative to the submodel itself, instead of relative
// to the parent
matrix rotation_matrix = model->orientation;
vm_rotate_matrix_by_angles(&rotation_matrix, &ang);
matrix inv_orientation;
vm_copy_transpose_matrix(&inv_orientation, &model->orientation);
matrix submodel_matrix;
vm_matrix_x_matrix(&submodel_matrix, &rotation_matrix, &inv_orientation);
g3_start_instance_matrix(&pm->submodel[mn].offset, &submodel_matrix, true);
if ( !(Interp_flags & MR_NO_LIGHTING) )
light_rotate_all();
+15 -10
View File
@@ -3038,6 +3038,11 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
case ID_PATH:
pm->n_paths = cfread_int( fp );
if (pm->n_paths <= 0) {
break;
}
pm->paths = (model_path *)vm_malloc(sizeof(model_path)*pm->n_paths);
Assert( pm->paths != NULL );
@@ -3670,6 +3675,8 @@ void model_maybe_fixup_subsys_path(polymodel *pm, int path_num)
float dist;
int index_1, index_2;
Assert( (path_num >= 0) && (path_num < pm->n_paths) );
model_path *mp;
mp = &pm->paths[path_num];
@@ -5405,13 +5412,13 @@ void swap_bsp_data( polymodel * pm, void *model_ptr )
void swap_sldc_data(ubyte *buffer)
{
#if BYTE_ORDER == BIG_ENDIAN
char *type_p = (char *)(Mc_pm->shield_collision_tree+offset);
int *size_p = (int *)(Mc_pm->shield_collision_tree+offset+1);
char *type_p = (char *)(buffer);
int *size_p = (int *)(buffer+1);
*size_p = INTEL_INT(*size_p);
// split and polygons
vec3d *minbox_p = (vec3d*)(Mc_pm->shield_collision_tree+offset+5);
vec3d *maxbox_p = (vec3d*)(Mc_pm->shield_collision_tree+offset+17);
vec3d *minbox_p = (vec3d*)(buffer+5);
vec3d *maxbox_p = (vec3d*)(buffer+17);
minbox_p->xyz.x = INTEL_FLOAT(&minbox_p->xyz.x);
minbox_p->xyz.y = INTEL_FLOAT(&minbox_p->xyz.y);
@@ -5423,20 +5430,18 @@ void swap_sldc_data(ubyte *buffer)
// split
unsigned int *front_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree+offset+29);
unsigned int *back_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree+offset+33);
unsigned int *front_offset_p = (unsigned int*)(buffer+29);
unsigned int *back_offset_p = (unsigned int*)(buffer+33);
// polygons
unsigned int *num_polygons_p = (unsigned int*)(Mc_pm->shield_collision_tree+offset+29);
unsigned int *num_polygons_p = (unsigned int*)(buffer+29);
unsigned int *shld_polys = (unsigned int*)(Mc_pm->shield_collision_tree+offset+33);
unsigned int *shld_polys = (unsigned int*)(buffer+33);
if (*type_p == 0) // SPLIT
{
*front_offset_p = INTEL_INT(*front_offset_p);
*back_offset_p = INTEL_INT(*back_offset_p);
mc_check_sldc(buffer+*front_offset_p);
mc_check_sldc(buffer+*back_offset_p);
}
else
{
Loaded 100 of 130 files, more files were not shown because too many files have changed in this diff. Show more