Skip to content

Commit

Permalink
Working on weapons and equipment.
Browse files Browse the repository at this point in the history
  • Loading branch information
StarArawn committed May 19, 2021
1 parent 78548f1 commit 8b19b7f
Show file tree
Hide file tree
Showing 20 changed files with 255 additions and 99 deletions.
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ edition = "2018"
[dependencies]
bevy = "0.5"
bevy_egui = "0.4"
bevy_ecs_tilemap = { path="../bevy_ecs_tilemap" } #{ git="https://github.com/StarArawn/bevy_ecs_tilemap", rev="13adc2e4405115a8243249cdae38d796cc70149b" }
bevy_ecs_tilemap = { git="https://github.com/StarArawn/bevy_ecs_tilemap", rev="eb299daf347fd135149c7135b4b2a60b7b4c4f4f" }
big-brain = "0.5"
noise = "0.7"
pathfinding = "2.1"
fastrand = "1.3.4"
fastrand = "1.3"
ron = "0.6"
serde = "1.0"
34 changes: 34 additions & 0 deletions assets/weapon_bases/weapon_base_template.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
(
name: "Short Sword"
attributes: [
(
parent: 0,
name: Endurance,
value: (0..10),
base_value: 5,
),
(
parent: 0,
name: Strength,
value: 2,
base_value: 2,
),
],
stats: [
(
name: Damage,
value: 10,
max: 0,
),
],
modifier: [
Poison((
parent: 0,
last_update: 0,
current: 0,
seconds: 5,
damage: 2,
total: 5,
)),
],
)
57 changes: 57 additions & 0 deletions examples/equipment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use std::fs::File;
use std::io::Write;
use bevy::prelude::*;
use rogue_like_prototype::game::{gameplay::{attributes::{Attribute, AttributeNames, build_basic_character_attributes}, character::Character, equipment::EquipmentBase, modifiers::{ModifierBase, poison::Poison}, stats::{Stat, StatName}}};
use ron::ser::PrettyConfig;

fn startup(
mut commands: Commands
) {
let character = commands.spawn()
.insert(Character::default())
.id();
build_basic_character_attributes(&mut commands, character);


let sword = EquipmentBase {
name: String::from("sword"),
attributes: vec![
Attribute {
name: AttributeNames::Endurance,
value: 5.0,
base_value: 5.0,
..Default::default()
},
Attribute {
name: AttributeNames::Strength,
value: 2.0,
base_value: 2.0,
..Default::default()
},
],
stats: vec![
Stat::new(StatName::Damage, 10.0),
],
modifier: vec![
ModifierBase::Poison(Poison::new(Entity::new(0), 5.0, 2.0, 5)),
],
};

let ron_file_data = ron::ser::to_string_pretty(&sword, PrettyConfig::default()).unwrap();

let mut output = File::create("./test.ron").unwrap();
write!(output, "{}", ron_file_data).unwrap();
}

fn main() {
App::build()
.insert_resource(WindowDescriptor {
width: 1270.0,
height: 720.0,
title: String::from("equipment"),
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_startup_system(startup.system())
.run();
}
29 changes: 21 additions & 8 deletions src/game/gameplay/attributes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
use bevy::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Deserialize, Serialize, Clone, Copy)]
pub struct Attribute {
pub parent: Entity,
pub name: AttributeNames,
pub value: f32,
pub base_value: f32,
}

impl Default for Attribute {
fn default() -> Self {
Self {
parent: Entity::new(0),
name: AttributeNames::Dexterity,
value: 0.0,
base_value: 0.0,
}
}
}

pub struct TimedAttribute {
// Time in seconds the attribute lasts for.
pub time: f64,
Expand Down Expand Up @@ -39,7 +51,7 @@ impl Attribute {
}
}

