mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 16:18:19 -10:00
Ship_info is already an SCP_vector but MAX_SHIP_CLASSES (500) is held in place by fixed-size structures throughout the engine and editors. This converts the seven file-format-adjacent arrays whose persistence touches the .csg campaign save and .plr pilot file formats: campaign::ships_allowed [MAX_SHIP_CLASSES] -> SCP_vector<ubyte> campaign::weapons_allowed [MAX_WEAPON_TYPES] -> SCP_vector<ubyte> loadout_data::ship_pool [MAX_SHIP_CLASSES] -> SCP_vector<int> loadout_data::weapon_pool [MAX_WEAPON_TYPES] -> SCP_vector<int> scoring_struct::kills [MAX_SHIP_CLASSES] -> SCP_vector<int> scoring_struct::m_kills [MAX_SHIP_CLASSES] -> SCP_vector<int> scoring_struct::m_okKills [MAX_SHIP_CLASSES] -> SCP_vector<int> The CSG and PLR file formats already store explicit counts and key by ship/weapon names, so no on-disk format change is needed. Existing read/write loops already iterated by ship_info_size() / weapon_info_size() and just compile through against the new vector types. Vectors are sized to ship_info_size() / weapon_info_size() in scoring_struct::init(), mission_campaign_clear(), player_loadout_init(), and the campaign-pool reset paths in csg.cpp and multi_campaign.cpp. All of these run after weapon_init() / ship_init(), so the sizing invariant holds. scoring_struct globals constructed at static-init time start with empty vectors; first index access is always post-table-parse. Multiplayer stats sync (multimsgs.cpp) now derives offsets and counts from the vector size; added USHRT_MAX assertions on the sender side since the wire protocol packs offset/count as USHORT. The FSTracker sync (multi_fstracker.cpp) clamps vmt->num_ships down to the local mod's kills.size() before transmission and guards the receive-side write so a tracker payload with more ship slots than this mod has won't overrun the vector. The MAX_SHIP_CLASSES cap itself stays in place at ship.cpp:2327; this is one prerequisite toward lifting it. The other ~25 fixed-size ship-class-indexed structures (team_data, Ss_pool_teams, Wl_ships, FRED2 editor arrays, qtFRED Editor::_ship_usage, etc.) remain to be addressed in follow-up PRs. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
186 lines
6.8 KiB
C++
186 lines
6.8 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 _SCORING_HEADER_FILE
|
|
#define _SCORING_HEADER_FILE
|
|
|
|
#include <ctime>
|
|
|
|
#include "globalincs/globals.h"
|
|
#include "globalincs/pstypes.h"
|
|
|
|
class player;
|
|
class ship;
|
|
class object;
|
|
|
|
#define NUM_MEDALS_FS2 18
|
|
#define NUM_MEDALS_FS1 16
|
|
|
|
//Ranks are no longer limited to the retail 10 and checks are against index position rather than arbitrary title - Mjn
|
|
//#define RANK_ENSIGN 0
|
|
//#define RANK_LT_JUNIOR 1
|
|
//#define RANK_LT 2
|
|
//#define RANK_LT_CMDR 3
|
|
//#define RANK_CMDR 4
|
|
//#define RANK_CAPTAIN 5
|
|
//#define RANK_COMMODORE 6
|
|
//#define RANK_REAR_ADMIRAL 7
|
|
//#define RANK_VICE_ADMIRAL 8
|
|
//#define RANK_ADMIRAL 9
|
|
|
|
//#define MAX_FREESPACE1_RANK RANK_COMMODORE
|
|
//#define MAX_FREESPACE2_RANK RANK_ADMIRAL
|
|
|
|
|
|
/*
|
|
The ins and outs of when/where stats are stored and retreived - BE SURE TO FOLLOW THESE GUIDELINES
|
|
|
|
SINGLE PLAYER :
|
|
scoring_level_init() is called from game_level_init(). This zeroes out mission specific stats
|
|
scoring_level_close() is called from the debriefing screen when the player hits accept. This saves the mission
|
|
stats to alltime stats, and updates any campaign stats
|
|
NOTE : in single player mode, if the player is going back to replay an old mission, the stats shouldn't be
|
|
stored again
|
|
|
|
MULTI PLAYER :
|
|
scoring_level_init() is called in game_level_init() again.
|
|
init_multiplayer_stats() is called on all computers in the game when moving _into_ the MISSION_SYNC state
|
|
|
|
scoring_level_close() is called on all machines when the host selects accept. If the host is not on the standalone
|
|
he sends a packet to all players indicating that they should save their data. If he _is_ on the standalone, he should
|
|
send only to the standalone, and then it rebroadcasts the packet ot everyone else.
|
|
*/
|
|
|
|
|
|
struct rank_stuff {
|
|
char name[NAME_LENGTH]; // name of this rank
|
|
SCP_string alt_name; // Alt name for displaying
|
|
SCP_string title; // Title used for replacing the $RankTitle variable
|
|
SCP_map<int, SCP_string> promotion_text; // text to display when promoted to this rank
|
|
int points; // points needed to reach this rank
|
|
char bitmap[MAX_FILENAME_LEN]; // bitmap of this rank medal
|
|
char promotion_voice_base[MAX_FILENAME_LEN];
|
|
};
|
|
|
|
struct traitor_stuff {
|
|
SCP_map<int, SCP_string> debriefing_text;
|
|
char traitor_voice_base[MAX_FILENAME_LEN];
|
|
SCP_string recommendation_text;
|
|
};
|
|
|
|
struct traitor_override_t {
|
|
SCP_string name;
|
|
SCP_string text;
|
|
char voice_filename[MAX_FILENAME_LEN];
|
|
SCP_string recommendation_text;
|
|
};
|
|
|
|
#define STATS_FLAG_INVALID (1<<0)
|
|
#define STATS_FLAG_CAMPAIGN (1<<1)
|
|
#define STATS_FLAG_MULTIPLAYER (1<<2)
|
|
|
|
class scoring_struct
|
|
{
|
|
public:
|
|
int flags;
|
|
|
|
// All-time total
|
|
int score; // all time score
|
|
int rank; // all time rank
|
|
SCP_vector<int> medal_counts; // all time medal counts
|
|
|
|
SCP_vector<int> kills; // only valid kills (i.e. not on friendlies). Sized to ship_info_size() after table parse.
|
|
int assists; // alltime assists
|
|
int kill_count; // total alltime kills
|
|
int kill_count_ok; // total valid alltime kills (no friendlies)
|
|
unsigned int p_shots_fired; // primary weapon shots fired
|
|
unsigned int s_shots_fired; // secondary weapon shots fired
|
|
|
|
unsigned int p_shots_hit; // primary weapon shots hit
|
|
unsigned int s_shots_hit; // secondary weapon shots hit
|
|
|
|
unsigned int p_bonehead_hits; // alltime primary friendly hits
|
|
unsigned int s_bonehead_hits; // alltime secondary friendly hits
|
|
int bonehead_kills; // alltime friendly kills
|
|
|
|
unsigned int missions_flown; // total # of missions flown
|
|
unsigned int flight_time; // total # of flight hours the player has
|
|
_fs_time_t last_flown; // last time the player has flown
|
|
_fs_time_t last_backup; // so we can easily call scoring_level_backout()
|
|
|
|
// Mission total
|
|
int m_medal_earned; // which medal (if any) earned this mission
|
|
SCP_vector<int> m_badge_earned; // which badge(s) was(/were) earned. Calculated after mission is over
|
|
int m_promotion_earned; // was a promotion earned. Calculated after mission is over
|
|
|
|
int m_score;
|
|
SCP_vector<int> m_kills; // this will represent all kills in the mission (bonehead or not). Sized to ship_info_size().
|
|
SCP_vector<int> m_okKills; // this will be only the "valid" kills the player made. Sized to ship_info_size().
|
|
int m_kill_count; // total kills for this mission
|
|
int m_kill_count_ok; // total (non-friendly) kills for this mission
|
|
int m_assists; // player assits for the mission
|
|
unsigned int mp_shots_fired; // primary shots fired for the mission
|
|
unsigned int ms_shots_fired; // secondary shots fired for the mission
|
|
unsigned int mp_shots_hit; // primary shots hit for the mission
|
|
unsigned int ms_shots_hit; // secondary shots hit for the mission
|
|
unsigned int mp_bonehead_hits; // primary friendly hits for the mission
|
|
unsigned int ms_bonehead_hits; // secondary friendly hits for the mission
|
|
int m_bonehead_kills; // # of friendly kills for the mission
|
|
int m_player_deaths; // player deaths for the mission (really only useful for multiplayer)
|
|
|
|
int m_dogfight_kills[MAX_PLAYERS]; // kills by player for multiplayer dogfight
|
|
|
|
scoring_struct() { init(); }
|
|
scoring_struct(const scoring_struct &s) { assign(s); }
|
|
scoring_struct& operator=(const scoring_struct &s) { assign(s); return *this; }
|
|
|
|
void init();
|
|
void assign(const scoring_struct &s);
|
|
|
|
bool operator==(const scoring_struct& rhs) const;
|
|
bool operator!=(const scoring_struct& rhs) const;
|
|
};
|
|
|
|
extern SCP_vector<rank_stuff> Ranks;
|
|
extern traitor_stuff Traitor;
|
|
extern SCP_vector<traitor_override_t> Traitor_overrides;
|
|
|
|
int verify_rank(int rank);
|
|
|
|
SCP_string get_rank_display_name(rank_stuff* rank);
|
|
|
|
void rank_init();
|
|
void traitor_init();
|
|
void scoring_close();
|
|
|
|
void scoring_level_init( scoring_struct *score );
|
|
void scoring_level_close(int accepted = 1);
|
|
void scoring_backout_accept( scoring_struct *score );
|
|
void scoring_do_accept( scoring_struct *score );
|
|
|
|
void scoring_add_damage(const object *ship_obj, const object *other_obj, float damage);
|
|
int scoring_eval_kill(const object *ship_obj);
|
|
int scoring_eval_kill_on_weapon(object *weapon_obj, object *other_obj);
|
|
void scoring_eval_assists(ship *sp,int killer_sig, bool enemy_player = false);
|
|
|
|
// bash the passed player to the specified rank
|
|
void scoring_bash_rank(player *pl,int rank);
|
|
|
|
// eval a hit on an object (for primary and secondary hit purposes)
|
|
void scoring_eval_hit(const object *hit_obj, const object *other_obj, int from_blast = 0);
|
|
|
|
// get a scaling factor for adding/subtracting from mission score
|
|
float scoring_get_scale_factor();
|
|
|
|
traitor_override_t* get_traitor_override_pointer(const SCP_string& name);
|
|
|
|
#endif
|