From b950447bedd389b906850d41f4c6d8d89102ef11 Mon Sep 17 00:00:00 2001 From: Monty Marz Date: Sat, 21 Nov 2020 00:30:14 +0100 Subject: [PATCH] added enum for different dungeon enemies --- server/src/rtsim/entity.rs | 129 ++++++++++++++--------- world/src/site/dungeon/mod.rs | 189 +++++++++++++++++++++++++++------- 2 files changed, 233 insertions(+), 85 deletions(-) diff --git a/server/src/rtsim/entity.rs b/server/src/rtsim/entity.rs index 3ea74561ab..4ce43e54e3 100644 --- a/server/src/rtsim/entity.rs +++ b/server/src/rtsim/entity.rs @@ -1,14 +1,9 @@ use super::*; +use common::{comp::item::tool::AbilityMap, store::Id, terrain::TerrainGrid, LoadoutBuilder}; use world::{ + civ::{Site, Track}, util::RandomPerm, World, - civ::{Site, Track}, -}; -use common::{ - terrain::TerrainGrid, - store::Id, - LoadoutBuilder, - comp::item::tool::AbilityMap, }; pub struct Entity { @@ -27,12 +22,12 @@ const PERM_LOADOUT: u32 = 2; const PERM_LEVEL: u32 = 3; impl Entity { - pub fn rng(&self, perm: u32) -> impl Rng { - RandomPerm::new(self.seed + perm) - } + pub fn rng(&self, perm: u32) -> impl Rng { RandomPerm::new(self.seed + perm) } pub fn get_body(&self) -> comp::Body { - let species = *(&comp::humanoid::ALL_SPECIES).choose(&mut self.rng(PERM_SPECIES)).unwrap(); + let species = *(&comp::humanoid::ALL_SPECIES) + .choose(&mut self.rng(PERM_SPECIES)) + .unwrap(); comp::humanoid::Body::random_with(&mut self.rng(PERM_BODY), &species).into() } @@ -42,54 +37,83 @@ impl Entity { pub fn get_loadout(&self, ability_map: &AbilityMap) -> comp::Loadout { let mut rng = self.rng(PERM_LOADOUT); - let main_tool = comp::Item::new_from_asset_expect((&[ - "common.items.weapons.sword.wood_sword", - "common.items.weapons.sword.starter_sword", - "common.items.weapons.sword.short_sword_0", - "common.items.weapons.bow.starter_bow", - "common.items.weapons.bow.leafy_longbow-0", - ]).choose(&mut rng).unwrap()); + let main_tool = comp::Item::new_from_asset_expect( + (&[ + "common.items.weapons.sword.wood_sword", + "common.items.weapons.sword.starter_sword", + "common.items.weapons.sword.short_sword_0", + "common.items.weapons.bow.starter_bow", + "common.items.weapons.bow.leafy_longbow-0", + ]) + .choose(&mut rng) + .unwrap(), + ); let back = match rng.gen_range(0, 5) { - 0 => Some(comp::Item::new_from_asset_expect("common.items.armor.back.leather_adventurer")), - 1 => Some(comp::Item::new_from_asset_expect("common.items.npc_armor.back.backpack_0")), - 2 => Some(comp::Item::new_from_asset_expect("common.items.npc_armor.back.backpack_blue_0")), - 3 => Some(comp::Item::new_from_asset_expect("common.items.npc_armor.back.leather_blue_0")), + 0 => Some(comp::Item::new_from_asset_expect( + "common.items.armor.back.leather_adventurer", + )), + 1 => Some(comp::Item::new_from_asset_expect( + "common.items.npc_armor.back.backpack_0", + )), + 2 => Some(comp::Item::new_from_asset_expect( + "common.items.npc_armor.back.backpack_blue_0", + )), + 3 => Some(comp::Item::new_from_asset_expect( + "common.items.npc_armor.back.leather_blue_0", + )), _ => None, }; let lantern = match rng.gen_range(0, 3) { - 0 => Some(comp::Item::new_from_asset_expect("common.items.lantern.black_0")), - 1 => Some(comp::Item::new_from_asset_expect("common.items.lantern.blue_0")), - _ => Some(comp::Item::new_from_asset_expect("common.items.lantern.red_0")), + 0 => Some(comp::Item::new_from_asset_expect( + "common.items.lantern.black_0", + )), + 1 => Some(comp::Item::new_from_asset_expect( + "common.items.lantern.blue_0", + )), + _ => Some(comp::Item::new_from_asset_expect( + "common.items.lantern.red_0", + )), }; - let chest = Some(comp::Item::new_from_asset_expect("common.items.npc_armor.chest.leather_blue_0")); - let pants = Some(comp::Item::new_from_asset_expect("common.items.npc_armor.pants.leather_blue_0")); - let shoulder = Some(comp::Item::new_from_asset_expect("common.items.armor.shoulder.leather_0")); + let chest = Some(comp::Item::new_from_asset_expect( + "common.items.npc_armor.chest.leather_blue_0", + )); + let pants = Some(comp::Item::new_from_asset_expect( + "common.items.npc_armor.pants.leather_blue_0", + )); + let shoulder = Some(comp::Item::new_from_asset_expect( + "common.items.armor.shoulder.leather_0", + )); - LoadoutBuilder::build_loadout(self.get_body(), comp::Alignment::Npc, Some(main_tool), false, ability_map) - .back(back) - .lantern(lantern) - .chest(chest) - .pants(pants) - .shoulder(shoulder) - .build() + LoadoutBuilder::build_loadout( + self.get_body(), + comp::Alignment::Npc, + Some(main_tool), + false, + ability_map, + None, + ) + .back(back) + .lantern(lantern) + .chest(chest) + .pants(pants) + .shoulder(shoulder) + .build() } pub fn tick(&mut self, terrain: &TerrainGrid, world: &World) { let tgt_site = self.brain.tgt.or_else(|| { - world.civs().sites + world + .civs() + .sites .iter() .filter(|_| thread_rng().gen_range(0i32, 4) == 0) .min_by_key(|(_, site)| { let wpos = site.center * TerrainChunk::RECT_SIZE.map(|e| e as i32); let dist = wpos.map(|e| e as f32).distance(self.pos.xy()) as u32; - dist + if dist < 96 { - 100_000 - } else { - 0 - } + dist + if dist < 96 { 100_000 } else { 0 } }) .map(|(id, _)| id) }); @@ -105,11 +129,24 @@ impl Entity { self.brain.tgt = None; } - 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); + 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); self.controller.speed_factor = 0.70; }); diff --git a/world/src/site/dungeon/mod.rs b/world/src/site/dungeon/mod.rs index 5d916e6831..09a9b85829 100644 --- a/world/src/site/dungeon/mod.rs +++ b/world/src/site/dungeon/mod.rs @@ -3,7 +3,7 @@ use crate::{ block::block_from_structure, column::ColumnSample, sim::WorldSim, - site::{BlockMask, namegen::NameGen}, + site::{namegen::NameGen, BlockMask}, util::{attempt, Grid, RandomField, Sampler, CARDINALS, DIRS}, IndexRef, }; @@ -76,7 +76,8 @@ impl Dungeon { noise: RandomField::new(ctx.rng.gen()), floors: (0..LEVELS) .scan(Vec2::zero(), |stair_tile, level| { - let (floor, st) = Floor::generate(&mut ctx, *stair_tile, level as i32, difficulty); + let (floor, st) = + Floor::generate(&mut ctx, *stair_tile, level as i32, difficulty); *stair_tile = st; Some(floor) }) @@ -87,9 +88,7 @@ impl Dungeon { this } - pub fn name(&self) -> &str { - &self.name - } + pub fn name(&self) -> &str { &self.name } pub fn get_origin(&self) -> Vec2 { self.origin } @@ -103,9 +102,7 @@ impl Dungeon { } } - pub fn difficulty(&self) -> u32 { - self.difficulty - } + pub fn difficulty(&self) -> u32 { self.difficulty } pub fn apply_to<'a>( &'a self, @@ -200,12 +197,10 @@ impl Dungeon { // Add waypoint let pos = self.origin.map2(FLOOR_SIZE, |e, sz| e + sz as i32 / 2); if area.contains_point(pos - self.origin) { - supplement.add_entity(EntityInfo::at(Vec3::new( - pos.x as f32, - pos.y as f32, - self.alt as f32, - ) + 0.5) - .into_waypoint()); + supplement.add_entity( + EntityInfo::at(Vec3::new(pos.x as f32, pos.y as f32, self.alt as f32) + 0.5) + .into_waypoint(), + ); } let mut z = self.alt + ALT_OFFSET; @@ -531,14 +526,57 @@ impl Floor { && !tile_is_pillar { // Bad - let chosen = - Lottery::::load_expect(match dynamic_rng.gen_range(0, 5) { - 0 => "common.loot_tables.loot_table_humanoids", - 1 => "common.loot_tables.loot_table_armor_misc", - _ => "common.loot_tables.loot_table_cultists", - }); + let chosen = match room.difficulty { + 0 => { + Lottery::::load_expect(match dynamic_rng.gen_range(0, 5) { + 0 => "common.loot_tables.loot_table_humanoids", + 1 => "common.loot_tables.loot_table_armor_misc", + _ => "common.loot_tables.loot_table_cultists", + }) + }, + 1 => { + Lottery::::load_expect(match dynamic_rng.gen_range(0, 5) { + 0 => "common.loot_tables.loot_table_humanoids", + 1 => "common.loot_tables.loot_table_armor_misc", + _ => "common.loot_tables.loot_table_cultists", + }) + }, + 2 => { + Lottery::::load_expect(match dynamic_rng.gen_range(0, 5) { + 0 => "common.loot_tables.loot_table_humanoids", + 1 => "common.loot_tables.loot_table_armor_misc", + _ => "common.loot_tables.loot_table_cultists", + }) + }, + 3 => { + Lottery::::load_expect(match dynamic_rng.gen_range(0, 5) { + 0 => "common.loot_tables.loot_table_humanoids", + 1 => "common.loot_tables.loot_table_armor_misc", + _ => "common.loot_tables.loot_table_cultists", + }) + }, + 4 => { + Lottery::::load_expect(match dynamic_rng.gen_range(0, 5) { + 0 => "common.loot_tables.loot_table_humanoids", + 1 => "common.loot_tables.loot_table_armor_misc", + _ => "common.loot_tables.loot_table_cultists", + }) + }, + 5 => { + Lottery::::load_expect(match dynamic_rng.gen_range(0, 5) { + 0 => "common.loot_tables.loot_table_humanoids", + 1 => "common.loot_tables.loot_table_armor_misc", + _ => "common.loot_tables.loot_table_cultists", + }) + }, + _ => Lottery::::load_expect( + "common.loot_tables.loot_table_armor_misc", + ), + }; let chosen = chosen.choose(); - let is_giant = RandomField::new(room.seed.wrapping_add(1)).chance(Vec3::from(tile_pos), 0.2) && !room.boss; + //let is_giant = + // RandomField::new(room.seed.wrapping_add(1)).chance(Vec3::from(tile_pos), + // 0.2) && !room.boss; let entity = EntityInfo::at( tile_wcenter.map(|e| e as f32) // Randomly displace them a little @@ -546,24 +584,92 @@ impl Floor { .map(|e| (RandomField::new(room.seed.wrapping_add(10 + e)).get(Vec3::from(tile_pos)) % 32) as i32 - 16) .map(|e| e as f32 / 16.0), ) - .do_if(is_giant, |e| e.into_giant()) - .with_alignment(comp::Alignment::Enemy) + //.do_if(is_giant, |e| e.into_giant()) .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) - .with_name("Cultist Acolyte") - .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_main_tool(comp::Item::new_from_asset_expect(match dynamic_rng.gen_range(0, 6) { - 0 => "common.items.npc_weapons.axe.malachite_axe-0", - 1 => "common.items.npc_weapons.sword.cultist_purp_2h-0", - 2 => "common.items.npc_weapons.sword.cultist_purp_2h-0", - 3 => "common.items.npc_weapons.hammer.cultist_purp_2h-0", - 4 => "common.items.npc_weapons.staff.cultist_staff", - _ => "common.items.npc_weapons.bow.horn_longbow-0", - })) - .with_level(dynamic_rng.gen_range( + .with_alignment(comp::Alignment::Enemy) + .with_loot_drop(comp::Item::new_from_asset_expect(chosen)).with_evel(dynamic_rng.gen_range( (room.difficulty as f32).powf(1.25) + 3.0, (room.difficulty as f32).powf(1.5) + 4.0, ).round() as u32); - + let entity = match room.difficulty { + 0 => entity.with_name("Outcast").with_main_tool( + comp::Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 6) { + 0 => "common.items.npc_weapons.axe.malachite_axe-0", + 1 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 2 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 3 => "common.items.npc_weapons.hammer.cultist_purp_2h-0", + 4 => "common.items.npc_weapons.staff.cultist_staff", + _ => "common.items.npc_weapons.bow.horn_longbow-0", + }, + ), + ), + 1 => entity.with_name("Highwayman").with_main_tool( + comp::Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 6) { + 0 => "common.items.npc_weapons.axe.malachite_axe-0", + 1 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 2 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 3 => "common.items.npc_weapons.hammer.cultist_purp_2h-0", + 4 => "common.items.npc_weapons.staff.cultist_staff", + _ => "common.items.npc_weapons.bow.horn_longbow-0", + }, + ), + ), + 2 => entity.with_name("Bandit").with_main_tool( + comp::Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 6) { + 0 => "common.items.npc_weapons.axe.malachite_axe-0", + 1 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 2 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 3 => "common.items.npc_weapons.hammer.cultist_purp_2h-0", + 4 => "common.items.npc_weapons.staff.cultist_staff", + _ => "common.items.npc_weapons.bow.horn_longbow-0", + }, + ), + ), + 3 => entity.with_name("Cultist Novice").with_main_tool( + comp::Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 6) { + 0 => "common.items.npc_weapons.axe.malachite_axe-0", + 1 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 2 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 3 => "common.items.npc_weapons.hammer.cultist_purp_2h-0", + 4 => "common.items.npc_weapons.staff.cultist_staff", + _ => "common.items.npc_weapons.bow.horn_longbow-0", + }, + ), + ), + 4 => entity.with_name("Cultist Acolyte").with_main_tool( + comp::Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 6) { + 0 => "common.items.npc_weapons.axe.malachite_axe-0", + 1 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 2 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 3 => "common.items.npc_weapons.hammer.cultist_purp_2h-0", + 4 => "common.items.npc_weapons.staff.cultist_staff", + _ => "common.items.npc_weapons.bow.horn_longbow-0", + }, + ), + ), + 5 => entity.with_name("Cultist Elite").with_main_tool( + comp::Item::new_from_asset_expect( + match dynamic_rng.gen_range(0, 6) { + 0 => "common.items.npc_weapons.axe.malachite_axe-0", + 1 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 2 => "common.items.npc_weapons.sword.cultist_purp_2h-0", + 3 => "common.items.npc_weapons.hammer.cultist_purp_2h-0", + 4 => "common.items.npc_weapons.staff.cultist_staff", + _ => "common.items.npc_weapons.bow.horn_longbow-0", + }, + ), + ), + _ => entity.with_name("Humanoid").with_main_tool( + comp::Item::new_from_asset_expect( + "common.items.npc_weapons.bow.horn_longbow-0", + ), + ), + }; supplement.add_entity(entity); } @@ -595,10 +701,15 @@ impl Floor { ))) .with_name("Stonework Defender".to_string()) .with_loot_drop(comp::Item::new_from_asset_expect(chosen)) - .with_level(dynamic_rng.gen_range( - (room.difficulty as f32).powf(1.25) + 3.0, - (room.difficulty as f32).powf(1.5) + 4.0, - ).round() as u32 * 5); + .with_level( + dynamic_rng + .gen_range( + (room.difficulty as f32).powf(1.25) + 3.0, + (room.difficulty as f32).powf(1.5) + 4.0, + ) + .round() as u32 + * 5, + ); supplement.add_entity(entity); }