fix the Monster spawn between stage challenges

This commit is contained in:
Akka
2022-05-10 00:05:01 +08:00
parent 45b45c4beb
commit faa3cde575
10 changed files with 133 additions and 50 deletions

View File

@@ -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);

View File

@@ -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){
return;
public class OnMonsterDead implements ScriptMonsterListener{
@Override
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;
}
this.monsterKillCount.incrementAndGet();
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()));
}
public void unload(){
this.sceneScriptManager.getScriptMonsterSpawnService().removeMonsterCreatedListener(onMonsterCreated);
this.sceneScriptManager.getScriptMonsterSpawnService().removeMonsterDeadListener(onMonsterDead);
}
}