From 447617dc69a178dc9ba41fd96dfd41d86ddc8322 Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sun, 15 Mar 2020 14:34:17 +0100 Subject: [PATCH] Make durations and damage depend on weapon type --- assets/common/items/weapons/hammer_1.ron | 4 -- assets/common/items/weapons/staff_1.ron | 4 -- assets/common/items/weapons/starter_axe.ron | 4 -- assets/common/items/weapons/starter_bow.ron | 4 -- .../common/items/weapons/starter_dagger.ron | 4 -- .../common/items/weapons/starter_hammer.ron | 4 -- assets/common/items/weapons/starter_sword.ron | 4 -- common/src/comp/ability.rs | 9 ++- common/src/comp/character_state.rs | 4 +- common/src/comp/inventory/item.rs | 60 ++++++++++--------- common/src/comp/stats.rs | 2 +- common/src/states/basic_attack.rs | 9 ++- common/src/states/equipping.rs | 2 +- common/src/states/idle.rs | 1 + common/src/states/timed_combo.rs | 25 ++++---- common/src/states/wielding.rs | 9 +-- common/src/sys/character_behavior.rs | 20 +++---- server/src/sys/terrain.rs | 10 +++- 18 files changed, 83 insertions(+), 96 deletions(-) diff --git a/assets/common/items/weapons/hammer_1.ron b/assets/common/items/weapons/hammer_1.ron index 13862f88c2..caeaf8ad28 100644 --- a/assets/common/items/weapons/hammer_1.ron +++ b/assets/common/items/weapons/hammer_1.ron @@ -5,10 +5,6 @@ Item( ToolData ( kind: Hammer, equip_time_millis: 1000, - attack_buildup_millis: 700, - attack_recover_millis: 100, - range: 3, - base_damage: 10, ) ) ) diff --git a/assets/common/items/weapons/staff_1.ron b/assets/common/items/weapons/staff_1.ron index cb1bc62358..f56cb59f42 100644 --- a/assets/common/items/weapons/staff_1.ron +++ b/assets/common/items/weapons/staff_1.ron @@ -5,10 +5,6 @@ Item( ToolData ( kind: Staff, equip_time_millis: 800, - attack_buildup_millis: 400, - attack_recover_millis: 300, - range: 3, - base_damage: 10, ) ), ) diff --git a/assets/common/items/weapons/starter_axe.ron b/assets/common/items/weapons/starter_axe.ron index 9145b4a09a..adbb486de2 100644 --- a/assets/common/items/weapons/starter_axe.ron +++ b/assets/common/items/weapons/starter_axe.ron @@ -5,10 +5,6 @@ Item( ToolData ( kind: Axe, equip_time_millis: 1000, - attack_buildup_millis: 700, - attack_recover_millis: 100, - range: 3, - base_damage: 10, ) ), ) diff --git a/assets/common/items/weapons/starter_bow.ron b/assets/common/items/weapons/starter_bow.ron index 724824581a..b265ef65da 100644 --- a/assets/common/items/weapons/starter_bow.ron +++ b/assets/common/items/weapons/starter_bow.ron @@ -5,10 +5,6 @@ Item( ToolData ( kind: Bow, equip_time_millis: 800, - attack_buildup_millis: 0, - attack_recover_millis: 800, - range: 3, - base_damage: 10, ) ), ) diff --git a/assets/common/items/weapons/starter_dagger.ron b/assets/common/items/weapons/starter_dagger.ron index 5d2c20c32e..bb50379b52 100644 --- a/assets/common/items/weapons/starter_dagger.ron +++ b/assets/common/items/weapons/starter_dagger.ron @@ -5,10 +5,6 @@ Item( ToolData ( kind: Dagger, equip_time_millis: 300, - attack_buildup_millis: 100, - attack_recover_millis: 400, - range: 3, - base_damage: 10, ) ), ) diff --git a/assets/common/items/weapons/starter_hammer.ron b/assets/common/items/weapons/starter_hammer.ron index be0b2505f8..1d3aa1a05a 100644 --- a/assets/common/items/weapons/starter_hammer.ron +++ b/assets/common/items/weapons/starter_hammer.ron @@ -5,10 +5,6 @@ Item( ToolData ( kind: Hammer, equip_time_millis: 1000, - attack_buildup_millis: 700, - attack_recover_millis: 100, - range: 3, - base_damage: 10, ) ), ) diff --git a/assets/common/items/weapons/starter_sword.ron b/assets/common/items/weapons/starter_sword.ron index 4f3f1b2506..ad3511c1e2 100644 --- a/assets/common/items/weapons/starter_sword.ron +++ b/assets/common/items/weapons/starter_sword.ron @@ -5,10 +5,6 @@ Item( ToolData ( kind: Sword(Rapier), equip_time_millis: 800, - attack_buildup_millis: 100, - attack_recover_millis: 500, - range: 3, - base_damage: 10, ) ), ) diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index d7508f36f7..b8d3abee5f 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -10,14 +10,15 @@ pub enum CharacterAbility { BasicAttack { buildup_duration: Duration, recover_duration: Duration, + base_damage: u32, }, BasicBlock, Roll, ChargeAttack, TimedCombo { - tool: ToolData, buildup_duration: Duration, recover_duration: Duration, + base_damage: u32, }, } @@ -47,10 +48,12 @@ impl From for CharacterState { CharacterAbility::BasicAttack { buildup_duration, recover_duration, + base_damage, } => CharacterState::BasicAttack(basic_attack::Data { exhausted: false, buildup_duration, recover_duration, + base_damage, }), CharacterAbility::BasicBlock { .. } => CharacterState::BasicBlock, CharacterAbility::Roll { .. } => CharacterState::Roll(roll::Data { @@ -62,16 +65,16 @@ impl From for CharacterState { }) }, CharacterAbility::TimedCombo { - tool, buildup_duration, recover_duration, + base_damage, } => CharacterState::TimedCombo(timed_combo::Data { - tool, buildup_duration, recover_duration, stage: 0, stage_exhausted: false, stage_time_active: Duration::default(), + base_damage, }), } } diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index bbc3242743..6c4ae39be9 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -29,7 +29,7 @@ pub enum CharacterState { /// Player is busy equipping or unequipping weapons Equipping(equipping::Data), /// Player is holding a weapon and can perform other actions - Wielding(wielding::Data), + Wielding, /// Player rushes forward and slams an enemy with their weapon ChargeAttack(charge_attack::Data), /// A dodge where player can roll @@ -47,7 +47,7 @@ pub enum CharacterState { impl CharacterState { pub fn is_wield(&self) -> bool { match self { - CharacterState::Wielding(_) + CharacterState::Wielding | CharacterState::BasicAttack(_) | CharacterState::TimedCombo(_) | CharacterState::BasicBlock => true, diff --git a/common/src/comp/inventory/item.rs b/common/src/comp/inventory/item.rs index 9f07d6a3b3..e420f100b5 100644 --- a/common/src/comp/inventory/item.rs +++ b/common/src/comp/inventory/item.rs @@ -37,41 +37,37 @@ impl ToolData { use ToolKind::*; match self.kind { - Sword(_) => vec![TimedCombo { - buildup_duration: Duration::from_millis(500), - recover_duration: Duration::from_millis(1000), - tool: *self, + Sword(_) => vec![BasicAttack { + buildup_duration: Duration::from_millis(100), + recover_duration: Duration::from_millis(500), + base_damage: 60, }], Axe => vec![BasicAttack { - buildup_duration: Duration::from_millis(1000), - recover_duration: Duration::from_millis(500), + buildup_duration: Duration::from_millis(700), + recover_duration: Duration::from_millis(100), + base_damage: 80, }], Hammer => vec![BasicAttack { - buildup_duration: Duration::from_millis(1000), - recover_duration: Duration::from_millis(500), - }], - Bow => vec![BasicAttack { - buildup_duration: Duration::from_millis(1000), - recover_duration: Duration::from_millis(500), + buildup_duration: Duration::from_millis(700), + recover_duration: Duration::from_millis(300), + base_damage: 100, }], + Bow => vec![], Dagger => vec![BasicAttack { - buildup_duration: Duration::from_millis(1000), - recover_duration: Duration::from_millis(500), + buildup_duration: Duration::from_millis(100), + recover_duration: Duration::from_millis(400), + base_damage: 50, }], Staff => vec![BasicAttack { - buildup_duration: Duration::from_millis(1000), - recover_duration: Duration::from_millis(500), - }], - Shield => vec![BasicAttack { - buildup_duration: Duration::from_millis(1000), - recover_duration: Duration::from_millis(500), + buildup_duration: Duration::from_millis(400), + recover_duration: Duration::from_millis(300), + base_damage: 70, }], + Shield => vec![], Debug(kind) => match kind { Boost => vec![], Possess => vec![], }, - - _ => vec![], } } } @@ -125,18 +121,24 @@ pub enum Ingredient { pub struct ToolData { pub kind: ToolKind, equip_time_millis: u64, - attack_buildup_millis: u64, - attack_recover_millis: u64, - range: u32, - pub base_damage: u32, + // TODO: item specific abilities } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum ItemKind { + /// Something wieldable Tool(ToolData), - Armor { kind: Armor, power: u32 }, - Consumable { kind: Consumable, effect: Effect }, - Utility { kind: Utility }, + Armor { + kind: Armor, + power: u32, + }, + Consumable { + kind: Consumable, + effect: Effect, + }, + Utility { + kind: Utility, + }, Ingredient(Ingredient), } diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs index d60e2d45dd..d7e4fe9ebd 100644 --- a/common/src/comp/stats.rs +++ b/common/src/comp/stats.rs @@ -134,7 +134,7 @@ impl Stats { } // TODO: Delete this once stat points will be a thing - pub fn update_max_hp(&mut self) { self.health.set_maximum(27 + 15 * self.level.amount); } + pub fn update_max_hp(&mut self) { self.health.set_maximum(200 + 47 * self.level.amount); } } impl Stats { diff --git a/common/src/states/basic_attack.rs b/common/src/states/basic_attack.rs index 64846659ba..b81fba8de1 100644 --- a/common/src/states/basic_attack.rs +++ b/common/src/states/basic_attack.rs @@ -11,6 +11,8 @@ pub struct Data { pub buildup_duration: Duration, /// How long the state has until exiting pub recover_duration: Duration, + /// Base damage + pub base_damage: u32, /// Whether the attack can deal more damage pub exhausted: bool, } @@ -37,6 +39,7 @@ impl CharacterBehavior for Data { .checked_sub(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(), recover_duration: self.recover_duration, + base_damage: self.base_damage, exhausted: false, }); } @@ -44,7 +47,7 @@ impl CharacterBehavior for Data { else if !self.exhausted { if let Some(tool) = unwrap_tool_data(data) { data.updater.insert(data.entity, Attacking { - base_damage: tool.base_damage, + base_damage: self.base_damage, applied: false, hit_count: 0, }); @@ -53,6 +56,7 @@ impl CharacterBehavior for Data { update.character = CharacterState::BasicAttack(Data { buildup_duration: self.buildup_duration, recover_duration: self.recover_duration, + base_damage: self.base_damage, exhausted: true, }); } @@ -64,13 +68,14 @@ impl CharacterBehavior for Data { .recover_duration .checked_sub(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(), + base_damage: self.base_damage, exhausted: true, }); } // Done else { if let Some(tool) = unwrap_tool_data(data) { - update.character = CharacterState::Wielding(wielding::Data { tool }); + update.character = CharacterState::Wielding; // Make sure attack component is removed data.updater.remove::(data.entity); } else { diff --git a/common/src/states/equipping.rs b/common/src/states/equipping.rs index d79be81b34..cc4b8cba09 100644 --- a/common/src/states/equipping.rs +++ b/common/src/states/equipping.rs @@ -31,7 +31,7 @@ impl CharacterBehavior for Data { if self.time_left == Duration::default() { // Wield delay has expired - update.character = CharacterState::Wielding(wielding::Data { tool: self.tool }); + update.character = CharacterState::Wielding; } else { // Wield delay hasn't expired yet // Update wield delay diff --git a/common/src/states/idle.rs b/common/src/states/idle.rs index 282d465b54..7d78d9b73f 100644 --- a/common/src/states/idle.rs +++ b/common/src/states/idle.rs @@ -18,6 +18,7 @@ impl CharacterBehavior for Data { local_events: VecDeque::new(), server_events: VecDeque::new(), }; + handle_move(data, &mut update); handle_jump(data, &mut update); handle_wield(data, &mut update); diff --git a/common/src/states/timed_combo.rs b/common/src/states/timed_combo.rs index 4467ce7173..9ee4ebe613 100644 --- a/common/src/states/timed_combo.rs +++ b/common/src/states/timed_combo.rs @@ -1,6 +1,5 @@ use crate::{ - comp::{Attacking, CharacterState, EnergySource, StateUpdate, ToolData}, - states::wielding, + comp::{Attacking, CharacterState, EnergySource, StateUpdate}, sys::character_behavior::{CharacterBehavior, JoinData}, }; use std::{collections::VecDeque, time::Duration}; @@ -16,8 +15,8 @@ pub struct Data { pub recover_duration: Duration, /// Tracks how long current stage has been active pub stage_time_active: Duration, - /// `ToolData` to be sent to `Attacking` component - pub tool: ToolData, + /// Base damage + pub base_damage: u32, } impl CharacterBehavior for Data { @@ -44,17 +43,17 @@ impl CharacterBehavior for Data { if data.inputs.primary.is_just_pressed() { println!("Failed"); // They failed, go back to `Wielding` - update.character = CharacterState::Wielding(wielding::Data { tool: self.tool }); + update.character = CharacterState::Wielding; } // Keep updating else { update.character = CharacterState::TimedCombo(Data { - tool: self.tool, stage: self.stage, buildup_duration: self.buildup_duration, recover_duration: self.recover_duration, stage_exhausted: false, stage_time_active: new_stage_time_active, + base_damage: self.base_damage, }); } } @@ -62,18 +61,18 @@ impl CharacterBehavior for Data { else if !self.stage_exhausted { // Swing hits data.updater.insert(data.entity, Attacking { - base_damage: self.tool.base_damage, + base_damage: self.base_damage, applied: false, hit_count: 0, }); update.character = CharacterState::TimedCombo(Data { - tool: self.tool, stage: self.stage, buildup_duration: self.buildup_duration, recover_duration: self.recover_duration, stage_exhausted: true, stage_time_active: new_stage_time_active, + base_damage: self.base_damage, }); } // Swing recovery window @@ -87,12 +86,12 @@ impl CharacterBehavior for Data { if data.inputs.primary.is_just_pressed() { println!("Transition"); update.character = CharacterState::TimedCombo(Data { - tool: self.tool, stage: self.stage + 1, buildup_duration: self.buildup_duration, recover_duration: self.recover_duration, stage_exhausted: true, stage_time_active: Duration::default(), + base_damage: self.base_damage, }); } // Player didn't click this frame @@ -100,19 +99,19 @@ impl CharacterBehavior for Data { // Update state println!("Missed"); update.character = CharacterState::TimedCombo(Data { - tool: self.tool, stage: self.stage, buildup_duration: self.buildup_duration, recover_duration: self.recover_duration, stage_exhausted: true, stage_time_active: new_stage_time_active, + base_damage: self.base_damage, }); } } // Stage expired but missed transition to next stage else { // Back to `Wielding` - update.character = CharacterState::Wielding(wielding::Data { tool: self.tool }); + update.character = CharacterState::Wielding; // Make sure attack component is removed data.updater.remove::(data.entity); } @@ -121,12 +120,12 @@ impl CharacterBehavior for Data { else { println!("Success!"); // Back to `Wielding` - update.character = CharacterState::Wielding(wielding::Data { tool: self.tool }); + update.character = CharacterState::Wielding; // Make sure attack component is removed data.updater.remove::(data.entity); } - // Subtract energy on successful hit + // Grant energy on successful hit if let Some(attack) = data.attacking { if attack.applied && attack.hit_count > 0 { println!("Hit"); diff --git a/common/src/states/wielding.rs b/common/src/states/wielding.rs index 27e60d9be7..6d2aaa491a 100644 --- a/common/src/states/wielding.rs +++ b/common/src/states/wielding.rs @@ -1,14 +1,11 @@ use super::utils::*; use crate::{ - comp::{StateUpdate, ToolData}, + comp::StateUpdate, sys::character_behavior::{CharacterBehavior, JoinData}, }; use std::collections::VecDeque; -#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] -pub struct Data { - /// The weapon being wielded - pub tool: ToolData, -} + +pub struct Data; impl CharacterBehavior for Data { fn behavior(&self, data: &JoinData) -> StateUpdate { diff --git a/common/src/sys/character_behavior.rs b/common/src/sys/character_behavior.rs index 2309e7a579..1217a98147 100644 --- a/common/src/sys/character_behavior.rs +++ b/common/src/sys/character_behavior.rs @@ -172,17 +172,17 @@ impl<'a> System<'a> for Sys { } let mut state_update = match j.character { - CharacterState::Idle => states::idle::Data::behavior(&states::idle::Data, &j), - CharacterState::Climb => states::climb::Data::behavior(&states::climb::Data, &j), - CharacterState::Glide => states::glide::Data::behavior(&states::glide::Data, &j), + CharacterState::Idle => states::idle::Data.behavior(&j), + CharacterState::Climb => states::climb::Data.behavior(&j), + CharacterState::Glide => states::glide::Data.behavior(&j), CharacterState::Sit => states::sit::Data::behavior(&states::sit::Data, &j), - CharacterState::BasicBlock => states::basic_block::Data::behavior(&states::basic_block::Data, &j), - CharacterState::Roll (data) => data.behavior(&j), - CharacterState::Wielding (data) => data.behavior(&j), - CharacterState::Equipping (data) => data.behavior(&j), - CharacterState::ChargeAttack (data) => data.behavior(&j), - CharacterState::TripleStrike (data) => data.behavior(&j), - CharacterState::BasicAttack (data) => data.behavior(&j), + CharacterState::BasicBlock => states::basic_block::Data.behavior(&j), + CharacterState::Roll(data) => data.behavior(&j), + CharacterState::Wielding => states::wielding::Data.behavior(&j), + CharacterState::Equipping(data) => data.behavior(&j), + CharacterState::ChargeAttack(data) => data.behavior(&j), + CharacterState::TripleStrike(data) => data.behavior(&j), + CharacterState::BasicAttack(data) => data.behavior(&j), CharacterState::TimedCombo(data) => data.behavior(&j), // Do not use default match. diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index f646795e9a..9bba2ee86c 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -215,7 +215,9 @@ impl<'a> System<'a> for Sys { loadout = comp::Loadout { active_item: Some(comp::ItemConfig { item: assets::load_expect_cloned("common.items.weapons.hammer_1"), - primary_ability: None, + primary_ability: None, /* TODO: when implementing this, make sure + * to adjust the base damage (see todo + * below) */ secondary_ability: None, block_ability: None, dodge_ability: None, @@ -228,14 +230,20 @@ impl<'a> System<'a> for Sys { } stats.update_max_hp(); + stats .health .set_to(stats.health.maximum(), comp::HealthSource::Revive); + + // TODO: This code sets an appropriate base_damage for the enemy. This doesn't + // work because the damage is now saved in an ability + /* if let Some(item::ItemKind::Tool(item::ToolData { base_damage, .. })) = &mut loadout.active_item.map(|i| i.item.kind) { *base_damage = stats.level.level() as u32 * 3; } + */ server_emitter.emit(ServerEvent::CreateNpc { pos: Pos(entity.pos), stats,