GameEntity.java 7.4 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
package emu.grasscutter.game.entity;

Melledy's avatar
Melledy committed
3
4
5
import java.util.HashMap;
import java.util.Map;

Melledy's avatar
Melledy committed
6
import emu.grasscutter.game.player.Player;
Melledy's avatar
Melledy committed
7
8
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.LifeState;
Melledy's avatar
Melledy committed
9
import emu.grasscutter.game.world.Scene;
Melledy's avatar
Melledy committed
10
import emu.grasscutter.game.world.SpawnDataEntry;
Melledy's avatar
Melledy committed
11
import emu.grasscutter.game.world.World;
12
import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair;
Melledy's avatar
Melledy committed
13
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
Melledy's avatar
Melledy committed
14
15
16
17
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState;
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
18
import emu.grasscutter.server.event.entity.EntityDeathEvent;
Melledy's avatar
Melledy committed
19
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
Melledy's avatar
Melledy committed
20
import emu.grasscutter.utils.Position;
21
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
Melledy's avatar
Melledy committed
22
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
Melledy's avatar
Melledy committed
23
24
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
Melledy's avatar
Melledy committed
25

26
public abstract class GameEntity {
Melledy's avatar
Melledy committed
27
	protected int id;
28
	private final Scene scene;
Melledy's avatar
Melledy committed
29
	private SpawnDataEntry spawnEntry;
KingRainbow44's avatar
KingRainbow44 committed
30

31
32
33
	private int blockId;
	private int configId;
	private int groupId;
KingRainbow44's avatar
KingRainbow44 committed
34

Melledy's avatar
Melledy committed
35
36
37
	private MotionState moveState;
	private int lastMoveSceneTimeMs;
	private int lastMoveReliableSeq;
KingRainbow44's avatar
KingRainbow44 committed
38

Melledy's avatar
Melledy committed
39
40
41
	// Abilities
	private Map<String, Float> metaOverrideMap;
	private Int2ObjectMap<String> metaModifiers;
KingRainbow44's avatar
KingRainbow44 committed
42

43
	public GameEntity(Scene scene) {
44
		this.scene = scene;
45
		this.moveState = MotionState.MOTION_STATE_NONE;
Melledy's avatar
Melledy committed
46
	}
KingRainbow44's avatar
KingRainbow44 committed
47

Melledy's avatar
Melledy committed
48
49
50
	public int getId() {
		return this.id;
	}
KingRainbow44's avatar
KingRainbow44 committed
51

Melledy's avatar
Melledy committed
52
53
54
	public int getEntityType() {
		return getId() >> 24;
	}
KingRainbow44's avatar
KingRainbow44 committed
55

Melledy's avatar
Melledy committed
56
	public World getWorld() {
57
58
59
		return this.getScene().getWorld();
	}

60
	public Scene getScene() {
61
		return this.scene;
Melledy's avatar
Melledy committed
62
	}
KingRainbow44's avatar
KingRainbow44 committed
63

Melledy's avatar
Melledy committed
64
65
66
67
68
69
70
	public boolean isAlive() {
		return true;
	}

