Commit 7e377dff authored by Melledy's avatar Melledy
Browse files

Implement script region check

parent 1ed46df6
...@@ -34,6 +34,10 @@ public abstract class GameEntity { ...@@ -34,6 +34,10 @@ public abstract class GameEntity {
return this.id; return this.id;
} }
public int getEntityType() {
return getId() >> 24;
}
public World getWorld() { public World getWorld() {
return this.getScene().getWorld(); return this.getScene().getWorld();
} }
......
...@@ -508,6 +508,7 @@ public class Scene { ...@@ -508,6 +508,7 @@ public class Scene {
} }
group.triggers.forEach(getScriptManager()::registerTrigger); group.triggers.forEach(getScriptManager()::registerTrigger);
group.regions.forEach(getScriptManager()::registerRegion);
} }
// Spawn gadgets AFTER triggers are added // Spawn gadgets AFTER triggers are added
...@@ -526,6 +527,7 @@ public class Scene { ...@@ -526,6 +527,7 @@ public class Scene {
for (SceneGroup group : block.groups) { for (SceneGroup group : block.groups) {
group.triggers.forEach(getScriptManager()::deregisterTrigger); group.triggers.forEach(getScriptManager()::deregisterTrigger);
group.regions.forEach(getScriptManager()::deregisterRegion);
} }
} }
......
...@@ -35,6 +35,7 @@ import emu.grasscutter.scripts.data.SceneGadget; ...@@ -35,6 +35,7 @@ import emu.grasscutter.scripts.data.SceneGadget;
import emu.grasscutter.scripts.data.SceneGroup; import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneInitConfig; import emu.grasscutter.scripts.data.SceneInitConfig;
import emu.grasscutter.scripts.data.SceneMonster; import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.scripts.data.SceneRegion;
import emu.grasscutter.scripts.data.SceneSuite; import emu.grasscutter.scripts.data.SceneSuite;
import emu.grasscutter.scripts.data.SceneTrigger; import emu.grasscutter.scripts.data.SceneTrigger;
import emu.grasscutter.scripts.data.SceneVar; import emu.grasscutter.scripts.data.SceneVar;
...@@ -51,14 +52,17 @@ public class SceneScriptManager { ...@@ -51,14 +52,17 @@ public class SceneScriptManager {
private Bindings bindings; private Bindings bindings;
private SceneConfig config; private SceneConfig config;
private List<SceneBlock> blocks; private List<SceneBlock> blocks;
private Int2ObjectOpenHashMap<Set<SceneTrigger>> triggers;
private boolean isInit; private boolean isInit;
private final Int2ObjectOpenHashMap<Set<SceneTrigger>> triggers;
private final Int2ObjectOpenHashMap<SceneRegion> regions;
public SceneScriptManager(Scene scene) { public SceneScriptManager(Scene scene) {
this.scene = scene; this.scene = scene;
this.scriptLib = new ScriptLib(this); this.scriptLib = new ScriptLib(this);
this.scriptLibLua = CoerceJavaToLua.coerce(this.scriptLib); this.scriptLibLua = CoerceJavaToLua.coerce(this.scriptLib);
this.triggers = new Int2ObjectOpenHashMap<>(); this.triggers = new Int2ObjectOpenHashMap<>();
this.regions = new Int2ObjectOpenHashMap<>();
this.variables = new HashMap<>(); this.variables = new HashMap<>();
// TEMPORARY // TEMPORARY
...@@ -110,6 +114,18 @@ public class SceneScriptManager { ...@@ -110,6 +114,18 @@ public class SceneScriptManager {
getTriggersByEvent(trigger.event).remove(trigger); getTriggersByEvent(trigger.event).remove(trigger);
} }
public SceneRegion getRegionById(int id) {
return regions.get(id);
}
public void registerRegion(SceneRegion region) {
regions.put(region.config_id, region);
}
public void deregisterRegion(SceneRegion region) {
regions.remove(region.config_id);
}
// TODO optimize // TODO optimize
public SceneGroup getGroupById(int groupId) { public SceneGroup getGroupById(int groupId) {
for (SceneBlock block : this.getScene().getLoadedBlocks()) { for (SceneBlock block : this.getScene().getLoadedBlocks()) {
...@@ -210,6 +226,7 @@ public class SceneScriptManager { ...@@ -210,6 +226,7 @@ public class SceneScriptManager {
group.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, bindings.get("gadgets")); group.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, bindings.get("gadgets"));
group.triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, bindings.get("triggers")); group.triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, bindings.get("triggers"));
group.suites = ScriptLoader.getSerializer().toList(SceneSuite.class, bindings.get("suites")); group.suites = ScriptLoader.getSerializer().toList(SceneSuite.class, bindings.get("suites"));
group.regions = ScriptLoader.getSerializer().toList(SceneRegion.class, bindings.get("regions"));
group.init_config = ScriptLoader.getSerializer().toObject(SceneInitConfig.class, bindings.get("init_config")); group.init_config = ScriptLoader.getSerializer().toObject(SceneInitConfig.class, bindings.get("init_config"));
// Add variables to suite // Add variables to suite
...@@ -234,11 +251,27 @@ public class SceneScriptManager { ...@@ -234,11 +251,27 @@ public class SceneScriptManager {
} }
public void onTick() { public void onTick() {
checkTriggers(); checkRegions();
} }
public void checkTriggers() { public void checkRegions() {
if (this.regions.size() == 0) {
return;
}
for (SceneRegion region : this.regions.values()) {
getScene().getEntities().values()
.stream()
.filter(e -> e.getEntityType() <= 2 && region.contains(e.getPosition()))
.forEach(region::addEntity);
if (region.hasNewEntities()) {
// This is not how it works, source_eid should be region entity id, but we dont have an entity for regions yet
callEvent(EventType.EVENT_ENTER_REGION, new ScriptArgs(region.config_id).setSourceEntityId(region.config_id));
region.resetNewEntities();
}
}
} }
public void spawnGadgetsInGroup(SceneGroup group) { public void spawnGadgetsInGroup(SceneGroup group) {
......
...@@ -17,6 +17,7 @@ import emu.grasscutter.game.entity.GameEntity; ...@@ -17,6 +17,7 @@ import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.scripts.constants.EventType; import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneGroup; import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneMonster; import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.scripts.data.SceneRegion;
import emu.grasscutter.scripts.data.ScriptArgs; import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify; import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
import emu.grasscutter.server.packet.send.PacketWorktopOptionNotify; import emu.grasscutter.server.packet.send.PacketWorktopOptionNotify;
...@@ -184,6 +185,19 @@ public class ScriptLib { ...@@ -184,6 +185,19 @@ public class ScriptLib {
return 0; return 0;
} }
public int GetRegionEntityCount(LuaTable table) {
int regionId = table.get("region_eid").toint();
int entityType = table.get("entity_type").toint();
SceneRegion region = this.getSceneScriptManager().getRegionById(regionId);
if (region == null) {
return 0;
}
return (int) region.getEntities().intStream().filter(e -> e >> 24 == entityType).count();
}
public void PrintContextLog(String msg) { public void PrintContextLog(String msg) {
Grasscutter.getLogger().info("[LUA] " + msg); Grasscutter.getLogger().info("[LUA] " + msg);
} }
......
...@@ -14,6 +14,7 @@ public class SceneGroup { ...@@ -14,6 +14,7 @@ public class SceneGroup {
public List<SceneMonster> monsters; public List<SceneMonster> monsters;
public List<SceneGadget> gadgets; public List<SceneGadget> gadgets;
public List<SceneTrigger> triggers; public List<SceneTrigger> triggers;
public List<SceneRegion> regions;
public List<SceneSuite> suites; public List<SceneSuite> suites;
public SceneInitConfig init_config; public SceneInitConfig init_config;
......
package emu.grasscutter.scripts.data;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.scripts.constants.ScriptRegionShape;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
public class SceneRegion {
public int config_id;
public int shape;
public Position pos;
public Position size;
private boolean hasNewEntities;
private final IntSet entities; // Ids of entities inside this region
public SceneRegion() {
this.entities = new IntOpenHashSet();
}
public IntSet getEntities() {
return entities;
}
public void addEntity(GameEntity entity) {
if (this.getEntities().contains(entity.getId())) {
return;
}
this.getEntities().add(entity.getId());
this.hasNewEntities = true;
}
public void removeEntity(GameEntity entity) {
this.getEntities().remove(entity.getId());
}
public boolean contains(Position p) {
switch (shape) {
case ScriptRegionShape.CUBIC:
return (Math.abs(pos.getX() - p.getX()) <= size.getX()) &&
(Math.abs(pos.getZ() - p.getZ()) <= size.getZ());
case ScriptRegionShape.SPHERE:
return false;
}
return false;
}
public boolean hasNewEntities() {
return hasNewEntities;
}
public void resetNewEntities() {
hasNewEntities = false;
}
}
...@@ -4,6 +4,7 @@ public class ScriptArgs { ...@@ -4,6 +4,7 @@ public class ScriptArgs {
public int param1; public int param1;
public int param2; public int param2;
public int param3; public int param3;
public int source_eid; // Source entity
public ScriptArgs() { public ScriptArgs() {
...@@ -44,4 +45,13 @@ public class ScriptArgs { ...@@ -44,4 +45,13 @@ public class ScriptArgs {
this.param3 = param3; this.param3 = param3;
return this; return this;
} }
public int getSourceEntityId() {
return source_eid;
}
public ScriptArgs setSourceEntityId(int source_eid) {
this.source_eid = source_eid;
return this;
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment