Balancing, make fireball not holdable, arrow knockback

This commit is contained in:
timokoesters 2020-03-26 22:52:44 +01:00
parent 8010e5afb4
commit 2b68adff51
9 changed files with 65 additions and 25 deletions

View File

@ -21,6 +21,7 @@ pub enum CharacterAbility {
},
BasicRanged {
energy_cost: u32,
holdable: bool,
prepare_duration: Duration,
recover_duration: Duration,
projectile: Projectile,
@ -60,7 +61,7 @@ impl CharacterAbility {
&& data.vel.0.xy().magnitude_squared() > 0.5
&& update
.energy
.try_change_by(-150, EnergySource::Ability)
.try_change_by(-220, EnergySource::Ability)
.is_ok()
},
CharacterAbility::DashMelee { .. } => update
@ -122,6 +123,7 @@ impl From<&CharacterAbility> for CharacterState {
max_angle: *max_angle,
}),
CharacterAbility::BasicRanged {
holdable,
prepare_duration,
recover_duration,
projectile,
@ -132,6 +134,7 @@ impl From<&CharacterAbility> for CharacterState {
} => CharacterState::BasicRanged(basic_ranged::Data {
exhausted: false,
prepare_timer: Duration::default(),
holdable: *holdable,
prepare_duration: *prepare_duration,
recover_duration: *recover_duration,
projectile: projectile.clone(),

View File

@ -73,7 +73,7 @@ impl ToolData {
Sword(_) => vec![TripleStrike { base_damage: 5 }, DashMelee {
buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500),
base_damage: 20,
base_damage: 10,
}],
Axe(_) => vec![BasicMelee {
energy_cost: 0,
@ -93,17 +93,19 @@ impl ToolData {
}],
Bow(_) => vec![BasicRanged {
energy_cost: 0,
holdable: true,
prepare_duration: Duration::from_millis(100),
recover_duration: Duration::from_millis(300),
recover_duration: Duration::from_millis(500),
projectile: Projectile {
hit_ground: vec![projectile::Effect::Stick],
hit_wall: vec![projectile::Effect::Stick],
hit_entity: vec![
projectile::Effect::Damage(HealthChange {
// TODO: This should not be fixed (?)
amount: -3,
amount: -5,
cause: HealthSource::Projectile { owner: None },
}),
projectile::Effect::Knockback(10.0),
projectile::Effect::Vanish,
],
time_left: Duration::from_secs(15),
@ -132,15 +134,16 @@ impl ToolData {
},
BasicRanged {
energy_cost: 0,
prepare_duration: Duration::from_millis(300),
recover_duration: Duration::from_millis(100),
holdable: false,
prepare_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(200),
projectile: Projectile {
hit_ground: vec![projectile::Effect::Vanish],
hit_wall: vec![projectile::Effect::Vanish],
hit_entity: vec![
projectile::Effect::Damage(HealthChange {
// TODO: This should not be fixed (?)
amount: -2,
amount: -1,
cause: HealthSource::Projectile { owner: None },
}),
projectile::Effect::Vanish,
@ -158,6 +161,7 @@ impl ToolData {
},
BasicRanged {
energy_cost: 400,
holdable: false,
prepare_duration: Duration::from_millis(800),
recover_duration: Duration::from_millis(300),
projectile: Projectile {
@ -217,7 +221,8 @@ impl ToolData {
],
Possess => vec![BasicRanged {
energy_cost: 0,
prepare_duration: Duration::from_millis(300),
holdable: false,
prepare_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(300),
projectile: Projectile {
hit_ground: vec![projectile::Effect::Stick],

View File

@ -6,6 +6,7 @@ use std::time::Duration;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Effect {
Damage(comp::HealthChange),
Knockback(f32),
Explode { power: f32 },
Vanish,
Stick,

View File

@ -8,6 +8,8 @@ use std::time::Duration;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Data {
/// Can you hold the abilty beyond the prepare duration
pub holdable: bool,
/// How long we have to prepare the weapon
pub prepare_duration: Duration,
/// How long we prepared the weapon already
@ -26,15 +28,16 @@ impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
handle_move(data, &mut update, 0.5);
handle_move(data, &mut update, 0.2);
handle_jump(data, &mut update);
if self.prepare_timer < self.prepare_duration
|| !self.exhausted && data.inputs.holding_ability_key()
|| self.holdable && !self.exhausted && data.inputs.holding_ability_key()
{
// Prepare (draw the bow)
update.character = CharacterState::BasicRanged(Data {
prepare_timer: self.prepare_timer + Duration::from_secs_f32(data.dt.0),
holdable: self.holdable,
prepare_duration: self.prepare_duration,
recover_duration: self.recover_duration,
projectile: self.projectile.clone(),
@ -58,6 +61,7 @@ impl CharacterBehavior for Data {
update.character = CharacterState::BasicRanged(Data {
prepare_timer: self.prepare_timer,
holdable: self.holdable,
prepare_duration: self.prepare_duration,
recover_duration: self.recover_duration,
projectile: self.projectile.clone(),
@ -70,6 +74,7 @@ impl CharacterBehavior for Data {
// Recovery
update.character = CharacterState::BasicRanged(Data {
prepare_timer: self.prepare_timer,
holdable: self.holdable,
prepare_duration: self.prepare_duration,
recover_duration: self
.recover_duration

View File

@ -4,10 +4,10 @@ use crate::{
sys::character_behavior::{CharacterBehavior, JoinData},
};
use std::time::Duration;
use vek::vec::{Vec2, Vec3};
use vek::vec::Vec3;
// In millis
const STAGE_DURATION: u64 = 500;
const STAGE_DURATION: u64 = 700;
const INITIAL_ACCEL: f32 = 90.0;
const BASE_SPEED: f32 = 25.0;

View File

@ -10,6 +10,7 @@ use vek::vec::Vec2;
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
const BASE_HUMANOID_ACCEL: f32 = 100.0;
const BASE_HUMANOID_SPEED: f32 = 150.0;
const NPC_HUMANOID_SPEED: f32 = 150.0;
const BASE_HUMANOID_AIR_ACCEL: f32 = 15.0;
const BASE_HUMANOID_AIR_SPEED: f32 = 8.0;
const BASE_HUMANOID_WATER_ACCEL: f32 = 70.0;
@ -39,7 +40,14 @@ pub fn handle_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
/// Updates components to move player as if theyre on ground or in air
fn basic_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
let (accel, speed): (f32, f32) = if data.physics.on_ground {
(BASE_HUMANOID_ACCEL, BASE_HUMANOID_SPEED)
(
BASE_HUMANOID_ACCEL,
if data.agent.is_some() {
NPC_HUMANOID_SPEED
} else {
BASE_HUMANOID_SPEED
},
)
} else {
(BASE_HUMANOID_AIR_ACCEL, BASE_HUMANOID_AIR_SPEED)
};

View File

@ -1,7 +1,7 @@
use crate::{
comp::{
Attacking, Body, CharacterState, ControlAction, Controller, ControllerInputs, Energy,
Loadout, Mounting, Ori, PhysicsState, Pos, StateUpdate, Stats, Vel,
Agent, Attacking, Body, CharacterState, ControlAction, Controller, ControllerInputs,
Energy, Loadout, Mounting, Ori, PhysicsState, Pos, StateUpdate, Stats, Vel,
},
event::{EventBus, LocalEvent, ServerEvent},
state::DeltaTime,
@ -46,6 +46,7 @@ pub struct JoinData<'a> {
pub body: &'a Body,
pub physics: &'a PhysicsState,
pub attacking: Option<&'a Attacking>,
pub agent: Option<&'a Agent>,
pub updater: &'a LazyUpdate,
}
@ -63,6 +64,7 @@ pub type JoinTuple<'a> = (
&'a Body,
&'a PhysicsState,
Option<&'a Attacking>,
Option<&'a Agent>,
);
fn incorporate_update(tuple: &mut JoinTuple, state_update: StateUpdate) {
@ -91,6 +93,7 @@ impl<'a> JoinData<'a> {
body: j.10,
physics: j.11,
attacking: j.12,
agent: j.13,
updater,
dt,
}
@ -121,6 +124,7 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Body>,
ReadStorage<'a, PhysicsState>,
ReadStorage<'a, Attacking>,
ReadStorage<'a, Agent>,
ReadStorage<'a, Uid>,
ReadStorage<'a, Mounting>,
);
@ -145,6 +149,7 @@ impl<'a> System<'a> for Sys {
bodies,
physics_states,
attacking_storage,
agent_storage,
uids,
mountings,
): Self::SystemData,
@ -166,6 +171,7 @@ impl<'a> System<'a> for Sys {
&bodies,
&physics_states,
attacking_storage.maybe(),
agent_storage.maybe(),
)
.join();

View File

@ -1,7 +1,6 @@
use crate::{
comp::{
Agent, Attacking, Body, CharacterState, Controller, HealthChange, HealthSource, Ori, Pos,
Scale, Stats,
Agent, Attacking, Body, CharacterState, HealthChange, HealthSource, Ori, Pos, Scale, Stats,
},
event::{EventBus, LocalEvent, ServerEvent},
sync::Uid,
@ -25,7 +24,6 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Ori>,
ReadStorage<'a, Scale>,
ReadStorage<'a, Agent>,
ReadStorage<'a, Controller>,
ReadStorage<'a, Body>,
ReadStorage<'a, Stats>,
WriteStorage<'a, Attacking>,
@ -43,7 +41,6 @@ impl<'a> System<'a> for Sys {
orientations,
scales,
agents,
controllers,
bodies,
stats,
mut attacking_storage,
@ -53,15 +50,12 @@ impl<'a> System<'a> for Sys {
let mut server_emitter = server_bus.emitter();
let mut local_emitter = local_bus.emitter();
// Attacks
for (entity, uid, pos, ori, scale_maybe, agent_maybe, _, _attacker_stats, attack) in (
for (entity, uid, pos, ori, scale_maybe, attack) in (
&entities,
&uids,
&positions,
&orientations,
scales.maybe(),
agents.maybe(),
&controllers,
&stats,
&mut attacking_storage,
)
.join()

View File

@ -1,10 +1,12 @@
use crate::{
comp::{projectile, HealthSource, Ori, PhysicsState, Pos, Projectile, Vel},
event::{EventBus, ServerEvent},
event::{EventBus, LocalEvent, ServerEvent},
state::DeltaTime,
sync::UidAllocator,
};
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
use specs::{saveload::MarkerAllocator, Entities, Join, Read, ReadStorage, System, WriteStorage};
use std::time::Duration;
use vek::*;
/// This system is responsible for handling projectile effect triggers
pub struct Sys;
@ -12,6 +14,8 @@ impl<'a> System<'a> for Sys {
type SystemData = (
Entities<'a>,
Read<'a, DeltaTime>,
Read<'a, UidAllocator>,
Read<'a, EventBus<LocalEvent>>,
Read<'a, EventBus<ServerEvent>>,
ReadStorage<'a, Pos>,
ReadStorage<'a, PhysicsState>,
@ -25,6 +29,8 @@ impl<'a> System<'a> for Sys {
(
entities,
dt,
uid_allocator,
local_bus,
server_bus,
positions,
physics_states,
@ -33,6 +39,7 @@ impl<'a> System<'a> for Sys {
mut projectiles,
): Self::SystemData,
) {
let mut local_emitter = local_bus.emitter();
let mut server_emitter = server_bus.emitter();
// Attacks
@ -90,6 +97,17 @@ impl<'a> System<'a> for Sys {
projectile::Effect::Damage(change) => {
server_emitter.emit(ServerEvent::Damage { uid: other, change })
},
projectile::Effect::Knockback(knockback) => {
if let Some(entity) =
uid_allocator.retrieve_entity_internal(other.into())
{
local_emitter.emit(LocalEvent::ApplyForce {
entity,
dir: Vec3::slerp(ori.0, Vec3::new(0.0, 0.0, 1.0), 0.5),
force: knockback,
});
}
},
projectile::Effect::Explode { power } => {
server_emitter.emit(ServerEvent::Explosion {
pos: pos.0,