[Fix,LUA] most events are now limited to only their source group and fixes some group variable null handling

This commit is contained in:
hartie95 2023-02-07 02:49:21 +01:00
parent 63da8bf420
commit 5b64ff92d4
15 changed files with 70 additions and 42 deletions

View File

@ -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() {

View File

@ -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));
}

View File

@ -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())));

View File

@ -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)

View File

@ -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));

View File

@ -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));

View File

@ -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;

View File

@ -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));

View File

@ -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;

View File

@ -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());
}

View File

@ -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;

View File

@ -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<String, Integer> 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));

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 {