diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 66edd98f7b..649e8934dc 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -100,9 +100,10 @@ impl Component for CharacterState { type Storage = FlaggedStorage>; } -#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Attacking { pub base_damage: u32, + pub max_angle: f32, pub applied: bool, pub hit_count: u32, } diff --git a/common/src/comp/inventory/item.rs b/common/src/comp/inventory/item.rs index 708b31a7b4..16961c3005 100644 --- a/common/src/comp/inventory/item.rs +++ b/common/src/comp/inventory/item.rs @@ -71,7 +71,7 @@ impl ToolData { hit_entity: vec![ projectile::Effect::Damage(HealthChange { // TODO: This should not be fixed (?) - amount: -30, + amount: -3, cause: HealthSource::Item, }), projectile::Effect::Vanish, @@ -104,7 +104,17 @@ impl ToolData { only_up: true, }, ], - Possess => vec![], + Possess => vec![BasicRanged { + projectile: Projectile { + hit_ground: vec![projectile::Effect::Stick], + hit_wall: vec![projectile::Effect::Stick], + hit_entity: vec![projectile::Effect::Stick, projectile::Effect::Possess], + time_left: Duration::from_secs(10), + owner: None, + }, + projectile_body: Body::Object(object::Body::ArrowSnake), + recover_duration: Duration::from_millis(300), + }], }, Empty => vec![], } diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs index cb43eb985d..e5e3e7e642 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(21 + 3 * self.level.amount); } + pub fn update_max_hp(&mut self) { self.health.set_maximum(33 + 7 * self.level.amount); } } impl Stats { diff --git a/common/src/states/basic_melee.rs b/common/src/states/basic_melee.rs index 1f972e0594..0c1a8d3ea1 100644 --- a/common/src/states/basic_melee.rs +++ b/common/src/states/basic_melee.rs @@ -46,6 +46,7 @@ impl CharacterBehavior for Data { // Hit attempt data.updater.insert(data.entity, Attacking { base_damage: self.base_damage, + max_angle: 75_f32.to_radians(), applied: false, hit_count: 0, }); diff --git a/common/src/states/basic_ranged.rs b/common/src/states/basic_ranged.rs index 533759d031..40412bb558 100644 --- a/common/src/states/basic_ranged.rs +++ b/common/src/states/basic_ranged.rs @@ -48,12 +48,14 @@ impl CharacterBehavior for Data { }); } else if !self.exhausted { // Fire + let mut projectile = self.projectile.clone(); + projectile.owner = Some(*data.uid); update.server_events.push_front(ServerEvent::Shoot { entity: data.entity, dir: data.inputs.look_dir, body: self.projectile_body, light: None, - projectile: self.projectile.clone(), + projectile, gravity: Some(Gravity(0.1)), }); diff --git a/common/src/states/dash_melee.rs b/common/src/states/dash_melee.rs index a58eb31d62..b72502d219 100644 --- a/common/src/states/dash_melee.rs +++ b/common/src/states/dash_melee.rs @@ -54,6 +54,7 @@ impl CharacterBehavior for Data { // Hit attempt data.updater.insert(data.entity, Attacking { base_damage: self.base_damage, + max_angle: 180_f32.to_radians(), applied: false, hit_count: 0, }); diff --git a/common/src/states/timed_combo.rs b/common/src/states/timed_combo.rs index cd7cd7b9d9..56be959851 100644 --- a/common/src/states/timed_combo.rs +++ b/common/src/states/timed_combo.rs @@ -61,6 +61,7 @@ impl CharacterBehavior for Data { // Swing hits data.updater.insert(data.entity, Attacking { base_damage: self.base_damage * (self.stage as u32 + 1), + max_angle: 75_f32.to_radians(), applied: false, hit_count: 0, }); diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs index f5ebc3e0ea..f6cdb6ca3d 100644 --- a/common/src/sys/combat.rs +++ b/common/src/sys/combat.rs @@ -101,7 +101,7 @@ impl<'a> System<'a> for Sys { && !stats_b.is_dead // Spherical wedge shaped attack field && pos.0.distance_squared(pos_b.0) < (rad_b + scale * ATTACK_RANGE).powi(2) - && ori2.angle_between(pos_b2 - pos2) < ATTACK_ANGLE.to_radians() / 2.0 + (rad_b / pos2.distance(pos_b2)).atan() + && ori2.angle_between(pos_b2 - pos2) < attack.max_angle + (rad_b / pos2.distance(pos_b2)).atan() { // Weapon gives base damage let mut dmg = attack.base_damage; diff --git a/server/src/events/interaction.rs b/server/src/events/interaction.rs index 7d7e3fd124..e424554ab3 100644 --- a/server/src/events/interaction.rs +++ b/server/src/events/interaction.rs @@ -77,46 +77,24 @@ pub fn handle_possess(server: &Server, possessor_uid: Uid, possesse_uid: Uid) { e ) }); - // Create inventory if it doesn't exist - { - let mut inventories = ecs.write_storage::(); - if let Some(inventory) = inventories.get_mut(possesse) { - inventory.push(assets::load_expect_cloned("common.items.debug.possess")); - } else { - inventories - .insert(possesse, comp::Inventory { - slots: vec![ - Some(assets::load_expect_cloned("common.items.debug.possess")), - None, - None, - None, - None, - None, - None, - None, - ], - }) - .err() - .map(|e| { - error!( - "Error inserting inventory component during possession: {:?}", - e - ) - }); - } - } - ecs.write_storage::() - .insert( - possesse, - comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Possession), - ) - .err() - .map(|e| { - error!( - "Error inserting inventory update component during possession: {:?}", - e - ) + // Put possess item into loadout + let mut loadouts = ecs.write_storage::(); + let loadout = loadouts + .entry(possesse) + .expect("Could not read loadouts component while possessing") + .or_insert(comp::Loadout::default()); + + let item = assets::load_expect_cloned::("common.items.debug.possess"); + if let comp::ItemKind::Tool(tool) = item.kind { + loadout.active_item = Some(comp::ItemConfig { + item, + primary_ability: tool.get_abilities().get(0).cloned(), + secondary_ability: None, + block_ability: None, + dodge_ability: None, }); + } + // Move player component { let mut players = ecs.write_storage::();