Monsters tide turn by turn && Ban User Skill && Lua functions

This commit is contained in:
Akka 2022-05-07 21:47:13 +08:00 committed by Melledy
parent a7c1f85579
commit 8739277970
9 changed files with 247 additions and 88 deletions

View File

@ -0,0 +1,15 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message CanUseSkillNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1019;
}
bool is_can_use_skill = 1;
}

View File

@ -117,6 +117,7 @@ public class EntityMonster extends GameEntity {
this.getScene().getDeadSpawnedEntities().add(getSpawnEntry()); this.getScene().getDeadSpawnedEntities().add(getSpawnEntry());
} }
if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) { if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) {
getScene().getScriptManager().onMonsterDie();
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, null); getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, null);
} }
if (getScene().getChallenge() != null && getScene().getChallenge().getGroup().id == this.getGroupId()) { if (getScene().getChallenge() != null && getScene().getChallenge().getGroup().id == this.getGroupId()) {

View File

@ -7,6 +7,7 @@ import emu.grasscutter.data.def.TowerLevelData;
import emu.grasscutter.game.dungeons.DungeonSettleListener; import emu.grasscutter.game.dungeons.DungeonSettleListener;
import emu.grasscutter.game.dungeons.TowerDungeonSettleListener; import emu.grasscutter.game.dungeons.TowerDungeonSettleListener;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
import emu.grasscutter.server.packet.send.PacketTowerCurLevelRecordChangeNotify; import emu.grasscutter.server.packet.send.PacketTowerCurLevelRecordChangeNotify;
import emu.grasscutter.server.packet.send.PacketTowerEnterLevelRsp; import emu.grasscutter.server.packet.send.PacketTowerEnterLevelRsp;
@ -75,7 +76,8 @@ public class TowerManager {
player.getScene().setPrevScenePoint(enterPointId); player.getScene().setPrevScenePoint(enterPointId);
player.getSession().send(new PacketTowerEnterLevelRsp(currentFloorId, currentLevel)); player.getSession().send(new PacketTowerEnterLevelRsp(currentFloorId, currentLevel));
// stop using skill
player.getSession().send(new PacketCanUseSkillNotify(false));
} }
public void notifyCurLevelRecordChange(){ public void notifyCurLevelRecordChange(){

View File

@ -105,7 +105,13 @@ public class Scene {
public GameEntity getEntityById(int id) { public GameEntity getEntityById(int id) {
return this.entities.get(id); return this.entities.get(id);
} }
public GameEntity getEntityByConfigId(int configId) {
return this.entities.values().stream()
.filter(x -> x.getConfigId() == configId)
.findFirst()
.orElse(null);
}
/** /**
* @return the autoCloseTime * @return the autoCloseTime
*/ */

View File

@ -1,19 +1,14 @@
package emu.grasscutter.scripts; package emu.grasscutter.scripts;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.script.Bindings; import javax.script.Bindings;
import javax.script.CompiledScript; import javax.script.CompiledScript;
import javax.script.ScriptException; import javax.script.ScriptException;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue; import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.CoerceJavaToLua; import org.luaj.vm2.lib.jse.CoerceJavaToLua;
@ -23,12 +18,8 @@ import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.data.def.WorldLevelData; import emu.grasscutter.data.def.WorldLevelData;
import emu.grasscutter.game.entity.EntityGadget; import emu.grasscutter.game.entity.EntityGadget;
import emu.grasscutter.game.entity.EntityMonster; import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.props.EntityType;
import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.constants.EventType; import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.constants.ScriptGadgetState;
import emu.grasscutter.scripts.constants.ScriptRegionShape;
import emu.grasscutter.scripts.data.SceneBlock; import emu.grasscutter.scripts.data.SceneBlock;
import emu.grasscutter.scripts.data.SceneConfig; import emu.grasscutter.scripts.data.SceneConfig;
import emu.grasscutter.scripts.data.SceneGadget; import emu.grasscutter.scripts.data.SceneGadget;
@ -56,7 +47,12 @@ public class SceneScriptManager {
private final Int2ObjectOpenHashMap<Set<SceneTrigger>> triggers; private final Int2ObjectOpenHashMap<Set<SceneTrigger>> triggers;
private final Int2ObjectOpenHashMap<SceneRegion> regions; private final Int2ObjectOpenHashMap<SceneRegion> regions;
private SceneGroup currentGroup;
private AtomicInteger monsterAlive;
private AtomicInteger monsterTideCount;
private int monsterSceneLimit;
private ConcurrentLinkedQueue<Integer> monsterOrders;
public SceneScriptManager(Scene scene) { public SceneScriptManager(Scene scene) {
this.scene = scene; this.scene = scene;
this.scriptLib = new ScriptLib(this); this.scriptLib = new ScriptLib(this);
@ -222,7 +218,8 @@ public class SceneScriptManager {
cs.eval(getBindings()); cs.eval(getBindings());
// Set // Set
group.monsters = ScriptLoader.getSerializer().toList(SceneMonster.class, bindings.get("monsters")); group.monsters = ScriptLoader.getSerializer().toList(SceneMonster.class, bindings.get("monsters")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y));
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"));
@ -235,7 +232,7 @@ public class SceneScriptManager {
// Add monsters to suite TODO optimize // Add monsters to suite TODO optimize
Int2ObjectMap<Object> map = new Int2ObjectOpenHashMap<>(); Int2ObjectMap<Object> map = new Int2ObjectOpenHashMap<>();
group.monsters.forEach(m -> map.put(m.config_id, m)); group.monsters.entrySet().forEach(m -> map.put(m.getValue().config_id, m));
group.gadgets.forEach(m -> map.put(m.config_id, m)); group.gadgets.forEach(m -> map.put(m.config_id, m));
for (SceneSuite suite : group.suites) { for (SceneSuite suite : group.suites) {
@ -323,60 +320,92 @@ public class SceneScriptManager {
} }
public void spawnMonstersInGroup(SceneGroup group, int suiteIndex) { public void spawnMonstersInGroup(SceneGroup group, int suiteIndex) {
spawnMonstersInGroup(group, group.getSuiteByIndex(suiteIndex)); this.currentGroup = group;
this.monsterSceneLimit = 0;
var suite = group.getSuiteByIndex(suiteIndex);
if(suite == null){
return;
}
suite.sceneMonsters.forEach(mob -> spawnMonstersInGroup(group, mob));
} }
public void spawnMonstersInGroup(SceneGroup group) { public void spawnMonstersInGroup(SceneGroup group) {
spawnMonstersInGroup(group, null); this.currentGroup = group;
this.monsterSceneLimit = 0;
group.monsters.values().forEach(mob -> spawnMonstersInGroup(group, mob));
} }
public void spawnMonstersInGroup(SceneGroup group,Integer[] ordersConfigId, int tideCount, int sceneLimit) {
public void spawnMonstersInGroup(SceneGroup group, SceneSuite suite) { this.currentGroup = group;
List<SceneMonster> monsters = group.monsters; this.monsterSceneLimit = sceneLimit;
this.monsterTideCount = new AtomicInteger(tideCount);
if (suite != null) { this.monsterAlive = new AtomicInteger(0);
monsters = suite.sceneMonsters; this.monsterOrders = new ConcurrentLinkedQueue<>(List.of(ordersConfigId));
// add the last turn
group.monsters.keySet().stream()
.filter(i -> !this.monsterOrders.contains(i))
.forEach(this.monsterOrders::add);
for (int i = 0; i < sceneLimit; i++) {
spawnMonstersInGroup(group, group.monsters.get(this.monsterOrders.poll()));
}
}
public void spawnMonstersInGroup(SceneGroup group, SceneMonster monster) {
if(monster == null){
return;
}
if(this.monsterSceneLimit > 0){
this.monsterTideCount.decrementAndGet();
this.monsterAlive.incrementAndGet();
} }
List<GameEntity> toAdd = new ArrayList<>(); MonsterData data = GameData.getMonsterDataMap().get(monster.monster_id);
for (SceneMonster monster : monsters) { if (data == null) {
MonsterData data = GameData.getMonsterDataMap().get(monster.monster_id); return;
if (data == null) {
continue;
}
// Calculate level
int level = monster.level;
if (getScene().getDungeonData() != null) {
level = getScene().getDungeonData().getShowLevel();
} else if (getScene().getWorld().getWorldLevel() > 0) {
WorldLevelData worldLevelData = GameData.getWorldLevelDataMap().get(getScene().getWorld().getWorldLevel());
if (worldLevelData != null) {
level = worldLevelData.getMonsterLevel();
}
}
// Spawn mob
EntityMonster entity = new EntityMonster(getScene(), data, monster.pos, level);
entity.getRotation().set(monster.rot);
entity.setGroupId(group.id);
entity.setConfigId(monster.config_id);
toAdd.add(entity);
} }
if (toAdd.size() > 0) { // Calculate level
getScene().addEntities(toAdd); int level = monster.level;
for (GameEntity entity : toAdd) { if (getScene().getDungeonData() != null) {
callEvent(EventType.EVENT_ANY_MONSTER_LIVE, new ScriptArgs(entity.getConfigId())); level = getScene().getDungeonData().getShowLevel();
} else if (getScene().getWorld().getWorldLevel() > 0) {
WorldLevelData worldLevelData = GameData.getWorldLevelDataMap().get(getScene().getWorld().getWorldLevel());
if (worldLevelData != null) {
level = worldLevelData.getMonsterLevel();
}
}
// Spawn mob
EntityMonster entity = new EntityMonster(getScene(), data, monster.pos, level);
entity.getRotation().set(monster.rot);
entity.setGroupId(group.id);
entity.setConfigId(monster.config_id);
getScene().addEntity(entity);
callEvent(EventType.EVENT_ANY_MONSTER_LIVE, new ScriptArgs(entity.getConfigId()));
}
public void onMonsterDie(){
if(this.monsterSceneLimit <= 0){
return;
}
if(this.monsterAlive.decrementAndGet() >= this.monsterSceneLimit) {
// maybe not happen
return;
}
if(this.monsterTideCount.get() > 0){
// add more
spawnMonstersInGroup(this.currentGroup, this.currentGroup.monsters.get(this.monsterOrders.poll()));
}else if(this.monsterAlive.get() == 0){
// spawn the last turn of monsters
while(!this.monsterOrders.isEmpty()){
spawnMonstersInGroup(this.currentGroup, this.currentGroup.monsters.get(this.monsterOrders.poll()));
} }
} }
} }
// Events // Events
public void callEvent(int eventType, ScriptArgs params) { public void callEvent(int eventType, ScriptArgs params) {
@ -405,4 +434,8 @@ public class SceneScriptManager {
} }
} }
} }
// public LuaValue safetyCall(){
//
// }
} }

View File

@ -1,28 +1,24 @@
package emu.grasscutter.scripts; package emu.grasscutter.scripts;
import java.util.ArrayList;
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;
import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.game.dungeons.DungeonChallenge; import emu.grasscutter.game.dungeons.DungeonChallenge;
import emu.grasscutter.game.entity.EntityGadget; import emu.grasscutter.game.entity.EntityGadget;
import emu.grasscutter.game.entity.EntityMonster; import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.entity.GameEntity; import emu.grasscutter.game.entity.GameEntity;
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.SceneRegion; import emu.grasscutter.scripts.data.SceneRegion;
import emu.grasscutter.scripts.data.ScriptArgs; import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
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;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Optional;
public class ScriptLib { public class ScriptLib {
public static final Logger logger = LoggerFactory.getLogger(ScriptLib.class);
private final SceneScriptManager sceneScriptManager; private final SceneScriptManager sceneScriptManager;
public ScriptLib(SceneScriptManager sceneScriptManager) { public ScriptLib(SceneScriptManager sceneScriptManager) {
@ -34,6 +30,8 @@ public class ScriptLib {
} }
public int SetGadgetStateByConfigId(int configId, int gadgetState) { public int SetGadgetStateByConfigId(int configId, int gadgetState) {
logger.debug("[LUA] Call SetGadgetStateByConfigId with {},{}",
configId,gadgetState);
Optional<GameEntity> entity = getSceneScriptManager().getScene().getEntities().values().stream() Optional<GameEntity> entity = getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e.getConfigId() == configId).findFirst(); .filter(e -> e.getConfigId() == configId).findFirst();
@ -53,6 +51,8 @@ public class ScriptLib {
} }
public int SetGroupGadgetStateByConfigId(int groupId, int configId, int gadgetState) { public int SetGroupGadgetStateByConfigId(int groupId, int configId, int gadgetState) {
logger.debug("[LUA] Call SetGroupGadgetStateByConfigId with {},{},{}",
groupId,configId,gadgetState);
List<GameEntity> list = getSceneScriptManager().getScene().getEntities().values().stream() List<GameEntity> list = getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e.getGroupId() == groupId).toList(); .filter(e -> e.getGroupId() == groupId).toList();
@ -71,6 +71,8 @@ public class ScriptLib {
} }
public int SetWorktopOptionsByGroupId(int groupId, int configId, int[] options) { public int SetWorktopOptionsByGroupId(int groupId, int configId, int[] options) {
logger.debug("[LUA] Call SetWorktopOptionsByGroupId with {},{},{}",
groupId,configId,options);
Optional<GameEntity> entity = getSceneScriptManager().getScene().getEntities().values().stream() Optional<GameEntity> entity = getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e.getConfigId() == configId && e.getGroupId() == groupId).findFirst(); .filter(e -> e.getConfigId() == configId && e.getGroupId() == groupId).findFirst();
@ -90,6 +92,8 @@ public class ScriptLib {
} }
public int DelWorktopOptionByGroupId(int groupId, int configId, int option) { public int DelWorktopOptionByGroupId(int groupId, int configId, int option) {
logger.debug("[LUA] Call DelWorktopOptionByGroupId with {},{},{}",groupId,configId,option);
Optional<GameEntity> entity = getSceneScriptManager().getScene().getEntities().values().stream() Optional<GameEntity> entity = getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e.getConfigId() == configId && e.getGroupId() == groupId).findFirst(); .filter(e -> e.getConfigId() == configId && e.getGroupId() == groupId).findFirst();
@ -109,20 +113,24 @@ public class ScriptLib {
} }
// Some fields are guessed // Some fields are guessed
public int AutoMonsterTide(int challengeIndex, int groupId, int[] config_ids, int param4, int param5, int param6) { 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); SceneGroup group = getSceneScriptManager().getGroupById(groupId);
if (group == null || group.monsters == null) { if (group == null || group.monsters == null) {
return 1; return 1;
} }
// TODO just spawn all from group for now this.getSceneScriptManager().spawnMonstersInGroup(group, ordersConfigId, tideCount, sceneLimit);
this.getSceneScriptManager().spawnMonstersInGroup(group);
return 0; return 0;
} }
public int AddExtraGroupSuite(int groupId, int suite) { public int AddExtraGroupSuite(int groupId, int suite) {
logger.debug("[LUA] Call AddExtraGroupSuite with {},{}",
groupId,suite);
SceneGroup group = getSceneScriptManager().getGroupById(groupId); SceneGroup group = getSceneScriptManager().getGroupById(groupId);
if (group == null || group.monsters == null) { if (group == null || group.monsters == null) {
@ -136,8 +144,17 @@ public class ScriptLib {
} }
// param3 (probably time limit for timed dungeons) // param3 (probably time limit for timed dungeons)
public int ActiveChallenge(int challengeId, int challengeIndex, int param3, int groupId, int objectiveKills, int param5) { 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);
SceneGroup group = getSceneScriptManager().getGroupById(groupId); SceneGroup group = getSceneScriptManager().getGroupById(groupId);
var objective = objectiveKills;
if(group == null){
group = getSceneScriptManager().getGroupById(timeLimitOrGroupId);
objective = groupId;
}
if (group == null || group.monsters == null) { if (group == null || group.monsters == null) {
return 1; return 1;
@ -146,7 +163,7 @@ public class ScriptLib {
DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(), group); DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(), group);
challenge.setChallengeId(challengeId); challenge.setChallengeId(challengeId);
challenge.setChallengeIndex(challengeIndex); challenge.setChallengeIndex(challengeIndex);
challenge.setObjective(objectiveKills); challenge.setObjective(objective);
getSceneScriptManager().getScene().setChallenge(challenge); getSceneScriptManager().getScene().setChallenge(challenge);
@ -155,26 +172,37 @@ public class ScriptLib {
} }
public int GetGroupMonsterCountByGroupId(int groupId) { public int GetGroupMonsterCountByGroupId(int groupId) {
logger.debug("[LUA] Call GetGroupMonsterCountByGroupId with {}",
groupId);
return (int) getSceneScriptManager().getScene().getEntities().values().stream() return (int) getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e instanceof EntityMonster && e.getGroupId() == groupId) .filter(e -> e instanceof EntityMonster && e.getGroupId() == groupId)
.count(); .count();
} }
public int GetGroupVariableValue(String var) { public int GetGroupVariableValue(String var) {
logger.debug("[LUA] Call GetGroupVariableValue with {}",
var);
return getSceneScriptManager().getVariables().getOrDefault(var, 0); return getSceneScriptManager().getVariables().getOrDefault(var, 0);
} }
public int SetGroupVariableValue(String var, int value) { public int SetGroupVariableValue(String var, int value) {
logger.debug("[LUA] Call SetGroupVariableValue with {},{}",
var, value);
getSceneScriptManager().getVariables().put(var, value); getSceneScriptManager().getVariables().put(var, value);
return 0; return 0;
} }
public LuaValue ChangeGroupVariableValue(String var, int value) { public LuaValue ChangeGroupVariableValue(String var, int value) {
logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}",
var, value);
getSceneScriptManager().getVariables().put(var, getSceneScriptManager().getVariables().get(var) + value); getSceneScriptManager().getVariables().put(var, getSceneScriptManager().getVariables().get(var) + value);
return LuaValue.ZERO; return LuaValue.ZERO;
} }
public int RefreshGroup(LuaTable table) { public int RefreshGroup(LuaTable table) {
logger.debug("[LUA] Call RefreshGroup with {}",
table);
// Kill and Respawn? // Kill and Respawn?
int groupId = table.get("group_id").toint(); int groupId = table.get("group_id").toint();
int suite = table.get("suite").toint(); int suite = table.get("suite").toint();
@ -192,6 +220,8 @@ public class ScriptLib {
} }
public int GetRegionEntityCount(LuaTable table) { public int GetRegionEntityCount(LuaTable table) {
logger.debug("[LUA] Call GetRegionEntityCount with {}",
table);
int regionId = table.get("region_eid").toint(); int regionId = table.get("region_eid").toint();
int entityType = table.get("entity_type").toint(); int entityType = table.get("entity_type").toint();
@ -205,21 +235,68 @@ public class ScriptLib {
} }
public void PrintContextLog(String msg) { public void PrintContextLog(String msg) {
Grasscutter.getLogger().info("[LUA] " + msg); logger.info("[LUA] " + msg);
} }
public int TowerCountTimeStatus(int var1, int var2){ public int TowerCountTimeStatus(int isDone, int var2){
logger.debug("[LUA] Call TowerCountTimeStatus with {},{}",
isDone,var2);
// TODO record time
return 0; return 0;
} }
public int GetGroupMonsterCount(int var1){ public int GetGroupMonsterCount(int var1){
// Maybe... logger.debug("[LUA] Call GetGroupMonsterCount with {}",
return GetGroupMonsterCountByGroupId(var1); var1);
return (int) getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e instanceof EntityMonster)
.count();
} }
public int SetMonsterBattleByGroup(int var1, int var2, int var3){ public int SetMonsterBattleByGroup(int var1, int var2, int var3){
logger.debug("[LUA] Call SetMonsterBattleByGroup with {},{},{}",
var1,var2,var3);
return 0; return 0;
} }
public int CauseDungeonFail(int var1){ public int CauseDungeonFail(int var1){
logger.debug("[LUA] Call CauseDungeonFail with {}",
var1);
return 0; return 0;
} }
// 8-1
public int GetGroupVariableValueByGroup(int var1, String var2, int var3){
logger.debug("[LUA] Call GetGroupVariableValueByGroup with {},{},{}",
var1,var2,var3);
//TODO
return getSceneScriptManager().getVariables().getOrDefault(var2, 0);
}
public int SetIsAllowUseSkill(int canUse, int var2){
logger.debug("[LUA] Call SetIsAllowUseSkill with {},{}",
canUse,var2);
getSceneScriptManager().getScene().broadcastPacket(new PacketCanUseSkillNotify(canUse == 1));
return 0;
}
public int KillEntityByConfigId(LuaTable table){
logger.debug("[LUA] Call KillEntityByConfigId with {}",
table);
var configId = table.get("config_id");
if(configId == LuaValue.NIL){
return 1;
}
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId.toint());
if(entity == null){
return 1;
}
getSceneScriptManager().getScene().killEntity(entity, 0);
return 0;
}
} }

View File

@ -1,17 +1,21 @@
package emu.grasscutter.scripts.data; package emu.grasscutter.scripts.data;
import java.util.List;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import java.util.List;
import java.util.Map;
public class SceneGroup { public class SceneGroup {
public transient int block_id; // Not an actual variable in the scripts but we will keep it here for reference public transient int block_id; // Not an actual variable in the scripts but we will keep it here for reference
public int id; public int id;
public int refresh_id; public int refresh_id;
public Position pos; public Position pos;
public List<SceneMonster> monsters; /**
* ConfigId - Monster
*/
public Map<Integer,SceneMonster> monsters;
public List<SceneGadget> gadgets; public List<SceneGadget> gadgets;
public List<SceneTrigger> triggers; public List<SceneTrigger> triggers;
public List<SceneRegion> regions; public List<SceneRegion> regions;

View File

@ -0,0 +1,19 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.CanUseSkillNotifyOuterClass;
public class PacketCanUseSkillNotify extends BasePacket {
public PacketCanUseSkillNotify(boolean canUseSkill) {
super(PacketOpcodes.CanUseSkillNotify);
CanUseSkillNotifyOuterClass.CanUseSkillNotify proto = CanUseSkillNotifyOuterClass.CanUseSkillNotify.newBuilder()
.setIsCanUseSkill(canUseSkill)
.build();
this.setData(proto);
}
}

View File

@ -19,4 +19,6 @@
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</root> </root>
<logger name="emu.grasscutter.scripts.ScriptLib" level="DEBUG">
</logger>
</Configuration> </Configuration>