mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-10 18:33:20 +08:00
refactor the challenge
This commit is contained in:
parent
717c2d1dd7
commit
791b9534b7
@ -1,180 +0,0 @@
|
|||||||
package emu.grasscutter.game.dungeons;
|
|
||||||
|
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
|
||||||
import emu.grasscutter.data.def.DungeonData;
|
|
||||||
import emu.grasscutter.game.entity.EntityMonster;
|
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
|
||||||
import emu.grasscutter.game.world.Scene;
|
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
|
||||||
import emu.grasscutter.scripts.data.SceneGroup;
|
|
||||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class DungeonChallenge {
|
|
||||||
private final Scene scene;
|
|
||||||
private final SceneGroup group;
|
|
||||||
|
|
||||||
private int challengeIndex;
|
|
||||||
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, 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Scene getScene() {
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneGroup getGroup() {
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChallengeIndex() {
|
|
||||||
return challengeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChallengeIndex(int challengeIndex) {
|
|
||||||
this.challengeIndex = challengeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChallengeId() {
|
|
||||||
return challengeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChallengeId(int challengeId) {
|
|
||||||
this.challengeId = challengeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getObjective() {
|
|
||||||
return objective;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObjective(int objective) {
|
|
||||||
this.objective = objective;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSuccess() {
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSuccess(boolean isSuccess) {
|
|
||||||
this.success = isSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean inProgress() {
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getScore() {
|
|
||||||
return score;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStage() {
|
|
||||||
return stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStage(boolean stage) {
|
|
||||||
this.stage = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTimeLimit() {
|
|
||||||
return 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntSet getRewardedPlayers() {
|
|
||||||
return rewardedPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRewardedPlayers(IntSet rewardedPlayers) {
|
|
||||||
this.rewardedPlayers = rewardedPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
this.progress = true;
|
|
||||||
getScene().broadcastPacket(new PacketDungeonChallengeBeginNotify(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void finish() {
|
|
||||||
this.progress = false;
|
|
||||||
|
|
||||||
getScene().broadcastPacket(new PacketDungeonChallengeFinishNotify(this));
|
|
||||||
|
|
||||||
if (this.isSuccess()) {
|
|
||||||
// Call success script event
|
|
||||||
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS,
|
|
||||||
// TODO record the time in PARAM2 and used in action
|
|
||||||
new ScriptArgs().setParam2(100));
|
|
||||||
|
|
||||||
// Settle
|
|
||||||
settle();
|
|
||||||
} else {
|
|
||||||
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_FAIL, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
getScene().broadcastPacket(new PacketChallengeDataNotify(this, 1, getScore()));
|
|
||||||
|
|
||||||
if (getScore() >= getObjective() && this.progress) {
|
|
||||||
this.setSuccess(true);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getStatueDrops(Player player) {
|
|
||||||
DungeonData dungeonData = getScene().getDungeonData();
|
|
||||||
if (!isSuccess() || dungeonData == null || dungeonData.getRewardPreview() == null || dungeonData.getRewardPreview().getPreviewItems().length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Already rewarded
|
|
||||||
if (getRewardedPlayers().contains(player.getUid())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<GameItem> rewards = new ArrayList<>();
|
|
||||||
for (ItemParamData param : getScene().getDungeonData().getRewardPreview().getPreviewItems()) {
|
|
||||||
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
player.getInventory().addItems(rewards, ActionReason.DungeonStatueDrop);
|
|
||||||
player.sendPacket(new PacketGadgetAutoPickDropInfoNotify(rewards));
|
|
||||||
|
|
||||||
getRewardedPlayers().add(player.getUid());
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,91 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
|
import emu.grasscutter.data.def.DungeonData;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.ChallengeTrigger;
|
||||||
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DungeonChallenge extends WorldChallenge {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* has more challenge
|
||||||
|
*/
|
||||||
|
private boolean stage;
|
||||||
|
private IntSet rewardedPlayers;
|
||||||
|
|
||||||
|
public DungeonChallenge(Scene scene, SceneGroup group,
|
||||||
|
int challengeId, int challengeIndex,
|
||||||
|
List<Integer> paramList,
|
||||||
|
int timeLimit, int goal,
|
||||||
|
List<ChallengeTrigger> challengeTriggers) {
|
||||||
|
super(scene, group, challengeId, challengeIndex, paramList, timeLimit, goal, challengeTriggers);
|
||||||
|
this.setRewardedPlayers(new IntOpenHashSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStage() {
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStage(boolean stage) {
|
||||||
|
this.stage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntSet getRewardedPlayers() {
|
||||||
|
return rewardedPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRewardedPlayers(IntSet rewardedPlayers) {
|
||||||
|
this.rewardedPlayers = rewardedPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void done() {
|
||||||
|
super.done();
|
||||||
|
if (this.isSuccess()) {
|
||||||
|
// Settle
|
||||||
|
settle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void settle() {
|
||||||
|
if(!stage){
|
||||||
|
getScene().getDungeonSettleObservers().forEach(o -> o.onDungeonSettle(getScene()));
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE,
|
||||||
|
new ScriptArgs(this.isSuccess() ? 1 : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getStatueDrops(Player player) {
|
||||||
|
DungeonData dungeonData = getScene().getDungeonData();
|
||||||
|
if (!isSuccess() || dungeonData == null || dungeonData.getRewardPreview() == null || dungeonData.getRewardPreview().getPreviewItems().length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already rewarded
|
||||||
|
if (getRewardedPlayers().contains(player.getUid())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GameItem> rewards = new ArrayList<>();
|
||||||
|
for (ItemParamData param : getScene().getDungeonData().getRewardPreview().getPreviewItems()) {
|
||||||
|
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
player.getInventory().addItems(rewards, ActionReason.DungeonStatueDrop);
|
||||||
|
player.sendPacket(new PacketGadgetAutoPickDropInfoNotify(rewards));
|
||||||
|
|
||||||
|
getRewardedPlayers().add(player.getUid());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.ChallengeTrigger;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class WorldChallenge {
|
||||||
|
private final Scene scene;
|
||||||
|
private final SceneGroup group;
|
||||||
|
private final int challengeId;
|
||||||
|
private final int challengeIndex;
|
||||||
|
private final List<Integer> paramList;
|
||||||
|
private final int timeLimit;
|
||||||
|
private final List<ChallengeTrigger> challengeTriggers;
|
||||||
|
private boolean progress;
|
||||||
|
private boolean success;
|
||||||
|
private long startedAt;
|
||||||
|
private int finishedTime;
|
||||||
|
private final int goal;
|
||||||
|
private final AtomicInteger score;
|
||||||
|
|
||||||
|
public WorldChallenge(Scene scene, SceneGroup group,
|
||||||
|
int challengeId, int challengeIndex, List<Integer> paramList,
|
||||||
|
int timeLimit, int goal,
|
||||||
|
List<ChallengeTrigger> challengeTriggers){
|
||||||
|
this.scene = scene;
|
||||||
|
this.group = group;
|
||||||
|
this.challengeId = challengeId;
|
||||||
|
this.challengeIndex = challengeIndex;
|
||||||
|
this.paramList = paramList;
|
||||||
|
this.timeLimit = timeLimit;
|
||||||
|
this.challengeTriggers = challengeTriggers;
|
||||||
|
this.goal = goal;
|
||||||
|
this.score = new AtomicInteger(0);
|
||||||
|
}
|
||||||
|
public boolean inProgress(){
|
||||||
|
return this.progress;
|
||||||
|
}
|
||||||
|
public void onCheckTimeOut(){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(timeLimit <= 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
challengeTriggers.forEach(t -> t.onCheckTimeout(this));
|
||||||
|
}
|
||||||
|
public void start(){
|
||||||
|
if(inProgress()){
|
||||||
|
Grasscutter.getLogger().info("Could not start a in progress challenge.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.progress = true;
|
||||||
|
this.startedAt = System.currentTimeMillis();
|
||||||
|
getScene().broadcastPacket(new PacketDungeonChallengeBeginNotify(this));
|
||||||
|
challengeTriggers.forEach(t -> t.onBegin(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void done(){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finish(true);
|
||||||
|
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS,
|
||||||
|
// TODO record the time in PARAM2 and used in action
|
||||||
|
new ScriptArgs().setParam2(finishedTime));
|
||||||
|
|
||||||
|
challengeTriggers.forEach(t -> t.onFinish(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fail(){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finish(false);
|
||||||
|
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_FAIL, null);
|
||||||
|
challengeTriggers.forEach(t -> t.onFinish(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finish(boolean success){
|
||||||
|
this.progress = false;
|
||||||
|
this.success = success;
|
||||||
|
this.finishedTime = (int)((System.currentTimeMillis() - this.startedAt) / 1000L);
|
||||||
|
getScene().broadcastPacket(new PacketDungeonChallengeFinishNotify(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int increaseScore(){
|
||||||
|
return score.incrementAndGet();
|
||||||
|
}
|
||||||
|
public void onMonsterDeath(EntityMonster monster){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(monster.getGroupId() != getGroup().id){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.challengeTriggers.forEach(t -> t.onMonsterDeath(this, monster));
|
||||||
|
}
|
||||||
|
public void onGadgetDeath(EntityGadget gadget){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(gadget.getGroupId() != getGroup().id){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.challengeTriggers.forEach(t -> t.onGadgetDeath(this, gadget));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onGadgetDamage(EntityGadget gadget){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(gadget.getGroupId() != getGroup().id){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.challengeTriggers.forEach(t -> t.onGadgetDamage(this, gadget));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ChallengeFactory {
|
||||||
|
|
||||||
|
private static final List<ChallengeFactoryHandler> challengeFactoryHandlers = new ArrayList<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
challengeFactoryHandlers.add(new DungeonChallengeFactoryHandler());
|
||||||
|
challengeFactoryHandlers.add(new DungeonGuardChallengeFactoryHandler());
|
||||||
|
challengeFactoryHandlers.add(new KillGadgetChallengeFactoryHandler());
|
||||||
|
challengeFactoryHandlers.add(new KillMonsterChallengeFactoryHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WorldChallenge getChallenge(int param1, int param2, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group){
|
||||||
|
for(var handler : challengeFactoryHandlers){
|
||||||
|
if(!handler.isThisType(param1, param2, param3, param4, param5, param6, scene, group)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return handler.build(param1, param2, param3, param4, param5, param6, scene, group);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
public interface ChallengeFactoryHandler {
|
||||||
|
boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group);
|
||||||
|
WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group);
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger;
|
||||||
|
import emu.grasscutter.game.props.SceneType;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DungeonChallengeFactoryHandler implements ChallengeFactoryHandler{
|
||||||
|
@Override
|
||||||
|
public boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
// ActiveChallenge with 1,1000,300,233101003,15,0
|
||||||
|
return scene.getSceneType() == SceneType.SCENE_DUNGEON
|
||||||
|
&& param4 == group.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
var realGroup = scene.getScriptManager().getGroupById(param4);
|
||||||
|
return new DungeonChallenge(
|
||||||
|
scene, realGroup,
|
||||||
|
challengeId, // Id
|
||||||
|
challengeIndex, // Index
|
||||||
|
List.of(param5, param3),
|
||||||
|
param3, // Limit
|
||||||
|
param5, // Goal
|
||||||
|
List.of(new InTimeTrigger(), new KillMonsterTrigger()));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.GuardTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger;
|
||||||
|
import emu.grasscutter.game.props.SceneType;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DungeonGuardChallengeFactoryHandler implements ChallengeFactoryHandler{
|
||||||
|
@Override
|
||||||
|
public boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
// ActiveChallenge with 1,188,234101003,12,3030,0
|
||||||
|
return scene.getSceneType() == SceneType.SCENE_DUNGEON
|
||||||
|
&& param3 == group.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
var realGroup = scene.getScriptManager().getGroupById(param3);
|
||||||
|
return new DungeonChallenge(
|
||||||
|
scene, realGroup,
|
||||||
|
challengeId, // Id
|
||||||
|
challengeIndex, // Index
|
||||||
|
List.of(param4, 0),
|
||||||
|
0, // Limit
|
||||||
|
param5, // Goal
|
||||||
|
List.of(new GuardTrigger()));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.factory.ChallengeFactoryHandler;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.KillGadgetTrigger;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class KillGadgetChallengeFactoryHandler implements ChallengeFactoryHandler {
|
||||||
|
@Override
|
||||||
|
public boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
// kill gadgets(explosive barrel) in time
|
||||||
|
// ActiveChallenge with 56,201,20,2,201,4
|
||||||
|
// open chest in time
|
||||||
|
// ActiveChallenge with 666,202,30,7,202,1
|
||||||
|
return challengeId == 201 || challengeId == 202;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
return new WorldChallenge(
|
||||||
|
scene, group,
|
||||||
|
challengeId, // Id
|
||||||
|
challengeIndex, // Index
|
||||||
|
List.of(param3, param6, 0),
|
||||||
|
param3, // Limit
|
||||||
|
param6, // Goal
|
||||||
|
List.of(new InTimeTrigger(), new KillGadgetTrigger())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class KillMonsterChallengeFactoryHandler implements ChallengeFactoryHandler{
|
||||||
|
@Override
|
||||||
|
public boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
// ActiveChallenge with 180,180,45,133108061,1,0
|
||||||
|
return challengeId == 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
var realGroup = scene.getScriptManager().getGroupById(param4);
|
||||||
|
return new WorldChallenge(
|
||||||
|
scene, realGroup,
|
||||||
|
challengeId, // Id
|
||||||
|
challengeIndex, // Index
|
||||||
|
List.of(param5, param3),
|
||||||
|
param3, // Limit
|
||||||
|
param5, // Goal
|
||||||
|
List.of(new KillMonsterTrigger(), new InTimeTrigger())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
|
|
||||||
|
public abstract class ChallengeTrigger {
|
||||||
|
public void onBegin(WorldChallenge challenge){}
|
||||||
|
public void onFinish(WorldChallenge challenge){}
|
||||||
|
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster){}
|
||||||
|
public void onGadgetDeath(WorldChallenge challenge, EntityGadget gadget){}
|
||||||
|
public void onCheckTimeout(WorldChallenge challenge){}
|
||||||
|
public void onGadgetDamage(WorldChallenge challenge, EntityGadget gadget){}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
|
||||||
|
|
||||||
|
public class GuardTrigger extends KillMonsterTrigger{
|
||||||
|
@Override
|
||||||
|
public void onBegin(WorldChallenge challenge) {
|
||||||
|
super.onBegin(challenge);
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGadgetDamage(WorldChallenge challenge, EntityGadget gadget) {
|
||||||
|
var curHp = gadget.getFightProperties().get(FightProperty.FIGHT_PROP_CUR_HP.getId());
|
||||||
|
var maxHp = gadget.getFightProperties().get(FightProperty.FIGHT_PROP_BASE_HP.getId());
|
||||||
|
int percent = (int) (curHp / maxHp);
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, percent));
|
||||||
|
|
||||||
|
if(percent <= 0){
|
||||||
|
challenge.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
|
||||||
|
public class InTimeTrigger extends ChallengeTrigger{
|
||||||
|
@Override
|
||||||
|
public void onCheckTimeout(WorldChallenge challenge) {
|
||||||
|
var current = System.currentTimeMillis();
|
||||||
|
if(current - challenge.getStartedAt() > challenge.getTimeLimit() * 1000L){
|
||||||
|
challenge.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
|
||||||
|
|
||||||
|
public class KillGadgetTrigger extends ChallengeTrigger{
|
||||||
|
@Override
|
||||||
|
public void onBegin(WorldChallenge challenge) {
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, challenge.getScore().get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGadgetDeath(WorldChallenge challenge, EntityGadget gadget) {
|
||||||
|
var newScore = challenge.increaseScore();
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, newScore));
|
||||||
|
|
||||||
|
if(newScore >= challenge.getGoal()){
|
||||||
|
challenge.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
|
||||||
|
|
||||||
|
public class KillMonsterTrigger extends ChallengeTrigger{
|
||||||
|
@Override
|
||||||
|
public void onBegin(WorldChallenge challenge) {
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 1, challenge.getScore().get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster) {
|
||||||
|
var newScore = challenge.increaseScore();
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 1, newScore));
|
||||||
|
|
||||||
|
if(newScore >= challenge.getGoal()){
|
||||||
|
challenge.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,10 @@
|
|||||||
package emu.grasscutter.game.entity;
|
package emu.grasscutter.game.entity;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.def.GadgetData;
|
import emu.grasscutter.data.def.GadgetData;
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
import emu.grasscutter.data.def.GadgetPropData;
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetContent;
|
import emu.grasscutter.game.entity.gadget.*;
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetGatherPoint;
|
import emu.grasscutter.game.props.*;
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetRewardStatue;
|
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
|
||||||
import emu.grasscutter.game.props.EntityIdType;
|
|
||||||
import emu.grasscutter.game.props.EntityType;
|
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||||
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
||||||
@ -32,6 +24,7 @@ import emu.grasscutter.scripts.constants.EventType;
|
|||||||
import emu.grasscutter.scripts.data.SceneGadget;
|
import emu.grasscutter.scripts.data.SceneGadget;
|
||||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import emu.grasscutter.utils.ProtoHelper;
|
import emu.grasscutter.utils.ProtoHelper;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||||
@ -160,7 +153,10 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath(int killerId) {
|
public void onDeath(int killerId) {
|
||||||
|
if(getScene().getChallenge() != null){
|
||||||
|
getScene().getChallenge().onGadgetDeath(this);
|
||||||
|
}
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_GADGET_DIE, new ScriptArgs(this.getConfigId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -203,4 +199,8 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
|
|
||||||
return entityInfo.build();
|
return entityInfo.build();
|
||||||
}
|
}
|
||||||
|
public void die() {
|
||||||
|
getScene().broadcastPacket(new PacketLifeStateChangeNotify(this, LifeState.LIFE_DEAD));
|
||||||
|
this.onDeath(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,8 @@ public class EntityMonster extends GameEntity {
|
|||||||
this.getScene().getDeadSpawnedEntities().add(getSpawnEntry());
|
this.getScene().getDeadSpawnedEntities().add(getSpawnEntry());
|
||||||
}
|
}
|
||||||
// first set the challenge data
|
// first set the challenge data
|
||||||
if (getScene().getChallenge() != null && getScene().getChallenge().getGroup().id == this.getGroupId()) {
|
if (getScene().getChallenge() != null) {
|
||||||
getScene().getChallenge().onMonsterDie(this);
|
getScene().getChallenge().onMonsterDeath(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){
|
||||||
|
@ -38,6 +38,8 @@ public class GadgetChest extends GadgetContent {
|
|||||||
|
|
||||||
getGadget().updateState(ScriptGadgetState.ChestOpened);
|
getGadget().updateState(ScriptGadgetState.ChestOpened);
|
||||||
player.sendPacket(new PacketGadgetInteractRsp(this.getGadget(), InteractTypeOuterClass.InteractType.INTERACT_OPEN_CHEST));
|
player.sendPacket(new PacketGadgetInteractRsp(this.getGadget(), InteractTypeOuterClass.InteractType.INTERACT_OPEN_CHEST));
|
||||||
|
// let the chest disappear
|
||||||
|
getGadget().die();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package emu.grasscutter.game.entity.gadget;
|
package emu.grasscutter.game.entity.gadget;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
@ -14,8 +15,8 @@ public class GadgetRewardStatue extends GadgetContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
if (player.getScene().getChallenge() != null) {
|
if (player.getScene().getChallenge() != null && player.getScene().getChallenge() instanceof DungeonChallenge dungeonChallenge) {
|
||||||
player.getScene().getChallenge().getStatueDrops(player);
|
dungeonChallenge.getStatueDrops(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
player.sendPacket(new PacketGadgetInteractRsp(getGadget(), InteractType.INTERACT_OPEN_STATUE));
|
player.sendPacket(new PacketGadgetInteractRsp(getGadget(), InteractType.INTERACT_OPEN_STATUE));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package emu.grasscutter.game.entity.gadget.chest;
|
package emu.grasscutter.game.entity.gadget.chest;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
@ -22,6 +23,10 @@ public class BossChestInteractHandler implements ChestInteractHandler{
|
|||||||
var monster = chest.getGadget().getMetaGadget().group.monsters.get(chest.getGadget().getMetaGadget().boss_chest.monster_config_id);
|
var monster = chest.getGadget().getMetaGadget().group.monsters.get(chest.getGadget().getMetaGadget().boss_chest.monster_config_id);
|
||||||
var reward = worldDataManager.getRewardByBossId(monster.monster_id);
|
var reward = worldDataManager.getRewardByBossId(monster.monster_id);
|
||||||
|
|
||||||
|
if(reward == null){
|
||||||
|
Grasscutter.getLogger().warn("Could not found the reward of boss monster {}", monster.monster_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
List<GameItem> rewards = new ArrayList<>();
|
List<GameItem> rewards = new ArrayList<>();
|
||||||
for (ItemParamData param : reward.getPreviewItems()) {
|
for (ItemParamData param : reward.getPreviewItems()) {
|
||||||
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
||||||
|
@ -4,7 +4,6 @@ import emu.grasscutter.Grasscutter;
|
|||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.GameDepot;
|
import emu.grasscutter.data.GameDepot;
|
||||||
import emu.grasscutter.data.def.*;
|
import emu.grasscutter.data.def.*;
|
||||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
|
||||||
import emu.grasscutter.game.dungeons.DungeonSettleListener;
|
import emu.grasscutter.game.dungeons.DungeonSettleListener;
|
||||||
import emu.grasscutter.game.entity.*;
|
import emu.grasscutter.game.entity.*;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
@ -14,6 +13,7 @@ import emu.grasscutter.game.props.FightProperty;
|
|||||||
import emu.grasscutter.game.props.LifeState;
|
import emu.grasscutter.game.props.LifeState;
|
||||||
import emu.grasscutter.game.props.SceneType;
|
import emu.grasscutter.game.props.SceneType;
|
||||||
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
||||||
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
||||||
@ -32,8 +32,6 @@ import org.danilopianini.util.SpatialIndex;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static emu.grasscutter.utils.Language.translate;
|
|
||||||
|
|
||||||
public class Scene {
|
public class Scene {
|
||||||
private final World world;
|
private final World world;
|
||||||
private final SceneData sceneData;
|
private final SceneData sceneData;
|
||||||
@ -51,7 +49,7 @@ public class Scene {
|
|||||||
private int weather;
|
private int weather;
|
||||||
|
|
||||||
private SceneScriptManager scriptManager;
|
private SceneScriptManager scriptManager;
|
||||||
private DungeonChallenge challenge;
|
private WorldChallenge challenge;
|
||||||
private List<DungeonSettleListener> dungeonSettleListeners;
|
private List<DungeonSettleListener> dungeonSettleListeners;
|
||||||
private DungeonData dungeonData;
|
private DungeonData dungeonData;
|
||||||
private int prevScene; // Id of the previous scene
|
private int prevScene; // Id of the previous scene
|
||||||
@ -199,11 +197,11 @@ public class Scene {
|
|||||||
this.dungeonData = dungeonData;
|
this.dungeonData = dungeonData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DungeonChallenge getChallenge() {
|
public WorldChallenge getChallenge() {
|
||||||
return challenge;
|
return challenge;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChallenge(DungeonChallenge challenge) {
|
public void setChallenge(WorldChallenge challenge) {
|
||||||
this.challenge = challenge;
|
this.challenge = challenge;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +351,14 @@ public class Scene {
|
|||||||
this.broadcastPacket(new PacketSceneEntityDisappearNotify(removed, visionType));
|
this.broadcastPacket(new PacketSceneEntityDisappearNotify(removed, visionType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public synchronized void removeEntities(List<GameEntity> entity, VisionType visionType) {
|
||||||
|
var toRemove = entity.stream()
|
||||||
|
.map(this::removeEntityDirectly)
|
||||||
|
.toList();
|
||||||
|
if (toRemove.size() > 0) {
|
||||||
|
this.broadcastPacket(new PacketSceneEntityDisappearNotify(toRemove, visionType));
|
||||||
|
}
|
||||||
|
}
|
||||||
public synchronized void replaceEntity(EntityAvatar oldEntity, EntityAvatar newEntity) {
|
public synchronized void replaceEntity(EntityAvatar oldEntity, EntityAvatar newEntity) {
|
||||||
this.removeEntityDirectly(oldEntity);
|
this.removeEntityDirectly(oldEntity);
|
||||||
this.addEntityDirectly(newEntity);
|
this.addEntityDirectly(newEntity);
|
||||||
@ -418,6 +423,10 @@ public class Scene {
|
|||||||
}
|
}
|
||||||
// Triggers
|
// Triggers
|
||||||
this.scriptManager.checkRegions();
|
this.scriptManager.checkRegions();
|
||||||
|
|
||||||
|
if(challenge != null){
|
||||||
|
challenge.onCheckTimeOut();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - Test
|
// TODO - Test
|
||||||
@ -590,21 +599,21 @@ public class Scene {
|
|||||||
if (suite == 0 || group.suites == null || group.suites.size() == 0) {
|
if (suite == 0 || group.suites == null || group.suites.size() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
|
||||||
var suiteData = group.getSuiteByIndex(suite);
|
|
||||||
suiteData.sceneTriggers.forEach(getScriptManager()::registerTrigger);
|
|
||||||
|
|
||||||
entities.addAll(suiteData.sceneGadgets.stream()
|
// just load the 'init' suite, avoid spawn the suite added by AddExtraGroupSuite etc.
|
||||||
.map(g -> scriptManager.createGadget(group.id, group.block_id, g)).toList());
|
var suiteData = group.getSuiteByIndex(suite);
|
||||||
entities.addAll(suiteData.sceneMonsters.stream()
|
suiteData.sceneTriggers.forEach(getScriptManager()::registerTrigger);
|
||||||
.map(mob -> scriptManager.createMonster(group.id, group.block_id, mob)).toList());
|
|
||||||
|
entities.addAll(suiteData.sceneGadgets.stream()
|
||||||
suite++;
|
.map(g -> scriptManager.createGadget(group.id, group.block_id, g)).toList());
|
||||||
} while (suite < group.init_config.end_suite);
|
entities.addAll(suiteData.sceneMonsters.stream()
|
||||||
|
.map(mob -> scriptManager.createMonster(group.id, group.block_id, mob)).toList());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptManager.meetEntities(entities);
|
scriptManager.meetEntities(entities);
|
||||||
|
//scriptManager.callEvent(EventType.EVENT_GROUP_LOAD, null);
|
||||||
|
//groups.forEach(g -> scriptManager.callEvent(EventType.EVENT_GROUP_LOAD, null));
|
||||||
Grasscutter.getLogger().info("Scene {} loaded {} group(s)", this.getId(), groups.size());
|
Grasscutter.getLogger().info("Scene {} loaded {} group(s)", this.getId(), groups.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,16 +26,13 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class SceneScriptManager {
|
public class SceneScriptManager {
|
||||||
private final Scene scene;
|
private final Scene scene;
|
||||||
private final Map<String, Integer> variables;
|
private final Map<String, Integer> variables;
|
||||||
private SceneMeta meta;
|
private SceneMeta meta;
|
||||||
private boolean isInit;
|
private boolean isInit;
|
||||||
/**
|
|
||||||
* SceneTrigger Set
|
|
||||||
*/
|
|
||||||
private final Map<String, SceneTrigger> triggers;
|
|
||||||
/**
|
/**
|
||||||
* current triggers controlled by RefreshGroup
|
* current triggers controlled by RefreshGroup
|
||||||
*/
|
*/
|
||||||
@ -51,12 +48,11 @@ public class SceneScriptManager {
|
|||||||
public static final ExecutorService eventExecutor;
|
public static final ExecutorService eventExecutor;
|
||||||
static {
|
static {
|
||||||
eventExecutor = new ThreadPoolExecutor(4, 4,
|
eventExecutor = new ThreadPoolExecutor(4, 4,
|
||||||
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100),
|
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000),
|
||||||
FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy());
|
FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy());
|
||||||
}
|
}
|
||||||
public SceneScriptManager(Scene scene) {
|
public SceneScriptManager(Scene scene) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.triggers = new HashMap<>();
|
|
||||||
this.currentTriggers = new Int2ObjectOpenHashMap<>();
|
this.currentTriggers = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
this.regions = new Int2ObjectOpenHashMap<>();
|
this.regions = new Int2ObjectOpenHashMap<>();
|
||||||
@ -96,13 +92,16 @@ public class SceneScriptManager {
|
|||||||
public Set<SceneTrigger> getTriggersByEvent(int eventId) {
|
public Set<SceneTrigger> getTriggersByEvent(int eventId) {
|
||||||
return currentTriggers.computeIfAbsent(eventId, e -> new HashSet<>());
|
return currentTriggers.computeIfAbsent(eventId, e -> new HashSet<>());
|
||||||
}
|
}
|
||||||
|
public void registerTrigger(List<SceneTrigger> triggers) {
|
||||||
|
triggers.forEach(this::registerTrigger);
|
||||||
|
}
|
||||||
public void registerTrigger(SceneTrigger trigger) {
|
public void registerTrigger(SceneTrigger trigger) {
|
||||||
this.triggers.put(trigger.name, trigger);
|
|
||||||
getTriggersByEvent(trigger.event).add(trigger);
|
getTriggersByEvent(trigger.event).add(trigger);
|
||||||
}
|
}
|
||||||
|
public void deregisterTrigger(List<SceneTrigger> triggers) {
|
||||||
|
triggers.forEach(this::deregisterTrigger);
|
||||||
|
}
|
||||||
public void deregisterTrigger(SceneTrigger trigger) {
|
public void deregisterTrigger(SceneTrigger trigger) {
|
||||||
this.triggers.remove(trigger.name);
|
|
||||||
getTriggersByEvent(trigger.event).remove(trigger);
|
getTriggersByEvent(trigger.event).remove(trigger);
|
||||||
}
|
}
|
||||||
public void resetTriggers(int eventId) {
|
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) {
|
public void spawnGadgetsInGroup(SceneGroup group, int suiteIndex) {
|
||||||
spawnGadgetsInGroup(group, group.getSuiteByIndex(suiteIndex));
|
spawnGadgetsInGroup(group, group.getSuiteByIndex(suiteIndex));
|
||||||
}
|
}
|
||||||
@ -241,7 +250,6 @@ public class SceneScriptManager {
|
|||||||
}
|
}
|
||||||
this.addEntities(suite.sceneMonsters.stream()
|
this.addEntities(suite.sceneMonsters.stream()
|
||||||
.map(mob -> createMonster(group.id, group.block_id, mob)).toList());
|
.map(mob -> createMonster(group.id, group.block_id, mob)).toList());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawnMonstersInGroup(SceneGroup group) {
|
public void spawnMonstersInGroup(SceneGroup group) {
|
||||||
@ -326,7 +334,7 @@ public class SceneScriptManager {
|
|||||||
try{
|
try{
|
||||||
return func.call(ScriptLoader.getScriptLibLua(), args);
|
return func.call(ScriptLoader.getScriptLibLua(), args);
|
||||||
}catch (LuaError error){
|
}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);
|
return LuaValue.valueOf(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -388,6 +396,7 @@ public class SceneScriptManager {
|
|||||||
entity.setGroupId(groupId);
|
entity.setGroupId(groupId);
|
||||||
entity.setBlockId(blockId);
|
entity.setBlockId(blockId);
|
||||||
entity.setConfigId(monster.config_id);
|
entity.setConfigId(monster.config_id);
|
||||||
|
entity.setPoseId(monster.pose_id);
|
||||||
|
|
||||||
this.getScriptMonsterSpawnService()
|
this.getScriptMonsterSpawnService()
|
||||||
.onMonsterCreatedListener.forEach(action -> action.onNotify(entity));
|
.onMonsterCreatedListener.forEach(action -> action.onNotify(entity));
|
||||||
@ -410,4 +419,28 @@ public class SceneScriptManager {
|
|||||||
public PhTree<SceneBlock> getBlocksIndex() {
|
public PhTree<SceneBlock> getBlocksIndex() {
|
||||||
return meta.sceneBlockIndex;
|
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;
|
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.EntityGadget;
|
||||||
import emu.grasscutter.game.entity.EntityMonster;
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
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.SceneGroup;
|
||||||
import emu.grasscutter.scripts.data.SceneRegion;
|
import emu.grasscutter.scripts.data.SceneRegion;
|
||||||
import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
|
import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
|
||||||
@ -159,48 +160,102 @@ public class ScriptLib {
|
|||||||
if (group == null || group.monsters == null) {
|
if (group == null || group.monsters == null) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
var suiteData = group.getSuiteByIndex(suite);
|
||||||
|
if(suiteData == null){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
// avoid spawn wrong monster
|
// avoid spawn wrong monster
|
||||||
if(getSceneScriptManager().getScene().getChallenge() != null)
|
if(getSceneScriptManager().getScene().getChallenge() != null)
|
||||||
if(!getSceneScriptManager().getScene().getChallenge().inProgress() ||
|
if(!getSceneScriptManager().getScene().getChallenge().inProgress() ||
|
||||||
getSceneScriptManager().getScene().getChallenge().getGroup().id != groupId){
|
getSceneScriptManager().getScene().getChallenge().getGroup().id != groupId){
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// param3 (probably time limit for timed dungeons)
|
// param3 (probably time limit for timed dungeons)
|
||||||
public int ActiveChallenge(int challengeId, int challengeIndex, int timeLimitOrGroupId, int groupId, int objectiveKills, int param5) {
|
public int ActiveChallenge(int challengeId, int challengeIndex, int timeLimitOrGroupId, int groupId, int objectiveKills, int param5) {
|
||||||
logger.debug("[LUA] Call ActiveChallenge with {},{},{},{},{},{}",
|
logger.debug("[LUA] Call ActiveChallenge with {},{},{},{},{},{}",
|
||||||
challengeId,challengeIndex,timeLimitOrGroupId,groupId,objectiveKills,param5);
|
challengeId,challengeIndex,timeLimitOrGroupId,groupId,objectiveKills,param5);
|
||||||
|
|
||||||
SceneGroup group = getSceneScriptManager().getGroupById(groupId);
|
var challenge = ChallengeFactory.getChallenge(
|
||||||
var objective = objectiveKills;
|
challengeId,
|
||||||
|
challengeIndex,
|
||||||
|
timeLimitOrGroupId,
|
||||||
|
groupId,
|
||||||
|
objectiveKills,
|
||||||
|
param5,
|
||||||
|
getSceneScriptManager().getScene(),
|
||||||
|
getCurrentGroup().get()
|
||||||
|
);
|
||||||
|
|
||||||
if(group == null){
|
if(challenge == null){
|
||||||
group = getSceneScriptManager().getGroupById(timeLimitOrGroupId);
|
|
||||||
objective = groupId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group == null || group.monsters == null) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(getSceneScriptManager().getScene().getChallenge() != null &&
|
if(challenge instanceof DungeonChallenge dungeonChallenge){
|
||||||
getSceneScriptManager().getScene().getChallenge().inProgress())
|
// set if tower first stage (6-1)
|
||||||
{
|
dungeonChallenge.setStage(getSceneScriptManager().getVariables().getOrDefault("stage", -1) == 0);
|
||||||
return 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);
|
getSceneScriptManager().getScene().setChallenge(challenge);
|
||||||
|
|
||||||
challenge.start();
|
challenge.start();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -257,7 +312,7 @@ public class ScriptLib {
|
|||||||
|
|
||||||
public int GetRegionEntityCount(LuaTable table) {
|
public int GetRegionEntityCount(LuaTable table) {
|
||||||
logger.debug("[LUA] Call GetRegionEntityCount with {}",
|
logger.debug("[LUA] Call GetRegionEntityCount with {}",
|
||||||
table);
|
printTable(table));
|
||||||
int regionId = table.get("region_eid").toint();
|
int regionId = table.get("region_eid").toint();
|
||||||
int entityType = table.get("entity_type").toint();
|
int entityType = table.get("entity_type").toint();
|
||||||
|
|
||||||
@ -280,9 +335,8 @@ public class ScriptLib {
|
|||||||
// TODO record time
|
// TODO record time
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
public int GetGroupMonsterCount(int var1){
|
public int GetGroupMonsterCount(){
|
||||||
logger.debug("[LUA] Call GetGroupMonsterCount with {}",
|
logger.debug("[LUA] Call GetGroupMonsterCount ");
|
||||||
var1);
|
|
||||||
|
|
||||||
return (int) getSceneScriptManager().getScene().getEntities().values().stream()
|
return (int) getSceneScriptManager().getScene().getEntities().values().stream()
|
||||||
.filter(e -> e instanceof EntityMonster &&
|
.filter(e -> e instanceof EntityMonster &&
|
||||||
@ -328,7 +382,7 @@ public class ScriptLib {
|
|||||||
|
|
||||||
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId.toint());
|
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId.toint());
|
||||||
if(entity == null){
|
if(entity == null){
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
getSceneScriptManager().getScene().killEntity(entity, 0);
|
getSceneScriptManager().getScene().killEntity(entity, 0);
|
||||||
return 0;
|
return 0;
|
||||||
@ -398,8 +452,13 @@ public class ScriptLib {
|
|||||||
public int GetGadgetStateByConfigId(int groupId, int configId){
|
public int GetGadgetStateByConfigId(int groupId, int configId){
|
||||||
logger.debug("[LUA] Call GetGadgetStateByConfigId with {},{}",
|
logger.debug("[LUA] Call GetGadgetStateByConfigId with {},{}",
|
||||||
groupId, configId);
|
groupId, configId);
|
||||||
|
|
||||||
|
if(groupId == 0){
|
||||||
|
groupId = getCurrentGroup().get().id;
|
||||||
|
}
|
||||||
|
final int realGroupId = groupId;
|
||||||
var gadget = getSceneScriptManager().getScene().getEntities().values().stream()
|
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)
|
.filter(g -> g.getConfigId() == configId)
|
||||||
.findFirst();
|
.findFirst();
|
||||||
if(gadget.isEmpty()){
|
if(gadget.isEmpty()){
|
||||||
@ -409,8 +468,8 @@ public class ScriptLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int MarkPlayerAction(int var1, int var2, int var3, int var4){
|
public int MarkPlayerAction(int var1, int var2, int var3, int var4){
|
||||||
logger.debug("[LUA] Call MarkPlayerAction with {},{}",
|
logger.debug("[LUA] Call MarkPlayerAction with {},{},{},{}",
|
||||||
var1, var2);
|
var1, var2,var3,var4);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,5 @@ public class SceneGadget extends SceneObject{
|
|||||||
public int state;
|
public int state;
|
||||||
public int point_type;
|
public int point_type;
|
||||||
public SceneBossChest boss_chest;
|
public SceneBossChest boss_chest;
|
||||||
|
public int interact_id;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public class SceneGroup {
|
|||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SceneGroup load(int sceneId){
|
public synchronized SceneGroup load(int sceneId){
|
||||||
if(loaded){
|
if(loaded){
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -118,6 +118,7 @@ public class SceneGroup {
|
|||||||
garbages = new SceneGarbage();
|
garbages = new SceneGarbage();
|
||||||
if (garbagesTable.checktable().get("gadgets") != LuaValue.NIL) {
|
if (garbagesTable.checktable().get("gadgets") != LuaValue.NIL) {
|
||||||
garbages.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, garbagesTable.checktable().get("gadgets").checktable());
|
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
|
@Setter
|
||||||
public class SceneMonster extends SceneObject{
|
public class SceneMonster extends SceneObject{
|
||||||
public int monster_id;
|
public int monster_id;
|
||||||
|
public int pose_id;
|
||||||
|
public int drop_id;
|
||||||
}
|
}
|
@ -1,13 +1,13 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.ChallengeDataNotifyOuterClass.ChallengeDataNotify;
|
import emu.grasscutter.net.proto.ChallengeDataNotifyOuterClass.ChallengeDataNotify;
|
||||||
|
|
||||||
public class PacketChallengeDataNotify extends BasePacket {
|
public class PacketChallengeDataNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketChallengeDataNotify(DungeonChallenge challenge, int index, int value) {
|
public PacketChallengeDataNotify(WorldChallenge challenge, int index, int value) {
|
||||||
super(PacketOpcodes.ChallengeDataNotify);
|
super(PacketOpcodes.ChallengeDataNotify);
|
||||||
|
|
||||||
ChallengeDataNotify proto = ChallengeDataNotify.newBuilder()
|
ChallengeDataNotify proto = ChallengeDataNotify.newBuilder()
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.DungeonChallengeBeginNotifyOuterClass.DungeonChallengeBeginNotify;
|
import emu.grasscutter.net.proto.DungeonChallengeBeginNotifyOuterClass.DungeonChallengeBeginNotify;
|
||||||
|
|
||||||
public class PacketDungeonChallengeBeginNotify extends BasePacket {
|
public class PacketDungeonChallengeBeginNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketDungeonChallengeBeginNotify(DungeonChallenge challenge) {
|
public PacketDungeonChallengeBeginNotify(WorldChallenge challenge) {
|
||||||
super(PacketOpcodes.DungeonChallengeBeginNotify, true);
|
super(PacketOpcodes.DungeonChallengeBeginNotify, true);
|
||||||
|
|
||||||
DungeonChallengeBeginNotify proto = DungeonChallengeBeginNotify.newBuilder()
|
DungeonChallengeBeginNotify proto = DungeonChallengeBeginNotify.newBuilder()
|
||||||
.setChallengeId(challenge.getChallengeId())
|
.setChallengeId(challenge.getChallengeId())
|
||||||
.setChallengeIndex(challenge.getChallengeIndex())
|
.setChallengeIndex(challenge.getChallengeIndex())
|
||||||
.setGroupId(challenge.getGroup().id)
|
.setGroupId(challenge.getGroup().id)
|
||||||
.addParamList(challenge.getObjective())
|
.addAllParamList(challenge.getParamList())
|
||||||
.addParamList(challenge.getTimeLimit())
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.DungeonChallengeFinishNotifyOuterClass.DungeonChallengeFinishNotify;
|
import emu.grasscutter.net.proto.DungeonChallengeFinishNotifyOuterClass.DungeonChallengeFinishNotify;
|
||||||
|
|
||||||
public class PacketDungeonChallengeFinishNotify extends BasePacket {
|
public class PacketDungeonChallengeFinishNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketDungeonChallengeFinishNotify(DungeonChallenge challenge) {
|
public PacketDungeonChallengeFinishNotify(WorldChallenge challenge) {
|
||||||
super(PacketOpcodes.DungeonChallengeFinishNotify, true);
|
super(PacketOpcodes.DungeonChallengeFinishNotify, true);
|
||||||
|
|
||||||
DungeonChallengeFinishNotify proto = DungeonChallengeFinishNotify.newBuilder()
|
DungeonChallengeFinishNotify proto = DungeonChallengeFinishNotify.newBuilder()
|
||||||
@ -15,7 +15,7 @@ public class PacketDungeonChallengeFinishNotify extends BasePacket {
|
|||||||
.setIsSuccess(challenge.isSuccess())
|
.setIsSuccess(challenge.isSuccess())
|
||||||
.setUnk1(2)
|
.setUnk1(2)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.DungeonSettleNotifyOuterClass.DungeonSettleNotify;
|
import emu.grasscutter.net.proto.DungeonSettleNotifyOuterClass.DungeonSettleNotify;
|
||||||
@ -9,7 +9,7 @@ import emu.grasscutter.net.proto.TowerLevelEndNotifyOuterClass.TowerLevelEndNoti
|
|||||||
|
|
||||||
public class PacketDungeonSettleNotify extends BasePacket {
|
public class PacketDungeonSettleNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketDungeonSettleNotify(DungeonChallenge challenge) {
|
public PacketDungeonSettleNotify(WorldChallenge challenge) {
|
||||||
super(PacketOpcodes.DungeonSettleNotify);
|
super(PacketOpcodes.DungeonSettleNotify);
|
||||||
|
|
||||||
DungeonSettleNotify proto = DungeonSettleNotify.newBuilder()
|
DungeonSettleNotify proto = DungeonSettleNotify.newBuilder()
|
||||||
@ -22,10 +22,10 @@ public class PacketDungeonSettleNotify extends BasePacket {
|
|||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketDungeonSettleNotify(DungeonChallenge challenge,
|
public PacketDungeonSettleNotify(WorldChallenge challenge,
|
||||||
boolean canJump,
|
boolean canJump,
|
||||||
boolean hasNextLevel,
|
boolean hasNextLevel,
|
||||||
int nextFloorId
|
int nextFloorId
|
||||||
) {
|
) {
|
||||||
super(PacketOpcodes.DungeonSettleNotify);
|
super(PacketOpcodes.DungeonSettleNotify);
|
||||||
|
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
import emu.grasscutter.game.props.LifeState;
|
import emu.grasscutter.game.props.LifeState;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.LifeStateChangeNotifyOuterClass.LifeStateChangeNotify;
|
import emu.grasscutter.net.proto.LifeStateChangeNotifyOuterClass.LifeStateChangeNotify;
|
||||||
import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType;
|
import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType;
|
||||||
import emu.grasscutter.net.proto.ServerBuffOuterClass.ServerBuff;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class PacketLifeStateChangeNotify extends BasePacket {
|
public class PacketLifeStateChangeNotify extends BasePacket {
|
||||||
|
public PacketLifeStateChangeNotify(GameEntity target, LifeState lifeState) {
|
||||||
|
super(PacketOpcodes.LifeStateChangeNotify);
|
||||||
|
|
||||||
|
LifeStateChangeNotify proto = LifeStateChangeNotify.newBuilder()
|
||||||
|
.setEntityId(target.getId())
|
||||||
|
.setLifeState(lifeState.getValue())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
public PacketLifeStateChangeNotify(GameEntity attacker, GameEntity target, LifeState lifeState) {
|
public PacketLifeStateChangeNotify(GameEntity attacker, GameEntity target, LifeState lifeState) {
|
||||||
super(PacketOpcodes.LifeStateChangeNotify);
|
super(PacketOpcodes.LifeStateChangeNotify);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user