Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/ai/ai_profiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ extern int Num_ai_profiles;
extern int Default_ai_profile;
extern ai_profile_t Ai_profiles[MAX_AI_PROFILES];

#define AI_PROFILES_INDEX(ai_p) ((int)((ai_p) - Ai_profiles))
#define AI_PROFILES_INDEX(ai_p) (static_cast<int>((ai_p)-Ai_profiles))

void ai_profiles_init();

Expand Down
2 changes: 1 addition & 1 deletion code/ai/aiturret.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1755,7 +1755,7 @@ bool turret_fire_weapon(int weapon_num,

parent_aip = &Ai_info[Ships[Objects[parent_objnum].instance].ai_index];
parent_ship = &Ships[Objects[parent_objnum].instance];
int turret_weapon_class = weapon_info_get_index(wip);
int turret_weapon_class = WEAPON_INFO_INDEX(wip);

#ifndef NDEBUG
// moved here from check_ok_to_fire
Expand Down
2 changes: 1 addition & 1 deletion code/debris/debris.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int Debris_num_submodels = 0;

particle::ParticleEffectHandle Debris_hit_particle;

#define DEBRIS_INDEX(dp) (int)(dp-Debris.data())
#define DEBRIS_INDEX(dp) (static_cast<int>((dp)-Debris.data()))

// Find the first available arc slot. If none is available, and no_create is false, add one.
debris_electrical_arc *debris_find_or_create_electrical_arc_slot(debris *db, bool no_create);
Expand Down
47 changes: 38 additions & 9 deletions code/mission/missionparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4801,8 +4801,26 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, bool force_create,
wingp->total_arrived_count++;
if (wingp->num_waves > 1)
{
char pre_bash_name[NAME_LENGTH];
strcpy_s(pre_bash_name, p_objp->name);

wing_bash_ship_name(p_objp, wingp, wingp->total_arrived_count + wingp->red_alert_skipped_ships);

// if the bash renamed this parse object (which can happen if the ship was saved using the legacy
// hash format), re-key its not-yet-present registry entry so that the old name doesn't shadow
// lookups of the new name. (For subsequent waves, the pre-bash name belongs to a previous wave's
// ship, whose entry must keep its key; the status and parse object checks exclude that case.)
if (stricmp(pre_bash_name, p_objp->name) != 0)
{
auto ship_it = Ship_registry_map.find(pre_bash_name);
if (ship_it != Ship_registry_map.end()
&& Ship_registry[ship_it->second].status == ShipStatus::NOT_YET_PRESENT
&& Ship_registry[ship_it->second].pobj_num == POBJ_INDEX(p_objp))
{
ship_registry_rename(ship_it->second, p_objp->name, true);
}
}

// subsequent waves of ships will not be in the ship registry, so add them
if (!ship_registry_exists(p_objp->name))
{
Expand Down Expand Up @@ -8026,6 +8044,17 @@ int mission_parse_get_multi_mission_info( const char *filename )
return The_mission.num_players;
}

static p_object *mission_parse_get_arrival_ship_sub(const char *name)
{
for (auto p_objp : list_range(&Ship_arrival_list))
{
if (!stricmp(p_objp->name, name))
return p_objp; // still on the arrival list
}

return nullptr;
}

/**
* @brief Returns the parse object on the ship arrival list associated with the given name.
* @param[in] name The name of the object
Expand All @@ -8036,18 +8065,18 @@ int mission_parse_get_multi_mission_info( const char *filename )
*/
p_object *mission_parse_get_arrival_ship(const char *name)
{
p_object *p_objp;

if (name == nullptr)
return nullptr;

for (p_objp = GET_FIRST(&Ship_arrival_list); p_objp != END_OF_LIST(&Ship_arrival_list); p_objp = GET_NEXT(p_objp))
{
if (!stricmp(p_objp->name, name))
{
return p_objp; // still on the arrival list
}
}
// try the normal lookup
auto p_objp = mission_parse_get_arrival_ship_sub(name);
if (p_objp)
return p_objp;

// also search for ship names hashed using the legacy format
SCP_string legacy_hashed;
if (wing_bash_legacy_hashed_ship_name(legacy_hashed, name))
return mission_parse_get_arrival_ship_sub(legacy_hashed.c_str());

return nullptr;
}
Expand Down
2 changes: 1 addition & 1 deletion code/mission/missionparse.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ class p_object

// Goober5000 - this is now dynamic
extern SCP_vector<p_object> Parse_objects;
#define POBJ_INDEX(pobjp) (int)(pobjp - &Parse_objects[0]) // yes, this arithmetic is valid :D
#define POBJ_INDEX(pobjp) (static_cast<int>((pobjp)-Parse_objects.data()))

extern p_object Support_ship_pobj, *Arriving_support_ship;
extern p_object Ship_arrival_list;
Expand Down
2 changes: 1 addition & 1 deletion code/network/multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class player;
//

// netplayer management
#define NET_PLAYER_INDEX(np) (static_cast<int>(np-Net_players))
#define NET_PLAYER_INDEX(np) (static_cast<int>((np)-Net_players))
#define NET_PLAYER_NUM(np) (NET_PLAYER_INDEX(np))
#define MY_NET_PLAYER_NUM (NET_PLAYER_INDEX(Net_player))

Expand Down
2 changes: 1 addition & 1 deletion code/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ extern object *Player_obj; // Which object is the player. Has to be valid.
// given it's pointer. This way, we can replace it with a macro
// to check that the pointer is valid for debugging.
// This code will break in 64 bit builds when we have more than 2^31 objects but that will probably never happen
#define OBJ_INDEX(objp) static_cast<int>(objp-Objects)
#define OBJ_INDEX(objp) (static_cast<int>((objp)-Objects))

/*
* FUNCTIONS
Expand Down
10 changes: 9 additions & 1 deletion code/parse/sexp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5846,7 +5846,15 @@ const ship_registry_entry *eval_ship(int node)
return eval_ship(arg_node);
}

auto ship_it = Ship_registry_map.find(CTEXT(node));
// look up the ship in the ship registry
auto ship_name = CTEXT(node);
auto ship_it = Ship_registry_map.find(ship_name);
if (ship_it == Ship_registry_map.end())
{
SCP_string legacy_hashed;
if (wing_bash_legacy_hashed_ship_name(legacy_hashed, ship_name))
ship_it = Ship_registry_map.find(legacy_hashed);
}
if (ship_it != Ship_registry_map.end())
{
// cache the value if it can't change later
Expand Down
105 changes: 94 additions & 11 deletions code/ship/ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ int ship_registry_get_index(const char *name)
if (ship_it != Ship_registry_map.end())
return ship_it->second;

// also search for ship names hashed using the legacy format
SCP_string legacy_hashed;
if (wing_bash_legacy_hashed_ship_name(legacy_hashed, name))
{
ship_it = Ship_registry_map.find(legacy_hashed);
if (ship_it != Ship_registry_map.end())
return ship_it->second;
}

return -1;
}

Expand All @@ -247,6 +256,15 @@ int ship_registry_get_index(const SCP_string &name)
if (ship_it != Ship_registry_map.end())
return ship_it->second;

// also search for ship names hashed using the legacy format
SCP_string legacy_hashed;
if (wing_bash_legacy_hashed_ship_name(legacy_hashed, name.c_str()))
{
ship_it = Ship_registry_map.find(legacy_hashed);
if (ship_it != Ship_registry_map.end())
return ship_it->second;
}

return -1;
}

Expand All @@ -267,18 +285,18 @@ bool ship_registry_exists(int index)

const ship_registry_entry *ship_registry_get(const char *name)
{
auto ship_it = Ship_registry_map.find(name);
if (ship_it != Ship_registry_map.end())
return &Ship_registry[ship_it->second];
auto idx = ship_registry_get_index(name);
if (idx >= 0)
return &Ship_registry[idx];

return nullptr;
}

const ship_registry_entry *ship_registry_get(const SCP_string &name)
{
auto ship_it = Ship_registry_map.find(name);
if (ship_it != Ship_registry_map.end())
return &Ship_registry[ship_it->second];
auto idx = ship_registry_get_index(name);
if (idx >= 0)
return &Ship_registry[idx];

return nullptr;
}
Expand All @@ -297,6 +315,27 @@ const ship_registry_entry *ship_registry_get(anchor_t anchor)
return ship_registry_get(anchor.value());
}

void ship_registry_rename(int entry_index, const char *new_name, bool erase_old_key)
{
Assertion(Ship_registry.in_bounds(entry_index), "Invalid ship registry index %d passed to ship_registry_rename!", entry_index);
if (!Ship_registry.in_bounds(entry_index))
return;

auto entry = &Ship_registry[entry_index];

// the old key is sometimes useful for looking up the ship under its previous name;
// if not, remove it (provided it actually refers to this entry)
if (erase_old_key)
{
auto ship_it = Ship_registry_map.find(entry->name);
if (ship_it != Ship_registry_map.end() && ship_it->second == entry_index)
Ship_registry_map.erase(ship_it);
}

strcpy_s(entry->name, new_name);
Ship_registry_map[entry->name] = entry_index;
}


int Num_engine_wash_types;
int Num_ship_subobj_types;
Expand Down Expand Up @@ -15028,6 +15067,34 @@ void wing_bash_ship_name(ship *shipp, const wing *wingp, int ordinal, bool reset
}
}

bool wing_bash_legacy_hashed_ship_name(SCP_string &dest, const char *src)
{
// missions might have ships within wings that were saved using the legacy hash format, with the hash suffix at the end
auto hash = get_pointer_to_first_hash_symbol(src);
if (hash && *(hash + 1) != '\0')
{
// find the run of digits immediately preceding the hash
auto digits = hash;
while (digits > src && isdigit(static_cast<unsigned char>(*(digits - 1))))
digits--;

// the ordinal must be at least one digit, preceded by a space, preceded by the wing name
if (digits < hash && digits > (src + 1) && *(digits - 1) == ' ')
{
// move the ordinal from before the hash to the end of the name
dest.assign(src, digits - 1);
dest += hash;
dest += ' ';
dest.append(digits, hash);

// we changed it
return true;
}
}

return false;
}

/**
* Return the object index of the ship with name *name.
*/
Expand Down Expand Up @@ -15251,10 +15318,7 @@ int ship_info_lookup(const char *token)
return ship_info_lookup_sub(name);
}

/**
* Return the ship index of the ship with name *name.
*/
int ship_name_lookup(const char *name, int inc_players)
static int ship_name_lookup_sub(const char *name, int inc_players)
{
Assertion(name != nullptr, "NULL name passed to ship_name_lookup");

Expand All @@ -15272,7 +15336,26 @@ int ship_name_lookup(const char *name, int inc_players)
return -1;
}

int ship_type_name_lookup_sub(const char *name)
/**
* Return the ship index of the ship with name *name.
*/
int ship_name_lookup(const char *name, int inc_players)
{
// try the normal lookup
auto idx = ship_name_lookup_sub(name, inc_players);
if (idx >= 0)
return idx;

// also search for ship names hashed using the legacy format
SCP_string legacy_hashed;
if (wing_bash_legacy_hashed_ship_name(legacy_hashed, name))
return ship_name_lookup_sub(legacy_hashed.c_str(), inc_players);

// couldn't find it
return -1;
}

static int ship_type_name_lookup_sub(const char *name)
{
Assertion(name != nullptr, "NULL name passed to ship_type_name_lookup");

Expand Down
9 changes: 6 additions & 3 deletions code/ship/ship.h
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,7 @@ extern const ship_registry_entry *ship_registry_get(const char *name);
extern const ship_registry_entry *ship_registry_get(const SCP_string &name);
extern const ship_registry_entry *ship_registry_get(int index);
extern const ship_registry_entry *ship_registry_get(anchor_t anchor);
extern void ship_registry_rename(int entry_index, const char *new_name, bool erase_old_key);

#define REGULAR_WEAPON (1<<0)
#define DOGFIGHT_WEAPON (1<<1)
Expand Down Expand Up @@ -1769,9 +1770,9 @@ extern SCP_vector<wing_formation> Wing_formations;

// Use the below macros when you want to find the index of an array element in the
// Wings[] or Ships[] arrays.
#define WING_INDEX(wingp) (static_cast<int>(wingp-Wings))
#define SHIP_INDEX(shipp) (static_cast<int>(shipp-Ships))
#define SHIP_REGISTRY_INDEX(ship_entry) (static_cast<int>(ship_entry-Ship_registry.data()))
#define WING_INDEX(wingp) (static_cast<int>((wingp)-Wings))
#define SHIP_INDEX(shipp) (static_cast<int>((shipp)-Ships))
#define SHIP_REGISTRY_INDEX(ship_entry) (static_cast<int>((ship_entry)-Ship_registry.data()))


extern void ship_init(); // called once at game start
Expand Down Expand Up @@ -1876,6 +1877,8 @@ extern void wing_bash_ship_name(SCP_string &ship_name, const char *wing_name, in
extern void wing_bash_ship_name(char *ship_name, const char *wing_name, int ordinal);
extern void wing_bash_ship_name(p_object *p_objp, const wing *wingp, int ordinal, bool reset_display_name_if_normal = false);
extern void wing_bash_ship_name(ship *shipp, const wing *wingp, int ordinal, bool reset_display_name_if_normal = false);
extern bool wing_bash_legacy_hashed_ship_name(SCP_string &dest, const char *src);

extern int Player_ship_class;

// Do the special effect for energy dissipating into the shield for a hit.
Expand Down
2 changes: 1 addition & 1 deletion code/weapon/beam.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ typedef struct beam {
extern std::array<beam, MAX_BEAMS> Beams; // all beams
extern int Beam_count;

#define BEAM_INDEX(beam) (int)((beam) - Beams.data())
#define BEAM_INDEX(beam) (static_cast<int>((beam)-Beams.data()))

// ------------------------------------------------------------------------------------------------
// BEAM WEAPON FUNCTIONS
Expand Down
2 changes: 1 addition & 1 deletion code/weapon/shockwave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ int Shockwave_inited = 0;
// -----------------------------------------------------------
// Function macros
// -----------------------------------------------------------
#define SW_INDEX(sw) (sw-Shockwaves)
#define SW_INDEX(sw) (static_cast<int>((sw)-Shockwaves))

// -----------------------------------------------------------
// Externals
Expand Down
2 changes: 1 addition & 1 deletion code/weapon/swarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ void turret_swarm_set_up_info(int parent_objnum, ship_subsys *turret, const weap
int bank_fired = swp->current_secondary_bank;

// initialize tsi
tsi->weapon_class = weapon_info_get_index(wip);
tsi->weapon_class = WEAPON_INFO_INDEX(wip);
if (wip->wi_flags[Weapon::Info_Flags::Swarm]) {
tsi->num_to_launch = wip->swarm_count;
} else {
Expand Down
4 changes: 2 additions & 2 deletions code/weapon/weapon.h
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,8 @@ extern int Default_cmeasure_index;

extern SCP_vector<int> Player_weapon_precedence; // Vector of weapon types, precedence list for player weapon selection

#define WEAPON_INDEX(wp) (int)(wp-Weapons)
#define WEAPON_INDEX(wp) (static_cast<int>((wp)-Weapons))
#define WEAPON_INFO_INDEX(wip) (static_cast<int>((wip)-Weapon_info.data()))

typedef struct tracking_info {
ship_subsys *subsys;
Expand All @@ -988,7 +989,6 @@ typedef struct tracking_info {
} tracking_info;

int weapon_info_lookup(const char *name);
int weapon_info_get_index(const weapon_info *wip);

inline int weapon_info_size()
{
Expand Down
Loading
Loading