mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-17 01:15:52 +01:00
refactor the challenge
This commit is contained in:
@@ -26,16 +26,13 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SceneScriptManager {
|
||||
private final Scene scene;
|
||||
private final Map<String, Integer> variables;
|
||||
private SceneMeta meta;
|
||||
private boolean isInit;
|
||||
/**
|
||||
* SceneTrigger Set
|
||||
*/
|
||||
private final Map<String, SceneTrigger> triggers;
|
||||
/**
|
||||
* current triggers controlled by RefreshGroup
|
||||
*/
|
||||
@@ -51,12 +48,11 @@ public class SceneScriptManager {
|
||||
public static final ExecutorService eventExecutor;
|
||||
static {
|
||||
eventExecutor = new ThreadPoolExecutor(4, 4,
|
||||
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100),
|
||||
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000),
|
||||
FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
||||
public SceneScriptManager(Scene scene) {
|
||||
this.scene = scene;
|
||||
this.triggers = new HashMap<>();
|
||||
this.currentTriggers = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
this.regions = new Int2ObjectOpenHashMap<>();
|
||||
@@ -96,13 +92,16 @@ public class SceneScriptManager {
|
||||
public Set<SceneTrigger> getTriggersByEvent(int eventId) {
|
||||
return currentTriggers.computeIfAbsent(eventId, e -> new HashSet<>());
|
||||
}
|
||||
public void registerTrigger(List<SceneTrigger> triggers) {
|
||||
triggers.forEach(this::registerTrigger);
|
||||
}
|
||||
public void registerTrigger(SceneTrigger trigger) {
|
||||
this.triggers.put(trigger.name, trigger);
|
||||
getTriggersByEvent(trigger.event).add(trigger);
|
||||
}
|
||||
|
||||
public void deregisterTrigger(List<SceneTrigger> triggers) {
|
||||
triggers.forEach(this::deregisterTrigger);
|
||||
}
|
||||
public void deregisterTrigger(SceneTrigger trigger) {
|
||||
this.triggers.remove(trigger.name);
|
||||
getTriggersByEvent(trigger.event).remove(trigger);
|
||||
}
|
||||
public void resetTriggers(int eventId) {
|
||||
@@ -205,7 +204,17 @@ public class SceneScriptManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addGroupSuite(SceneGroup group, SceneSuite suite){
|
||||
spawnMonstersInGroup(group, suite);
|
||||
spawnGadgetsInGroup(group, suite);
|
||||
registerTrigger(suite.sceneTriggers);
|
||||
}
|
||||
public void removeGroupSuite(SceneGroup group, SceneSuite suite){
|
||||
removeMonstersInGroup(group, suite);
|
||||
removeGadgetsInGroup(group, suite);
|
||||
deregisterTrigger(suite.sceneTriggers);
|
||||
}
|
||||
public void spawnGadgetsInGroup(SceneGroup group, int suiteIndex) {
|
||||
spawnGadgetsInGroup(group, group.getSuiteByIndex(suiteIndex));
|
||||
}
|
||||
@@ -241,7 +250,6 @@ public class SceneScriptManager {
|
||||
}
|
||||
this.addEntities(suite.sceneMonsters.stream()
|
||||
.map(mob -> createMonster(group.id, group.block_id, mob)).toList());
|
||||
|
||||
}
|
||||
|
||||
public void spawnMonstersInGroup(SceneGroup group) {
|
||||
@@ -326,7 +334,7 @@ public class SceneScriptManager {
|
||||
try{
|
||||
return func.call(ScriptLoader.getScriptLibLua(), args);
|
||||
}catch (LuaError error){
|
||||
ScriptLib.logger.error("[LUA] call trigger failed {},{},{}",name,args,error.getMessage());
|
||||
ScriptLib.logger.error("[LUA] call trigger failed {},{}",name,args,error);
|
||||
return LuaValue.valueOf(-1);
|
||||
}
|
||||
}
|
||||
@@ -388,6 +396,7 @@ public class SceneScriptManager {
|
||||
entity.setGroupId(groupId);
|
||||
entity.setBlockId(blockId);
|
||||
entity.setConfigId(monster.config_id);
|
||||
entity.setPoseId(monster.pose_id);
|
||||
|
||||
this.getScriptMonsterSpawnService()
|
||||
.onMonsterCreatedListener.forEach(action -> action.onNotify(entity));
|
||||
@@ -410,4 +419,28 @@ public class SceneScriptManager {
|
||||
public PhTree<SceneBlock> getBlocksIndex() {
|
||||
return meta.sceneBlockIndex;
|
||||
}
|
||||
public void removeMonstersInGroup(SceneGroup group, SceneSuite suite) {
|
||||
var configSet = suite.sceneMonsters.stream()
|
||||
.map(m -> m.config_id)
|
||||
.collect(Collectors.toSet());
|
||||
var toRemove = getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityMonster)
|
||||
.filter(e -> e.getGroupId() == group.id)
|
||||
.filter(e -> configSet.contains(e.getConfigId()))
|
||||
.toList();
|
||||
|
||||
getScene().removeEntities(toRemove, VisionTypeOuterClass.VisionType.VISION_MISS);
|
||||
}
|
||||
public void removeGadgetsInGroup(SceneGroup group, SceneSuite suite) {
|
||||
var configSet = suite.sceneGadgets.stream()
|
||||
.map(m -> m.config_id)
|
||||
.collect(Collectors.toSet());
|
||||
var toRemove = getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityGadget)
|
||||
.filter(e -> e.getGroupId() == group.id)
|
||||
.filter(e -> configSet.contains(e.getConfigId()))
|
||||
.toList();
|
||||
|
||||
getScene().removeEntities(toRemove, VisionTypeOuterClass.VisionType.VISION_MISS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package emu.grasscutter.scripts;
|
||||
|
||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
||||
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
|
||||
import emu.grasscutter.game.entity.EntityGadget;
|
||||
import emu.grasscutter.game.entity.EntityMonster;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
||||
import emu.grasscutter.game.dungeons.challenge.factory.ChallengeFactory;
|
||||
import emu.grasscutter.scripts.data.SceneGroup;
|
||||
import emu.grasscutter.scripts.data.SceneRegion;
|
||||
import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
|
||||
@@ -159,48 +160,102 @@ public class ScriptLib {
|
||||
if (group == null || group.monsters == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
var suiteData = group.getSuiteByIndex(suite);
|
||||
if(suiteData == null){
|
||||
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().spawnMonstersInGroup(group, suite);
|
||||
|
||||
this.getSceneScriptManager().addGroupSuite(group, suiteData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
public int GoToGroupSuite(int groupId, int suite) {
|
||||
logger.debug("[LUA] Call GoToGroupSuite 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;
|
||||
}
|
||||
|
||||
for(var suiteItem : group.suites){
|
||||
if(suiteData == suiteItem){
|
||||
continue;
|
||||
}
|
||||
this.getSceneScriptManager().removeGroupSuite(group, suiteItem);
|
||||
}
|
||||
this.getSceneScriptManager().addGroupSuite(group, suiteData);
|
||||
|
||||
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().removeGroupSuite(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);
|
||||
|
||||
SceneGroup group = getSceneScriptManager().getGroupById(groupId);
|
||||
var objective = objectiveKills;
|
||||
var challenge = ChallengeFactory.getChallenge(
|
||||
challengeId,
|
||||
challengeIndex,
|
||||
timeLimitOrGroupId,
|
||||
groupId,
|
||||
objectiveKills,
|
||||
param5,
|
||||
getSceneScriptManager().getScene(),
|
||||
getCurrentGroup().get()
|
||||
);
|
||||
|
||||
if(group == null){
|
||||
group = getSceneScriptManager().getGroupById(timeLimitOrGroupId);
|
||||
objective = groupId;
|
||||
}
|
||||
|
||||
if (group == null || group.monsters == null) {
|
||||
if(challenge == null){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(getSceneScriptManager().getScene().getChallenge() != null &&
|
||||
getSceneScriptManager().getScene().getChallenge().inProgress())
|
||||
{
|
||||
return 0;
|
||||
if(challenge instanceof DungeonChallenge dungeonChallenge){
|
||||
// set if tower first stage (6-1)
|
||||
dungeonChallenge.setStage(getSceneScriptManager().getVariables().getOrDefault("stage", -1) == 0);
|
||||
}
|
||||
|
||||
DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(),
|
||||
group, challengeId, challengeIndex, objective);
|
||||
// set if tower first stage (6-1)
|
||||
challenge.setStage(getSceneScriptManager().getVariables().getOrDefault("stage", -1) == 0);
|
||||
|
||||
getSceneScriptManager().getScene().setChallenge(challenge);
|
||||
|
||||
challenge.start();
|
||||
return 0;
|
||||
}
|
||||
@@ -257,7 +312,7 @@ public class ScriptLib {
|
||||
|
||||
public int GetRegionEntityCount(LuaTable table) {
|
||||
logger.debug("[LUA] Call GetRegionEntityCount with {}",
|
||||
table);
|
||||
printTable(table));
|
||||
int regionId = table.get("region_eid").toint();
|
||||
int entityType = table.get("entity_type").toint();
|
||||
|
||||
@@ -280,9 +335,8 @@ public class ScriptLib {
|
||||
// TODO record time
|
||||
return 0;
|
||||
}
|
||||
public int GetGroupMonsterCount(int var1){
|
||||
logger.debug("[LUA] Call GetGroupMonsterCount with {}",
|
||||
var1);
|
||||
public int GetGroupMonsterCount(){
|
||||
logger.debug("[LUA] Call GetGroupMonsterCount ");
|
||||
|
||||
return (int) getSceneScriptManager().getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityMonster &&
|
||||
@@ -328,7 +382,7 @@ public class ScriptLib {
|
||||
|
||||
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId.toint());
|
||||
if(entity == null){
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
getSceneScriptManager().getScene().killEntity(entity, 0);
|
||||
return 0;
|
||||
@@ -398,8 +452,13 @@ public class ScriptLib {
|
||||
public int GetGadgetStateByConfigId(int groupId, int configId){
|
||||
logger.debug("[LUA] Call GetGadgetStateByConfigId with {},{}",
|
||||
groupId, configId);
|
||||
|
||||
if(groupId == 0){
|
||||
groupId = getCurrentGroup().get().id;
|
||||
}
|
||||
final int realGroupId = groupId;
|
||||
var gadget = getSceneScriptManager().getScene().getEntities().values().stream()
|
||||
.filter(g -> g instanceof EntityGadget entityGadget && entityGadget.getGroupId() == groupId)
|
||||
.filter(g -> g instanceof EntityGadget entityGadget && entityGadget.getGroupId() == realGroupId)
|
||||
.filter(g -> g.getConfigId() == configId)
|
||||
.findFirst();
|
||||
if(gadget.isEmpty()){
|
||||
@@ -409,8 +468,8 @@ public class ScriptLib {
|
||||
}
|
||||
|
||||
public int MarkPlayerAction(int var1, int var2, int var3, int var4){
|
||||
logger.debug("[LUA] Call MarkPlayerAction with {},{}",
|
||||
var1, var2);
|
||||
logger.debug("[LUA] Call MarkPlayerAction with {},{},{},{}",
|
||||
var1, var2,var3,var4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,4 +10,5 @@ public class SceneGadget extends SceneObject{
|
||||
public int state;
|
||||
public int point_type;
|
||||
public SceneBossChest boss_chest;
|
||||
public int interact_id;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class SceneGroup {
|
||||
return bindings;
|
||||
}
|
||||
|
||||
public SceneGroup load(int sceneId){
|
||||
public synchronized SceneGroup load(int sceneId){
|
||||
if(loaded){
|
||||
return this;
|
||||
}
|
||||
@@ -118,6 +118,7 @@ public class SceneGroup {
|
||||
garbages = new SceneGarbage();
|
||||
if (garbagesTable.checktable().get("gadgets") != LuaValue.NIL) {
|
||||
garbages.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, garbagesTable.checktable().get("gadgets").checktable());
|
||||
garbages.gadgets.forEach(m -> m.group = this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,4 +7,6 @@ import lombok.ToString;
|
||||
@Setter
|
||||
public class SceneMonster extends SceneObject{
|
||||
public int monster_id;
|
||||
public int pose_id;
|
||||
public int drop_id;
|
||||
}
|
||||
Reference in New Issue
Block a user