Compare commits

..
63 Commits
Author SHA1 Message Date
Swifty 3d680e1431 Merge with Trunk Revision 6640. 2010-10-19 22:49:15 +00:00
Swifty 3ef2dc8134 Unversioned files can go to hell. 2010-10-19 07:22:33 +00:00
Swifty dd2c182a60 Merge with Trunk Revision 6635. Prepped for Antipodes 7. 2010-10-19 07:14:36 +00:00
Swifty 7c5756996c Revision of animated cockpit readouts. Removed training_obj_display(). 2010-10-09 10:35:20 +00:00
Swifty e606278ce6 Update changes up to Trunk 6586 2010-10-09 10:09:48 +00:00
Swifty 182ed7f9c7 And while we're on targetbox bugs, Asteroid target status should now render in the proper place in non-GR rez. 2010-09-21 02:48:56 +00:00
Swifty 4870b2fc9e Targetbox cargo of target ship no longer carries over to the next selected non-ship target. 2010-09-21 02:45:50 +00:00
Swifty 586e514874 No more crashing when scanning subsystems. 2010-09-21 02:42:20 +00:00
Swifty 202bd88392 Revision 6473 2010-09-20 20:34:57 +00:00
Swifty 96e4fe4b6e Forgot to include options for Wing Names in Wingman Status. 2010-09-04 10:30:01 +00:00
Swifty 2e8a5a2692 Fixed Training Messages not playing when hud_disabled_except_messages() is on. Fixes War in Heaven's credits sequence. 2010-09-04 02:54:58 +00:00
Swifty 02c7fc1c89 Fixed Wingman Status gauge to properly allow changing of status bitmaps. 2010-09-02 05:30:48 +00:00
Swifty 74ac243ae1 Squished Int3() when using BSG radar. 2010-09-01 04:07:37 +00:00
Swifty 8609816c7c Project file updates. Adding bitarray.h and excluding debug info. 2010-09-01 01:55:46 +00:00
Swifty 15f365b09f I haz 6410 2010-09-01 01:53:27 +00:00
Swifty 9292ebf2c9 Fixed a bunch of stuff reported by swashmebuckle: wingman anis can now change, Integrity Bar Foreground Clip Height fixed, extra target data time inits fixed. 2010-08-31 23:50:15 +00:00
Swifty a04089e8a9 Making FUBAR's life easier; parts of wxFred slipped past WinMerge. 2010-08-28 05:41:09 +00:00
Swifty 6bc3f565dd +Radar: no longer forces standard radar and will defer to orb radar launcher flags. 2010-08-27 11:45:03 +00:00
Swifty b94023a86f omfg, HUD-specific, ship-specific, and gauge-specific fonts. 2010-08-27 11:34:38 +00:00
Swifty edc8b93a64 Up 2 d8 with 6385 2010-08-26 09:08:08 +00:00
Swifty 93381a2061 Go go gadget radar range! 2010-08-26 08:26:29 +00:00
Swifty 7c6c19a162 Targetbox bitmaps should listen now. 2010-08-26 08:17:31 +00:00
Swifty e399f53251 There are 6 wingmen dots, not 7. :| 2010-08-26 08:08:29 +00:00
Swifty e62b09cdfd Fix Weapon List parsing for "Secondary List Entry Background:" and "Secondary List Bottom Background Filename:" 2010-08-26 07:37:12 +00:00
Swifty 4c6ffd1650 Force parser to advance past $Reticle Style. Forgot to put FS1-style defaults for Weapon Energy. 2010-08-16 05:38:05 +00:00
Swifty 93fcc4b8db Various syntax corrections 2010-08-15 04:00:47 +00:00
Swifty d87ad46bd0 Minor change to Damage display syntax for the sake of consistency. 2010-08-15 01:05:49 +00:00
Swifty 3314903dda A shitload of table configuration fields for almost all individual gauges. Documentation pending. :\ 2010-08-14 23:49:35 +00:00
Swifty 045b7fc264 Adding initSlew method to the base HudGauge class. 2010-08-14 23:43:16 +00:00
Swifty c99704efe4 Removing a redundant property from Wingman Status. 2010-08-14 23:39:41 +00:00
Swifty 015b1a6309 Renaming a targetbox property to something that fits better. 2010-08-14 23:36:03 +00:00
Swifty 7871c4f146 Simplify and clarify some Escort display parameters. 2010-08-14 23:31:11 +00:00
Swifty ddc4d51999 hud_disabled_except_messages should work now, even if hud_disabled is on. 2010-08-13 10:44:39 +00:00
Swifty 7e3e0a9388 Tweaked the weapons display to better match retail positions. 2010-08-13 10:40:23 +00:00
Swifty 9f6d4533f8 Squished comm menu bug where menu would not be populated if no target is selected. Sorry this took so long, The_E. 2010-08-13 08:56:57 +00:00
Swifty 090ea8ad50 An additional tweak to the directives gauge. 2010-08-13 08:31:55 +00:00
Swifty fdf05d7e80 Simplifying the directives gauge. 2010-08-13 08:27:14 +00:00
Swifty dbc87e4241 Probably should get rid of these vars as well. 2010-08-13 08:19:57 +00:00
Swifty cbef6291cd Getting rid of Split Missile Triangles. 2010-08-13 08:16:35 +00:00
Swifty 5a2bd299c2 Huh. It turns out the correct behavior for Talking Heads is to play once and not loop. Yay for one line fixes. 2010-08-13 06:46:07 +00:00
Swifty 1daa233fe4 Updating XCode project files. 2010-08-11 23:19:25 +00:00
Swifty b03cbff4d1 No more disappearing or 1 micrometer-sized sub-object target brackets. 2010-08-11 19:36:42 +00:00
Swifty 773bf8b983 Bring this up to speed with r6354. 2010-08-11 19:31:30 +00:00
Swifty 9421ab2fba Warheads no longer show up as black on standard and orb radar. 2010-07-29 12:10:51 +00:00
Swifty 669ea48153 Message sender, remote detonation missile, homing missile, and selection set brackets should have the proper gradients now. 2010-07-29 03:42:58 +00:00
Swifty 4995f11472 I yet again forget to do something. Updating the Lua libraries. 2010-07-29 03:40:59 +00:00
Swifty 6b884151bc Sorry in advance for any conflicts with your project files. Forgot to unselect my project files. >_< 2010-07-25 14:36:24 +00:00
Swifty 4c91519648 Sync with Trunk 6325 2010-07-25 14:18:19 +00:00
Swifty e3c095684b Reported by Backslash. Fixed FS1 Weapon Linking gauge color and head view movements. 2010-07-17 02:13:10 +00:00
Swifty 591904644d This should fix the Int3() that appears when using the Orb Radar. 2010-07-16 02:48:17 +00:00
Swifty c4d8a64a74 Lead sight should work properly now. 2010-07-16 00:20:09 +00:00
Swifty 0b1ea699bb Sync with trunk 6250, including fix for Mantis 1888. 2010-06-22 05:18:14 +00:00
Swifty b88d75efb8 Forgot to add bitarray.h 2010-06-21 19:45:49 +00:00
Swifty 96ca7b1ffe Core files for BSG radar. 2010-06-21 10:00:09 +00:00
Swifty 563b113c68 Experimental Diaspora stuff. 2010-06-21 09:22:05 +00:00
Swifty 112c1c4dfe Sync with trunk 6238. 2010-06-21 08:38:02 +00:00
Swifty 77a63521e4 Fix Supernova gauge. 2010-06-17 09:02:42 +00:00
Swifty 6b3ee7cfb7 The_E: Fix cargo scanning for Target Box gauge. 2010-06-17 08:18:38 +00:00
Swifty 549c76c137 The_E: Include support for growing Wingman Status gauge dots to a different direction. 2010-06-17 08:14:14 +00:00
Swifty c185dab59c Forgot to include parse entrypoint for the Weapon Linking gauge. Fix Training Messages to render at the correct user-defined scale. 2010-06-11 03:42:26 +00:00
Swifty 60f201d1df Initial check in for new HUD code. 2010-06-10 05:29:57 +00:00
Swifty 225c8ece25 Merge with trunk r6199 2010-06-10 04:08:23 +00:00
Goober5000 75d680483a 2010-04-04 19:27:43 +00:00
276 changed files with 47784 additions and 39037 deletions

No files matched your search