	public LifeState getLifeState() {
		return isAlive() ? LifeState.LIFE_ALIVE : LifeState.LIFE_DEAD;
	}
KingRainbow44's avatar
KingRainbow44 committed
71

Melledy's avatar
Melledy committed
72
73
74
75
76
77
	public Map<String, Float> getMetaOverrideMap() {
		if (this.metaOverrideMap == null) {
			this.metaOverrideMap = new HashMap<>();
		}
		return this.metaOverrideMap;
	}
KingRainbow44's avatar
KingRainbow44 committed
78

Melledy's avatar
Melledy committed
79
80
81
82
83
84
85
	public Int2ObjectMap<String> getMetaModifiers() {
		if (this.metaModifiers == null) {
			this.metaModifiers = new Int2ObjectOpenHashMap<>();
		}
		return this.metaModifiers;
	}

github-actions's avatar
github-actions committed
86
    public abstract Int2FloatOpenHashMap getFightProperties();
KingRainbow44's avatar
KingRainbow44 committed
87

github-actions's avatar
github-actions committed
88
    public abstract Position getPosition();
KingRainbow44's avatar
KingRainbow44 committed
89

github-actions's avatar
github-actions committed
90
    public abstract Position getRotation();
KingRainbow44's avatar
KingRainbow44 committed
91

github-actions's avatar
github-actions committed
92
93
94
    public MotionState getMotionState() {
        return moveState;
    }
Melledy's avatar
Melledy committed
95

github-actions's avatar
github-actions committed
96
97
98
    public void setMotionState(MotionState moveState) {
        this.moveState = moveState;
    }
KingRainbow44's avatar
KingRainbow44 committed
99

github-actions's avatar
github-actions committed
100
101
102
    public int getLastMoveSceneTimeMs() {
        return lastMoveSceneTimeMs;
    }
KingRainbow44's avatar
KingRainbow44 committed
103

github-actions's avatar
github-actions committed
104
105
106
    public void setLastMoveSceneTimeMs(int lastMoveSceneTimeMs) {
        this.lastMoveSceneTimeMs = lastMoveSceneTimeMs;
    }
KingRainbow44's avatar
KingRainbow44 committed
107

github-actions's avatar
github-actions committed
108
109
110
    public int getLastMoveReliableSeq() {
        return lastMoveReliableSeq;
    }
KingRainbow44's avatar
KingRainbow44 committed
111

github-actions's avatar
github-actions committed
112
113
114
    public void setLastMoveReliableSeq(int lastMoveReliableSeq) {
        this.lastMoveReliableSeq = lastMoveReliableSeq;
    }
KingRainbow44's avatar
KingRainbow44 committed
115

github-actions's avatar
github-actions committed
116
117
118
    public void setFightProperty(FightProperty prop, float value) {
        this.getFightProperties().put(prop.getId(), value);
    }
KingRainbow44's avatar
KingRainbow44 committed
119

github-actions's avatar
github-actions committed
120
121
122
    private void setFightProperty(int id, float value) {
        this.getFightProperties().put(id, value);
    }
123

github-actions's avatar
github-actions committed
124
125
126
    public void addFightProperty(FightProperty prop, float value) {
        this.getFightProperties().put(prop.getId(), getFightProperty(prop) + value);
    }
KingRainbow44's avatar
KingRainbow44 committed
127

github-actions's avatar
github-actions committed
128
129
130
    public float getFightProperty(FightProperty prop) {
        return getFightProperties().getOrDefault(prop.getId(), 0f);
    }
131

github-actions's avatar
github-actions committed
132
133
134
135
136
137
138
139
140
    public void addAllFightPropsToEntityInfo(SceneEntityInfo.Builder entityInfo) {
        for (Int2FloatMap.Entry entry : getFightProperties().int2FloatEntrySet()) {
            if (entry.getIntKey() == 0) {
                continue;
            }
            FightPropPair fightProp = FightPropPair.newBuilder().setPropType(entry.getIntKey()).setPropValue(entry.getFloatValue()).build();
            entityInfo.addFightPropList(fightProp);
        }
    }
KingRainbow44's avatar
KingRainbow44 committed
141

github-actions's avatar
github-actions committed
142
143
144
    public int getBlockId() {
        return blockId;
    }
145

github-actions's avatar
github-actions committed
146
147
148
    public void setBlockId(int blockId) {
        this.blockId = blockId;
    }
KingRainbow44's avatar
KingRainbow44 committed
149

github-actions's avatar
github-actions committed
150
151
152
    public int getConfigId() {
        return configId;
    }
KingRainbow44's avatar
KingRainbow44 committed
153

github-actions's avatar
github-actions committed
154
155
156
    public void setConfigId(int configId) {
        this.configId = configId;
    }
Melledy's avatar
Melledy committed
157

github-actions's avatar
github-actions committed
158
159
160
    public int getGroupId() {
        return groupId;
    }
Melledy's avatar
Melledy committed
161

github-actions's avatar
github-actions committed
162
163
164
    public void setGroupId(int groupId) {
        this.groupId = groupId;
    }
KingRainbow44's avatar
KingRainbow44 committed
165

github-actions's avatar
github-actions committed
166
167
168
169
170
171
172
    protected MotionInfo getMotionInfo() {
        MotionInfo proto = MotionInfo.newBuilder()
                .setPos(getPosition().toProto())
                .setRot(getRotation().toProto())
                .setSpeed(Vector.newBuilder())
                .setState(this.getMotionState())
                .build();
Melledy's avatar
Melledy committed
173

github-actions's avatar
github-actions committed
174
175
        return proto;
    }
KingRainbow44's avatar
KingRainbow44 committed
176

github-actions's avatar
github-actions committed
177
178
179
    public SpawnDataEntry getSpawnEntry() {
        return spawnEntry;
    }
KingRainbow44's avatar
KingRainbow44 committed
180

github-actions's avatar
github-actions committed
181
182
183
    public void setSpawnEntry(SpawnDataEntry spawnEntry) {
        this.spawnEntry = spawnEntry;
    }
KingRainbow44's avatar
KingRainbow44 committed
184

github-actions's avatar
github-actions committed
185
186
187
188
    public float heal(float amount) {
        if (this.getFightProperties() == null) {
            return 0f;
        }
KingRainbow44's avatar
KingRainbow44 committed
189

github-actions's avatar
github-actions committed
190
191
        float curHp = getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
        float maxHp = getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
KingRainbow44's avatar
KingRainbow44 committed
192

github-actions's avatar
github-actions committed
193
194
195
        if (curHp >= maxHp) {
            return 0f;
        }
KingRainbow44's avatar
KingRainbow44 committed
196

github-actions's avatar
github-actions committed
197
198
        float healed = Math.min(maxHp - curHp, amount);
        this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, healed);
KingRainbow44's avatar
KingRainbow44 committed
199

github-actions's avatar
github-actions committed
200
        getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, FightProperty.FIGHT_PROP_CUR_HP));
