mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-27 21:10:54 +00:00
Implement script region check
This commit is contained in:
parent
202361f2bf
commit
b140c7f5bf
@ -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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
|
|
||||||
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;
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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;
|
||||||
|
|
||||||
|
57
src/main/java/emu/grasscutter/scripts/data/SceneRegion.java
Normal file
57
src/main/java/emu/grasscutter/scripts/data/SceneRegion.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
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 {
|
|||||||
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 {
|
|||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user