Skip to content

Commit

Permalink
Merge pull request #2342 from Goober5000/mantis_1947
Browse files Browse the repository at this point in the history
implement Mantis 1947, treat ship comm systems the same as player comm systems
  • Loading branch information
Goober5000 committed May 10, 2020
2 parents 771d0c7 + cc39cfe commit 1d471e2
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 149 deletions.
1 change: 1 addition & 0 deletions code/ai/ai_flags.h
Expand Up @@ -84,6 +84,7 @@ namespace AI {
Assist_scoring_scales_with_damage,
Beams_damage_weapons,
Big_ships_can_attack_beam_turrets_on_untargeted_ships,
Check_comms_for_non_player_ships,
Disable_linked_fire_penalty,
Disable_player_secondary_doublefire,
Disable_ai_secondary_doublefire,
Expand Down
2 changes: 2 additions & 0 deletions code/ai/ai_profiles.cpp
Expand Up @@ -371,6 +371,8 @@ void parse_ai_profiles_tbl(const char *filename)

set_flag(profile, "$navigation subsystem governs warpout capability:", AI::Profile_Flags::Navigation_subsys_governs_warp);

set_flag(profile, "$check communications for non-player ships:", AI::Profile_Flags::Check_comms_for_non_player_ships);

set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AI::Profile_Flags::No_min_dock_speed_cap);

set_flag(profile, "$disable linked fire penalty:", AI::Profile_Flags::Disable_linked_fire_penalty);
Expand Down
4 changes: 4 additions & 0 deletions code/ai/aicode.cpp
Expand Up @@ -66,6 +66,7 @@
#include "ship/ship.h"
#include "ship/shipfx.h"
#include "ship/shiphit.h"
#include "ship/subsysdamage.h"
#include "weapon/beam.h"
#include "weapon/flak.h"
#include "weapon/swarm.h"
Expand Down Expand Up @@ -14530,6 +14531,9 @@ void process_friendly_hit_message( int message, object *objp )
if (Ships[objp->instance].flags[Ship::Ship_Flags::No_builtin_messages]) {
index = -1;
}
if (The_mission.ai_profile->flags[AI::Profile_Flags::Check_comms_for_non_player_ships] && hud_communications_state(&Ships[objp->instance]) <= COMM_DAMAGED) {
index = -1;
}

// Karajorma - pick a random ship to send Command messages if command is silenced.
if (index < 0 && (The_mission.flags[Mission::Mission_Flags::No_builtin_command]) ) {
Expand Down
118 changes: 43 additions & 75 deletions code/hud/hudsquadmsg.cpp
Expand Up @@ -238,8 +238,9 @@ SCP_vector<squadmsg_history> Squadmsg_history;
// forward declarations
void hud_add_issued_order(const char *name, int order);
void hud_update_last_order(char *target, int order_source, int special_index);
int hud_squadmsg_is_target_order_valid(int order, int find_order, ai_info *aip = NULL );
int hud_squadmsg_ship_order_valid( int shipnum, int order );
bool hud_squadmsg_is_target_order_valid(int order, int find_order, ai_info *aip = nullptr);
bool hud_squadmsg_ship_valid(ship *shipp, object *objp = nullptr);
bool hud_squadmsg_ship_order_valid( int shipnum, int order );

// function to set up variables needed when messaging mode is started
void hud_squadmsg_start()
Expand Down Expand Up @@ -300,31 +301,15 @@ bool hud_squadmsg_exist_fighters( )
{
objp = &Objects[so->objnum];
shipp = &Ships[objp->instance];
Assert ( shipp->objnum != -1 );
Assertion(shipp->objnum != -1, "hud_squadmsg_exist_fighters() discovered that ship #%d ('%s') has an objnum of -1. Since the ship was retrieved from its object number (%d), this should be impossible; get a coder!\n", objp->instance, shipp->ship_name, so->objnum);

// check fighter is accepting orders
if (shipp->orders_accepted == 0)
continue;

// be sure ship is on correct team
#ifdef NDEBUG
if (shipp->team != Player_ship->team)
continue;
#else
if (!Msg_enemies && (shipp->team != Player_ship->team))
continue;
#endif

// cannot be my ship or an instructor
if ((objp == Player_obj) || is_instructor(objp))
continue;

// ship must be a fighter/bomber
if ( !(Ship_info[shipp->ship_info_index].is_fighter_bomber()) )
if (!(Ship_info[shipp->ship_info_index].is_fighter_bomber()))
continue;

// this ship satisfies everything
return true;
if (hud_squadmsg_ship_valid(shipp, objp))
return true;
}

return false;
Expand All @@ -337,7 +322,7 @@ bool hud_squadmsg_ship_valid(ship *shipp, object *objp)
if (!objp) // For simplicity's sake, allow it to be called with just the ship pointer
objp = &Objects[shipp->objnum];

// ships must be able to receive a message
// ships must be able to receive orders
if ( Ship_info[shipp->ship_info_index].class_type < 0 || !(Ship_types[Ship_info[shipp->ship_info_index].class_type].flags[Ship::Type_Info_Flags::AI_accept_player_orders]) )
return false;

Expand Down Expand Up @@ -374,6 +359,10 @@ bool hud_squadmsg_ship_valid(ship *shipp, object *objp)
return false;
}

