Generate some entities in the pub using raws system

This commit is contained in:
Timothy Warren 2021-12-24 13:23:56 -05:00
parent a4e9c27c8f
commit 3f561e2ffc
7 changed files with 201 additions and 17 deletions

View File

@ -264,7 +264,8 @@
"defense": 1, "defense": 1,
"power": 4 "power": 4
}, },
"vision_range": 8 "vision_range": 8,
"ai": "melee"
}, },
{ {
"name": "Goblin", "name": "Goblin",
@ -281,7 +282,8 @@
"defense": 1, "defense": 1,
"power": 3 "power": 3
}, },
"vision_range": 8 "vision_range": 8,
"ai": "melee"
}, },
{ {
"name": "Kobold", "name": "Kobold",
@ -298,7 +300,62 @@
"defense": 0, "defense": 0,
"power": 2 "power": 2
}, },
"vision_range": 4 "vision_range": 4,
"ai": "melee"
},
{
"name": "Barkeep",
"renderable": {
"glyph": "☺",
"fg": "#EE82EE",
"bg": "#000000",
"order": 1
},
"blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4,
"ai": "bystander"
},
{
"name": "Shady Salesman",
"renderable": {
"glyph": "h",
"fg": "#EE82EE",
"bg": "#000000",
"order": 1
},
"blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4,
"ai": "bystander"
},
{
"name": "Patron",
"renderable": {
"glyph": "☺",
"fg": "#AAAAAA",
"bg": "#000000",
"order": 1
},
"blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4,
"ai": "bystander"
} }
], ],
"props": [ "props": [
@ -330,6 +387,36 @@
"blocks_tile": true, "blocks_tile": true,
"blocks_visibility": true, "blocks_visibility": true,
"door_open": true "door_open": true
},
{
"name": "Keg",
"renderable": {
"glyph": "φ",
"fg": "#AAAAAA",
"bg": "#000000",
"order": 2
},
"hidden": false
},
{
"name": "Table",
"renderable": {
"glyph": "╦",
"fg": "#AAAAAA",
"bg": "#000000",
"order": 2
},
"hidden": false
},
{
"name": "Chair",
"renderable": {
"glyph": "└",
"fg": "#AAAAAA",
"bg": "#000000",
"order": 2
},
"hidden": false
} }
] ]
} }

View File

@ -237,6 +237,9 @@ pub struct Door {
pub open: bool, pub open: bool,
} }
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct Bystander {}
// Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an // Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an
// Entity. // Entity.

View File

@ -532,6 +532,7 @@ fn main() -> ::rltk::BError {
SingleActivation, SingleActivation,
BlocksVisibility, BlocksVisibility,
Door, Door,
Bystander,
); );
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new()); gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());

View File

