mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
`support_ship_info::rearm_weapon_pool` was a dense per-weapon-class array where -1 = unlimited (the default), 0 = not rearmable, and >0 = remaining stockpile. Convert it to a sparse per-team map: `std::array<SCP_map<int, int>, MAX_TVT_TEAMS> rearm_weapon_pool;` `int rearm_pool_default() const; // -1, or 0 under rearm_pool_from_loadout` Mission-file format and save output are unchanged. Also tightens the two weapon-class bounds checks in ship.cpp. This removes another `MAX_WEAPON_TYPES` sized structure on the way to lifting the weapon class limit. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
697 lines
25 KiB
C++
697 lines
25 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
#ifndef _PARSE_H
|
|
#define _PARSE_H
|
|
|
|
#include <array>
|
|
#include <csetjmp>
|
|
#include <set>
|
|
|
|
#include "ai/ai.h"
|
|
#include "ai/ai_profiles.h"
|
|
#include "globalincs/version.h"
|
|
#include "graphics/2d.h"
|
|
#include "io/keycontrol.h"
|
|
#include "model/model.h"
|
|
#include "model/animation/modelanimation.h"
|
|
#include "object/object.h"
|
|
#include "parse/sexp.h"
|
|
#include "sound/sound.h"
|
|
#include "utils/reset_on_move.h"
|
|
#include "mission/mission_flags.h"
|
|
#include "nebula/volumetrics.h"
|
|
#include "ship/anchor_t.h"
|
|
#include "stats/scoring.h"
|
|
|
|
//WMC - This should be here
|
|
#define FS_MISSION_FILE_EXT NOX(".fs2")
|
|
|
|
struct wing;
|
|
struct p_dock_instance;
|
|
enum class ArrivalLocation;
|
|
enum class DepartureLocation;
|
|
|
|
#define NUM_NEBULAS 3 // how many background nebulas we have altogether
|
|
#define NUM_NEBULA_COLORS 9
|
|
|
|
#define DEFAULT_AMBIENT_LIGHT_LEVEL 0x00787878
|
|
|
|
#define MIN_TARGET_ARRIVAL_DISTANCE 500.0f // float because that's how FRED does the math
|
|
#define MIN_TARGET_ARRIVAL_MULTIPLIER 2.0f // minimum distance is 2 * target radius, but at least 500
|
|
|
|
anchor_t get_special_anchor(const char *name);
|
|
void check_anchor_for_hangar_bay(SCP_string &message, SCP_set<anchor_t> &anchors_checked, anchor_t anchor, const char *other_name, bool other_is_ship, bool is_arrival);
|
|
|
|
// MISSION_VERSION should be the earliest version of FSO that can load the current mission format without
|
|
// requiring version-specific comments. It should be updated whenever the format changes, but it should
|
|
// not be updated simply because the engine's version changed.
|
|
extern const gameversion::version MISSION_VERSION;
|
|
extern const gameversion::version LEGACY_MISSION_VERSION;
|
|
|
|
// These check to see if a mission has data that requires saving in a newer format. This would warrant
|
|
// a "soft version bump" rather than a hard bump because not all missions are affected.
|
|
extern bool check_for_23_3_data();
|
|
extern bool check_for_24_1_data();
|
|
extern bool check_for_24_3_data();
|
|
extern bool check_for_25_1_data();
|
|
|
|
#define WING_PLAYER_BASE 0x80000 // used by Fred to tell ship_index in a wing points to a player
|
|
|
|
// mission parse flags used for parse_mission() to tell what kind of information to get from the mission file
|
|
#define MPF_ONLY_MISSION_INFO (1 << 0)
|
|
#define MPF_IMPORT_FSM (1 << 1)
|
|
#define MPF_FAST_RELOAD (1 << 2) // skip clearing some stuff so we can load the mission faster (usually since it's the same mission)
|
|
#define MPF_IS_TEMPLATE (1 << 3) // loading a .fst mission template; post-load reset of name, author, timestamps, notes, description, and camera
|
|
|
|
// bitfield definitions for missions game types
|
|
#define OLD_MAX_GAME_TYPES 4 // needed for compatibility
|
|
#define OLD_GAME_TYPE_SINGLE_ONLY 0
|
|
#define OLD_GAME_TYPE_MULTI_ONLY 1
|
|
#define OLD_GAME_TYPE_SINGLE_MULTI 2
|
|
#define OLD_GAME_TYPE_TRAINING 3
|
|
|
|
#define MAX_MISSION_TYPES 5
|
|
#define MISSION_TYPE_SINGLE (1<<0)
|
|
#define MISSION_TYPE_MULTI (1<<1)
|
|
#define MISSION_TYPE_TRAINING (1<<2)
|
|
#define MISSION_TYPE_MULTI_COOP (1<<3)
|
|
#define MISSION_TYPE_MULTI_TEAMS (1<<4)
|
|
#define MISSION_TYPE_MULTI_DOGFIGHT (1<<5)
|
|
|
|
// some mice macros for mission type
|
|
#define IS_MISSION_MULTI_COOP (The_mission.game_type & MISSION_TYPE_MULTI_COOP)
|
|
#define IS_MISSION_MULTI_TEAMS (The_mission.game_type & MISSION_TYPE_MULTI_TEAMS)
|
|
#define IS_MISSION_MULTI_DOGFIGHT (The_mission.game_type & MISSION_TYPE_MULTI_DOGFIGHT)
|
|
|
|
// Used in the mission editor
|
|
inline const std::vector<std::pair<SCP_string, int>> Mission_event_teams_tvt = [] {
|
|
std::vector<std::pair<SCP_string, int>> arr;
|
|
arr.reserve(MAX_TVT_TEAMS);
|
|
for (int i = 0; i < MAX_TVT_TEAMS; ++i) {
|
|
arr.emplace_back("Team " + std::to_string(i + 1), i);
|
|
}
|
|
return arr;
|
|
}();
|
|
|
|
// Goober5000
|
|
struct support_ship_info
|
|
{
|
|
ArrivalLocation arrival_location; // arrival location
|
|
anchor_t arrival_anchor; // arrival anchor
|
|
DepartureLocation departure_location; // departure location
|
|
anchor_t departure_anchor; // departure anchor
|
|
float max_hull_repair_val; // % of a ship's hull that can be repaired -C
|
|
float max_subsys_repair_val; // same thing, except for subsystems -C
|
|
int max_support_ships; // max number of consecutive support ships
|
|
int max_concurrent_ships; // max number of concurrent support ships in mission per team
|
|
int ship_class; // ship class of support ship
|
|
int tally; // number of support ships so far
|
|
int support_available_for_species; // whether support is available for a given species (this is a bitfield)
|
|
bool disallow_rearm; // if true, support ships can only repair and will not rearm weapons
|
|
bool allow_rearm_weapon_precedence; // if true, support ships may swap to precedence weapons when rearm pool is empty
|
|
bool rearm_pool_from_loadout; // initialize rearm pool from mission loadout after filling starting loadout ships
|
|
|
|
// mission stockpile used to limit support ship rearming: weapon class -> amount remaining
|
|
// (-1 = unlimited, 0 = not rearmable, >0 = limited); an absent entry means rearm_pool_default()
|
|
std::array<SCP_map<int, int>, MAX_TVT_TEAMS> rearm_weapon_pool;
|
|
|
|
// the default for weapon classes without a pool entry: normally unlimited, but when the pool
|
|
// is seeded from the mission loadout, any weapon not in the loadout cannot be rearmed
|
|
int rearm_pool_default() const { return rearm_pool_from_loadout ? 0 : -1; }
|
|
|
|
void reset();
|
|
};
|
|
|
|
// movie type defines
|
|
// If you add one here, you must also add a description to missioncutscenedlg.cpp for FRED
|
|
// and update the dropdown list in fred.rc for the mission cutscene dialog editor.
|
|
enum : int {
|
|
MOVIE_PRE_FICTION,
|
|
MOVIE_PRE_CMD_BRIEF,
|
|
MOVIE_PRE_BRIEF,
|
|
MOVIE_PRE_GAME,
|
|
MOVIE_PRE_DEBRIEF,
|
|
MOVIE_POST_DEBRIEF,
|
|
MOVIE_END_CAMPAIGN,
|
|
|
|
// Must always be at the end of the list
|
|
Num_movie_types
|
|
};
|
|
|
|
struct cutscene_type_data {
|
|
int value; // enum
|
|
SCP_string label; // shown in combo boxes
|
|
SCP_string desc; // short explanation for the description box
|
|
};
|
|
|
|
static const cutscene_type_data CutsceneMenuData[] = {
|
|
{MOVIE_PRE_FICTION, "Fiction Viewer", "Plays just before the fiction viewer game state"},
|
|
{MOVIE_PRE_CMD_BRIEF, "Command Briefing", "Plays just before the command briefing game state"},
|
|
{MOVIE_PRE_BRIEF, "Briefing", "Plays just before the briefing game state"},
|
|
{MOVIE_PRE_GAME, "Pre-game", "Plays just before the mission starts after Accept has been pressed"},
|
|
{MOVIE_PRE_DEBRIEF, "Debriefing", "Plays just before the debriefing game state"},
|
|
{MOVIE_POST_DEBRIEF, "Post-debriefing", "Plays when the debriefing has been accepted but before exiting the mission"},
|
|
{MOVIE_END_CAMPAIGN, "End Campaign", "Plays when the campaign has been completed"}
|
|
};
|
|
|
|
// defines a mission cutscene.
|
|
typedef struct mission_cutscene {
|
|
int type;
|
|
char filename[MAX_FILENAME_LEN];
|
|
int formula;
|
|
} mission_cutscene;
|
|
|
|
typedef struct mission_default_custom_data {
|
|
SCP_string key;
|
|
SCP_string value;
|
|
SCP_string description;
|
|
} mission_default_custom_data;
|
|
|
|
typedef struct custom_string {
|
|
SCP_string name;
|
|
SCP_string value;
|
|
SCP_string text;
|
|
} custom_string;
|
|
|
|
inline bool operator==(const custom_string& a, const custom_string& b)
|
|
{
|
|
return a.name == b.name && a.value == b.value && a.text == b.text;
|
|
}
|
|
|
|
inline bool operator!=(const custom_string& a, const custom_string& b)
|
|
{
|
|
return !(a == b);
|
|
}
|
|
|
|
// descriptions of flags for FRED
|
|
template <class T>
|
|
struct parse_object_flag_description {
|
|
T def;
|
|
const char *flag_desc;
|
|
};
|
|
|
|
typedef struct mission {
|
|
SCP_string name;
|
|
SCP_string author;
|
|
gameversion::version required_fso_version;
|
|
char created[DATE_TIME_LENGTH];
|
|
char modified[DATE_TIME_LENGTH];
|
|
char notes[NOTES_LENGTH];
|
|
char mission_desc[MISSION_DESC_LENGTH];
|
|
int game_type;
|
|
flagset<Mission::Mission_Flags> flags;
|
|
int num_players; // valid in multiplayer missions -- number of players supported
|
|
uint num_respawns; // valid in multiplayer missions -- number of respawns allowed
|
|
int max_respawn_delay; // valid in multiplayer missions -- number of respawns allowed
|
|
support_ship_info support_ships; // Goober5000
|
|
char squad_filename[MAX_FILENAME_LEN]; // if the player has been reassigned to a squadron, this is the filename of the logo, otherwise empty string
|
|
char squad_name[NAME_LENGTH]; // if the player has been reassigned to a squadron, this is the name of the squadron, otherwise empty string
|
|
char loading_screen[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN];
|
|
char skybox_model[MAX_FILENAME_LEN];
|
|
animation::ModelAnimationSet skybox_model_animations;
|
|
matrix skybox_orientation;
|
|
char envmap_name[MAX_FILENAME_LEN];
|
|
int skybox_flags;
|
|
int contrail_threshold;
|
|
int large_ship_no_collide_collision_group;
|
|
int ambient_light_level;
|
|
std::optional<volumetric_nebula> volumetrics;
|
|
sound_env sound_environment;
|
|
vec3d gravity;
|
|
int HUD_timer_padding;
|
|
|
|
// Goober5000
|
|
int command_persona;
|
|
char command_sender[NAME_LENGTH];
|
|
int debriefing_persona;
|
|
traitor_override_t* traitor_override;
|
|
|
|
// Goober5000
|
|
char event_music_name[NAME_LENGTH];
|
|
char briefing_music_name[NAME_LENGTH];
|
|
char substitute_event_music_name[NAME_LENGTH];
|
|
char substitute_briefing_music_name[NAME_LENGTH];
|
|
|
|
// Goober5000
|
|
ai_profile_t *ai_profile;
|
|
|
|
SCP_string lighting_profile_name;
|
|
|
|
SCP_vector<mission_cutscene> cutscenes;
|
|
|
|
SCP_map<SCP_string, SCP_string> custom_data;
|
|
|
|
SCP_vector<custom_string> custom_strings;
|
|
SCP_vector<SCP_string> fred_layers;
|
|
|
|
void Reset( );
|
|
|
|
mission( )
|
|
{
|
|
Reset( );
|
|
}
|
|
} mission;
|
|
|
|
// cargo defines
|
|
// NOTE: MAX_CARGO MUST REMAIN <= 64 (CARGO_NO_DEPLETE) for NO_DEPLETE to work.
|
|
// FURTHER NOTE (Goober5000): If a new flag is added here, the code (particularly in sexp.cpp)
|
|
// must be reworked so that all the flags are maintained from function to function
|
|
#define CARGO_INDEX_MASK 0xBF
|
|
#define CARGO_NO_DEPLETE 0x40 // CARGO_NO_DEPLETE + CARGO_INDEX_MASK must == FF
|
|
#define MAX_CARGO 60
|
|
|
|
|
|
// Goober5000 - contrail threshold (previously defined in ShipContrails.cpp)
|
|
#define CONTRAIL_THRESHOLD_DEFAULT 45
|
|
|
|
extern mission The_mission;
|
|
extern char Mission_filename[80]; // filename of mission in The_mission (Fred only)
|
|
|
|
// enums for arrival locations. The integer values of these enums should match their counterparts in the arrival location array
|
|
#define MAX_ARRIVAL_NAMES 9
|
|
enum class ArrivalLocation : int
|
|
{
|
|
AT_LOCATION = 0,
|
|
NEAR_SHIP = 1,
|
|
IN_FRONT_OF_SHIP = 2,
|
|
IN_BACK_OF_SHIP = 3,
|
|
ABOVE_SHIP = 4,
|
|
BELOW_SHIP = 5,
|
|
TO_LEFT_OF_SHIP = 6,
|
|
TO_RIGHT_OF_SHIP = 7,
|
|
FROM_DOCK_BAY = 8
|
|
};
|
|
|
|
// enums for departure locations. The integer values of these enums should match their counterparts in the departure location array
|
|
#define MAX_DEPARTURE_NAMES 2
|
|
enum class DepartureLocation : int
|
|
{
|
|
AT_LOCATION = 0,
|
|
TO_DOCK_BAY = 1
|
|
};
|
|
|
|
#define MAX_GOAL_TYPE_NAMES 3
|
|
|
|
// alternate ship type names
|
|
#define MAX_ALT_TYPE_NAMES 100
|
|
extern char Mission_alt_types[MAX_ALT_TYPE_NAMES][NAME_LENGTH];
|
|
extern int Mission_alt_type_count;
|
|
|
|
// callsign
|
|
#define MAX_CALLSIGNS 100
|
|
extern char Mission_callsigns[MAX_CALLSIGNS][NAME_LENGTH];
|
|
extern int Mission_callsign_count;
|
|
|
|
// path restrictions
|
|
#define MAX_PATH_RESTRICTIONS 10
|
|
typedef struct path_restriction_t {
|
|
int num_paths;
|
|
int cached_mask;
|
|
char path_names[MAX_SHIP_BAY_PATHS][MAX_NAME_LEN];
|
|
} path_restriction_t;
|
|
|
|
extern const char *Ai_behavior_names[MAX_AI_BEHAVIORS];
|
|
extern const char *Arrival_location_names[MAX_ARRIVAL_NAMES];
|
|
extern const char *Departure_location_names[MAX_DEPARTURE_NAMES];
|
|
extern const char *Goal_type_names[MAX_GOAL_TYPE_NAMES];
|
|
|
|
extern const char *Reinforcement_type_names[];
|
|
extern flag_def_list_new<Mission::Mission_Flags> Parse_mission_flags[];
|
|
extern parse_object_flag_description<Mission::Mission_Flags> Parse_mission_flag_descriptions[];
|
|
extern const size_t Num_parse_mission_flags;
|
|
extern const size_t Num_parse_mission_flag_descriptions;
|
|
extern char *Object_flags[];
|
|
extern flag_def_list_new<Ship::Ship_Flags> Parse_ship_flags[];
|
|
extern const size_t Num_Parse_ship_flags;
|
|
extern flag_def_list_new<AI::AI_Flags> Parse_ship_ai_flags[];
|
|
extern const size_t Num_Parse_ship_ai_flags;
|
|
extern flag_def_list_new<Object::Object_Flags> Parse_ship_object_flags[];
|
|
extern const size_t Num_Parse_ship_object_flags;
|
|
extern flag_def_list_new<Mission::Parse_Object_Flags> Parse_object_flags[];
|
|
extern parse_object_flag_description<Mission::Parse_Object_Flags> Parse_object_flag_descriptions[];
|
|
extern const size_t Num_parse_object_flags;
|
|
extern flag_def_list_new<Ship::Wing_Flags> Parse_wing_flags[];
|
|
extern parse_object_flag_description<Ship::Wing_Flags> Parse_wing_flag_descriptions[];
|
|
extern const size_t Num_parse_wing_flags;
|
|
extern const size_t Num_parse_wing_flag_descriptions;
|
|
extern flag_def_list_new<Mission::Parse_Object_Flags> Parse_prop_flags[];
|
|
extern parse_object_flag_description<Mission::Parse_Object_Flags> Parse_prop_flag_descriptions[];
|
|
extern const size_t Num_parse_prop_flags;
|
|
extern const size_t Num_parse_prop_flag_descriptions;
|
|
extern const char *Icon_names[];
|
|
extern const char *Mission_event_log_flags[];
|
|
|
|
extern int Num_mission_event_flags;
|
|
extern flag_def_list Mission_event_flags[];
|
|
|
|
extern char *Cargo_names[MAX_CARGO];
|
|
extern char Cargo_names_buf[MAX_CARGO][NAME_LENGTH];
|
|
|
|
extern char Mission_parse_storm_name[NAME_LENGTH];
|
|
|
|
extern int Num_iff;
|
|
extern int Num_ai_behaviors;
|
|
extern int Num_ai_classes;
|
|
extern int Num_cargo;
|
|
extern int Num_arrival_names;
|
|
extern int Num_goal_type_names;
|
|
extern int Num_reinforcement_type_names;
|
|
extern int Player_starts;
|
|
extern fix Entry_delay_time;
|
|
extern int Loading_screen_bm_index;
|
|
|
|
extern int Num_unknown_ship_classes;
|
|
extern int Num_unknown_prop_classes;
|
|
extern int Num_unknown_weapon_classes;
|
|
extern int Num_unknown_loadout_classes;
|
|
|
|
extern ushort Current_file_checksum;
|
|
extern int Current_file_length;
|
|
|
|
extern SCP_vector<mission_default_custom_data> Default_custom_data;
|
|
|
|
#define SUBSYS_STATUS_NO_CHANGE -999
|
|
|
|
// Squadron Default Name
|
|
#define NO_SQUAD "<none>"
|
|
|
|
typedef struct subsys_status {
|
|
char name[NAME_LENGTH];
|
|
float percent; // percent damaged
|
|
int primary_banks[MAX_SHIP_PRIMARY_BANKS];
|
|
int primary_ammo[MAX_SHIP_PRIMARY_BANKS];
|
|
int secondary_banks[MAX_SHIP_SECONDARY_BANKS];
|
|
int secondary_ammo[MAX_SHIP_SECONDARY_BANKS];
|
|
int ai_class;
|
|
int subsys_cargo_name;
|
|
char subsys_cargo_title[NAME_LENGTH];
|
|
} subsys_status;
|
|
|
|
typedef struct texture_replace {
|
|
char ship_name[NAME_LENGTH];
|
|
char old_texture[MAX_FILENAME_LEN];
|
|
char new_texture[MAX_FILENAME_LEN];
|
|
int new_texture_id;
|
|
bool from_table;
|
|
} texture_replace;
|
|
|
|
extern SCP_vector<texture_replace> Fred_texture_replacements;
|
|
|
|
// which ships have had the "immobile" flag migrated to "don't-change-position" and "don't-change-orientation"
|
|
extern SCP_unordered_set<int> Fred_migrated_immobile_ships;
|
|
|
|
struct alt_class {
|
|
int ship_class;
|
|
int variable_index; // if set allows the class to be set by a variable
|
|
bool default_to_this_class;
|
|
alt_class()
|
|
{
|
|
ship_class = -1;
|
|
variable_index = -1;
|
|
default_to_this_class = false;
|
|
}
|
|
alt_class(const alt_class& a) {
|
|
ship_class = a.ship_class;
|
|
variable_index = a.variable_index;
|
|
default_to_this_class = a.default_to_this_class;
|
|
}
|
|
bool operator==(const alt_class& a) const
|
|
{
|
|
return (ship_class == a.ship_class && variable_index == a.variable_index && default_to_this_class == a.default_to_this_class);
|
|
}
|
|
alt_class& operator=(const alt_class& a)
|
|
{
|
|
ship_class = a.ship_class;
|
|
variable_index = a.variable_index;
|
|
default_to_this_class = a.default_to_this_class;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
// a parse object
|
|
// information from a $OBJECT: definition is read into this struct to
|
|
// be copied into the real object, ship, etc. structs
|
|
class p_object
|
|
{
|
|
public:
|
|
char name[NAME_LENGTH] = "";
|
|
SCP_string display_name;
|
|
p_object *next = nullptr, *prev = nullptr;
|
|
|
|
vec3d pos = vmd_zero_vector;
|
|
matrix orient = vmd_identity_matrix;
|
|
int ship_class = -1;
|
|
int team = -1;
|
|
int loadout_team = -1; // original team, should never be changed after being set!!
|
|
int ai_goals = -1; // sexp of lists of goals that this ship should try and do
|
|
char cargo1 = '\0';
|
|
char cargo_title[NAME_LENGTH] = "";
|
|
SCP_string team_color_setting;
|
|
|
|
int subsys_index = -1; // index into subsys_status array
|
|
int subsys_count = 0; // number of elements used in subsys_status array
|
|
int initial_velocity = 0;
|
|
int initial_hull = 100;
|
|
int initial_shields = 100;
|
|
|
|
ArrivalLocation arrival_location = ArrivalLocation::AT_LOCATION;
|
|
int arrival_distance = 0; // used when arrival location is near or in front of some ship
|
|
anchor_t arrival_anchor = anchor_t::invalid(); // ship registry entry used for anchoring an arrival point
|
|
int arrival_path_mask = 0; // Goober5000
|
|
int arrival_cue = -1; // Index in Sexp_nodes of this sexp.
|
|
int arrival_delay = 0;
|
|
|
|
DepartureLocation departure_location = DepartureLocation::AT_LOCATION;
|
|
anchor_t departure_anchor = anchor_t::invalid();
|
|
int departure_path_mask = 0; // Goober5000
|
|
int departure_cue = -1; // Index in Sexp_nodes of this sexp.
|
|
int departure_delay = 0;
|
|
|
|
int warpin_params_index = -1;
|
|
int warpout_params_index = -1;
|
|
|
|
int wingnum = -1; // set to -1 if not in a wing -- Wing array index otherwise
|
|
int pos_in_wing = -1; // Goober5000 - needed for FRED with the new way things work
|
|
|
|
flagset<Mission::Parse_Object_Flags> flags; // mission savable flags
|
|
int escort_priority = 0; // priority in escort list
|
|
int ship_guardian_threshold = 0;
|
|
int ai_class = -1;
|
|
int hotkey = -1; // hotkey number (between 0 and 9) -1 means no hotkey
|
|
int score = 0;
|
|
float assist_score_pct = 0.0f; // percentage of the score which players who gain an assist will get when this ship is killed
|
|
SCP_set<size_t> orders_accepted; // which orders this ship will accept from the player
|
|
util::reset_on_move<p_dock_instance *> dock_list; // Goober5000 - parse objects this parse object is docked to
|
|
object *created_object = nullptr; // Goober5000
|
|
int collision_group_id = 0; // Goober5000
|
|
int group = -1; // group object is within or -1 if none.
|
|
SCP_string fred_layer = "Default";
|
|
int persona_index = -1;
|
|
int kamikaze_damage = 0; // base damage for a kamikaze attack
|
|
|
|
bool use_special_explosion = false; // new special explosion/hitpoints system
|
|
int special_exp_damage = -1;
|
|
int special_exp_blast = -1;
|
|
int special_exp_inner = -1;
|
|
int special_exp_outer = -1;
|
|
bool use_shockwave = false;
|
|
int special_exp_shockwave_speed = 0;
|
|
int special_exp_deathroll_time = 0;
|
|
|
|
int special_hitpoints = 0;
|
|
int special_shield = -1;
|
|
|
|
ushort net_signature = 0; // network signature this object can have
|
|
int destroy_before_mission_time = -1;
|
|
|
|
char wing_status_wing_index = -1; // wing index (0-4) in wingman status gauge
|
|
char wing_status_wing_pos = -1; // wing position (0-5) in wingman status gauge
|
|
|
|
uint respawn_count = 0; // number of respawns for this object. Applies only to player wing ships in multiplayer
|
|
int respawn_priority = 0; // priority this ship has for controlling respawn points
|
|
|
|
int alt_type_index = -1; // optional alt type index
|
|
int callsign_index = -1; // optional callsign index
|
|
|
|
float ship_max_hull_strength = 0.0f; // Needed to deal with special hitpoints
|
|
float ship_max_shield_strength = 0.0f;
|
|
float max_shield_recharge = 0.0f;
|
|
|
|
// Goober5000
|
|
SCP_vector<texture_replace> replacement_textures;
|
|
|
|
SCP_vector<alt_class> alt_classes;
|
|
SCP_map<std::pair<int, int>, int> alt_iff_color;
|
|
|
|
~p_object();
|
|
|
|
// The destructor frees dock_list, and a user-declared destructor suppresses
|
|
// the implicit move operations, so define them here. Shallow copies are safe
|
|
// because parse code only copies p_objects before dock lists are built.
|
|
p_object() = default;
|
|
p_object(const p_object &) = default;
|
|
p_object &operator=(const p_object &) = default;
|
|
p_object(p_object &&) = default;
|
|
|
|
// not defaulted, because a memberwise move would overwrite (and leak) any
|
|
// dock list the assigned-to object owns; defined in missionparse.cpp
|
|
p_object &operator=(p_object &&other) noexcept;
|
|
|
|
const char* get_display_name();
|
|
bool has_display_name();
|
|
};
|
|
|
|
// Goober5000 - this is now dynamic
|
|
extern SCP_vector<p_object> Parse_objects;
|
|
#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;
|
|
|
|
// one line of a team loadout: a ship or weapon class (given literally or via a sexp variable)
|
|
// and how many of it are available (likewise literal or via a variable)
|
|
struct loadout_entry
|
|
{
|
|
int class_index = -1; // resolved ship or weapon class
|
|
int count = 0;
|
|
SCP_string class_variable; // sexp variable name; empty = class was given literally
|
|
SCP_string count_variable; // sexp variable name; empty = count was given literally
|
|
};
|
|
|
|
struct team_data
|
|
{
|
|
// ships
|
|
int default_ship = -1; // default ship type for player start point (recommended choice)
|
|
SCP_vector<loadout_entry> ship_choices; // ship classes (and counts) available in the loadout
|
|
|
|
// weapons
|
|
bool do_not_validate = false;
|
|
SCP_vector<loadout_entry> weapon_choices; // weapon classes (and counts) available in the loadout
|
|
SCP_set<int> required_weapons; // weapon classes that cannot be removed in weapon select
|
|
};
|
|
|
|
#define MAX_P_WINGS 16
|
|
#define MAX_SHIP_LIST 16
|
|
|
|
extern team_data Team_data[MAX_TVT_TEAMS];
|
|
extern int Num_teams;
|
|
|
|
extern subsys_status *Subsys_status;
|
|
extern int Subsys_index;
|
|
|
|
extern vec3d Parse_viewer_pos;
|
|
extern matrix Parse_viewer_orient;
|
|
|
|
extern fix Mission_end_time;
|
|
|
|
extern SCP_vector<SCP_string> Parse_names;
|
|
|
|
// Populated when Qtfred_running and a parse-time auto-correction fires. Drained by
|
|
// QtFRED's ErrorChecker so the corrections are visible to the designer instead of
|
|
// silently buried. Outside of QtFRED these sites still call Warning(LOCATION, ...).
|
|
extern SCP_vector<SCP_string> Mission_parse_warnings;
|
|
|
|
// true while a mission is being parsed and post-processed
|
|
extern bool Parsing_mission;
|
|
|
|
extern char Player_start_shipname[NAME_LENGTH];
|
|
extern int Player_start_shipnum;
|
|
extern p_object *Player_start_pobject;
|
|
|
|
extern int Mission_palette; // index of palette file to use for mission
|
|
extern int Nebula_index; // index into Nebula_filenames[] of nebula to use in mission.
|
|
extern const char *Nebula_filenames[NUM_NEBULAS];
|
|
extern const char *Nebula_colors[NUM_NEBULA_COLORS];
|
|
extern p_object *Arriving_support_ship;
|
|
|
|
extern char Neb2_texture_name[MAX_FILENAME_LEN];
|
|
|
|
|
|
void mission_init(mission *pm, bool quick_init = false);
|
|
bool parse_main(const char *mission_name, int flags = 0);
|
|
p_object *mission_parse_get_arrival_ship(ushort net_signature);
|
|
p_object *mission_parse_get_arrival_ship(const char *name);
|
|
bool mission_check_ship_yet_to_arrive(const char *name);
|
|
p_object *mission_parse_find_parse_object(const char *name);
|
|
int parse_create_object(p_object *objp, bool standalone_ship = false);
|
|
void resolve_parse_flags(object *objp, flagset<Mission::Parse_Object_Flags> &parse_flags);
|
|
|
|
void mission_parse_close();
|
|
|
|
// used in fred management.cpp when creating a new mission
|
|
void apply_default_custom_data(mission* pm);
|
|
|
|
bool mission_maybe_make_ship_arrive(p_object *p_objp, bool force_arrival = false);
|
|
bool mission_maybe_make_wing_arrive(int wingnum, bool force_arrival = false);
|
|
|
|
// used in squadmate messaging stuff to create wings from reinforcements.
|
|
int parse_wing_create_ships(wing *wingp, int num_to_create, bool force_create = false, bool force_arrival = false, int specific_instance = -1 );
|
|
|
|
// function for getting basic mission data without loading whole mission
|
|
int mission_parse_is_multi(const char *filename, char *mission_name );
|
|
int mission_parse_get_multi_mission_info(const char *filename);
|
|
|
|
// called externally from multiplayer code
|
|
int mission_do_departure(object *objp, bool goal_is_to_warp = false);
|
|
|
|
// called externally from freespace.cpp
|
|
void mission_parse_fixup_players(void);
|
|
|
|
// get a index to a perminently kept around name of a ship or wing
|
|
int get_parse_name_index(const char *name);
|
|
|
|
// called from freespace game level loop
|
|
void mission_parse_eval_stuff();
|
|
|
|
// code to bring in a repair ship.
|
|
void mission_bring_in_support_ship( object *requester_objp );
|
|
int mission_is_support_ship_arriving( void );
|
|
void mission_add_to_arriving_support( object *requester_objp );
|
|
int mission_is_repair_scheduled( object *objp );
|
|
int mission_remove_scheduled_repair( object *objp );
|
|
void mission_parse_support_arrived( int objnum );
|
|
|
|
// alternate name stuff
|
|
int mission_parse_lookup_alt(const char *name);
|
|
const char *mission_parse_lookup_alt_index(int index);
|
|
int mission_parse_add_alt(const char *name);
|
|
void mission_parse_remove_alt(const char *name);
|
|
void mission_parse_reset_alt();
|
|
void mission_process_alt_types();
|
|
|
|
// callsign stuff
|
|
int mission_parse_lookup_callsign(const char *name);
|
|
const char *mission_parse_lookup_callsign_index(int index);
|
|
int mission_parse_add_callsign(const char *name);
|
|
void mission_parse_remove_callsign(const char *name);
|
|
void mission_parse_reset_callsign();
|
|
|
|
// is training mission
|
|
int is_training_mission();
|
|
|
|
// code to save/restore mission parse stuff
|
|
int get_mission_info(const char *filename, mission *missionp = nullptr, bool basic = true, bool filename_is_full_path = false);
|
|
|
|
// Goober5000
|
|
void parse_dock_one_docked_object(p_object *pobjp, p_object *parent_pobjp);
|
|
|
|
// Karajorma
|
|
void swap_parse_object(p_object *p_obj, int ship_class);
|
|
void clear_texture_replacements();
|
|
|
|
// Goober5000
|
|
subsys_status *parse_get_subsys_status(p_object *pobjp, const char *subsys_name);
|
|
|
|
// MjnMixael
|
|
custom_string* get_custom_string_by_name(SCP_string name);
|
|
|
|
#endif
|
|
|