-
Notifications
You must be signed in to change notification settings - Fork 23
/
DeathSystem.java
94 lines (87 loc) · 4.75 KB
/
DeathSystem.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright 2020 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.wildAnimals.Death;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.core.Time;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.lifecycleEvents.OnAddedComponent;
import org.terasology.engine.entitySystem.event.EventPriority;
import org.terasology.engine.entitySystem.event.Priority;
import org.terasology.engine.entitySystem.systems.BaseComponentSystem;
import org.terasology.engine.entitySystem.systems.RegisterMode;
import org.terasology.engine.entitySystem.systems.RegisterSystem;
import org.terasology.engine.entitySystem.systems.UpdateSubscriberSystem;
import org.terasology.engine.logic.behavior.BehaviorComponent;
import org.terasology.engine.logic.characters.CharacterMovementComponent;
import org.terasology.engine.logic.health.BeforeDestroyEvent;
import org.terasology.engine.logic.health.DoDestroyEvent;
import org.terasology.engine.registry.In;
import org.terasology.engine.rendering.assets.animation.MeshAnimation;
import org.terasology.engine.rendering.logic.SkeletalMeshComponent;
import org.terasology.gestalt.entitysystem.event.ReceiveEvent;
import org.terasology.wildAnimals.component.WildAnimalComponent;
@RegisterSystem(RegisterMode.AUTHORITY)
public class DeathSystem extends BaseComponentSystem implements UpdateSubscriberSystem {
private static final Logger logger = LoggerFactory.getLogger(DeathSystem.class);
@In
EntityManager entityManager;
@In
private Time time;
/**
* On every update, checks for entities which have DestroyAtAnimationEndComponent,
* finds them and destroys them.
* Sending the DoDestroyEvent is essential for the DropGrammar system to handle
* item drops specified in the animal's DieComponent
*/
@Override
public void update(float delta) {
long currentTime = time.getGameTimeInMs();
for (EntityRef entity : entityManager.getEntitiesWith(DestroyAtAnimationEndComponent.class)) {
DestroyAtAnimationEndComponent destroyAtAnimationEndComponent = entity.getComponent(DestroyAtAnimationEndComponent.class);
if (destroyAtAnimationEndComponent.deathTime < currentTime) {
entity.send(new DoDestroyEvent(destroyAtAnimationEndComponent.getInstigator(), destroyAtAnimationEndComponent.getDirectCause(), destroyAtAnimationEndComponent.getDamageType()));
entity.destroy();
}
}
}
/**
* Compute and save deathTime whenever a DestroyAtAnimationEndComponent is added
*/
@ReceiveEvent
public void addedDestroyAtAnimationEndComponent(OnAddedComponent event, EntityRef entityRef, DestroyAtAnimationEndComponent destroyAtAnimationEndComponent) {
destroyAtAnimationEndComponent.deathTime = time.getGameTimeInMs() + (long) (destroyAtAnimationEndComponent.lifespan * 1000);
entityRef.saveComponent(destroyAtAnimationEndComponent);
}
/**
* Receives and consumes the BeforeDestroyEvent.
* Removes extra components from the animal entity and updates skeletalMesh to play dying animation
* Triggers the entity to self destruct after animation ends by attaching DestroyAtAnimationEndComponent
*/
@Priority(EventPriority.PRIORITY_HIGH)
@ReceiveEvent(components = {WildAnimalComponent.class, DieComponent.class})
public void onDeath(BeforeDestroyEvent event, EntityRef entity, DieComponent dieComponent) {
event.consume();
entity.removeComponent(BehaviorComponent.class);
entity.removeComponent(CharacterMovementComponent.class);
SkeletalMeshComponent skeletalMeshComponent = entity.getComponent(SkeletalMeshComponent.class);
if (skeletalMeshComponent == null) {
return;
}
// Add fall animation from DieComponent
skeletalMeshComponent.animation = null;
skeletalMeshComponent.animationPool.clear();
skeletalMeshComponent.animationPool.addAll(dieComponent.animationPool);
skeletalMeshComponent.loop = false;
entity.saveComponent(skeletalMeshComponent);
// Find total length of animations
float lifespan = 0;
for (MeshAnimation meshAnimation : skeletalMeshComponent.animationPool) {
lifespan += meshAnimation.getTimePerFrame() * (meshAnimation.getFrameCount() - 1);
}
// Trigger entity to self destruct after animations end
DestroyAtAnimationEndComponent destroyAtAnimationEndComponent = new DestroyAtAnimationEndComponent(lifespan, event.getInstigator(), event.getDirectCause(), event.getDamageType());
entity.addOrSaveComponent(destroyAtAnimationEndComponent);
}
}