115 lines
4.5 KiB
C++
115 lines
4.5 KiB
C++
// game::data -- ShipSectionDef: one `Species/<Race>/sections/*.shipsection`.
|
|
//
|
|
// shipsection {
|
|
// model PATH requires_tech TECH... section_type command|mission|engine
|
|
// section_class destroyer|cruiser|dreadnought
|
|
// health mass cost cpoints crew socket_fore/socket_aft NODE
|
|
// option TECH -- one-member option group
|
|
// option { option A option B } -- mutually exclusive option group
|
|
// optiondef { option ... } -- shield-level group (shield sections)
|
|
// bank { turretclass C turretsize S [weapon FILE] mount { node N min/max_azimuth min/max_inclination } ... }
|
|
// ftlspeed nodespeed engine_techera netforcelimits { force_* torque_* speed rotspeed }
|
|
// thruster { node effect idle_effect }
|
|
// }
|
|
//
|
|
// `options` is the normalised view of every `option` entry in file order:
|
|
// a scalar `option T` becomes a one-member group, a block keeps its members.
|
|
// `section_type` / `section_class` are case-mixed in the data; the enums are
|
|
// derived case-insensitively and the text is kept as written.
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
#include "game/data/block.h"
|
|
#include "game/data/common.h"
|
|
#include "mars/parse/blocks.h"
|
|
|
|
namespace game::data {
|
|
|
|
enum class SectionType { None, Command, Mission, Engine, Other };
|
|
enum class SectionClass { None, Destroyer, Cruiser, Dreadnought, Other };
|
|
|
|
std::string_view section_type_name(SectionType t);
|
|
std::string_view section_class_name(SectionClass c);
|
|
SectionType parse_section_type(std::string_view s);
|
|
SectionClass parse_section_class(std::string_view s);
|
|
|
|
struct OptionGroup {
|
|
std::vector<std::string> members; // tech names, file order
|
|
bool scalar = false; // written as `option T` (one member)
|
|
int line = 0;
|
|
};
|
|
|
|
struct MountDef {
|
|
std::string node;
|
|
std::optional<double> min_azimuth, max_azimuth, min_inclination, max_inclination;
|
|
std::optional<double> home_azimuth, home_inclination;
|
|
int line = 0;
|
|
};
|
|
|
|
struct BankDef {
|
|
std::string turret_class; // last value if the key repeats
|
|
std::string turret_size;
|
|
std::string weapon; // fixed weapon file (NPC banks); "" when the design chooses
|
|
std::optional<bool> show_turrets, invincible;
|
|
std::vector<MountDef> mounts;
|
|
bool repeated_turret_spec = false; // turretsize/turretclass written more than once
|
|
int line = 0;
|
|
};
|
|
|
|
struct NetForceLimits {
|
|
std::optional<double> force_forward, force_right, force_up;
|
|
std::optional<double> torque_yaw, torque_pitch, torque_roll;
|
|
std::optional<double> speed, rotspeed;
|
|
};
|
|
|
|
struct ThrusterDef {
|
|
std::string node, effect, idle_effect;
|
|
};
|
|
|
|
struct ShipSectionDef {
|
|
// identity (filled by the catalog)
|
|
std::string race; // directory name under Species/
|
|
Species species = Species::Unknown;
|
|
std::string stem;
|
|
std::string file;
|
|
std::optional<int> id; // from the race's _shipsections.txt
|
|
std::optional<std::string> display_name, description;
|
|
std::vector<std::string> unlocked_by; // techs whose ship{section} lists this stem
|
|
|
|
// body
|
|
std::string model, dam_model;
|
|
std::vector<std::string> requires_tech; // AND; may name GRP_<group>
|
|
std::string section_type_text;
|
|
SectionType section_type = SectionType::None;
|
|
std::string section_class_text;
|
|
SectionClass section_class = SectionClass::None;
|
|
std::string design_class, entity_class;
|
|
std::optional<double> health, mass;
|
|
std::optional<std::int64_t> cost, cpoints, crew;
|
|
std::optional<std::int64_t> command_cost, maintenance_cost, command_quota;
|
|
std::string socket_fore, socket_aft, dam_socket_fore, dam_socket_aft;
|
|
std::vector<OptionGroup> options;
|
|
std::optional<OptionGroup> optiondef;
|
|
std::vector<BankDef> banks;
|
|
std::optional<double> ftlspeed, nodespeed, range, scanrange, tactical_sensor_range;
|
|
std::string engine_techera;
|
|
std::optional<NetForceLimits> netforcelimits;
|
|
std::vector<ThrusterDef> thrusters;
|
|
std::vector<std::string> exclude;
|
|
std::string explicit_command_section, explicit_engine_section;
|
|
std::optional<bool> explicit_section, autonomous, nodesign;
|
|
|
|
Block raw;
|
|
|
|
bool has_sockets() const { return !socket_fore.empty() || !socket_aft.empty(); }
|
|
};
|
|
|
|
Loaded<ShipSectionDef> load_shipsection(const mars::parse::Document& doc, std::string file = {});
|
|
Loaded<ShipSectionDef> parse_shipsection(std::string_view text, std::string file = {});
|
|
|
|
} // namespace game::data
|