// game::data -- WeaponDef: one `*.weapon` file. // // weapon { // name @WEAPON_X weaponclass bullet weaponfamily gauss // requires TECH [requires TECH2] cost N // turretsize small turretclass standard // burst_volleys N recharge_time T range R range_planet RP // fc_* true/false rating_* N // { rangetable {...} dam_pop dam_infra dam_terra ... } // } // // Typed fields cover the keys design/combat rules read; the class-specific // behaviour block (bolt/beam/torpedo/missile/...) is typed for `bolt` and // reachable for every class through `behavior()` / `raw`. #pragma once #include #include #include #include #include #include "game/data/block.h" #include "game/data/common.h" #include "mars/parse/blocks.h" namespace game::data { enum class WeaponScope { Player, NPC }; // Damage falloff by range band: point-blank / effective / maximum. struct RangeTable { struct Band { std::optional range, deviation, damage; }; Band point_blank, effective, maximum; }; // Damage applied to a planet on impact (present in most behaviour blocks). struct PlanetDamage { std::optional pop, infra, terra; }; struct BoltDef { RangeTable rangetable; PlanetDamage planet; std::optional mass, beam_origin, beam_length, ricochet_mod; std::string effect, impact_effect, expire_effect; }; struct FireControl { std::optional requires_los, requires_inrange, requires_enemycolony; std::optional manual_target, manual_toggle, manual_launch; std::optional controllable, holdsfire; std::optional explicit_target, exclusive_launch, targets_expire; }; struct Ratings { std::optional fire_rate, damage, accuracy, range; }; struct WeaponDef { // identity (filled by the catalog; empty/nullopt for a standalone load) std::string stem; // file name without extension, as on disk std::string file; // path relative to the data root, '/'-separated WeaponScope scope = WeaponScope::Player; std::optional id; // from Weapons/_weapons.txt (player weapons only) std::optional display_name; // resolved `name` token // body std::string name; // "@WEAPON_X" token as written std::string weapon_class; // drives engine behaviour (bullet, beam, missile, ...) std::string weapon_family; // AI grouping (gauss, laser, torpedo, ...) std::string weapon_damage_type; std::vector requires; // AND of techs; may be empty std::vector compatible_section; // rider weapons: section stems they carry std::string exclusive_species; std::optional cost; std::string turret_size; // tiny / small / medium / large (as written) std::string turret_class; // standard / missile / beam / ... (as written) std::optional track_speed_mod; std::optional burst_volleys; std::optional recharge_time, volley_period, volley_duration, buildup_delay, solution_tolerance; std::optional range, range_planet, muzzle_speed, hpbonus, dam_est; std::optional hidden, pinpoint, blindfire, secondary_pd; std::string model1, model2, model3; std::string muzzle_effect, muzzle_sound, icon_file, icon_rect; FireControl fc; Ratings ratings; std::string behavior_kind; // name of the class block found (bolt, beam, torpedo, ...) std::optional bolt; // typed when behavior_kind == "bolt" std::optional rangetable; // from bolt{} or torpedo{} PlanetDamage planet_damage; // dam_pop/infra/terra of the behaviour block Block raw; // the whole weapon{} block const Block* behavior() const { return behavior_kind.empty() ? nullptr : raw.block(behavior_kind); } }; // Names of the behaviour blocks the engine keys on `weaponclass`; the loader // takes the first of these present in the weapon block. const std::vector& weapon_behavior_blocks(); Loaded load_weapon(const mars::parse::Document& doc, std::string file = {}); Loaded parse_weapon(std::string_view text, std::string file = {}); } // namespace game::data