diff --git a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java index be5812a1d..c9d0c0982 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java @@ -23,6 +23,7 @@ import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo; import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo; import emu.grasscutter.net.proto.SceneMonsterInfoOuterClass.SceneMonsterInfo; import emu.grasscutter.net.proto.SceneWeaponInfoOuterClass.SceneWeaponInfo; +import emu.grasscutter.scripts.constants.EventType; import emu.grasscutter.utils.Position; import emu.grasscutter.utils.ProtoHelper; import it.unimi.dsi.fastutil.ints.Int2FloatMap; @@ -115,6 +116,9 @@ public class EntityMonster extends GameEntity { if (this.getSpawnEntry() != null) { this.getScene().getDeadSpawnedEntities().add(getSpawnEntry()); } + if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) { + getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, null); + } if (getScene().getChallenge() != null && getScene().getChallenge().getGroup().id == this.getGroupId()) { getScene().getChallenge().onMonsterDie(this); } diff --git a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java index 6d0d1e845..5413021ea 100644 --- a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java +++ b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import javax.script.Bindings; @@ -33,6 +34,7 @@ import emu.grasscutter.scripts.data.SceneInitConfig; import emu.grasscutter.scripts.data.SceneMonster; import emu.grasscutter.scripts.data.SceneSuite; import emu.grasscutter.scripts.data.SceneTrigger; +import emu.grasscutter.scripts.data.SceneVar; import emu.grasscutter.scripts.data.ScriptArgs; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -41,8 +43,9 @@ public class SceneScriptManager { private final Scene scene; private final ScriptLib scriptLib; private final LuaValue scriptLibLua; - private Bindings bindings; + private final Map variables; + private Bindings bindings; private SceneConfig config; private List blocks; private Int2ObjectOpenHashMap> triggers; @@ -53,6 +56,7 @@ public class SceneScriptManager { this.scriptLib = new ScriptLib(this); this.scriptLibLua = CoerceJavaToLua.coerce(this.scriptLib); this.triggers = new Int2ObjectOpenHashMap<>(); + this.variables = new HashMap<>(); // TEMPORARY if (this.getScene().getId() < 10) { @@ -87,6 +91,10 @@ public class SceneScriptManager { return blocks; } + public Map getVariables() { + return variables; + } + public Set getTriggersByEvent(int eventId) { return triggers.computeIfAbsent(eventId, e -> new HashSet<>()); } @@ -203,6 +211,9 @@ public class SceneScriptManager { group.triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, bindings.get("triggers")); group.suites = ScriptLoader.getSerializer().toList(SceneSuite.class, bindings.get("suites")); group.init_config = ScriptLoader.getSerializer().toObject(SceneInitConfig.class, bindings.get("init_config")); + + List variables = ScriptLoader.getSerializer().toList(SceneVar.class, bindings.get("variables")); + variables.forEach(var -> this.getVariables().put(var.name, LuaValue.valueOf(var.value))); } catch (ScriptException e) { Grasscutter.getLogger().error("Error loading group " + group.id + " in scene " + getScene().getId(), e); } diff --git a/src/main/java/emu/grasscutter/scripts/ScriptLib.java b/src/main/java/emu/grasscutter/scripts/ScriptLib.java index a4559086c..9a20359e5 100644 --- a/src/main/java/emu/grasscutter/scripts/ScriptLib.java +++ b/src/main/java/emu/grasscutter/scripts/ScriptLib.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Optional; import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; import emu.grasscutter.Grasscutter; import emu.grasscutter.data.GameData; @@ -120,7 +121,7 @@ public class ScriptLib { return 0; } - public int AddExtraGroupSuite(int groupId, int param2) { + public int AddExtraGroupSuite(int groupId, int suite) { SceneGroup group = getSceneScriptManager().getGroupById(groupId); if (group == null || group.monsters == null) { @@ -151,8 +152,35 @@ public class ScriptLib { return 0; } + public int GetGroupMonsterCountByGroupId(int groupId) { + return (int) getSceneScriptManager().getScene().getEntities().values().stream() + .filter(e -> e instanceof EntityMonster && e.getGroupId() == groupId) + .count(); + } + + public LuaValue GetGroupVariableValue(String var) { + return getSceneScriptManager().getVariables().getOrDefault(var, LuaValue.NIL); + } + + public LuaValue ChangeGroupVariableValue(String var, LuaValue value) { + getSceneScriptManager().getVariables().put(var, value); + return LuaValue.ZERO; + } + public int RefreshGroup(LuaTable table) { - // Add group back to suite + // Kill and Respawn? + int groupId = table.get("group_id").toint(); + int suite = table.get("suite").toint(); + + SceneGroup group = getSceneScriptManager().getGroupById(groupId); + + if (group == null || group.monsters == null) { + return 1; + } + + // TODO just spawn all from group for now + this.getSceneScriptManager().spawnMonstersInGroup(group); + return 0; } diff --git a/src/main/java/emu/grasscutter/scripts/data/SceneVar.java b/src/main/java/emu/grasscutter/scripts/data/SceneVar.java new file mode 100644 index 000000000..9ead6f474 --- /dev/null +++ b/src/main/java/emu/grasscutter/scripts/data/SceneVar.java @@ -0,0 +1,7 @@ +package emu.grasscutter.scripts.data; + +public class SceneVar { + public String name; + public int value; + public boolean no_refresh; +}