Commit faa3cde5 authored by Akka's avatar Akka
Browse files

fix the Monster spawn between stage challenges

parent 45b45c4b
{ {
"scheduleId" : 1, "scheduleId" : 45,
"scheduleStartTime" : "2022-05-01T00:00:00+08:00", "scheduleStartTime" : "2022-05-01T00:00:00+08:00",
"nextScheduleChangeTime" : "2022-05-30T00:00:00+08:00" "nextScheduleChangeTime" : "2022-05-30T00:00:00+08:00"
} }
\ No newline at end of file
...@@ -28,14 +28,20 @@ public class DungeonChallenge { ...@@ -28,14 +28,20 @@ public class DungeonChallenge {
private int challengeId; private int challengeId;
private boolean success; private boolean success;
private boolean progress; private boolean progress;
/**
* has more challenge
*/
private boolean stage;
private int score; private int score;
private int objective = 0; private int objective = 0;
private IntSet rewardedPlayers; private IntSet rewardedPlayers;
public DungeonChallenge(Scene scene, SceneGroup group) { public DungeonChallenge(Scene scene, SceneGroup group, int challengeId, int challengeIndex, int objective) {
this.scene = scene; this.scene = scene;
this.group = group; this.group = group;
this.challengeId = challengeId;
this.challengeIndex = challengeIndex;
this.objective = objective;
this.setRewardedPlayers(new IntOpenHashSet()); this.setRewardedPlayers(new IntOpenHashSet());
} }
...@@ -86,7 +92,15 @@ public class DungeonChallenge { ...@@ -86,7 +92,15 @@ public class DungeonChallenge {
public int getScore() { public int getScore() {
return score; return score;
} }
public boolean isStage() {
return stage;
}
public void setStage(boolean stage) {
this.stage = stage;
}
public int getTimeLimit() { public int getTimeLimit() {
return 600; return 600;
} }
...@@ -112,7 +126,7 @@ public class DungeonChallenge { ...@@ -112,7 +126,7 @@ public class DungeonChallenge {
if (this.isSuccess()) { if (this.isSuccess()) {
// Call success script event // Call success script event
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS, null); this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS, null);
// Settle // Settle
settle(); settle();
} else { } else {
...@@ -122,8 +136,10 @@ public class DungeonChallenge { ...@@ -122,8 +136,10 @@ public class DungeonChallenge {
private void settle() { private void settle() {
getScene().getDungeonSettleObservers().forEach(o -> o.onDungeonSettle(getScene())); getScene().getDungeonSettleObservers().forEach(o -> o.onDungeonSettle(getScene()));
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE, new ScriptArgs(this.isSuccess() ? 1 : 0)); if(!stage){
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE, new ScriptArgs(this.isSuccess() ? 1 : 0));
}
} }
public void onMonsterDie(EntityMonster entity) { public void onMonsterDie(EntityMonster entity) {
......
...@@ -116,14 +116,18 @@ public class EntityMonster extends GameEntity { ...@@ -116,14 +116,18 @@ public class EntityMonster extends GameEntity {
if (this.getSpawnEntry() != null) { if (this.getSpawnEntry() != null) {
this.getScene().getDeadSpawnedEntities().add(getSpawnEntry()); this.getScene().getDeadSpawnedEntities().add(getSpawnEntry());
} }
// first set the challenge data
if (getScene().getChallenge() != null && getScene().getChallenge().getGroup().id == this.getGroupId()) {
getScene().getChallenge().onMonsterDie(this);
}
if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) { if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) {
if(getScene().getScriptManager().getScriptMonsterSpawnService() != null){ if(getScene().getScriptManager().getScriptMonsterSpawnService() != null){
getScene().getScriptManager().getScriptMonsterSpawnService().onMonsterDead(this); getScene().getScriptManager().getScriptMonsterSpawnService().onMonsterDead(this);
} }
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, null); // prevent spawn monster after success
} if(getScene().getChallenge() != null && getScene().getChallenge().inProgress()){
if (getScene().getChallenge() != null && getScene().getChallenge().getGroup().id == this.getGroupId()) { getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, null);
getScene().getChallenge().onMonsterDie(this); }
} }
} }
......
...@@ -122,7 +122,7 @@ public class TowerManager { ...@@ -122,7 +122,7 @@ public class TowerManager {
if(!hasNextLevel()){ if(!hasNextLevel()){
// set up the next floor // set up the next floor
recordMap.put(getNextFloorId(), new TowerLevelRecord(getNextFloorId())); recordMap.putIfAbsent(getNextFloorId(), new TowerLevelRecord(getNextFloorId()));
player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(getNextFloorId(), 1)); player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(getNextFloorId(), 1));
}else{ }else{
player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(currentFloorId, getCurrentLevel())); player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(currentFloorId, getCurrentLevel()));
......
...@@ -373,6 +373,12 @@ public class SceneScriptManager { ...@@ -373,6 +373,12 @@ public class SceneScriptManager {
new ScriptMonsterTideService(this, group, tideCount, sceneLimit, ordersConfigId); new ScriptMonsterTideService(this, group, tideCount, sceneLimit, ordersConfigId);
} }
public void unloadCurrentMonsterTide(){
if(this.getScriptMonsterTideService() == null){
return;
}
this.getScriptMonsterTideService().unload();
}
public void spawnMonstersByConfigId(int configId, int delayTime) { public void spawnMonstersByConfigId(int configId, int delayTime) {
// TODO delay // TODO delay
this.scriptMonsterSpawnService.spawnMonster(this.currentGroup.id, this.currentGroup.monsters.get(configId)); this.scriptMonsterSpawnService.spawnMonster(this.currentGroup.id, this.currentGroup.monsters.get(configId));
...@@ -395,12 +401,15 @@ public class SceneScriptManager { ...@@ -395,12 +401,15 @@ public class SceneScriptManager {
if (params != null) { if (params != null) {
args = CoerceJavaToLua.coerce(params); args = CoerceJavaToLua.coerce(params);
} }
ScriptLib.logger.trace("Call Condition Trigger {}", trigger);
ret = safetyCall(trigger.condition, condition, args); ret = safetyCall(trigger.condition, condition, args);
} }
if (ret.isboolean() && ret.checkboolean()) { if (ret.isboolean() && ret.checkboolean()) {
ScriptLib.logger.trace("Call Action Trigger {}", trigger);
LuaValue action = (LuaValue) this.getBindings().get(trigger.action); LuaValue action = (LuaValue) this.getBindings().get(trigger.action);
// TODO impl the param of SetGroupVariableValueByGroup
var arg = new ScriptArgs(); var arg = new ScriptArgs();
arg.param2 = 100; arg.param2 = 100;
var args = CoerceJavaToLua.coerce(arg); var args = CoerceJavaToLua.coerce(arg);
......
...@@ -147,6 +147,12 @@ public class ScriptLib { ...@@ -147,6 +147,12 @@ public class ScriptLib {
return 1; 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().spawnMonstersInGroup(group, suite);
return 0; return 0;
...@@ -175,13 +181,13 @@ public class ScriptLib { ...@@ -175,13 +181,13 @@ public class ScriptLib {
return 0; return 0;
} }
DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(), group); DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(),
challenge.setChallengeId(challengeId); group, challengeId, challengeIndex, objective);
challenge.setChallengeIndex(challengeIndex); // set if tower first stage (6-1)
challenge.setObjective(objective); challenge.setStage(getSceneScriptManager().getVariables().getOrDefault("stage", -1) == 0);
getSceneScriptManager().getScene().setChallenge(challenge); getSceneScriptManager().getScene().setChallenge(challenge);
challenge.start(); challenge.start();
return 0; return 0;
} }
...@@ -336,9 +342,19 @@ public class ScriptLib { ...@@ -336,9 +342,19 @@ public class ScriptLib {
logger.debug("[LUA] Call TowerMirrorTeamSetUp with {},{}", logger.debug("[LUA] Call TowerMirrorTeamSetUp with {},{}",
team,var1); team,var1);
getSceneScriptManager().unloadCurrentMonsterTide();
getSceneScriptManager().getScene().getPlayers().get(0).getTowerManager().mirrorTeamSetUp(team-1); getSceneScriptManager().getScene().getPlayers().get(0).getTowerManager().mirrorTeamSetUp(team-1);
return 0; return 0;
} }
public int CreateGadget(LuaTable table){
logger.debug("[LUA] Call CreateGadget with {}",
printTable(table));
var configId = table.get("config_id").toint();
//TODO
return 0;
}
} }
...@@ -21,4 +21,15 @@ public class SceneTrigger { ...@@ -21,4 +21,15 @@ public class SceneTrigger {
return name.hashCode(); return name.hashCode();
} }
@Override
public String toString() {
return "SceneTrigger{" +
"name='" + name + '\'' +
", config_id=" + config_id +
", event=" + event +
", source='" + source + '\'' +
", condition='" + condition + '\'' +
", action='" + action + '\'' +
'}';
}
} }
package emu.grasscutter.scripts.listener;
import emu.grasscutter.game.entity.EntityMonster;
public interface ScriptMonsterListener {
void onNotify(EntityMonster sceneMonster);
}
...@@ -8,31 +8,36 @@ import emu.grasscutter.scripts.SceneScriptManager; ...@@ -8,31 +8,36 @@ import emu.grasscutter.scripts.SceneScriptManager;
import emu.grasscutter.scripts.constants.EventType; import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneMonster; import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.scripts.data.ScriptArgs; import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.scripts.listener.ScriptMonsterListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
public class ScriptMonsterSpawnService { public class ScriptMonsterSpawnService {
private final SceneScriptManager sceneScriptManager; private final SceneScriptManager sceneScriptManager;
private final List<Consumer<EntityMonster>> onMonsterCreatedListener = new ArrayList<>(); private final List<ScriptMonsterListener> onMonsterCreatedListener = new ArrayList<>();
private final List<Consumer<EntityMonster>> onMonsterDeadListener = new ArrayList<>(); private final List<ScriptMonsterListener> onMonsterDeadListener = new ArrayList<>();
public ScriptMonsterSpawnService(SceneScriptManager sceneScriptManager){ public ScriptMonsterSpawnService(SceneScriptManager sceneScriptManager){
this.sceneScriptManager = sceneScriptManager; this.sceneScriptManager = sceneScriptManager;
} }
public void addMonsterCreatedListener(Consumer<EntityMonster> consumer){ public void addMonsterCreatedListener(ScriptMonsterListener scriptMonsterListener){
onMonsterCreatedListener.add(consumer); onMonsterCreatedListener.add(scriptMonsterListener);
} }
public void addMonsterDeadListener(Consumer<EntityMonster> consumer){ public void addMonsterDeadListener(ScriptMonsterListener scriptMonsterListener){
onMonsterDeadListener.add(consumer); onMonsterDeadListener.add(scriptMonsterListener);
}
public void removeMonsterCreatedListener(ScriptMonsterListener scriptMonsterListener){
onMonsterCreatedListener.remove(scriptMonsterListener);
}
public void removeMonsterDeadListener(ScriptMonsterListener scriptMonsterListener){
onMonsterDeadListener.remove(scriptMonsterListener);
} }
public void onMonsterDead(EntityMonster entityMonster){ public void onMonsterDead(EntityMonster entityMonster){
onMonsterDeadListener.forEach(l -> l.accept(entityMonster)); onMonsterDeadListener.forEach(l -> l.onNotify(entityMonster));
} }
public void spawnMonster(int groupId, SceneMonster monster) { public void spawnMonster(int groupId, SceneMonster monster) {
if(monster == null){ if(monster == null){
...@@ -64,7 +69,7 @@ public class ScriptMonsterSpawnService { ...@@ -64,7 +69,7 @@ public class ScriptMonsterSpawnService {
entity.setGroupId(groupId); entity.setGroupId(groupId);
entity.setConfigId(monster.config_id); entity.setConfigId(monster.config_id);
onMonsterCreatedListener.forEach(action -> action.accept(entity)); onMonsterCreatedListener.forEach(action -> action.onNotify(entity));
sceneScriptManager.getScene().addEntity(entity); sceneScriptManager.getScene().addEntity(entity);
......
...@@ -6,6 +6,7 @@ import emu.grasscutter.scripts.constants.EventType; ...@@ -6,6 +6,7 @@ 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.SceneMonster;
import emu.grasscutter.scripts.data.ScriptArgs; import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.scripts.listener.ScriptMonsterListener;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
...@@ -19,6 +20,8 @@ public class ScriptMonsterTideService { ...@@ -19,6 +20,8 @@ public class ScriptMonsterTideService {
private final AtomicInteger monsterKillCount; private final AtomicInteger monsterKillCount;
private final int monsterSceneLimit; private final int monsterSceneLimit;
private final ConcurrentLinkedQueue<Integer> monsterConfigOrders; private final ConcurrentLinkedQueue<Integer> monsterConfigOrders;
private final OnMonsterCreated onMonsterCreated= new OnMonsterCreated();
private final OnMonsterDead onMonsterDead= new OnMonsterDead();
public ScriptMonsterTideService(SceneScriptManager sceneScriptManager, public ScriptMonsterTideService(SceneScriptManager sceneScriptManager,
SceneGroup group, int tideCount, int monsterSceneLimit, Integer[] ordersConfigId){ SceneGroup group, int tideCount, int monsterSceneLimit, Integer[] ordersConfigId){
...@@ -30,18 +33,21 @@ public class ScriptMonsterTideService { ...@@ -30,18 +33,21 @@ public class ScriptMonsterTideService {
this.monsterAlive = new AtomicInteger(0); this.monsterAlive = new AtomicInteger(0);
this.monsterConfigOrders = new ConcurrentLinkedQueue<>(List.of(ordersConfigId)); this.monsterConfigOrders = new ConcurrentLinkedQueue<>(List.of(ordersConfigId));
this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterCreatedListener(this::onMonsterCreated); this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterCreatedListener(onMonsterCreated);
this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterDeadListener(this::onMonsterDead); this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterDeadListener(onMonsterDead);
// spawn the first turn // spawn the first turn
for (int i = 0; i < this.monsterSceneLimit; i++) { for (int i = 0; i < this.monsterSceneLimit; i++) {
this.sceneScriptManager.getScriptMonsterSpawnService().spawnMonster(group.id, getNextMonster()); this.sceneScriptManager.getScriptMonsterSpawnService().spawnMonster(group.id, getNextMonster());
} }
} }
public void onMonsterCreated(EntityMonster entityMonster){ public class OnMonsterCreated implements ScriptMonsterListener{
if(this.monsterSceneLimit > 0){ @Override
this.monsterTideCount.decrementAndGet(); public void onNotify(EntityMonster sceneMonster) {
this.monsterAlive.incrementAndGet(); if(monsterSceneLimit > 0){
monsterAlive.incrementAndGet();
monsterTideCount.decrementAndGet();
}
} }
} }
...@@ -54,21 +60,29 @@ public class ScriptMonsterTideService { ...@@ -54,21 +60,29 @@ public class ScriptMonsterTideService {
return currentGroup.monsters.values().stream().findFirst().orElse(null); return currentGroup.monsters.values().stream().findFirst().orElse(null);
} }
public void onMonsterDead(EntityMonster entityMonster){ public class OnMonsterDead implements ScriptMonsterListener{
if(this.monsterSceneLimit <= 0){ @Override
return; public void onNotify(EntityMonster sceneMonster) {
if(monsterSceneLimit <= 0){
return;
}
if(monsterAlive.decrementAndGet() >= monsterSceneLimit) {
// maybe not happen
return;
}
monsterKillCount.incrementAndGet();
if(monsterTideCount.get() > 0){
// add more
sceneScriptManager.getScriptMonsterSpawnService().spawnMonster(currentGroup.id, getNextMonster());
}
// spawn the last turn of monsters
// fix the 5-2
sceneScriptManager.callEvent(EventType.EVENT_MONSTER_TIDE_DIE, new ScriptArgs(monsterKillCount.get()));
} }
if(this.monsterAlive.decrementAndGet() >= this.monsterSceneLimit) { }
// maybe not happen
return; public void unload(){
} this.sceneScriptManager.getScriptMonsterSpawnService().removeMonsterCreatedListener(onMonsterCreated);
this.monsterKillCount.incrementAndGet(); this.sceneScriptManager.getScriptMonsterSpawnService().removeMonsterDeadListener(onMonsterDead);
if(this.monsterTideCount.get() > 0){
// add more
this.sceneScriptManager.getScriptMonsterSpawnService().spawnMonster(this.currentGroup.id, getNextMonster());
}
// spawn the last turn of monsters
// fix the 5-2
this.sceneScriptManager.callEvent(EventType.EVENT_MONSTER_TIDE_DIE, new ScriptArgs(this.monsterKillCount.get()));
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment