diff --git a/code/mission/missionparse.cpp b/code/mission/missionparse.cpp index 8cfdaf5781e..483c142db5d 100644 --- a/code/mission/missionparse.cpp +++ b/code/mission/missionparse.cpp @@ -8703,7 +8703,7 @@ void check_anchor_for_hangar_bay(SCP_string &message, SCP_set &anchor_shipn return; anchor_shipnums_checked.insert(anchor_shipnum); - if (!ship_has_dock_bay(anchor_shipnum)) + if (!ship_has_hangar_bay(anchor_shipnum)) { auto shipp = &Ships[anchor_shipnum]; sprintf(message, "%s (%s) is used as a%s anchor by %s %s (and possibly elsewhere too), but it does not have a hangar bay!", shipp->ship_name, diff --git a/code/model/model.h b/code/model/model.h index cd1c3562f8c..66d799700de 100644 --- a/code/model/model.h +++ b/code/model/model.h @@ -1254,6 +1254,7 @@ int model_get_dock_types(int modelnum); // Goober5000 // returns index in [0, MAX_SHIP_BAY_PATHS) int model_find_bay_path(int modelnum, char *bay_path_name); +bool model_has_hangar_bay(int modelnum); // Returns number of polygons in a submodel; int submodel_get_num_polys(int model_num, int submodel_num); diff --git a/code/model/modelread.cpp b/code/model/modelread.cpp index 11f671cb817..cf22498f26c 100644 --- a/code/model/modelread.cpp +++ b/code/model/modelread.cpp @@ -5431,6 +5431,14 @@ int model_find_bay_path(int modelnum, char *bay_path_name) return -1; } +bool model_has_hangar_bay(int modelnum) +{ + auto pm = model_get(modelnum); + Assertion(pm, "modelnum %d does not exist!", modelnum); + + return ( pm->ship_bay && (pm->ship_bay->num_paths > 0) ); +} + int model_create_bsp_collision_tree() { // first find an open slot diff --git a/code/parse/sexp.cpp b/code/parse/sexp.cpp index 10510d160c0..8ec582e309e 100644 --- a/code/parse/sexp.cpp +++ b/code/parse/sexp.cpp @@ -3017,8 +3017,8 @@ int check_sexp_syntax(int node, int return_type, int recursive, int *bad_node, s // ship exists at this point - // now determine if this ship has a docking bay - if (!ship_has_dock_bay(shipnum)) + // now determine if this ship has a hangar bay + if (!ship_has_hangar_bay(shipnum)) return SEXP_CHECK_INVALID_SHIP_WITH_BAY; break; diff --git a/code/ship/ship.cpp b/code/ship/ship.cpp index 2d48626c1a8..ebed2577176 100644 --- a/code/ship/ship.cpp +++ b/code/ship/ship.cpp @@ -221,6 +221,19 @@ ship* ship_registry_entry::shipp_or_null() const return (shipnum < 0) ? nullptr : &Ships[shipnum]; } +ship_info* ship_registry_entry::sip() const +{ + if (pobj_num >= 0) + return &Ship_info[Parse_objects[pobj_num].ship_class]; + else if (shipnum >= 0) + return &Ship_info[Ships[shipnum].ship_info_index]; + else + { + Assertion(false, "A ship registry entry must have either a parse object or a ship!"); + return nullptr; + } +} + SCP_vector Ship_registry; SCP_unordered_map Ship_registry_map; @@ -252,6 +265,11 @@ bool ship_registry_exists(const SCP_string &name) return Ship_registry_map.find(name) != Ship_registry_map.end(); } +bool ship_registry_exists(int index) +{ + return Ship_registry.in_bounds(index); +} + const ship_registry_entry *ship_registry_get(const char *name) { auto ship_it = Ship_registry_map.find(name); @@ -270,6 +288,14 @@ const ship_registry_entry *ship_registry_get(const SCP_string &name) return nullptr; } +const ship_registry_entry *ship_registry_get(int index) +{ + if (Ship_registry.in_bounds(index)) + return &Ship_registry[index]; + + return nullptr; +} + int Num_engine_wash_types; int Num_ship_subobj_types; @@ -20065,7 +20091,7 @@ void wing_load_squad_bitmap(wing *w) // Goober5000 - needed by new hangar depart code // check whether this ship has a docking bay -bool ship_has_dock_bay(int shipnum) +bool ship_has_hangar_bay(int shipnum) { Assert(shipnum >= 0 && shipnum < MAX_SHIPS); @@ -20083,10 +20109,7 @@ bool ship_has_dock_bay(int shipnum) return false; } - auto pm = model_get(sip->model_num); - Assert( pm ); - - return ( pm->ship_bay && (pm->ship_bay->num_paths > 0) ); + return model_has_hangar_bay(sip->model_num); } // Goober5000 @@ -20101,7 +20124,7 @@ bool ship_useful_for_departure(int shipnum, int /*path_mask*/) return false; // no dockbay, can't depart to it - if (!ship_has_dock_bay(shipnum)) + if (!ship_has_hangar_bay(shipnum)) return false; // make sure that the bays are not all destroyed diff --git a/code/ship/ship.h b/code/ship/ship.h index c4e616027ff..e731a6a64a8 100644 --- a/code/ship/ship.h +++ b/code/ship/ship.h @@ -956,6 +956,8 @@ struct ship_registry_entry p_object* p_objp_or_null() const; object* objp_or_null() const; ship* shipp_or_null() const; + + ship_info* sip() const; }; extern SCP_vector Ship_registry; @@ -965,8 +967,10 @@ extern int ship_registry_get_index(const char *name); extern int ship_registry_get_index(const SCP_string &name); extern bool ship_registry_exists(const char *name); extern bool ship_registry_exists(const SCP_string &name); +extern bool ship_registry_exists(int index); 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); #define REGULAR_WEAPON (1<<0) #define DOGFIGHT_WEAPON (1<<1) @@ -2018,7 +2022,7 @@ extern void ship_subsystem_set_new_ai_class(ship_subsys *ss, int new_ai_class); extern void wing_load_squad_bitmap(wing *w); // Goober5000 - needed by new hangar depart code -extern bool ship_has_dock_bay(int shipnum); +extern bool ship_has_hangar_bay(int shipnum); extern bool ship_useful_for_departure(int shipnum, int path_mask = 0); extern int ship_get_ship_for_departure(int team); diff --git a/fred2/sexp_tree.cpp b/fred2/sexp_tree.cpp index 437886ca36b..1cbf2ed811d 100644 --- a/fred2/sexp_tree.cpp +++ b/fred2/sexp_tree.cpp @@ -6525,8 +6525,8 @@ sexp_list_item *sexp_tree::get_listing_opf_ship_with_bay() { if ( (objp->type == OBJ_SHIP) || (objp->type == OBJ_START) ) { - // determine if this ship has a docking bay - if (ship_has_dock_bay(objp->instance)) + // determine if this ship has a hangar bay + if (ship_has_hangar_bay(objp->instance)) { head.add_data(Ships[objp->instance].ship_name); } diff --git a/fred2/shipeditordlg.cpp b/fred2/shipeditordlg.cpp index a398fb5a9db..509c5a29a5c 100644 --- a/fred2/shipeditordlg.cpp +++ b/fred2/shipeditordlg.cpp @@ -2495,7 +2495,7 @@ void CShipEditorDlg::OnRestrictArrival() arrive_from_ship = (int)box->GetItemData(m_arrival_target); - if (!ship_has_dock_bay(arrive_from_ship)) + if (!ship_has_hangar_bay(arrive_from_ship)) { Int3(); return; @@ -2539,7 +2539,7 @@ void CShipEditorDlg::OnRestrictDeparture() depart_to_ship = (int)box->GetItemData(m_departure_target); - if (!ship_has_dock_bay(depart_to_ship)) + if (!ship_has_hangar_bay(depart_to_ship)) { Int3(); return; diff --git a/fred2/wing_editor.cpp b/fred2/wing_editor.cpp index c29f26da94b..144fd299c96 100644 --- a/fred2/wing_editor.cpp +++ b/fred2/wing_editor.cpp @@ -1387,7 +1387,7 @@ void wing_editor::OnRestrictArrival() arrive_from_ship = (int)box->GetItemData(m_arrival_target); - if (!ship_has_dock_bay(arrive_from_ship)) + if (!ship_has_hangar_bay(arrive_from_ship)) { Int3(); return; @@ -1422,7 +1422,7 @@ void wing_editor::OnRestrictDeparture() depart_to_ship = (int)box->GetItemData(m_departure_target); - if (!ship_has_dock_bay(depart_to_ship)) + if (!ship_has_hangar_bay(depart_to_ship)) { Int3(); return; diff --git a/qtfred/src/mission/dialogs/WingEditorDialogModel.cpp b/qtfred/src/mission/dialogs/WingEditorDialogModel.cpp index 246e6f1eafb..d66f26f0ed8 100644 --- a/qtfred/src/mission/dialogs/WingEditorDialogModel.cpp +++ b/qtfred/src/mission/dialogs/WingEditorDialogModel.cpp @@ -68,7 +68,7 @@ std::vector> WingEditorDialogModel::getDockBayPathsF { std::vector> out; - if (anchorShipnum < 0 || !ship_has_dock_bay(anchorShipnum)) + if (anchorShipnum < 0 || !ship_has_hangar_bay(anchorShipnum)) return out; const int sii = Ships[anchorShipnum].ship_info_index; @@ -973,7 +973,7 @@ void WingEditorDialogModel::setArrivalPaths(const std::vectorarrival_anchor; - if (anchor < 0 || !ship_has_dock_bay(anchor)) + if (anchor < 0 || !ship_has_hangar_bay(anchor)) return; // Rebuild mask in the same order we produced the list @@ -1212,7 +1212,7 @@ void WingEditorDialogModel::setDeparturePaths(const std::vectordeparture_anchor; - if (anchor < 0 || !ship_has_dock_bay(anchor)) + if (anchor < 0 || !ship_has_hangar_bay(anchor)) return; // Rebuild mask in the same order we produced the list diff --git a/qtfred/src/ui/widgets/sexp_tree.cpp b/qtfred/src/ui/widgets/sexp_tree.cpp index 3562760b57a..9178aac7270 100644 --- a/qtfred/src/ui/widgets/sexp_tree.cpp +++ b/qtfred/src/ui/widgets/sexp_tree.cpp @@ -4414,8 +4414,8 @@ sexp_list_item* sexp_tree::get_listing_opf_ship_with_bay() { for (objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp)) { if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) { - // determine if this ship has a docking bay - if (ship_has_dock_bay(objp->instance)) { + // determine if this ship has a hangar bay + if (ship_has_hangar_bay(objp->instance)) { head.add_data(Ships[objp->instance].ship_name); } }