diff options
Diffstat (limited to 'src/engine/app.cpp')
| -rw-r--r-- | src/engine/app.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/src/engine/app.cpp b/src/engine/app.cpp index 0de71c5..cfe924c 100644 --- a/src/engine/app.cpp +++ b/src/engine/app.cpp @@ -148,7 +148,7 @@ void App::run() { device_defs[i].texture); SDL_Texture* deposit_tex = renderer.load_texture("data/textures/deposit.png"); - struct Device { int def, team; float x, y, hp, max_hp; bool on_deposit; }; + struct Device { int def, team; float x, y, hp, max_hp; bool on_deposit; int graph_id = -1; }; std::vector<Device> devices; auto devidx = [&](const char* n) -> int { @@ -177,11 +177,24 @@ void App::run() { int cur_mat = 0; int place_dev = -1; // >=0 = placing that device type; -1 = build materials + // Mount a device onto the nearest strut so cutting its supports destroys + // it (win-condition path (c): reactor falls when its supports are cut). + // Devices with no nearby strut (radius 2.0) stay unmounted (-1) and are + // only killed by weapon damage, same as before this feature existed. + const float MOUNT_RADIUS = 2.0f; + auto mount_at = [&](float x, float y, int def_idx, int team, float hp) -> int { + int eid = graph.find_nearest_edge(x, y, MOUNT_RADIUS); + if (eid < 0) return -1; + const BuildEdge& e = graph.edges[eid]; + return graph.mount_device(e.node_a, e.node_b, def_idx, team, hp); + }; + auto reset = [&]() { const MapDef& m = maps[current_map]; graph.nodes = snap_nodes; graph.edges = snap_edges; graph.rebuild(); + graph.devices.clear(); devices.clear(); for (auto& pd : m.devices) { int di = -1; @@ -190,6 +203,7 @@ void App::run() { if (di < 0) continue; Device dv{di, pd.team, pd.x, pd.y, device_defs[di].hp, device_defs[di].hp, true}; if (device_defs[di].needs_deposit) dv.on_deposit = on_deposit(pd.x, pd.y); + dv.graph_id = mount_at(pd.x, pd.y, di, pd.team, device_defs[di].hp); devices.push_back(dv); } cannons.clear(); @@ -317,8 +331,10 @@ void App::run() { const DeviceDef& def = device_defs[place_dev]; bool dep_ok = !def.needs_deposit || on_deposit(wx, wy); if (dep_ok && metal >= def.cost_metal && energy >= def.cost_energy) { - devices.push_back({ place_dev, 0, wx, wy, def.hp, def.hp, - def.needs_deposit ? on_deposit(wx, wy) : true }); + Device dv{ place_dev, 0, wx, wy, def.hp, def.hp, + def.needs_deposit ? on_deposit(wx, wy) : true }; + dv.graph_id = mount_at(wx, wy, place_dev, 0, def.hp); + devices.push_back(dv); metal -= def.cost_metal; energy -= def.cost_energy; } @@ -419,6 +435,14 @@ void App::run() { graph.update_fire(FIXED_DT); // burn DoT + spread graph.kill_grounded(); // destroy debris below the ground + // Devices mounted on the strut graph: if structural collapse (a + // snapped strut, kill_grounded) took out both mount nodes, the + // device falls too -- this is win-condition path (c), cutting + // supports to drop the reactor. + for (auto& dv : devices) + if (dv.graph_id >= 0 && !graph.is_device_alive(dv.graph_id)) + dv.hp = 0.0f; + // Weapons: tick reloads. for (auto& c : cannons) if (c.cooldown > 0.0f) c.cooldown = std::max(0.0f, c.cooldown - FIXED_DT); @@ -487,6 +511,8 @@ void App::run() { } accumulator -= FIXED_DT; } + for (auto& dv : devices) + if (dv.hp <= 0.0f && dv.graph_id >= 0) graph.unmount_device(dv.graph_id); devices.erase(std::remove_if(devices.begin(), devices.end(), [](const Device& d){ return d.hp <= 0.0f; }), devices.end()); projectiles.erase( |