// maybe check comm system
if (The_mission.ai_profile->flags[AI::Profile_Flags::Check_comms_for_non_player_ships] && hud_communications_state(shipp) != COMM_OK)
return false;

// If we got to this point, the ship must be valid.
return true;
}
Expand Down Expand Up @@ -420,14 +409,14 @@ int hud_squadmsg_count_ships(int add_to_menu)
}

// routine to return true if a wing should be put onto the messaging menu
int hud_squadmsg_wing_valid(wing *wingp)
bool hud_squadmsg_wing_valid(wing *wingp)
{
int idx, ship_num;

// a couple of special cases to account for before adding to count (or to menu). Don't count
// wings that are leaving or left.
if ( wingp->flags[Ship::Wing_Flags::Gone, Ship::Wing_Flags::Departing] )
return 0;
return false;

// Goober5000 - instead of checking wing leader, let's check all ships in wing;
// there are several significant cases when e.g. wings contain ships of different IFFs
Expand All @@ -436,34 +425,13 @@ int hud_squadmsg_wing_valid(wing *wingp)
ship_num = wingp->ship_index[idx];
Assert(ship_num >= 0);

// don't check player
if (ship_num == SHIP_INDEX(Player_ship))
continue;

// be sure ship is on same team
#ifdef NDEBUG
if (Ships[ship_num].team != Player_ship->team)
continue;
#else
if (!Msg_enemies && (Ships[ship_num].team != Player_ship->team))
continue;
#endif

// check if ship is accepting orders
if (Ships[ship_num].orders_accepted == 0)
continue;

// if doing a message shortcut is being used, be sure the ship can "accept" the command.
if ( Msg_shortcut_command >= 0 && !(Ships[ship_num].orders_accepted & Msg_shortcut_command) )
return 0;


// at least one ship in this wing is valid, and that's all we need
return 1;
// if at least one ship in this wing is valid, that's all we need
if (hud_squadmsg_ship_valid(&Ships[ship_num]))
return true;
}

// no ships in the wing were valid
return 0;
return false;
}

// function like above, except for wings
Expand Down Expand Up @@ -766,8 +734,8 @@ void hud_squadmsg_repair_rearm_abort( int toggle_state, object *obj)
}

// Goober5000 - redone and added a bit
// returns 1 if an order is valid for a ship. Applies to things like departure when engines are blown, etc.
int hud_squadmsg_ship_order_valid( int shipnum, int order )
// returns true if an order is valid for a ship. Applies to things like departure when engines are blown, etc.
bool hud_squadmsg_ship_order_valid( int shipnum, int order )
{
// Goober5000
Assert( shipnum >= 0 && shipnum < MAX_SHIPS );
Expand All @@ -778,7 +746,7 @@ int hud_squadmsg_ship_order_valid( int shipnum, int order )
case DEPART_ITEM:
// disabled ships can't depart.
if (shipp->flags[Ship::Ship_Flags::Disabled])
return 0;
return false;

// Goober5000: also can't depart if no subspace drives and no valid mothership
if (shipp->flags[Ship::Ship_Flags::No_subspace_drive])
Expand All @@ -788,21 +756,21 @@ int hud_squadmsg_ship_order_valid( int shipnum, int order )
{
int anchor_shipnum = ship_name_lookup(Parse_names[shipp->departure_anchor]);
if (anchor_shipnum >= 0 && ship_useful_for_departure(anchor_shipnum, shipp->departure_path_mask))
return 1;
return true;
}

return 0;
return false;
}

break;
}
return 1;
return true;
}

