[Fix] Rework EntityId <-> EntityIdType -> EntityType conversion

* Also reverts the Id sync for  EntityIdType and EntityType
This commit is contained in:
hartie95 2023-08-08 00:00:58 +02:00
parent 2be7475591
commit 1e86edb85e
7 changed files with 66 additions and 31 deletions

View File

@ -6,9 +6,7 @@ import emu.grasscutter.data.GameData;
import emu.grasscutter.game.ability.Ability;
import emu.grasscutter.game.ability.AbilityModifierController;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.LifeState;
import emu.grasscutter.game.props.*;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.game.world.SpawnDataEntry;
import emu.grasscutter.game.world.World;
@ -60,8 +58,8 @@ public abstract class GameEntity {
this.motionState = MotionState.MOTION_STATE_NONE;
}
public int getEntityType() {
return this.getId() >> 24;
public EntityType getEntityType() {
return EntityIdType.fromEntityId(this.getId()).getType();
}
public abstract int getEntityTypeId();

View File

@ -1,26 +1,60 @@
package emu.grasscutter.game.props;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
/**
* TODO for now keep it in sync with EntityType, maybe replace this by EntityType
* This comes from [ProtEntityType].
* Either the client or GC seems to expect ids to have this type in them, with these specific numbers.
*/
@AllArgsConstructor
public enum EntityIdType {
NONE (0x00),
AVATAR (0x01),
MONSTER (0x02),
NPC (0x0C),
GADGET (0x13),
REGION (0x05),
WEAPON (0x08),
TEAM (0x1F),
MPLEVEL (0x2A);
NONE (0x00, EntityType.None),
AVATAR (0x01, EntityType.Avatar),
MONSTER (0x02, EntityType.Monster),
NPC (0x03, EntityType.NPC),
GADGET (0x04, EntityType.Gadget),
REGION (0x05, EntityType.None), //TODO check maybe level or EnviroArea?
WEAPON (0x06, EntityType.Equip),
WEATHER (0x07, EntityType.None), //TODO check maybe EnviroArea or AOE?
SCENE (0x08, EntityType.None), //TODO check maybe level?
TEAM (0x09, EntityType.Team),
MASSIVE_ENTITY (0x0A, EntityType.None), //TODO check
MPLEVEL (0x0B, EntityType.MPLevel),
PLAY_TEAM_ENTITY (0x0C, EntityType.PlayTeam),
EYE_POINT (0x0D, EntityType.EyePoint)
;
@Getter
private final int id;
@Getter
private final EntityType type;
private EntityIdType(int id) {
this.id = id;
}
public int getId() {
return id;
}
private static final Int2ObjectMap<EntityIdType> map = new Int2ObjectOpenHashMap<>();
private static final Map<String, EntityIdType> stringMap = new HashMap<>();
static {
Stream.of(values()).forEach(e -> {
map.put(e.getId(), e);
stringMap.put(e.name(), e);
});
}
public static EntityIdType fromEntityId(int id) {
return map.getOrDefault(id >> 24, NONE);
}
public static int idFromEntityId(int id) {
return id >> 24;
}
public int toTypedEntityId(int nextEid) {
return (getId() << 24) + nextEid;
}
}

View File

@ -7,6 +7,8 @@ import java.util.stream.Stream;
import emu.grasscutter.scripts.constants.IntValueEnum;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
public enum EntityType implements IntValueEnum{
None (0),
@ -84,6 +86,7 @@ public enum EntityType implements IntValueEnum{
CoinCollectLevelGadget (72),
PlaceHolder (99);
@Getter
private final int value;
private static final Int2ObjectMap<EntityType> map = new Int2ObjectOpenHashMap<>();
private static final Map<String, EntityType> stringMap = new HashMap<>();
@ -99,9 +102,6 @@ public enum EntityType implements IntValueEnum{
this.value = value;
}
public int getValue() {
return value;
}
public static EntityType getTypeByValue(int value) {
return map.getOrDefault(value, None);

View File

@ -131,7 +131,7 @@ public class Scene {
var entity = this.entities.get(id);
if(entity == null) entity = this.weaponEntities.get(id);
if(entity == null && (id >> 24) == EntityIdType.AVATAR.getId()) {
if(entity == null && EntityIdType.idFromEntityId(id) == EntityIdType.AVATAR.getId()) {
for (var player : getPlayers()) {
for (var avatar : player.getTeamManager().getActiveTeam()) {
if(avatar.getId() == id) return avatar;

View File

@ -138,7 +138,7 @@ public class World implements Iterable<Player> {
}
public int getNextEntityId(EntityIdType idType) {
return (idType.getId() << 24) + ++this.nextEntityId;
return idType.toTypedEntityId(++this.nextEntityId);
}
public synchronized void addPlayer(Player player) {

View File

@ -572,7 +572,7 @@ public class SceneScriptManager {
private void callRegionEvent(EntityRegion region, int eventType, GameEntity entity) {
callEvent(new ScriptArgs(region.getGroupId(), eventType, region.getConfigId())
.setEventSource(entity.getEntityType())
.setEventSource(entity.getEntityType().getValue())
.setSourceEntityId(region.getId())
.setTargetEntityId(entity.getId())
);

View File

@ -100,7 +100,7 @@ public class ScriptLib {
}
public static int GetEntityType(int entityId){
return entityId >> 24;
return EntityIdType.fromEntityId(entityId).getType().getValue();
}
@ -561,7 +561,7 @@ public class ScriptLib {
return 0;
}
return (int) region.getEntities().stream().filter(e -> e.getEntityType() == entityType).count();
return (int) region.getEntities().stream().filter(e -> e.getEntityType().getValue() == entityType).count();
}
public static int TowerCountTimeStatus(GroupEventLuaContext context, int isDone, int var2){
@ -796,7 +796,7 @@ public class ScriptLib {
val entity = context.getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
if(entity == null || entity.getEntityType() != entityType){
if(entity == null || entity.getEntityType().getValue() != entityType){
return 1;
}
@ -876,7 +876,10 @@ public class ScriptLib {
}
public static boolean IsPlayerAllAvatarDie(GroupEventLuaContext context, int sceneUid){
logger.warn("[LUA] Call unimplemented IsPlayerAllAvatarDie {}", sceneUid);
var playerEntities = context.getSceneScriptManager().getScene().getEntities().values().stream().filter(e -> e.getEntityType() == EntityType.Avatar.getValue()).toList();
var playerEntities = context.getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e.getEntityType() == EntityType.Avatar)
.toList();
for (GameEntity p : playerEntities){
var player = (EntityAvatar)p;
if(player.isAlive()){