mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Make arrows 'bonk' hanging sprites
This commit is contained in:
parent
913c23e1ad
commit
0b1a820762
@ -19,6 +19,7 @@ pub enum Effect {
|
|||||||
Vanish,
|
Vanish,
|
||||||
Stick,
|
Stick,
|
||||||
Possess,
|
Possess,
|
||||||
|
Bonk, // Knock/dislodge/change objects on hit
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
@ -127,7 +128,7 @@ impl ProjectileConstructor {
|
|||||||
.with_combo_increment();
|
.with_combo_increment();
|
||||||
|
|
||||||
Projectile {
|
Projectile {
|
||||||
hit_solid: vec![Effect::Stick],
|
hit_solid: vec![Effect::Stick, Effect::Bonk],
|
||||||
hit_entity: vec![Effect::Attack(attack), Effect::Vanish],
|
hit_entity: vec![Effect::Attack(attack), Effect::Vanish],
|
||||||
time_left: Duration::from_secs(15),
|
time_left: Duration::from_secs(15),
|
||||||
owner,
|
owner,
|
||||||
|
@ -42,6 +42,11 @@ pub enum ServerEvent {
|
|||||||
explosion: Explosion,
|
explosion: Explosion,
|
||||||
owner: Option<Uid>,
|
owner: Option<Uid>,
|
||||||
},
|
},
|
||||||
|
Bonk {
|
||||||
|
pos: Vec3<f32>,
|
||||||
|
owner: Option<Uid>,
|
||||||
|
target: Option<Uid>,
|
||||||
|
},
|
||||||
Damage {
|
Damage {
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
change: comp::HealthChange,
|
change: comp::HealthChange,
|
||||||
|
@ -259,6 +259,14 @@ impl Block {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_bonkable(&self) -> bool {
|
||||||
|
match self.get_sprite() {
|
||||||
|
Some(SpriteKind::Apple | SpriteKind::Beehive | SpriteKind::Coconut) => self.is_solid(),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The tool required to mine this block. For blocks that cannot be mined,
|
/// The tool required to mine this block. For blocks that cannot be mined,
|
||||||
/// `None` is returned.
|
/// `None` is returned.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -238,6 +238,7 @@ impl SpriteKind {
|
|||||||
| SpriteKind::MedFlatCactus
|
| SpriteKind::MedFlatCactus
|
||||||
| SpriteKind::ShortFlatCactus
|
| SpriteKind::ShortFlatCactus
|
||||||
| SpriteKind::Apple
|
| SpriteKind::Apple
|
||||||
|
| SpriteKind::Beehive
|
||||||
| SpriteKind::Velorite
|
| SpriteKind::Velorite
|
||||||
| SpriteKind::VeloriteFrag
|
| SpriteKind::VeloriteFrag
|
||||||
| SpriteKind::Coconut
|
| SpriteKind::Coconut
|
||||||
|
@ -872,15 +872,14 @@ impl<'a> PhysicsData<'a> {
|
|||||||
.terrain
|
.terrain
|
||||||
.get(pos.0.map(|e| e.floor() as i32))
|
.get(pos.0.map(|e| e.floor() as i32))
|
||||||
.ok()
|
.ok()
|
||||||
.filter(|b| b.is_filled())
|
.filter(|b| b.is_solid())
|
||||||
// TODO: `is_solid`, when arrows are special-cased
|
|
||||||
{
|
{
|
||||||
(0.0, Some(block))
|
(0.0, Some(block))
|
||||||
} else {
|
} else {
|
||||||
let (dist, block) = read
|
let (dist, block) = read
|
||||||
.terrain
|
.terrain
|
||||||
.ray(pos.0, pos.0 + pos_delta)
|
.ray(pos.0, pos.0 + pos_delta)
|
||||||
.until(|block: &Block| block.is_filled())
|
.until(|block: &Block| block.is_solid())
|
||||||
.ignore_error()
|
.ignore_error()
|
||||||
.cast();
|
.cast();
|
||||||
(dist, block.unwrap()) // Can't fail since we do ignore_error above
|
(dist, block.unwrap()) // Can't fail since we do ignore_error above
|
||||||
@ -897,7 +896,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
.zip(read.bodies.get(entity).copied())
|
.zip(read.bodies.get(entity).copied())
|
||||||
{
|
{
|
||||||
outcomes.push(Outcome::ProjectileHit {
|
outcomes.push(Outcome::ProjectileHit {
|
||||||
pos: pos.0,
|
pos: pos.0 + pos_delta * dist,
|
||||||
body,
|
body,
|
||||||
vel: vel.0,
|
vel: vel.0,
|
||||||
source: projectile.owner,
|
source: projectile.owner,
|
||||||
|
@ -181,6 +181,13 @@ impl<'a> System<'a> for Sys {
|
|||||||
});
|
});
|
||||||
projectile_vanished = true;
|
projectile_vanished = true;
|
||||||
},
|
},
|
||||||
|
projectile::Effect::Bonk => {
|
||||||
|
server_emitter.emit(ServerEvent::Bonk {
|
||||||
|
pos: pos.0,
|
||||||
|
owner: projectile.owner,
|
||||||
|
target: None,
|
||||||
|
});
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,6 +332,15 @@ fn dispatch_hit(
|
|||||||
owner: owner_uid,
|
owner: owner_uid,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
projectile::Effect::Bonk => {
|
||||||
|
let Pos(pos) = *projectile_info.pos;
|
||||||
|
let owner_uid = projectile_info.owner_uid;
|
||||||
|
server_emitter.emit(ServerEvent::Bonk {
|
||||||
|
pos,
|
||||||
|
owner: owner_uid,
|
||||||
|
target: Some(projectile_target_info.uid),
|
||||||
|
});
|
||||||
|
},
|
||||||
projectile::Effect::Vanish => {
|
projectile::Effect::Vanish => {
|
||||||
let entity = projectile_info.entity;
|
let entity = projectile_info.entity;
|
||||||
server_emitter.emit(ServerEvent::Destroy {
|
server_emitter.emit(ServerEvent::Destroy {
|
||||||
|
@ -37,7 +37,7 @@ use common_state::BlockChange;
|
|||||||
use comp::chat::GenericChatMsg;
|
use comp::chat::GenericChatMsg;
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt};
|
use specs::{join::Join, saveload::MarkerAllocator, Builder, Entity as EcsEntity, WorldExt};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use vek::{Vec2, Vec3};
|
use vek::{Vec2, Vec3};
|
||||||
|
|
||||||
@ -378,7 +378,6 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
{
|
{
|
||||||
// Only drop loot if entity has agency (not a player), and if it is not owned by
|
// Only drop loot if entity has agency (not a player), and if it is not owned by
|
||||||
// another entity (not a pet)
|
// another entity (not a pet)
|
||||||
use specs::Builder;
|
|
||||||
|
|
||||||
// Decide for a loot drop before turning into a lootbag
|
// Decide for a loot drop before turning into a lootbag
|
||||||
let old_body = state.ecs().write_storage::<Body>().remove(entity);
|
let old_body = state.ecs().write_storage::<Body>().remove(entity);
|
||||||
@ -1021,6 +1020,37 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_bonk(server: &mut Server, pos: Vec3<f32>, owner: Option<Uid>, target: Option<Uid>) {
|
||||||
|
let ecs = &server.state.ecs();
|
||||||
|
let terrain = ecs.read_resource::<TerrainGrid>();
|
||||||
|
let mut block_change = ecs.write_resource::<BlockChange>();
|
||||||
|
|
||||||
|
if let Some(_target) = target {
|
||||||
|
// TODO: bonk entities but do no damage?
|
||||||
|
drop(owner);
|
||||||
|
} else {
|
||||||
|
use common::terrain::SpriteKind;
|
||||||
|
let pos = pos.map(|e| e.floor() as i32);
|
||||||
|
if let Some(block) = terrain.get(pos).ok().copied().filter(|b| b.is_bonkable()) {
|
||||||
|
if let Some(item) = comp::Item::try_reclaim_from_block(block) {
|
||||||
|
if block_change
|
||||||
|
.try_set(pos, block.with_sprite(SpriteKind::Empty))
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
drop(terrain);
|
||||||
|
drop(block_change);
|
||||||
|
server
|
||||||
|
.state
|
||||||
|
.create_object(Default::default(), comp::object::Body::Pouch)
|
||||||
|
.with(comp::Pos(pos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0)))
|
||||||
|
.with(item)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_aura(server: &mut Server, entity: EcsEntity, aura_change: aura::AuraChange) {
|
pub fn handle_aura(server: &mut Server, entity: EcsEntity, aura_change: aura::AuraChange) {
|
||||||
let ecs = &server.state.ecs();
|
let ecs = &server.state.ecs();
|
||||||
let mut auras_all = ecs.write_storage::<comp::Auras>();
|
let mut auras_all = ecs.write_storage::<comp::Auras>();
|
||||||
|
@ -6,9 +6,9 @@ use entity_creation::{
|
|||||||
handle_initialize_character, handle_loaded_character_data, handle_shockwave, handle_shoot,
|
handle_initialize_character, handle_loaded_character_data, handle_shockwave, handle_shoot,
|
||||||
};
|
};
|
||||||
use entity_manipulation::{
|
use entity_manipulation::{
|
||||||
handle_aura, handle_buff, handle_combo_change, handle_damage, handle_delete, handle_destroy,
|
handle_aura, handle_bonk, handle_buff, handle_combo_change, handle_damage, handle_delete,
|
||||||
handle_energy_change, handle_explosion, handle_knockback, handle_land_on_ground, handle_poise,
|
handle_destroy, handle_energy_change, handle_explosion, handle_knockback,
|
||||||
handle_respawn, handle_teleport_to,
|
handle_land_on_ground, handle_poise, handle_respawn, handle_teleport_to,
|
||||||
};
|
};
|
||||||
use group_manip::handle_group;
|
use group_manip::handle_group;
|
||||||
use information::handle_site_info;
|
use information::handle_site_info;
|
||||||
@ -67,6 +67,7 @@ impl Server {
|
|||||||
explosion,
|
explosion,
|
||||||
owner,
|
owner,
|
||||||
} => handle_explosion(self, pos, explosion, owner),
|
} => handle_explosion(self, pos, explosion, owner),
|
||||||
|
ServerEvent::Bonk { pos, owner, target } => handle_bonk(self, pos, owner, target),
|
||||||
ServerEvent::Shoot {
|
ServerEvent::Shoot {
|
||||||
entity,
|
entity,
|
||||||
dir,
|
dir,
|
||||||
|
Loading…
Reference in New Issue
Block a user