mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-10 18:03:20 +08:00
fix the Monster spawn between stage challenges
This commit is contained in:
parent
45b45c4beb
commit
faa3cde575
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"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"
|
||||||
}
|
}
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +93,14 @@ public class DungeonChallenge {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@ -123,7 +137,9 @@ 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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
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));
|
||||||
@ -396,11 +402,14 @@ public class SceneScriptManager {
|
|||||||
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 {
|
|||||||
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,10 +181,10 @@ 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);
|
||||||
|
|
||||||
@ -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 {
|
|||||||
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 + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
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.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 {
|
|||||||
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;
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user