add region entity

This commit is contained in:
Akka
2022-06-23 15:59:17 +08:00
committed by Melledy
parent 1c6c581399
commit 67ac0d700d
8 changed files with 194 additions and 145 deletions

View File

@@ -0,0 +1,74 @@
package emu.grasscutter.game.entity;
import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass;
import emu.grasscutter.scripts.data.SceneRegion;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
import lombok.Getter;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Getter
public class EntityRegion extends GameEntity{
private final Position position;
private boolean hasNewEntities;
private final Set<Integer> entities; // Ids of entities inside this region
private final SceneRegion metaRegion;
public EntityRegion(Scene scene, SceneRegion region) {
super(scene);
this.id = getScene().getWorld().getNextEntityId(EntityIdType.REGION);
setGroupId(region.group.id);
setBlockId(region.group.block_id);
setConfigId(region.config_id);
this.position = region.pos.clone();
this.entities = ConcurrentHashMap.newKeySet();
this.metaRegion = region;
}
public void addEntity(GameEntity entity) {
if (this.getEntities().contains(entity.getId())) {
return;
}
this.getEntities().add(entity.getId());
this.hasNewEntities = true;
}
public boolean hasNewEntities() {
return hasNewEntities;
}
public void resetNewEntities() {
hasNewEntities = false;
}
public void removeEntity(GameEntity entity) {
this.getEntities().remove(entity.getId());
}
@Override
public Int2FloatOpenHashMap getFightProperties() {
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public Position getRotation() {
return null;
}
@Override
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
/**
* The Region Entity would not be sent to client.
*/
return null;
}
}

View File

@@ -5,10 +5,11 @@ public enum EntityIdType {
MONSTER (0x02),
NPC (0x03),
GADGET (0x04),
WEAPON (0x06),
REGION (0x05),
WEAPON (0x06),
TEAM (0x09),
MPLEVEL (0x0b);
private final int id;
private EntityIdType(int id) {

View File

@@ -30,24 +30,25 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.danilopianini.util.SpatialIndex;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
public class Scene {
private final World world;
private final SceneData sceneData;
private final List<Player> players;
private final Int2ObjectMap<GameEntity> entities;
private final Map<Integer, GameEntity> entities;
private final Set<SpawnDataEntry> spawnedEntities;
private final Set<SpawnDataEntry> deadSpawnedEntities;
private final Set<SceneBlock> loadedBlocks;
private boolean dontDestroyWhenEmpty;
private int autoCloseTime;
private int time;
private ClimateType climate;
private int weather;
private SceneScriptManager scriptManager;
private WorldChallenge challenge;
private List<DungeonSettleListener> dungeonSettleListeners;
@@ -57,19 +58,19 @@ public class Scene {
public Scene(World world, SceneData sceneData) {
this.world = world;
this.sceneData = sceneData;
this.players = Collections.synchronizedList(new ArrayList<>());
this.entities = Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>());
this.players = new CopyOnWriteArrayList<>();
this.entities = new ConcurrentHashMap<>();
this.time = 8 * 60;
this.climate = ClimateType.CLIMATE_SUNNY;
this.prevScene = 3;
this.spawnedEntities = new HashSet<>();
this.deadSpawnedEntities = new HashSet<>();
this.loadedBlocks = new HashSet<>();
this.spawnedEntities = ConcurrentHashMap.newKeySet();
this.deadSpawnedEntities = ConcurrentHashMap.newKeySet();
this.loadedBlocks = ConcurrentHashMap.newKeySet();
this.scriptManager = new SceneScriptManager(this);
}
public int getId() {
return sceneData.getId();
}
@@ -89,15 +90,15 @@ public class Scene {
public List<Player> getPlayers() {
return players;
}
public int getPlayerCount() {
return this.getPlayers().size();
}
public Int2ObjectMap<GameEntity> getEntities() {
public Map<Integer, GameEntity> getEntities() {
return entities;
}
public GameEntity getEntityById(int id) {
return this.entities.get(id);
}
@@ -629,15 +630,10 @@ public class Scene {
var suiteData = group.getSuiteByIndex(suite);
suiteData.sceneTriggers.forEach(getScriptManager()::registerTrigger);
entities.addAll(suiteData.sceneGadgets.stream()
.map(g -> scriptManager.createGadget(group.id, group.block_id, g))
.filter(Objects::nonNull)
.toList());
entities.addAll(suiteData.sceneMonsters.stream()
.map(mob -> scriptManager.createMonster(group.id, group.block_id, mob))
.filter(Objects::nonNull)
.toList());
entities.addAll(scriptManager.getGadgetsInGroupSuite(group, suiteData));
entities.addAll(scriptManager.getMonstersInGroupSuite(group, suiteData));
scriptManager.registerRegionInGroupSuite(group, suiteData);
}
scriptManager.meetEntities(entities);
@@ -654,19 +650,18 @@ public class Scene {
toRemove.forEach(this::removeEntityDirectly);
this.broadcastPacket(new PacketSceneEntityDisappearNotify(toRemove, VisionType.VISION_TYPE_REMOVE));
}
for (SceneGroup group : block.groups.values()) {
if(group.triggers != null){
group.triggers.values().forEach(getScriptManager()::deregisterTrigger);
}
if(group.regions != null){
group.regions.forEach(getScriptManager()::deregisterRegion);
group.regions.values().forEach(getScriptManager()::deregisterRegion);
}
}
scriptManager.getLoadedGroupSetPerBlock().remove(block.id);
Grasscutter.getLogger().info("Scene {} Block {} is unloaded.", this.getId(), block.id);
}
// Gadgets
public void onPlayerCreateGadget(EntityClientGadget gadget) {