Versus teams, gold for allies, fallen hearts as spectators, multi-mission editor co-op
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
811c955bad
commit
fc9c49d4ca
16 files changed
+1896
-49
No files matched your search
@@ -734,6 +734,20 @@ pub fn editor_fort(g: &mut Game, x: i32, y: i32, level: u32, shard: bool) {
|
||||
g.recount();
|
||||
}
|
||||
|
||||
// an island in a lake (water or lava) at a map fraction, with a mana spring and/or treasure
|
||||
pub fn editor_island(g: &mut Game, at: (f32, f32), lava: bool, spring: bool, treasure: i32, seed: u32) {
|
||||
let (w, h) = (g.map.w, g.map.h);
|
||||
place_island(g, &island(at, lava, spring, treasure), w, h, seed);
|
||||
g.recount();
|
||||
}
|
||||
|
||||
// a sealed cave at a map fraction, with a chained creature and/or treasure
|
||||
pub fn editor_cave(g: &mut Game, at: (f32, f32), chained: Option<(EK, u32)>, treasure: i32) {
|
||||
let (w, h) = (g.map.w, g.map.h);
|
||||
place_cave(g, &cave(at, chained, treasure), w, h);
|
||||
g.recount();
|
||||
}
|
||||
|
||||
// a painted map: the game state saved by the map editor
|
||||
pub fn load_fixed_map(json: &str) -> Option<Game> {
|
||||
let mut g: Game = serde_json::from_str(json).ok()?;
|
||||
@@ -774,6 +788,45 @@ pub fn carry_from(g: &Game) -> Carry {
|
||||
Carry { creatures: c.iter().take(CARRY_CREATURES).map(|e| (e.kind, e.level, e.xp)).collect(), gold: (g.gold * CARRY_GOLD).floor(), rune_free: g.rune_free, rune_final: g.rune_final + g.rune_next }
|
||||
}
|
||||
|
||||
// a co-op match of an editor campaign: what every master takes into the next mission - his
|
||||
// strongest creatures and a fifth of his gold. It comes from the shared world, so it is the same on
|
||||
// every client (the host sends it along with the next mission anyway).
|
||||
pub fn coop_carry_from(g: &Game) -> Vec<(u8, Carry)> {
|
||||
let power = |e: &Ent| e.max_hp * e.atk() / st(e.kind).interval;
|
||||
g.master_sides()
|
||||
.into_iter()
|
||||
.map(|side| {
|
||||
let mut c: Vec<&Ent> = g.ents.iter().filter(|e| e.alive && !e.hero && e.side == side && e.kind != EK::Worker && !e.chained && e.captive == 0).collect();
|
||||
c.sort_by(|a, b| power(b).partial_cmp(&power(a)).unwrap_or(std::cmp::Ordering::Equal).then(a.id.cmp(&b.id)));
|
||||
let creatures = c.iter().take(CARRY_CREATURES).map(|e| (e.kind, e.level, e.xp)).collect();
|
||||
(side, Carry { creatures, gold: (g.gold_of(side).max(0.0) * CARRY_GOLD).floor(), rune_free: 0, rune_final: 0 })
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// the carry of every master put into a new co-op mission: gold for him, his creatures around his heart
|
||||
pub fn apply_coop_carry(g: &mut Game, carry: &[(u8, Carry)]) {
|
||||
let local = g.local_side;
|
||||
for (side, c) in carry {
|
||||
if !g.is_master(*side) {
|
||||
continue; // the seat is played by the AI now
|
||||
}
|
||||
g.switch_to(*side);
|
||||
g.gold += c.gold.max(0.0);
|
||||
let (cx, cy) = g.map.core;
|
||||
for (k, &(kind, level, xp)) in c.creatures.iter().take(CARRY_CREATURES).enumerate() {
|
||||
let a = k as f32 * 1.1;
|
||||
let (x, y) = (cx as f32 + 1.5 + a.cos() * 3.0, cy as f32 + 1.5 + a.sin() * 3.0);
|
||||
let id = g.spawn(kind, false, x, y, level.clamp(1, 10));
|
||||
if let Some(e) = g.ents.iter_mut().find(|e| e.id == id) {
|
||||
e.xp = xp;
|
||||
e.happy = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
g.switch_to(local);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in new issue
Block a user