aboutsummaryrefslogtreecommitdiffstats
path: root/src/game/build_graph.hpp
diff options
context:
space:
mode:
authorVaino Kauppila <vaino@vke.fi>2026-07-30 11:56:27 +0300
committerVaino Kauppila <vaino@vke.fi>2026-07-30 11:56:27 +0300
commit6cdd436caf9e2103f516442ab6e70a870d4cba04 (patch)
tree7a69242d34ef3739f3e554227213ec5d91a2a958 /src/game/build_graph.hpp
parent521b5da83485a956811fc510cba9f139acad8b26 (diff)
downloadforts_clone-6cdd436caf9e2103f516442ab6e70a870d4cba04.tar.gz
forts_clone-6cdd436caf9e2103f516442ab6e70a870d4cba04.zip
Mount devices on the strut graph so cutting supports destroys them
Implements win-condition path (c): destroy the enemy reactor by cutting its supports so it falls. Previously devices sat at fixed map coordinates, structurally immune to collapse. - BuildGraph gains MountedDevice tracking: mount_device/unmount_device, is_device_alive/get_device_hp/damage_device, nearest_device, with a break_node index-shift fix so mount references stay correct as other geometry on the same fort is destroyed. update_fire now also damages any device mounted on a burning strut. - app.cpp mounts devices onto the nearest strut (within 2 units) at both map-load and interactive placement, and after each tick's structural collapse pass, zeroes a device's HP if its mount didn't survive -- which flows through the existing win-condition/cleanup code unchanged. - tools/device_collapse_test.cpp: 15 headless tests covering collapse, partial support loss, splash/beam/fire-through-mount damage, multiple devices, index stability, and clean unmount. Verified: full test suite passes (15/15), sim_check shows zero regressions across all 3 maps. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'src/game/build_graph.hpp')
-rw-r--r--src/game/build_graph.hpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/game/build_graph.hpp b/src/game/build_graph.hpp
index 4452139..cd8dc3d 100644
--- a/src/game/build_graph.hpp
+++ b/src/game/build_graph.hpp
@@ -67,6 +67,17 @@ struct BuildEdge {
struct BuildFace { int node_a, node_b, node_c; };
+// A device mounted on the strut graph via two mount nodes. It is destroyed when
+// (a) both mount nodes are removed (fall below ground, snap, break), or
+// (b) its HP reaches zero from splash/beam/fire damage.
+struct MountedDevice {
+ int node_a, node_b; // mount-point node indices (-1 if destroyed)
+ int type; // index into DeviceDefs (from data.hpp)
+ int team = 0; // team index (0 = player, 1 = enemy)
+ float hp, max_hp;
+ bool alive = true;
+};
+
class BuildGraph {
public:
// Material table, loaded from Lua at startup (build modes index into it).
@@ -133,6 +144,24 @@ public:
// e.g. restoring a scenario snapshot).
void rebuild() { rebuild_topology(); }
+ // --- devices mounted on the strut graph ------------------------------
+ // Attach a device to two mount nodes (any type from DeviceDefs).
+ // Returns the device index in the graph's devices vector.
+ int mount_device(int na, int nb, int device_type, int team, float hp);
+
+ // Remove a device (e.g. when a weapon shot destroys it outright).
+ // Does NOT shift indices — marks it dead and skips it in queries.
+ void unmount_device(int device_id);
+
+ bool is_device_alive(int device_id) const;
+ float get_device_hp(int device_id) const;
+ const std::vector<MountedDevice>& get_devices() const { return devices; }
+ int nearest_device(float x, float y, float radius) const;
+
+ // Deal damage to a device (splash/beam/fire). Returns true if the device
+ // was alive before and is dead after (for downstream win-condition checks).
+ bool damage_device(int device_id, float amount);
+
// --- destruction primitives -------------------------------------------
void break_edge(int edge_id);
void break_node(int node_id);
@@ -147,6 +176,7 @@ public:
std::vector<BuildNode> nodes;
std::vector<BuildEdge> edges;
std::vector<BuildFace> faces;
+ std::vector<MountedDevice> devices;
struct Destroyed { float x, y; };
std::vector<Destroyed> destroyed_events; // drained by the app for FX