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

View File

@ -1,3 +1,4 @@
use crate::gamesystem::attr_bonus;
use ::rltk::{Point, RGB};
use ::serde::{Deserialize, Serialize};
use ::specs::error::NoError;
@ -248,6 +249,31 @@ pub struct Quips {
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
// 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 damage_system;
mod game_log;
mod gamesystem;
mod gui;
mod hunger_system;
mod inventory_system;
@ -541,6 +542,7 @@ fn main() -> ::rltk::BError {
Bystander,
Vendor,
Quips,
Attributes,
);
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());

View File

@ -11,6 +11,7 @@ pub struct Mob {
pub vision_range: i32,
pub ai: String,
pub quips: Option<Vec<String>>,
pub attributes: MobAttributes,
}
#[derive(Deserialize, Debug)]
@ -20,3 +21,11 @@ pub struct MobStats {
pub power: 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 {
eb = eb.with(BlocksTile {});
}

View File

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

View File

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