Nazrin 9d94888da3
Fix race condition with worktops (#2216)
* Fix race condition with worktops

* Update ScriptLib.java

* Update ScriptLib.java

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2023-06-17 11:00:10 -04:00

1625 lines
59 KiB
Java

package emu.grasscutter.scripts;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.game.activity.ActivityManager;
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
import emu.grasscutter.game.dungeons.challenge.enums.FatherChallengeProperty;
import emu.grasscutter.game.dungeons.challenge.factory.ChallengeFactory;
import emu.grasscutter.game.entity.*;
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
import emu.grasscutter.game.entity.gadget.platform.ConfigRoute;
import emu.grasscutter.game.entity.gadget.platform.PointArrayRoute;
import emu.grasscutter.game.props.ClimateType;
import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.props.EntityType;
import emu.grasscutter.game.quest.enums.QuestCond;
import emu.grasscutter.game.quest.enums.QuestContent;
import emu.grasscutter.game.quest.enums.QuestState;
import emu.grasscutter.game.world.SceneGroupInstance;
import emu.grasscutter.net.proto.EnterTypeOuterClass;
import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.constants.GroupKillPolicy;
import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneObject;
import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.game.world.Position;
import io.netty.util.concurrent.FastThreadLocal;
import lombok.val;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.util.*;
import static emu.grasscutter.game.props.EnterReason.Lua;
import static emu.grasscutter.scripts.ScriptUtils.luaToPos;
import static emu.grasscutter.scripts.ScriptUtils.posToLua;
import static emu.grasscutter.scripts.constants.GroupKillPolicy.*;
@SuppressWarnings("unused")
public class ScriptLib {
public static final Logger logger = LoggerFactory.getLogger(ScriptLib.class);
private final FastThreadLocal<SceneScriptManager> sceneScriptManager;
private final FastThreadLocal<SceneGroup> currentGroup;
private final FastThreadLocal<ScriptArgs> callParams;
private final FastThreadLocal<GameEntity> currentEntity;
public ScriptLib() {
this.sceneScriptManager = new FastThreadLocal<>();
this.currentGroup = new FastThreadLocal<>();
this.callParams = new FastThreadLocal<>();
this.currentEntity = new FastThreadLocal<>();
}
public void setSceneScriptManager(SceneScriptManager sceneScriptManager){
this.sceneScriptManager.set(sceneScriptManager);
}
public void removeSceneScriptManager(){
this.sceneScriptManager.remove();
}
public SceneScriptManager getSceneScriptManager() {
// normally not null
return Optional.of(sceneScriptManager.get()).get();
}
private String printTable(LuaTable table){
StringBuilder sb = new StringBuilder();
sb.append("{");
for(var meta : table.keys()){
sb.append(meta).append(":").append(table.get(meta)).append(",");
}
sb.append("}");
return sb.toString();
}
public void setCurrentGroup(SceneGroup currentGroup){
this.currentGroup.set(currentGroup);
}
public void setCurrentCallParams(ScriptArgs callArgs){
this.callParams.set(callArgs);
}
public Optional<SceneGroup> getCurrentGroup(){
return Optional.of(this.currentGroup.get());
}
public void removeCurrentGroup(){
this.currentGroup.remove();
}
public void setCurrentEntity(GameEntity currentGroup){
this.currentEntity.set(currentGroup);
}
public void removeCurrentEntity(){
this.currentEntity.remove();
}
public Optional<GameEntity> getCurrentEntity(){
return Optional.of(this.currentEntity.get());
}
public int SetGadgetStateByConfigId(int configId, int gadgetState) {
logger.debug("[LUA] Call SetGadgetStateByConfigId with {},{}",
configId,gadgetState);
GameEntity entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
if (!(entity instanceof EntityGadget gadget)) {
return 1;
}
gadget.updateState(gadgetState);
return 0;
}
public int SetGroupGadgetStateByConfigId(int groupId, int configId, int gadgetState) {
logger.debug("[LUA] Call SetGroupGadgetStateByConfigId with {},{},{}",
groupId,configId,gadgetState);
val entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
if(!(entity instanceof EntityGadget gadget)){
return -1;
}
gadget.updateState(gadgetState);
return 0;
}
public int SetWorktopOptionsByGroupId(int groupId, int configId, int[] options) {
logger.debug("[LUA] Call SetWorktopOptionsByGroupId with {},{},{}",
groupId, configId, options);
val entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
if (!(entity instanceof EntityGadget gadget)) {
return 1;
}
if (!(gadget.getContent() instanceof GadgetWorktop worktop)) {
return 2;
}
worktop.addWorktopOptions(options);
this.getSceneScriptManager().getScene()
.broadcastPacket(new PacketWorktopOptionNotify(gadget));
return 0;
}
public int SetWorktopOptions(LuaTable table){
logger.debug("[LUA] Call SetWorktopOptions with {}", printTable(table));
var callParams = this.callParams.getIfExists();
var group = this.currentGroup.getIfExists();
if (callParams == null || group == null) {
return 1;
}
var configId = callParams.param1;
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
var worktopOptions = new int[table.length()];
for (int i = 1; i<=table.length(); i++) {
worktopOptions[i-1] = table.get(i).optint(-1);
}
if (!(entity instanceof EntityGadget gadget) || worktopOptions.length == 0) {
return 2;
}
if (!(gadget.getContent() instanceof GadgetWorktop worktop)) {
return 3;
}
worktop.addWorktopOptions(worktopOptions);
// Done in order to synchronize with addEntities in Scene.class.
synchronized (this.getSceneScriptManager().getScene()) {
scene.broadcastPacket(new PacketWorktopOptionNotify(gadget));
}
return 0;
}
public int DelWorktopOptionByGroupId(int groupId, int configId, int option) {
logger.debug("[LUA] Call DelWorktopOptionByGroupId with {},{},{}",groupId,configId,option);
val entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
if (!(entity instanceof EntityGadget gadget)) {
return 1;
}
if (!(gadget.getContent() instanceof GadgetWorktop worktop)) {
return 1;
}
worktop.removeWorktopOption(option);
getSceneScriptManager().getScene().broadcastPacket(new PacketWorktopOptionNotify(gadget));
return 0;
}
public int DelWorktopOption(int var1){
logger.warn("[LUA] Call unimplemented DelWorktopOption with {}", var1);
var callParams = this.callParams.getIfExists();
var group = this.currentGroup.getIfExists();
if(callParams == null || group == null){
return 1;
}
var configId = callParams.param1;
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
if (!(entity instanceof EntityGadget gadget)) {
return 1;
}
if (!(gadget.getContent() instanceof GadgetWorktop worktop)) {
return 2;
}
worktop.removeWorktopOption(callParams.param2);
var scene = getSceneScriptManager().getScene();
Grasscutter.getGameServer().getScheduler().scheduleDelayedTask(() -> {
scene.broadcastPacket(new PacketWorktopOptionNotify(gadget));
},1);
return 0;
}
// Some fields are guessed
public int AutoMonsterTide(int challengeIndex, int groupId, Integer[] ordersConfigId, int tideCount, int sceneLimit, int param6) {
logger.debug("[LUA] Call AutoMonsterTide with {},{},{},{},{},{}",
challengeIndex,groupId,ordersConfigId,tideCount,sceneLimit,param6);
SceneGroup group = getSceneScriptManager().getGroupById(groupId);
if (group == null || group.monsters == null) {
return 1;
}
this.getSceneScriptManager().startMonsterTideInGroup(group, ordersConfigId, tideCount, sceneLimit);
return 0;
}
public int AddExtraGroupSuite(int groupId, int suite) {
logger.debug("[LUA] Call AddExtraGroupSuite with {},{}",
groupId,suite);
SceneGroup group = getSceneScriptManager().getGroupById(groupId);
SceneGroupInstance groupInstance = getSceneScriptManager().getGroupInstanceById(groupId);
if (group == null || groupInstance == null || group.monsters == null) {
return 1;
}
var suiteData = group.getSuiteByIndex(suite);
if(suiteData == null){
Grasscutter.getLogger().warn("trying to get suite that doesn't exist: {} {}", groupId, suite);
return 1;
}
// avoid spawn wrong monster
if(getSceneScriptManager().getScene().getChallenge() != null)
if(!getSceneScriptManager().getScene().getChallenge().inProgress() ||
getSceneScriptManager().getScene().getChallenge().getGroup().id != groupId){
return 0;
}
this.getSceneScriptManager().addGroupSuite(groupInstance, suiteData);
return 0;
}
public int GoToGroupSuite(int groupId, int suite) {
logger.debug("[LUA] Call GoToGroupSuite with {},{}",
groupId,suite);
SceneGroup group = getSceneScriptManager().getGroupById(groupId);
SceneGroupInstance groupInstance = getSceneScriptManager().getGroupInstanceById(groupId);
if (group == null || groupInstance == null || group.monsters == null) {
return 1;
}
var suiteData = group.getSuiteByIndex(suite);
if(suiteData == null){
return 1;
}
/*for(var suiteItem : group.suites){
if(suiteData == suiteItem){
continue;
}
this.getSceneScriptManager().removeGroupSuite(group, suiteItem);
}*/
if(groupInstance.getActiveSuiteId() == 0 || groupInstance.getActiveSuiteId() != suite) {
groupInstance.getDeadEntities().clear();
this.getSceneScriptManager().addGroupSuite(groupInstance, suiteData);
groupInstance.setActiveSuiteId(suite);
}
return 0;
}
public int RemoveExtraGroupSuite(int groupId, int suite) {
logger.debug("[LUA] Call RemoveExtraGroupSuite with {},{}",
groupId,suite);
SceneGroup group = getSceneScriptManager().getGroupById(groupId);
if (group == null || group.monsters == null) {
return 1;
}
var suiteData = group.getSuiteByIndex(suite);
if(suiteData == null){
return 1;
}
this.getSceneScriptManager().removeGroupSuite(group, suiteData);
return 0;
}
public int KillExtraGroupSuite(int groupId, int suite) {
logger.debug("[LUA] Call KillExtraGroupSuite with {},{}",
groupId,suite);
SceneGroup group = getSceneScriptManager().getGroupById(groupId);
if (group == null || group.monsters == null) {
return 1;
}
var suiteData = group.getSuiteByIndex(suite);
if(suiteData == null){
return 1;
}
this.getSceneScriptManager().killGroupSuite(group, suiteData);
return 0;
}
// param3 (probably time limit for timed dungeons)
public int ActiveChallenge(int challengeId, int challengeIndex, int timeLimitOrGroupId, int groupId, int objectiveKills, int param5) {
logger.debug("[LUA] Call ActiveChallenge with {},{},{},{},{},{}",
challengeId,challengeIndex,timeLimitOrGroupId,groupId,objectiveKills,param5);
var challenge = ChallengeFactory.getChallenge(
challengeId,
challengeIndex,
timeLimitOrGroupId,
groupId,
objectiveKills,
param5,
getSceneScriptManager().getScene(),
getCurrentGroup().get()
);
if(challenge == null){
return 1;
}
if(challenge instanceof DungeonChallenge dungeonChallenge){
// set if tower first stage (6-1)
dungeonChallenge.setStage(getSceneScriptManager().getVariables(groupId).getOrDefault("stage", -1) == 0);
}
getSceneScriptManager().getScene().setChallenge(challenge);
challenge.start();
return 0;
}
public int GetGroupMonsterCountByGroupId(int groupId) {
logger.debug("[LUA] Call GetGroupMonsterCountByGroupId with {}",
groupId);
return (int) getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e instanceof EntityMonster && e.getGroupId() == groupId)
.count();
}
public int CreateVariable(String type, Object value) {
logger.warn("[LUA] Call unimplemented CreateVariable with {} {}",
type, value);
//TODO implement
switch (type){
case "int":
default:
logger.warn("[LUA] Call CreateVariable with unsupported type {} and value {}", type, value);
}
return 0;
}
public int SetVariableValue(int var1) {
logger.warn("[LUA] Call unimplemented SetVariableValue with {}",
var1);
//TODO implement var1 type
return 0;
}
public int GetVariableValue(int var1) {
logger.warn("[LUA] Call unimplemented GetVariableValue with {}",
var1);
//TODO implement var1 type
return 0;
}
public int GetGroupVariableValue(String var) {
logger.debug("[LUA] Call GetGroupVariableValue with {}",
var);
return getSceneScriptManager().getVariables(currentGroup.get().id).getOrDefault(var, 0);
}
public int SetGroupVariableValue(String var, int value) {
logger.debug("[LUA] Call SetGroupVariableValue with {},{}",
var, value);
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 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(groupId, EventType.EVENT_VARIABLE_CHANGE, old+value, old));
return LuaValue.ZERO;
}
/**
* Set the actions and triggers to designated group
*/
public int RefreshGroup(LuaTable table) {
logger.debug("[LUA] Call RefreshGroup with {}",
printTable(table));
// Kill and Respawn?
int groupId = table.get("group_id").toint();
int suite = table.get("suite").toint();
SceneGroupInstance groupInstance = getSceneScriptManager().getGroupInstanceById(groupId);
if (groupInstance == null) {
logger.warn("[LUA] trying to refresh unloaded group {}", groupId);
return 1;
}
getSceneScriptManager().refreshGroup(groupInstance, suite, false);
return 0;
}
public int GetRegionEntityCount(LuaTable table) {
logger.debug("[LUA] Call GetRegionEntityCount with {}",
printTable(table));
int regionId = table.get("region_eid").toint();
int entityType = table.get("entity_type").toint();
var region = this.getSceneScriptManager().getRegionById(regionId);
if (region == null) {
return 0;
}
return (int) region.getEntities().stream().filter(e -> e >> 24 == entityType).count();
}
private void printLog(String source, String msg){
var currentGroup = this.currentGroup.getIfExists();
if(currentGroup != null) {
Grasscutter.getLogger().trace("[LUA] {} {} {}", source, currentGroup.id, msg);
} else {
Grasscutter.getLogger().trace("[LUA] {} {}", source, msg);
}
}
public void PrintContextLog(String msg) {
printLog("PrintContextLog", msg);
}
public void PrintLog(String msg) {
printLog("PrintLog", msg);
}
public int TowerCountTimeStatus(int isDone, int var2){
logger.debug("[LUA] Call TowerCountTimeStatus with {},{}",
isDone,var2);
// TODO record time
return 0;
}
public int GetGroupMonsterCount(){
logger.debug("[LUA] Call GetGroupMonsterCount ");
return (int) getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e instanceof EntityMonster &&
e.getGroupId() == getCurrentGroup().map(sceneGroup -> sceneGroup.id).orElse(-1))
.count();
}
public int SetMonsterBattleByGroup(int configId, int groupId) {
logger.debug("[LUA] Call SetMonsterBattleByGroup with {} {}",
configId,groupId);
// TODO implement scene50008_group250008057.lua uses incomplete group numbers
// -> MonsterForceAlertNotify
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
if (entity instanceof EntityMonster monster) {
this.getSceneScriptManager().getScene().broadcastPacket(new PacketMonsterForceAlertNotify(monster.getId()));
}
return 0;
}
public int CauseDungeonFail(){
logger.debug("[LUA] Call CauseDungeonFail with");
var scriptManager = sceneScriptManager.getIfExists();
if(scriptManager==null){
return 1;
}
var dungeonManager = scriptManager.getScene().getDungeonManager();
if(dungeonManager==null){
return 2;
}
dungeonManager.failDungeon();
return 0;
}
public int SetEntityServerGlobalValueByConfigId(int cfgId, String sgvName, int value) {
logger.debug("[LUA] Call SetEntityServerGlobalValueByConfigId with {}, {}, {}",
cfgId, sgvName, value);
var scriptManager = this.getSceneScriptManager();
if (scriptManager == null) return 1;
var scene = scriptManager.getScene();
var entity = scene.getEntityByConfigId(cfgId);
if (entity == null) return 2;
scene.broadcastPacket(
new PacketServerGlobalValueChangeNotify(entity, sgvName, value));
return 0;
}
public int GetGroupVariableValueByGroup(String name, int groupId){
logger.debug("[LUA] Call GetGroupVariableValueByGroup with {},{}",
name,groupId);
return getSceneScriptManager().getVariables(groupId).getOrDefault(name, 0);
}
public int ChangeGroupVariableValueByGroup(String name, int value, int groupId){
logger.debug("[LUA] Call ChangeGroupVariableValueByGroup with {},{}",
name,groupId);
//TODO test
getSceneScriptManager().getVariables(groupId).put(name, value);
return 0;
}
public int SetIsAllowUseSkill(int canUse){
logger.debug("[LUA] Call SetIsAllowUseSkill with {}",
canUse);
getSceneScriptManager().getScene().broadcastPacket(new PacketCanUseSkillNotify(canUse == 1));
return 0;
}
public int KillEntityByConfigId(LuaTable table){
logger.debug("[LUA] Call KillEntityByConfigId with {}",
printTable(table));
var configId = table.get("config_id");
if(configId == LuaValue.NIL){
return 1;
}
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId.toint());
if(entity == null){
return 0;
}
getSceneScriptManager().getScene().killEntity(entity, 0);
return 0;
}
public int SetGroupVariableValueByGroup(String key, int value, int groupId){
logger.debug("[LUA] Call SetGroupVariableValueByGroup with {},{},{}",
key,value,groupId);
getSceneScriptManager().getVariables(groupId).put(key, value);
return 0;
}
public int CreateMonster(LuaTable table){
logger.debug("[LUA] Call CreateMonster with {}",
printTable(table));
var configId = table.get("config_id").toint();
var delayTime = table.get("delay_time").toint();
if(getCurrentGroup().isEmpty()){
return 1;
}
getSceneScriptManager().spawnMonstersByConfigId(getCurrentGroup().get(), configId, delayTime);
return 0;
}
public int TowerMirrorTeamSetUp(int team, int var1) {
logger.debug("[LUA] Call TowerMirrorTeamSetUp with {},{}",
team,var1);
getSceneScriptManager().unloadCurrentMonsterTide();
getSceneScriptManager().getScene().getPlayers().get(0).getTowerManager().mirrorTeamSetUp(team-1);
return 0;
}
public int CreateGadget(LuaTable table){
logger.debug("[LUA] Call CreateGadget with {}",
printTable(table));
var configId = table.get("config_id").toint();
var group = getCurrentGroup();
if (group.isEmpty()) {
return 1;
}
createGadget(configId, group.get());
return 0;
}
private GameEntity createGadget(int configId, SceneGroup group){
var gadget = group.gadgets.get(configId);
var entity = getSceneScriptManager().createGadget(group.id, group.block_id, gadget);
if(entity==null){
logger.warn("[LUA] Create gadget null with cid: {} gid: {} bid: {}", configId, group.id, group.block_id);
return null;
}
getSceneScriptManager().addEntity(entity);
return entity;
}
public int CheckRemainGadgetCountByGroupId(LuaTable table){
logger.debug("[LUA] Call CheckRemainGadgetCountByGroupId with {}",
printTable(table));
var groupId = table.get("group_id").toint();
var count = getSceneScriptManager().getScene().getEntities().values().stream()
.filter(g -> g instanceof EntityGadget entityGadget && entityGadget.getGroupId() == groupId)
.count();
return (int)count;
}
public int GetGadgetStateByConfigId(int groupId, int configId){
logger.debug("[LUA] Call GetGadgetStateByConfigId with {},{}",
groupId, configId);
val scene = getSceneScriptManager().getScene();
val gadget = groupId == 0 ? scene.getEntityByConfigId(configId) : scene.getEntityByConfigId(configId, groupId);
if(!(gadget instanceof EntityGadget)){
return -1;
}
return ((EntityGadget)gadget).getState();
}
public int MarkPlayerAction(int var1, int var2, int var3){
logger.debug("[LUA] Call MarkPlayerAction with {},{},{}",
var1, var2,var3);
return 0;
}
public int AddQuestProgress(String var1){
logger.debug("[LUA] Call AddQuestProgress with {}",
var1);
for(var player : getSceneScriptManager().getScene().getPlayers()){
player.getPlayerProgress().addToCurrentProgress(var1, 1);
player.getQuestManager().queueEvent(QuestCond.QUEST_COND_LUA_NOTIFY, var1);
player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_LUA_NOTIFY, var1);
}
return 0;
}
/**
* change the state of gadget
*/
public int ChangeGroupGadget(LuaTable table){
logger.debug("[LUA] Call ChangeGroupGadget with {}",
printTable(table));
var configId = table.get("config_id").toint();
var state = table.get("state").toint();
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
if(entity == null){
return 1;
}
if (entity instanceof EntityGadget entityGadget) {
entityGadget.updateState(state);
return 0;
}
return 1;
}
public int GetEntityType(int entityId){
var entity = getSceneScriptManager().getScene().getEntityById(entityId);
if(entity == null){
return EntityType.None.getValue();
}
return entity.getEntityType();
}
public int GetQuestState(int entityId, int questId){
val player = getSceneScriptManager().getScene().getWorld().getHost();
val quest = player.getQuestManager().getQuestById(questId);
if(quest == null){
return QuestState.QUEST_STATE_NONE.getValue();
}
return quest.getState().getValue();
}
public int GetHostQuestState(int questId){
val player = getSceneScriptManager().getScene().getWorld().getHost();
val quest = player.getQuestManager().getQuestById(questId);
if(quest == null){
return QuestState.QUEST_STATE_NONE.getValue();
}
return quest.getState().getValue();
}
public int ShowReminder(int reminderId){
getSceneScriptManager().getScene().broadcastPacket(new PacketDungeonShowReminderNotify(reminderId));
return 0;
}
public int RemoveEntityByConfigId(int groupId, int entityType, int configId){
logger.debug("[LUA] Call RemoveEntityByConfigId");
val entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
if(entity == null || entity.getEntityType() != entityType){
return 1;
}
getSceneScriptManager().getScene().removeEntity(entity);
return 0;
}
public int CreateGroupTimerEvent(int groupID, String source, double time) {
return sceneScriptManager.get().createGroupTimerEvent(groupID, source, time);
}
public int CancelGroupTimerEvent(int groupID, String source) {
return sceneScriptManager.get().cancelGroupTimerEvent(groupID, source);
}
public int GetGroupSuite(int groupId) {
//logger.warn("[LUA] Call GetGroupSuite with {}", groupID);
var instance = getSceneScriptManager().getGroupInstanceById(groupId);
if(instance != null) return instance.getActiveSuiteId();
return 0;
}
public int SetGroupReplaceable(int groupId, boolean value) {
logger.warn("[LUA] Call SetGroupReplaceable with {} {}", groupId, value);
var group = getSceneScriptManager().getGroupById(groupId);
if(group != null && group.is_replaceable != null) {
group.is_replaceable.value = value;
return 0;
}
return 1;
}
public LuaTable GetSceneUidList(){
logger.warn("[LUA] Call unchecked GetSceneUidList");
//TODO check
var scriptManager = sceneScriptManager.getIfExists();
if(scriptManager == null){
return new LuaTable();
}
var players = scriptManager.getScene().getPlayers();
var result = new LuaTable();
for(int i = 0; i< players.size(); i++){
result.set(Integer.toString(i+1), players.get(i).getUid());
}
return result;
}
public int GetSeaLampActivityPhase(){
logger.warn("[LUA] Call unimplemented GetSeaLampActivityPhase");
//TODO implement
return 0;
}
public int GadgetPlayUidOp(int groupId, int gadget_crucible, int var3, int var4, String var5, int var6 ){
logger.warn("[LUA] Call unimplemented GadgetPlayUidOp with {}, {}, {}, {}, {}, {}", groupId, gadget_crucible, var3, var4, var5, var6);
//TODO implement
return 0;
}
public long GetServerTime(){
logger.debug("[LUA] Call GetServerTime");
//TODO check
return new Date().getTime();
}
public long GetServerTimeByWeek(){
logger.debug("[LUA] Call GetServerTimeByWeek");
return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
}
public int GetCurTriggerCount(){
logger.debug("[LUA] Call GetCurTriggerCount");
//TODO check
return getSceneScriptManager().getTriggerCount();
}
public int GetChannellerSlabLoopDungeonLimitTime(){
logger.warn("[LUA] Call unimplemented GetChannellerSlabLoopDungeonLimitTime");
//TODO implement
return 0;
}
public int IsPlayerAllAvatarDie(int sceneUid){
logger.warn("[LUA] Call unimplemented IsPlayerAllAvatarDie {}", sceneUid);
var playerEntities = getSceneScriptManager().getScene().getEntities().values().stream().filter(e -> e.getEntityType() == EntityIdType.AVATAR.getId()).toList();
for (GameEntity p : playerEntities){
var player = (EntityAvatar)p;
if(player.isAlive()){
return 0;
}
}
//TODO check
return 1;
}
public int sendShowCommonTipsToClient(String title, String content, int closeTime) {
logger.debug("[LUA] Call sendShowCommonTipsToClient with {}, {}, {}", title, content, closeTime);
sceneScriptManager.get().getScene().broadcastPacket(new PacketShowCommonTipsNotify(title, content, closeTime));
return 0;
}
public int sendCloseCommonTipsToClient(){
logger.debug("[LUA] Call unimplemented sendCloseCommonTipsToClient");
sceneScriptManager.get().getScene().broadcastPacket(new PacketCloseCommonTipsNotify());
return 0;
}
public int CreateFatherChallenge(int var1, int var2, int var3, LuaTable var4){
logger.warn("[LUA] Call unimplemented CreateFatherChallenge with {} {} {} {}", var1, var2, var3, var4);
//TODO implement var4 object has int success, int fail, bool fail_on_wipe
return 0;
}
public int StartFatherChallenge(int var1){
logger.warn("[LUA] Call unimplemented StartFatherChallenge with {}", var1);
//TODO implement
return 0;
}
public int ModifyFatherChallengeProperty(int challengeId, int propertyTypeIndex, int value){
val propertyType = FatherChallengeProperty.values()[propertyTypeIndex];
logger.warn("[LUA] Call unimplemented ModifyFatherChallengeProperty with {} {} {}", challengeId, propertyType.name(), value);
//TODO implement
return 0;
}
public int AttachChildChallenge(int var1, int var2, int var3, int[] var4, LuaTable var5, LuaTable var6){
logger.warn("[LUA] Call unimplemented AttachChildChallenge with {} {} {} {} {} {}", var1, var2, var3, var4, var5, var6);
//TODO implement var6 object has int success, int fail, bool fail_on_wipe
return 0;
}
public int CreateEffigyChallengeMonster(int var1, int[] var2){
logger.warn("[LUA] Call unimplemented CreateEffigyChallengeMonster with {} {}", var1, var2);
//TODO implement
return 0;
}
public int GetEffigyChallengeMonsterLevel(){
logger.warn("[LUA] Call unimplemented CreateEffigyChallengeMonster");
//TODO implement
return 0;
}
public int AddTeamEntityGlobalFloatValue(int[] sceneUidList, String var2, int var3){
logger.warn("[LUA] Call unimplemented AddTeamEntityGlobalFloatValue with {} {} {}", sceneUidList, var2, var3);
//TODO implement
return 0;
}
public int CreateBlossomChestByGroupId(int groupId, int var2){
logger.warn("[LUA] Call unimplemented SetBlossomScheduleStateByGroupId with {} {}", groupId, var2);
//TODO implement
return 0;
}
public int SetBlossomScheduleStateByGroupId(int groupId, int scene){
logger.warn("[LUA] Call unimplemented SetBlossomScheduleStateByGroupId with {} {}", groupId, scene);
//TODO implement scene is guessed
return 0;
}
public int RefreshBlossomGroup(LuaTable var1){
logger.warn("[LUA] Call unimplemented RefreshBlossomGroup with {}", printTable(var1));
//TODO implement var3 has int group_id, int suite, bool exclude_prev
return 0;
}
public int RefreshBlossomDropRewardByGroupId(int groupId){
logger.warn("[LUA] Call unimplemented RefreshBlossomDropRewardByGroupId with {}", groupId);
//TODO implement
return 0;
}
public int AddBlossomScheduleProgressByGroupId(int groupId){
logger.warn("[LUA] Call unimplemented AddBlossomScheduleProgressByGroupId with {}", groupId);
//TODO implement
return 0;
}
public int RefreshHuntingClueGroup(){
logger.warn("[LUA] Call unimplemented RefreshHuntingClueGroup"); //TODO: Much many calls o this garbages the log
//TODO implement
return 0;
}
public int GetHuntingMonsterExtraSuiteIndexVec(){
logger.warn("[LUA] Call unimplemented GetHuntingMonsterExtraSuiteIndexVec");
//TODO implement
return 0;
}
public int SetGroupTempValue(String name, int value, LuaTable var3){
logger.warn("[LUA] Call unimplemented SetGroupTempValue with {} {} {}", name, value, printTable(var3));
//TODO implement var3 has int group_id
return 0;
}
public int GetGroupTempValue(String name, LuaTable var2){
logger.warn("[LUA] Call unimplemented GetGroupTempValue with {} {}", name, printTable(var2));
//TODO implement var3 has int group_id
return 0;
}
public int FinishExpeditionChallenge(){
logger.warn("[LUA] unimplemented Call FinishExpeditionChallenge");
//TODO implement
return 0;
}
public int ExpeditionChallengeEnterRegion(boolean var1){
logger.warn("[LUA] unimplemented Call ExpeditionChallengeEnterRegion with {}", var1);
//TODO implement
return 0;
}
public int StartSealBattle(int gadgetId, LuaTable var2){
logger.warn("[LUA] unimplemented Call StartSealBattle with {} {}", gadgetId, printTable(var2));
//TODO implement var2 containt int radius, int battle_time, int monster_group_id, int default_kill_charge, int auto_charge, int auto_decline, int max_energy, SealBattleType battleType
// for type KILL_MONSTER watch group monster_group_id and afterwards trigger EVENT_SEAL_BATTLE_END with the result in param2
return 0;
}
public int InitTimeAxis(String var1, int[] var2, boolean var3){
logger.warn("[LUA] Call unimplemented InitTimeAxis with {} {} {}", var1, var2, var3);
//TODO implement var1 == name? var2 == delay? var3 == should loop?
return 0;
}
public int EndTimeAxis(String var1){
logger.warn("[LUA] Call unimplemented EndTimeAxis with {} {} {}", var1);
//TODO implement var1 == name?
return 0;
}
public int SetTeamEntityGlobalFloatValue(int[] sceneUidList, String var2, int var3){
logger.warn("[LUA] Call unimplemented SetTeamEntityGlobalFloatValue with {} {} {}", sceneUidList, var2, var3);
//TODO implement
return 0;
}
public int SetTeamServerGlobalValue(int sceneUid, String var2, int var3){
logger.warn("[LUA] Call unimplemented SetTeamServerGlobalValue with {} {} {}", sceneUid, var2, var3);
//TODO implement
return 0;
}
public int GetLanternRiteValue(){
logger.warn("[LUA] Call unimplemented GetLanternRiteValue");
//TODO implement
return 0;
}
public int CreateMonsterFaceAvatar(LuaTable var1){
logger.warn("[LUA] Call unimplemented CreateMonsterFaceAvatar with {}", printTable(var1));
//TODO implement var1 contains int entity_id, int[] monsters (cfgIds), int[] ranges, int angle
return 0;
}
public int ChangeToTargetLevelTag(int var1){
logger.warn("[LUA] Call unimplemented ChangeToTargetLevelTag with {}", var1);
//TODO implement
return 0;
}
public int AddSceneTag(int sceneId, int sceneTagId){
logger.warn("[LUA] Call unimplemented AddSceneTag with {}, {}", sceneId, sceneTagId);
//TODO implement
return 0;
}
public int DelSceneTag(int sceneId, int sceneTagId){
logger.warn("[LUA] Call unimplemented DelSceneTag with {}, {}", sceneId, sceneTagId);
//TODO implement
return 0;
}
public boolean CheckSceneTag(int sceneId, int sceneTagId){
logger.warn("[LUA] Call unimplemented CheckSceneTag with {}, {}", sceneId, sceneTagId);
//TODO implement
return false;
}
public int StartHomeGallery(int galleryId, int uid){
logger.warn("[LUA] Call unimplemented StartHomeGallery with {} {}", galleryId, uid);
//TODO implement
return 0;
}
public int StopGallery(int galleryId, boolean var2){
logger.warn("[LUA] Call unimplemented StopGallery with {} {}", galleryId, var2);
//TODO implement
return 0;
}
public int StartGallery(int galleryId){
logger.warn("[LUA] Call unimplemented StartGallery with {}", galleryId);
//TODO implement
return 0;
}
public int UpdatePlayerGalleryScore(int galleryId, LuaTable var2){
logger.warn("[LUA] Call unimplemented UpdatePlayerGalleryScore with {} {}", galleryId, printTable(var2));
//TODO implement var2 contains int uid
return 0;
}
public int SetHandballGalleryBallPosAndRot(int galleryId, LuaTable position, LuaTable rotation){
logger.warn("[LUA] Call unimplemented SetHandballGalleryBallPosAndRot with {} {} {}", galleryId, printTable(position), printTable(rotation));
//TODO implement
return 0;
}
public int UnlockFloatSignal(int groupId, int gadgetSignalId){
logger.warn("[LUA] Call unimplemented UnlockFloatSignal with {} {}", groupId, gadgetSignalId);
//TODO implement
return 0;
}
public int SendServerMessageByLuaKey(String var1, int[] var2){
logger.warn("[LUA] Call unimplemented SendServerMessageByLuaKey with {} {}", var1, var2);
//TODO implement
return 0;
}
public int TryReallocateEntityAuthority(int uid, int endConfig, int var3){
logger.warn("[LUA] Call unimplemented TryReallocateEntityAuthority with {} {} {}", uid, endConfig, var3);
//TODO implement check var3 type
return 0;
}
public int ForceRefreshAuthorityByConfigId(int var1, int uid){
logger.warn("[LUA] Call unimplemented ForceRefreshAuthorityByConfigId with {} {}", var1, uid);
//TODO implement check var3 type
return 0;
}
public int AddPlayerGroupVisionType(int[] uids, int[] var2){
logger.warn("[LUA] Call unimplemented AddPlayerGroupVisionType with {} {}", uids, var2);
//TODO implement
return 0;
}
public int DelPlayerGroupVisionType(int[] uids, int[] var2){
logger.warn("[LUA] Call unimplemented DelPlayerGroupVisionType with {} {}", uids, var2);
//TODO implement
return 0;
}
public int MoveAvatarByPointArray(int uid, int targetId, LuaTable var3, String var4){
logger.warn("[LUA] Call unimplemented MoveAvatarByPointArray with {} {} {} {}", uid, targetId, printTable(var3), var4);
//TODO implement var3 contains int speed, var4 is a json string
return 0;
}
public int MovePlayerToPos(LuaTable var1){
logger.warn("[LUA] Call unchecked MovePlayerToPos with {}", printTable(var1));
//TODO implement var1 contains int[] uid_list, Position pos, int radius, Position rot
return TransPlayerToPos(var1); // todo this is probably not a full scene reload
}
public int TransPlayerToPos(LuaTable var1){
logger.warn("[LUA] Call unchecked TransPlayerToPos with {}", printTable(var1));
//TODO implement var1 contains int[] uid_list, Position pos, int radius, Position rot
var targetsTable = var1.get("uid_list");
var pos = var1.get("pos");
var rot = var1.get("rot");
var radius = var1.get("radius");
if(targetsTable.isnil() || !targetsTable.istable() || targetsTable.length()==0 || pos.isnil()){
return 1;
}
ArrayList<Integer> targets = new ArrayList<>(targetsTable.length());
for (int i = 1; i <= targetsTable.length(); i++) {
targets.add(targetsTable.get(i).optint(-1));
}
var x = pos.get("x");
var y = pos.get("y");
var z = pos.get("z");
var scriptManager = sceneScriptManager.getIfExists();
if(scriptManager==null || !x.isnumber() || !y.isnumber() || !z.isnumber()){
return 2;
}
var targetPos = new Position(x.toint(), y.toint(), z.toint());
var scene = scriptManager.getScene();
scene.getPlayers().stream().filter(p -> targets.contains(p.getUid())).forEach(p -> {
scene.removePlayer(p);
scene.addPlayer(p);
p.getPosition().set(targetPos);
// Teleport packet
p.sendPacket(new PacketPlayerEnterSceneNotify(p, EnterTypeOuterClass.EnterType.ENTER_TYPE_GOTO, Lua, scene.getId(), targetPos));
});
return 0;
}
public int PlayCutScene(int cutsceneId, int var2){
logger.warn("[LUA] Call unimplemented PlayCutScene with {} {}", cutsceneId, var2);
sceneScriptManager.get().getScene().broadcastPacket(new PacketCutsceneBeginNotify(cutsceneId));
//TODO implement
return 0;
}
public int PlayCutSceneWithParam(int cutsceneId, int var2, LuaTable var3){
logger.warn("[LUA] Call unimplemented PlayCutScene with {} {}", cutsceneId, var2, var3);
//TODO implement
return 0;
}
public int ScenePlaySound(LuaTable soundInfo){
logger.debug("[LUA] Call unimplemented ScenePlaySound with {}", printTable(soundInfo));
val luaSoundName = soundInfo.get("sound_name");
val luaIsBroadcast = soundInfo.get("is_broadcast");
val luaPlayPosition = soundInfo.get("play_pos");
val luaPlayType = soundInfo.get("play_type");
val soundName = luaSoundName.optjstring(null);
val isBroadcast = luaIsBroadcast.optboolean(true);
val playPosition = luaToPos(luaPlayPosition);
val playType = luaPlayType.optint(0); // TODO
sceneScriptManager.get().getScene().broadcastPacket(new PacketScenePlayerSoundNotify(playPosition, soundName, playType));
return 0;
}
public int BeginCameraSceneLook(LuaTable sceneLookParams){
logger.debug("[LUA] Call BeginCameraSceneLook with {}", printTable(sceneLookParams));
// INVESTIGATE: Sniff the content for 'BeginCameraSceneLookNotify'.
// This packet is known as 260 (3.5) or 215 (3.6).
// Compare data to ones found in Lua, then de-obfuscate.
// var luaLookPos = sceneLookParams.get("look_pos");
// var luaFollowPos = sceneLookParams.get("follow_pos");
// var luaDuration = sceneLookParams.get("duration");
// var luaIsForce = sceneLookParams.get("is_force");
// var luaIsBroadcast = sceneLookParams.get("is_broadcast");
// var luaAllowInput = sceneLookParams.get("is_allow_input");
// var luaSetFollowPos = sceneLookParams.get("is_set_follow_pos");
// var luaIsForceWalk = sceneLookParams.get("is_force_walk");
// var luaIsChangePlayMode = sceneLookParams.get("is_change_play_mode");
// var luaScreenX = sceneLookParams.get("screen_x");
// var luaScreenY = sceneLookParams.get("screen_y");
//
// var cameraParams = new PacketBeginCameraSceneLookNotify.CameraSceneLookNotify();
// cameraParams.setLookPos(luaToPos(luaLookPos));
// cameraParams.setFollowPos(luaToPos(luaFollowPos));
// if (luaDuration.isnumber()) {
// cameraParams.setDuration(luaDuration.tofloat());
// }
// if (luaScreenX.isnumber()) {
// cameraParams.setScreenX(luaScreenX.tofloat());
// }
// if (luaScreenY.isnumber()) {
// cameraParams.setScreenY(luaScreenY.tofloat());
// }
// if (luaIsForce.isboolean()) {
// cameraParams.setForce(luaIsForce.toboolean());
// }
// if (luaAllowInput.isboolean()) {
// cameraParams.setAllowInput(luaAllowInput.toboolean());
// }
// if (luaSetFollowPos.isboolean()) {
// cameraParams.setSetFollowPos(luaSetFollowPos.toboolean());
// }
// if (luaIsForceWalk.isboolean()) {
// cameraParams.setForceWalk(luaIsForceWalk.toboolean());
// }
// if (luaIsChangePlayMode.isboolean()) {
// cameraParams.setChangePlayMode(luaIsChangePlayMode.toboolean());
// }
// if(luaIsBroadcast.isboolean()) { } // TODO
//
// sceneScriptManager.get().getScene().broadcastPacket(new PacketBeginCameraSceneLookNotify(cameraParams));
return 0;
}
public int ShowReminderRadius(int var1, LuaTable var2, int var3){
logger.warn("[LUA] Call unimplemented ShowReminderRadius with {} {} {}", var1, printTable(var2), var3);
//TODO implement var2 is a postion
return 0;
}
public int ShowClientGuide(String guideName){
logger.debug("[LUA] Call unimplemented ShowClientGuide with {}", guideName);
if (GameData.getGuideTriggerDataStringMap().get(guideName) != null) {
// if should handle by open state, dont send packet here
// not entirely sure what return value is about
// probably not needing this check statement here since the value comes from
// the lua script
return 1;
}
sceneScriptManager.get().getScene().broadcastPacket(new PacketShowClientGuideNotify(guideName));
return 0;
}
public int ActivateDungeonCheckPoint(int var1){
logger.warn("[LUA] Call untested ActivateDungeonCheckPoint with {}", var1);
var dungeonManager = getSceneScriptManager().getScene().getDungeonManager();
if(dungeonManager == null){
return 1;
}
return dungeonManager.activateRespawnPoint(var1) ? 0:2;
}
//TODO check
public int SetWeatherAreaState(int var1, int var2){
logger.warn("[LUA] Call unimplemented SetWeatherAreaState with {} {}", var1, var2);
getSceneScriptManager().getScene().getPlayers().forEach(p -> p.setWeather(var1, ClimateType.getTypeByValue(var2)));
return 0;
}
public int EnterWeatherArea(int var1){
logger.warn("[LUA] Call unimplemented EnterWeatherArea with {}", var1);
//TODO implement
return 0;
}
//TODO check
public boolean CheckIsInMpMode(){
logger.debug("[LUA] Call CheckIsInMpMode");
return getSceneScriptManager().getScene().getWorld().isMultiplayer();
}
/**
* TODO properly implement
* var3 might contain the next point, sometimes is a single int, sometimes multiple ints as array
* var4 has RouteType route_type, bool turn_mode
*/
public int SetPlatformPointArray(int entityConfigId, int pointArrayId, int[] var3, LuaTable var4){
logger.warn("[LUA] Call unimplemented SetPlatformPointArray with {} {} {} {}", entityConfigId, pointArrayId, var3, printTable(var4));
val entity = getSceneScriptManager().getScene().getEntityByConfigId(entityConfigId);
if(entity == null){
return 1;
}
if(!(entity instanceof EntityGadget entityGadget)){
return 2; //todo maybe also check the gadget type?
}
var routeConfig = entityGadget.getRouteConfig();
if(!(routeConfig instanceof PointArrayRoute)){
routeConfig = new PointArrayRoute((entityGadget).getMetaGadget());
entityGadget.setRouteConfig(routeConfig);
}
val configRoute = (PointArrayRoute) routeConfig;
//TODO also check targetPoint/targetPoints
if(configRoute.getPointArrayId() == pointArrayId){
return -1;
}
configRoute.setPointArrayId(pointArrayId);
//TODO also set targetPoint/targetPoints
sceneScriptManager.get().getScene().broadcastPacket(new PacketPlatformChangeRouteNotify(entityGadget));
return -1;
}
//TODO check
public int SetPlatformRouteId(int entityConfigId, int routeId){
logger.info("[LUA] Call SetPlatformRouteId {} {}", entityConfigId, routeId);
val entity = getSceneScriptManager().getScene().getEntityByConfigId(entityConfigId);
if(entity == null){
return 1;
}
if(!(entity instanceof EntityGadget entityGadget)){
return 2; //todo maybe also check the gadget type?
}
var routeConfig = entityGadget.getRouteConfig();
if(!(routeConfig instanceof ConfigRoute)){
routeConfig = new ConfigRoute((entityGadget).getMetaGadget());
entityGadget.setRouteConfig(routeConfig);
}
val configRoute = (ConfigRoute) routeConfig;
if(configRoute.getRouteId() == routeId){
return 0;
}
configRoute.setRouteId(routeId);
sceneScriptManager.get().getScene().broadcastPacket(new PacketPlatformChangeRouteNotify(entityGadget));
return 0;
}
//TODO check
public int StartPlatform(int configId){
logger.debug("[LUA] Call StartPlatform {} ", configId);
val entity = sceneScriptManager.get().getScene().getEntityByConfigId(configId);
if(!(entity instanceof EntityGadget entityGadget)) {
return 1;
}
return entityGadget.startPlatform() ? 0 : 2;
}
//TODO check
public int StopPlatform(int configId){
logger.info("[LUA] Call StopPlatform {} ", configId);
val entity = sceneScriptManager.get().getScene().getEntityByConfigId(configId);
if(!(entity instanceof EntityGadget entityGadget)) {
return 1;
}
return entityGadget.stopPlatform() ? 0 : 2;
}
public int CreateChannellerSlabCampRewardGadget(int configId){
logger.warn("[LUA] Call unimplemented CreateChannellerSlabCampRewardGadget {}", configId);
var group = currentGroup.getIfExists();
if(group == null){
return 1;
}
createGadget(configId, group);
//TODO implement fully
return 0;
}
public int AssignPlayerShowTemplateReminder(int var1, LuaTable var2){
logger.warn("[LUA] Call unimplemented AssignPlayerShowTemplateReminder {} {}", var1, var2);
//TODO implement var2 contains LuaTable param_uid_vec, LuaTable param_vec int[] uid_vec
return 0;
}
public int RevokePlayerShowTemplateReminder(int var1, LuaValue var2){
logger.warn("[LUA] Call unimplemented AssignPlayerShowTemplateReminder {} {}", var1, var2);
//TODO implement
return 0;
}
public int UnlockForce(int force){
logger.debug("[LUA] Call UnlockForce {}", force);
getSceneScriptManager().getScene().unlockForce(force);
return 0;
}
public int LockForce(int force){
logger.debug("[LUA] Call LockForce {}", force);
getSceneScriptManager().getScene().lockForce(force);
return 0;
}
public int KillGroupEntity(LuaTable var1){
logger.debug("[LUA] Call KillGroupEntity with {}", printTable(var1));
//TODO check
var sceneManager = sceneScriptManager.getIfExists();
var groupId = var1.get("group_id").optint(-1);
var killPolicyId = var1.get("kill_policy").optint(-1);
var gadgetList = var1.get("gadgets");
if(groupId == -1 || sceneManager == null){
return 1;
}
var group = sceneManager.getGroupById(groupId);
if (group == null) {
return 2;
}
if(killPolicyId!=-1 ){
var killPolicy = GroupKillPolicy.values()[killPolicyId];
return killGroupEntityWithPolicy(sceneManager, group, killPolicy);
}
return killGroupEntityWithTable(sceneManager, group, var1);
}
private int killGroupEntityWithTable(SceneScriptManager sceneScriptManager, SceneGroup group, LuaTable lists){
// get targets
var monsterList = lists.get("monsters");
var gadgetList = lists.get("gadgets");
int[] targets = new int[monsterList.length()+gadgetList.length()];
int targetsIndex = 0;
for (int i = 1; i<=monsterList.length(); i++, targetsIndex++){
targets[targetsIndex] = monsterList.get(i).optint(-1);
}
for (int i = 1; i<=gadgetList.length(); i++, targetsIndex++){
targets[targetsIndex] = gadgetList.get(i).optint(-1);
}
// kill targets if exists
for(int cfgId : targets){
var entity = getSceneScriptManager().getScene().getEntityByConfigId(cfgId);
if (entity == null || cfgId == 0) {
continue;
}
getSceneScriptManager().getScene().killEntity(entity, 0);
}
return 0;
}
private int killGroupEntityWithPolicy(SceneScriptManager sceneScriptManager,SceneGroup group, GroupKillPolicy killPolicy){
// get targets
var targets = new ArrayList<SceneObject>();
if(killPolicy==GROUP_KILL_MONSTER || killPolicy == GROUP_KILL_ALL){
targets.addAll(group.monsters.values());
}
if(killPolicy == GROUP_KILL_GADGET || killPolicy == GROUP_KILL_ALL) {
targets.addAll(group.gadgets.values());
}
// kill targets if exists
targets.forEach(o -> {
var entity = getSceneScriptManager().getScene().getEntityByConfigId(o.config_id);
if (entity == null) {
return;
}
getSceneScriptManager().getScene().killEntity(entity, 0);
});
return 0;
}
public int GetGadgetIdByEntityId(int entityId){
var entity = getSceneScriptManager().getScene().getEntityById(entityId);
if(!(entity instanceof EntityBaseGadget)){
return 0;
}
return ((EntityBaseGadget) entity).getGadgetId();
}
public int GetMonsterIdByEntityId(int entityId){
var entity = getSceneScriptManager().getScene().getEntityById(entityId);
if(!(entity instanceof EntityMonster)){
return 0;
}
return ((EntityMonster) entity).getMonsterData().getId();
}
public int GetMonsterID(int var1){
//TODO implement var1 type
return 0;
}
public int GetEntityIdByConfigId(int configId){
logger.warn("[LUA] Call GetEntityIdByConfigId with {}", configId);
//TODO check
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
return entity != null ? entity.getId() : 0;
}
public int GetAvatarEntityIdByUid(int uid){
logger.warn("[LUA] Call unchecked GetAvatarEntityIdByUid with {}", uid);
//TODO check
var entity = getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e instanceof EntityAvatar && ((EntityAvatar)e).getPlayer().getUid() == uid)
.findFirst();
return entity.map(GameEntity::getId).orElse(0);
}
public LuaTable GetPosByEntityId(int entityId){
logger.warn("[LUA] Call unchecked GetPosByEntityId with {}", entityId);
//TODO check
var entity = getSceneScriptManager().getScene().getEntityById(entityId);
return posToLua(entity != null? entity.getPosition() : null);
}
public LuaTable GetRotationByEntityId(int entityId){
logger.debug("[LUA] Call unchecked GetRotationByEntityId with {}", entityId);
//TODO check
var entity = getSceneScriptManager().getScene().getEntityById(entityId);
return posToLua(entity != null? entity.getRotation() : null);
}
public LuaTable GetActivityOpenAndCloseTimeByScheduleId(int scheduleId){
logger.debug("[LUA] Call GetActivityOpenAndCloseTimeByScheduleId with {}", scheduleId);
var result = new LuaTable();
var activityConfig = ActivityManager.getScheduleActivityConfigMap().get(scheduleId);
if(activityConfig != null){
result.set(1, LuaValue.valueOf(activityConfig.getBeginTime().getTime()));
result.set(2, LuaValue.valueOf(activityConfig.getEndTime().getTime()));
}
return result;
}
public int GetGameHour(){
return getSceneScriptManager().getScene().getWorld().getGameTimeHours();
}
/**
* Methods used in EntityControllers
*/
@Nullable
public EntityGadget getCurrentEntityGadget(){
val entity = currentEntity.getIfExists();
if(entity instanceof EntityGadget){
return (EntityGadget) entity;
}
return null;
}
public int SetGadgetState(int gadgetState) {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
gadget.updateState(gadgetState);
return 0;
}
public int GetGadgetState(int gadgetState) {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
return gadget.getState();
}
public int ResetGadgetState(int gadgetState) {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
gadget.getPosition().set(gadget.getBornPos());
gadget.getRotation().set(gadget.getBornRot());
gadget.setStartValue(0);
gadget.setStopValue(0);
gadget.updateState(gadgetState);
return 0;
}
public int SetGearStartValue(int startValue) {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
gadget.setStartValue(startValue);
return 0;
}
public int GetGearStartValue() {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
return gadget.getStartValue();
}
public int SetGearStopValue(int startValue) {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
gadget.setStopValue(startValue);
return 0;
}
public int GetGearStopValue() {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
return gadget.getStopValue();
}
public int GetGadgetStateBeginTime() {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
return gadget.getTicksSinceChange();
}
public int GetContextGadgetConfigId() {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
return gadget.getConfigId();
}
public int GetContextGroupId() {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget == null) return -1;
return gadget.getGroupId();
}
public int SetGadgetEnableInteract(int groupId, int configId, boolean enable) {
EntityGadget gadget = getCurrentEntityGadget();
if(gadget.getGroupId() != groupId || gadget.getConfigId() != configId) return -1;
gadget.setInteractEnabled(enable);
return 0;
}
public int DropSubfield(LuaTable table) {
String subfield_name = table.get("subfield_name").toString();
var entity = getCurrentEntity();
if(!entity.isPresent()) return -1;
entity.get().dropSubfield(subfield_name);
return -1;
}
public int[] GetGatherConfigIdList() {
EntityGadget gadget = getCurrentEntityGadget();
var children = gadget.getChildren();
int[] configIds = new int[children.size()];
for(int i = 0; i < children.size(); i++) {
configIds[i] = children.get(i).getConfigId();
}
return configIds;
}
}