Implement rerunning cocoon/boss battles

This commit is contained in:
Melledy
2023-09-30 01:35:03 -07:00
parent 3aadea4d86
commit 2076efaef2
7 changed files with 153 additions and 6 deletions

View File

@@ -5,6 +5,7 @@ import java.util.List;
import emu.lunarcore.data.GameResource; import emu.lunarcore.data.GameResource;
import emu.lunarcore.data.ResourceType; import emu.lunarcore.data.ResourceType;
import emu.lunarcore.game.enums.StageType;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import lombok.AccessLevel; import lombok.AccessLevel;
@@ -15,6 +16,7 @@ import lombok.Getter;
public class StageExcel extends GameResource { public class StageExcel extends GameResource {
private int StageID; private int StageID;
private long StageName; private long StageName;
private StageType StageType;
private int Level; private int Level;
@Getter(AccessLevel.NONE) @Getter(AccessLevel.NONE)

View File

@@ -15,28 +15,46 @@ import emu.lunarcore.proto.SceneBattleInfoOuterClass.SceneBattleInfo;
import emu.lunarcore.proto.SceneMonsterOuterClass.SceneMonster; import emu.lunarcore.proto.SceneMonsterOuterClass.SceneMonster;
import emu.lunarcore.proto.SceneMonsterWaveOuterClass.SceneMonsterWave; import emu.lunarcore.proto.SceneMonsterWaveOuterClass.SceneMonsterWave;
import emu.lunarcore.util.Utils; import emu.lunarcore.util.Utils;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
public class Battle { public class Battle {
private final int id;
private final Player player; private final Player player;
private final PlayerLineup lineup; private final PlayerLineup lineup;
private final List<EntityMonster> npcMonsters; private final List<EntityMonster> npcMonsters;
private final List<MazeBuff> buffs; private final List<MazeBuff> buffs;
private final List<StageExcel> stages; private final List<StageExcel> stages;
// Constructor params subject to change private Battle(Player player, PlayerLineup lineup) {
public Battle(Player player, PlayerLineup lineup, Collection<StageExcel> stages) { this.id = player.getNextBattleId();
this.player = player; this.player = player;
this.lineup = lineup; this.lineup = lineup;
this.npcMonsters = new ArrayList<>(); this.npcMonsters = new ArrayList<>();
this.buffs = new ArrayList<>(); this.buffs = new ArrayList<>();
this.stages = new ArrayList<>(); this.stages = new ArrayList<>();
}
public Battle(Player player, PlayerLineup lineup, StageExcel stage) {
this(player, lineup);
this.stages.add(stage);
}
public Battle(Player player, PlayerLineup lineup, Collection<StageExcel> stages) {
this(player, lineup);
this.stages.addAll(stages); this.stages.addAll(stages);
} }
public int getStageId() {
if (this.getStages().size() > 0) {
return this.getStages().get(0).getId();
} else {
return 0;
}
}
public MazeBuff addBuff(int buffId, int ownerId) { public MazeBuff addBuff(int buffId, int ownerId) {
return addBuff(buffId, ownerId, 0xffffffff); return addBuff(buffId, ownerId, 0xffffffff);
} }
@@ -51,9 +69,14 @@ public class Battle {
return buff; return buff;
} }
public void clearBuffs() {
this.buffs.clear();
}
public SceneBattleInfo toProto() { public SceneBattleInfo toProto() {
// Build battle info // Build battle info
var proto = SceneBattleInfo.newInstance() var proto = SceneBattleInfo.newInstance()
.setBattleId(this.getId())
.setLogicRandomSeed(Utils.randomRange(1, Short.MAX_VALUE)) .setLogicRandomSeed(Utils.randomRange(1, Short.MAX_VALUE))
.setWorldLevel(player.getWorldLevel()); .setWorldLevel(player.getWorldLevel());

View File

@@ -7,6 +7,7 @@ import emu.lunarcore.data.GameData;
import emu.lunarcore.data.excel.CocoonExcel; import emu.lunarcore.data.excel.CocoonExcel;
import emu.lunarcore.data.excel.StageExcel; import emu.lunarcore.data.excel.StageExcel;
import emu.lunarcore.game.avatar.GameAvatar; import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.enums.StageType;
import emu.lunarcore.game.player.Player; import emu.lunarcore.game.player.Player;
import emu.lunarcore.game.scene.entity.EntityMonster; import emu.lunarcore.game.scene.entity.EntityMonster;
import emu.lunarcore.game.scene.entity.EntityProp; import emu.lunarcore.game.scene.entity.EntityProp;
@@ -16,6 +17,7 @@ import emu.lunarcore.proto.AvatarPropertyOuterClass.AvatarProperty;
import emu.lunarcore.proto.BattleEndStatusOuterClass.BattleEndStatus; import emu.lunarcore.proto.BattleEndStatusOuterClass.BattleEndStatus;
import emu.lunarcore.server.game.BaseGameService; import emu.lunarcore.server.game.BaseGameService;
import emu.lunarcore.server.game.GameServer; import emu.lunarcore.server.game.GameServer;
import emu.lunarcore.server.packet.send.PacketReEnterLastElementStageScRsp;
import emu.lunarcore.server.packet.send.PacketSceneCastSkillScRsp; import emu.lunarcore.server.packet.send.PacketSceneCastSkillScRsp;
import emu.lunarcore.server.packet.send.PacketStartCocoonStageScRsp; import emu.lunarcore.server.packet.send.PacketStartCocoonStageScRsp;
import emu.lunarcore.server.packet.send.PacketSyncLineupNotify; import emu.lunarcore.server.packet.send.PacketSyncLineupNotify;
@@ -30,6 +32,11 @@ public class BattleService extends BaseGameService {
} }
public void startBattle(Player player, int attackerId, RepeatedInt attackedList) { public void startBattle(Player player, int attackerId, RepeatedInt attackedList) {
// Sanity check to make sure player isnt in a battle
if (player.isInBattle()) {
return;
}
// Setup variables // Setup variables
List<GameEntity> entities = new ArrayList<>(); List<GameEntity> entities = new ArrayList<>();
List<EntityMonster> monsters = new ArrayList<>(); List<EntityMonster> monsters = new ArrayList<>();
@@ -119,6 +126,11 @@ public class BattleService extends BaseGameService {
} }
public void startCocoon(Player player, int cocoonId, int worldLevel, int wave) { public void startCocoon(Player player, int cocoonId, int worldLevel, int wave) {
// Sanity check to make sure player isnt in a battle
if (player.isInBattle()) {
return;
}
// Get cocoon data // Get cocoon data
CocoonExcel cocoonExcel = GameData.getCocoonExcel(cocoonId, worldLevel); CocoonExcel cocoonExcel = GameData.getCocoonExcel(cocoonId, worldLevel);
if (cocoonExcel == null) { if (cocoonExcel == null) {
@@ -129,6 +141,8 @@ public class BattleService extends BaseGameService {
// Get waves // Get waves
wave = Math.min(Math.max(1, wave), cocoonExcel.getMaxWave()); wave = Math.min(Math.max(1, wave), cocoonExcel.getMaxWave());
// TODO sanity check stamina
// Get stages from cocoon // Get stages from cocoon
List<StageExcel> stages = new ArrayList<>(); List<StageExcel> stages = new ArrayList<>();
@@ -155,7 +169,7 @@ public class BattleService extends BaseGameService {
} }
public void finishBattle(Player player, BattleEndStatus result, RepeatedMessage<AvatarBattleInfo> battleAvatars) { public void finishBattle(Player player, BattleEndStatus result, RepeatedMessage<AvatarBattleInfo> battleAvatars) {
// Sanity // Sanity check to make sure player is in a battle
if (!player.isInBattle()) { if (!player.isInBattle()) {
return; return;
} }
@@ -191,4 +205,26 @@ public class BattleService extends BaseGameService {
// Done - Clear battle object from player // Done - Clear battle object from player
player.setBattle(null); player.setBattle(null);
} }
public void reEnterBattle(Player player, int stageId) {
// Sanity check to make sure player isnt in a battle
if (player.isInBattle()) {
player.sendPacket(new PacketReEnterLastElementStageScRsp());
return;
}
// Get stage
StageExcel stage = GameData.getStageExcelMap().get(stageId);
if (stage == null || stage.getStageType() != StageType.FarmElement) {
player.sendPacket(new PacketReEnterLastElementStageScRsp());
return;
}
// Create new battle for player
Battle battle = new Battle(player, player.getLineupManager().getCurrentLineup(), stage);
player.setBattle(battle);
// Send packet
player.sendPacket(new PacketReEnterLastElementStageScRsp(battle));
}
} }

View File

@@ -0,0 +1,35 @@
package emu.lunarcore.game.enums;
import lombok.Getter;
public enum StageType {
Unknown (0),
Mainline (1),
Maze (2),
Adventure (3),
Cocoon (4),
FarmElement (5),
Client (6),
FarmRelic (7),
VerseSimulation (8),
Trial (9),
PunkLord (10),
FightActivity (11),
TrialAdventure (12),
BoxingClub (13),
TrialInBattle (14),
RogueChallengeActivity (15),
TreasureDungeon (16),
AetherDivide (17),
FantasticStory (18),
BattleCollege (19),
Heliobus (20),
RogueEndlessActivity (21);
@Getter
private final int val;
private StageType(int value) {
this.val = value;
}
}

View File

@@ -28,7 +28,6 @@ import emu.lunarcore.server.packet.SessionState;
import emu.lunarcore.server.packet.send.PacketEnterSceneByServerScNotify; import emu.lunarcore.server.packet.send.PacketEnterSceneByServerScNotify;
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify; import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
import emu.lunarcore.server.packet.send.PacketRevcMsgScNotify; import emu.lunarcore.server.packet.send.PacketRevcMsgScNotify;
import emu.lunarcore.server.packet.send.PacketSetHeroBasicTypeScRsp;
import emu.lunarcore.util.Position; import emu.lunarcore.util.Position;
import lombok.Getter; import lombok.Getter;
@@ -64,6 +63,7 @@ public class Player {
// Etc // Etc
@Setter private transient boolean paused; @Setter private transient boolean paused;
private transient int nextBattleId;
// Player managers // Player managers
private transient final AvatarStorage avatars; private transient final AvatarStorage avatars;
@@ -249,6 +249,10 @@ public class Player {
this.curBasicType = heroType; this.curBasicType = heroType;
} }
public int getNextBattleId() {
return ++nextBattleId;
}
public boolean isInBattle() { public boolean isInBattle() {
return this.battle != null; return this.battle != null;
} }

View File

@@ -0,0 +1,19 @@
package emu.lunarcore.server.packet.recv;
import emu.lunarcore.proto.ReEnterLastElementStageCsReqOuterClass.ReEnterLastElementStageCsReq;
import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.Opcodes;
import emu.lunarcore.server.packet.PacketHandler;
@Opcodes(CmdId.ReEnterLastElementStageCsReq)
public class HandlerReEnterLastElementStageCsReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
var req = ReEnterLastElementStageCsReq.parseFrom(data);
session.getServer().getBattleService().reEnterBattle(session.getPlayer(), req.getStageId());
}
}

View File

@@ -0,0 +1,28 @@
package emu.lunarcore.server.packet.send;
import emu.lunarcore.game.battle.Battle;
import emu.lunarcore.proto.ReEnterLastElementStageScRspOuterClass.ReEnterLastElementStageScRsp;
import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId;
public class PacketReEnterLastElementStageScRsp extends BasePacket {
public PacketReEnterLastElementStageScRsp() {
super(CmdId.ReEnterLastElementStageScRsp);
var data = ReEnterLastElementStageScRsp.newInstance()
.setRetcode(1);
this.setData(data);
}
public PacketReEnterLastElementStageScRsp(Battle battle) {
super(CmdId.ReEnterLastElementStageScRsp);
var data = ReEnterLastElementStageScRsp.newInstance()
.setStageId(battle.getStageId())
.setBattleInfo(battle.toProto());
this.setData(data);
}
}