Skip to content
Snippets Groups Projects
Commit faa3cde5 authored by Akka's avatar Akka
Browse files

fix the Monster spawn between stage challenges

parent 45b45c4b
No related merge requests found
Showing
with 133 additions and 50 deletions
{
"scheduleId" : 1,
"scheduleId" : 45,
"scheduleStartTime" : "2022-05-01T00: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 {
private int challengeId;
private boolean success;
private boolean progress;
/**
* has more challenge
*/
private boolean stage;
private int score;
private int objective = 0;
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.group = group;
this.challengeId = challengeId;
this.challengeIndex = challengeIndex;
this.objective = objective;
this.setRewardedPlayers(new IntOpenHashSet());
}
......@@ -87,6 +93,14 @@ public class DungeonChallenge {
return score;
}
public boolean isStage() {
return stage;
}
public void setStage(boolean stage) {
this.stage = stage;
}
public int getTimeLimit() {
return 600;
}
......@@ -123,8 +137,10 @@ public class DungeonChallenge {
private void settle() {
getScene().getDungeonSettleObservers().forEach(o -> o.onDungeonSettle(getScene()));
if(!stage){
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE, new ScriptArgs(this.isSuccess() ? 1 : 0));
}
}
public void onMonsterDie(EntityMonster entity) {
score = getScore() + 1;
......
......@@ -116,14 +116,18 @@ public class EntityMonster extends GameEntity {
if (this.getSpawnEntry() != null) {
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().getScriptMonsterSpawnService() != null){
getScene().getScriptManager().getScriptMonsterSpawnService().onMonsterDead(this);
}
// prevent spawn monster after success
if(getScene().getChallenge() != null && getScene().getChallenge().inProgress()){
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, null);
}
if (getScene().getChallenge() != null && getScene().getChallenge().getGroup().id == this.getGroupId()) {
getScene().getChallenge().onMonsterDie(this);
}
}
......
......@@ -122,7 +122,7 @@ public class TowerManager {
if(!hasNextLevel()){
// set up the next floor
recordMap.put(getNextFloorId(), new TowerLevelRecord(getNextFloorId()));
recordMap.putIfAbsent(getNextFloorId(), new TowerLevelRecord(getNextFloorId()));
player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(getNextFloorId(), 1));
}else{
player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(currentFloorId, getCurrentLevel()));
......
......@@ -373,6 +373,12 @@ public class SceneScriptManager {
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) {
// TODO delay
this.scriptMonsterSpawnService.spawnMonster(this.currentGroup.id, this.currentGroup.monsters.get(configId));
......@@ -396,11 +402,14 @@ public class SceneScriptManager {
args = CoerceJavaToLua.coerce(params);
}
ScriptLib.logger.trace("Call Condition Trigger {}", trigger);
ret = safetyCall(trigger.condition, condition, args);
}
if (ret.isboolean() && ret.checkboolean()) {
ScriptLib.logger.trace("Call Action Trigger {}", trigger);
LuaValue action = (LuaValue) this.getBindings().get(trigger.action);
// TODO impl the param of SetGroupVariableValueByGroup
var arg = new ScriptArgs();
arg.param2 = 100;
var args = CoerceJavaToLua.coerce(arg);
......
......@@ -147,6 +147,12 @@ public class ScriptLib {
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);
return 0;
......@@ -175,10 +181,10 @@ public class ScriptLib {
return 0;
}
DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(), group);
challenge.setChallengeId(challengeId);
challenge.setChallengeIndex(challengeIndex);
challenge.setObjective(objective);
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);
......@@ -336,9 +342,19 @@ public class ScriptLib {
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();
//TODO
return 0;
}
}
......@@ -21,4 +21,15 @@ public class SceneTrigger {
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;
import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.scripts.listener.ScriptMonsterListener;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class ScriptMonsterSpawnService {
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){
this.sceneScriptManager = sceneScriptManager;
}
public void addMonsterCreatedListener(Consumer<EntityMonster> consumer){
onMonsterCreatedListener.add(consumer);
public void addMonsterCreatedListener(ScriptMonsterListener scriptMonsterListener){
onMonsterCreatedListener.add(scriptMonsterListener);
}
public void addMonsterDeadListener(Consumer<EntityMonster> consumer){
onMonsterDeadListener.add(consumer);
public void addMonsterDeadListener(ScriptMonsterListener scriptMonsterListener){
onMonsterDeadListener.add(scriptMonsterListener);
}
public void removeMonsterCreatedListener(ScriptMonsterListener scriptMonsterListener){
onMonsterCreatedListener.remove(scriptMonsterListener);
}
public void removeMonsterDeadListener(ScriptMonsterListener scriptMonsterListener){
onMonsterDeadListener.remove(scriptMonsterListener);
}
public void onMonsterDead(EntityMonster entityMonster){
onMonsterDeadListener.forEach(l -> l.accept(entityMonster));
onMonsterDeadListener.forEach(l -> l.onNotify(entityMonster));
}
public void spawnMonster(int groupId, SceneMonster monster) {
if(monster == null){
......@@ -64,7 +69,7 @@ public class ScriptMonsterSpawnService {
entity.setGroupId(groupId);
entity.setConfigId(monster.config_id);
onMonsterCreatedListener.forEach(action -> action.accept(entity));
onMonsterCreatedListener.forEach(action -> action.onNotify(entity));
sceneScriptManager.getScene().addEntity(entity);
......
......@@ -6,6 +6,7 @@ import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.scripts.listener.ScriptMonsterListener;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
......@@ -19,6 +20,8 @@ public class ScriptMonsterTideService {
private final AtomicInteger monsterKillCount;
private final int monsterSceneLimit;
private final ConcurrentLinkedQueue<Integer> monsterConfigOrders;
private final OnMonsterCreated onMonsterCreated= new OnMonsterCreated();
private final OnMonsterDead onMonsterDead= new OnMonsterDead();
public ScriptMonsterTideService(SceneScriptManager sceneScriptManager,
SceneGroup group, int tideCount, int monsterSceneLimit, Integer[] ordersConfigId){
......@@ -30,18 +33,21 @@ public class ScriptMonsterTideService {
this.monsterAlive = new AtomicInteger(0);
this.monsterConfigOrders = new ConcurrentLinkedQueue<>(List.of(ordersConfigId));
this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterCreatedListener(this::onMonsterCreated);
this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterDeadListener(this::onMonsterDead);
this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterCreatedListener(onMonsterCreated);
this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterDeadListener(onMonsterDead);
// spawn the first turn
for (int i = 0; i < this.monsterSceneLimit; i++) {
this.sceneScriptManager.getScriptMonsterSpawnService().spawnMonster(group.id, getNextMonster());
}
}
public void onMonsterCreated(EntityMonster entityMonster){
if(this.monsterSceneLimit > 0){
this.monsterTideCount.decrementAndGet();
this.monsterAlive.incrementAndGet();
public class OnMonsterCreated implements ScriptMonsterListener{
@Override
public void onNotify(EntityMonster sceneMonster) {
if(monsterSceneLimit > 0){
monsterAlive.incrementAndGet();
monsterTideCount.decrementAndGet();
}
}
}
......@@ -54,21 +60,29 @@ public class ScriptMonsterTideService {
return currentGroup.monsters.values().stream().findFirst().orElse(null);
}
public void onMonsterDead(EntityMonster entityMonster){
if(this.monsterSceneLimit <= 0){
public class OnMonsterDead implements ScriptMonsterListener{
@Override
public void onNotify(EntityMonster sceneMonster) {
if(monsterSceneLimit <= 0){
return;
}
if(this.monsterAlive.decrementAndGet() >= this.monsterSceneLimit) {
if(monsterAlive.decrementAndGet() >= monsterSceneLimit) {
// maybe not happen
return;
}
this.monsterKillCount.incrementAndGet();
if(this.monsterTideCount.get() > 0){
monsterKillCount.incrementAndGet();
if(monsterTideCount.get() > 0){
// add more
this.sceneScriptManager.getScriptMonsterSpawnService().spawnMonster(this.currentGroup.id, getNextMonster());
sceneScriptManager.getScriptMonsterSpawnService().spawnMonster(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()));
sceneScriptManager.callEvent(EventType.EVENT_MONSTER_TIDE_DIE, new ScriptArgs(monsterKillCount.get()));
}
}
public void unload(){
this.sceneScriptManager.getScriptMonsterSpawnService().removeMonsterCreatedListener(onMonsterCreated);
this.sceneScriptManager.getScriptMonsterSpawnService().removeMonsterDeadListener(onMonsterDead);
}
}
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