// returns true or false if the Players target is valid for the given order
// find_order is true when we need to search the comm_orders array for the order entry. We have
// to do this action in some cases since all we know is the actual "value" of the order
int hud_squadmsg_is_target_order_valid(int order, int find_order, ai_info *aip )
bool hud_squadmsg_is_target_order_valid(int order, int find_order, ai_info *aip )
{
int target_objnum, i;
ship *shipp, *ordering_shipp;
Expand All @@ -823,77 +791,77 @@ int hud_squadmsg_is_target_order_valid(int order, int find_order, ai_info *aip )

// orders which don't operate on targets are always valid
if ( !(Comm_orders[order].item & TARGET_MESSAGES) )
return 1;
return true;

target_objnum = aip->target_objnum;

// order isn't valid if there is no player target
if ( target_objnum == -1 ) {
return 0;
return false;
}

objp = &Objects[target_objnum];

ordering_shipp = &Ships[aip->shipnum];

// target isn't a ship, then return 0
// target isn't a ship, then return false
if ( (objp->type != OBJ_SHIP) && (objp->type != OBJ_WEAPON) )
return 0;
return false;

// if it's a weapon, then it needs to be a WIF_BOMB weapon. Only attack order valid, and only
// valid on bombs not on the player's team
// MageKing17: Now also works on WIF3_FIGHTER_INTERCEPTABLE weapons.
if ( objp->type == OBJ_WEAPON ) {

if (Weapons[objp->instance].lssm_stage==3){
return 0;
return false;
}

if ( (Comm_orders[order].item == ATTACK_TARGET_ITEM )
&& ((Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags[Weapon::Info_Flags::Bomb]) || (Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags[Weapon::Info_Flags::Fighter_Interceptable]))
&& (Weapons[objp->instance].team != ordering_shipp->team) )

return 1;
&& (Weapons[objp->instance].team != ordering_shipp->team) ) {
return true;
}

return 0;
return false;
}

Assert( objp->type == OBJ_SHIP );

shipp = &Ships[objp->instance];

// if target is a navbouy, return 0
// if target is a navbouy, return false
if ( Ship_info[shipp->ship_info_index].flags[Ship::Info_Flags::Navbuoy] ){
return 0;
return false;
}

// if we are messaging a ship, and that ship is our target, no target type orders are ever active
if ( (Squad_msg_mode == SM_MODE_SHIP_COMMAND) && (Objects[target_objnum].instance == Msg_instance) ){
return 0;
return false;
}

// if the order is a disable order or depart, and the ship is disabled, order isn't active
if ( (Comm_orders[order].item == DISABLE_TARGET_ITEM) && (shipp->flags[Ship::Ship_Flags::Disabled]) ){
return 0;
return false;
}

// same as above except for disarmed.
if ( (Comm_orders[order].item == DISARM_TARGET_ITEM) && ((shipp->subsys_info[SUBSYSTEM_TURRET].type_count == 0) || (shipp->subsys_info[SUBSYSTEM_TURRET].aggregate_current_hits <= 0.0f)) ){
return 0;
return false;
}

// if order is disable subsystem, and no subsystem targeted or no hits, then order not valid
if ( (Comm_orders[order].item == DISABLE_SUBSYSTEM_ITEM) && ((aip->targeted_subsys == NULL) || (aip->targeted_subsys->current_hits <= 0.0f)) ){
return 0;
return false;
}

// check based on target's and player's team
if ( (shipp->team == ordering_shipp->team) && (FRIENDLY_TARGET_MESSAGES & Comm_orders[order].item) ){
return 1;
return true;
} else if ( (shipp->team != ordering_shipp->team) && (ENEMY_TARGET_MESSAGES & Comm_orders[order].item) ){
return 1;
return true;
} else {
return 0;
return false;
}
}

Expand Down
12 changes: 6 additions & 6 deletions code/hud/hudtarget.cpp
Expand Up @@ -4558,7 +4558,7 @@ int hud_sensors_ok(ship *sp, int show_msg)
}
}

int hud_communications_state(ship *sp)
int hud_communications_state(ship *sp, bool for_death_scream)
{
float str;

Expand All @@ -4572,18 +4572,18 @@ int hud_communications_state(ship *sp)
if ((sp == Player_ship) && (sp->flags[Ship::Ship_Flags::Dying]))
return COMM_OK;

// Goober5000 - check for scrambled communications
if ( emp_active_local() || sp->flags[Ship::Ship_Flags::Scramble_messages] )
return COMM_SCRAMBLED;

str = ship_get_subsystem_strength( sp, SUBSYSTEM_COMMUNICATION );
str = ship_get_subsystem_strength( sp, SUBSYSTEM_COMMUNICATION, for_death_scream );

if ( (str <= 0.01) || ship_subsys_disrupted(sp, SUBSYSTEM_COMMUNICATION) ) {
return COMM_DESTROYED;
} else if ( str < MIN_COMM_STR_TO_MESSAGE ) {
return COMM_DAMAGED;
}

// Goober5000 - check for scrambled communications
if (emp_active_local() || sp->flags[Ship::Ship_Flags::Scramble_messages])
return COMM_SCRAMBLED;

return COMM_OK;
}

Expand Down
2 changes: 1 addition & 1 deletion code/hud/hudtarget.h
Expand Up @@ -125,7 +125,7 @@ void hud_update_weapon_flash();
void hud_process_homing_missiles(void);

int hud_sensors_ok(ship *sp, int show_msg = 1);
int hud_communications_state(ship *sp);
int hud_communications_state(ship *sp, bool for_death_scream = false);

int hud_get_best_primary_bank(float *range);
void hud_target_toggle_hidden_from_sensors();
Expand Down

0 comments on commit 1d471e2

Please sign in to comment.