+2 -2
View File
@@ -258,8 +258,6 @@ FS2_SOURCES = \
debugconsole/dbugfile.h \
debugconsole/timerbar.cpp \
debugconsole/timerbar.h \
decals/decals.cpp \
decals/decals.h \
demo/demo.cpp \
demo/demo.h \
exceptionhandler/exceptionhandler.cpp \
@@ -293,6 +291,8 @@ FS2_SOURCES = \
globalincs/crypt.h \
globalincs/def_files.cpp \
globalincs/def_files.h \
globalincs/fsmemory.cpp \
globalincs/fsmemory.h \
globalincs/globals.h \
globalincs/linklist.h \
globalincs/pstypes.h \
+1 -1
View File
@@ -88,7 +88,7 @@ char *ai_get_goal_ship_name(char *name, int *index)
}
Assert(Total_goal_ship_names < MAX_GOAL_SHIP_NAMES);
Assert(strlen(name) < NAME_LENGTH - 1);
Assertion(strlen(name) < NAME_LENGTH - 1, "Ship name %s is too long. Needs to be 31 characters or less.", name);
i = Total_goal_ship_names++;
strcpy_s(Goal_ship_names[i], name);
*index = i;
+6
View File
@@ -21,6 +21,7 @@
struct ship_weapon;
struct ship_subsys;
struct object;
struct ship_info;
#define AI_DEFAULT_CLASS 3 // default AI class for new ships (Fred)
@@ -639,6 +640,7 @@ extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, i
extern void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int dockee_index );
extern void ai_add_rearm_goal( object *requester_objp, object *support_objp );
extern void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_path=0);
extern int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 );
// Goober5000
extern void ai_do_safety(object *objp);
@@ -701,4 +703,8 @@ void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t
//SUSHI: Updating AI aim
void ai_update_aim(ai_info *aip, object* En_Objp);
//SUSHI: Random evasive sidethrust
void do_random_sidethrust(ai_info *aip, ship_info *sip);
#endif
+7 -1
View File
@@ -49,7 +49,6 @@ void set_flag(ai_profile_t *profile, char *name, int flag, int type)
void parse_ai_profiles_tbl(char *filename)
{
int i, rval;
bool no_create = false;
char profile_name[NAME_LENGTH];
ai_profile_t dummy_profile;
char *saved_Mp = NULL;
@@ -84,6 +83,7 @@ void parse_ai_profiles_tbl(char *filename)
{
ai_profile_t *profile = &dummy_profile;
ai_profile_t *previous_profile = NULL;
bool no_create = false;
// get the name
required_string("$Profile Name:");
@@ -393,6 +393,12 @@ void parse_ai_profiles_tbl(char *filename)
set_flag(profile, "$perform less checks for death screams:", AIPF2_PERFORM_LESS_SCREAM_CHECKS, AIP_FLAG2);
set_flag(profile, "$advanced turret fov edge checks:", AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS, AIP_FLAG2);
set_flag(profile, "$require turrets to have target in fov:", AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV, AIP_FLAG2);
set_flag(profile, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
// if we've been through once already and are at the same place, force a move
if ( saved_Mp && (saved_Mp == Mp) )
Mp++;
+4
View File
@@ -54,6 +54,10 @@
#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0)
#define AIPF2_NO_SPECIAL_PLAYER_AVOID (1 << 1)
#define AIPF2_PERFORM_LESS_SCREAM_CHECKS (1 << 2)
#define AIPF2_ALL_SHIPS_MANAGE_SHIELDS (1 << 3)
#define AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS (1 << 4)
#define AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV (1 << 5)
#define MAX_AI_PROFILES 5
+22 -3
View File
@@ -376,7 +376,12 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
float dist;
pm = model_get( Ship_info[Ships[Pl_objp->instance].ship_info_index].model_num );
//Necessary sanity check
polymodel *pm_t;
pm_t = model_get(Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].model_num);
Assertion(aip->targeted_subsys->system_info->path_num <= pm_t->n_paths, "Invalid Path number %d for subsystem %s on ship %s (Model: %s)\n", aip->targeted_subsys->system_info->path_num, aip->targeted_subsys->system_info->name, Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].name, pm_t->filename );
if (aip->targeted_subsys->system_info->path_num > pm_t->n_paths)
return 0;
// If attacking a subsystem, ensure that we have an unobstructed line of sight... if not, then move
// towards path linked to subsystem
subsys_in_sight = 0; // assume Pl_objp doesn't have line of sight to subys
@@ -420,7 +425,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
aip->path_goal_dist = 5;
subsys_path_num = aip->targeted_subsys->system_info->path_num;
if ( (aip->path_start) == -1 || (aip->mp_index != subsys_path_num) ) {
if ( ((aip->path_start) == -1 || (aip->mp_index != subsys_path_num)) && subsys_path_num <= pm->n_paths ) {
// maybe create a new path
if ( subsys_path_num >= 0 ) {
Assert(aip->target_objnum >= 0);
@@ -694,7 +699,7 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
ship_weapon *tswp = &temp_shipp->weapons;
if ( tswp->num_primary_banks > 0 ) {
Assert(tswp->current_primary_bank < tswp->num_primary_banks);
Assertion(tswp->current_primary_bank < tswp->num_primary_banks, "AI tried to select primary bank %d. Might be a model error\n", tswp->current_primary_bank);
weapon_info *wip = &Weapon_info[tswp->primary_bank_weapons[tswp->current_primary_bank]];
if (dist_to_enemy < MIN((wip->max_speed * wip->lifetime), wip->weapon_range)){
@@ -1640,6 +1645,20 @@ void ai_big_strafe()
Int3(); // Illegal submode for AIM_STRAFE
break;
}
//Maybe apply random sidethrust, depending on the current submode
//The following are valid targets for random sidethrust (circle strafe uses it too, but that is handled separately)
if (aip->submode == AIS_STRAFE_ATTACK ||
aip->submode == AIS_STRAFE_AVOID ||
aip->submode == AIS_STRAFE_RETREAT1 ||
aip->submode == AIS_STRAFE_RETREAT2 ||
aip->submode == AIS_STRAFE_POSITION)
{
//Re-roll for random sidethrust every 2 seconds
if (static_randf((Missiontime + static_rand(aip->shipnum)) >> 17) < aip->ai_random_sidethrust_percent) {
do_random_sidethrust(aip, &Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index]);
}
}
}
// See if Pl_objp should enter strafe mode (This is called from maybe_evade_dumbfire_weapon(), and the
+213 -433
View File
@@ -304,6 +304,9 @@ typedef struct {
// Move to a position relative to a dock bay using thrusters.
float dock_orient_and_approach(object *docker_objp, int docker_index, object *dockee_objp, int dockee_index, int dock_mode, rotating_dockpoint_info *rdinfo = NULL);
// The object that is declared to be the leader of the group formation for
// the "autopilot"
object *Autopilot_flight_leader = NULL;
// ai_set_rearm_status takes a team (friendly, hostile, neutral) and a time. This function
// sets the timestamp used to tell is it is a good time for this team to rearm. Once the timestamp
@@ -766,6 +769,8 @@ void parse_ai_class()
set_aic_flag(aicp, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG);
set_aic_flag(aicp, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
set_aic_flag(aicp, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
}
void reset_ai_class_names()
@@ -1311,40 +1316,6 @@ if (!((objp->type == OBJ_WEAPON) && (Weapon_info[Weapons[objp->instance].weapon_
// If new target (objnum) is different than old target, reset target_time.
int set_target_objnum(ai_info *aip, int objnum)
{
/*
char old_name[32], new_name[32];
if (!timestamp_elapsed(aip->ok_to_target_timestamp))
return aip->target_objnum;
if (Player_ship && (Ships[aip->shipnum].team == Player_ship->team)) {
if (aip->target_objnum == -1)
strcpy_s(old_name, "none");
else
strcpy_s(old_name, Ships[Objects[aip->target_objnum].instance].ship_name);
if (objnum == -1)
strcpy_s(new_name, "none");
else
strcpy_s(new_name, Ships[Objects[objnum].instance].ship_name);
nprintf(("AI", "Ship %s changing target from %s to %s\n", Ships[aip->shipnum].ship_name, old_name, new_name));
}
*/
// AL 2-25-97: Ensure that a protected ship isn't being set as a target (for non-players only)
/*
if ( objnum >= 0 ) {
if ( !(Objects[Ships[aip->shipnum].objnum].flags & OF_PLAYER_SHIP) ) {
if ( Objects[objnum].flags & OF_PROTECTED ) {
// AL 2-26-97: removing Int3() until issue with setting OF_PROTECTED in ai_set_attack_subsystem()
//Int3(); // this should not happen
return aip->target_objnum; // don't change targets
}
}
}
*/
if ((aip != Player_ai) && (!timestamp_elapsed(aip->ok_to_target_timestamp))) {
return aip->target_objnum;
}
@@ -1446,7 +1417,6 @@ void adjust_accel_for_docking(ai_info *aip)
// make sure we at least some velocity
if (ratio < 0.1f) {
// Int3();
ratio = 0.1f;
}
@@ -1849,52 +1819,6 @@ float get_wing_lowest_max_speed(object *objp)
return lowest_max_speed;
}
/*
// Tell everyone to ignore object objnum.
void set_global_ignore_object(int objnum)
{
int i;
Assert(Objects[objnum].type == OBJ_SHIP);
nprintf(("AI", "Telling everyone to ignore object %s\n", Ships[Objects[objnum].instance].ship_name));
for (i=0; i<MAX_IGNORE_OBJECTS; i++) {
if (Ignore_objects[i].objnum == -1) {
Ignore_objects[i].objnum = objnum;
Ignore_objects[i].signature = Objects[objnum].signature;
break;
}
}
if (i == MAX_IGNORE_OBJECTS) {
// Couldn't find a free slot, but maybe one of these objects has died.
for (i=0; i<MAX_IGNORE_OBJECTS; i++) {
int o = Ignore_objects[i].objnum;
if (Objects[o].type != OBJ_SHIP)
break; // Not a ship, so use this slot.
if (Objects[o].signature != Ignore_objects[i].signature)
break; // Signatures don't match, so use this slot.
}
if (i != MAX_IGNORE_OBJECTS) {
Ignore_objects[i].objnum = objnum;
Ignore_objects[i].signature = Objects[objnum].signature;
} else {
nprintf(("Warning", "Ignore_objects buffer full. Stealing a slot to ignore object #%i\n"));
Int3();
int r;
r = objnum % MAX_IGNORE_OBJECTS;
Ignore_objects[r].objnum = objnum;
Ignore_objects[r].signature = Objects[objnum].signature;
}
}
}
*/
// Goober5000 - fixed up a bit
// Determine if object objnum is supposed to be ignored by object with ai_info *aip.
@@ -2976,7 +2900,7 @@ void ai_find_path(object *pl_objp, int objnum, int path_num, int exit_flag, int
if(pm->n_paths <= path_num)
Error(LOCATION,"ai_find_path tring to find a path (%d) that doesn't exist, on ship %s", path_num, shipp->ship_name);
// Assert(pm->n_paths > path_num);
aip->goal_objnum = objp-Objects;
aip->goal_objnum = objnum;
aip->goal_signature = objp->signature;
if (exit_flag)
create_model_exit_path(pl_objp, objp, path_num);
@@ -4174,13 +4098,13 @@ void ai_safety()
// --------------------------------------------------------------------------
// make Pl_objp fly tword a ship
// Goal created by Kazan
// code adapted from waypoints
void ai_fly_to_ship()
// make Pl_objp fly to its target's position
// optionally returns true if Pl_objp (pl_done_p) has reached the target position (can be NULL)
// optionally returns true if Pl_objp's (pl_treat_as_ship_p) fly to order was issued to him directly,
// or if the order was issued to his wing (returns false) (can be NULL, and result is only
// valid if Pl_done_p was not NULL and was set true by function.
void ai_fly_to_target_position(vec3d* target_pos, bool* pl_done_p=NULL, bool* pl_treat_as_ship_p=NULL)
{
vec3d *target_pos;
float dot, dist_to_goal, speed;
ship *shipp = &Ships[Pl_objp->instance];
ship_info *sip = &Ship_info[shipp->ship_info_index];
@@ -4190,30 +4114,25 @@ void ai_fly_to_ship()
float prev_dot_to_goal;
vec3d temp_vec;
vec3d *slop_vec;
int target_object=-1;
int j;
Assert( target_pos != NULL );
if ( pl_done_p != NULL ) {
// initialize this to false now incase we leave early so that that
// the caller of this function doesn't get any funny ideas about
// the status of the waypoint
*pl_done_p = false;
}
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
int i,j ;
for (i = 0; i < MAX_AI_GOALS && target_object == -1; i++)
{
if (aip->goals[i].ai_mode == AIM_FLY_TO_SHIP || aip->goals[i].ai_mode == AI_GOAL_FLY_TO_SHIP)
{
for (j = 0; j < MAX_SHIPS; j++)
{
if (Ships[j].objnum != -1 && !stricmp(aip->goals[i].ship_name, Ships[j].ship_name))
{
target_object = Ships[j].objnum;
break;
}
}
}
/* I shouldn't be flying to position for what ever called me any more.
Set mode to none so that default dynamic behaviour gets started up again. */
if ( (aip->active_goal == AI_GOAL_NONE) || (aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC) ) {
aip->mode = AIM_NONE;
}
target_pos = &Objects[target_object].pos;
speed = Pl_objp->phys_info.speed;
dist_to_goal = vm_vec_dist_quick(&Pl_objp->pos, target_pos);
@@ -4247,53 +4166,54 @@ void ai_fly_to_ship()
// If a wing leader, take turns more slowly, based on size of wing.
int scale;
if (Ai_info[Ships[Pl_objp->instance].ai_index].wing >= 0) {
scale = Wings[Ai_info[Ships[Pl_objp->instance].ai_index].wing].current_count;
if (aip->wing >= 0) {
scale = Wings[aip->wing].current_count;
scale = (int) ((scale+1)/2);
} else {
scale = 1;
}
// ----------------------------------------------
// if in autopilot mode make sure to not collide
// and "keep reasonable distance"
// this needs to be done for ALL SHIPS not just capships STOP CHANGING THIS
// ----------------------------------------------
object *wing_leader = get_wing_leader(aip->wing);
vec3d perp, goal_point;
bool carry_flag = ((shipp->flags2 & SF2_NAVPOINT_CARRY) || ((shipp->wingnum >= 0) && (Wings[shipp->wingnum].flags & WF_NAV_CARRY)));
if (AutoPilotEngaged && timestamp_elapsed(LockAPConv) && carry_flag
&& ((The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) || (Pl_objp != wing_leader)) )
if (AutoPilotEngaged
&& timestamp_elapsed(LockAPConv)
&& carry_flag
&& ((The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) || (Pl_objp != Autopilot_flight_leader)) )
{
Assertion( Autopilot_flight_leader != NULL, "When under autopilot there must be a flight leader" );
// snap wings into formation them into formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) {
if (aip->wing != -1) {
int wing_index = get_wing_index(Pl_objp, aip->wing);
object *wing_leader = get_wing_leader(aip->wing);
if (wing_leader != Pl_objp) {
// not leader.. get our position relative to leader
// not wing leader.. get my position relative to wing leader
get_absolute_wing_pos_autopilot(&goal_point, wing_leader, wing_index, aip->ai_flags & AIF_FORMATION_OBJECT);
} else {
// Am wing leader.. get the wings position relative to the flight leader
j = 1+int( (float)floor(double(autopilot_wings[aip->wing]-1)/2.0) );
switch (autopilot_wings[aip->wing] % 2) {
case 1: // back-left
vm_vec_copy_normalize(&perp, &Player_obj->orient.vec.rvec);
vm_vec_copy_normalize(&perp, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
default: //back-right
case 0:
vm_vec_copy_normalize(&perp, &Player_obj->orient.vec.rvec);
vm_vec_copy_normalize(&perp, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_scale(&perp, 166.0f*j);
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
}
@@ -4302,10 +4222,10 @@ void ai_fly_to_ship()
Pl_objp->pos = goal_point;
}
vm_vec_sub(&perp, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
vm_vec_sub(&perp, Navs[CurrentNav].GetPosition(), &Autopilot_flight_leader->pos);
vm_vector_2_matrix(&Pl_objp->orient, &perp, NULL, NULL);
} else {
vm_vec_scale_add(&perp, &Pl_objp->pos, &wing_leader->phys_info.vel, 1000.0f);
vm_vec_scale_add(&perp, &Pl_objp->pos, &Autopilot_flight_leader->phys_info.vel, 1000.0f);
ai_turn_towards_vector(&perp, Pl_objp, flFrametime, sip->srotation_time*3.0f*scale, slop_vec, NULL, 0.0f, 0);
}
} else {
@@ -4320,8 +4240,6 @@ void ai_fly_to_ship()
dot = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, target_pos);
aip->prev_dot_to_goal = dot;
// nprintf(("AI", "Wp #%i, dot = %6.3f, next dot = %6.3f, dist = %7.2f\n", wp_index, dot, dot_to_next, dist_to_goal));
if (Pl_objp->phys_info.speed < 0.0f) {
accelerate_ship(aip, 1.0f/32);
} else if (prev_dot_to_goal > dot+0.01f) {
@@ -4383,13 +4301,11 @@ void ai_fly_to_ship()
r = find_nearest_point_on_line(&nearest_point, &Pl_objp->last_pos, &Pl_objp->pos, target_pos);
if ( (vm_vec_dist_quick(&Pl_objp->pos, target_pos) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius) + vm_vec_dist_quick(&Pl_objp->pos, &Pl_objp->last_pos))) ||
((r >= 0.0f) && (r <= 1.0f)) && (vm_vec_dist_quick(&nearest_point, target_pos) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius)))) {
if ( (vm_vec_dist_quick(&Pl_objp->pos, target_pos) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius) + vm_vec_dist_quick(&Pl_objp->pos, &Pl_objp->last_pos)))
|| (((r >= 0.0f) && (r <= 1.0f)) && (vm_vec_dist_quick(&nearest_point, target_pos) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius)))))
{
int treat_as_ship;
// when not repeating waypoints -- mark the goal as done and put and entry into the mission log
// we must be careful when dealing with wings. A ship in a wing might be completing
// a waypoint for for the entire wing, or it might be completing a goal for itself. If
// for itself and in a wing, treat the completion as we would a ship
@@ -4397,15 +4313,6 @@ void ai_fly_to_ship()
if ( Ships[Pl_objp->instance].wingnum != -1 ) {
int type;
// I don't think that you can fly waypoints as dynamic goals!!!
// -- This is legal, just stupid. -- Assert( (aip->active_goal != AI_GOAL_NONE) && (aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC) );
// Clean up from above Assert, just in case we ship without fixing it. (Encountered by JimB on 2/9/98)
if ( (aip->active_goal == AI_GOAL_NONE) || (aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC) ) {
aip->mode = AIM_NONE;
Int3(); // Look at the ship, find out of it's supposed to be flying waypoints. -- MK.
}
type = aip->goals[aip->active_goal].type;
if ( (type == AIG_TYPE_EVENT_WING) || (type == AIG_TYPE_PLAYER_WING) ) {
treat_as_ship = 0;
@@ -4413,20 +4320,20 @@ void ai_fly_to_ship()
treat_as_ship = 1;
}
}
// if the ship is not in a wing, remove the goal and continue on
if ( treat_as_ship ) {
ai_mission_goal_complete( aip ); // this call should reset the AI mode
//mission_log_add_entry(LOG_WAYPOINTS_DONE, Ships[Pl_objp->instance].ship_name, wpl->name, -1 );
// setup out parameters
if ( pl_done_p != NULL ) {
*pl_done_p = true;
if ( pl_treat_as_ship_p != NULL ) {
if ( treat_as_ship ) {
*pl_treat_as_ship_p = true;
} else {
*pl_treat_as_ship_p = false;
}
}
} else {
// this ship is in a wing. We must mark the goal as being completed for all ships
// in the wing. We will also mark an entry in the log that the wing completed the goal
// not the individual ship.
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
//mission_log_add_entry( LOG_WAYPOINTS_DONE, Wings[Ships[Pl_objp->instance].wingnum].name, wpl->name, -1 );
Assertion( pl_treat_as_ship_p != NULL,
"pl_done_p cannot be NULL while pl_treat_as_ship_p is not NULL" );
}
//wp_index = wpl->count-1;
}
}
}
@@ -4436,18 +4343,8 @@ void ai_fly_to_ship()
void ai_waypoints()
{
int wp_index;
vec3d *wp_cur, *wp_next;
float dot, dist_to_goal, dist_to_next, speed, dot_to_next;
ship *shipp = &Ships[Pl_objp->instance];
ship_info *sip = &Ship_info[shipp->ship_info_index];
waypoint_list *wpl;
ai_info *aip;
vec3d nvel_vec;
float mag;
float prev_dot_to_goal;
vec3d temp_vec;
vec3d *slop_vec;
int j;
waypoint_list *wpl;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -4461,236 +4358,111 @@ void ai_waypoints()
wpl = &Waypoint_lists[aip->wp_list];
Assert(wpl->count); // What? Is this zero? Probably wp_index never got initialized!
Assert(wpl->count > 0); // What? Is this zero? Probably wp_index never got initialized!
wp_cur = &wpl->waypoints[wp_index];
wp_next = &wpl->waypoints[(wp_index+1) % wpl->count];
speed = Pl_objp->phys_info.speed;
bool done, treat_as_ship;
ai_fly_to_target_position(&(wpl->waypoints[wp_index]), &done, &treat_as_ship);
dist_to_goal = vm_vec_dist_quick(&Pl_objp->pos, wp_cur);
dist_to_next = vm_vec_dist_quick(&Pl_objp->pos, wp_next);
// Can't use fvec, need to use velocity vector because we aren't necessarily
// moving in the direction we're facing.
// AL 23-3-98: Account for very small velocities by checking result of vm_vec_mag().
// If we don't vm_vec_copy_normalize() will think it is normalizing a null vector.
// if (IS_VEC_NULL(&Pl_objp->phys_info.vel)) {
if ( vm_vec_mag_quick(&Pl_objp->phys_info.vel) < AICODE_SMALL_MAGNITUDE ) {
mag = 0.0f;
vm_vec_zero(&nvel_vec);
} else {
mag = vm_vec_copy_normalize(&nvel_vec, &Pl_objp->phys_info.vel);
}
// If moving not-very-slowly and sliding, then try to slide at goal, rather than
// point at goal.
slop_vec = NULL;
if (mag < 1.0f) {
nvel_vec = Pl_objp->orient.vec.fvec;
} else if (mag > 5.0f) {
float nv_dot;
nv_dot = vm_vec_dot(&Pl_objp->orient.vec.fvec, &nvel_vec);
if ((nv_dot > 0.5f) && (nv_dot < 0.97f)) {
slop_vec = &temp_vec;
vm_vec_sub(slop_vec, &nvel_vec, &Pl_objp->orient.vec.fvec);
}
}
// If a wing leader, take turns more slowly, based on size of wing.
int scale;
if (aip->wing >= 0) {
scale = Wings[aip->wing].current_count;
scale = (int) ((scale+1)/2);
} else {
scale = 1;
}
// ----------------------------------------------
// if in autopilot mode make sure to not collide
// and "keep reasonable distance"
// this needs to be done for ALL SHIPS not just capships STOP CHANGING THIS
// ----------------------------------------------
object *wing_leader = get_wing_leader(aip->wing);
vec3d perp, goal_point;
bool carry_flag = ((shipp->flags2 & SF2_NAVPOINT_CARRY) || ((shipp->wingnum >= 0) && (Wings[shipp->wingnum].flags & WF_NAV_CARRY)));
if (AutoPilotEngaged && timestamp_elapsed(LockAPConv) && carry_flag
&& ((The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) || (Pl_objp != wing_leader)) )
{
// snap wings into formation them into formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) {
if (aip->wing != -1) {
int wing_index = get_wing_index(Pl_objp, aip->wing);
if (wing_leader != Pl_objp) {
// not leader.. get our position relative to leader
get_absolute_wing_pos_autopilot(&goal_point, wing_leader, wing_index, aip->ai_flags & AIF_FORMATION_OBJECT);
} else {
j = 1+int( (float)floor(double(autopilot_wings[aip->wing]-1)/2.0) );
switch (autopilot_wings[aip->wing] % 2) {
case 1: // back-left
vm_vec_copy_normalize(&perp, &Player_obj->orient.vec.rvec);
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
break;
default: //back-right
case 0:
vm_vec_copy_normalize(&perp, &Player_obj->orient.vec.rvec);
vm_vec_scale(&perp, 166.0f*j);
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
break;
}
}
Pl_objp->pos = goal_point;
}
vm_vec_sub(&perp, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
vm_vector_2_matrix(&Pl_objp->orient, &perp, NULL, NULL);
} else {
if ( !wing_leader )
wing_leader = Pl_objp;
vm_vec_scale_add(&perp, &Pl_objp->pos, &wing_leader->phys_info.vel, 1000.0f);
ai_turn_towards_vector(&perp, Pl_objp, flFrametime, sip->srotation_time*3.0f*scale, slop_vec, NULL, 0.0f, 0);
}
} else {
if (dist_to_goal > 0.1f) {
ai_turn_towards_vector(wp_cur, Pl_objp, flFrametime, sip->srotation_time*3.0f*scale, slop_vec, NULL, 0.0f, 0);
}
}
// ----------------------------------------------
prev_dot_to_goal = aip->prev_dot_to_goal;
dot = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, wp_cur);
dot_to_next = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, wp_next);
aip->prev_dot_to_goal = dot;
// If there is no next point on the path, don't care about dot to next.
if (wp_index + 1 >= wpl->count) {
dot_to_next = dot;
}
// nprintf(("AI", "Wp #%i, dot = %6.3f, next dot = %6.3f, dist = %7.2f\n", wp_index, dot, dot_to_next, dist_to_goal));
if (Pl_objp->phys_info.speed < 0.0f) {
accelerate_ship(aip, 1.0f/32);
} else if (prev_dot_to_goal > dot+0.01f) {
// We are further from pointing at our goal this frame than last frame, so slow down.
set_accel_for_target_speed(Pl_objp, Pl_objp->phys_info.speed * 0.95f);
} else if (dist_to_goal < 100.0f) {
float slew_dot = vm_vec_dot(&Pl_objp->orient.vec.fvec, &nvel_vec);
if (fl_abs(slew_dot) < 0.9f) {
accelerate_ship(aip, 0.0f);
} else if (dot < 0.88f + 0.1f*(100.0f - dist_to_goal)/100.0f) {
accelerate_ship(aip, 0.0f);
} else {
accelerate_ship(aip, 0.5f * dot * dot);
}
} else {
float dot1;
if (dist_to_goal < 250.0f) {
dot1 = dot*dot*dot; // Very important to be pointing towards goal when nearby. Note, cubing preserves sign.
} else {
if (dot > 0.0f) {
dot1 = dot*dot;
if ( done ) {
aip->wp_index++; // go on to next waypoint in path
if ( (aip->wp_index >= wpl->count) ) {
// have reached the last waypoint. Do I?
if ( ((aip->wp_flags & WPF_REPEAT) > 0) ) {
aip->wp_index = 0; // go back to the start.
} else {
dot1 = dot;
}
}
if (dist_to_goal > 100.0f + Pl_objp->radius * 2) {
if (dot < 0.2f) {
dot1 = 0.2f;
}
}
if (sip->flags & SIF_SMALL_SHIP) {
set_accel_for_target_speed(Pl_objp, dot1 * dist_to_goal/5.0f);
} else {
set_accel_for_target_speed(Pl_objp, dot1 * dist_to_goal/10.0f);
}
}
// Make sure not travelling too fast for someone to keep up.
float max_allowed_speed = 9999.9f;
if (shipp->wingnum != -1) {
max_allowed_speed = 0.9f * get_wing_lowest_max_speed(Pl_objp);
}
// check if waypoint speed cap is set and adjust max speed
if (aip->waypoint_speed_cap > 0) {
max_allowed_speed = (float) aip->waypoint_speed_cap;
}
if (aip->prev_accel * shipp->current_max_speed > max_allowed_speed) {
accelerate_ship(aip, max_allowed_speed / shipp->current_max_speed);
}
if ( (dist_to_goal < MIN_DIST_TO_WAYPOINT_GOAL) || (vm_vec_dist_quick(&Pl_objp->last_pos, &Pl_objp->pos) > 0.1f) ) {
vec3d nearest_point;
float r;
r = find_nearest_point_on_line(&nearest_point, &Pl_objp->last_pos, &Pl_objp->pos, wp_cur);
if ( (vm_vec_dist_quick(&Pl_objp->pos, wp_cur) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius) + vm_vec_dist_quick(&Pl_objp->pos, &Pl_objp->last_pos))) ||
((r >= 0.0f) && (r <= 1.0f)) && (vm_vec_dist_quick(&nearest_point, wp_cur) < (MIN_DIST_TO_WAYPOINT_GOAL + fl_sqrt(Pl_objp->radius)))) {
wp_index++;
if (wp_index >= wpl->count)
if (aip->wp_flags & WPF_REPEAT) {
wp_index = 0;
aip->wp_index = (wpl->count - 1); // stay on the last waypoint
// Log a message that the wing or ship reached his waypoint and
// remove the goal from the AI goals of the ship pr wing, respectively.
// Wether or not we should treat this as a ship or a wing is determined by
// ai_fly_to_target_position when it marks the AI directive as complete
if ( treat_as_ship ) {
ai_mission_goal_complete( aip ); // this call should reset the AI mode
mission_log_add_entry( LOG_WAYPOINTS_DONE, Ships[Pl_objp->instance].ship_name, wpl->name, -1 );
} else {
int treat_as_ship;
// when not repeating waypoints -- mark the goal as done and put and entry into the mission log
// we must be careful when dealing with wings. A ship in a wing might be completing
// a waypoint for for the entire wing, or it might be completing a goal for itself. If
// for itself and in a wing, treat the completion as we would a ship
treat_as_ship = 1;
if ( Ships[Pl_objp->instance].wingnum != -1 ) {
int type;
// I don't think that you can fly waypoints as dynamic goals!!!
// -- This is legal, just stupid. -- Assert( (aip->active_goal != AI_GOAL_NONE) && (aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC) );
// Clean up from above Assert, just in case we ship without fixing it. (Encountered by JimB on 2/9/98)
if ( (aip->active_goal == AI_GOAL_NONE) || (aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC) ) {
aip->mode = AIM_NONE;
//Int3(); // Look at the ship, find out of it's supposed to be flying waypoints. -- MK.
}
type = aip->goals[aip->active_goal].type;
if ( (type == AIG_TYPE_EVENT_WING) || (type == AIG_TYPE_PLAYER_WING) ) {
treat_as_ship = 0;
} else {
treat_as_ship = 1;
}
}
// if the ship is not in a wing, remove the goal and continue on
if ( treat_as_ship ) {
ai_mission_goal_complete( aip ); // this call should reset the AI mode
mission_log_add_entry(LOG_WAYPOINTS_DONE, Ships[Pl_objp->instance].ship_name, wpl->name, -1 );
} else {
// this ship is in a wing. We must mark the goal as being completed for all ships
// in the wing. We will also mark an entry in the log that the wing completed the goal
// not the individual ship.
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
mission_log_add_entry( LOG_WAYPOINTS_DONE, Wings[Ships[Pl_objp->instance].wingnum].name, wpl->name, -1 );
}
//wp_index = wpl->count-1;
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
mission_log_add_entry( LOG_WAYPOINTS_DONE, Wings[Ships[Pl_objp->instance].wingnum].name, wpl->name, -1 );
}
}
}
}
}
aip->wp_index = wp_index;
// --------------------------------------------------------------------------
// make Pl_objp fly toward a ship
void ai_fly_to_ship()
{
ai_info *aip;
object* target_p = NULL;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
if ( aip->mode != AIM_FLY_TO_SHIP ) {
Warning(LOCATION,
"ai_fly_to_ship called for '%s' when ai_info.mode not equal to AIM_FLY_TO_SHIP. Is actually '%d'",
Ships[Pl_objp->instance].ship_name,
aip->mode);
aip->mode = AIM_NONE;
return;
}
if ( aip->active_goal < 0 || aip->active_goal >= MAX_AI_GOALS ) {
Warning(LOCATION,
"'%s' is trying to fly-to a ship without an active AI_GOAL\n\n"
"Active ai mode is '%d'",
Ships[Pl_objp->instance].ship_name,
aip->active_goal);
aip->mode = AIM_NONE;
return;
}
Assert( aip->goals[aip->active_goal].ship_name != NULL );
if ( strlen(aip->goals[aip->active_goal].ship_name) == 0 ) {
Warning(LOCATION,
"'%s' is trying to fly-to a ship without a name for the ship",
Ships[Pl_objp->instance].ship_name);
aip->mode = AIM_NONE;
ai_remove_ship_goal( aip, aip->active_goal ); // function sets aip->active_goal to NONE for me
return;
}
for (int j = 0; j < MAX_SHIPS; j++)
{
if (Ships[j].objnum != -1 && !stricmp(aip->goals[aip->active_goal].ship_name, Ships[j].ship_name))
{
target_p = &Objects[Ships[j].objnum];
break;
}
}
if ( target_p == NULL ) {
#ifndef NDEBUG
for (int i = 0; i < MAX_AI_GOALS; i++)
{
if (aip->mode == AIM_FLY_TO_SHIP || aip->goals[i].ai_mode == AI_GOAL_FLY_TO_SHIP)
{
mprintf(("Ship '%s' told to fly to target ship '%s'",
Ships[Pl_objp->instance].ship_name,
aip->goals[i].ship_name));
}
}
#endif
Warning(LOCATION, "Ship '%s' told to fly to a ship but none of the ships it was told to fly to exist.\n"
"See log before this message for list of ships set as fly-to tagets",
Ships[Pl_objp->instance].ship_name);
aip->mode = AIM_NONE;
ai_remove_ship_goal( aip, aip->active_goal ); // function sets aip->active_goal to NONE for me
return;
} else {
bool done, treat_as_ship;
ai_fly_to_target_position(&(target_p->pos), &done, &treat_as_ship);
if ( done ) {
// remove the goal from the AI goals of the ship pr wing, respectively.
// Wether or not we should treat this as a ship or a wing is determined by
// ai_fly_to_target when it marks the AI directive as complete
if ( treat_as_ship ) {
ai_mission_goal_complete( aip ); // this call should reset the AI mode
} else {
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
}
}
}
}
@@ -5398,7 +5170,6 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
{
// this can be NULL in the case of a target death and attacker weapon
// change. using notification message instead of a fault
// Int3();
mprintf(("'other_objpp == NULL' in ai_select_primary_weapon()\n"));
return -1;
}
@@ -5450,7 +5221,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
// ##UnknownPlayer## - removed.
}
if ( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))
if ( (other_objp->type == OBJ_SHIP) && (Ship_info[Ships[other_objp->instance].ship_info_index].flags & (SIF_BIG_SHIP|SIF_HUGE_SHIP) ) )
{
//Check if we have a capital+ weapon on board
for (int i = 0; i < swp->num_primary_banks; i++)
@@ -5476,16 +5247,20 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
int i;
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
// Find the weapon with the highest hull * damage / fire delay factor
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
if (((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev) && (!(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) && !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))) )
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) )
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
}
}
}
}
@@ -5497,15 +5272,16 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
return i_hullfactor_prev_bank; // Return
}
//if the shields are above lets say 10% defanantly use a pierceing weapon if there are any-Bobboau
if (enemy_remaining_shield >= 0.10f){
//if the shields are above lets say 10% definitely use a pierceing weapon if there are any-Bobboau
if (enemy_remaining_shield >= 0.10f)
{
if (swp->current_primary_bank >= 0)
{
int bank_index;
bank_index = swp->current_primary_bank;
if ((Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)))
if ((Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_CAPITAL_PLUS))
{
return swp->current_primary_bank;
}
@@ -5518,7 +5294,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
if (weapon_info_index > -1)
{
if ((Weapon_info[weapon_info_index].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)))
if ((Weapon_info[weapon_info_index].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS))
{
swp->current_primary_bank = i;
return i;
@@ -5539,11 +5315,14 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
{
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
if (((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev ) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)))
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
// This weapon is the new candidate
i_hullfactor_prev = ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait));
i_hullfactor_prev_bank = i;
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) )
{
// This weapon is the new candidate
i_hullfactor_prev = ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait));
i_hullfactor_prev_bank = i;
}
}
}
}
@@ -5565,11 +5344,14 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
{
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
if (((((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev ) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)))
if ((((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) )
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
}
}
}
}
@@ -5738,7 +5520,7 @@ int ai_fire_primary_weapon(object *objp)
if (aip->target_objnum != -1){
enemy_objp = &Objects[aip->target_objnum];
enemy_sip = &Ship_info[Ships[enemy_objp->instance].ship_info_index];
enemy_sip = (enemy_objp->type == OBJ_SHIP) ? &Ship_info[Ships[enemy_objp->instance].ship_info_index] : NULL;
} else {
enemy_objp = NULL;
enemy_sip = NULL;
@@ -5775,7 +5557,7 @@ int ai_fire_primary_weapon(object *objp)
//SUSHI: Burst-fire for ballistic primaries.
if (The_mission.ai_profile->primary_ammo_burst_mult[Game_skill_level] > 0 && //Make sure we are using burst fire
enemy_objp != NULL && //We need a target, obviously
enemy_objp != NULL && enemy_sip != NULL && //We need a target, obviously
(enemy_objp->phys_info.speed >= 1.0f) && //Only burst for moving ships
(enemy_sip->flags & (SIF_SMALL_SHIP | SIF_TRANSPORT)) && //Only burst for small ships (transports count)
swp->primary_bank_start_ammo[swp->current_primary_bank] > 0 && //Prevent div by 0
@@ -6427,7 +6209,6 @@ float ai_get_weapon_dist(ship_weapon *swp)
// If weapon_num is illegal, return a reasonable value. A valid weapon
// will get selected when this ship tries to fire.
if (weapon_num == -1) {
// Int3();
return 1000.0f;
}
@@ -6445,7 +6226,6 @@ float ai_get_weapon_speed(ship_weapon *swp)
weapon_num = swp->primary_bank_weapons[bank_num];
if (weapon_num == -1) {
//Int3();
return 100.0f;
}
@@ -6727,8 +6507,14 @@ void do_random_sidethrust(ai_info *aip, ship_info *sip)
//This means that we get the same random values for a little bit.
//Using static_rand(shipnum) as a crude hash function to make sure that the seed is different for each ship and direction
//The *2 ensures that y and x stay separate.
side_vec.x = static_randf_range((((Missiontime + static_rand(aip->shipnum)) >> 16) / strafeHoldDirAmount) , -1.0f, 1.0f);
side_vec.y = static_randf_range((((Missiontime + static_rand(aip->shipnum)) >> 16) / strafeHoldDirAmount) * 2, -1.0f, 1.0f);
if (strafeHoldDirAmount > 0) { //This may look unnecessary, but we're apparently still getting div by zero errors on Macs here.
side_vec.x = static_randf_range((((Missiontime + static_rand(aip->shipnum)) >> 16) / strafeHoldDirAmount) , -1.0f, 1.0f);
side_vec.y = static_randf_range((((Missiontime + static_rand(aip->shipnum)) >> 16) / strafeHoldDirAmount) * 2, -1.0f, 1.0f);
} else {
Warning(LOCATION, "Division by zero in do_random_sidethrust averted. Please tell a coder.\n");
side_vec.x = 1.0f;
side_vec.y = 1.0f;
}
//Scale it up so that the longest dimension is length 1.0. This ensures we are always getting as much use out of sidethrust as possible.
vm_vec_boxscale(&side_vec, 1.0f);
@@ -6793,13 +6579,13 @@ void attack_set_accel(ai_info *aip, ship_info *sip, float dist_to_enemy, float d
if (!( Pl_objp->phys_info.flags & PF_AFTERBURNER_ON )) {
float percent_left;
ship *shipp;
ship_info *sip;
ship_info *sip_local;
shipp = &Ships[Pl_objp->instance];
sip = &Ship_info[shipp->ship_info_index];
sip_local = &Ship_info[shipp->ship_info_index];
if (sip->afterburner_fuel_capacity > 0.0f) {
percent_left = 100.0f * shipp->afterburner_fuel / sip->afterburner_fuel_capacity;
if (sip_local->afterburner_fuel_capacity > 0.0f) {
percent_left = 100.0f * shipp->afterburner_fuel / sip_local->afterburner_fuel_capacity;
if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) {
afterburners_start(Pl_objp);
if (aip->ai_profile_flags & AIPF_SMART_AFTERBURNER_MANAGEMENT) {
@@ -6809,11 +6595,11 @@ void attack_set_accel(ai_info *aip, ship_info *sip, float dist_to_enemy, float d
float ab_time;
// Max afterburner speed - make sure we don't devide by 0 later
max_ab_vel = sip->afterburner_max_vel.xyz.z > 0.0f ? sip->afterburner_max_vel.xyz.z : sip->max_vel.xyz.z;
max_ab_vel = sip_local->afterburner_max_vel.xyz.z > 0.0f ? sip_local->afterburner_max_vel.xyz.z : sip_local->max_vel.xyz.z;
max_ab_vel = max_ab_vel > 0.0f ? max_ab_vel : 0.0001f;
// Time to exhaust 25% of the remaining fuel
time_to_exhaust_25pct_fuel = shipp->afterburner_fuel * 0.25f / sip->afterburner_burn_rate;
time_to_exhaust_25pct_fuel = shipp->afterburner_fuel * 0.25f / sip_local->afterburner_burn_rate;
// Time to fly 75% of the distance to the target
time_to_fly_75pct_of_distance = dist_to_enemy * 0.75f / max_ab_vel;
@@ -8099,14 +7885,6 @@ void ai_cruiser_chase()
ship *shipp = &Ships[Pl_objp->instance];
ai_info *aip = &Ai_info[shipp->ai_index];
//WMC - We don't need/want this anymore.
/*
if (!(sip->flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
Int3(); // Hmm, not a very big ship, how did we get in this function?
aip->mode = AIM_NONE;
return;
}*/
if (En_objp->type != OBJ_SHIP) {
Int3();
return;
@@ -8496,10 +8274,14 @@ void ai_chase()
aip->submode == SM_SUPER_ATTACK ||
aip->submode == SM_EVADE_SQUIGGLE ||
aip->submode == SM_EVADE ||
aip->submode == SM_GET_AWAY)
aip->submode == SM_GET_AWAY ||
aip->submode == AIS_CHASE_GLIDEATTACK)
{
//Re-roll for random sidethrust every 2 seconds
if (static_randf((Missiontime + static_rand(aip->shipnum)) >> 17) < aip->ai_random_sidethrust_percent)
//Also, only do this if we've recently been hit or are in current primary weapon range of target
float current_weapon_range = Weapon_info[swp->primary_bank_weapons[swp->current_primary_bank]].weapon_range;
if (static_randf((Missiontime + static_rand(aip->shipnum)) >> 17) < aip->ai_random_sidethrust_percent &&
((Missiontime - aip->last_hit_time < i2f(5) && aip->hitter_objnum >= 0) || dist_to_enemy < current_weapon_range))
{
do_random_sidethrust(aip, sip);
}
@@ -8577,8 +8359,7 @@ void ai_chase()
aip->submode_start_time = Missiontime;
aip->submode_parm0 = SM_SF_AHEAD;
} else if (dist_to_enemy < CIRCLE_STRAFE_MAX_DIST + En_objp->radius &&
(En_objp->phys_info.speed < MAX(sip->max_vel.xyz.x, sip->max_vel.xyz.y)) &&
(dot_to_enemy > 0.33) &&
(En_objp->phys_info.speed < MAX(sip->max_vel.xyz.x, sip->max_vel.xyz.y) * 1.5f) &&
(static_randf((Missiontime + static_rand(aip->shipnum)) >> 19) < aip->ai_circle_strafe_percent)) {
aip->submode = AIS_CHASE_CIRCLESTRAFE;
aip->submode_start_time = Missiontime;
@@ -8693,8 +8474,7 @@ void ai_chase()
aip->submode_start_time = Missiontime;
aip->submode_parm0 = SM_SF_AHEAD;
} else if (dist_to_enemy < CIRCLE_STRAFE_MAX_DIST + En_objp->radius &&
(En_objp->phys_info.speed < MAX(sip->max_vel.xyz.x, sip->max_vel.xyz.y)) &&
(dot_to_enemy > 0.33) &&
(En_objp->phys_info.speed < MAX(sip->max_vel.xyz.x, sip->max_vel.xyz.y) * 1.5f) &&
(static_randf((Missiontime + static_rand(aip->shipnum)) >> 19) < aip->ai_circle_strafe_percent)) {
aip->submode = AIS_CHASE_CIRCLESTRAFE;
aip->submode_start_time = Missiontime;
@@ -10905,8 +10685,6 @@ void ai_dock()
// model_anim_start_type(shipp, TRIGGER_TYPE_DOCKED, aip->dockee_index, 1);
// model_anim_start_type(shipp, TRIGGER_TYPE_DOCKED, 1);
snd_play_3d( &Snds[SND_DOCK_ATTACH], &Pl_objp->pos, &View_position );
hud_maybe_flash_docking_text(Pl_objp);
hud_maybe_flash_docking_text(goal_objp);
// ai_dock_shake(Pl_objp, goal_objp);
if ((Pl_objp == Player_obj) || (goal_objp == Player_obj))
@@ -12459,7 +12237,7 @@ void ai_manage_shield(object *objp, ai_info *aip)
// set timestamp
aip->shield_manage_timestamp = timestamp((int) (delay * 1000.0f));
if (sip->flags & SIF_SMALL_SHIP) {
if (sip->flags & SIF_SMALL_SHIP || (aip->ai_profile_flags2 & AIPF2_ALL_SHIPS_MANAGE_SHIELDS)) {
if (Missiontime - aip->last_hit_time < F1_0*10)
ai_transfer_shield(objp, aip->last_hit_quadrant);
else
@@ -13518,6 +13296,8 @@ void ai_warp_out(object *objp)
// flag us as trying to warp so that this function keeps getting called
// (in other words, if we can't warp just yet, we want to warp at the first
// opportunity)
if (aip->mode != AIM_WARP_OUT)
aip->mode = AIM_WARP_OUT;
aip->submode = AIS_WARP_1;
aip->ai_flags |= AIF_TRYING_UNSUCCESSFULLY_TO_WARP;
@@ -15263,7 +15043,7 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_
objp_hitter = &Objects[hitter_objnum];
// lets not check hits by ghosts any further either
if(objp_hitter->type & OBJ_GHOST)
if(objp_hitter->type == OBJ_GHOST)
return;
// Hit by a protected ship, don't attack it.
+1 -1
View File
@@ -1008,7 +1008,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
* Pass -1 in priority to ignore priority when searching
* Returns -1 if not found, or [0, MAX_AI_GOALS)
*/
int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 )
int ai_find_goal_index( ai_goal* aigp, int mode, int submode, int priority )
{
Assert( aigp != NULL );
for ( int i = 0; i < MAX_AI_GOALS; i++ )
+24 -24
View File
@@ -26,35 +26,35 @@ struct ai_goal;
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
// to worry about doing this. Also add it to list in Fred\Management.cpp, and let Hoffoss know!
// WMC - Oh and add them to Ai_goal_names plz. TY! :)
#define AI_GOAL_CHASE (1<<1)
#define AI_GOAL_DOCK (1<<2) // used for undocking as well
#define AI_GOAL_WAYPOINTS (1<<3)
#define AI_GOAL_WAYPOINTS_ONCE (1<<4)
#define AI_GOAL_WARP (1<<5)
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6)
#define AI_GOAL_FORM_ON_WING (1<<7)
#define AI_GOAL_UNDOCK (1<<8)
#define AI_GOAL_CHASE_WING (1<<9)
#define AI_GOAL_GUARD (1<<10)
#define AI_GOAL_DISABLE_SHIP (1<<11)
#define AI_GOAL_DISARM_SHIP (1<<12)
#define AI_GOAL_CHASE_ANY (1<<13)
#define AI_GOAL_IGNORE (1<<14)
#define AI_GOAL_GUARD_WING (1<<15)
#define AI_GOAL_EVADE_SHIP (1<<16)
#define AI_GOAL_CHASE (1<<1) // 0x00000002
#define AI_GOAL_DOCK (1<<2) // 0x00000004 // used for undocking as well
#define AI_GOAL_WAYPOINTS (1<<3) // 0x00000008
#define AI_GOAL_WAYPOINTS_ONCE (1<<4) // 0x00000010
#define AI_GOAL_WARP (1<<5) // 0x00000020
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6) // 0x00000040
#define AI_GOAL_FORM_ON_WING (1<<7) // 0x00000080
#define AI_GOAL_UNDOCK (1<<8) // 0x00000100
#define AI_GOAL_CHASE_WING (1<<9) // 0x00000200
#define AI_GOAL_GUARD (1<<10) // 0x00000400
#define AI_GOAL_DISABLE_SHIP (1<<11) // 0x00000800
#define AI_GOAL_DISARM_SHIP (1<<12) // 0x00001000
#define AI_GOAL_CHASE_ANY (1<<13) // 0x00002000
#define AI_GOAL_IGNORE (1<<14) // 0x00004000
#define AI_GOAL_GUARD_WING (1<<15) // 0x00008000
#define AI_GOAL_EVADE_SHIP (1<<16) // 0x00010000
// the next goals are for support ships only
#define AI_GOAL_STAY_NEAR_SHIP (1<<17)
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18)
#define AI_GOAL_REARM_REPAIR (1<<19)
#define AI_GOAL_STAY_NEAR_SHIP (1<<17) // 0x00020000
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18) // 0x00040000
#define AI_GOAL_REARM_REPAIR (1<<19) // 0x00080000
// resume regular goals
#define AI_GOAL_STAY_STILL (1<<20)
#define AI_GOAL_PLAY_DEAD (1<<21)
#define AI_GOAL_CHASE_WEAPON (1<<22)
#define AI_GOAL_STAY_STILL (1<<20) // 0x00100000
#define AI_GOAL_PLAY_DEAD (1<<21) // 0x00200000
#define AI_GOAL_CHASE_WEAPON (1<<22) // 0x00400000
#define AI_GOAL_FLY_TO_SHIP (1<<23) // kazan
#define AI_GOAL_IGNORE_NEW (1<<24) // Goober5000
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
// now the masks for ship types
+169 -14
View File
@@ -100,6 +100,101 @@ int object_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos
return 0;
}
bool is_object_radius_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, vec3d *v2e, vec3d *predicted_pos, float distance)
{
float target_dist = distance;
if (distance == 0.0f)
target_dist = vm_vec_dist(predicted_pos,tpos);
if (object_in_turret_fov(objp, ss, tvec, tpos, target_dist + objp->radius)) {
// so the targeted spot in not in fov but the enemy + radius is
// lets align the darn gun and try shooting there
vec3d temp_vec;
float multiplier = 0;
model_subsystem *tp = ss->system_info;
// project v2e_from_turret to turret normal
// substract resultant vector from the temp_vec (v2e_from_turret)
// adjust z component as necessary
// calculate multiplier for the resultant vector
// use multiplier and the z component and compose a new vector
float dot = vm_vec_dot(v2e, tvec);
vm_vec_scale_add(&temp_vec, v2e, tvec, -dot);
if (IS_VEC_NULL_SQ_SAFE(&temp_vec)) {
// return false, target is perfectly aligned over or below the turret
// safe bet is to allow turret to reacquire better target
return false;
}
// normalize the vec, it needs to be done regardless
vm_vec_normalize(&temp_vec);
bool fix_elevation = false;
bool fix_base_rot = false;
if (dot < tp->turret_fov) {
dot = tp->turret_fov;
fix_elevation = true;
}
if (dot > tp->turret_max_fov) {
dot = tp->turret_max_fov;
fix_elevation = true;
}
if (tp->flags & MSS_FLAG_TURRET_ALT_MATH) {
vec3d temp_vec2;
vm_vec_rotate(&temp_vec2, &temp_vec, &ss->world_to_turret_matrix);
// now in turrets frame of reference
// check if math is actually possible
if (!((temp_vec2.xyz.x == 0) && (temp_vec2.xyz.y == 0))) {
float temp_z = temp_vec2.xyz.z;
temp_vec2.xyz.z = 0.0f;
// make sure null vecs wont happen
if (!IS_VEC_NULL_SQ_SAFE(&temp_vec2)) {
vm_vec_normalize(&temp_vec2);
// only do this if it actually is required
if (-temp_vec2.xyz.y < tp->turret_y_fov) {
float check_pos = 1;
fix_base_rot = true;
temp_vec2.xyz.y = -tp->turret_y_fov;
if (temp_vec2.xyz.x < 0)
check_pos = -1;
temp_vec2.xyz.x = check_pos * sqrtf(1 - (temp_vec2.xyz.y*temp_vec2.xyz.y));
// restore z component
float scaler = sqrtf(1 - (temp_z*temp_z));
vm_vec_scale(&temp_vec2,scaler);
temp_vec2.xyz.z = temp_z;
// back to world frame
vm_vec_unrotate(&temp_vec, &temp_vec2, &ss->world_to_turret_matrix);
}
}
}
}
if (fix_elevation || fix_base_rot) {
if (fix_elevation) {
multiplier = sqrtf(1 - (dot*dot));
// keep the temp_vec scaled with the tweaked vector
vm_vec_scale(&temp_vec, multiplier);
}
vm_vec_scale_add(v2e, &temp_vec, tvec, dot);
// and we are done with v2e...
vm_vec_scale_add(predicted_pos, tpos, v2e, target_dist);
// and we are done with predicted position
return true;
} else {
mprintf(("Warning: Function 'is_object_radius_in_turret_fov' was called\nwithout need to fix turret alignments\n"));
return false;
}
}
// outside of the expanded radii, unable to align, return false
return false;
}
// return 1 if bomb_objp is headed towards ship_objp
int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
{
@@ -357,9 +452,10 @@ extern int Player_attacking_enabled;
void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
{
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
ship *shipp;
ship *shipp;
ship_subsys *ss = eeo->turret_subsys;
float dist, dist_comp;
bool turret_has_no_target = false;
// Don't look for bombs when weapon system is not ok
if (objp->type == OBJ_WEAPON && !eeo->weapon_system_ok) {
@@ -476,7 +572,10 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
if ((objp->type == OBJ_WEAPON) && check_weapon) {
if ( Weapons[objp->instance].homing_object == &Objects[eeo->turret_parent_objnum] ) {
if ( dist_comp < eeo->nearest_homing_bomb_dist ) {
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
turret_has_no_target = true;
}
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
eeo->nearest_homing_bomb_dist = dist_comp;
eeo->nearest_homing_bomb_objnum = OBJ_INDEX(objp);
}
@@ -484,7 +583,10 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
// if not homing, check if bomb is flying towards ship
} else if ( bomb_headed_towards_ship(objp, &Objects[eeo->turret_parent_objnum]) ) {
if ( dist_comp < eeo->nearest_bomb_dist ) {
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
turret_has_no_target = true;
}
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
eeo->nearest_bomb_dist = dist_comp;
eeo->nearest_bomb_objnum = OBJ_INDEX(objp);
}
@@ -540,7 +642,10 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
// maybe update nearest attacker
if ( dist_comp < eeo->nearest_attacker_dist ) {
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
turret_has_no_target = true;
}
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
// nprintf(("AI", "Nearest enemy = %s, dist = %7.3f, dot = %6.3f, fov = %6.3f\n", Ships[objp->instance].ship_name, dist, vm_vec_dot(&v2e, tvec), tp->turret_fov));
eeo->nearest_attacker_dist = dist_comp;
eeo->nearest_attacker_objnum = OBJ_INDEX(objp);
@@ -555,7 +660,10 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
dist_comp *= 0.9f + (0.01f * asteroid_time_to_impact(objp));
if (dist_comp < eeo->nearest_dist ) {
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
turret_has_no_target = true;
}
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
eeo->nearest_dist = dist_comp;
eeo->nearest_objnum = OBJ_INDEX(objp);
}
@@ -945,7 +1053,13 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
dist = vm_vec_normalized_dir(&v2e, &Objects[aip->target_objnum].pos, tpos);
in_fov = turret_fov_test(turret_subsys, tvec, &v2e);
// MODIFY FOR ATTACKING BIG SHIP
if (turret_subsys->flags & SSF_FOV_EDGE_CHECK) {
if (in_fov == false)
if (object_in_turret_fov(&Objects[aip->target_objnum], turret_subsys, tvec, tpos, dist + Objects[aip->target_objnum].radius))
in_fov = true;
}
// MODIFY FOR ATTACKING BIG SHIP
// dot += (0.5f * Objects[aip->target_objnum].radius / dist);
if (in_fov) {
return aip->target_objnum;
@@ -1106,6 +1220,11 @@ int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object
in_fov = turret_fov_test(ss, gvec, &v2e);
if (ss->flags & SSF_FOV_EDGE_CHECK) {
if (in_fov == false)
in_fov = is_object_radius_in_turret_fov(&Objects[ss->turret_enemy_objnum], ss, gvec, &gun_pos, &v2e, predicted_enemy_pos, 0.0f);
}
if (in_fov) {
ret_val = model_rotate_gun(Ship_info[shipp->ship_info_index].model_num,
tp, &Objects[parent_objnum].orient,
@@ -1381,6 +1500,9 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
wait *= frand_range(0.9f, 1.1f);
}
if(turret->rof_scaler != 1.0f)
wait /= get_adjusted_turret_rof(turret);
(*fs_dest) = timestamp((int)wait);
}
@@ -1905,8 +2027,8 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
if(num_valid < 1)
ss->turret_enemy_objnum = -1;
// Maybe pick a new enemy.
if ( turret_should_pick_new_target(ss) ) {
// Maybe pick a new enemy, unless targeting has been taken over by scripting
if ( turret_should_pick_new_target(ss) && !ss->scripting_target_override) {
Num_find_turret_enemy++;
int objnum = find_turret_enemy(ss, parent_objnum, &gpos, &gvec, ss->turret_enemy_objnum);
//Assert(objnum < 0 || is_target_beam_valid(tp, objnum));
@@ -2141,6 +2263,12 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
turret_fire_weapon(valid_weapons[0], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
else
turret_fire_weapon(valid_weapons[i], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
} else {
// make sure salvo fire mode does not turn into autofire
if ((tp->flags & MSS_FLAG_TURRET_SALVO) && ((i + 1) == number_of_firings)) {
ai_info *parent_aip = &Ai_info[Ships[Objects[parent_objnum].instance].ai_index];
turret_set_next_fire_timestamp(valid_weapons[0], wip, ss, parent_aip);
}
}
// moved this here so we increment the fire pos only after we have fired and not during it
ss->turret_next_fire_pos++;
@@ -2200,7 +2328,7 @@ bool turret_std_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
{
model_subsystem *tp = ss->system_info;
float dot = vm_vec_dot(v2e, gvec);
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov))
if (((dot + size_mod) >= tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov))
return true;
return false;
@@ -2210,17 +2338,19 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
{
model_subsystem *tp = ss->system_info;
float dot = vm_vec_dot(v2e, gvec);
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
if (((dot + size_mod) >= tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
vec3d of_dst;
vm_vec_rotate( &of_dst, v2e, &ss->world_to_turret_matrix );
vm_vec_normalize(&of_dst);
if ((of_dst.xyz.x == 0) && (of_dst.xyz.y == 0)) {
return true;
} else {
of_dst.xyz.z = 0;
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
return true;
if (!IS_VEC_NULL_SQ_SAFE(&of_dst)) {
vm_vec_normalize(&of_dst);
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
if ((-of_dst.xyz.y + size_mod) >= tp->turret_y_fov)
return true;
}
}
}
return false;
@@ -2236,3 +2366,28 @@ bool turret_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
return in_fov;
}
float get_adjusted_turret_rof(ship_subsys *ss)
{
float tempf = ss->rof_scaler;
// optional reset switch (negative value)
if (tempf < 0) {
ss->rof_scaler = 1.0f;
return 1.0f;
}
if (tempf == 0) {
// special case returning the number of firingpoints
ss->rof_scaler = (float) ss->system_info->turret_num_firing_points;
tempf = ss->rof_scaler;
// safety check to avoid div/0 issues
if (tempf == 0) {
ss->rof_scaler = 1.0f;
return 1.0f;
}
}
return tempf;
}
+18 -6
View File
@@ -112,11 +112,13 @@ MONITOR(NumANIPlayed)
// Setup an anim_play_struct for passing into anim_play(). Will fill in default values, which you
// can then change before calling anim_play().
//
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y)
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int base_w, int base_h)
{
aps->anim_info = a_info;
aps->x = x;
aps->y = y;
aps->base_w = base_w;
aps->base_h = base_h;
aps->start_at = 0;
aps->stop_at = a_info->total_frames - 1;
aps->screen_id = 0;
@@ -219,6 +221,14 @@ anim_instance *anim_play(anim_play_struct *aps)
instance->xlate_pal = 0;
}
if(aps->base_w < 0 || aps->base_h < 0) {
instance->base_w = gr_screen.max_w_unscaled;
instance->base_h = gr_screen.max_h_unscaled;
} else {
instance->base_w = aps->base_w;
instance->base_h = aps->base_h;
}
// determining the start_at frame is more complicated, since it must be a key-frame.
// Futhermore, need to subtract 1 from key-frame number, since frame number is always
// incremented the first time anim_show_next_frame() is called
@@ -521,6 +531,8 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
// determine x,y to display the bitmap at
if ( instance->world_pos == NULL ) {
gr_set_screen_scale(instance->base_w, instance->base_h);
gr_set_clip(0, 0, instance->base_w, instance->base_h, false);
if ( instance->aa_color == NULL ) {
gr_bitmap(instance->x, instance->y);
}
@@ -528,6 +540,8 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
gr_set_color_fast( (color*)instance->aa_color );
gr_aabitmap(instance->x, instance->y);
}
gr_reset_screen_scale();
gr_reset_clip();
}
else {
g3_rotate_vertex(&image_vertex,instance->world_pos);
@@ -1085,11 +1099,9 @@ void anim_reverse_direction(anim_instance *ai)
{
int temp;
if(!(ai->parent->flags & ANF_ALL_KEYFRAMES)){
// you're not allowed to call anim_reverse_direction(...) unless every frame is a keyframe!!!!
// The God of Delta-RLE demands it be thus.
Int3();
}
// you're not allowed to call anim_reverse_direction(...) unless every frame is a keyframe!!!!
// The God of Delta-RLE demands it be thus.
Assertion( ai->parent->flags & ANF_ALL_KEYFRAMES, "Ani was set to play backwards. In order to enable this, all frames of the animation MUST be keyframes.");
// flip the animation direction
if(ai->direction == ANIM_DIRECT_FORWARD){
+3 -1
View File
@@ -24,6 +24,8 @@ typedef struct {
anim *anim_info;
int x;
int y;
int base_w;
int base_h;
int start_at;
int stop_at;
int screen_id;
@@ -50,7 +52,7 @@ void anim_level_init();
void anim_level_close();
void anim_render_all(int screen_id, float frametime);
void anim_render_one(int screen_id, anim_instance *ani, float frametime);
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y);
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int max_x = -1, int max_y = -1);
anim_instance *anim_play(anim_play_struct *aps);
void anim_ignore_next_frametime();
int anim_stop_playing(anim_instance* anim_instance);
+1 -149
View File
@@ -168,154 +168,6 @@ ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap
return inst->frame;
}
// --------------------------------------------------------------------
// anim_get_frame()
//
// Get a bitmap id from the anim_instance for the specified frame_num
//
// input: *inst => pointer to anim instance
// frame_num => frame number to get (first frame is 0)
// xlate_pal => DEFAULT PARM (value 1): whether to translate the palette
// to the current game palette
//
int anim_get_frame(anim_instance *inst, int frame_num, int xlate_pal)
{
/*
int bm, bitmap_flags, key = 0, offset = 0;
int idx;
if ((frame_num < 0) || (frame_num >= inst->parent->total_frames)) // illegal frame number
return -1;
int need_reset = 0;
if ( anim_instance_is_streamed(inst) ) {
if ( inst->file_offset < 0 ) {
need_reset = 1;
}
} else {
if ( !inst->data ) {
need_reset = 1;
}
}
if (need_reset || (inst->frame_num >= inst->parent->total_frames)) { // reset to valid info
inst->data = inst->parent->data;
inst->file_offset = inst->parent->file_offset;
inst->frame_num = 0;
}
bitmap_flags = 0;
if (inst->parent->flags & ANF_XPARENT) {
// bitmap_flags = BMP_XPARENT;
bitmap_flags = 0;
}
if ( inst->frame_num == frame_num ) {
bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
bm_unload(bm);
return bm;
}
if (inst->parent->flags & ANF_XPARENT){
// bitmap_flags = BMP_XPARENT;
bitmap_flags = 0;
} else {
bitmap_flags = 0;
}
idx = 0;
key = 0;
while(idx < inst->parent->num_keys){
if (( (inst->parent->keys[idx].frame_num-1) <= frame_num) && ( (inst->parent->keys[idx].frame_num-1) > key)) { // find closest key
key = inst->parent->keys[idx].frame_num - 1;
offset = inst->parent->keys[idx].offset;
if ( key == frame_num )
break;
}
idx++;
}
if ( key == frame_num ) {
inst->frame_num = key;
if ( anim_instance_is_streamed(inst) ) {
inst->file_offset = inst->parent->file_offset + offset;
} else {
inst->data = inst->parent->data + offset;
}
anim_check_for_palette_change(inst);
if ( anim_instance_is_streamed(inst) ) {
if ( xlate_pal ){
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
} else {
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
}
} else {
if ( xlate_pal ){
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
} else {
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
}
}
goto create_bitmap;
}
if (key > inst->frame_num) // best key is closer than current position
{
inst->frame_num = key;
if ( anim_instance_is_streamed(inst) ) {
inst->file_offset = inst->parent->file_offset + offset;
} else {
inst->data = inst->parent->data + offset;
}
anim_check_for_palette_change(inst);
if ( anim_instance_is_streamed(inst) ) {
if ( xlate_pal )
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
else
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
} else {
if ( xlate_pal )
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
else
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
}
}
while (inst->frame_num != frame_num) {
anim_check_for_palette_change(inst);
if ( anim_instance_is_streamed(inst) ) {
if ( xlate_pal )
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
else
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
} else {
if ( xlate_pal )
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
else
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
}
inst->frame_num++;
}
create_bitmap:
bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
bm_unload(bm);
return bm;
*/
Int3();
return -1;
}
// frame = frame pixel data to pack
// save = memory to store packed data to
// size = number of bytes to pack
@@ -1173,7 +1025,7 @@ int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal
}
}
else {
// Int3(); // unknown packing method
// unknown packing method
return -1;
}
+1 -1
View File
@@ -71,6 +71,7 @@ typedef struct anim {
typedef struct anim_instance {
anim_instance *next, *prev;
int x,y; // coordinates anim is played at (top left corner of anim)
int base_w, base_h; // coordinate scale this anim is played in.
vec3d *world_pos; // world (x,y,z) position of explosion
float radius; // radius of image, needed for scaling
int frame_num; // current frame, or last frame if between frames (first frame is 0)
@@ -106,7 +107,6 @@ void anim_init();
anim_instance *init_anim_instance(anim *ptr, int bpp);
void free_anim_instance(anim_instance *inst);
int anim_get_next_frame(anim_instance *inst);
int anim_get_frame(anim_instance *inst, int frame_num, int xlate_pal=1);
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp);
void anim_set_palette(anim *a);
void anim_check_for_palette_change(anim_instance *inst);
+4 -17
View File
@@ -1935,23 +1935,10 @@ void asteroid_show_brackets()
g3_rotate_vertex(&asteroid_vertex,&asteroid_objp->pos);
g3_project_vertex(&asteroid_vertex);
if (!(asteroid_vertex.flags & PF_OVERFLOW)) {
gr_set_color_fast(iff_get_color(IFF_COLOR_SELECTION, 1));
hud_show_brackets(asteroid_objp, &asteroid_vertex);
if ( Cmdline_targetinfo ) {
hud_show_lead_indicator_quick(&asteroid_objp->pos, asteroid_objp);
}
}
// if asteroid is not on screen, draw an offscreen indicator
if ( hud_gauge_active(HUD_OFFSCREEN_INDICATOR) ) {
if (asteroid_vertex.codes != 0) {
float dist;
// dist = vm_vec_dist_quick(&Player_obj->pos, &asteroid_objp->pos);
dist = hud_find_target_distance( asteroid_objp, Player_obj );
gr_set_color_fast(iff_get_color(IFF_COLOR_SELECTION, 1));
hud_draw_offscreen_indicator(&asteroid_vertex, &asteroid_objp->pos, dist);
}
if ( Cmdline_targetinfo ) {
hud_target_add_display_list(asteroid_objp, &asteroid_vertex, &asteroid_objp->pos, 0, NULL, NULL, TARGET_DISPLAY_DIST | TARGET_DISPLAY_LEAD);
} else {
hud_target_add_display_list(asteroid_objp, &asteroid_vertex, &asteroid_objp->pos, 0, NULL, NULL, TARGET_DISPLAY_DIST);
}
}
}
+199 -142
View File
@@ -39,6 +39,7 @@ extern int Cmdline_autopilot_interruptable;
// Module variables
bool AutoPilotEngaged;
bool UseCutsceneBars;
bool LockWeaponsDuringAutopilot;
int CurrentNav;
float ramp_bias;
NavPoint Navs[MAX_NAVPOINTS];
@@ -55,6 +56,9 @@ bool CinematicStarted, CameraMoving;
vec3d cameraPos, cameraTarget;
std::map<int,int> autopilot_wings;
int AutopilotMinEnemyDistance;
int AutopilotMinAsteroidDistance;
// used for ramping time compression;
int start_dist;
@@ -149,12 +153,7 @@ char* NavPoint::GetInteralName()
}
// ********************************************************************************************
// Tell us if autopilot is allowed
// This needs:
// * Nav point selected
// * No enemies within X distance
// * Destination > 1,000 meters away
bool CanAutopilot(bool send_msg)
bool CanAutopilot(vec3d targetPos, bool send_msg)
{
if (CurrentNav == -1)
{
@@ -162,99 +161,69 @@ bool CanAutopilot(bool send_msg)
send_autopilot_msgID(NP_MSG_FAIL_NOSEL);
return false;
}
if (object_get_gliding(Player_obj))
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_GLIDING);
return false;
}
// You cannot autopilot if you're within 1000 meters of your destination nav point
if (vm_vec_dist_quick(&Player_obj->pos, Navs[CurrentNav].GetPosition()) < 1000)
{
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_TOCLOSE);
return false;
}
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO))
if ( AutopilotMinEnemyDistance > 0 ) {
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
// Cannot autopilot if enemy within 5,000 meters
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < 5000)
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
return false;
// Cannot autopilot if enemy within AutopilotMinEnemyDistance meters
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < AutopilotMinEnemyDistance) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
return false;
}
}
}
}
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// asteroid
if (Asteroids[n].flags & AF_USED)
{
// Cannot autopilot if asteroid within 1,000 meters
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Asteroids[n].objnum].pos) < 1000)
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
return false;
}
}
}
return true;
}
// ********************************************************************************************
// Tell us if autopilot is allowed at a certain position (only performs checks based on that position)
// This needs:
// * Nav point selected
// * No enemies within X distance
// * Destination > 1,000 meters away
bool CanAutopilotPos(vec3d targetPos)
{
// You cannot autopilot if you're within 1000 meters of your destination nav point
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000)
return false;
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
{
// Cannot autopilot if enemy within 5,000 meters
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < 5000)
return false;
}
}
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// asteroid
if (Asteroids[n].flags & AF_USED)
if ( AutopilotMinAsteroidDistance > 0 ) {
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// Cannot autopilot if asteroid within 1,000 meters
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < 1000)
return false;
// asteroid
if (Asteroids[n].flags & AF_USED)
{
// Cannot autopilot if asteroid within AutopilotMinAsteroidDistance meters
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < AutopilotMinAsteroidDistance) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
return false;
}
}
}
}
// check for support ships
// cannot autopilot if support ship present
if ( ship_find_repair_ship(Player_obj) != NULL ) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_PRESENT);
return false;
}
return true;
}
extern object* Autopilot_flight_leader;
// ********************************************************************************************
// Engages autopilot
// This does:
@@ -263,13 +232,54 @@ bool CanAutopilotPos(vec3d targetPos)
// * Lock time compression -WMC
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
void StartAutopilot()
bool StartAutopilot()
{
// Check for support ship and dismiss it if it is not doing anything.
// If the support ship is doing something then tell the user such.
bool done = false;
while (!done) {
object* support_ship_op = ship_find_repair_ship(Player_obj);
if ( support_ship_op == NULL ) {
// no more
done = true;
break;
}
Assert( support_ship_op->type == OBJ_SHIP );
Assert( support_ship_op->instance >= 0 );
Assert( support_ship_op->instance < MAX_SHIPS );
Assert( Ships[support_ship_op->instance].ai_index != -1 );
ai_info* support_ship_aip = &(Ai_info[Ships[support_ship_op->instance].ai_index]);
// is support ship trying to rearm-repair
if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
// no, so tell it to depart
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
} else {
// yes
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
return false;
}
}
if (!CanAutopilot())
return;
return false;
AutoPilotEngaged = true;
// find the ship that is "leading" all of the ships when the player starts
// autopilot
// by default the ship that is leading the autopilot session the player's
// wing leader (if the player is the wing leader then it will be the
// player).
// TODO:implement a way to allow a FREDer to say a different ship is leader
Autopilot_flight_leader = get_wing_leader(Player_ship->wingnum);
if ( Autopilot_flight_leader == NULL ) {
// force player to be the leader if he doesn't have a wing
Autopilot_flight_leader = Player_obj;
}
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
LockAPConv = timestamp(); // lock convergence instantly
else
@@ -328,10 +338,20 @@ void StartAutopilot()
}
}
// damp speed_cap to 90% of actual -- to make sure ships stay in formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
speed_cap = 0.90f * speed_cap;
if ( speed_cap < 1.0f ) {
/* We need to deal with this so that incorrectly flagged ships will not
cause the engine to fail to limit all the ships speeds correctly. */
Warning(LOCATION, "Ship speed cap is way too small (%f)!\n"
"This is normally caused by a ship that has nav-carry-status set, but cannot move itself (like a Cargo container).\n"
"Speed cap has been set to 1.0 m/s.",
speed_cap);
speed_cap = 1.0f;
}
ramp_bias = speed_cap/50.0f;
// assign ship goals
@@ -397,10 +417,10 @@ void StartAutopilot()
vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
}
// snap wings into formation them into formation
// snap wings into formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS && // only if using cinematics
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY) // only if in a wing
&& Player_obj != &Objects[Ships[i].objnum]) //only if not player object
&& Autopilot_flight_leader != &Objects[Ships[i].objnum]) //only if not flight leader's object
{
ai_info *aip = &Ai_info[Ships[i].ai_index];
int wingnum = aip->wing, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
@@ -419,33 +439,34 @@ void StartAutopilot()
switch (wcount % 2)
{
case 1: // back-left
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
vm_vec_normalize(&perp);
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
default: //back-right
case 0:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
vm_vec_normalize(&perp);
vm_vec_scale(&perp, 166.0f*j);
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
}
autopilot_wings[wingnum] = wcount;
wcount++;
}
Objects[Ships[i].objnum].pos = goal_point;
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
{
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
}
}
// lock primary and secondary weapons
//Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
if ( LockWeaponsDuringAutopilot )
Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
// clear the ship goals and cap the waypoint speed
ai_clear_ship_goals(&Ai_info[Ships[i].ai_index]);
@@ -540,9 +561,9 @@ void StartAutopilot()
vec3d right, front, up, offset;
for (i = 0; i < (int)capIndexes.size(); i++)
{
vm_vec_add(&right, &Player_obj->orient.vec.rvec, &zero);
vm_vec_add(&front, &Player_obj->orient.vec.fvec, &zero);
vm_vec_add(&up, &Player_obj->orient.vec.uvec, &zero);
vm_vec_add(&right, &Autopilot_flight_leader->orient.vec.rvec, &zero);
vm_vec_add(&front, &Autopilot_flight_leader->orient.vec.fvec, &zero);
vm_vec_add(&up, &Autopilot_flight_leader->orient.vec.uvec, &zero);
vm_vec_add(&offset, &zero, &zero);
if (Ship_info[Ships[capIndexes[i]].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
{
@@ -610,7 +631,7 @@ void StartAutopilot()
vm_vec_scale(&up, (1+((float)floor((float)capship_placed[1]/3))));
// move ourselves up and out of the way of the smaller ships
vm_vec_add(&perp, &Player_obj->orient.vec.uvec, &zero);
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.uvec, &zero);
vm_vec_scale(&perp, capship_spreads[2]);
vm_vec_add(&up, &up, &perp);
@@ -665,7 +686,7 @@ void StartAutopilot()
vm_vec_scale(&front, 2*(1+((float)floor((float)capship_placed[2]/3))));
// move "out" by 166*(wcount-1) so we don't bump into fighters
vm_vec_add(&perp, &Player_obj->orient.vec.rvec, &zero);
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.rvec, &zero);
vm_vec_scale(&perp, 166.0f*float(wcount-1));
if ( (capship_placed[2] % 2) == 0)
vm_vec_add(&right, &right, &perp);
@@ -687,16 +708,16 @@ void StartAutopilot()
// global scale the position by 50%
//vm_vec_scale(&offset, 1.5);
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Player_obj->pos, &offset);
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Autopilot_flight_leader->pos, &offset);
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
{
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
}
}
}
ftemp = floor(Player_obj->phys_info.max_vel.xyz.z/speed_cap);
ftemp = floor(Autopilot_flight_leader->phys_info.max_vel.xyz.z/speed_cap);
if (ftemp >= 2.0f && ftemp < 4.0f)
tc_factor = 2;
else if (ftemp >= 4.0f && ftemp < 8.0f)
@@ -708,11 +729,11 @@ void StartAutopilot()
tpos = *Navs[CurrentNav].GetPosition();
// determine distance toward nav at which camera will be
vm_vec_sub(&pos, &tpos, &Player_obj->pos);
vm_vec_sub(&pos, &tpos, &Autopilot_flight_leader->pos);
vm_vec_normalize(&pos); // pos is now a unit vector in the direction we will be moving the camera
//norm1 = pos;
vm_vec_scale(&pos, 5*speed_cap*tc_factor); // pos is now scaled by 5 times the speed (5 seconds ahead)
vm_vec_add(&pos, &pos, &Player_obj->pos); // pos is now 5*speed cap in front of player ship
vm_vec_add(&pos, &pos, &Autopilot_flight_leader->pos); // pos is now 5*speed cap in front of player ship
switch (myrand()%24)
// 8 different ways of getting perp points
@@ -723,74 +744,74 @@ void StartAutopilot()
case 9:
case 16:
if (capship_placed[0] == 0)
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
else
{ // become up-left
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
}
break;
case 2: // up
case 10:
case 23:
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
if (capshipPresent) // become up-right
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
break;
case 3: // left
case 11:
case 22:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
break;
case 4: // up-left
case 12:
case 21:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 5: // up-right
case 13:
case 20:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 6: // down-left
case 14:
case 19:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
if (capship_placed[0] < 2)
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
else
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 7: // down-right
case 15:
case 18:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
if (capship_placed[0] < 1)
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
else
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
default:
case 0: // right
case 8:
case 17:
perp = Player_obj->orient.vec.rvec;
perp = Autopilot_flight_leader->orient.vec.rvec;
break;
}
vm_vec_normalize(&perp);
//vm_vec_scale(&perp, 2*radius+distance);
vm_vec_scale(&perp, Player_obj->radius+radius);
vm_vec_scale(&perp, Autopilot_flight_leader->radius+radius);
// randomly scale up/down by up to 20%
j = 20-myrand()%40; // [-20,20]
@@ -830,16 +851,8 @@ void StartAutopilot()
camMovingTime = int(4.5*float(tc_factor));
set_time_compression((float)tc_factor);
}
}
// ********************************************************************************************
// Checks if autopilot should automatically die
// Returns true if:
// * Targetted waypoint < 10,000 meters away
// * Enemy < 10,000 meters
bool Autopilot_AutoDiable()
{
return !CanAutopilot();
return true;
}
// ********************************************************************************************
@@ -852,6 +865,8 @@ void EndAutoPilot()
{
AutoPilotEngaged = false;
Autopilot_flight_leader = NULL;
set_time_compression(1);
lock_time_compression(false);
Player_use_ai = 0;
@@ -899,8 +914,10 @@ void EndAutoPilot()
)
{
//unlock their weaponry
//Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
if ( LockWeaponsDuringAutopilot )
Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
Ai_info[Ships[i].ai_index].waypoint_speed_cap = -1; // uncap their speed
Ai_info[Ships[i].ai_index].mode = AIM_NONE; // make AI re-evaluate current ship mode
for (j = 0; j < MAX_AI_GOALS; j++)
{
@@ -975,34 +992,54 @@ camera* nav_get_set_camera()
void nav_warp(bool prewarp=false)
{
// ok... find our end distance - norm1 is still a unit vector in the direction from the player to the navpoint
vec3d targetPos, tpos=Player_obj->pos, pos;
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
/* ok... find our end distance - norm1 is still a unit vector in the
direction from the flight leader to the navpoint */
vec3d targetPos, tpos=Autopilot_flight_leader->pos, pos, velocity;
/* calculate a vector that we can use to make a path from the flight
leader's location to the nav point */
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Autopilot_flight_leader->pos);
vm_vec_normalize(&pos);
velocity = pos; // make a copy for later when we do setup veleocity vector
vm_vec_scale(&pos, 250.0f); // we move by increments of 250
while (CanAutopilotPos(tpos))
/* using the vector of the flight leaders's path, simulate moving the
flight along this path by checking the autopilot conditions as specific
intervals along the path*/
while (CanAutopilot(tpos))
{
vm_vec_add(&tpos, &tpos, &pos);
}
vm_vec_sub(&targetPos, &tpos, &Player_obj->pos); //targetPos is actually a projection in a the direction toward the nav
vm_vec_sub(&targetPos, &tpos, &Autopilot_flight_leader->pos);
/* targetPos is actually a vector that describes the exact 3D movement that
the flgith leader needs to execute to reach the location that the auto
pilot is to shut off */
// Check if we are actually just setting up for the cinimatic shot of the
// flight flying on autopilot. Only jump halfway. Also we also need to
// put the camera in the correct position to show the player this cinimatic
if (prewarp)
{
vm_vec_scale(&targetPos, 0.5);
vm_vec_add(&cameraPos, &cameraPos, &targetPos);
}
/* calcuate the speed that everyone is supposed to be going so that there
is no need for anyone to accelerate or decelerate (most obvious with
the player's fighter slowing down as it changes the camera pan speed). */
Assert( Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap > 0 );
vm_vec_scale(&velocity, (float)Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap);
// Find all ships that are supposed to autopilot with the player and move them
// to the cinimatic location or the final destination
for (int i = 0; i < MAX_SHIPS; i++)
{
if (Ships[i].objnum != -1 &&
(Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
)
)
if (Ships[i].objnum != -1
&& (Ships[i].flags2 & SF2_NAVPOINT_CARRY
|| (Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)))
{
vm_vec_add(&Objects[Ships[i].objnum].pos, &Objects[Ships[i].objnum].pos, &targetPos);
Objects[Ships[i].objnum].phys_info.vel = velocity;
}
}
@@ -1041,7 +1078,7 @@ void NavSystem_Do()
}
if (timestamp() >= EndAPCinematic || Autopilot_AutoDiable())
if (timestamp() >= EndAPCinematic || !CanAutopilot())
{
nav_warp();
EndAutoPilot();
@@ -1060,7 +1097,7 @@ void NavSystem_Do()
if(cam != NULL)
{
cam->set_position(&cameraPos);
cam->set_rotation_facing(&Player_obj->pos);
cam->set_rotation_facing(&Autopilot_flight_leader->pos);
}
CinematicStarted = true;
@@ -1068,7 +1105,7 @@ void NavSystem_Do()
}
else
{
if (Autopilot_AutoDiable())
if (!CanAutopilot())
EndAutoPilot();
}
@@ -1141,7 +1178,10 @@ void NavSystem_Do()
}
}
// autopilot linking
/* Link in any ships that need to be linked in when the player gets close
enough. Always done by the player because: "making sure the AI fighters
are where they're supposed to be at all times is like herding cats" -Woolie Wool
*/
for (int i = 0; i < MAX_SHIPS; i++)
{
if (Ships[i].objnum != -1 && Ships[i].flags2 & SF2_NAVPOINT_NEEDSLINK)
@@ -1191,7 +1231,7 @@ void send_autopilot_msg(char *msg, char *snd)
// send/play
if (audio_handle != -1)
{
audiostream_play(audio_handle, Master_event_music_volume, 0);
audiostream_play(audio_handle, (Master_event_music_volume * aav_music_volume), 0);
}
if (strlen(msg) != 0 && strcmp(msg, "none"))
@@ -1247,6 +1287,21 @@ void parse_autopilot_table(char *filename)
required_string("$Link Distance:");
stuff_int(&NavLinkDistance);
if (optional_string("$Interrupt autopilot if enemy within distance:"))
stuff_int(&AutopilotMinEnemyDistance);
else
AutopilotMinEnemyDistance = 5000;
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
stuff_int(&AutopilotMinAsteroidDistance);
else
AutopilotMinAsteroidDistance = 1000;
if (optional_string("$Lock Weapons During Autopilot:"))
stuff_boolean(&LockWeaponsDuringAutopilot);
else
LockWeaponsDuringAutopilot = false;
// optional no cutscene bars
if (optional_string("+No_Cutscene_Bars"))
UseCutsceneBars = false;
@@ -1255,7 +1310,9 @@ void parse_autopilot_table(char *filename)
Cmdline_autopilot_interruptable = 0;
// No Nav selected message
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:", "$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:" };
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
"$Support Present:", "$Support Working:" };
for (int i = 0; i < NP_NUM_MESSAGES; i++)
{
required_string(msg_tags[i]);
+17 -13
View File
@@ -8,6 +8,7 @@
#define _AUTOPILOT_H_
#include "globalincs/pstypes.h"
#include "object/object.h"
#include <map>
// milliseconds between updates
@@ -37,13 +38,15 @@ struct NavPoint
};
#define NP_NUM_MESSAGES 6
#define NP_MSG_FAIL_NOSEL 0
#define NP_MSG_FAIL_GLIDING 1
#define NP_MSG_FAIL_TOCLOSE 2
#define NP_MSG_FAIL_HOSTILES 3
#define NP_MSG_MISC_LINKED 4
#define NP_MSG_FAIL_HAZARD 5
#define NP_MSG_FAIL_SUPPORT_PRESENT 6
#define NP_MSG_FAIL_SUPPORT_WORKING 7
#define NP_NUM_MESSAGES 8
struct NavMessage
{
@@ -62,27 +65,28 @@ extern std::map<int,int> autopilot_wings;
bool Sel_NextNav();
// Tell us is autopilot is allow
// Tell us if autopilot is allowed
// This needs:
// * Nav point selected
// * No enemies within 5,000 meters
// * No enemies within AutopilotMinEnemyDistance meters
// * No asteroids within AutopilotMinAsteroidDistance meters
// * Destination > 1,000 meters away
bool CanAutopilot(bool send_msg=false);
bool CanAutopilotPos(vec3d targetPos);
// * Support ship not present or is actively leaving
bool CanAutopilot(vec3d targetPos, bool send_msg=false);
// Check if autopilot is allowed at player's current position
// See CanAutopilot(vec3d, bool) for more information
inline bool CanAutopilot(bool send_msg=false) { return CanAutopilot(Player_obj->pos, send_msg); }
// Engages autopilot
// This does:
// * Checks if Autopilot is allowed. See CanAutopilot() for conditions.
// * Control switched from player to AI
// * Time compression to 32x
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
void StartAutopilot();
// Checks if autopilot should automatically die
// Returns true if:
// * Targetted waypoint < 1,000 meters away
// * Enemy < 5,000 meters
bool Autopilot_AutoDiable();
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
// Returns false if autopilot cannot be started. True otherwise.
bool StartAutopilot();
// Disengages autopilot
// this does:
+5 -11
View File
@@ -534,7 +534,7 @@ int bm_load( char *real_filename )
}
if (free_slot < 0) {
Int3();
Assertion(free_slot < 0, "Could not find free BMPMAN slot for bitmap: %s", real_filename);
goto Done;
}
@@ -1046,7 +1046,7 @@ int bm_get_info( int handle, int *w, int * h, ubyte * flags, int *nframes, int *
}
#endif
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE!
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_info().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
if ( (bm_bitmaps[bitmapnum].type == BM_TYPE_NONE) || (bm_bitmaps[bitmapnum].handle != handle) ) {
if (w) *w = 0;
@@ -1089,7 +1089,7 @@ unsigned int bm_get_signature(int handle)
if ( !bm_inited ) bm_init();
int bitmapnum = handle % MAX_BITMAPS;
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_signature().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
return bm_bitmaps[bitmapnum].signature;
}
@@ -1100,7 +1100,7 @@ ubyte bm_get_type(int handle)
if ( !bm_inited ) bm_init();
int bitmapnum = handle % MAX_BITMAPS;
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid bitmap handle %d passed to bm_get_type().\nThis might be due to an invalid animation somewhere else.\n", handle ); // INVALID BITMAP HANDLE!
return bm_bitmaps[bitmapnum].type;
}
@@ -1597,13 +1597,7 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
int bitmapnum = handle % MAX_BITMAPS;
#ifndef NDEBUG
if(bm_bitmaps[bitmapnum].handle != handle) {
mprintf(("bm_lock - %s: bm_bitmaps[%d].handle = %d, handle = %d\n", bm_bitmaps[bitmapnum].filename, bitmapnum, bm_bitmaps[bitmapnum].handle, handle));
}
#endif
Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid handle %d passed to bm_lock. This might be due to an animation elsewhere in the code being too short.\n", handle ); // INVALID BITMAP HANDLE
// flags &= (~BMP_RLE);
+8 -50
View File
@@ -78,7 +78,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .png .dds", CF_TYPE_PLAYERS },
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css", CF_TYPE_PLAYERS },
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr", CF_TYPE_PLAYERS },
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .ibx .tsb", CF_TYPE_DATA }, //clr=cached color
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .bx", CF_TYPE_DATA }, //clr=cached color
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .png .dds .fs2 .txt", CF_TYPE_DATA },
{ CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA },
{ CF_TYPE_CONFIG, "data" DIR_SEPARATOR_STR "config", ".cfg", CF_TYPE_DATA },
@@ -147,9 +147,14 @@ int cfile_in_root_dir(char *exe_path)
token_count++;
tok = strtok(NULL, DIR_SEPARATOR_STR);
} while(tok != NULL);
// root directory if we have <= 1 slash
#ifdef SCP_UNIX
// /freespace works, / does not
if(token_count <= 1) {
#else
// C:/freespace works, C:/ does not
if(token_count <= 2){
#endif
return 1;
}
@@ -813,53 +818,6 @@ CFILE *cfopen_special(char *file_path, char *mode, const int size, const int off
// it's a normal file
return cf_open_fill_cfblock(fp, dir_type);
}
/* char longname[_MAX_PATH];
if ( !cfile_inited ) {
Int3();
return NULL;
}
//================================================
// Check that all the parameters make sense
Assert( file_path && strlen(file_path) );
Assert( mode != NULL );
if ( (ext_num <= 0) || (!ext_list) ) {
Int3();
return NULL;
}
// cfopen_ext() only supports reading files, not creating them
if ( strchr(mode, 'w') ) {
Int3();
return NULL;
}
//================================================
// Search for file on disk, on cdrom, or in a packfile
int offset, size;
char copy_file_path[MAX_PATH_LEN]; // FIX change in memory from cf_find_file_location
strcpy_s(copy_file_path, file_path);
if ( cf_find_file_location_ext(copy_file_path, ext_num, ext_list, dir_type, sizeof(longname) - 1, longname, &size, &offset, localize) ) {
// Fount it, now create a cfile out of it
FILE *fp = fopen( longname, "rb" );
if ( fp ) {
if ( offset ) {
// Found it in a pack file
return cf_open_packed_cfblock(fp, dir_type, offset, size );
} else {
// Found it in a normal file
return cf_open_fill_cfblock(fp, dir_type);
}
}
}
return NULL;*/
}
+28 -31
View File
@@ -79,6 +79,8 @@ enum
#define BUILD_CAP_NO_D3D (1<<1)
#define BUILD_CAP_NEW_SND (1<<2)
#define PARSE_COMMAND_LINE_STRING "-parse_cmdline_only"
typedef struct
{
// DO NOT CHANGE THE SIZE OF THIS STRING!
@@ -136,8 +138,6 @@ Flag exe_params[] =
{ "-3dwarp", "Enable 3d warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
{ "-tbp", "Toggle features for The Babylon Project", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tbp", }, // TBP warp effects -Et1
{ "-wcsaga", "Toggle features for Wing Commander Saga", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-wcsaga", },
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
{ "-nosound", "Disable sound and music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
@@ -166,6 +166,7 @@ Flag exe_params[] =
{ "-no_glsl", "Disable GLSL (shader) support", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-ati_swap", "Fix Color issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-disable_glsl_model","Don't use shaders for model rendering", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-ingame_join", "Allows ingame joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
{ "-voicer", "Voice recognition", true, 0, EASY_DEFAULT, "Experimental", "", },
@@ -175,7 +176,7 @@ Flag exe_params[] =
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-timerbar", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-timerbar", },
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
@@ -252,7 +253,6 @@ cmdline_parm spec_point_arg("-spec_point", NULL);
cmdline_parm spec_tube_arg("-spec_tube", NULL);
cmdline_parm ambient_factor_arg("-ambient_factor", NULL); // Cmdline_ambient_factor
cmdline_parm cell_arg("-cell", NULL); // Cmdline_cell
cmdline_parm decals("-decals", NULL); // Cmdline_decals
cmdline_parm env("-env", NULL); // Cmdline_env
cmdline_parm mipmap_arg("-mipmap", NULL); // Cmdline_mipmap
cmdline_parm missile_lighting_arg("-missile_lighting", NULL); // Cmdline_missile_lighting
@@ -272,7 +272,6 @@ float Cmdline_fov = 0.75f;
float Cmdline_ogl_spec = 80.0f;
int Cmdline_ambient_factor = 128;
int Cmdline_cell = 0;
int Cmdline_decals = 0;
int Cmdline_env = 0;
int Cmdline_mipmap = 0;
int Cmdline_missile_lighting = 0;
@@ -335,10 +334,8 @@ int Cmdline_voice_recognition = 0;
// MOD related
cmdline_parm mod_arg("-mod", NULL, true); // Cmdline_mod -- DTP modsupport
cmdline_parm tbp("-tbp", NULL); // Cmdline_tbp -- TBP warp effects -Et1
char *Cmdline_mod = NULL; //DTP for mod arguement
int Cmdline_tbp = 0;
// Multiplayer/Network related
cmdline_parm almission_arg("-almission", NULL); // Cmdline_almission -- DTP for autoload Multi mission
@@ -368,6 +365,7 @@ cmdline_parm no_fbo_arg("-disable_fbo", NULL); // Cmdline_no_fbo
cmdline_parm noglsl_arg("-no_glsl", NULL); // Cmdline_noglsl -- disable GLSL support in OpenGL
cmdline_parm atiswap_arg("-ati_swap", NULL); // Cmdline_atiswap - Fix ATI color swap issue for screenshots.
cmdline_parm no3dsound_arg("-no_3d_sound", NULL); // Cmdline_no_3d_sound - Disable use of full 3D sounds
cmdline_parm no_glsl_models_arg("-disable_glsl_model", NULL); // Cmdline_no_glsl_model_rendering -- switches model rendering to fixed pipeline
int Cmdline_d3d_lesstmem = 0;
int Cmdline_load_all_weapons = 0;
@@ -381,6 +379,7 @@ int Cmdline_no_fbo = 0;
int Cmdline_noglsl = 0;
int Cmdline_ati_color_swap = 0;
int Cmdline_no_3d_sound = 0;
int Cmdline_no_glsl_model_rendering = 0;
// Developer/Testing related
cmdline_parm start_mission_arg("-start_mission", NULL); // Cmdline_start_mission
@@ -400,6 +399,7 @@ cmdline_parm window_arg("-window", NULL); // Cmdline_window
cmdline_parm fullscreen_window_arg("-fullscreen_window",NULL);
cmdline_parm res_arg("-res", NULL); // Cmdline_lores
cmdline_parm verify_vps_arg("-verify_vps", NULL); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, NULL);
#ifdef SCP_UNIX
cmdline_parm no_grab("-nograb", NULL); // Cmdline_no_grab
#endif
@@ -608,8 +608,8 @@ void os_validate_parms(char *cmdline)
char *token;
int parm_found;
token = strtok(cmdline, seps);
while(token != NULL) {
token = strtok(cmdline, seps);
while(token != NULL) {
if (token[0] == '-') {
parm_found = 0;
@@ -682,6 +682,12 @@ void os_init_cmdline(char *cmdline)
{
FILE *fp;
bool parse_config = true;
if (strstr(cmdline, PARSE_COMMAND_LINE_STRING) != NULL) {
parse_config = false;
}
// read the cmdline.cfg file from the data folder, and pass the command line arguments to
// the the parse_parms and validate_parms line. Read these first so anything actually on
// the command line will take precedence
@@ -706,7 +712,7 @@ void os_init_cmdline(char *cmdline)
#endif
// if the file exists, get a single line, and deal with it
if ( fp ) {
if ( fp && parse_config ) {
char *buf, *p;
size_t len = filelength( fileno(fp) ) + 2;
@@ -920,7 +926,9 @@ bool SetCmdlineParams()
}
if (timerbar_arg.found()) {
Cmdline_timerbar = 1;
#ifdef WIN32
MessageBox(NULL, "the timerbar has been disabled in builds after August 31, 2010. Please remove the \"-timerbar\" command line from the launcher to prevent this message from appearing the the future.", "", MB_OK | MB_ICONINFORMATION);
#endif
}
if ( missioncrcspew_arg.found() ) {
@@ -941,9 +949,11 @@ bool SetCmdlineParams()
}
}
// is this a standalone server??
if (standalone_arg.found()) {
Is_standalone = 1;
if (!Fred_running) { //There is no standalone FRED
// is this a standalone server??
if (standalone_arg.found()) {
Is_standalone = 1;
}
}
// object update control
@@ -1182,16 +1192,6 @@ bool SetCmdlineParams()
Cmdline_orb_radar = 1;
}
// TBP warp effects -Et1
// Chief1983 - Add 3d shockwave, ship choice 3d and weapon choice 3d if TBP is checked
if( tbp.found() )
{
Cmdline_tbp = 1;
Cmdline_enable_3d_shockwave = 1;
Cmdline_ship_choice_3d = 1;
Cmdline_weapon_choice_3d = 1;
}
if ( use_3dwarp.found() ) {
Cmdline_3dwarp = 1;
}
@@ -1264,6 +1264,10 @@ bool SetCmdlineParams()
Cmdline_noglsl = 1;
}
if (no_glsl_models_arg.found() ) {
Cmdline_no_glsl_model_rendering = 1;
}
if ( img2dds_arg.found() )
Cmdline_img2dds = 1;
@@ -1360,13 +1364,6 @@ bool SetCmdlineParams()
Cmdline_env = 1;
}
if ( decals.found() ) {
#ifdef WIN32
MessageBox(NULL, "Decals have been disabled in builds after May 4, 2006. Please remove the \"-decals\" command line from the launcher to prevent this message from appearing the the future.", "", MB_OK | MB_ICONINFORMATION);
#endif
}
if ( ballistic_gauge.found() ) {
Cmdline_ballistic_gauge = 1;
}
+1 -3
View File
@@ -63,7 +63,6 @@ extern float static_point_factor;
extern float static_tube_factor;
extern int Cmdline_ambient_factor;
extern int Cmdline_cell;
extern int Cmdline_decals;
extern int Cmdline_env;
extern int Cmdline_mipmap;
extern int Cmdline_missile_lighting;
@@ -104,8 +103,6 @@ extern int Cmdline_voice_recognition;
// MOD related
extern char *Cmdline_mod; // DTP for mod support
extern int Cmdline_tbp;
// Multiplayer/Network related
extern char *Cmdline_almission; // DTP for autoload mission (for multi only)
extern int Cmdline_ingamejoin;
@@ -127,6 +124,7 @@ extern int Cmdline_no_fbo;
extern int Cmdline_noglsl;
extern int Cmdline_ati_color_swap;
extern int Cmdline_no_3d_sound;
extern int Cmdline_no_glsl_model_rendering;
// Developer/Testing related
extern char *Cmdline_start_mission;
+6 -11
View File
@@ -167,7 +167,6 @@ void cutscene_mark_viewable(char *filename)
#define PLAY_BUTTON 6
#define EXIT_BUTTON 7
static int Num_files;
static SCP_vector<int> Cutscene_list;
//static int Stats_scroll_offset; // not used - taylor
static int Selected_line = 0; // line that is currently selected for binding
@@ -331,7 +330,7 @@ void cutscenes_screen_play()
char name[MAX_FILENAME_LEN]; // *full_name
int which_cutscene;
Assert( (Selected_line >= 0) && (Selected_line < Num_files) );
Assert( (Selected_line >= 0) && (Selected_line < (int)Cutscene_list.size()) );
which_cutscene = Cutscene_list[Selected_line];
strcpy_s(name, Cutscenes[which_cutscene].filename );
@@ -372,7 +371,7 @@ void cutscenes_screen_scroll_line_down()
{
int h;
if (Selected_line < Num_files - 1) {
if (Selected_line < (int)Cutscene_list.size() - 1) {
Selected_line++;
gamesnd_play_iface(SND_SCROLL);
@@ -409,7 +408,7 @@ void cutscenes_screen_scroll_screen_down()
int h;
h = Cutscene_list_coords[gr_screen.res][3] / gr_get_font_height();
if (Scroll_offset + h < Num_files) {
if (Scroll_offset + h < (int)Cutscene_list.size()) {
Scroll_offset++;
if (Selected_line < Scroll_offset){
Selected_line = Scroll_offset;
@@ -507,12 +506,10 @@ void cutscenes_screen_init()
// if (All_movies_enabled)
// Cutscenes_viewable = 0xffffffff; // Cheat code enables all movies.
Num_files = 0;
Cutscene_list.clear();
for (size_t j = 0; j < Cutscenes.size(); j++ ) {
if ( Cutscenes_viewable & (1<<j) ) {
Cutscene_list.push_back((int)j);
Num_files++;
}
}
}
@@ -570,11 +567,9 @@ void cutscenes_screen_do_frame()
// the "show-all" hotkey
case KEY_CTRLED | KEY_SHIFTED | KEY_S:
{
Num_files = 0;
Cutscene_list.clear();
for (size_t t = 0; t < Cutscenes.size(); t++) {
Cutscene_list.push_back((int)t);
Num_files++;
}
break;
@@ -592,14 +587,14 @@ void cutscenes_screen_do_frame()
if (List_region.button_down()) {
List_region.get_mouse_pos(NULL, &y);
z = Scroll_offset + y / font_height;
if ((z >= 0) && (z < Num_files))
if ((z >= 0) && (z < (int)Cutscene_list.size()))
select_tease_line = z;
}
if (List_region.pressed()) {
List_region.get_mouse_pos(NULL, &y);
z = Scroll_offset + y / font_height;
if ((z >= 0) && (z < Num_files))
if ((z >= 0) && (z < (int)Cutscene_list.size()))
Selected_line = z;
}
@@ -624,7 +619,7 @@ void cutscenes_screen_do_frame()
y = 0;
z = Scroll_offset;
while (y + font_height <= Cutscene_list_coords[gr_screen.res][3]) {
if (z >= Num_files){
if (z >= (int)Cutscene_list.size()){
break;
}
+4 -2
View File
@@ -668,8 +668,10 @@ int mve_video_init(ubyte *data)
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
GL_state.Texture.SetWrapS(GL_CLAMP_TO_EDGE);
GL_state.Texture.SetWrapT(GL_CLAMP_TO_EDGE);
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB5_A1, wp2, hp2, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
+4 -2
View File
@@ -360,8 +360,10 @@ static void OGG_video_init(theora_info *tinfo)
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
GL_state.Texture.SetWrapS(GL_CLAMP_TO_EDGE);
GL_state.Texture.SetWrapT(GL_CLAMP_TO_EDGE);
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB8, wp2, hp2, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
+1 -1
View File
@@ -42,7 +42,7 @@ typedef struct debris {
vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
int arc_timestamp[MAX_DEBRIS_ARCS]; // When this times out, the spark goes away. -1 is not used
int arc_frequency; // Starts at 0, gets bigger
char parent_alt_name;
int parent_alt_name;
float damage_mult;
} debris;
File diff suppressed because it is too large. Load diff
-129
View File
@@ -1,129 +0,0 @@
//header file for making decals-Bobboau
#ifndef _DECAL_H
#define _DECAL_H
#include "object/object.h"
#include "globalincs/pstypes.h"
//#include "ship/ship.h"
#ifdef ENABLE_DECALS
#define MAX_DECAL_POLY 40
#define MAX_DECAL_POLY_POINT 10
#define MAX_DECAL_DEFPOINTS 10000
#define MAX_DECAL_POINT 10
#define MAX_SHIP_DECALS 25
#define MAX_GLOBAL_DECAL_POLYS 11000
#define QUICKFIND_SUBDIVISION 100
#define QUICKFIND_SEGMENT_LENGTH (MAX_GLOBAL_DECAL_POLYS/QUICKFIND_SUBDIVISION)
#define MAX_GLOBAL_DECALS 5000
#define DP_EOF 0
#define DP_DEFPOINTS 1
#define DP_FLATPOLY 2
#define DP_TMAPPOLY 3
#define DP_SORTNORM 4
#define DP_BOUNDBOX 5
#endif // ENABLE_DECALS
struct decal;
struct decal_list;
struct decal_list_controle;
struct decal_poly{
vec3d norm[3];
vertex point[3];
decal_poly *next;
decal* parent;
int idx;
};
struct decal{
int n_poly;
int timestamp; //when this decal was created
int burn_time; //how long it takes for the glow texture to fade
int vertex_buffer_start; //were is the start of this decal's polys in the vertex buffer
decal_poly* poly;
decal_poly* add_poly();
decal_poly* get_last_poly();
void remove_last_poly();
decal_list_controle *parent;
};
struct decal_list{
decal dec;
decal_list *next;
};
struct decal_item{
decal_list dec;
bool used;
};
struct decal_list_controle{
int n_decals;
int buffer;
int texture;
int n_poly;
int burn_texture;
int glow_texture;
bool modifyed;
decal_list *d_list;
decal_list *end;
decal_list *add_new();
void trim();
void clear();
~decal_list_controle();
decal_list_controle();
};
struct decal_system{
decal_list_controle *decals;
int n_decal_textures;
bool decals_modified;
int max_decals;
decal_system():decals(NULL),n_decal_textures(0),decals_modified(false){};
};
//this is used to give all the data to the generation data to the functions that make them
struct decal_point{
vec3d pnt;
matrix orient;
float radius;
};
#ifdef ENABLE_DECALS
int decal_create(object * obj, decal_point *point, int subobject, int texture, int backfaced_texture = -1, int glow_texture = -1, int burn_texture = -1, int burn_time = 1000);//makes the decal
int decal_create_simple(object * obj, decal_point *point, int texture);//makes a simple non-clipped decal
void decal_render_all(object * obj); //renders all decals
int decal_create_sub(void *model_ptr);
void clear_decals(decal_system *system);
void init_decals();
#else // ENABLE_DECALS
inline int decal_create(object * obj, decal_point *point, int subobject, int texture, int backfaced_texture = -1, int glow_texture = -1, int burn_texture = -1, int burn_time = 1000)
{
return 0;
}
#define decal_create_simple(a, b, c) (0)
#define decal_render_all(a)
#define decal_create_sub(a) (0);
#define clear_decals(a)
#define init_decals()
#endif // ENABLE_DECALS
#endif // _DECAL_H
+3 -1
View File
@@ -922,7 +922,9 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
}
if ( fb->fireball_render_type == FIREBALL_WARP_EFFECT ) {
Assert( warp_lifetime > 4.0f ); // Warp lifetime must be at least 4 seconds!
Assert( warp_lifetime >= 4.0f ); // Warp lifetime must be at least 4 seconds!
if ( warp_lifetime < 4.0f )
warp_lifetime = 4.0f;
fb->total_time = warp_lifetime; // in seconds
} else {
fb->total_time = i2fl(fl->num_frames) / fl->fps; // in seconds
-1
View File
@@ -14,7 +14,6 @@
#include "ship/ship.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -8,7 +8,6 @@
#include "gamesnd/eventmusic.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -16,7 +16,6 @@
#include "parse/sexp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -15,7 +15,6 @@
#include "mission/missiongrid.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -19,7 +19,6 @@
#include "species_defs/species_defs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -7,7 +7,6 @@
#include "ship/ship.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -26,7 +26,6 @@
#include "mission/missionparse.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -30,7 +30,6 @@
#include "localization/localize.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -23,7 +23,6 @@
#include "mission/missiongoals.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -19,7 +19,6 @@
#include "mission/missionparse.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -18,7 +18,6 @@
#include "mission/missionparse.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -22,7 +22,6 @@
#include "mission/missionparse.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -17,7 +17,6 @@
#include "localization/localize.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -20,7 +20,6 @@
#include "iff_defs/iff_defs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -7,7 +7,6 @@
#include "ship/ship.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -20,7 +20,6 @@
#include "localization/localize.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -14,7 +14,6 @@
#include "dialog1.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -27,7 +27,6 @@
#include "weapon/weapon.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+11 -9
View File
@@ -22,7 +22,6 @@
#include "localization/localize.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -82,15 +81,17 @@ void event_editor::DoDataExchange(CDataExchange* pDX)
DDX_CBString(pDX, IDC_WAVE_FILENAME, m_wave_filename);
DDX_LBIndex(pDX, IDC_MESSAGE_LIST, m_cur_msg);
// m_team == -1 maps to 2
if(m_team == -1){
m_team = 2;
m_team = MAX_TVT_TEAMS;
}
DDX_CBIndex(pDX, IDC_EVENT_TEAM, m_team);
// m_message_team == -1 maps to 2
if(m_message_team == -1){
m_message_team = 2;
m_message_team = MAX_TVT_TEAMS;
}
DDX_CBIndex(pDX, IDC_MESSAGE_TEAM, m_message_team);
//}}AFX_DATA_MAP
@@ -570,7 +571,7 @@ void event_editor::update_cur_message()
m_persona = 0;
}
if(m_messages[m_cur_msg].multi_team >= 2){
if(m_messages[m_cur_msg].multi_team >= MAX_TVT_TEAMS){
m_message_team = -1;
m_messages[m_cur_msg].multi_team = -1;
} else {
@@ -715,6 +716,7 @@ void event_editor::reset_event(int num, HTREEITEM after)
m_events[num].chain_delay = -1;
m_events[num].objective_text = NULL;
m_events[num].objective_key_text = NULL;
m_events[num].team = -1;
m_sig[num] = -1;
m_event_tree.item_index = -1;
@@ -1174,7 +1176,7 @@ int event_editor::save_message(int num)
// box list.
m_messages[num].persona_index = m_persona - 1;
if(m_message_team >= 2){
if(m_message_team >= MAX_TVT_TEAMS){
m_messages[num].multi_team = -1;
m_message_team = -1;
} else {
@@ -1409,8 +1411,8 @@ void event_editor::OnSelchangeTeam()
UpdateData(TRUE);
// team == 2, means no team
if(m_team == 2){
// If the team isn't valid mark it as such.
if((m_team >= MAX_TVT_TEAMS) || (m_team < -1) ){
m_team = -1;
}
@@ -1426,8 +1428,8 @@ void event_editor::OnSelchangeMessageTeam()
UpdateData(TRUE);
// team == 2, means no team
if(m_message_team == 2){
// If the team isn't valid mark it as such.
if((m_message_team>= MAX_TVT_TEAMS) || (m_message_team < -1) ) {
m_message_team = -1;
}
+38 -4
View File
@@ -28,6 +28,8 @@
#include "debugconsole/dbugfile.h"
#include "globalincs/mspdb_callstack.h"
#include "AFXADV.H"
#ifdef NDEBUG
#ifndef FRED
#error macro FRED is not defined when trying to build release Fred. Please define FRED macro in build settings in all Fred projects
@@ -35,7 +37,6 @@
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -80,12 +81,12 @@ window_data Mission_notes_wnd_data;
BEGIN_MESSAGE_MAP(CFREDApp, CWinApp)
//{{AFX_MSG_MAP(CFREDApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
@@ -125,7 +126,7 @@ BOOL CFREDApp::InitInstance()
// disable the debug memory stuff
_CrtSetDbgFlag(~(_CRTDBG_ALLOC_MEM_DF) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
// _CrtSetDbgFlag(~(_CRTDBG_ALLOC_MEM_DF) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
// Standard initialization
// If you are not using these features and wish to reduce the size
@@ -236,9 +237,23 @@ BOOL CFREDApp::InitInstance()
*str_end = '\0';
// Goober5000 - figure out where the FRED file dialog should go
if ((m_pRecentFileList != NULL) && (m_pRecentFileList->GetSize() > 0))
{
// use the most recently opened file to supply the default folder
m_sInitialDir = m_pRecentFileList->operator[](0); // lol syntax
}
else
{
// use FRED's own directory to search for missions
m_sInitialDir = Fred_base_dir;
m_sInitialDir += "\\data\\missions";
}
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
ParseCommandLine(cmdInfo);
m_nCmdShow = Main_wnd_data.p.showCmd;
@@ -309,6 +324,25 @@ void CFREDApp::OnAppAbout()
aboutDlg.DoModal();
}
// G5K - from http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_20155824.html
void CFREDApp::OnFileOpen()
{
// use the initial dir the first time we prompt for a file
// name. after a successful open, the file name will be
// changed to be the empty string and the default dir
// will be supplied by the CFileDialog internal memory
if(!DoPromptFileName(m_sInitialDir, AFX_IDS_OPENFILE, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
{
// open cancelled
return;
}
AfxGetApp()->OpenDocumentFile(m_sInitialDir);
// if returns NULL, the user has already been alerted
// now erase the initial dir since we only want to use it once
m_sInitialDir.Empty();
}
/////////////////////////////////////////////////////////////////////////////
// CFREDApp commands
+2
View File
@@ -52,6 +52,7 @@ typedef struct window_data {
class CFREDApp : public CWinApp
{
int app_init;
CString m_sInitialDir;
public:
void record_window_data(window_data *wndd, CWnd *wnd);
@@ -75,6 +76,7 @@ public:
//{{AFX_MSG(CFREDApp)
afx_msg void OnAppAbout();
afx_msg void OnFileOpen();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
+9 -5
View File
@@ -2457,17 +2457,18 @@ BEGIN
WS_TABSTOP
LTEXT "Example",IDC_LBL_EXAMPLE,17,158,31,10
EDITTEXT IDC_EXAMPLE,49,156,77,12,ES_AUTOHSCROLL | ES_READONLY
CONTROL "Don't replace existing file names",IDC_NO_REPLACE,
CONTROL "Include sender name in filename",IDC_INCLUDE_SENDER,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,175,112,10
PUSHBUTTON "Generate File Names",IDC_GENERATE_FILE_NAMES,12,190,120,
14
CONTROL "Don't replace existing file names",IDC_NO_REPLACE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,186,112,10
PUSHBUTTON "Generate File Names",IDC_GENERATE_FILE_NAMES,12,198,120,14
GROUPBOX "Script Options",IDC_SCRIPT_OPTIONS,143,7,257,204
GROUPBOX "Script Entry Format",IDC_ENTRY,149,17,246,76
EDITTEXT IDC_ENTRY_FORMAT,154,28,109,56,ES_MULTILINE |
ES_AUTOHSCROLL | ES_WANTRETURN
LTEXT "$filename - name of the message file\r\n$message - text of the message\r\n$persona - persona of the sender\r\n$sender - name of the sender\r\n\r\nNote that $persona and $sender will only appear for the Message section.",
IDC_STATIC,270,28,120,58
GROUPBOX "Export",IDC_EXPORT,149,98,119,64
GROUPBOX "Export",IDC_EXPORT,149,98,119,83
CONTROL "Everything",IDC_EXPORT_EVERYTHING,"Button",
BS_AUTORADIOBUTTON,153,108,99,9
CONTROL "Just Command Briefings",IDC_EXPORT_COMMAND_BRIEFINGS,
@@ -2479,6 +2480,9 @@ BEGIN
CONTROL "Just Messages",IDC_EXPORT_MESSAGES,"Button",
BS_AUTORADIOBUTTON,153,148,99,9
PUSHBUTTON "Generate Script",IDC_GENERATE_SCRIPT,149,190,120,14
CONTROL "Group send-message-list messages before others",
IDC_GROUP_MESSAGES,"Button",BS_AUTOCHECKBOX | BS_TOP |
BS_MULTILINE | WS_TABSTOP,166,159,100,19
END
IDD_BRIEFING_PERSONAS DIALOG DISCARDABLE 0, 0, 320, 201
@@ -2559,7 +2563,7 @@ END
IDD_SOUND_ENVIRONMENT DIALOGEX 0, 0, 315, 89
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Sound Environment"
FONT 8, "MS Sans Serif"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
COMBOBOX IDC_SOUND_ENVIRONMENT,75,9,117,30,CBS_DROPDOWN |
WS_VSCROLL | WS_TABSTOP
+3 -4
View File
@@ -50,7 +50,6 @@
extern int Num_objects;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -427,7 +426,7 @@ int CFREDDoc::load_mission(char *pathname, int flags)
generate_weaponry_usage_list(i, used_pool);
for (j=0; j<Team_data[i].num_weapon_choices; j++) {
// The amount used in wings is always set by a static loadout entry so skip any that were set by Sexp variables
if ((Team_data[i].weaponry_pool_variable[j] == -1) && (Team_data[i].weaponry_amount_variable[j] == -1) ) {
if ( (!strlen(Team_data[i].weaponry_pool_variable[j])) && (!strlen(Team_data[i].weaponry_amount_variable[j])) ) {
// convert weaponry_pool to be extras available beyond the current ships weapons
Team_data[i].weaponry_count[j] -= used_pool[Team_data[i].weaponry_pool[j]];
if (Team_data[i].weaponry_count[j] < 0) {
@@ -446,8 +445,8 @@ int CFREDDoc::load_mission(char *pathname, int flags)
// add the weapon as a new entry
Team_data[i].weaponry_pool[Team_data[i].num_weapon_choices] = j;
Team_data[i].weaponry_count[Team_data[i].num_weapon_choices] = used_pool[j];
Team_data[i].weaponry_amount_variable[Team_data[i].num_weapon_choices] = -1;
Team_data[i].weaponry_pool_variable[Team_data[i].num_weapon_choices++] = -1;
strcpy_s(Team_data[i].weaponry_amount_variable[Team_data[i].num_weapon_choices], "");
strcpy_s(Team_data[i].weaponry_pool_variable[Team_data[i].num_weapon_choices++], "");
}
}
}
-1
View File
@@ -58,7 +58,6 @@ extern float flFrametime;
extern subsys_to_render Render_subsys;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -188,7 +188,6 @@ int Framerate_delay;
void game_start_time(){}
void game_stop_time(){}
int game_get_default_skill_level(){return 0;}
void game_load_palette(){}
float FreeSpace_gamma;
int set_cdrom_path(int){return 0;}
int find_freespace_cd(char*){return 0;}
-1
View File
@@ -65,7 +65,6 @@
#include "gl/glu.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -18,7 +18,6 @@
#include "editor.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -16,7 +16,6 @@
#include "globalincs/linklist.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -18,7 +18,6 @@
#include "weapon/weapon.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -19,7 +19,6 @@
#include "object/objectdock.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -26,7 +26,6 @@
#include "iff_defs/iff_defs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+4 -4
View File
@@ -999,9 +999,9 @@ void clear_mission()
for ( j = 0; j < MAX_SHIP_CLASSES; j++ ) {
if (Ship_info[j].flags & SIF_DEFAULT_PLAYER_SHIP) {
Team_data[i].ship_list[count] = j;
Team_data[i].ship_list_variables[count] = -1;
strcpy_s(Team_data[i].ship_list_variables[count], "");
Team_data[i].ship_count[count] = 5;
Team_data[i].ship_count_variables[count++] = -1;
strcpy_s(Team_data[i].ship_count_variables[count++], "");
}
}
Team_data[i].num_ship_choices = count;
@@ -1015,8 +1015,8 @@ void clear_mission()
Team_data[i].weaponry_count[count] = 500;
}
Team_data[i].weaponry_pool[count] = j;
Team_data[i].weaponry_pool_variable[count] = -1;
Team_data[i].weaponry_amount_variable[count++] = -1;
strcpy_s(Team_data[i].weaponry_pool_variable[count], "");
strcpy_s(Team_data[i].weaponry_amount_variable[count++], "");
}
}
Team_data[i].num_weapon_choices = count;
-1
View File
@@ -19,7 +19,6 @@
#include "mission/missionmessage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -25,7 +25,6 @@
#define ID_REPLACE_WINGS 15000
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -22,7 +22,6 @@
#include "mission/missionmessage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+18 -13
View File
@@ -1135,6 +1135,7 @@ int CFred_mission_save::save_variables()
int CFred_mission_save::save_players()
{
int i, j;
int var_idx;
int used_pool[MAX_WEAPON_TYPES];
// write out alternate name list
@@ -1179,20 +1180,22 @@ int CFred_mission_save::save_players()
for (j=0; j<Team_data[i].num_ship_choices; j++) {
// Check to see if a variable name should be written for the class rather than a number
if (Team_data[i].ship_list_variables[j] != -1) {
Assert (Team_data[i].ship_list_variables[j] > -1 && Team_data[i].ship_list_variables[j] < MAX_SEXP_VARIABLES);
if (strlen(Team_data[i].ship_list_variables[j])) {
var_idx = get_index_sexp_variable_name(Team_data[i].ship_list_variables[j]);
Assert (var_idx > -1 && var_idx < MAX_SEXP_VARIABLES);
fout("\t@%s\t", Sexp_variables[Team_data[i].ship_list_variables[j]].variable_name);
fout("\t@%s\t", Sexp_variables[var_idx].variable_name);
}
else {
fout("\t\"%s\"\t", Ship_info[Team_data[i].ship_list[j]].name);
}
// Now check if we should write a variable or a number for the amount of ships available
if (Team_data[i].ship_count_variables[j] != -1) {
Assert (Team_data[i].ship_count_variables[j] > -1 && Team_data[i].ship_count_variables[j] < MAX_SEXP_VARIABLES);
if (strlen(Team_data[i].ship_count_variables[j])) {
var_idx = get_index_sexp_variable_name(Team_data[i].ship_count_variables[j]);
Assert (var_idx > -1 && var_idx < MAX_SEXP_VARIABLES);
fout("@%s\n", Sexp_variables[Team_data[i].ship_count_variables[j]].variable_name);
fout("@%s\n", Sexp_variables[var_idx].variable_name);
}
else {
fout("%d\n", Team_data[i].ship_count[j]);
@@ -1211,10 +1214,11 @@ int CFred_mission_save::save_players()
generate_weaponry_usage_list(i, used_pool);
for (j=0; j<Team_data[i].num_weapon_choices; j++) {
// first output the weapon name or a variable that sets it
if (Team_data[i].weaponry_pool_variable[j] != -1) {
Assert (Team_data[i].weaponry_pool_variable[j] > -1 && Team_data[i].weaponry_pool_variable[j] < MAX_SEXP_VARIABLES);
if (strlen(Team_data[i].weaponry_pool_variable[j])) {
var_idx = get_index_sexp_variable_name(Team_data[i].weaponry_pool_variable[j]);
Assert (var_idx > -1 && var_idx < MAX_SEXP_VARIABLES);
fout("\t@%s\t", Sexp_variables[Team_data[i].weaponry_pool_variable[j]].variable_name);
fout("\t@%s\t", Sexp_variables[var_idx].variable_name);
}
else {
fout("\t\"%s\"\t", Weapon_info[Team_data[i].weaponry_pool[j]].name);
@@ -1223,13 +1227,14 @@ int CFred_mission_save::save_players()
// now output the amount of this weapon or a variable that sets it. If this weapon is in the used pool and isn't
// set by a variable we should add the amount of weapons used by the wings to it and zero the entry so we know
// that we have dealt with it
if (Team_data[i].weaponry_amount_variable[j] != -1) {
Assert (Team_data[i].weaponry_amount_variable[j] > -1 && Team_data[i].weaponry_amount_variable[j] < MAX_SEXP_VARIABLES);
if (strlen(Team_data[i].weaponry_amount_variable[j])) {
var_idx = get_index_sexp_variable_name(Team_data[i].weaponry_amount_variable[j]);
Assert (var_idx > -1 && var_idx < MAX_SEXP_VARIABLES);
fout ("@%s\n", Sexp_variables[Team_data[i].weaponry_amount_variable[j]].variable_name);
fout ("@%s\n", Sexp_variables[var_idx].variable_name);
}
else {
if (Team_data[i].weaponry_pool_variable[j] != -1) {
if (strlen(Team_data[i].weaponry_pool_variable[j])) {
fout ("%d\n", Team_data[i].weaponry_count[j]);
}
else {
-1
View File
@@ -16,7 +16,6 @@
#include "parse/sexp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -14,7 +14,6 @@
#include "OperatorArgTypeSelect.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -17,7 +17,6 @@
#include "FREDView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+46 -21
View File
@@ -19,7 +19,6 @@
#include "weapon/weapon.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -95,22 +94,32 @@ BOOL player_start_editor::OnInitDialog()
for(idx=0; idx<Team_data[i].num_ship_choices; idx++)
{
// do we have a variable for this entry? if we don't....
if (Team_data[i].ship_list_variables[idx] == -1)
if (!strlen(Team_data[i].ship_list_variables[idx]))
{
// This pool is set to hold the number of ships available at an index corresponding to the Ship_info array.
static_ship_pool[i][Team_data[i].ship_list[idx]] = Team_data[i].ship_count[idx];
// This pool is set to hold whether a ship at a Ship_info index has been set by a variable (and the
// variables index in Sexp_variables) if it has).
static_ship_variable_pool[i][Team_data[i].ship_list[idx]] = Team_data[i].ship_count_variables[idx];
if (strlen(Team_data[i].ship_count_variables[idx])) {
static_ship_variable_pool[i][Team_data[i].ship_list[idx]] = get_index_sexp_variable_name(Team_data[i].ship_count_variables[idx]);
}
else {
static_ship_variable_pool[i][Team_data[i].ship_list[idx]] = -1;
}
}
// if we do....
else
{
// This pool is set to hold the number of ships available at an index corresponding to the Sexp_variables array
dynamic_ship_pool[i][Team_data[i].ship_list_variables[idx]] = Team_data[i].ship_count[idx];
dynamic_ship_pool[i][get_index_sexp_variable_name(Team_data[i].ship_list_variables[idx])] = Team_data[i].ship_count[idx];
// This pool is set to hold whether a ship at a Ship_info index has been set by a variable (and the
// variables index in Sexp_variables) if it has).
dynamic_ship_variable_pool[i][Team_data[i].ship_list_variables[idx]] = Team_data[i].ship_count_variables[idx];
if (strlen(Team_data[i].ship_count_variables[idx])) {
dynamic_ship_variable_pool[i][get_index_sexp_variable_name(Team_data[i].ship_list_variables[idx])] = get_index_sexp_variable_name(Team_data[i].ship_count_variables[idx]);
}
else {
dynamic_ship_variable_pool[i][get_index_sexp_variable_name(Team_data[i].ship_list_variables[idx])] = -1;
}
}
}
}
@@ -125,16 +134,26 @@ BOOL player_start_editor::OnInitDialog()
for(idx=0; idx<Team_data[i].num_weapon_choices; idx++)
{
// do we have a variable for this entry?
if (Team_data[i].weaponry_pool_variable[idx] == -1)
if (!strlen(Team_data[i].weaponry_pool_variable[idx]))
{
static_weapon_pool[i][Team_data[i].weaponry_pool[idx]] = Team_data[i].weaponry_count[idx];
static_weapon_variable_pool[i][Team_data[i].weaponry_pool[idx]] = Team_data[i].weaponry_amount_variable[idx];
if (strlen(Team_data[i].weaponry_amount_variable[idx])) {
static_weapon_variable_pool[i][Team_data[i].weaponry_pool[idx]] = get_index_sexp_variable_name(Team_data[i].weaponry_amount_variable[idx]);
}
else {
static_weapon_variable_pool[i][Team_data[i].weaponry_pool[idx]] = -1;
}
}
// if we do....
else
{
dynamic_weapon_pool[i][Team_data[i].weaponry_pool_variable[idx]] = Team_data[i].weaponry_count[idx];
dynamic_weapon_variable_pool[i][Team_data[i].weaponry_pool_variable[idx]] = Team_data[i].weaponry_amount_variable[idx];
dynamic_weapon_pool[i][get_index_sexp_variable_name(Team_data[i].weaponry_pool_variable[idx])] = Team_data[i].weaponry_count[idx];
if (strlen(Team_data[i].weaponry_amount_variable[idx])) {
dynamic_weapon_variable_pool[i][get_index_sexp_variable_name(Team_data[i].weaponry_pool_variable[idx])] = get_index_sexp_variable_name(Team_data[i].weaponry_amount_variable[idx]);
}
else {
dynamic_weapon_variable_pool[i][get_index_sexp_variable_name(Team_data[i].weaponry_pool_variable[idx])] = -1;
}
}
}
}
@@ -760,18 +779,24 @@ void player_start_editor::OnOK()
// Copy the variable to Team_data
Team_data[i].ship_list_variables[num_choices] = idx;
if (idx != -1) {
Assert (idx < MAX_SEXP_VARIABLES);
strcpy_s(Team_data[i].ship_list_variables[num_choices], Sexp_variables[idx].variable_name);
}
else {
strcpy_s(Team_data[i].ship_list_variables[num_choices], "");
}
Team_data[i].ship_list[num_choices] = -1;
// Now we need to set the number of this type available
if (dynamic_ship_variable_pool[i][idx] == -1) {
Team_data[i].ship_count[num_choices] = dynamic_ship_pool[i][idx];
Team_data[i].ship_count_variables[num_choices] = -1;
strcpy_s(Team_data[i].ship_count_variables[num_choices], "");
}
else {
Assert (Sexp_variables[dynamic_ship_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
Team_data[i].ship_count_variables[num_choices] = dynamic_ship_variable_pool[i][idx];
strcpy_s(Team_data[i].ship_count_variables[num_choices], Sexp_variables[dynamic_ship_variable_pool[i][idx]].variable_name);
Team_data[i].ship_count[num_choices] = atoi(Sexp_variables[dynamic_ship_variable_pool[i][idx]].text);
}
@@ -785,17 +810,17 @@ void player_start_editor::OnOK()
// if we have ships here
if(static_ship_pool[i][idx] > 0 || static_ship_variable_pool[i][idx] > -1) {
Team_data[i].ship_list[num_choices] = idx;
Team_data[i].ship_list_variables[num_choices] = -1;
strcpy_s(Team_data[i].ship_list_variables[num_choices], "");
// Now set the number of this class available
if (static_ship_variable_pool[i][idx] == -1) {
Team_data[i].ship_count[num_choices] = static_ship_pool[i][idx];
Team_data[i].ship_count_variables[num_choices] = -1;
strcpy_s(Team_data[i].ship_count_variables[num_choices], "");
}
else {
Assert (Sexp_variables[static_ship_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
Team_data[i].ship_count_variables[num_choices] = static_ship_variable_pool[i][idx];
strcpy_s(Team_data[i].ship_count_variables[num_choices], Sexp_variables[static_ship_variable_pool[i][idx]].variable_name);
Team_data[i].ship_count[num_choices] = atoi(Sexp_variables[static_ship_variable_pool[i][idx]].text);
}
@@ -830,20 +855,20 @@ void player_start_editor::OnOK()
}
// Copy the variable to Team_data
Team_data[i].weaponry_pool_variable[num_choices] = idx;
strcpy_s(Team_data[i].weaponry_pool_variable[num_choices], Sexp_variables[idx].variable_name);
Team_data[i].weaponry_pool[num_choices] = -1;
// Now we need to set the number of this class available
if (dynamic_weapon_variable_pool[i][idx] == -1)
{
Team_data[i].weaponry_count[num_choices] = dynamic_weapon_pool[i][idx];
Team_data[i].weaponry_amount_variable[num_choices] = -1;
strcpy_s(Team_data[i].weaponry_amount_variable[num_choices], "");
}
else
{
Assert (Sexp_variables[dynamic_weapon_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
Team_data[i].weaponry_amount_variable[num_choices] = dynamic_weapon_variable_pool[i][idx];
strcpy_s(Team_data[i].weaponry_amount_variable[num_choices], Sexp_variables[dynamic_weapon_variable_pool[i][idx]].variable_name);
Team_data[i].weaponry_count[num_choices] = atoi(Sexp_variables[dynamic_weapon_variable_pool[i][idx]].text);
}
@@ -859,19 +884,19 @@ void player_start_editor::OnOK()
if(static_weapon_pool[i][idx] > 0 || static_weapon_variable_pool[i][idx] > -1)
{
Team_data[i].weaponry_pool[num_choices] = idx;
Team_data[i].weaponry_pool_variable[num_choices] = -1;
strcpy_s(Team_data[i].weaponry_pool_variable[num_choices], "");
// Now set the number of this class available
if (static_weapon_variable_pool[i][idx] == -1)
{
Team_data[i].weaponry_count[num_choices] = static_weapon_pool[i][idx];
Team_data[i].weaponry_amount_variable[num_choices] = -1;
strcpy_s(Team_data[i].weaponry_amount_variable[num_choices], "");
}
else
{
Assert (Sexp_variables[static_weapon_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
Team_data[i].weaponry_amount_variable[num_choices] = static_weapon_variable_pool[i][idx];
strcpy_s(Team_data[i].weaponry_amount_variable[num_choices], Sexp_variables[static_weapon_variable_pool[i][idx]].variable_name);
Team_data[i].weaponry_count[num_choices] = atoi(Sexp_variables[static_weapon_variable_pool[i][idx]].text);
}
-1
View File
@@ -16,7 +16,6 @@
#include "FREDView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -22,7 +22,6 @@
#define ID_WING_DATA 9000
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+3 -1
View File
@@ -1139,6 +1139,8 @@
#define IDC_SOUND_ENVIRONMENT_DECAY 1625
#define IDC_SOUND_ENVIRONMENT_BUTTON 1626
#define IDC_SOUND_ENVIRONMENT_TEST 1627
#define IDC_GROUP_MESSAGES 1628
#define IDC_INCLUDE_SENDER 1629
#define ID_FILE_MISSIONNOTES 32771
#define ID_DUPLICATE 32774
#define ID_VIEW_ROTATE 32775
@@ -1432,7 +1434,7 @@
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 320
#define _APS_NEXT_COMMAND_VALUE 33098
#define _APS_NEXT_CONTROL_VALUE 1628
#define _APS_NEXT_CONTROL_VALUE 1629
#define _APS_NEXT_SYMED_VALUE 105
#endif
#endif
-1
View File
@@ -13,7 +13,6 @@
#include "model/model.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -6,7 +6,6 @@
#include "SetGlobalShipFlags.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+61 -11
View File
@@ -43,6 +43,7 @@
#include "iff_defs/iff_defs.h"
#include "mission/missionmessage.h"
#include "graphics/gropenglshader.h"
#include "graphics/gropenglpostprocessing.h"
#include "sound/ds.h"
#define TREE_NODE_INCREMENT 100
@@ -56,7 +57,6 @@
// note: stay below 0xe000 so we don't collide with MFC defines..
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -2576,6 +2576,11 @@ int sexp_tree::get_default_value(sexp_list_item *item, int op, int i)
case OPF_FONT:
str = Fonts[0].filename;
break;
case OPF_AUDIO_VOLUME_OPTION:
str = "Music";
break;
default:
str = "<new default required!>";
@@ -2660,6 +2665,9 @@ int sexp_tree::query_default_argument_available(int op, int i)
case OPF_HUD_ELEMENT:
case OPF_SOUND_ENVIRONMENT:
case OPF_SOUND_ENVIRONMENT_OPTION:
case OPF_EXPLOSION_OPTION:
case OPF_AUDIO_VOLUME_OPTION:
case OPF_WEAPON_BANK_NUMBER:
return 1;
case OPF_SHIP:
@@ -4369,6 +4377,18 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
list = get_listing_opf_sound_environment_option();
break;
case OPF_AUDIO_VOLUME_OPTION:
list = get_listing_opf_adjust_audio_volume();
break;
case OPF_EXPLOSION_OPTION:
list = get_listing_opf_explosion_option();
break;
case OPF_WEAPON_BANK_NUMBER:
list = get_listing_opf_weapon_banks();
break;
default:
Int3(); // unknown OPF code
list = NULL;
@@ -5215,7 +5235,7 @@ sexp_list_item *sexp_tree::get_listing_opf_sound_environment()
sexp_list_item head;
head.add_data(SEXP_NONE_STRING);
for (int i = 0; i < EFX_presets.size(); i++) {
for (int i = 0; i < (int)EFX_presets.size(); i++) {
// ugh
char *text = const_cast<char*>(EFX_presets[i].name.c_str());
head.add_data(text);
@@ -5234,6 +5254,26 @@ sexp_list_item *sexp_tree::get_listing_opf_sound_environment_option()
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_adjust_audio_volume()
{
sexp_list_item head;
for (int i = 0; i < Num_adjust_audio_options; i++)
head.add_data(Adjust_audio_options[i]);
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_explosion_option()
{
sexp_list_item head;
for (int i = 0; i < Num_explosion_options; i++)
head.add_data(Explosion_option[i]);
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_waypoint_path()
{
int i;
@@ -5464,7 +5504,7 @@ sexp_list_item *sexp_tree::get_listing_opf_string()
{
sexp_list_item head;
head.add_data("<any string>");
head.add_data(SEXP_ANY_STRING);
return head.next;
}
@@ -5692,9 +5732,11 @@ sexp_list_item *sexp_tree::get_listing_opf_post_effect()
{
unsigned int i;
sexp_list_item head;
SCP_vector<opengl::post_effect> &ppe_names = opengl::post_shader::get_effects();
for (i=0; i < ppe_names.size(); i++)
head.add_data(const_cast<char*>(ppe_names[i].name.c_str()));
SCP_vector<SCP_string> ppe_names;
get_post_process_effect_names(ppe_names);
for (i=0; i < ppe_names.size(); i++) {
head.add_data(const_cast<char*>(ppe_names[i].c_str()));
}
return head.next;
}
@@ -5731,6 +5773,14 @@ sexp_list_item *sexp_tree::get_listing_opf_hud_elements()
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_weapon_banks()
{
sexp_list_item head;
head.add_data(SEXP_ALL_BANKS_STRING);
return head.next;
}
// Deletes sexp_variable from sexp_tree.
// resets tree to not include given variable, and resets text and type
void sexp_tree::delete_sexp_tree_variable(const char *var_name)
@@ -5871,20 +5921,20 @@ int sexp_tree::get_loadout_variable_count(int var_index)
for (int i=0; i < MAX_TVT_TEAMS; i++) {
for(idx=0; idx<Team_data[i].num_ship_choices; idx++) {
if (var_index == Team_data[i].ship_list_variables[idx]) {
if (!strcmp(Team_data[i].ship_list_variables[idx], Sexp_variables[var_index].variable_name)) {
count++;
}
if (var_index == Team_data[i].ship_count_variables[idx]) {
count++;
if (!strcmp(Team_data[i].ship_count_variables[idx], Sexp_variables[var_index].variable_name)) {
count++;
}
}
for (idx=0; idx<Team_data[i].num_weapon_choices; idx++) {
if (var_index == Team_data[i].weaponry_pool_variable[idx]) {
if (!strcmp(Team_data[i].weaponry_pool_variable[idx], Sexp_variables[var_index].variable_name)) {
count++;
}
if (var_index == Team_data[i].weaponry_amount_variable[idx]) {
if (!strcmp(Team_data[i].weaponry_amount_variable[idx], Sexp_variables[var_index].variable_name)) {
count++;
}
}
+3
View File
@@ -260,6 +260,9 @@ public:
sexp_list_item *get_listing_opf_hud_elements();
sexp_list_item *get_listing_opf_sound_environment();
sexp_list_item *get_listing_opf_sound_environment_option();
sexp_list_item *get_listing_opf_explosion_option();
sexp_list_item *get_listing_opf_adjust_audio_volume();
sexp_list_item *get_listing_opf_weapon_banks();
int m_mode;
int item_index;
-1
View File
@@ -17,7 +17,6 @@
#include "iff_defs/iff_defs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -22,7 +22,6 @@
#define ACTIVITY_WING 2
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -14,7 +14,6 @@
#include "ShipClassEditorDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -47,7 +47,6 @@
#define NO_PERSONA_INDEX 999
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -16,7 +16,6 @@
#include "globalincs/linklist.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -28,7 +28,6 @@
#define DATA_MASK 0x0fff
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -18,7 +18,6 @@
#include "FREDDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -9,7 +9,6 @@
#include "FREDDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -8,7 +8,6 @@
#include "bmpman/bmpman.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -10,7 +10,6 @@
#include "cfile/cfile.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -16,7 +16,6 @@
#include "FREDDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -16,7 +16,6 @@
#include "cfile/cfile.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+317 -56
View File
@@ -2,22 +2,27 @@
//
#include "stdafx.h"
#include <string.h>
#include "fred.h"
#include "fred2/freddoc.h"
#include "VoiceActingManager.h"
#include "missionui/missioncmdbrief.h"
#include "mission/missionbriefcommon.h"
#include "mission/missionmessage.h"
#include "mission/missiongoals.h"
#include "hud/hudtarget.h"
#include "parse/sexp.h"
#include "iff_defs/iff_defs.h"
#include "mission/missiongoals.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define INVALID_MESSAGE ((MMessage*)0xFFFFFFFF)
// to keep track of data
char Voice_abbrev_briefing[NAME_LENGTH];
char Voice_abbrev_campaign[NAME_LENGTH];
@@ -28,6 +33,7 @@ char Voice_abbrev_mission[NAME_LENGTH];
bool Voice_no_replace_filenames;
char Voice_script_entry_format[NOTES_LENGTH];
int Voice_export_selection;
bool Voice_group_messages;
/////////////////////////////////////////////////////////////////////////////
@@ -44,6 +50,7 @@ VoiceActingManager::VoiceActingManager(CWnd* pParent /*=NULL*/)
m_abbrev_debriefing = _T("");
m_abbrev_message = _T("");
m_abbrev_mission = _T("");
m_use_sender_in_filename = FALSE;
m_example = _T("");
m_no_replace = FALSE;
m_script_entry_format = _T("");
@@ -52,6 +59,7 @@ VoiceActingManager::VoiceActingManager(CWnd* pParent /*=NULL*/)
m_export_briefings = FALSE;
m_export_debriefings = FALSE;
m_export_messages = FALSE;
m_group_messages = FALSE;
//}}AFX_DATA_INIT
}
@@ -68,12 +76,14 @@ void VoiceActingManager::DoDataExchange(CDataExchange* pDX)
DDX_Text(pDX, IDC_ABBREV_MISSION, m_abbrev_mission);
DDX_Text(pDX, IDC_EXAMPLE, m_example);
DDX_Check(pDX, IDC_NO_REPLACE, m_no_replace);
DDX_Check(pDX, IDC_INCLUDE_SENDER, m_use_sender_in_filename);
DDX_Text(pDX, IDC_ENTRY_FORMAT, m_script_entry_format);
DDX_Check(pDX, IDC_EXPORT_EVERYTHING, m_export_everything);
DDX_Check(pDX, IDC_EXPORT_COMMAND_BRIEFINGS, m_export_command_briefings);
DDX_Check(pDX, IDC_EXPORT_BRIEFINGS, m_export_briefings);
DDX_Check(pDX, IDC_EXPORT_DEBRIEFINGS, m_export_debriefings);
DDX_Check(pDX, IDC_EXPORT_MESSAGES, m_export_messages);
DDX_Check(pDX, IDC_GROUP_MESSAGES, m_group_messages);
//}}AFX_DATA_MAP
}
@@ -98,6 +108,12 @@ BEGIN_MESSAGE_MAP(VoiceActingManager, CDialog)
ON_BN_CLICKED(IDC_NO_REPLACE, OnChangeNoReplace)
ON_BN_CLICKED(IDC_GENERATE_FILE_NAMES, OnGenerateFileNames)
ON_BN_CLICKED(IDC_GENERATE_SCRIPT, OnGenerateScript)
ON_BN_CLICKED(IDC_EXPORT_EVERYTHING, OnExportEverything)
ON_BN_CLICKED(IDC_EXPORT_COMMAND_BRIEFINGS, OnExportCommandBriefings)
ON_BN_CLICKED(IDC_EXPORT_BRIEFINGS, OnExportBriefings)
ON_BN_CLICKED(IDC_EXPORT_DEBRIEFINGS, OnExportDebriefings)
ON_BN_CLICKED(IDC_EXPORT_MESSAGES, OnExportMessages)
ON_BN_CLICKED(IDC_INCLUDE_SENDER, OnBnClickedIncludeSender)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
@@ -133,6 +149,10 @@ BOOL VoiceActingManager::OnInitDialog()
m_export_messages = TRUE;
else
m_export_everything = TRUE;
m_group_messages = Voice_group_messages;
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(m_export_everything || m_export_messages);
UpdateData(FALSE);
@@ -150,7 +170,7 @@ void VoiceActingManager::OnClose()
strcpy_s(Voice_abbrev_debriefing, m_abbrev_debriefing);
strcpy_s(Voice_abbrev_message, m_abbrev_message);
strcpy_s(Voice_abbrev_mission, m_abbrev_mission);
Voice_no_replace_filenames = m_no_replace == TRUE ? true : false;
Voice_no_replace_filenames = (m_no_replace == TRUE) ? true : false;
// save data for script
strcpy_s(Voice_script_entry_format, m_script_entry_format);
@@ -164,6 +184,7 @@ void VoiceActingManager::OnClose()
Voice_export_selection = 4;
else
Voice_export_selection = 0;
Voice_group_messages = (m_group_messages == TRUE) ? true : false;
CDialog::OnClose();
}
@@ -213,10 +234,10 @@ void VoiceActingManager::build_example(CString section)
return;
}
m_example = generate_filename(section, 1, 2);
m_example = generate_filename(section, 1, 2, INVALID_MESSAGE);
}
CString VoiceActingManager::generate_filename(CString section, int number, int digits)
CString VoiceActingManager::generate_filename(CString section, int number, int digits, MMessage *message)
{
if (section == "")
return "none.wav";
@@ -241,9 +262,52 @@ CString VoiceActingManager::generate_filename(CString section, int number, int d
}
str = str + num;
const CString suffix = get_suffix();
// append sender name if supposed to and I have been passed a message
// to get the sender from
if ( message != NULL && m_use_sender_in_filename ) {
size_t allow_to_copy = NAME_LENGTH - suffix.GetLength() - str.GetLength();
char sender[NAME_LENGTH];
if ( message == INVALID_MESSAGE ) {
strcpy_s(sender, "Alpha 1");
} else {
get_valid_sender(sender, sizeof(sender), message);
}
// truncate sender to that we don't overflow filename
sender[allow_to_copy] = '\0';
size_t j;
for( j = 0; sender[j] != '\0'; j++ ) {
// lower case letter
sender[j] = (char)tolower(sender[j]);
// replace any non alpha numeric with a underscore
if ( !isalnum( sender[j] ) )
sender[j] = '_';
}
// flatten muliple underscores
j = 1;
while( sender[j] != '\0' ) {
if ( sender[j-1] == '_' && sender[j] == '_' ) {
size_t k;
for (k = j + 1; sender[k] != '\0'; k++ )
sender[k - 1] = sender[k];
sender[k - 1] = '\0';
} else {
// only increment on rounds when I am not moving the string down
j++;
}
}
str = str + sender;
}
// suffix
str = str + get_suffix();
Assert( str.GetLength() < NAME_LENGTH );
return str;
}
@@ -251,6 +315,7 @@ void VoiceActingManager::OnGenerateFileNames()
{
int i;
int digits;
size_t modified_filenames = 0;
// stuff data to variables
UpdateData(TRUE);
@@ -262,9 +327,10 @@ void VoiceActingManager::OnGenerateFileNames()
char *filename = Cmd_briefs[0].stage[i].wave_filename;
// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || !strnicmp(filename, "none.wav", 4) || message_filename_is_generic(filename))
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_command_briefing, i + 1, digits)));
modified_filenames++;
}
}
@@ -275,9 +341,10 @@ void VoiceActingManager::OnGenerateFileNames()
char *filename = Briefings[0].stages[i].voice;
// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || !strnicmp(filename, "none.wav", 4) || message_filename_is_generic(filename))
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_briefing, i + 1, digits)));
modified_filenames++;
}
}
@@ -288,9 +355,10 @@ void VoiceActingManager::OnGenerateFileNames()
char *filename = Debriefings[0].stages[i].voice;
// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || !strnicmp(filename, "none.wav", 4) || message_filename_is_generic(filename))
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_debriefing, i + 1, digits)));
modified_filenames++;
}
}
@@ -299,21 +367,30 @@ void VoiceActingManager::OnGenerateFileNames()
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
{
char *filename = Messages[i + Num_builtin_messages].wave_info.name;
MMessage *message = &Messages[i + Num_builtin_messages];
// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !filename || !strlen(filename) || !strnicmp(filename, "none.wav", 4) || message_filename_is_generic(filename))
if (!m_no_replace || !strlen(filename) || !strlen(filename) || message_filename_is_generic(filename))
{
// free existing filename
if (filename != NULL)
free(filename);
// allocate new filename
Messages[i + Num_builtin_messages].wave_info.name = strdup(LPCTSTR(generate_filename(m_abbrev_message, i + 1, digits)));
Messages[i + Num_builtin_messages].wave_info.name = strdup(LPCTSTR(generate_filename(m_abbrev_message, i + 1, digits, message)));
modified_filenames++;
}
}
// notify
MessageBox("File name generation complete.", "Woohoo!");
if ( modified_filenames > 0 ) {
// Tell FRED that we actually modified something
set_modified(TRUE);
}
// notify user that we are done and how many filenames were changed
char message[128] = { '\0' };
snprintf(message, sizeof(message), "File name generation complete. Modified %d messages.", modified_filenames);
MessageBox(message, "Woohoo!");
}
void VoiceActingManager::OnGenerateScript()
@@ -402,56 +479,27 @@ void VoiceActingManager::OnGenerateScript()
{
fout("\n\nMessages\n--------\n\n");
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
if (m_group_messages)
{
CString entry = m_script_entry_format;
entry.Replace("\r\n", "\n");
SCP_vector<int> message_indexes;
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
message_indexes.push_back(i + Num_builtin_messages);
MMessage *message = &Messages[i + Num_builtin_messages];
group_message_indexes(message_indexes);
// replace file name
entry.Replace("$filename", message->wave_info.name);
// determine and replace persona
entry.Replace("$message", message->message);
if (message->persona_index >= 0)
entry.Replace("$persona", Personas[message->persona_index].name);
else
entry.Replace("$persona", "<none>");
// determine sender
char sender[NAME_LENGTH+1];
strcpy_s(sender, get_message_sender(message->name));
int shipnum = ship_name_lookup(sender);
if (shipnum >= 0)
for (i = 0; i < message_indexes.size(); i++)
{
ship *shipp = &Ships[shipnum];
// we may have to use the callsign
if (*Fred_callsigns[shipnum])
{
hud_stuff_ship_callsign(sender, shipp);
}
// account for hidden ship names
else if ( ((Iff_info[shipp->team].flags & IFFF_WING_NAME_HIDDEN) && (shipp->wingnum != -1)) || (shipp->flags2 & SF2_HIDE_SHIP_NAME) )
{
hud_stuff_ship_class(sender, shipp);
}
// use the regular sender text
else
{
end_string_at_first_hash_symbol(sender);
}
MMessage *message = &Messages[message_indexes[i]];
export_one_message(message);
}
}
else
{
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
{
MMessage *message = &Messages[i + Num_builtin_messages];
export_one_message(message);
}
// replace sender (but print #Command as Command)
if (*sender == '#')
entry.Replace("$sender", &sender[1]);
else
entry.Replace("$sender", sender);
fout("%s\n\n\n", (char *) (LPCTSTR) entry);
}
}
@@ -461,6 +509,76 @@ void VoiceActingManager::OnGenerateScript()
MessageBox("Script generation complete.", "Woohoo!");
}
void VoiceActingManager::export_one_message(MMessage *message)
{
CString entry = m_script_entry_format;
entry.Replace("\r\n", "\n");
// replace file name
entry.Replace("$filename", message->wave_info.name);
// determine and replace persona
entry.Replace("$message", message->message);
if (message->persona_index >= 0)
entry.Replace("$persona", Personas[message->persona_index].name);
else
entry.Replace("$persona", "<none>");
// determine sender
char sender[NAME_LENGTH+1];
get_valid_sender(sender, sizeof(sender), message);
// replace sender (but print #Command as Command)
if (*sender == '#')
entry.Replace("$sender", &sender[1]);
else
entry.Replace("$sender", sender);
fout("%s\n\n\n", (char *) (LPCTSTR) entry);
}
/** Passed sender string will have either have the senders name
or '<none>'*/
void VoiceActingManager::get_valid_sender(char *sender, size_t sender_size, MMessage *message) {
Assert( sender != NULL );
Assert( message != NULL );
strncpy(sender, get_message_sender(message->name), sender_size);
// strip hash if present
if ( sender[0] == '#' ) {
size_t i = 1;
for(; sender[i] != '\0'; i++ ) {
sender[i-1] = sender[i];
}
sender[i-1] = '\0';
}
int shipnum = ship_name_lookup(sender, 1); // The player's ship is valid for this search.
if (shipnum >= 0)
{
ship *shipp = &Ships[shipnum];
// we may have to use the callsign
if (*Fred_callsigns[shipnum])
{
hud_stuff_ship_callsign(sender, shipp);
}
// account for hidden ship names
else if ( ((Iff_info[shipp->team].flags & IFFF_WING_NAME_HIDDEN) && (shipp->wingnum != -1)) || (shipp->flags2 & SF2_HIDE_SHIP_NAME) )
{
hud_stuff_ship_class(sender, shipp);
}
// use the regular sender text
else
{
end_string_at_first_hash_symbol(sender);
}
}
}
void VoiceActingManager::OnSetfocusAbbrevBriefing()
{
UpdateData(TRUE);
@@ -667,3 +785,146 @@ char *VoiceActingManager::get_message_sender(char *message)
return "<none>";
}
void VoiceActingManager::group_message_indexes(SCP_vector<int> &message_indexes)
{
int i;
#ifndef NDEBUG
int initial_size = message_indexes.size();
#endif
SCP_vector<int> temp_message_indexes = message_indexes;
message_indexes.clear();
// add all messages found in send-message-list or send-random-message node trees
for (i = 0; i < Num_mission_events; i++)
{
mission_event *event = &Mission_events[i];
group_message_indexes_in_tree(event->formula, temp_message_indexes, message_indexes);
}
// add remaining messages
for (i = 0; i < temp_message_indexes.size(); i++)
message_indexes.push_back(temp_message_indexes[i]);
#ifndef NDEBUG
if (initial_size > message_indexes.size())
{
Warning(LOCATION, "Initial size is greater than size after sorting!");
}
else if (initial_size < message_indexes.size())
{
Warning(LOCATION, "Initial size is less than size after sorting!");
}
#endif
}
void VoiceActingManager::group_message_indexes_in_tree(int node, SCP_vector<int> &source_list, SCP_vector<int> &destination_list)
{
int i, op, n;
if (node < 0)
return;
if (Sexp_nodes[node].type == SEXP_NOT_USED)
return;
// stuff
op = get_operator_const(Sexp_nodes[node].text);
n = CDR(node);
if (op == OP_SEND_MESSAGE_LIST)
{
// check the argument list
while (n != -1)
{
// the third argument is a message
char *message_name = Sexp_nodes[CDDR(n)].text;
// check source messages
for (i = 0; i < source_list.size(); i++)
{
if (!strcmp(message_name, Messages[source_list[i]].name))
{
// move it from source to destination
destination_list.push_back(source_list[i]);
source_list.erase(source_list.begin() + i);
break;
}
}
// iterate along the list
n = CDDDDR(n);
}
}
else if (op == OP_SEND_RANDOM_MESSAGE)
{
// check the argument list
n = CDDR(n);
while (n != -1)
{
// each argument from this point on is a message
char *message_name = Sexp_nodes[n].text;
// check source messages
for (i = 0; i < source_list.size(); i++)
{
if (!strcmp(message_name, Messages[source_list[i]].name))
{
// move it from source to destination
destination_list.push_back(source_list[i]);
source_list.erase(source_list.begin() + i);
break;
}
}
// iterate along the list
n = CDR(n);
}
}
// iterate on first element
group_message_indexes_in_tree(CAR(node), source_list, destination_list);
// iterate on rest of elements
group_message_indexes_in_tree(CDR(node), source_list, destination_list);
}
void VoiceActingManager::OnExportEverything()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(TRUE);
}
void VoiceActingManager::OnExportCommandBriefings()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(FALSE);
}
void VoiceActingManager::OnExportBriefings()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(FALSE);
}
void VoiceActingManager::OnExportDebriefings()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(FALSE);
}
void VoiceActingManager::OnExportMessages()
{
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(TRUE);
}
void VoiceActingManager::OnBnClickedIncludeSender()
{
UpdateData(TRUE);
build_example();
UpdateData(FALSE);
}
+15 -1
View File
@@ -7,6 +7,8 @@
// VoiceActingManager.h : header file
//
#include "mission/missionmessage.h"
/////////////////////////////////////////////////////////////////////////////
// VoiceActingManager dialog
@@ -25,6 +27,7 @@ public:
CString m_abbrev_debriefing;
CString m_abbrev_message;
CString m_abbrev_mission;
BOOL m_use_sender_in_filename;
CString m_example;
BOOL m_no_replace;
CString m_script_entry_format;
@@ -33,6 +36,7 @@ public:
BOOL m_export_briefings;
BOOL m_export_debriefings;
BOOL m_export_messages;
BOOL m_group_messages;
//}}AFX_DATA
@@ -50,8 +54,12 @@ protected:
int calc_digits(int size);
void build_example();
void build_example(CString section);
CString generate_filename(CString section, int number, int digits);
CString generate_filename(CString section, int number, int digits, MMessage *message=NULL);
char *get_message_sender(char *message);
void export_one_message(MMessage *message);
void get_valid_sender(char *sender, size_t sender_size, MMessage *message);
void group_message_indexes(SCP_vector<int> &message_indexes);
void group_message_indexes_in_tree(int node, SCP_vector<int> &source_list, SCP_vector<int> &destination_list);
CFILE *fp;
int fout(char *format, ...);
@@ -77,6 +85,12 @@ protected:
afx_msg void OnChangeNoReplace();
afx_msg void OnGenerateFileNames();
afx_msg void OnGenerateScript();
afx_msg void OnExportEverything();
afx_msg void OnExportCommandBriefings();
afx_msg void OnExportBriefings();
afx_msg void OnExportDebriefings();
afx_msg void OnExportMessages();
afx_msg void OnBnClickedIncludeSender();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
-1
View File
@@ -27,7 +27,6 @@
#define ID_WAYPOINT_MENU 9000
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -20,7 +20,6 @@
#define BLANK_FIELD -99
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -30,7 +30,6 @@
#define MULTI_WING 999999
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
-1
View File
@@ -27,7 +27,6 @@
#define ID_WING_MENU 9000
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+39 -111
View File
@@ -308,10 +308,6 @@ char Game_current_mission_filename[MAX_FILENAME_LEN];
int game_single_step = 0;
int last_single_step=0;
extern int MSG_WINDOW_X_START; // used to position mission_time and shields output
extern int MSG_WINDOW_Y_START;
extern int MSG_WINDOW_HEIGHT;
int game_zbuffer = 1;
//static int Game_music_paused;
static int Game_paused;
@@ -994,6 +990,7 @@ void game_level_close()
cam_close();
subtitles_close();
trail_level_close();
hud_level_close();
// be sure to not only reset the time but the lock as well
set_time_compression(1.0f, 0.0f);
@@ -1088,7 +1085,6 @@ void game_level_init(int seed)
mission_brief_common_init(); // Free all existing briefing/debriefing text
weapon_level_init();
init_decals();
NavSystem_Init(); // zero out the nav system
@@ -1103,9 +1099,6 @@ void game_level_init(int seed)
// cmeasure_init(); //WMC - cmeasures are now weapons
shield_hit_init(); // Initialize system for showing shield hits
if ( !Is_standalone )
radar_mission_init();
mission_init_goals();
mission_log_init();
messages_init();
@@ -1132,8 +1125,7 @@ void game_level_init(int seed)
supernova_level_init();
cam_init();
subtitles_init();
snd_aav_init();
// multiplayer dogfight hack
dogfight_blown = 0;
@@ -1193,32 +1185,6 @@ void game_do_networking()
}
}
// Loads the best palette for this level, based
// on nebula color and hud color. You could just call palette_load_table with
// the appropriate filename, but who wants to do that.
void game_load_palette()
{
char palette_filename[1024];
// We only use 3 hud colors right now
// Assert( HUD_config.color >= 0 );
// Assert( HUD_config.color <= 2 );
Assert( Mission_palette >= 0 );
Assert( Mission_palette <= 98 );
// if ( The_mission.flags & MISSION_FLAG_SUBSPACE ) {
strcpy_s( palette_filename, NOX("gamepalette-subspace") );
// } else {
// sprintf( palette_filename, NOX("gamepalette%d-%02d"), HUD_config.color+1, Mission_palette+1 );
// }
mprintf(( "Loading palette %s\n", palette_filename ));
// palette_load_table(palette_filename);
}
// An estimate as to how high the count passed to game_loading_callback will go.
// This is just a guess, it seems to always be about the same. The count is
// proportional to the code being executed, not the time, so this works good
@@ -1265,7 +1231,7 @@ void game_loading_callback(int count)
game_do_networking();
Assert( Game_loading_callback_inited==1 );
Assert( Game_loading_ani.num_frames > 0 );
Assertion( Game_loading_ani.num_frames > 0, "Load Screen animation %s not found, or corrupted. Needs to be an animation with at least 1 frame.", Game_loading_ani.filename );
int do_flip = 0;
@@ -1382,7 +1348,7 @@ void game_loading_callback_init()
strcpy(Game_loading_ani.filename, Game_loading_ani_fname[gr_screen.res]);
generic_anim_init(&Game_loading_ani, Game_loading_ani.filename);
generic_anim_load(&Game_loading_ani);
Assert( Game_loading_ani.num_frames > 0 );
Assertion( Game_loading_ani.num_frames > 0, "Load Screen animation %s not found, or corrupted. Needs to be an animation with at least 1 frame.", Game_loading_ani.filename );
Game_loading_callback_inited = 1;
Mouse_hidden = 1;
@@ -1573,11 +1539,7 @@ int game_start_mission()
mprintf(( "=================== STARTING LEVEL LOAD ==================\n" ));
// clear post processing settings
if(!Is_standalone)
gr_screen.gf_set_default_post_process();
// clear shader manager cache
gr_clear_shaders_cache();
gr_post_process_set_defaults();
get_mission_info(Game_current_mission_filename, &The_mission, false);
@@ -1617,14 +1579,6 @@ int game_start_mission()
extern void stop_parse();
stop_parse();
//WMC - *sigh* more mprintf clutter. It was commented out when I got here
/*
// the standalone server in multiplayer doesn't do any rendering, so we will not even bother loading the palette
if ( !(Game_mode & GM_STANDALONE_SERVER) ) {
mprintf(( "=================== LOADING GAME PALETTE ================\n" ));
// game_load_palette();
}*/
game_busy( NOX("** starting game_post_level_init() **") );
load_post_level_init = (uint) time(NULL);
game_post_level_init();
@@ -2179,9 +2133,6 @@ void game_init()
bm_set_low_mem(0); // Use all frames of bitmaps
}
if(!Is_standalone)
gr_screen.gf_post_process_init();
//WMC - Initialize my new GUI system
//This may seem scary, but it should take up 0 processing time and very little memory
//as long as it's not being used.
@@ -2219,8 +2170,6 @@ void game_init()
mouse_init();
gamesnd_parse_soundstbl();
select_radar_mode(Cmdline_orb_radar);
gameseq_init();
multi_init();
@@ -3882,7 +3831,7 @@ void game_render_frame( camid cid )
}
gr_zbuffer_clear(TRUE);
gr_screen.gf_post_process_before();
gr_post_process_begin();
clip_frame_view();
@@ -3935,7 +3884,7 @@ void game_render_frame( camid cid )
//This is so we can change the minimum clipping distance without messing everything up.
if(draw_viewer_last && Viewer_obj)
{
gr_screen.gf_save_zbuffer();
gr_post_process_save_zbuffer();
gr_zbuffer_clear(TRUE);
ship_render(Viewer_obj);
}
@@ -3963,13 +3912,13 @@ void game_render_frame( camid cid )
//Draw viewer cockpit
if(Viewer_obj != NULL && Viewer_mode != VM_TOPDOWN)
{
gr_screen.gf_save_zbuffer();
gr_post_process_save_zbuffer();
gr_zbuffer_clear(TRUE);
ship_render_cockpit(Viewer_obj);
}
//================ END OF 3D RENDERING STUFF ====================
gr_screen.gf_post_process_after();
gr_post_process_end();
extern int Multi_display_netinfo;
if(Multi_display_netinfo){
@@ -4307,7 +4256,7 @@ void game_simulation_frame()
// process some stuff every frame (before frame is rendered)
emp_process_local();
hud_update_frame(); // update hud systems
hud_update_frame(flFrametime); // update hud systems
if (!physics_paused) {
// Move particle system
@@ -4438,34 +4387,24 @@ int game_actually_playing()
return 1;
}
// Draw the 2D HUD gauges
void game_render_hud_2d()
void game_render_hud(camid cid)
{
if ( !(Game_detail_flags & DETAIL_FLAG_HUD) ) {
return;
}
HUD_render_2d(flFrametime);
gr_reset_clip();
}
// Draw the 3D-dependant HUD gauges
void game_render_hud_3d(camid cid)
{
if(!cid.isValid())
return;
if(cid.isValid()) {
g3_start_frame(0); // 0 = turn zbuffering off
g3_set_view( cid.getCamera() );
g3_start_frame(0); // 0 = turn zbuffering off
g3_set_view( cid.getCamera() );
hud_render_preprocess(flFrametime);
if ( (Game_detail_flags & DETAIL_FLAG_HUD) && (supernova_active() < 3)/* && !(Game_mode & GM_MULTIPLAYER) || ( (Game_mode & GM_MULTIPLAYER) && !(Net_player->flags & NETINFO_FLAG_OBSERVER) )*/ ) {
HUD_render_3d(flFrametime);
g3_end_frame();
}
// main HUD rendering function
hud_render_all();
// Diminish the palette effect
game_flash_diminish(flFrametime);
g3_end_frame();
}
//100% blackness
@@ -4747,22 +4686,23 @@ void game_frame(int paused)
Scripting_didnt_draw_hud = 0;
Script_system.RemHookVar("Self");
if(Scripting_didnt_draw_hud)
{
hud_show_target_model();
}
if(Scripting_didnt_draw_hud)
{
hud_show_radar();
if(Scripting_didnt_draw_hud) {
game_render_hud(cid);
}
HUD_reset_clip();
if( (Game_detail_flags & DETAIL_FLAG_HUD) && (!(Game_mode & GM_MULTIPLAYER) || ((Game_mode & GM_MULTIPLAYER) && !(Net_player->flags & NETINFO_FLAG_OBSERVER))) ) {
hud_maybe_clear_head_area();
anim_render_all(0, flFrametime);
}
Script_system.SetHookObject("Self", Viewer_obj);
if (!hud_disabled_except_messages() && !(Viewer_mode & (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY)))
{
Script_system.RunBytecode(Script_hudhook);
Script_system.RunCondition(CHA_HUDDRAW, '\0', NULL, Viewer_obj);
}
Script_system.RemHookVar("Self");
// check to see if we should display the death died popup
if(Game_mode & GM_DEAD_BLEW_UP){
if(Game_mode & GM_MULTIPLAYER){
@@ -4792,26 +4732,6 @@ void game_frame(int paused)
game_show_time_left();
// Draw the 2D HUD gauges
if(Scripting_didnt_draw_hud)
{
if(supernova_active() < 3){
game_render_hud_2d();
}
// Draw 3D HUD gauges
game_render_hud_3d(cid);
}
Script_system.SetHookObject("Self", Viewer_obj);
if (!hud_disabled_except_messages() && !(Viewer_mode & (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY)))
{
Script_system.RunBytecode(Script_hudhook);
Script_system.RunCondition(CHA_HUDDRAW, '\0', NULL, Viewer_obj);
}
Script_system.RemHookVar("Self");
gr_reset_clip();
game_render_post_frame();
@@ -5022,7 +4942,7 @@ void game_set_frametime(int state)
}
#endif
Assert( Framerate_cap > 0 );
Assertion( Framerate_cap > 0, "Framerate cap %d is too low. Needs to be a positive, non-zero number", Framerate_cap );
// Cap the framerate so it doesn't get too high.
if (!Cmdline_NoFPSCap)
@@ -6095,6 +6015,7 @@ void game_leave_state( int old_state, int new_state )
if ( (Game_mode & GM_MULTIPLAYER) && (new_state == GS_STATE_MAIN_MENU) ){
multi_quit_game(PROMPT_NONE);
}
snd_aav_init();
freespace_stop_mission();
}
@@ -6554,6 +6475,12 @@ void game_enter_state( int old_state, int new_state )
}
player_restore_target_and_weapon_link_prefs();
if ( !Is_standalone )
radar_mission_init();
//Set the current hud
set_current_hud();
Game_mode |= GM_IN_MISSION;
#ifndef NDEBUG
@@ -7730,6 +7657,7 @@ void game_shutdown(void)
// load up common multiplayer icons
multi_unload_common_icons();
hud_close();
shockwave_close(); // release any memory used by shockwave system
fireball_close(); // free fireball system
particle_close(); // close out the particle system
-5
View File
@@ -192,11 +192,6 @@ void big_explosion_flash(float flash);
// flash effect to 0.
void game_flash_diminish();
// Loads the best palette for this level, based
// on nebula color and hud color. You could just call palette_load_table with
// the appropriate filename, but who wants to do that.
void game_load_palette();
//================================================================
// Call at the beginning of each frame
-2
View File
@@ -19,7 +19,6 @@ extern void debris_page_in();
extern void particle_page_in();
extern void stars_page_in();
extern void hud_page_in();
extern void (*radar_page_in)();
extern void weapons_page_in();
extern void fireballs_page_in();
extern void shockwave_page_in();
@@ -54,7 +53,6 @@ void level_page_in()
particle_page_in();
debris_page_in();
hud_page_in();
radar_page_in();
training_mission_page_in();
stars_page_in();
shockwave_page_in();
+75 -38
View File
@@ -66,7 +66,8 @@ static bool do_full_packet = true;
static int Local_timeout = -1;
static int Next_gameserver_update = -1;
static int Last_pong = -1;
static int Ping_timestamp = -1;
static int Last_activity = -1;
static int Login_retry_time = -1;
static SCP_vector<file_record> FS2NetD_file_list;
@@ -92,7 +93,8 @@ static void fs2netd_reset_state()
do_full_packet = true;
Local_timeout = -1;
Next_gameserver_update = -1;
Last_pong = -1;
Last_activity = -1;
Ping_timestamp = -1;
Duplicate_login_detected = false;
Login_retry_time = -1;
}
@@ -167,19 +169,38 @@ void fs2netd_reset_connection()
FS2NetD_Disconnect();
// wait a little to allow for the port to clear
Sleep(250);
fs2netd_reset_state();
// wait a little to allow for the port to clear
Sleep(500);
// try to reinit the server connection
fs2netd_login();
if (reset_gameserver) {
Sleep(250);
if ( reset_gameserver && fs2netd_is_online() ) {
fs2netd_gameserver_start();
}
}
void fs2netd_disconnect()
{
if ( !Is_connected ) {
return;
}
if (Net_player->flags & NETINFO_FLAG_MT_CONNECTED) {
fs2netd_gameserver_disconnect();
}
FS2NetD_Disconnect();
fs2netd_reset_state();
Sleep(500);
}
static int fs2netd_connect_do()
{
int retval = FS2NetD_ConnectToServer(Multi_options_g.game_tracker_ip, Multi_options_g.tracker_port);
@@ -307,6 +328,10 @@ int fs2netd_login_do()
return 2;
}
if (do_full_packet) {
ml_printf("FS2NetD MSG: Requesting login pilot stats for '%s' ...", Players[Player_num].callsign);
}
int rescode = FS2NetD_GetPlayerData(Players[Player_num].callsign, &Players[Player_num], true, do_full_packet);
do_full_packet = false;
@@ -469,6 +494,9 @@ bool fs2netd_login()
if (retval) {
Logged_in = true;
sprintf(Multi_tracker_id_string, "%d", Multi_tracker_id);
} else {
// clear and reset connection, for the next time we try...
fs2netd_disconnect();
}
if (Is_standalone) {
@@ -480,11 +508,13 @@ bool fs2netd_login()
static void fs2netd_handle_ping()
{
static int Next_ping = -1;
bool reset = false;
static int CONN_check = -1;
// if we didn't get a pong within 30 seconds of a ping then assume that the
// server connection must of have dropped or is otherwise unresponsive
if ( (Ping_timestamp != -1) && ((timer_get_seconds() - Ping_timestamp) > 30) ) {
Ping_timestamp = -1;
// if we didn't get a PONG within 4 minutes the server connection must have dropped
if ( (Last_pong != -1) && ((Next_ping - Last_pong) > 240) ) {
ml_string("FS2NetD WARNING: Lost connection to server!");
fs2netd_reset_connection();
@@ -496,11 +526,11 @@ static void fs2netd_handle_ping()
}
ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!");
FS2NetD_Disconnect();
fs2netd_reset_state();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 30 minutes...");
Login_retry_time = timer_get_seconds() + 1800;
fs2netd_disconnect();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes...");
Login_retry_time = timer_get_seconds() + 300;
return;
} else {
@@ -508,24 +538,24 @@ static void fs2netd_handle_ping()
}
}
// send out ping every 90 seconds
if ( (Next_ping == -1) || (timer_get_seconds() >= Next_ping) ) {
// if we have seen a long period of time between pings then reset the pong time too
if ( (timer_get_seconds() - Next_ping) > 120 ) {
reset = true;
}
Next_ping = timer_get_seconds() + 90;
// we go ahead and set the initial Last_pong here, even though we haven't gotten a pong yet
if ( (Last_pong == -1) || reset ) {
Last_pong = Next_ping;
reset = false;
}
// send out a ping after 5 minutes of no other activity to make sure the server
// is still responding (probably not though)
if ( (Ping_timestamp == -1) && (timer_get_seconds() >= (Last_activity + 300)) ) {
Ping_timestamp = timer_get_seconds();
FS2NetD_Ping();
ml_string("FS2NetD sent PING");
// also send out a ID check to keep our login verified
if (Last_activity < 0) {
Last_activity = timer_get_seconds();
}
}
// check for a valid connection (SID, duplicate login, etc.)
if ( (CONN_check == -1) || (timer_get_seconds() >= CONN_check) ) {
// every 3 minutes
CONN_check = timer_get_seconds() + 180;
// session ID check
if ( FS2NetD_CheckValidID() < 0 ) {
ml_string("FS2NetD WARNING: Unable to validate login!");
fs2netd_reset_connection();
@@ -538,11 +568,11 @@ static void fs2netd_handle_ping()
}
ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!");
FS2NetD_Disconnect();
fs2netd_reset_state();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 30 minutes...");
Login_retry_time = timer_get_seconds() + 1800;
fs2netd_disconnect();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes...");
Login_retry_time = timer_get_seconds() + 300;
return;
} else {
@@ -555,7 +585,7 @@ static void fs2netd_handle_ping()
FS2NetD_CheckDuplicateLogin();
}
ml_string("FS2NetD sent PING/IDENT");
ml_string("FS2NetD sent IDENT check");
}
}
@@ -584,6 +614,8 @@ static void fs2netd_handle_messages()
return;
}
Last_activity = timer_get_seconds();
buffer_offset = 0;
while (buffer_offset+BASE_PACKET_SIZE <= bytes_read) {
@@ -612,7 +644,8 @@ static void fs2netd_handle_messages()
ml_printf("FS2NetD PONG: %d ms", timer_get_milliseconds() - itemp);
Last_pong = timer_get_seconds();
// reset timestamp, since the ping was successful
Ping_timestamp = -1;
break;
}
@@ -739,8 +772,8 @@ void fs2netd_do_frame()
fs2netd_login();
if ( !Logged_in ) {
// bah! try again in another 30 minutes
Login_retry_time = timer_get_seconds() + 1800;
// bah! try again in another 5 minutes
Login_retry_time = timer_get_seconds() + 300;
} else {
Login_retry_time = -1;
}
@@ -1550,6 +1583,10 @@ int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_cal
In_process = true;
}
if (first_call) {
ml_printf("FS2NetD MSG: Requesting pilot stats for '%s' ...", callsign);
}
int rc = FS2NetD_GetPlayerData(callsign, &new_plr, false, first_call);
// some sort of failure
+1
View File
@@ -47,6 +47,7 @@ extern tracker_game_data Multi_tracker_game_data;
bool fs2netd_is_online();
void fs2netd_reset_connection();
void fs2netd_disconnect();
void fs2netd_close();
+2 -2
View File
@@ -265,8 +265,8 @@ int FS2NetD_GetPlayerData(const char *player_name, player *pl, bool can_create,
PXO_GET_DATA( reply_type );
// if we weren't retrieved or created then bail out now
if (reply_type > 1) {
// if we weren't retrieved then bail out now
if (reply_type != 0) {
return (int)reply_type;
}
+4 -8
View File
@@ -368,17 +368,13 @@ void help_overlay_init()
{
// load right_bracket bitmap
help_right_bracket_bitmap = bm_load("right_bracket");
if(help_right_bracket_bitmap < 0){
// we failed to load the bitmap - this is very bad
Int3();
}
// we failed to load the bitmap - this is very bad
Assertion( help_right_bracket_bitmap >= 0, "Failed to load bitmap right_bracket for help overlay\n");
// load left_bracket bitmap
help_left_bracket_bitmap = bm_load("left_bracket");
if(help_left_bracket_bitmap < 0){
// we failed to load the bitmap - this is very bad
Int3();
}
// we failed to load the bitmap - this is very bad
Assertion( help_left_bracket_bitmap >= 0, "Failed to load bitmap left_bracket for help overlay\n");
atexit(close_help);
// parse help.tbl
Loaded 100 of 276 files, more files were not shown because too many files have changed in this diff. Show more