sots-engine/src/game/data/turrets.h

78 lines
2.8 KiB
C++

// game::data -- the turret table (Weapons/_turrets.txt) and the stable id
// registries (Weapons/_weapons.txt, Species/<Race>/sections/_shipsections.txt).
//
// _turrets.txt is a whitespace-positional table, one row per (mount size,
// weapon size, class):
// size weapon-size class health track-speed azimuth% inclination% "model"
// A row is what makes a weapon of (weapon-size, class) fit a bank of (size,
// class); the model may be "" (the weapon supplies its own turret model).
//
// The id manifests assign the persistent network / savegame ids; retired ids
// stay as `// DELETED - n` tombstones and must never be reused.
#pragma once
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "game/data/common.h"
namespace game::data {
struct TurretRow {
std::string mount_size; // bank turretsize (small / medium / large)
std::string weapon_size; // weapon turretsize (tiny / small / medium / large)
std::string turret_class;
std::optional<double> health, track_speed, azimuth_scale, inclination_scale;
std::string model; // may be empty
int line = 0;
};
class TurretTable {
public:
const std::vector<TurretRow>& rows() const { return rows_; }
std::size_t size() const { return rows_.size(); }
void add(TurretRow row) { rows_.push_back(std::move(row)); }
// All comparisons are case-insensitive (the data mixes `Large`/`large`,
// `Missile`/`missile`, `PlanetMissile`/`planetmissile`).
const TurretRow* find(std::string_view mount_size, std::string_view weapon_size, std::string_view turret_class) const;
bool has_weapon_pair(std::string_view weapon_size, std::string_view turret_class) const;
bool has_bank_pair(std::string_view mount_size, std::string_view turret_class) const;
std::vector<const TurretRow*> rows_for_bank(std::string_view mount_size, std::string_view turret_class) const;
private:
std::vector<TurretRow> rows_;
};
Loaded<TurretTable> parse_turret_table(std::string_view text, std::string file = {});
struct IdEntry {
int id = 0;
std::string name; // as written, e.g. "DEWar.SHIPSECTION"
std::string stem; // name without extension, as written
int line = 0;
};
class IdRegistry {
public:
const std::vector<IdEntry>& entries() const { return entries_; }
const std::vector<int>& deleted() const { return deleted_; }
std::size_t size() const { return entries_.size(); }
const IdEntry* find(int id) const;
std::optional<int> id_of(std::string_view name_or_stem) const; // case-insensitive
bool is_deleted(int id) const;
void add(IdEntry e);
void add_deleted(int id) { deleted_.push_back(id); }
private:
std::vector<IdEntry> entries_;
std::vector<int> deleted_;
};
Loaded<IdRegistry> parse_id_registry(std::string_view text, std::string file = {});
} // namespace game::data