@ -17,6 +17,18 @@ pub fn town_builder(
chain chain
} }
enum BuildingTag {
Pub,
Temple,
Blacksmith,
Clothier,
Alchemist,
PlayerHouse,
Hovel,
Abandoned,
Unassigned,
}
pub struct TownBuilder {} pub struct TownBuilder {}
impl InitialMapBuilder for TownBuilder { impl InitialMapBuilder for TownBuilder {
@ -50,19 +62,8 @@ impl TownBuilder {
let exit_idx = build_data.map.xy_idx(build_data.width - 5, wall_gap_y); let exit_idx = build_data.map.xy_idx(build_data.width - 5, wall_gap_y);
build_data.map.tiles[exit_idx] = TileType::DownStairs; build_data.map.tiles[exit_idx] = TileType::DownStairs;
// Sort buildings by size let building_size = self.sort_buildings(&buildings);
let mut building_size: Vec<(usize, i32)> = Vec::new(); self.building_factory(rng, build_data, &buildings, &building_size);
for (i, building) in buildings.iter().enumerate() {
building_size.push((i, building.2 * building.3));
}
building_size.sort_by(|a, b| b.1.cmp(&a.1));
// Start in the pub
let the_pub = &buildings[building_size[0].0];
build_data.starting_position = Some(Position {
x: the_pub.0 + (the_pub.2 / 2),
y: the_pub.1 + (the_pub.3 / 2),
})
} }
fn grass_layer(&mut self, build_data: &mut BuilderMap) { fn grass_layer(&mut self, build_data: &mut BuilderMap) {
@ -299,4 +300,88 @@ impl TownBuilder {
build_data.take_snapshot(); build_data.take_snapshot();
} }
} }
fn sort_buildings(
&mut self,
buildings: &[(i32, i32, i32, i32)],
) -> Vec<(usize, i32, BuildingTag)> {
// Sort buildings by size
let mut building_size: Vec<(usize, i32, BuildingTag)> = Vec::new();
for (i, building) in buildings.iter().enumerate() {
building_size.push((i, building.2 * building.3, BuildingTag::Unassigned));
}
building_size.sort_by(|a, b| b.1.cmp(&a.1));
building_size[0].2 = BuildingTag::Pub;
building_size[1].2 = BuildingTag::Temple;
building_size[2].2 = BuildingTag::Blacksmith;
building_size[3].2 = BuildingTag::Clothier;
building_size[4].2 = BuildingTag::Alchemist;
building_size[5].2 = BuildingTag::PlayerHouse;
for b in building_size.iter_mut().skip(6) {
b.2 = BuildingTag::Hovel;
}
let last_index = building_size.len() - 1;
building_size[last_index].2 = BuildingTag::Abandoned;
building_size
}
fn building_factory(
&mut self,
rng: &mut RandomNumberGenerator,
build_data: &mut BuilderMap,
buildings: &[(i32, i32, i32, i32)],
building_index: &[(usize, i32, BuildingTag)],
) {
for (i, building) in buildings.iter().enumerate() {
let build_type = &building_index[i].2;
match build_type {
BuildingTag::Pub => self.build_pub(building, build_data, rng),
_ => {}
}
}
}
fn build_pub(
&mut self,
building: &(i32, i32, i32, i32),
build_data: &mut BuilderMap,
rng: &mut RandomNumberGenerator,
) {
// Place the player
build_data.starting_position = Some(Position {
x: building.0 + (building.2 / 2),
y: building.1 + (building.3 / 2),
});
let player_idx = build_data
.map
.xy_idx(building.0 + (building.2 / 2), building.1 + (building.3 / 2));
// Place other items
let mut to_place: Vec<&str> = vec![
"Barkeep",
"Shady Salesman",
"Patron",
"Patron",
"Table",
"Chair",
"Table",
"Chair",
];
for y in building.1..building.1 + building.3 {
for x in building.0..building.0 + building.2 {
let idx = build_data.map.xy_idx(x, y);
if build_data.map.tiles[idx] == TileType::WoodFloor
&& idx != player_idx
&& rng.roll_dice(1, 3) == 1
&& !to_place.is_empty()
{
let entity_tag = to_place[0];
to_place.remove(0);
build_data.spawn_list.push((idx, entity_tag.to_string()));
}
}
}
}
} }

View File

@ -9,6 +9,7 @@ pub struct Mob {
pub blocks_tile: bool, pub blocks_tile: bool,
pub stats: MobStats, pub stats: MobStats,
pub vision_range: i32, pub vision_range: i32,
pub ai: String,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]

View File

@ -212,7 +212,12 @@ pub fn spawn_named_mob(
eb = eb.with(Name::from(&mob_template.name)); eb = eb.with(Name::from(&mob_template.name));
eb = eb.with(Monster {}); match mob_template.ai.as_ref() {
"melee" => eb = eb.with(Monster {}),
"bystander" => eb = eb.with(Bystander {}),
_ => {}
};
if mob_template.blocks_tile { if mob_template.blocks_tile {
eb = eb.with(BlocksTile {}); eb = eb.with(BlocksTile {});
} }

View File

@ -89,6 +89,7 @@ pub fn save_game(ecs: &mut World) {
SingleActivation, SingleActivation,
BlocksVisibility, BlocksVisibility,
Door, Door,
Bystander,
); );
} }
@ -180,6 +181,7 @@ pub fn load_game(ecs: &mut World) {
SingleActivation, SingleActivation,
BlocksVisibility, BlocksVisibility,
Door, Door,
Bystander,
); );
} }