@@ -2387,6 +2387,7 @@ void ai_attack_object(object* attacker, object* attacked, int ship_info_index)
23872387
23882388 Assert(attacker != nullptr);
23892389 Assert(attacker->instance >= 0);
2390+ Assert(attacker->type == OBJ_SHIP);
23902391 Assert(Ships[attacker->instance].ai_index != -1);
23912392 // Bogus! Who tried to get me to attack myself!
23922393 if (attacker == attacked) {
@@ -10006,7 +10007,7 @@ void guard_object_was_hit(object *guard_objp, object *hitter_objp)
1000610007 aip->submode = SM_ATTACK;
1000710008 aip->submode_start_time = Missiontime;
1000810009 aip->active_goal = AI_ACTIVE_GOAL_DYNAMIC;
10009- } else {
10010+ } else if (Objects[aip->target_objnum].type == OBJ_SHIP) {
1001010011 int num_attacking_cur, num_attacking_new;
1001110012
1001210013 num_attacking_cur = num_ships_attacking(aip->target_objnum);
@@ -14482,6 +14483,9 @@ void validate_mode_submode(ai_info *aip)
1448214483 */
1448314484void ai_frame(int objnum)
1448414485{
14486+ // Cyborg - can you believe this was added in *2022*??
14487+ Assertion (Objects[objnum].type == OBJ_SHIP, "Ai_frame was called for a non-ship of type %d. Please report!", Objects[objnum].type);
14488+
1448514489 ship *shipp = &Ships[Objects[objnum].instance];
1448614490 ai_info *aip = &Ai_info[shipp->ai_index];
1448714491 int target_objnum;
@@ -14564,7 +14568,7 @@ void ai_frame(int objnum)
1456414568 } else if (aip->resume_goal_time == -1) {
1456514569 // AL 12-9-97: Don't allow cargo and navbuoys to set their aip->target_objnum
1456614570 if ( Ship_info[shipp->ship_info_index].class_type > -1 && (Ship_types[Ship_info[shipp->ship_info_index].class_type].flags[Ship::Type_Info_Flags::AI_auto_attacks]) ) {
14567- target_objnum = find_enemy(objnum, MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level]); // Attack up to 25K units away.
14571+ target_objnum = find_enemy(objnum, MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level]); // Attack up to 2.5K units away.
1456814572 if (target_objnum != -1) {
1456914573 if (aip->target_objnum != target_objnum)
1457014574 aip->aspect_locked_time = 0.0f;
@@ -15101,8 +15105,9 @@ void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t
1510115105
1510215106void ai_do_default_behavior(object *obj)
1510315107{
15104- Assert(obj != NULL );
15108+ Assert(obj != nullptr );
1510515109 Assert(obj->instance != -1);
15110+ Assert(obj->type == OBJ_SHIP);
1510615111 Assert(Ships[obj->instance].ai_index != -1);
1510715112
1510815113 ai_info *aip = &Ai_info[Ships[obj->instance].ai_index];
@@ -15201,118 +15206,125 @@ void maybe_process_friendly_hit(object *objp_hitter, object *objp_hit, object *o
1520115206 return;
1520215207 }
1520315208
15204- if ((obj_team(objp_hitter) == obj_team(objp_hit)) && (objp_hitter == Player_obj)) {
15209+ // Cyborg -- I had to switch around the logic here because it was potentially
15210+ // sending non-ships to obj_team, which would trigger an assert
15211+ if (objp_hitter == Player_obj){
1520515212
15206- // AL 12-4-97: It is possible the Player is a OBJ_GHOST at this point. If so, bail out.
15213+ // Cyborg - So check if this is a ship first. Probably true, but you never know, with FSO
15214+ // (especially in multi)
1520715215 if ( objp_hitter->type != OBJ_SHIP ) {
1520815216 return;
1520915217 }
1521015218
15211- Assert(objp_hitter->type == OBJ_SHIP);
15219+ // And assert that obj_hit is a ship as well.
1521215220 Assert(objp_hit->type == OBJ_SHIP);
15213- Assert((objp_weapon->type == OBJ_WEAPON) || (objp_weapon->type == OBJ_BEAM)); //beam added for traitor detection - FUBAR
15214-
15215- ship *shipp_hitter = &Ships[objp_hitter->instance];
15216- ship *shipp_hit = &Ships[objp_hit->instance];
15217-
15218- if (shipp_hitter->team != shipp_hit->team) {
15219- return;
15220- }
1522115221
15222- // get the player
15223- player *pp = &Players[Player_num];
15222+ if (obj_team(objp_hitter) == obj_team(objp_hit)) {
1522415223
15225- // wacky stuff here
15226- if (pp->friendly_hits != 0) {
15227- float time_since_last_hit = f2fl(Missiontime - pp->friendly_last_hit_time);
15228- if ((time_since_last_hit >= 0.0f) && (time_since_last_hit < 10000.0f)) {
15229- if (time_since_last_hit > 60.0f) {
15230- pp->friendly_hits = 0;
15231- pp->friendly_damage = 0.0f;
15232- } else if (time_since_last_hit > 2.0f) {
15233- pp->friendly_hits -= (int) time_since_last_hit/2;
15234- pp->friendly_damage -= time_since_last_hit;
15235- }
15224+ Assert((objp_weapon->type == OBJ_WEAPON) || (objp_weapon->type == OBJ_BEAM)); //beam added for traitor detection - FUBAR
1523615225
15237- if (pp->friendly_damage < 0.0f) {
15238- pp->friendly_damage = 0.0f;
15239- }
15226+ ship *shipp_hitter = &Ships[objp_hitter->instance];
15227+ ship *shipp_hit = &Ships[objp_hit->instance];
1524015228
15241- if (pp->friendly_hits < 0) {
15242- pp->friendly_hits = 0;
15243- }
15229+ if (shipp_hitter->team != shipp_hit->team) {
15230+ return;
1524415231 }
15245- }
15246-
15247- float damage; // Damage done by weapon. Gets scaled down based on size of ship.
1524815232
15249- if (objp_weapon->type == OBJ_BEAM) // added beam for traitor detection -FUBAR
15250- damage = beam_get_ship_damage(&Beams[objp_weapon->instance], objp_hit);
15251- else
15252- damage = Weapon_info[Weapons[objp_weapon->instance].weapon_info_index].damage;
15253-
15254- // wacky stuff here
15255- ship_info *sip = &Ship_info[Ships[objp_hit->instance].ship_info_index];
15256- if (shipp_hit->ship_max_hull_strength > 1000.0f) {
15257- float factor = shipp_hit->ship_max_hull_strength / 1000.0f;
15258- factor = MIN(100.0f, factor);
15259- damage /= factor;
15260- }
15233+ // get the player
15234+ player *pp = &Players[Player_num];
1526115235
15262- // Don't penalize much at all for hitting cargo
15263- if (sip->class_type > -1) {
15264- damage *= Ship_types[sip->class_type].ff_multiplier;
15265- }
15236+ // wacky stuff here
15237+ if (pp->friendly_hits != 0) {
15238+ float time_since_last_hit = f2fl(Missiontime - pp->friendly_last_hit_time);
15239+ if ((time_since_last_hit >= 0.0f) && (time_since_last_hit < 10000.0f)) {
15240+ if (time_since_last_hit > 60.0f) {
15241+ pp->friendly_hits = 0;
15242+ pp->friendly_damage = 0.0f;
15243+ } else if (time_since_last_hit > 2.0f) {
15244+ pp->friendly_hits -= (int) time_since_last_hit/2;
15245+ pp->friendly_damage -= time_since_last_hit;
15246+ }
1526615247
15267- // Hit ship, but not targeting it, so it's not so heinous, maybe an accident.
15268- if (Ai_info[shipp_hitter->ai_index].target_objnum != OBJ_INDEX(objp_hit)) {
15269- damage /= 5.0f;
15270- }
15248+ if (pp->friendly_damage < 0.0f) {
15249+ pp->friendly_damage = 0.0f;
15250+ }
1527115251
15272- pp->friendly_last_hit_time = Missiontime;
15273- pp->friendly_hits++;
15252+ if (pp->friendly_hits < 0) {
15253+ pp->friendly_hits = 0;
15254+ }
15255+ }
15256+ }
1527415257
15275- // cap damage and number of hits done this frame
15276- float accredited_damage = MIN(MAX_BURST_DAMAGE, pp->damage_this_burst + damage) - pp->damage_this_burst;
15277- pp->friendly_damage += accredited_damage;
15278- pp->damage_this_burst += accredited_damage;
15258+ float damage; // Damage done by weapon. Gets scaled down based on size of ship.
1527915259
15280- // Done with adjustments to damage. Evaluate based on current friendly_damage
15281- nprintf(("AI", "Friendly damage: %.1f, threshold: %.1f, inc damage: %.1f, max burst: %d\n", pp->friendly_damage, FRIENDLY_DAMAGE_THRESHOLD * (1.0f + (float) (NUM_SKILL_LEVELS + 1 - Game_skill_level)/3.0f), pp->damage_this_burst, MAX_BURST_DAMAGE ));
15282-
15283- if (is_instructor(objp_hit)) {
15284- // it's not nice to hit your instructor
15285- if (pp->friendly_damage > FRIENDLY_DAMAGE_THRESHOLD) {
15286- message_send_builtin_to_player( MESSAGE_INSTRUCTOR_ATTACK, NULL, MESSAGE_PRIORITY_HIGH, MESSAGE_TIME_IMMEDIATE, 0, 0, -1, -1);
15287- pp->last_warning_message_time = Missiontime;
15288- ship_set_subsystem_strength( Player_ship, SUBSYSTEM_WEAPONS, 0.0f);
15260+ if (objp_weapon->type == OBJ_BEAM) // added beam for traitor detection -FUBAR
15261+ damage = beam_get_ship_damage(&Beams[objp_weapon->instance], objp_hit);
15262+ else
15263+ damage = Weapon_info[Weapons[objp_weapon->instance].weapon_info_index].damage;
15264+
15265+ // wacky stuff here
15266+ ship_info *sip = &Ship_info[Ships[objp_hit->instance].ship_info_index];
15267+ if (shipp_hit->ship_max_hull_strength > 1000.0f) {
15268+ float factor = shipp_hit->ship_max_hull_strength / 1000.0f;
15269+ factor = MIN(100.0f, factor);
15270+ damage /= factor;
15271+ }
1528915272
15290- training_fail();
15273+ // Don't penalize much at all for hitting cargo
15274+ if (sip->class_type > -1) {
15275+ damage *= Ship_types[sip->class_type].ff_multiplier;
15276+ }
1529115277
15292- // Instructor leaves.
15293- mission_do_departure(objp_hit);
15294- gameseq_post_event( GS_EVENT_PLAYER_WARPOUT_START_FORCED ); // Force player to warp out.
15295- } else if (Missiontime - pp->last_warning_message_time > F1_0*4) {
15296- // warning every 4 sec
15297- // use NULL as the message sender here since it is the Terran Command persona
15298- message_send_builtin_to_player( MESSAGE_INSTRUCTOR_HIT, NULL, MESSAGE_PRIORITY_HIGH, MESSAGE_TIME_IMMEDIATE, 0, 0, -1, -1);
15299- pp->last_warning_message_time = Missiontime;
15278+ // Hit ship, but not targeting it, so it's not so heinous, maybe an accident.
15279+ if (Ai_info[shipp_hitter->ai_index].target_objnum != OBJ_INDEX(objp_hit)) {
15280+ damage /= 5.0f;
1530015281 }
1530115282
15302- // not nice to hit your friends
15303- } else if (pp->friendly_damage > FRIENDLY_DAMAGE_THRESHOLD * (1.0f + (float) (NUM_SKILL_LEVELS + 1 - Game_skill_level)/3.0f)) {
15304- process_friendly_hit_message( MESSAGE_HAMMER_SWINE, objp_hit );
15305- mission_goal_fail_all();
15306- ai_abort_rearm_request( Player_obj );
15283+ pp->friendly_last_hit_time = Missiontime;
15284+ pp->friendly_hits++;
1530715285
15308- Player_ship->team = Iff_traitor;
15286+ // cap damage and number of hits done this frame
15287+ float accredited_damage = MIN(MAX_BURST_DAMAGE, pp->damage_this_burst + damage) - pp->damage_this_burst;
15288+ pp->friendly_damage += accredited_damage;
15289+ pp->damage_this_burst += accredited_damage;
1530915290
15310- } else if ((damage > frand()) && (Missiontime - pp->last_warning_message_time > F1_0*4) && (pp->friendly_damage > FRIENDLY_DAMAGE_THRESHOLD)) {
15311- // no closer than 4 sec intervals
15312- // Note: (damage > frand()) added on 12/9/97 by MK. Since damage is now scaled down for big ships, we could get too
15313- // many warnings. Kind of tedious. frand() returns a value in 0..1, so this won't affect legit hits.
15314- process_friendly_hit_message( MESSAGE_OOPS, objp_hit );
15315- pp->last_warning_message_time = Missiontime;
15291+ // Done with adjustments to damage. Evaluate based on current friendly_damage
15292+ nprintf(("AI", "Friendly damage: %.1f, threshold: %.1f, inc damage: %.1f, max burst: %d\n", pp->friendly_damage, FRIENDLY_DAMAGE_THRESHOLD * (1.0f + (float) (NUM_SKILL_LEVELS + 1 - Game_skill_level)/3.0f), pp->damage_this_burst, MAX_BURST_DAMAGE ));
15293+
15294+ if (is_instructor(objp_hit)) {
15295+ // it's not nice to hit your instructor
15296+ if (pp->friendly_damage > FRIENDLY_DAMAGE_THRESHOLD) {
15297+ message_send_builtin_to_player( MESSAGE_INSTRUCTOR_ATTACK, NULL, MESSAGE_PRIORITY_HIGH, MESSAGE_TIME_IMMEDIATE, 0, 0, -1, -1);
15298+ pp->last_warning_message_time = Missiontime;
15299+ ship_set_subsystem_strength( Player_ship, SUBSYSTEM_WEAPONS, 0.0f);
15300+
15301+ training_fail();
15302+
15303+ // Instructor leaves.
15304+ mission_do_departure(objp_hit);
15305+ gameseq_post_event( GS_EVENT_PLAYER_WARPOUT_START_FORCED ); // Force player to warp out.
15306+ } else if (Missiontime - pp->last_warning_message_time > F1_0*4) {
15307+ // warning every 4 sec
15308+ // use NULL as the message sender here since it is the Terran Command persona
15309+ message_send_builtin_to_player( MESSAGE_INSTRUCTOR_HIT, NULL, MESSAGE_PRIORITY_HIGH, MESSAGE_TIME_IMMEDIATE, 0, 0, -1, -1);
15310+ pp->last_warning_message_time = Missiontime;
15311+ }
15312+
15313+ // not nice to hit your friends
15314+ } else if (pp->friendly_damage > FRIENDLY_DAMAGE_THRESHOLD * (1.0f + (float) (NUM_SKILL_LEVELS + 1 - Game_skill_level)/3.0f)) {
15315+ process_friendly_hit_message( MESSAGE_HAMMER_SWINE, objp_hit );
15316+ mission_goal_fail_all();
15317+ ai_abort_rearm_request( Player_obj );
15318+
15319+ Player_ship->team = Iff_traitor;
15320+
15321+ } else if ((damage > frand()) && (Missiontime - pp->last_warning_message_time > F1_0*4) && (pp->friendly_damage > FRIENDLY_DAMAGE_THRESHOLD)) {
15322+ // no closer than 4 sec intervals
15323+ // Note: (damage > frand()) added on 12/9/97 by MK. Since damage is now scaled down for big ships, we could get too
15324+ // many warnings. Kind of tedious. frand() returns a value in 0..1, so this won't affect legit hits.
15325+ process_friendly_hit_message( MESSAGE_OOPS, objp_hit );
15326+ pp->last_warning_message_time = Missiontime;
15327+ }
1531615328 }
1531715329 }
1531815330}
@@ -15541,7 +15553,7 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hit_normal)
1554115553 objp_hitter = &Objects[hitter_objnum];
1554215554
1554315555 // lets not check hits by ghosts any further either
15544- if(objp_hitter->type == OBJ_GHOST )
15556+ if(objp_hitter->type != OBJ_SHIP && objp_hitter->type != OBJ_WEAPON && objp_hitter->type != OBJ_ASTEROID && objp_hitter->type != OBJ_BEAM )
1554515557 return;
1554615558
1554715559 // Hit by a protected ship, don't attack it.
@@ -16139,6 +16151,8 @@ void maybe_cheat_fire_synaptic(object *objp)
1613916151 ship *shipp;
1614016152 int wing_index, time;
1614116153
16154+ Assertion(objp->type == OBJ_SHIP, "maybe_cheat_fire_synaptic was called with a non-ship object type of %d. Please report!", objp->type);
16155+
1614216156 shipp = &Ships[objp->instance];
1614316157
1614416158 if (!(strnicmp(shipp->ship_name, NOX("delta"), 5)))
0 commit comments