Add attributes to Player and NPCs

This commit is contained in:
Timothy Warren 2022-01-03 15:21:12 -05:00
parent 3c36ee7fd3
commit 5a4d8bc234
8 changed files with 117 additions and 126 deletions

View File

@ -258,14 +258,14 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "vendor" "ai": "vendor",
"attributes": {
"intelligence": 13
},
"skills": {
"Melee": 2
}
}, },
{ {
"name": "Shady Salesman", "name": "Shady Salesman",
@ -276,14 +276,9 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "vendor" "ai": "vendor",
"attributes": {}
}, },
{ {
"name": "Patron", "name": "Patron",
@ -294,19 +289,14 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander", "ai": "bystander",
"quips": [ "quips": [
"Quiet down, it's too early!", "Quiet down, it's too early!",
"Oh my, I drank too much.", "Oh my, I drank too much.",
"Still saving the world, eh?" "Still saving the world, eh?"
] ],
"attributes": {}
}, },
{ {
"name": "Priest", "name": "Priest",
@ -317,14 +307,9 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander" "ai": "bystander",
"attributes": {}
}, },
{ {
"name": "Parishioner", "name": "Parishioner",
@ -335,19 +320,14 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander", "ai": "bystander",
"quips": [ "quips": [
"Great to see a new face here!", "Great to see a new face here!",
"I hear there's going to be a good sermon on tea", "I hear there's going to be a good sermon on tea",
"Want some cake?" "Want some cake?"
] ],
"attributes": {}
}, },
{ {
"name": "Blacksmith", "name": "Blacksmith",
@ -358,14 +338,9 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "vendor" "ai": "vendor",
"attributes": {}
}, },
{ {
"name": "Clothier", "name": "Clothier",
@ -376,14 +351,9 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "vendor" "ai": "vendor",
"attributes": {}
}, },
{ {
"name": "Alchemist", "name": "Alchemist",
@ -394,14 +364,9 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "vendor" "ai": "vendor",
"attributes": {}
}, },
{ {
"name": "Mom", "name": "Mom",
@ -412,12 +377,6 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander", "ai": "bystander",
"quips": [ "quips": [
@ -425,7 +384,8 @@
"Off saving the world again?", "Off saving the world again?",
"Be careful in the dungeon!", "Be careful in the dungeon!",
"Your father would be so proud, were he here." "Your father would be so proud, were he here."
] ],
"attributes": {}
}, },
{ {
"name": "Peasant", "name": "Peasant",
@ -436,17 +396,12 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander", "ai": "bystander",
"quips": [ "quips": [
"Why are you in my house?" "Why are you in my house?"
] ],
"attributes": {}
}, },
{ {
"name": "Dock Worker", "name": "Dock Worker",
@ -457,19 +412,14 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander", "ai": "bystander",
"quips": [ "quips": [
"Lovely day, eh?", "Lovely day, eh?",
"Nice weather", "Nice weather",
"Hello" "Hello"
] ],
"attributes": {}
}, },
{ {
"name": "Fisher", "name": "Fisher",
@ -480,19 +430,14 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander", "ai": "bystander",
"quips": [ "quips": [
"They're biting today!", "They're biting today!",
"I caught something, but it wasn't a fish!", "I caught something, but it wasn't a fish!",
"Looks like rain" "Looks like rain"
] ],
"attributes": {}
}, },
{ {
"name": "Wannabe Pirate", "name": "Wannabe Pirate",
@ -503,19 +448,14 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander", "ai": "bystander",
"quips": [ "quips": [
"Arrr", "Arrr",
"Grog!", "Grog!",
"Booze!" "Booze!"
] ],
"attributes": {}
}, },
{ {
"name": "Drunk", "name": "Drunk",
@ -526,19 +466,14 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 4, "vision_range": 4,
"ai": "bystander", "ai": "bystander",
"quips": [ "quips": [
"Hic", "Hic",
"Need... more... booze!", "Need... more... booze!",
"Spare a copper?" "Spare a copper?"
] ],
"attributes": {}
}, },
{ {
"name": "Rat", "name": "Rat",
@ -549,14 +484,16 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 2,
"hp": 2,
"defense": 1,
"power": 3
},
"vision_range": 8, "vision_range": 8,
"ai": "melee" "ai": "melee",
"attributes": {
"Might": 3,
"Fitness": 3
},
"skills": {
"Melee": -1,
"Defense": -1
}
}, },
{ {
"name": "Orc", "name": "Orc",
@ -567,14 +504,9 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 16,
"hp": 16,
"defense": 1,
"power": 4
},
"vision_range": 8, "vision_range": 8,
"ai": "melee" "ai": "melee",
"attributes": {}
}, },
{ {
"name": "Goblin", "name": "Goblin",
@ -585,14 +517,9 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 8,
"hp": 8,
"defense": 1,
"power": 3
},
"vision_range": 8, "vision_range": 8,
"ai": "melee" "ai": "melee",
"attributes": {}
}, },
{ {
"name": "Kobold", "name": "Kobold",
@ -603,14 +530,9 @@
"order": 1 "order": 1
}, },
"blocks_tile": true, "blocks_tile": true,
"stats": {
"max_hp": 4,
"hp": 4,
"defense": 0,
"power": 2
},
"vision_range": 4, "vision_range": 4,
"ai": "melee" "ai": "melee",
"attributes": {}
} }
], ],
"props": [ "props": [

View File

@ -1,3 +1,4 @@
use crate::gamesystem::attr_bonus;
use ::rltk::{Point, RGB}; use ::rltk::{Point, RGB};
use ::serde::{Deserialize, Serialize}; use ::serde::{Deserialize, Serialize};
use ::specs::error::NoError; use ::specs::error::NoError;
@ -248,6 +249,31 @@ pub struct Quips {
pub available: Vec<String>, pub available: Vec<String>,
} }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Attribute {
pub base: i32,
pub modifiers: i32,
pub bonus: i32,
}
impl Attribute {
pub fn new(base: i32) -> Self {
Attribute {
base,
modifiers: 0,
bonus: attr_bonus(base),
}
}
}
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct Attributes {
pub might: Attribute,
pub fitness: Attribute,
pub quickness: Attribute,
pub intelligence: Attribute,
}
// 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.

3
src/gamesystem.rs Normal file
View File

@ -0,0 +1,3 @@
pub fn attr_bonus(value: i32) -> i32 {
(value - 10) / 2 // See: https://roll20.net/compendium/dnd5e/Ability%20Scores#content
}

View File

@ -3,6 +3,7 @@ pub mod camera;
mod components; mod components;
mod damage_system; mod damage_system;
mod game_log; mod game_log;
mod gamesystem;
mod gui; mod gui;
mod hunger_system; mod hunger_system;
mod inventory_system; mod inventory_system;
@ -541,6 +542,7 @@ fn main() -> ::rltk::BError {
Bystander, Bystander,
Vendor, Vendor,
Quips, Quips,
Attributes,
); );
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new()); gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());

