From e75156e052477669d327498e6e396f8c84160b01 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 4 Sep 2021 00:34:30 -0400 Subject: [PATCH] Hacky raid mechanics for cultist raiders. --- server/src/rtsim/entity.rs | 72 ++++++++++++++++++++++++++++++++++++++ server/src/rtsim/mod.rs | 39 ++++++++++++++------- 2 files changed, 98 insertions(+), 13 deletions(-) diff --git a/server/src/rtsim/entity.rs b/server/src/rtsim/entity.rs index 97498fdcb4..eca83fc977 100644 --- a/server/src/rtsim/entity.rs +++ b/server/src/rtsim/entity.rs @@ -475,6 +475,58 @@ impl Entity { Travel::Lost } }, + Travel::DirectRaid { + target_id, + home_id, + raid_complete, + } => { + let dest_site = if raid_complete { + &world.civs().sites[home_id] + } else { + &world.civs().sites[target_id] + }; + let destination_name = dest_site + .site_tmp + .map_or("".to_string(), |id| index.sites[id].name().to_string()); + + let wpos = dest_site.center * TerrainChunk::RECT_SIZE.map(|e| e as i32); + let dist = wpos.map(|e| e as f32).distance_squared(self.pos.xy()) as u32; + + if dist < 64_u32.pow(2) { + Travel::DirectRaid { + target_id, + home_id, + raid_complete: !raid_complete, + } + } else { + let travel_to = self.pos.xy() + + Vec3::from( + (wpos.map(|e| e as f32 + 0.5) - self.pos.xy()) + .try_normalized() + .unwrap_or_else(Vec2::zero), + ) * 64.0; + let travel_to_alt = world + .sim() + .get_alt_approx(travel_to.map(|e| e as i32)) + .unwrap_or(0.0) as i32; + let travel_to = terrain + .find_space(Vec3::new( + travel_to.x as i32, + travel_to.y as i32, + travel_to_alt, + )) + .map(|e| e as f32) + + Vec3::new(0.5, 0.5, 0.0); + + self.controller.travel_to = Some((travel_to, destination_name)); + self.controller.speed_factor = 0.70; + Travel::DirectRaid { + target_id, + home_id, + raid_complete, + } + } + }, Travel::Idle => Travel::Idle, }; @@ -517,6 +569,12 @@ enum Travel { progress: usize, reversed: bool, }, + // Move directly towards a target site, then head back to a home territory + DirectRaid { + target_id: Id, + home_id: Id, + raid_complete: bool, + }, // For testing purposes Idle, } @@ -545,6 +603,20 @@ impl Brain { } } + pub fn raid(home_id: Id, target_id: Id) -> Self { + Self { + begin: None, + tgt: None, + route: Travel::DirectRaid { + target_id, + home_id, + raid_complete: false, + }, + last_visited: None, + memories: Vec::new(), + } + } + pub fn add_memory(&mut self, memory: Memory) { self.memories.push(memory); } pub fn forget_enemy(&mut self, to_forget: &str) { diff --git a/server/src/rtsim/mod.rs b/server/src/rtsim/mod.rs index 239150376b..b1e9df2234 100644 --- a/server/src/rtsim/mod.rs +++ b/server/src/rtsim/mod.rs @@ -136,28 +136,41 @@ pub fn init( brain: Default::default(), }); } - for site in world + for (site_id, site) in world .civs() .sites .iter() - .filter_map(|(_, site)| site.site_tmp.map(|id| &index.sites[id])) + .filter_map(|(site_id, site)| site.site_tmp.map(|id| (site_id, &index.sites[id]))) { use world::site::SiteKind; match &site.kind { SiteKind::Dungeon(dungeon) => match dungeon.dungeon_difficulty() { Some(5) => { let pos = site.get_origin(); - - for _ in 0..25 { - rtsim.entities.insert(Entity { - is_loaded: false, - pos: Vec3::from(pos.map(|e| e as f32)), - seed: thread_rng().gen(), - controller: RtSimController::default(), - last_time_ticked: 0.0, - kind: RtSimEntityKind::Cultist, - brain: Brain::idle(), - }); + if let Some(nearest_village) = world + .civs() + .sites + .iter() + .filter(|s| s.1.is_settlement()) + .min_by_key(|(_, site)| { + let wpos = site.center * TerrainChunk::RECT_SIZE.map(|e| e as i32); + wpos.map(|e| e as f32) + .distance_squared(pos.map(|x| x as f32)) + as u32 + }) + .map(|(id, _)| id) + { + for _ in 0..25 { + rtsim.entities.insert(Entity { + is_loaded: false, + pos: Vec3::from(pos.map(|e| e as f32)), + seed: thread_rng().gen(), + controller: RtSimController::default(), + last_time_ticked: 0.0, + kind: RtSimEntityKind::Cultist, + brain: Brain::raid(site_id, nearest_village), + }); + } } }, _ => {},