Ranged weapons now give xp on kill and also make enemies angry

This commit is contained in:
timokoesters 2020-03-20 14:26:18 +01:00
parent 6836a043af
commit c630df7f9a
7 changed files with 37 additions and 10 deletions

View File

@ -99,7 +99,7 @@ impl ToolData {
projectile::Effect::Damage(HealthChange {
// TODO: This should not be fixed (?)
amount: -3,
cause: HealthSource::Item,
cause: HealthSource::Projectile { owner: None },
}),
projectile::Effect::Vanish,
],
@ -128,7 +128,7 @@ impl ToolData {
projectile::Effect::Damage(HealthChange {
// TODO: This should not be fixed (?)
amount: -8,
cause: HealthSource::Item,
cause: HealthSource::Projectile { owner: None },
}),
projectile::Effect::Vanish,
],

View File

@ -22,6 +22,26 @@ pub struct Projectile {
pub owner: Option<Uid>,
}
impl Projectile {
pub fn set_owner(&mut self, new_owner: Uid) {
self.owner = Some(new_owner);
for e in self
.hit_ground
.iter_mut()
.chain(self.hit_wall.iter_mut())
.chain(self.hit_entity.iter_mut())
{
if let Effect::Damage(comp::HealthChange {
cause: comp::HealthSource::Projectile { owner, .. },
..
}) = e
{
*owner = Some(new_owner);
}
}
}
}
impl Component for Projectile {
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
}

View File

@ -15,6 +15,7 @@ pub struct HealthChange {
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub enum HealthSource {
Attack { by: Uid }, // TODO: Implement weapon
Projectile { owner: Option<Uid> },
Suicide,
World,
Revive,

View File

@ -49,7 +49,7 @@ impl CharacterBehavior for Data {
} else if !self.exhausted {
// Fire
let mut projectile = self.projectile.clone();
projectile.owner = Some(*data.uid);
projectile.set_owner(*data.uid);
update.server_events.push_front(ServerEvent::Shoot {
entity: data.entity,
dir: data.inputs.look_dir,

View File

@ -252,7 +252,10 @@ impl<'a> System<'a> for Sys {
if let Some(stats) = stats.get(entity) {
// Only if the attack was recent
if stats.health.last_change.0 < 5.0 {
if let comp::HealthSource::Attack { by } = stats.health.last_change.1.cause {
if let comp::HealthSource::Attack { by }
| comp::HealthSource::Projectile { owner: Some(by) } =
stats.health.last_change.1.cause
{
if !agent.activity.is_attack() {
if let Some(attacker) = uid_allocator.retrieve_entity_internal(by.id())
{

View File

@ -27,7 +27,9 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
// Chat message
if let Some(player) = state.ecs().read_storage::<Player>().get(entity) {
let msg = if let HealthSource::Attack { by } = cause {
let msg = if let HealthSource::Attack { by }
| HealthSource::Projectile { owner: Some(by) } = cause
{
state.ecs().entity_from_uid(by.into()).and_then(|attacker| {
state
.ecs()
@ -49,7 +51,9 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
// Give EXP to the killer if entity had stats
let mut stats = state.ecs().write_storage::<Stats>();
if let Some(entity_stats) = stats.get(entity).cloned() {
if let HealthSource::Attack { by } = cause {
if let HealthSource::Attack { by } | HealthSource::Projectile { owner: Some(by) } =
cause
{
state.ecs().entity_from_uid(by.into()).map(|attacker| {
if let Some(attacker_stats) = stats.get_mut(attacker) {
// TODO: Discuss whether we should give EXP by Player

View File

@ -70,7 +70,7 @@ impl<'a> System<'a> for Sys {
// (maybe health changes could be sent to the client as a list
// of events)
if match health.last_change.1.cause {
HealthSource::Attack { by } => {
HealthSource::Attack { by } | HealthSource::Projectile { owner: Some(by) } => {
let by_me = my_uid.map_or(false, |&uid| by == uid);
// If the attack was by me also reset this timer
if by_me {
@ -80,11 +80,10 @@ impl<'a> System<'a> for Sys {
},
HealthSource::Suicide => my_entity.0 == entity,
HealthSource::World => my_entity.0 == entity,
HealthSource::Revive => false,
HealthSource::Command => true,
HealthSource::LevelUp => my_entity.0 == entity,
HealthSource::Command => true,
HealthSource::Item => true,
HealthSource::Unknown => false,
_ => false,
} {
hp_floater_list.floaters.push(HpFloater {
timer: 0.0,