View File

@ -11,6 +11,7 @@ pub struct Mob {
pub vision_range: i32, pub vision_range: i32,
pub ai: String, pub ai: String,
pub quips: Option<Vec<String>>, pub quips: Option<Vec<String>>,
pub attributes: MobAttributes,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
@ -20,3 +21,11 @@ pub struct MobStats {
pub power: i32, pub power: i32,
pub defense: i32, pub defense: i32,
} }
#[derive(Deserialize, Debug)]
pub struct MobAttributes {
pub might: Option<i32>,
pub fitness: Option<i32>,
pub quickness: Option<i32>,
pub intelligence: Option<i32>,
}

View File

@ -226,6 +226,27 @@ pub fn spawn_named_mob(
}); });
} }
let mut attr = Attributes {
might: Attribute::new(11),
fitness: Attribute::new(11),
quickness: Attribute::new(11),
intelligence: Attribute::new(11),
};
if let Some(might) = mob_template.attributes.might {
attr.might = Attribute::new(might);
}
if let Some(fitness) = mob_template.attributes.fitness {
attr.fitness = Attribute::new(fitness);
}
if let Some(quickness) = mob_template.attributes.quickness {
attr.quickness = Attribute::new(quickness);
}
if let Some(intelligence) = mob_template.attributes.intelligence {
attr.intelligence = Attribute::new(intelligence);
}
eb = eb.with(attr);
if mob_template.blocks_tile { if mob_template.blocks_tile {
eb = eb.with(BlocksTile {}); eb = eb.with(BlocksTile {});
} }

View File

@ -92,6 +92,7 @@ pub fn save_game(ecs: &mut World) {
Bystander, Bystander,
Vendor, Vendor,
Quips, Quips,
Attributes,
); );
} }
@ -186,6 +187,7 @@ pub fn load_game(ecs: &mut World) {
Bystander, Bystander,
Vendor, Vendor,
Quips, Quips,
Attributes,
); );
} }

View File

@ -35,6 +35,12 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
state: HungerState::WellFed, state: HungerState::WellFed,
duration: 20, duration: 20,
}) })
.with(Attributes {
might: Attribute::new(11),
fitness: Attribute::new(11),
quickness: Attribute::new(11),
intelligence: Attribute::new(11),
})
.marked::<SimpleMarker<SerializeMe>>() .marked::<SimpleMarker<SerializeMe>>()
.build() .build()
} }