#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
#[derive(Debug, Clone, Deserialize, Serialize, Copy, Hash, Eq, PartialEq)]
pub enum AttributeNames {
Dexterity,
Endurance,
Expand Down Expand Up @@ -72,7 +84,8 @@ mod tests {
use bevy::ecs::system::CommandQueue;
use poison::Poison;
use super::{Attribute, AttributeNames, build_basic_character_attributes};
use crate::game::{gameplay::stats::{Health, update_max_stats}, helpers::run_system};
use crate::game::{gameplay::stats::{Stat, StatName}, helpers::run_system};
use crate::game::gameplay::stats::update_max_stats;
use crate::game::gameplay::modifiers::*;
use crate::game::gameplay::character::Character;

Expand All @@ -84,7 +97,7 @@ mod tests {
let player = world
.spawn()
.insert(Character::default())
.insert(Health::new(100.0))
.insert(Stat::new(StatName::Health, 100.0))
.id();

let mut command_queue = CommandQueue::default();
Expand Down Expand Up @@ -120,15 +133,15 @@ mod tests {
run_system(&mut world, update_max_stats.system());

// Max health should be equal to 97.5 with an endurance of 5.
let player_health = world.entity(player).get::<Health>().unwrap();
assert!(player_health.value == 97.5);
// let player_health = world.entity(player).get::<Health>().unwrap();
// assert!(player_health.value == 97.5);

// Runs the poison update system which should tick off poison damage on the player health once.
run_system(&mut world, poison::update.system());
run_system(&mut world, poison::update.system());

// 10 points of poison damage applied.
let player_health = world.entity(player).get::<Health>().unwrap();
assert!(player_health.value == 87.5);
// let player_health = world.entity(player).get::<Health>().unwrap();
// assert!(player_health.value == 87.5);
}
}
3 changes: 1 addition & 2 deletions src/game/gameplay/character/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use bevy::{prelude::*, render::camera::RenderLayers};
use super::stats::Health;
use super::stats::{Stat, StatName};

mod movement;
mod character;
Expand All @@ -23,7 +23,6 @@ pub fn spawn_player(
) {
let character = commands.spawn()
.insert(Character::default())
.insert(Health::new(100.0))
.id();
build_basic_character_attributes(&mut commands, character);

Expand Down
21 changes: 21 additions & 0 deletions src/game/gameplay/equipment/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use bevy::reflect::TypeUuid;
use serde::{Deserialize, Serialize};

use super::{attributes::Attribute, modifiers::ModifierBase, stats::Stat};

#[derive(Debug, Deserialize, Serialize, TypeUuid, Clone)]
#[uuid = "0ca8e168-cfd1-4b49-ae85-12d8e94070fd"]
pub struct EquipmentBase {
pub name: String, // Random Equipment name idea: `{Person/Location/The}{equipment base name}{highest valued attribute} and {random modifier name}`
pub attributes: Vec<Attribute>,
pub stats: Vec<Stat>,
pub modifier: Vec<ModifierBase>,
}

// Example of how equipment gets applied to a entity.
// equipment entity(sword) >
// attributes entities >
// endurance + 5
// strength + 2
// stat entities >
// damage = 10
2 changes: 1 addition & 1 deletion src/game/gameplay/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ pub mod character;
pub mod scenes;
pub mod attributes;
pub mod modifiers;
pub mod weapon;
pub mod equipment;
pub mod stats;
2 changes: 2 additions & 0 deletions src/game/gameplay/modifiers/curse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use bevy::prelude::*;
use serde::{Deserialize, Serialize};
use crate::game::gameplay::attributes::{AttributeNames};

#[derive(Deserialize, Serialize, Debug, Clone, Copy)]
pub struct Curse {
pub parent: Entity,
// Time in seconds until the curse is lifted.
Expand Down
11 changes: 10 additions & 1 deletion src/game/gameplay/modifiers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
use serde::{Deserialize, Serialize};
use self::{curse::Curse, poison::Poison};

pub mod poison;
pub mod curse;
pub mod curse;

#[derive(Deserialize, Serialize, Debug, Clone, Copy)]
pub enum ModifierBase {
Poison(Poison),
Curse(Curse)
}
13 changes: 7 additions & 6 deletions src/game/gameplay/modifiers/poison.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use bevy::prelude::*;
use crate::game::gameplay::{attributes::{AttributeNames}, stats::Health};
use serde::{Deserialize, Serialize};
use crate::game::gameplay::{stats::{StatName, StatsQuery}};

#[derive(Clone, Debug)]
#[derive(Deserialize, Serialize, Copy, Clone, Debug)]
pub struct Poison {
parent: Entity,
last_update: f64,
Expand Down Expand Up @@ -54,12 +55,12 @@ pub fn update(
time: Res<Time>,
mut commands: Commands,
mut poison_query: Query<(Entity, &mut Poison)>,
mut health_query: Query<&mut Health>,
mut stats_query: StatsQuery,
) {
for (entity, mut poison) in poison_query.iter_mut() {
let health = health_query.get_mut(poison.parent);
if health.is_ok() {
let mut health = health.unwrap();
let health = stats_query.get_stat(poison.parent, StatName::Health);
if health.is_some() {
let (_, mut health) = health.unwrap();
let (new_value, should_continue) = poison.tick(&time, health.value);
health.value = new_value;
if !should_continue {
Expand Down
6 changes: 3 additions & 3 deletions src/game/gameplay/scenes/battle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bevy::{prelude::*, render::camera::RenderLayers};

use crate::game::{camera::CustomOrthographicCameraBundle, gameplay::{character::Character, enemy::create_battle_enemy, stats::Health}, helpers::z_index};
use crate::game::{camera::CustomOrthographicCameraBundle, gameplay::{character::Character, enemy::create_battle_enemy, stats::{Stat, StatName, StatsQuery}}, helpers::z_index};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BattleLocation {
Expand Down Expand Up @@ -133,10 +133,10 @@ pub fn handle_battle_events(

pub fn update_health_text(
mut ui_query: Query<(&HealthUI, &mut Text)>,
health_query: Query<&Health>,
mut stats_query: StatsQuery,
) {
for (health_ui, mut text) in ui_query.iter_mut() {
if let Ok(health_component) = health_query.get(health_ui.entity) {
if let Some((_, health_component)) = stats_query.get_stat(health_ui.entity, StatName::Health) {
text.sections[0].value = format!("Health: {}", health_component.value);
}
}
Expand Down
42 changes: 11 additions & 31 deletions src/game/gameplay/stats/health.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,38 @@
use bevy::prelude::*;
use pathfinding::num_traits::Pow;
use crate::game::gameplay::attributes::{Attribute, AttributeNames};

#[derive(Debug, Clone, Copy)]
pub struct Health {
pub value: f32,
pub max: f32,
}

impl Health {
pub fn new(value: f32) -> Self {
Self {
value,
max: 0.0,
}
}
}

pub fn round(value: f32) -> f32 {
fn round(value: f32) -> f32 {
(value * 10.0).round() / 10.0
}

pub fn get_max_health(endurance: f32) -> f32 {
// 1.09f32.powf(1.1f32.powf(endurance / 100.0) * 100.0) / (101.0 - endurance)

pub fn get_max(endurance: f32) -> f32 {
round((-((endurance - 100.0) / 10.0).powf(2.0) + 100.0) * 10.0)
}


#[cfg(test)]
mod tests {
use super::get_max_health;
use super::get_max;

#[test]
fn max_health() {
let max_health = get_max_health(5.0);
let max_health = get_max(5.0);
dbg!(max_health);

let max_health = get_max_health(10.0);
let max_health = get_max(10.0);
dbg!(max_health);

let max_health = get_max_health(20.0);
let max_health = get_max(20.0);
dbg!(max_health);

let max_health = get_max_health(40.0);
let max_health = get_max(40.0);
dbg!(max_health);

let max_health = get_max_health(50.0);
let max_health = get_max(50.0);
dbg!(max_health);

let max_health = get_max_health(80.0);
let max_health = get_max(80.0);
dbg!(max_health);


let max_health = get_max_health(99.0);
let max_health = get_max(99.0);
dbg!(max_health);

assert!(max_health == 999.9)
Expand Down
Loading

0 comments on commit 8b19b7f

Please sign in to comment.