108 lines
4.3 KiB
C++
108 lines
4.3 KiB
C++
// 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
|
|
// <class block> { 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 <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 WeaponScope { Player, NPC };
|
|
|
|
// Damage falloff by range band: point-blank / effective / maximum.
|
|
struct RangeTable {
|
|
struct Band {
|
|
std::optional<double> range, deviation, damage;
|
|
};
|
|
Band point_blank, effective, maximum;
|
|
};
|
|
|
|
// Damage applied to a planet on impact (present in most behaviour blocks).
|
|
struct PlanetDamage {
|
|
std::optional<double> pop, infra, terra;
|
|
};
|
|
|
|
struct BoltDef {
|
|
RangeTable rangetable;
|
|
PlanetDamage planet;
|
|
std::optional<double> mass, beam_origin, beam_length, ricochet_mod;
|
|
std::string effect, impact_effect, expire_effect;
|
|
};
|
|
|
|
struct FireControl {
|
|
std::optional<bool> requires_los, requires_inrange, requires_enemycolony;
|
|
std::optional<bool> manual_target, manual_toggle, manual_launch;
|
|
std::optional<bool> controllable, holdsfire;
|
|
std::optional<bool> explicit_target, exclusive_launch, targets_expire;
|
|
};
|
|
|
|
struct Ratings {
|
|
std::optional<double> 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<int> id; // from Weapons/_weapons.txt (player weapons only)
|
|
std::optional<std::string> 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<std::string> requires; // AND of techs; may be empty
|
|
std::vector<std::string> compatible_section; // rider weapons: section stems they carry
|
|
std::string exclusive_species;
|
|
std::optional<std::int64_t> cost;
|
|
std::string turret_size; // tiny / small / medium / large (as written)
|
|
std::string turret_class; // standard / missile / beam / ... (as written)
|
|
std::optional<double> track_speed_mod;
|
|
std::optional<std::int64_t> burst_volleys;
|
|
std::optional<double> recharge_time, volley_period, volley_duration, buildup_delay, solution_tolerance;
|
|
std::optional<std::int64_t> range, range_planet, muzzle_speed, hpbonus, dam_est;
|
|
std::optional<bool> 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<BoltDef> bolt; // typed when behavior_kind == "bolt"
|
|
std::optional<RangeTable> 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<std::string_view>& weapon_behavior_blocks();
|
|
|
|
Loaded<WeaponDef> load_weapon(const mars::parse::Document& doc, std::string file = {});
|
|
Loaded<WeaponDef> parse_weapon(std::string_view text, std::string file = {});
|
|
|
|
} // namespace game::data
|