diff --git a/src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java b/src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java index 7bf9384e1..c6ba88b02 100644 --- a/src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java +++ b/src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java @@ -123,7 +123,7 @@ public class DungeonManager { return pointData.getRot() != null ? pointData.getRot() : null; } - public boolean getStatueDrops(Player player, boolean useCondensed) { + public boolean getStatueDrops(Player player, boolean useCondensed, int groupId) { if (!isFinishedSuccessfully() || dungeonData.getRewardPreviewData() == null || dungeonData.getRewardPreviewData().getPreviewItems().length == 0) { return false; } @@ -146,7 +146,7 @@ public class DungeonManager { rewardedPlayers.add(player.getUid()); - scene.getScriptManager().callEvent(new ScriptArgs(EventType.EVENT_DUNGEON_REWARD_GET)); + scene.getScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_DUNGEON_REWARD_GET)); return true; } @@ -280,7 +280,7 @@ public class DungeonManager { p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_FINISH_DUNGEON); } }); - scene.getScriptManager().callEvent(new ScriptArgs(EventType.EVENT_DUNGEON_SETTLE, successfully ? 1 : 0)); + scene.getScriptManager().callEvent(new ScriptArgs(0, EventType.EVENT_DUNGEON_SETTLE, successfully ? 1 : 0)); } public void quitDungeon() { diff --git a/src/main/java/emu/grasscutter/game/dungeons/challenge/WorldChallenge.java b/src/main/java/emu/grasscutter/game/dungeons/challenge/WorldChallenge.java index f7aff3471..459c71666 100644 --- a/src/main/java/emu/grasscutter/game/dungeons/challenge/WorldChallenge.java +++ b/src/main/java/emu/grasscutter/game/dungeons/challenge/WorldChallenge.java @@ -85,10 +85,10 @@ public class WorldChallenge { String.valueOf(getChallengeId()) )); } - + this.getScene().getScriptManager().callEvent( // TODO record the time in PARAM2 and used in action - new ScriptArgs(EventType.EVENT_CHALLENGE_SUCCESS).setParam2(finishedTime)); + new ScriptArgs(getGroupId(), EventType.EVENT_CHALLENGE_SUCCESS).setParam2(finishedTime)); this.getScene().triggerDungeonEvent(DungeonPassConditionType.DUNGEON_COND_FINISH_CHALLENGE, getChallengeId(), getChallengeIndex()); challengeTriggers.forEach(t -> t.onFinish(this)); @@ -99,7 +99,7 @@ public class WorldChallenge { return; } finish(false); - this.getScene().getScriptManager().callEvent(new ScriptArgs(EventType.EVENT_CHALLENGE_FAIL)); + this.getScene().getScriptManager().callEvent(new ScriptArgs(getGroupId(), EventType.EVENT_CHALLENGE_FAIL)); challengeTriggers.forEach(t -> t.onFinish(this)); } diff --git a/src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java b/src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java index 76e81768a..2a5b2a1e3 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java @@ -44,7 +44,7 @@ public abstract class EntityBaseGadget extends GameEntity { @Override public void callLuaHPEvent(EntityDamageEvent event) { super.callLuaHPEvent(event); - getScene().getScriptManager().callEvent(new ScriptArgs(EVENT_SPECIFIC_GADGET_HP_CHANGE, getConfigId(), getGadgetId()) + getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EVENT_SPECIFIC_GADGET_HP_CHANGE, getConfigId(), getGadgetId()) .setSourceEntityId(getId()) .setParam3((int) this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP)) .setEventSource(Integer.toString(getConfigId()))); diff --git a/src/main/java/emu/grasscutter/game/entity/EntityGadget.java b/src/main/java/emu/grasscutter/game/entity/EntityGadget.java index 6ac6d5dc9..7508db1e3 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityGadget.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityGadget.java @@ -111,7 +111,7 @@ public class EntityGadget extends EntityBaseGadget { this.setState(state); ticksSinceChange = getScene().getSceneTimeSeconds(); this.getScene().broadcastPacket(new PacketGadgetStateNotify(this, state)); - getScene().getScriptManager().callEvent(new ScriptArgs(EventType.EVENT_GADGET_STATE_CHANGE, state, this.getConfigId())); + getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EventType.EVENT_GADGET_STATE_CHANGE, state, this.getConfigId())); } @Deprecated(forRemoval = true) // Dont use! @@ -152,7 +152,7 @@ public class EntityGadget extends EntityBaseGadget { @Override public void onCreate() { // Lua event - getScene().getScriptManager().callEvent(new ScriptArgs(EventType.EVENT_GADGET_CREATE, this.getConfigId())); + getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EventType.EVENT_GADGET_CREATE, this.getConfigId())); } @Override @@ -174,7 +174,7 @@ public class EntityGadget extends EntityBaseGadget { if (getScene().getChallenge() != null) { getScene().getChallenge().onGadgetDeath(this); } - getScene().getScriptManager().callEvent(new ScriptArgs(EventType.EVENT_ANY_GADGET_DIE, this.getConfigId())); + getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EventType.EVENT_ANY_GADGET_DIE, this.getConfigId())); SceneGroupInstance groupInstance = getScene().getScriptManager().getCachedGroupInstanceById(this.getGroupId()); if(groupInstance != null && metaGadget != null) diff --git a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java index 44e48e3e8..9ac69c3d2 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java @@ -107,7 +107,7 @@ public class EntityMonster extends GameEntity { @Override public void onCreate() { // Lua event - getScene().getScriptManager().callEvent(new ScriptArgs(EventType.EVENT_ANY_MONSTER_LIVE, this.getConfigId())); + getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EventType.EVENT_ANY_MONSTER_LIVE, this.getConfigId())); } @Override @@ -130,7 +130,7 @@ public class EntityMonster extends GameEntity { @Override public void callLuaHPEvent(EntityDamageEvent event) { super.callLuaHPEvent(event); - getScene().getScriptManager().callEvent(new ScriptArgs(EVENT_SPECIFIC_MONSTER_HP_CHANGE, getConfigId(), monsterData.getId()) + getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EVENT_SPECIFIC_MONSTER_HP_CHANGE, getConfigId(), monsterData.getId()) .setSourceEntityId(getId()) .setParam3((int) this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP)) .setEventSource(Integer.toString(getConfigId()))); @@ -152,11 +152,11 @@ public class EntityMonster extends GameEntity { Optional.ofNullable(scriptManager.getScriptMonsterSpawnService()).ifPresent(s -> s.onMonsterDead(this)); // prevent spawn monster after success - if (challenge.map(c -> c.inProgress()).orElse(true)) { - scriptManager.callEvent(new ScriptArgs(EventType.EVENT_ANY_MONSTER_DIE, this.getConfigId())); + /*if (challenge.map(c -> c.inProgress()).orElse(true)) { + scriptManager.callEvent(new ScriptArgs(EventType.EVENT_ANY_MONSTER_DIE, this.getConfigId()).setGroupId(this.getGroupId())); } else if (getScene().getChallenge() == null) { - scriptManager.callEvent(new ScriptArgs(EventType.EVENT_ANY_MONSTER_DIE, this.getConfigId())); - } + }*/ + scriptManager.callEvent(new ScriptArgs(this.getGroupId(), EventType.EVENT_ANY_MONSTER_DIE, this.getConfigId())); } // Battle Pass trigger scene.getPlayers().forEach(p -> p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_MONSTER_DIE, this.getMonsterId(), 1)); diff --git a/src/main/java/emu/grasscutter/game/entity/gadget/GadgetRewardStatue.java b/src/main/java/emu/grasscutter/game/entity/gadget/GadgetRewardStatue.java index 61eb35a0e..be110b92a 100644 --- a/src/main/java/emu/grasscutter/game/entity/gadget/GadgetRewardStatue.java +++ b/src/main/java/emu/grasscutter/game/entity/gadget/GadgetRewardStatue.java @@ -18,7 +18,7 @@ public class GadgetRewardStatue extends GadgetContent { public boolean onInteract(Player player, GadgetInteractReq req) { if (player.getScene().getDungeonManager() != null || player.getScene().getChallenge() instanceof DungeonChallenge dungeonChallenge) { var useCondensed = req.getResinCostType() == ResinCostTypeOuterClass.ResinCostType.RESIN_COST_TYPE_CONDENSE; - player.getScene().getDungeonManager().getStatueDrops(player, useCondensed); + player.getScene().getDungeonManager().getStatueDrops(player, useCondensed, getGadget().getGroupId()); } player.sendPacket(new PacketGadgetInteractRsp(getGadget(), InteractType.INTERACT_TYPE_OPEN_STATUE)); diff --git a/src/main/java/emu/grasscutter/game/entity/gadget/chest/BossChestInteractHandler.java b/src/main/java/emu/grasscutter/game/entity/gadget/chest/BossChestInteractHandler.java index 91738d654..f6d3a884d 100644 --- a/src/main/java/emu/grasscutter/game/entity/gadget/chest/BossChestInteractHandler.java +++ b/src/main/java/emu/grasscutter/game/entity/gadget/chest/BossChestInteractHandler.java @@ -38,7 +38,7 @@ public class BossChestInteractHandler implements ChestInteractHandler{ var dungeonManager = player.getScene().getDungeonManager(); if(dungeonManager != null){ - return dungeonManager.getStatueDrops(player, useCondensedResin); + return dungeonManager.getStatueDrops(player, useCondensedResin, chest.getGadget().getGroupId()); } Grasscutter.getLogger().warn("Could not found the reward of boss monster {}", monster.monster_id); return false; diff --git a/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java b/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java index e85c4365c..a45c76a91 100644 --- a/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java +++ b/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java @@ -247,7 +247,7 @@ public class PlayerProgressManager extends BasePlayerDataManager { // Fire quest and script trigger for trans point unlock. this.player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_UNLOCK_TRANS_POINT, sceneId, pointId); - this.player.getScene().getScriptManager().callEvent(new ScriptArgs(EVENT_UNLOCK_TRANS_POINT, sceneId, pointId)); + this.player.getScene().getScriptManager().callEvent(new ScriptArgs(0, EVENT_UNLOCK_TRANS_POINT, sceneId, pointId)); // Send packet. this.player.sendPacket(new PacketScenePointUnlockNotify(sceneId, pointId)); diff --git a/src/main/java/emu/grasscutter/game/quest/exec/ExecNotifyGroupLua.java b/src/main/java/emu/grasscutter/game/quest/exec/ExecNotifyGroupLua.java index 051a7c131..c2f09bb32 100644 --- a/src/main/java/emu/grasscutter/game/quest/exec/ExecNotifyGroupLua.java +++ b/src/main/java/emu/grasscutter/game/quest/exec/ExecNotifyGroupLua.java @@ -39,7 +39,7 @@ public class ExecNotifyGroupLua extends QuestExecHandler { val eventType = quest.getState() == QuestState.QUEST_STATE_FINISHED ? EventType.EVENT_QUEST_FINISH : EventType.EVENT_QUEST_START; scriptManager.callEvent( - new ScriptArgs(eventType, quest.getSubQuestId())); + new ScriptArgs(groupId, eventType, quest.getSubQuestId())); }); return true; diff --git a/src/main/java/emu/grasscutter/game/world/Scene.java b/src/main/java/emu/grasscutter/game/world/Scene.java index 40c29038a..90f4f3f06 100644 --- a/src/main/java/emu/grasscutter/game/world/Scene.java +++ b/src/main/java/emu/grasscutter/game/world/Scene.java @@ -813,7 +813,7 @@ public class Scene { } scriptManager.meetEntities(entities); - groups.forEach(g -> scriptManager.callEvent(new ScriptArgs(EventType.EVENT_GROUP_LOAD, g.id))); + groups.forEach(g -> scriptManager.callEvent(new ScriptArgs(g.id, EventType.EVENT_GROUP_LOAD, g.id))); Grasscutter.getLogger().info("Scene {} loaded {} group(s)", this.getId(), groups.size()); } diff --git a/src/main/java/emu/grasscutter/game/world/SceneGroupInstance.java b/src/main/java/emu/grasscutter/game/world/SceneGroupInstance.java index 6e7efdccb..1e46791ca 100644 --- a/src/main/java/emu/grasscutter/game/world/SceneGroupInstance.java +++ b/src/main/java/emu/grasscutter/game/world/SceneGroupInstance.java @@ -48,6 +48,9 @@ public class SceneGroupInstance { this.isCached = false; //This is true when the group is not loaded on scene but caches suite data } + SceneGroupInstance(){ + this.cachedVariables = new ConcurrentHashMap<>(); + } public void setLuaGroup(SceneGroup group) { this.luaGroup = group; diff --git a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java index bbfe7ecd2..e52c6110b 100644 --- a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java +++ b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java @@ -36,6 +36,7 @@ import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.CoerceJavaToLua; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.io.FileWriter; import java.io.IOException; @@ -119,6 +120,7 @@ public class SceneScriptManager { return meta.blocks; } + @Nullable public Map getVariables(int group_id) { if(getCachedGroupInstanceById(group_id) == null) return null; return getCachedGroupInstanceById(group_id).getCachedVariables(); @@ -473,9 +475,10 @@ public class SceneScriptManager { } if (group.variables != null) { - group.variables.forEach(var -> { - if(!this.getVariables(group.id).containsKey(var.name)) - this.getVariables(group.id).put(var.name, var.value); + group.variables.forEach(variable -> { + val variables = this.getVariables(group.id); + if(variables != null && !variables.containsKey(variable.name)) + variables.put(variable.name, variable.value); }); } } @@ -506,7 +509,7 @@ public class SceneScriptManager { if (region.hasNewEntities()) { Grasscutter.getLogger().trace("Call EVENT_ENTER_REGION_{}",region.getMetaRegion().config_id); - callEvent(new ScriptArgs(EventType.EVENT_ENTER_REGION, region.getConfigId()) + callEvent(new ScriptArgs(region.getGroupId(), EventType.EVENT_ENTER_REGION, region.getConfigId()) .setSourceEntityId(region.getId()) .setTargetEntityId(targetID) ); @@ -521,7 +524,7 @@ public class SceneScriptManager { } } if (region.entityLeave()) { - callEvent(new ScriptArgs(EventType.EVENT_LEAVE_REGION, region.getConfigId()) + callEvent(new ScriptArgs(region.getGroupId(), EventType.EVENT_LEAVE_REGION, region.getConfigId()) .setSourceEntityId(region.getId()) .setTargetEntityId(region.getFirstEntityId()) ); @@ -621,8 +624,8 @@ public class SceneScriptManager { } } // Events - public void callEvent(int eventType) { - callEvent(new ScriptArgs(eventType)); + public void callEvent(int groupId, int eventType) { + callEvent(new ScriptArgs(groupId, eventType)); } public void callEvent(@Nonnull ScriptArgs params) { /** @@ -644,7 +647,11 @@ public class SceneScriptManager { .filter(p -> p.getCondition().contains(String.valueOf(params.param1)) && (p.getSource().isEmpty() || p.getSource().equals(params.getEventSource()))).toList(); relevantTriggers = new HashSet<>(relevantTriggersList); - } else {relevantTriggers = new HashSet<>(this.getTriggersByEvent(eventType));} + } else { + relevantTriggers = this.getTriggersByEvent(eventType).stream() + .filter(t -> params.getGroupId() == 0 || t.getCurrentGroup().id == params.getGroupId()) + .collect(Collectors.toSet()); + } for (SceneTrigger trigger : relevantTriggers) { handleEventForTrigger(params, trigger); } @@ -909,7 +916,7 @@ public class SceneScriptManager { Grasscutter.getLogger().warn("[LUA] Found timer trigger with source {} for group {} : {}", source, groupID, trigger.getName()); var taskIdentifier = Grasscutter.getGameServer().getScheduler().scheduleDelayedRepeatingTask(() -> - callEvent(new ScriptArgs(EVENT_TIMER_EVENT) + callEvent(new ScriptArgs(groupID, EVENT_TIMER_EVENT) .setEventSource(source)), (int)time, (int)time); var groupTasks = activeGroupTimers.computeIfAbsent(groupID, k -> new HashSet<>()); groupTasks.add(new Pair<>(source, taskIdentifier)); diff --git a/src/main/java/emu/grasscutter/scripts/ScriptLib.java b/src/main/java/emu/grasscutter/scripts/ScriptLib.java index f61343a22..6235cde88 100644 --- a/src/main/java/emu/grasscutter/scripts/ScriptLib.java +++ b/src/main/java/emu/grasscutter/scripts/ScriptLib.java @@ -393,20 +393,27 @@ public class ScriptLib { logger.debug("[LUA] Call SetGroupVariableValue with {},{}", var, value); - val old = getSceneScriptManager().getVariables(currentGroup.get().id).getOrDefault(var, value); - getSceneScriptManager().getVariables(currentGroup.get().id).put(var, value); - getSceneScriptManager().callEvent(new ScriptArgs(EventType.EVENT_VARIABLE_CHANGE, value, old)); + val groupId= currentGroup.get().id; + val variables = getSceneScriptManager().getVariables(groupId); + + val old = variables.getOrDefault(var, value); + variables.put(var, value); + getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, value, old)); return 0; } public LuaValue ChangeGroupVariableValue(String var, int value) { logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}", var, value); - val old = getSceneScriptManager().getVariables(currentGroup.get().id).getOrDefault(var, 0); - getSceneScriptManager().getVariables(currentGroup.get().id).put(var, old + value); + + val groupId= currentGroup.get().id; + val variables = getSceneScriptManager().getVariables(groupId); + + val old = variables.getOrDefault(var, 0); + variables.put(var, old + value); logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}", old, old+value); - getSceneScriptManager().callEvent(new ScriptArgs(EventType.EVENT_VARIABLE_CHANGE, old+value, old)); + getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, old+value, old)); return LuaValue.ZERO; } diff --git a/src/main/java/emu/grasscutter/scripts/data/ScriptArgs.java b/src/main/java/emu/grasscutter/scripts/data/ScriptArgs.java index 75d3ccf3b..a072c32ec 100644 --- a/src/main/java/emu/grasscutter/scripts/data/ScriptArgs.java +++ b/src/main/java/emu/grasscutter/scripts/data/ScriptArgs.java @@ -6,21 +6,23 @@ public class ScriptArgs { public int param3; public int source_eid; // Source entity public int target_eid; + public int group_id; public String source; // source string, used for timers public int type; // lua event type, used by scripts and the ScriptManager - public ScriptArgs(int eventType) { - this(eventType, 0,0); + public ScriptArgs(int groupId, int eventType) { + this(groupId, eventType, 0,0); } - public ScriptArgs(int eventType, int param1) { - this(eventType, param1,0); + public ScriptArgs(int groupId, int eventType, int param1) { + this(groupId, eventType, param1,0); } - public ScriptArgs(int eventType, int param1, int param2) { + public ScriptArgs(int groupId, int eventType, int param1, int param2) { this.type = eventType; this.param1 = param1; this.param2 = param2; + this.group_id = groupId; } public int getParam1() { @@ -76,4 +78,13 @@ public class ScriptArgs { this.source = source; return this; } + + public int getGroupId() { + return group_id; + } + + public ScriptArgs setGroupId(int group_id) { + this.group_id = group_id; + return this; + } } diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerSelectWorktopOptionReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerSelectWorktopOptionReq.java index 24a2bdc04..c767f32d5 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerSelectWorktopOptionReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerSelectWorktopOptionReq.java @@ -27,7 +27,7 @@ public class HandlerSelectWorktopOptionReq extends PacketHandler { } session.getPlayer().getScene().selectWorktopOptionWith(req); session.getPlayer().getScene().getScriptManager().callEvent( - new ScriptArgs(EventType.EVENT_SELECT_OPTION, entity.getConfigId(), req.getOptionId()) + new ScriptArgs(entity.getGroupId(), EventType.EVENT_SELECT_OPTION, entity.getConfigId(), req.getOptionId()) ); session.getPlayer().getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_WORKTOP_SELECT, entity.getConfigId(), req.getOptionId()); } finally {