From d943bb4537baf7bcbd64706a6014eb655749c296 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 6 Jul 2020 20:51:23 +0100 Subject: [PATCH 01/10] Made pets regulate their speed --- common/src/sys/agent.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index ef5e4a49e5..01df0ffb62 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -191,9 +191,9 @@ impl<'a> System<'a> for Sys { if let (Some(tgt_pos), _tgt_stats) = (positions.get(*target), stats.get(*target)) { - let dist_sqrd = pos.0.distance_squared(tgt_pos.0); + let dist = pos.0.distance(tgt_pos.0); // Follow, or return to idle - if dist_sqrd > AVG_FOLLOW_DIST.powf(2.0) { + if dist > AVG_FOLLOW_DIST { if let Some((bearing, speed)) = chaser.chase( &*terrain, pos.0, @@ -204,7 +204,7 @@ impl<'a> System<'a> for Sys { ) { inputs.move_dir = bearing.xy().try_normalized().unwrap_or(Vec2::zero()) - * speed; + * speed.min(0.2 + (dist - AVG_FOLLOW_DIST) / 8.0); inputs.jump.set_state(bearing.z > 1.5); } } else { From 64dc339f13e43014550eb163946acbb3606c1789 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 6 Jul 2020 20:51:57 +0100 Subject: [PATCH 02/10] Reduced acceleration in air --- common/src/states/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 597eaaf5a8..8fcf278448 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -11,7 +11,7 @@ use crate::{ use vek::vec::Vec2; pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0; -const BASE_HUMANOID_AIR_ACCEL: f32 = 15.0; +const BASE_HUMANOID_AIR_ACCEL: f32 = 8.0; const BASE_HUMANOID_WATER_ACCEL: f32 = 150.0; const BASE_HUMANOID_WATER_SPEED: f32 = 180.0; // const BASE_HUMANOID_CLIMB_ACCEL: f32 = 10.0; From 55852f9bc7a608cfd2a06662051724518c9c0f20 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 6 Jul 2020 21:02:16 +0100 Subject: [PATCH 03/10] Made fireballs brighter, animals slightly more effective at combat --- common/src/comp/inventory/item/tool.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index 5746370145..5ad3221484 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -350,7 +350,7 @@ impl Tool { }, projectile_body: Body::Object(object::Body::BoltFire), projectile_light: Some(LightEmitter { - col: (0.72, 0.11, 0.11).into(), + col: (1.0, 0.8, 0.11).into(), ..Default::default() }), @@ -375,7 +375,7 @@ impl Tool { }, projectile_body: Body::Object(object::Body::BoltFireBig), projectile_light: Some(LightEmitter { - col: (0.72, 0.11, 0.11).into(), + col: (1.0, 0.8, 0.11).into(), ..Default::default() }), @@ -448,9 +448,9 @@ impl Tool { energy_cost: 0, buildup_duration: Duration::from_millis(0), recover_duration: Duration::from_millis(1000), - base_healthchange: -2, - range: 3.5, - max_angle: 45.0, + base_healthchange: -3, + range: 5.0, + max_angle: 60.0, }], } } From 99a526f702950c1a4fab0f8a314d3756c1d203b1 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 6 Jul 2020 21:18:30 +0100 Subject: [PATCH 04/10] Made pets healable --- common/src/comp/agent.rs | 10 ++++++++++ common/src/sys/combat.rs | 12 ++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index c9679e6b02..2ae77e6ce3 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -40,6 +40,16 @@ impl Alignment { _ => false, } } + + // TODO: Remove this hack + pub fn is_friendly_to_players(&self) -> bool { + match self { + Alignment::Npc + | Alignment::Tame + | Alignment::Owned(_) => true, + _ => false, + } + } } impl Component for Alignment { diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs index 910c87e5f5..9c6043ec02 100644 --- a/common/src/sys/combat.rs +++ b/common/src/sys/combat.rs @@ -1,6 +1,6 @@ use crate::{ comp::{ - Agent, Attacking, Body, CharacterState, HealthChange, HealthSource, Ori, Pos, Scale, Stats, + Alignment, Attacking, Body, CharacterState, HealthChange, HealthSource, Ori, Pos, Scale, Stats, }, event::{EventBus, LocalEvent, ServerEvent}, sync::Uid, @@ -25,7 +25,7 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Pos>, ReadStorage<'a, Ori>, ReadStorage<'a, Scale>, - ReadStorage<'a, Agent>, + ReadStorage<'a, Alignment>, ReadStorage<'a, Body>, ReadStorage<'a, Stats>, WriteStorage<'a, Attacking>, @@ -42,7 +42,7 @@ impl<'a> System<'a> for Sys { positions, orientations, scales, - agents, + alignments, bodies, stats, mut attacking_storage, @@ -74,7 +74,7 @@ impl<'a> System<'a> for Sys { pos_b, ori_b, scale_b_maybe, - agent_b_maybe, + alignment_b_maybe, character_b, stats_b, body_b, @@ -84,7 +84,7 @@ impl<'a> System<'a> for Sys { &positions, &orientations, scales.maybe(), - agents.maybe(), + alignments.maybe(), character_states.maybe(), &stats, &bodies, @@ -120,7 +120,7 @@ impl<'a> System<'a> for Sys { // TODO: remove this when there is a better way to target healing // Don't heal npc's hp - if agent_b_maybe.is_some() && healthchange > 0.0 { + if alignment_b_maybe.map(|a| !a.is_friendly_to_players()).unwrap_or(true) && healthchange > 0.0 { healthchange = 0.0; } From 62b59de95a59cd7384b10f350b570c075d207cbc Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 6 Jul 2020 22:41:21 +0100 Subject: [PATCH 05/10] Fixed sprite select flickering --- assets/voxygen/shaders/include/srgb.glsl | 10 +++++++++- assets/voxygen/shaders/sprite-vert.glsl | 2 +- voxygen/src/session.rs | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/assets/voxygen/shaders/include/srgb.glsl b/assets/voxygen/shaders/include/srgb.glsl index 4eaf579e17..a56a97b384 100644 --- a/assets/voxygen/shaders/include/srgb.glsl +++ b/assets/voxygen/shaders/include/srgb.glsl @@ -5,4 +5,12 @@ vec3 srgb_to_linear(vec3 srgb) { vec3 lower = srgb/vec3(12.92); return mix(higher, lower, cutoff); -} \ No newline at end of file +} + +vec3 linear_to_srgb(vec3 linear) { + bvec3 cutoff = lessThan(linear, vec3(0.0031308)); + vec3 higher = vec3(1.055) * pow(linear, vec3(1.0 / 2.4)) - vec3(0.055); + vec3 lower = linear * vec3(12.92); + + return mix(higher, lower, cutoff); +} diff --git a/assets/voxygen/shaders/sprite-vert.glsl b/assets/voxygen/shaders/sprite-vert.glsl index f22018bef3..11de3a8b2f 100644 --- a/assets/voxygen/shaders/sprite-vert.glsl +++ b/assets/voxygen/shaders/sprite-vert.glsl @@ -50,7 +50,7 @@ void main() { // Select glowing if (select_pos.w > 0 && select_pos.xyz == floor(sprite_pos)) { - f_col *= 4.0; + f_col = f_col * 8.0; } f_light = 1.0; diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 32e8609d0e..c22d4e81f8 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -249,7 +249,7 @@ impl PlayState for SessionState { { ( Some((cam_pos + cam_dir * (cam_dist - 0.01)).map(|e| e.floor() as i32)), - Some((cam_pos + cam_dir * cam_dist).map(|e| e.floor() as i32)), + Some((cam_pos + cam_dir * (cam_dist + 0.01)).map(|e| e.floor() as i32)), ) }, _ => (None, None), From 30619771afa84509ec475d9be74edac1c95d5552 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 6 Jul 2020 23:04:13 +0100 Subject: [PATCH 06/10] Improved block picking --- assets/voxygen/shaders/sprite-vert.glsl | 2 +- assets/voxygen/shaders/terrain-frag.glsl | 12 ++++++++ voxygen/src/session.rs | 35 ++++++++---------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/assets/voxygen/shaders/sprite-vert.glsl b/assets/voxygen/shaders/sprite-vert.glsl index 11de3a8b2f..91cc75e6d2 100644 --- a/assets/voxygen/shaders/sprite-vert.glsl +++ b/assets/voxygen/shaders/sprite-vert.glsl @@ -50,7 +50,7 @@ void main() { // Select glowing if (select_pos.w > 0 && select_pos.xyz == floor(sprite_pos)) { - f_col = f_col * 8.0; + f_col *= 8.0; } f_light = 1.0; diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index edbd8833f8..037357d0af 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -21,6 +21,10 @@ out vec4 tgt_color; #include #include +float vmax(vec3 v) { + return max(v.x, max(v.y, v.z)); +} + void main() { // First 3 normals are negative, next 3 are positive vec3 normals[6] = vec3[](vec3(-1,0,0), vec3(1,0,0), vec3(0,-1,0), vec3(0,1,0), vec3(0,0,-1), vec3(0,0,1)); @@ -46,6 +50,14 @@ void main() { diffuse_light += point_light * ao; vec3 col = f_col + hash(vec4(floor(f_chunk_pos * 3.0 - f_norm * 0.5), 0)) * 0.02; // Small-scale noise + + // Select glowing + if (select_pos.w > 0 && select_pos.xyz == floor(f_pos - f_norm * 0.01)) { + if (vmax(abs(mod(f_pos - f_norm * 0.5, 1.0) - 0.5)) > 0.45) { + col *= 0.5; + } + } + vec3 surf_color = illuminate(srgb_to_linear(col), light, diffuse_light, ambient_light); float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x); diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index c22d4e81f8..d257c4ed6f 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -256,6 +256,13 @@ impl PlayState for SessionState { } }; + let can_build = self.client + .borrow() + .state() + .read_storage::() + .get(self.client.borrow().entity()) + .is_some(); + // Only highlight collectables self.scene.set_select_pos(select_pos.filter(|sp| { self.client @@ -263,7 +270,7 @@ impl PlayState for SessionState { .state() .terrain() .get(*sp) - .map(|b| b.is_collectible()) + .map(|b| b.is_collectible() || can_build) .unwrap_or(false) })); @@ -279,16 +286,9 @@ impl PlayState for SessionState { return PlayStateResult::Shutdown; }, Event::InputUpdate(GameInput::Primary, state) => { - // Check the existence of CanBuild component. If it's here, use LMB to - // break blocks, if not, use it to attack + // If we can build, use LMB to break blocks, if not, use it to attack let mut client = self.client.borrow_mut(); - if state - && client - .state() - .read_storage::() - .get(client.entity()) - .is_some() - { + if state && can_build { if let Some(select_pos) = select_pos { client.remove_block(select_pos); } @@ -302,13 +302,7 @@ impl PlayState for SessionState { let mut client = self.client.borrow_mut(); - if state - && client - .state() - .read_storage::() - .get(client.entity()) - .is_some() - { + if state && can_build { if let Some(build_pos) = build_pos { client.place_block(build_pos, self.selected_block); } @@ -319,12 +313,7 @@ impl PlayState for SessionState { Event::InputUpdate(GameInput::Roll, state) => { let client = self.client.borrow(); - if client - .state() - .read_storage::() - .get(client.entity()) - .is_some() - { + if can_build { if state { if let Some(block) = select_pos .and_then(|sp| client.state().terrain().get(sp).ok().copied()) From f77d2f06c6231aa725c8870255c9b7765f05b3ad Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 6 Jul 2020 23:37:44 +0100 Subject: [PATCH 07/10] Fixed staff RMB, bug in ranged weapon code --- common/src/comp/agent.rs | 4 +--- common/src/comp/inventory/item/tool.rs | 12 ++++++------ common/src/states/basic_ranged.rs | 8 +++++--- common/src/sys/combat.rs | 9 +++++++-- voxygen/src/session.rs | 3 ++- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 2ae77e6ce3..d1052d1af5 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -44,9 +44,7 @@ impl Alignment { // TODO: Remove this hack pub fn is_friendly_to_players(&self) -> bool { match self { - Alignment::Npc - | Alignment::Tame - | Alignment::Owned(_) => true, + Alignment::Npc | Alignment::Tame | Alignment::Owned(_) => true, _ => false, } } diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index 5ad3221484..443859c859 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -331,18 +331,18 @@ impl Tool { }, BasicRanged { energy_cost: 0, - holdable: true, + holdable: false, prepare_duration: Duration::from_millis(250), - recover_duration: Duration::from_millis(200), + recover_duration: Duration::from_millis(600), projectile: Projectile { hit_solid: vec![projectile::Effect::Vanish], hit_entity: vec![ projectile::Effect::Damage(HealthChange { // TODO: This should not be fixed (?) - amount: -2, + amount: -3, cause: HealthSource::Projectile { owner: None }, }), - projectile::Effect::RewardEnergy(100), + projectile::Effect::RewardEnergy(150), projectile::Effect::Vanish, ], time_left: Duration::from_secs(20), @@ -350,7 +350,7 @@ impl Tool { }, projectile_body: Body::Object(object::Body::BoltFire), projectile_light: Some(LightEmitter { - col: (1.0, 0.8, 0.11).into(), + col: (0.85, 0.5, 0.11).into(), ..Default::default() }), @@ -375,7 +375,7 @@ impl Tool { }, projectile_body: Body::Object(object::Body::BoltFireBig), projectile_light: Some(LightEmitter { - col: (1.0, 0.8, 0.11).into(), + col: (1.0, 0.75, 0.11).into(), ..Default::default() }), diff --git a/common/src/states/basic_ranged.rs b/common/src/states/basic_ranged.rs index 3652c40e1e..70da464d13 100644 --- a/common/src/states/basic_ranged.rs +++ b/common/src/states/basic_ranged.rs @@ -31,9 +31,11 @@ impl CharacterBehavior for Data { handle_move(data, &mut update, 0.3); handle_jump(data, &mut update); - if self.prepare_timer < self.prepare_duration - || self.holdable && !self.exhausted && data.inputs.holding_ability_key() - { + if !self.exhausted && if self.holdable { + data.inputs.holding_ability_key() || self.prepare_timer < self.prepare_duration + } else { + self.prepare_timer < self.prepare_duration + } { // Prepare (draw the bow) update.character = CharacterState::BasicRanged(Data { prepare_timer: self.prepare_timer + Duration::from_secs_f32(data.dt.0), diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs index 9c6043ec02..5e6f3dc879 100644 --- a/common/src/sys/combat.rs +++ b/common/src/sys/combat.rs @@ -1,6 +1,7 @@ use crate::{ comp::{ - Alignment, Attacking, Body, CharacterState, HealthChange, HealthSource, Ori, Pos, Scale, Stats, + Alignment, Attacking, Body, CharacterState, HealthChange, HealthSource, Ori, Pos, Scale, + Stats, }, event::{EventBus, LocalEvent, ServerEvent}, sync::Uid, @@ -120,7 +121,11 @@ impl<'a> System<'a> for Sys { // TODO: remove this when there is a better way to target healing // Don't heal npc's hp - if alignment_b_maybe.map(|a| !a.is_friendly_to_players()).unwrap_or(true) && healthchange > 0.0 { + if alignment_b_maybe + .map(|a| !a.is_friendly_to_players()) + .unwrap_or(true) + && healthchange > 0.0 + { healthchange = 0.0; } diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index d257c4ed6f..d03907e483 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -256,7 +256,8 @@ impl PlayState for SessionState { } }; - let can_build = self.client + let can_build = self + .client .borrow() .state() .read_storage::() From e626f6255f49dec39abc81e960dd747d391058bc Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 7 Jul 2020 01:01:39 +0100 Subject: [PATCH 08/10] Prevented pet damage --- common/src/comp/agent.rs | 10 +++--- common/src/lib.rs | 3 +- common/src/msg/ecs_packet.rs | 5 +++ common/src/state.rs | 2 +- common/src/states/basic_ranged.rs | 12 ++++--- common/src/states/utils.rs | 24 ++++++++++++-- common/src/sys/agent.rs | 48 ++++++++++++++++------------ common/src/sys/combat.rs | 13 +++++--- common/src/sys/projectile.rs | 15 ++++++++- server/src/cmd.rs | 5 +-- server/src/events/inventory_manip.rs | 6 ++-- server/src/state_ext.rs | 2 +- server/src/sys/sentinel.rs | 12 ++++++- voxygen/src/session.rs | 4 +-- 14 files changed, 111 insertions(+), 50 deletions(-) diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index d1052d1af5..8c87de7b6a 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -1,9 +1,9 @@ -use crate::path::Chaser; -use specs::{Component, Entity as EcsEntity}; +use crate::{path::Chaser, sync::Uid}; +use specs::{Component, Entity as EcsEntity, FlaggedStorage}; use specs_idvs::IdvStorage; use vek::*; -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum Alignment { /// Wild animals and gentle giants Wild, @@ -14,7 +14,7 @@ pub enum Alignment { /// Farm animals and pets of villagers Tame, /// Pets you've tamed with a collar - Owned(EcsEntity), + Owned(Uid), } impl Alignment { @@ -51,7 +51,7 @@ impl Alignment { } impl Component for Alignment { - type Storage = IdvStorage; + type Storage = FlaggedStorage>; } #[derive(Clone, Debug, Default)] diff --git a/common/src/lib.rs b/common/src/lib.rs index 92c913e50f..5bdead5efe 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -7,7 +7,8 @@ bool_to_option, label_break_value, trait_alias, - type_alias_impl_trait + type_alias_impl_trait, + option_zip, )] #[macro_use] extern crate serde_derive; diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index 204b927c19..08cd5f52ad 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -17,6 +17,7 @@ sum_type! { LightEmitter(comp::LightEmitter), Item(comp::Item), Scale(comp::Scale), + Alignment(comp::Alignment), MountState(comp::MountState), Mounting(comp::Mounting), Mass(comp::Mass), @@ -43,6 +44,7 @@ sum_type! { LightEmitter(PhantomData), Item(PhantomData), Scale(PhantomData), + Alignment(PhantomData), MountState(PhantomData), Mounting(PhantomData), Mass(PhantomData), @@ -69,6 +71,7 @@ impl sync::CompPacket for EcsCompPacket { EcsCompPacket::LightEmitter(comp) => sync::handle_insert(comp, entity, world), EcsCompPacket::Item(comp) => sync::handle_insert(comp, entity, world), EcsCompPacket::Scale(comp) => sync::handle_insert(comp, entity, world), + EcsCompPacket::Alignment(comp) => sync::handle_insert(comp, entity, world), EcsCompPacket::MountState(comp) => sync::handle_insert(comp, entity, world), EcsCompPacket::Mounting(comp) => sync::handle_insert(comp, entity, world), EcsCompPacket::Mass(comp) => sync::handle_insert(comp, entity, world), @@ -93,6 +96,7 @@ impl sync::CompPacket for EcsCompPacket { EcsCompPacket::LightEmitter(comp) => sync::handle_modify(comp, entity, world), EcsCompPacket::Item(comp) => sync::handle_modify(comp, entity, world), EcsCompPacket::Scale(comp) => sync::handle_modify(comp, entity, world), + EcsCompPacket::Alignment(comp) => sync::handle_modify(comp, entity, world), EcsCompPacket::MountState(comp) => sync::handle_modify(comp, entity, world), EcsCompPacket::Mounting(comp) => sync::handle_modify(comp, entity, world), EcsCompPacket::Mass(comp) => sync::handle_modify(comp, entity, world), @@ -119,6 +123,7 @@ impl sync::CompPacket for EcsCompPacket { }, EcsCompPhantom::Item(_) => sync::handle_remove::(entity, world), EcsCompPhantom::Scale(_) => sync::handle_remove::(entity, world), + EcsCompPhantom::Alignment(_) => sync::handle_remove::(entity, world), EcsCompPhantom::MountState(_) => sync::handle_remove::(entity, world), EcsCompPhantom::Mounting(_) => sync::handle_remove::(entity, world), EcsCompPhantom::Mass(_) => sync::handle_remove::(entity, world), diff --git a/common/src/state.rs b/common/src/state.rs index 99792738ef..d932b57ef7 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -123,6 +123,7 @@ impl State { ecs.register::(); ecs.register::(); ecs.register::(); + ecs.register::(); // Register components send from clients -> server ecs.register::(); @@ -146,7 +147,6 @@ impl State { ecs.register::>(); ecs.register::>(); ecs.register::(); - ecs.register::(); ecs.register::(); ecs.register::(); ecs.register::(); diff --git a/common/src/states/basic_ranged.rs b/common/src/states/basic_ranged.rs index 70da464d13..6596283491 100644 --- a/common/src/states/basic_ranged.rs +++ b/common/src/states/basic_ranged.rs @@ -31,11 +31,13 @@ impl CharacterBehavior for Data { handle_move(data, &mut update, 0.3); handle_jump(data, &mut update); - if !self.exhausted && if self.holdable { - data.inputs.holding_ability_key() || self.prepare_timer < self.prepare_duration - } else { - self.prepare_timer < self.prepare_duration - } { + if !self.exhausted + && if self.holdable { + data.inputs.holding_ability_key() || self.prepare_timer < self.prepare_duration + } else { + self.prepare_timer < self.prepare_duration + } + { // Prepare (draw the bow) update.character = CharacterState::BasicRanged(Data { prepare_timer: self.prepare_timer + Duration::from_secs_f32(data.dt.0), diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 8fcf278448..7ebec30dc4 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -45,6 +45,24 @@ impl Body { Body::QuadrupedLow(_) => 120.0, } } + + pub fn base_ori_rate(&self) -> f32 { + match self { + Body::Humanoid(_) => 20.0, + Body::QuadrupedSmall(_) => 15.0, + Body::QuadrupedMedium(_) => 10.0, + Body::BirdMedium(_) => 30.0, + Body::FishMedium(_) => 5.0, + Body::Dragon(_) => 5.0, + Body::BirdSmall(_) => 35.0, + Body::FishSmall(_) => 10.0, + Body::BipedLarge(_) => 12.0, + Body::Object(_) => 5.0, + Body::Golem(_) => 8.0, + Body::Critter(_) => 35.0, + Body::QuadrupedLow(_) => 12.0, + } + } } /// Handles updating `Components` to move player based on state of `JoinData` @@ -68,10 +86,10 @@ fn basic_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) { update.vel.0 = update.vel.0 + Vec2::broadcast(data.dt.0) * data.inputs.move_dir * accel * efficiency; - handle_orientation(data, update, 20.0); + handle_orientation(data, update, data.body.base_ori_rate()); } -pub fn handle_orientation(data: &JoinData, update: &mut StateUpdate, strength: f32) { +pub fn handle_orientation(data: &JoinData, update: &mut StateUpdate, rate: f32) { // Set direction based on move direction let ori_dir = if update.character.is_attack() || update.character.is_block() { data.inputs.look_dir.xy() @@ -82,7 +100,7 @@ pub fn handle_orientation(data: &JoinData, update: &mut StateUpdate, strength: f }; // Smooth orientation - update.ori.0 = Dir::slerp_to_vec3(update.ori.0, ori_dir.into(), strength * data.dt.0); + update.ori.0 = Dir::slerp_to_vec3(update.ori.0, ori_dir.into(), rate * data.dt.0); } /// Updates components to move player as if theyre swimming diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index 01df0ffb62..21da0ef13e 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -245,7 +245,11 @@ impl<'a> System<'a> for Sys { alignments .get(*target) .copied() - .unwrap_or(Alignment::Owned(*target)), + .unwrap_or(uids + .get(*target) + .copied() + .map(Alignment::Owned) + .unwrap_or(Alignment::Wild)), ) { if let Some(dir) = Dir::from_unnormalized(tgt_pos.0 - pos.0) { inputs.look_dir = dir; @@ -419,7 +423,10 @@ impl<'a> System<'a> for Sys { // Follow owner if we're too far, or if they're under attack if let Some(Alignment::Owned(owner)) = alignment.copied() { - if let Some(owner_pos) = positions.get(owner) { + (|| { + let owner = uid_allocator.retrieve_entity_internal(owner.id())?; + + let owner_pos = positions.get(owner)?; let dist_sqrd = pos.0.distance_squared(owner_pos.0); if dist_sqrd > MAX_FOLLOW_DIST.powf(2.0) && !agent.activity.is_follow() { agent.activity = Activity::Follow { @@ -429,28 +436,27 @@ impl<'a> System<'a> for Sys { } // Attack owner's attacker - if let Some(owner_stats) = stats.get(owner) { - if owner_stats.health.last_change.0 < 5.0 { - if let comp::HealthSource::Attack { by } = - owner_stats.health.last_change.1.cause - { - if !agent.activity.is_attack() { - if let Some(attacker) = - uid_allocator.retrieve_entity_internal(by.id()) - { - agent.activity = Activity::Attack { - target: attacker, - chaser: Chaser::default(), - time: time.0, - been_close: false, - powerup: 0.0, - }; - } - } + let owner_stats = stats.get(owner)?; + if owner_stats.health.last_change.0 < 5.0 { + if let comp::HealthSource::Attack { by } = + owner_stats.health.last_change.1.cause + { + if !agent.activity.is_attack() { + let attacker = uid_allocator.retrieve_entity_internal(by.id())?; + + agent.activity = Activity::Attack { + target: attacker, + chaser: Chaser::default(), + time: time.0, + been_close: false, + powerup: 0.0, + }; } } } - } + + Some(()) + })(); } debug_assert!(inputs.move_dir.map(|e| !e.is_nan()).reduce_and()); diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs index 5e6f3dc879..1882b5c390 100644 --- a/common/src/sys/combat.rs +++ b/common/src/sys/combat.rs @@ -119,12 +119,15 @@ impl<'a> System<'a> for Sys { // healthchange = (healthchange / 1.5).min(-1.0); //} - // TODO: remove this when there is a better way to target healing - // Don't heal npc's hp - if alignment_b_maybe + // TODO: remove this when there is a better way to deal with alignment + // Don't heal NPCs + if (healthchange > 0.0 && alignment_b_maybe .map(|a| !a.is_friendly_to_players()) - .unwrap_or(true) - && healthchange > 0.0 + .unwrap_or(true)) + // Don't hurt pets + || (healthchange < 0.0 && alignment_b_maybe + .map(|b| Alignment::Owned(*uid).passive_towards(*b)) + .unwrap_or(false)) { healthchange = 0.0; } diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index 7faf63b9a3..056806786c 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -1,6 +1,7 @@ use crate::{ comp::{ projectile, Energy, EnergySource, HealthSource, Ori, PhysicsState, Pos, Projectile, Vel, + Alignment, }, event::{EventBus, LocalEvent, ServerEvent}, state::DeltaTime, @@ -27,6 +28,7 @@ impl<'a> System<'a> for Sys { WriteStorage<'a, Ori>, WriteStorage<'a, Projectile>, WriteStorage<'a, Energy>, + ReadStorage<'a, Alignment>, ); fn run( @@ -43,6 +45,7 @@ impl<'a> System<'a> for Sys { mut orientations, mut projectiles, mut energies, + alignments, ): Self::SystemData, ) { let mut local_emitter = local_bus.emitter(); @@ -82,7 +85,17 @@ impl<'a> System<'a> for Sys { for effect in projectile.hit_entity.drain(..) { match effect { projectile::Effect::Damage(change) => { - if other != projectile.owner.unwrap() { + let owner_uid = projectile.owner.unwrap(); + // Hacky: remove this when groups get implemented + let passive = uid_allocator + .retrieve_entity_internal(other.into()) + .and_then(|other| + alignments + .get(other) + .map(|a| Alignment::Owned(owner_uid) + .passive_towards(*a))) + .unwrap_or(false); + if other != projectile.owner.unwrap() && !passive { server_emitter.emit(ServerEvent::Damage { uid: other, change }); } }, diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 70886e603a..f44c5743e1 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -507,7 +507,8 @@ fn handle_spawn( String ) { (Some(opt_align), Some(npc::NpcBody(id, mut body)), opt_amount, opt_ai) => { - if let Some(alignment) = parse_alignment(target, &opt_align) { + let uid = server.state.read_component_cloned(target).expect("Expected player to have a UID"); + if let Some(alignment) = parse_alignment(uid, &opt_align) { let amount = opt_amount .and_then(|a| a.parse().ok()) .filter(|x| *x > 0) @@ -715,7 +716,7 @@ fn handle_help( } } -fn parse_alignment(owner: EcsEntity, alignment: &str) -> Option { +fn parse_alignment(owner: Uid, alignment: &str) -> Option { match alignment { "wild" => Some(comp::Alignment::Wild), "enemy" => Some(comp::Alignment::Enemy), diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs index 0d6c37839d..7b9f5fc753 100644 --- a/server/src/events/inventory_manip.rs +++ b/server/src/events/inventory_manip.rs @@ -188,13 +188,15 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv let reinsert = if let Some(pos) = state.read_storage::().get(entity) { + let uid = state.read_component_cloned(entity) + .expect("Expected player to have a UID"); if ( &state.read_storage::(), &state.read_storage::(), ) .join() .filter(|(alignment, _)| { - alignment == &&comp::Alignment::Owned(entity) + alignment == &&comp::Alignment::Owned(uid) }) .count() >= 3 @@ -222,7 +224,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv } { let _ = state.ecs().write_storage().insert( tameable_entity, - comp::Alignment::Owned(entity), + comp::Alignment::Owned(uid), ); let _ = state .ecs() diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index 20a7baac5d..a9b300dea9 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -171,7 +171,7 @@ impl StateExt for State { }); self.write_component(entity, comp::Gravity(1.0)); self.write_component(entity, comp::CharacterState::default()); - self.write_component(entity, comp::Alignment::Owned(entity)); + self.write_component(entity, comp::Alignment::Owned(self.read_component_cloned(entity).unwrap())); // Set the character id for the player // TODO this results in a warning in the console: "Error modifying synced diff --git a/server/src/sys/sentinel.rs b/server/src/sys/sentinel.rs index bdbde3248b..7fc0f9a59a 100644 --- a/server/src/sys/sentinel.rs +++ b/server/src/sys/sentinel.rs @@ -2,7 +2,7 @@ use super::SysTimer; use common::{ comp::{ Body, CanBuild, CharacterState, Collider, Energy, Gravity, Item, LightEmitter, Loadout, - Mass, MountState, Mounting, Ori, Player, Pos, Scale, Stats, Sticky, Vel, + Mass, MountState, Mounting, Ori, Player, Pos, Scale, Stats, Sticky, Vel, Alignment, }, msg::EcsCompPacket, sync::{CompSyncPackage, EntityPackage, EntitySyncPackage, Uid, UpdateTracker, WorldSyncExt}, @@ -48,6 +48,7 @@ pub struct TrackedComps<'a> { pub scale: ReadStorage<'a, Scale>, pub mounting: ReadStorage<'a, Mounting>, pub mount_state: ReadStorage<'a, MountState>, + pub alignment: ReadStorage<'a, Alignment>, pub mass: ReadStorage<'a, Mass>, pub collider: ReadStorage<'a, Collider>, pub sticky: ReadStorage<'a, Sticky>, @@ -104,6 +105,10 @@ impl<'a> TrackedComps<'a> { .get(entity) .cloned() .map(|c| comps.push(c.into())); + self.alignment + .get(entity) + .cloned() + .map(|c| comps.push(c.into())); self.mass.get(entity).copied().map(|c| comps.push(c.into())); self.collider .get(entity) @@ -146,6 +151,7 @@ pub struct ReadTrackers<'a> { pub scale: ReadExpect<'a, UpdateTracker>, pub mounting: ReadExpect<'a, UpdateTracker>, pub mount_state: ReadExpect<'a, UpdateTracker>, + pub alignment: ReadExpect<'a, UpdateTracker>, pub mass: ReadExpect<'a, UpdateTracker>, pub collider: ReadExpect<'a, UpdateTracker>, pub sticky: ReadExpect<'a, UpdateTracker>, @@ -178,6 +184,7 @@ impl<'a> ReadTrackers<'a> { .with_component(&comps.uid, &*self.scale, &comps.scale, filter) .with_component(&comps.uid, &*self.mounting, &comps.mounting, filter) .with_component(&comps.uid, &*self.mount_state, &comps.mount_state, filter) + .with_component(&comps.uid, &*self.alignment, &comps.alignment, filter) .with_component(&comps.uid, &*self.mass, &comps.mass, filter) .with_component(&comps.uid, &*self.collider, &comps.collider, filter) .with_component(&comps.uid, &*self.sticky, &comps.sticky, filter) @@ -207,6 +214,7 @@ pub struct WriteTrackers<'a> { scale: WriteExpect<'a, UpdateTracker>, mounting: WriteExpect<'a, UpdateTracker>, mount_state: WriteExpect<'a, UpdateTracker>, + alignment: WriteExpect<'a, UpdateTracker>, mass: WriteExpect<'a, UpdateTracker>, collider: WriteExpect<'a, UpdateTracker>, sticky: WriteExpect<'a, UpdateTracker>, @@ -228,6 +236,7 @@ fn record_changes(comps: &TrackedComps, trackers: &mut WriteTrackers) { trackers.scale.record_changes(&comps.scale); trackers.mounting.record_changes(&comps.mounting); trackers.mount_state.record_changes(&comps.mount_state); + trackers.alignment.record_changes(&comps.alignment); trackers.mass.record_changes(&comps.mass); trackers.collider.record_changes(&comps.collider); trackers.sticky.record_changes(&comps.sticky); @@ -282,6 +291,7 @@ pub fn register_trackers(world: &mut World) { world.register_tracker::(); world.register_tracker::(); world.register_tracker::(); + world.register_tracker::(); world.register_tracker::(); world.register_tracker::(); world.register_tracker::(); diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index d03907e483..5592cad96d 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -57,9 +57,9 @@ impl SessionState { .set_fov_deg(global_state.settings.graphics.fov); let hud = Hud::new(global_state, &client.borrow()); { - let my_entity = client.borrow().entity(); + let mut client = client.borrow_mut(); + let my_entity = client.entity(); client - .borrow_mut() .state_mut() .ecs_mut() .insert(MyEntity(my_entity)); From d1cdb6ea5565f714151c45ec1e9b819f092318ab Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 7 Jul 2020 01:11:37 +0100 Subject: [PATCH 09/10] Updated changelog --- CHANGELOG.md | 6 ++++++ common/src/lib.rs | 2 +- common/src/sys/agent.rs | 10 ++++------ common/src/sys/projectile.rs | 12 ++++++------ server/src/cmd.rs | 5 ++++- server/src/events/inventory_manip.rs | 11 ++++++----- server/src/state_ext.rs | 5 ++++- server/src/sys/sentinel.rs | 4 ++-- voxygen/src/session.rs | 5 +---- 9 files changed, 34 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de98e44886..90d4ddc625 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Connection screen fails after 4 minutes if it can't connect to the server instead of 80 minutes - Rebuilt quadruped_medium animation and assets - Disabled destruction of most blocks by explosions +- Disable damage to pets +- Made pets healable +- Rebalanced fire staff +- Animals are more effective in combat +- Pathfinding is much smoother and pets are cleverer +- Animals run/turn at different speeds ### Removed diff --git a/common/src/lib.rs b/common/src/lib.rs index 5bdead5efe..5111e5a346 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -8,7 +8,7 @@ label_break_value, trait_alias, type_alias_impl_trait, - option_zip, + option_zip )] #[macro_use] extern crate serde_derive; diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index 21da0ef13e..cd2e1208c2 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -242,14 +242,12 @@ impl<'a> System<'a> for Sys { if let (Some(tgt_pos), Some(tgt_stats), tgt_alignment) = ( positions.get(*target), stats.get(*target), - alignments - .get(*target) - .copied() - .unwrap_or(uids - .get(*target) + alignments.get(*target).copied().unwrap_or( + uids.get(*target) .copied() .map(Alignment::Owned) - .unwrap_or(Alignment::Wild)), + .unwrap_or(Alignment::Wild), + ), ) { if let Some(dir) = Dir::from_unnormalized(tgt_pos.0 - pos.0) { inputs.look_dir = dir; diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index 056806786c..306b0bab10 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -1,7 +1,7 @@ use crate::{ comp::{ - projectile, Energy, EnergySource, HealthSource, Ori, PhysicsState, Pos, Projectile, Vel, - Alignment, + projectile, Alignment, Energy, EnergySource, HealthSource, Ori, PhysicsState, Pos, + Projectile, Vel, }, event::{EventBus, LocalEvent, ServerEvent}, state::DeltaTime, @@ -89,11 +89,11 @@ impl<'a> System<'a> for Sys { // Hacky: remove this when groups get implemented let passive = uid_allocator .retrieve_entity_internal(other.into()) - .and_then(|other| + .and_then(|other| { alignments - .get(other) - .map(|a| Alignment::Owned(owner_uid) - .passive_towards(*a))) + .get(other) + .map(|a| Alignment::Owned(owner_uid).passive_towards(*a)) + }) .unwrap_or(false); if other != projectile.owner.unwrap() && !passive { server_emitter.emit(ServerEvent::Damage { uid: other, change }); diff --git a/server/src/cmd.rs b/server/src/cmd.rs index f44c5743e1..8e7f3517e7 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -507,7 +507,10 @@ fn handle_spawn( String ) { (Some(opt_align), Some(npc::NpcBody(id, mut body)), opt_amount, opt_ai) => { - let uid = server.state.read_component_cloned(target).expect("Expected player to have a UID"); + let uid = server + .state + .read_component_cloned(target) + .expect("Expected player to have a UID"); if let Some(alignment) = parse_alignment(uid, &opt_align) { let amount = opt_amount .and_then(|a| a.parse().ok()) diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs index 7b9f5fc753..b33a170e0b 100644 --- a/server/src/events/inventory_manip.rs +++ b/server/src/events/inventory_manip.rs @@ -188,7 +188,8 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv let reinsert = if let Some(pos) = state.read_storage::().get(entity) { - let uid = state.read_component_cloned(entity) + let uid = state + .read_component_cloned(entity) .expect("Expected player to have a UID"); if ( &state.read_storage::(), @@ -222,10 +223,10 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv .map(|(entity, _, _)| entity); nearest_tameable } { - let _ = state.ecs().write_storage().insert( - tameable_entity, - comp::Alignment::Owned(uid), - ); + let _ = state + .ecs() + .write_storage() + .insert(tameable_entity, comp::Alignment::Owned(uid)); let _ = state .ecs() .write_storage() diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index a9b300dea9..645e7843d4 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -171,7 +171,10 @@ impl StateExt for State { }); self.write_component(entity, comp::Gravity(1.0)); self.write_component(entity, comp::CharacterState::default()); - self.write_component(entity, comp::Alignment::Owned(self.read_component_cloned(entity).unwrap())); + self.write_component( + entity, + comp::Alignment::Owned(self.read_component_cloned(entity).unwrap()), + ); // Set the character id for the player // TODO this results in a warning in the console: "Error modifying synced diff --git a/server/src/sys/sentinel.rs b/server/src/sys/sentinel.rs index 7fc0f9a59a..55da254f51 100644 --- a/server/src/sys/sentinel.rs +++ b/server/src/sys/sentinel.rs @@ -1,8 +1,8 @@ use super::SysTimer; use common::{ comp::{ - Body, CanBuild, CharacterState, Collider, Energy, Gravity, Item, LightEmitter, Loadout, - Mass, MountState, Mounting, Ori, Player, Pos, Scale, Stats, Sticky, Vel, Alignment, + Alignment, Body, CanBuild, CharacterState, Collider, Energy, Gravity, Item, LightEmitter, + Loadout, Mass, MountState, Mounting, Ori, Player, Pos, Scale, Stats, Sticky, Vel, }, msg::EcsCompPacket, sync::{CompSyncPackage, EntityPackage, EntitySyncPackage, Uid, UpdateTracker, WorldSyncExt}, diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 5592cad96d..ea83cf918c 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -59,10 +59,7 @@ impl SessionState { { let mut client = client.borrow_mut(); let my_entity = client.entity(); - client - .state_mut() - .ecs_mut() - .insert(MyEntity(my_entity)); + client.state_mut().ecs_mut().insert(MyEntity(my_entity)); } let voxygen_i18n = load_expect::(&i18n_asset_key( &global_state.settings.language.selected_language, From 3cfd8bdd3cee7e14ed05604a77cdb545bd8468cb Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 7 Jul 2020 02:21:14 +0100 Subject: [PATCH 10/10] Fixed animal loadouts and /spawn --- common/src/comp/inventory/item/tool.rs | 2 +- common/src/loadout_builder.rs | 35 ++++++++++++++++++++++++ common/src/sys/agent.rs | 10 +++---- common/src/sys/combat.rs | 20 ++++++++------ server/src/cmd.rs | 3 +- server/src/sys/terrain.rs | 38 ++++---------------------- 6 files changed, 60 insertions(+), 48 deletions(-) diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index 443859c859..2f2dc32f81 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -448,7 +448,7 @@ impl Tool { energy_cost: 0, buildup_duration: Duration::from_millis(0), recover_duration: Duration::from_millis(1000), - base_healthchange: -3, + base_healthchange: -2, range: 5.0, max_angle: 60.0, }], diff --git a/common/src/loadout_builder.rs b/common/src/loadout_builder.rs index 76562e8d90..48df447299 100644 --- a/common/src/loadout_builder.rs +++ b/common/src/loadout_builder.rs @@ -5,6 +5,7 @@ use crate::{ CharacterAbility, ItemConfig, Loadout, }, }; +use std::time::Duration; /// Builder for character Loadouts, containing weapon and armour items belonging /// to a character, along with some helper methods for loading Items and @@ -61,6 +62,40 @@ impl LoadoutBuilder { ))) } + /// Default animal configuration + pub fn animal() -> Self { + Self(Loadout { + active_item: Some(ItemConfig { + item: assets::load_expect_cloned("common.items.weapons.empty"), + ability1: Some(CharacterAbility::BasicMelee { + energy_cost: 10, + buildup_duration: Duration::from_millis(600), + recover_duration: Duration::from_millis(100), + base_healthchange: -6, + range: 5.0, + max_angle: 80.0, + }), + ability2: None, + ability3: None, + block_ability: None, + dodge_ability: None, + }), + second_item: None, + shoulder: None, + chest: None, + belt: None, + hand: None, + pants: None, + foot: None, + back: None, + ring: None, + neck: None, + lantern: None, + head: None, + tabard: None, + }) + } + /// Get the default [ItemConfig](../comp/struct.ItemConfig.html) for a tool /// (weapon). This information is required for the `active` and `second` /// weapon items in a loadout. If some customisation to the item's diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index cd2e1208c2..5fcfd5d47a 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -118,7 +118,7 @@ impl<'a> System<'a> for Sys { const LISTEN_DIST: f32 = 16.0; const SEARCH_DIST: f32 = 48.0; const SIGHT_DIST: f32 = 128.0; - const MIN_ATTACK_DIST: f32 = 3.25; + const MIN_ATTACK_DIST: f32 = 3.5; let scale = scales.get(entity).map(|s| s.0).unwrap_or(1.0); @@ -266,10 +266,10 @@ impl<'a> System<'a> for Sys { let dist_sqrd = pos.0.distance_squared(tgt_pos.0); if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) { // Close-range attack - /*inputs.move_dir = Vec2::from(tgt_pos.0 - pos.0) - .try_normalized() - .unwrap_or(Vec2::unit_y()) - * 0.7;*/ + inputs.move_dir = Vec2::from(tgt_pos.0 - pos.0) + .try_normalized() + .unwrap_or(Vec2::unit_y()) + * 0.1; match tactic { Tactic::Melee | Tactic::Staff => inputs.primary.set_state(true), diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs index 1882b5c390..f0e84e65bb 100644 --- a/common/src/sys/combat.rs +++ b/common/src/sys/combat.rs @@ -111,6 +111,7 @@ impl<'a> System<'a> for Sys { { // Weapon gives base damage let mut healthchange = attack.base_healthchange as f32; + let mut knockback = attack.knockback; // TODO: remove this, either it will remain unused or be used as a temporary // gameplay balance @@ -130,6 +131,7 @@ impl<'a> System<'a> for Sys { .unwrap_or(false)) { healthchange = 0.0; + knockback = 0.0; } if rand::random() { @@ -143,14 +145,16 @@ impl<'a> System<'a> for Sys { healthchange *= 1.0 - BLOCK_EFFICIENCY } - server_emitter.emit(ServerEvent::Damage { - uid: *uid_b, - change: HealthChange { - amount: healthchange as i32, - cause: HealthSource::Attack { by: *uid }, - }, - }); - if attack.knockback != 0.0 { + if healthchange != 0.0 { + server_emitter.emit(ServerEvent::Damage { + uid: *uid_b, + change: HealthChange { + amount: healthchange as i32, + cause: HealthSource::Attack { by: *uid }, + }, + }); + } + if knockback != 0.0 { local_emitter.emit(LocalEvent::ApplyForce { entity: b, force: attack.knockback diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 8e7f3517e7..3f6bac7169 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -16,6 +16,7 @@ use common::{ terrain::TerrainChunkSize, util::Dir, vol::RectVolSize, + LoadoutBuilder, }; use rand::Rng; use specs::{Builder, Entity as EcsEntity, Join, WorldExt}; @@ -543,7 +544,7 @@ fn handle_spawn( .create_npc( pos, comp::Stats::new(get_npc_name(id).into(), body), - comp::Loadout::default(), + LoadoutBuilder::animal().build(), body, ) .with(comp::Vel(vel)) diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index 54d01b0596..5a3b9c6a36 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -9,6 +9,7 @@ use common::{ npc::NPC_NAMES, state::TerrainChanges, terrain::TerrainGrid, + LoadoutBuilder, }; use rand::Rng; use specs::{Join, Read, ReadStorage, System, Write, WriteExpect, WriteStorage}; @@ -136,9 +137,9 @@ impl<'a> System<'a> for Sys { energy_cost: 0, buildup_duration: Duration::from_millis(0), recover_duration: Duration::from_millis(400), - base_healthchange: -2, - range: 3.5, - max_angle: 60.0, + base_healthchange: -6, + range: 5.0, + max_angle: 80.0, }), ability2: None, ability3: None, @@ -214,36 +215,7 @@ impl<'a> System<'a> for Sys { head: None, tabard: None, }, - _ => comp::Loadout { - active_item: Some(comp::ItemConfig { - item: assets::load_expect_cloned("common.items.weapons.empty"), - ability1: Some(CharacterAbility::BasicMelee { - energy_cost: 10, - buildup_duration: Duration::from_millis(800), - recover_duration: Duration::from_millis(200), - base_healthchange: -2, - range: 3.5, - max_angle: 60.0, - }), - ability2: None, - ability3: None, - block_ability: None, - dodge_ability: None, - }), - second_item: None, - shoulder: None, - chest: None, - belt: None, - hand: None, - pants: None, - foot: None, - back: None, - ring: None, - neck: None, - lantern: None, - head: None, - tabard: None, - }, + _ => LoadoutBuilder::animal().build(), }; let mut scale = entity.scale;