KingRainbow44's avatar
KingRainbow44 committed
201

github-actions's avatar
github-actions committed
202
203
        return healed;
    }
KingRainbow44's avatar
KingRainbow44 committed
204

github-actions's avatar
github-actions committed
205
206
207
    public void damage(float amount) {
        damage(amount, 0);
    }
KingRainbow44's avatar
KingRainbow44 committed
208

github-actions's avatar
github-actions committed
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
    public void damage(float amount, int killerId) {
        // Sanity check
        if (getFightProperties() == null) {
            return;
        }

        // Lose hp
        addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -amount);

        // Check if dead
        boolean isDead = false;
        if (getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) {
            setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
            isDead = true;
        }

        // Packets
        this.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, FightProperty.FIGHT_PROP_CUR_HP));

        // Check if dead
        if (isDead) {
            getScene().killEntity(this, killerId);
        }
    }
KingRainbow44's avatar
KingRainbow44 committed
233
234
235
236
237
238
239
240
241
242
243
244

    /**
     * Move this entity to a new position.
     * @param position The new position.
     * @param rotation The new rotation.
     */
    public void move(Position position, Position rotation) {
        // Set the position and rotation.
        this.getPosition().set(position);
        this.getRotation().set(rotation);
    }

github-actions's avatar
github-actions committed
245
    /**
Melledy's avatar
Melledy committed
246
247
     * Called when a player interacts with this entity
     * @param player Player that is interacting with this entity
github-actions's avatar
github-actions committed
248
     * @param interactReq Interact request protobuf data
Melledy's avatar
Melledy committed
249
250
     */
    public void onInteract(Player player, GadgetInteractReq interactReq) {
github-actions's avatar
github-actions committed
251

Melledy's avatar
Melledy committed
252
    }
github-actions's avatar
github-actions committed
253

254
255
256
    /**
     * Called when this entity is added to the world
     */
github-actions's avatar
github-actions committed
257
    public void onCreate() {
KingRainbow44's avatar
KingRainbow44 committed
258

github-actions's avatar
github-actions committed
259
    }
KingRainbow44's avatar
KingRainbow44 committed
260

github-actions's avatar
github-actions committed
261
    /**
262
263
264
     * Called when this entity dies
     * @param killerId Entity id of the entity that killed this entity
     */
github-actions's avatar
github-actions committed
265
    public void onDeath(int killerId) {
266
267
268
        // Invoke entity death event.
        EntityDeathEvent event = new EntityDeathEvent(this, killerId);
        event.call();
github-actions's avatar
github-actions committed
269
    }
KingRainbow44's avatar
KingRainbow44 committed
270

github-actions's avatar
github-actions committed
271
    public abstract SceneEntityInfo toProto();
Melledy's avatar
Melledy committed
272
}