mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-13 05:44:36 +01:00
Challenges now spawn the right monsters and can be completed
This commit is contained in:
@@ -20,6 +20,10 @@ public class GroupInfo {
|
||||
if (this.id == 0) this.id = id;
|
||||
}
|
||||
|
||||
public MonsterInfo getMonsterById(int configId) {
|
||||
return MonsterList.stream().filter(m -> m.getID() == configId).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public static enum GroupLoadSide {
|
||||
Client, Server;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ public class ChallengeExcel extends GameResource {
|
||||
private int ID;
|
||||
private int MapEntranceID;
|
||||
private int StageNum;
|
||||
private int ChallengeCountDown;
|
||||
private int MazeBuffID;
|
||||
|
||||
private int MazeGroupID1;
|
||||
|
||||
@@ -22,6 +22,7 @@ import emu.lunarcore.util.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
public class Battle {
|
||||
@@ -34,6 +35,8 @@ public class Battle {
|
||||
private final List<GameItem> drops;
|
||||
private final long timestamp;
|
||||
|
||||
@Setter private int roundsLimit;
|
||||
|
||||
private Battle(Player player, PlayerLineup lineup) {
|
||||
this.id = player.getNextBattleId();
|
||||
this.player = player;
|
||||
@@ -158,6 +161,7 @@ public class Battle {
|
||||
// Build battle info
|
||||
var proto = SceneBattleInfo.newInstance()
|
||||
.setBattleId(this.getId())
|
||||
.setRoundsLimit(this.getRoundsLimit())
|
||||
.setLogicRandomSeed(Utils.randomRange(1, Short.MAX_VALUE))
|
||||
.setWorldLevel(player.getWorldLevel());
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.game.scene.entity.EntityProp;
|
||||
import emu.lunarcore.game.scene.entity.GameEntity;
|
||||
import emu.lunarcore.proto.AvatarBattleInfoOuterClass.AvatarBattleInfo;
|
||||
import emu.lunarcore.proto.AvatarPropertyOuterClass.AvatarProperty;
|
||||
import emu.lunarcore.proto.BattleEndStatusOuterClass.BattleEndStatus;
|
||||
import emu.lunarcore.proto.BattleStatisticsOuterClass.BattleStatistics;
|
||||
import emu.lunarcore.server.game.BaseGameService;
|
||||
import emu.lunarcore.server.game.GameServer;
|
||||
import emu.lunarcore.server.packet.send.PacketReEnterLastElementStageScRsp;
|
||||
@@ -23,7 +23,6 @@ import emu.lunarcore.server.packet.send.PacketStartCocoonStageScRsp;
|
||||
import emu.lunarcore.server.packet.send.PacketSyncLineupNotify;
|
||||
|
||||
import us.hebi.quickbuf.RepeatedInt;
|
||||
import us.hebi.quickbuf.RepeatedMessage;
|
||||
|
||||
public class BattleService extends BaseGameService {
|
||||
|
||||
@@ -126,6 +125,11 @@ public class BattleService extends BaseGameService {
|
||||
}
|
||||
}
|
||||
|
||||
// Challenge
|
||||
if (player.getChallengeData() != null) {
|
||||
player.getChallengeData().onBattleStart(battle);
|
||||
}
|
||||
|
||||
// Set battle and send rsp packet
|
||||
player.setBattle(battle);
|
||||
player.sendPacket(new PacketSceneCastSkillScRsp(battle, attackedGroupId));
|
||||
@@ -179,7 +183,7 @@ public class BattleService extends BaseGameService {
|
||||
player.sendPacket(new PacketStartCocoonStageScRsp(battle, cocoonId, wave));
|
||||
}
|
||||
|
||||
public Battle finishBattle(Player player, BattleEndStatus result, RepeatedMessage<AvatarBattleInfo> battleAvatars) {
|
||||
public Battle finishBattle(Player player, BattleEndStatus result, BattleStatistics stats) {
|
||||
// Sanity check to make sure player is in a battle
|
||||
if (!player.isInBattle()) {
|
||||
return null;
|
||||
@@ -222,7 +226,7 @@ public class BattleService extends BaseGameService {
|
||||
// Check if avatar hp/sp should be updated after a battle
|
||||
if (updateStatus) {
|
||||
// Set health/energy for player avatars
|
||||
for (var battleAvatar : battleAvatars) {
|
||||
for (var battleAvatar : stats.getBattleAvatarList()) {
|
||||
GameAvatar avatar = player.getAvatarById(battleAvatar.getId());
|
||||
if (avatar == null) continue;
|
||||
|
||||
@@ -253,6 +257,11 @@ public class BattleService extends BaseGameService {
|
||||
}
|
||||
}
|
||||
|
||||
// Challenge
|
||||
if (player.getChallengeData() != null) {
|
||||
player.getChallengeData().onBattleFinish(battle, result, stats);
|
||||
}
|
||||
|
||||
// Done - Clear battle object from player
|
||||
player.setBattle(null);
|
||||
return battle;
|
||||
|
||||
158
src/main/java/emu/lunarcore/game/challenge/ChallengeData.java
Normal file
158
src/main/java/emu/lunarcore/game/challenge/ChallengeData.java
Normal file
@@ -0,0 +1,158 @@
|
||||
package emu.lunarcore.game.challenge;
|
||||
|
||||
import emu.lunarcore.data.GameData;
|
||||
import emu.lunarcore.data.config.GroupInfo;
|
||||
import emu.lunarcore.data.config.MonsterInfo;
|
||||
import emu.lunarcore.data.excel.ChallengeExcel;
|
||||
import emu.lunarcore.data.excel.NpcMonsterExcel;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.game.scene.Scene;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.BattleEndStatusOuterClass.BattleEndStatus;
|
||||
import emu.lunarcore.proto.BattleStatisticsOuterClass.BattleStatistics;
|
||||
import emu.lunarcore.proto.ChallengeInfoOuterClass.ChallengeInfo;
|
||||
import emu.lunarcore.proto.ChallengeStatusOuterClass.ChallengeStatus;
|
||||
import emu.lunarcore.proto.ExtraLineupTypeOuterClass.ExtraLineupType;
|
||||
import emu.lunarcore.server.packet.send.PacketChallengeLineupNotify;
|
||||
import emu.lunarcore.server.packet.send.PacketChallengeSettleNotify;
|
||||
import emu.lunarcore.util.Position;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
public class ChallengeData {
|
||||
private final Player player;
|
||||
private final Scene scene;
|
||||
private final ChallengeExcel excel;
|
||||
private final Position startPos;
|
||||
|
||||
private int currentStage;
|
||||
private ExtraLineupType currentExtraLineup;
|
||||
private ChallengeStatus status;
|
||||
|
||||
@Setter private int roundsLimit;
|
||||
@Setter private int stars;
|
||||
|
||||
public ChallengeData(Player player, ChallengeExcel excel) {
|
||||
this.player = player;
|
||||
this.scene = player.getScene();
|
||||
this.excel = excel;
|
||||
this.startPos = player.getPos().clone();
|
||||
this.currentStage = 1;
|
||||
this.roundsLimit = excel.getChallengeCountDown();
|
||||
this.status = ChallengeStatus.CHALLENGE_DOING;
|
||||
this.currentExtraLineup = ExtraLineupType.LINEUP_CHALLENGE;
|
||||
|
||||
// Setup first stage
|
||||
this.setupStage1();
|
||||
}
|
||||
|
||||
private void setupStage1() {
|
||||
this.setupStage(
|
||||
excel.getMazeGroupID1(),
|
||||
excel.getConfigList1(),
|
||||
excel.getNpcMonsterIDList1(),
|
||||
excel.getEventIDList1(),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private void setupStage2() {
|
||||
this.setupStage(
|
||||
excel.getMazeGroupID2(),
|
||||
excel.getConfigList2(),
|
||||
excel.getNpcMonsterIDList2(),
|
||||
excel.getEventIDList2(),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
private void setupStage(int groupId, int[] configs, int[] npcMonsters, int[] eventIds, boolean sendPacket) {
|
||||
// Load group
|
||||
GroupInfo group = getScene().getFloorInfo().getGroups().get(groupId);
|
||||
|
||||
// Replace monsters in scene
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
// Setup vars
|
||||
int instId = configs[i];
|
||||
int npcMonster = npcMonsters[i];
|
||||
int eventId = eventIds[i];
|
||||
|
||||
// Get monster info
|
||||
MonsterInfo monsterInfo = group.getMonsterById(instId);
|
||||
if (monsterInfo == null) continue;
|
||||
|
||||
// Get excels from game data
|
||||
NpcMonsterExcel npcMonsterExcel = GameData.getNpcMonsterExcelMap().get(npcMonster);
|
||||
if (npcMonsterExcel == null) continue;
|
||||
|
||||
// Create monster with excels
|
||||
EntityMonster monster = new EntityMonster(getScene(), npcMonsterExcel, monsterInfo.clonePos());
|
||||
monster.getRot().setY((int) (monsterInfo.getRotY() * 1000f));
|
||||
monster.setInstId(instId);
|
||||
monster.setEventId(eventId);
|
||||
monster.setOverrideStageId(eventId);
|
||||
monster.setGroupId(group.getId());
|
||||
monster.setWorldLevel(this.getPlayer().getWorldLevel());
|
||||
|
||||
// Add to scene
|
||||
getScene().addEntity(monster, sendPacket);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWin() {
|
||||
return status == ChallengeStatus.CHALLENGE_FINISH;
|
||||
}
|
||||
|
||||
public void onBattleStart(Battle battle) {
|
||||
battle.setRoundsLimit(player.getChallengeData().getRoundsLimit());
|
||||
}
|
||||
|
||||
public void onBattleFinish(Battle battle, BattleEndStatus result, BattleStatistics stats) {
|
||||
if (result == BattleEndStatus.BATTLE_END_WIN) {
|
||||
// Get monster count in stage
|
||||
long monsters = player.getScene().getEntities().values().stream().filter(e -> e instanceof EntityMonster).count();
|
||||
|
||||
if (monsters == 0) {
|
||||
// Progress to the next stage
|
||||
if (this.currentStage >= excel.getStageNum()) {
|
||||
// Last stage
|
||||
this.status = ChallengeStatus.CHALLENGE_FINISH;
|
||||
this.stars = 9; // TODO calculate the right amount stars
|
||||
// Send challenge result data
|
||||
player.sendPacket(new PacketChallengeSettleNotify(this));
|
||||
} else {
|
||||
// Increment and reset stage
|
||||
this.currentStage++;
|
||||
this.setupStage2();
|
||||
// Change player line up
|
||||
this.currentExtraLineup = ExtraLineupType.LINEUP_CHALLENGE_2;
|
||||
player.getLineupManager().setCurrentExtraLineup(this.getCurrentExtraLineup(), true);
|
||||
player.sendPacket(new PacketChallengeLineupNotify(this.getCurrentExtraLineup()));
|
||||
// Move player
|
||||
player.moveTo(this.getStartPos());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fail challenge
|
||||
this.status = ChallengeStatus.CHALLENGE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
public void onUpdate() {
|
||||
// End challenge if its done
|
||||
if (status != ChallengeStatus.CHALLENGE_DOING) {
|
||||
getPlayer().setChallengeData(null);
|
||||
}
|
||||
}
|
||||
|
||||
public ChallengeInfo toProto() {
|
||||
var proto = ChallengeInfo.newInstance()
|
||||
.setChallengeId(this.getExcel().getId())
|
||||
.setStatus(this.getStatus())
|
||||
.setExtraLineupType(this.getCurrentExtraLineup());
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,19 @@ public class ChallengeService extends BaseGameService {
|
||||
return;
|
||||
}
|
||||
|
||||
player.enterScene(excel.getMapEntranceID(), 0, false);
|
||||
// Sanity check lineups TODO
|
||||
|
||||
// Enter scene
|
||||
boolean success = player.enterScene(excel.getMapEntranceID(), 0, false);
|
||||
if (success == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set challenge data for player
|
||||
ChallengeData data = new ChallengeData(player, excel);
|
||||
|
||||
player.setChallengeData(data);
|
||||
player.getLineupManager().setCurrentExtraLineup(data.getCurrentExtraLineup(), false);
|
||||
|
||||
// Send packet
|
||||
player.sendPacket(new PacketStartChallengeScRsp(player, challengeId));
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.lunarcore.GameConstants;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.proto.ExtraLineupTypeOuterClass.ExtraLineupType;
|
||||
import emu.lunarcore.server.packet.send.PacketSyncLineupNotify;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
@@ -43,8 +44,21 @@ public class LineupManager {
|
||||
this.mp = Math.max(this.mp - i, 0);
|
||||
}
|
||||
|
||||
public void setCurrentExtraLineup(int i) {
|
||||
this.currentExtraLineup = i;
|
||||
/**
|
||||
* Sets the player's current extra lineup type.
|
||||
* @param type Extra lineup type
|
||||
* @param sync Whether or not to sync lineup with scene. Not needed when changing scenes.
|
||||
*/
|
||||
public void setCurrentExtraLineup(int type, boolean sync) {
|
||||
this.currentExtraLineup = type;
|
||||
|
||||
if (sync) {
|
||||
this.getPlayer().getScene().syncLineup();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentExtraLineup(ExtraLineupType type, boolean sync) {
|
||||
this.setCurrentExtraLineup(type.getNumber(), sync);
|
||||
}
|
||||
|
||||
public PlayerLineup getLineupByIndex(int index, int extraLineup) {
|
||||
@@ -74,15 +88,7 @@ public class LineupManager {
|
||||
* @return
|
||||
*/
|
||||
private PlayerLineup getExtraLineupByType(int extraLineupType) {
|
||||
PlayerLineup lineup = this.extraLineups.get(extraLineupType);
|
||||
|
||||
if (lineup == null) {
|
||||
lineup = new PlayerLineup(0, extraLineupType);
|
||||
lineup.setOwnerAndIndex(this.getPlayer(), 0);
|
||||
this.extraLineups.put(extraLineupType, lineup);
|
||||
}
|
||||
|
||||
return lineup;
|
||||
return getExtraLineups().computeIfAbsent(extraLineupType, type -> new PlayerLineup(getPlayer(), 0, type));
|
||||
}
|
||||
|
||||
public PlayerLineup getCurrentLineup() {
|
||||
@@ -309,9 +315,10 @@ public class LineupManager {
|
||||
// Create new lineups for any missing ones
|
||||
for (int i = 0; i < this.lineups.length; i++) {
|
||||
if (this.lineups[i] == null) {
|
||||
this.lineups[i] = new PlayerLineup(i);
|
||||
this.lineups[i] = new PlayerLineup(getPlayer(), i, 0);
|
||||
} else {
|
||||
this.lineups[i].setOwnerAndIndex(getPlayer(), i);
|
||||
}
|
||||
this.lineups[i].setOwnerAndIndex(getPlayer(), i);
|
||||
}
|
||||
|
||||
// Set current index if out of bounds
|
||||
|
||||
@@ -20,6 +20,7 @@ import emu.lunarcore.game.avatar.AvatarStorage;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.avatar.HeroPath;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.challenge.ChallengeData;
|
||||
import emu.lunarcore.game.chat.ChatManager;
|
||||
import emu.lunarcore.game.chat.ChatMessage;
|
||||
import emu.lunarcore.game.enums.PropState;
|
||||
@@ -84,10 +85,12 @@ public class Player {
|
||||
private PlayerGachaInfo gachaInfo;
|
||||
|
||||
// Etc
|
||||
@Setter private transient boolean paused;
|
||||
private transient boolean inAnchorRange;
|
||||
private transient int nextBattleId;
|
||||
|
||||
|
||||
@Setter private transient boolean paused;
|
||||
@Setter private transient ChallengeData challengeData;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public Player() {
|
||||
this.curBasicType = GameConstants.TRAILBLAZER_AVATAR_ID;
|
||||
@@ -443,6 +446,9 @@ public class Player {
|
||||
} else {
|
||||
nextScene = new Scene(this, planeExcel, floorId);
|
||||
}
|
||||
|
||||
// Clear any extra data the player might have
|
||||
this.setChallengeData(null);
|
||||
|
||||
// Set positions if player has logged in
|
||||
if (this.getSession().getState() != SessionState.WAITING_FOR_TOKEN) {
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.List;
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.lunarcore.GameConstants;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.proto.ExtraLineupTypeOuterClass.ExtraLineupType;
|
||||
import emu.lunarcore.proto.LineupInfoOuterClass.LineupInfo;
|
||||
import emu.lunarcore.server.packet.send.PacketSyncLineupNotify;
|
||||
import lombok.Getter;
|
||||
@@ -26,11 +25,9 @@ public class PlayerLineup {
|
||||
|
||||
}
|
||||
|
||||
public PlayerLineup(int index) {
|
||||
this(index, 0);
|
||||
}
|
||||
|
||||
public PlayerLineup(int index, int extraLineupType) {
|
||||
public PlayerLineup(Player player, int index, int extraLineupType) {
|
||||
this.owner = player;
|
||||
this.index = index;
|
||||
this.extraLineupType = extraLineupType;
|
||||
this.avatars = new ArrayList<>(GameConstants.MAX_AVATARS_IN_TEAM);
|
||||
|
||||
@@ -93,7 +90,7 @@ public class PlayerLineup {
|
||||
.setLeaderSlot(this.getOwner().getLineupManager().getCurrentLeader())
|
||||
.setMp(this.getOwner().getLineupManager().getMp())
|
||||
.setMaxMp(GameConstants.MAX_MP)
|
||||
.setExtraLineupType(ExtraLineupType.LINEUP_NONE);
|
||||
.setExtraLineupTypeValue(this.getExtraLineupType());
|
||||
|
||||
for (int slot = 0; slot < this.getAvatars().size(); slot++) {
|
||||
GameAvatar avatar = owner.getAvatars().getAvatarById(getAvatars().get(slot));
|
||||
|
||||
@@ -10,6 +10,7 @@ import emu.lunarcore.data.excel.MazePlaneExcel;
|
||||
import emu.lunarcore.data.excel.NpcMonsterExcel;
|
||||
import emu.lunarcore.data.excel.PropExcel;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.enums.GameModeType;
|
||||
import emu.lunarcore.game.enums.PropState;
|
||||
import emu.lunarcore.game.enums.PropType;
|
||||
import emu.lunarcore.game.player.PlayerLineup;
|
||||
@@ -78,110 +79,122 @@ public class Scene {
|
||||
this.avatarEntityIds.add(avatar.getEntityId());
|
||||
}
|
||||
|
||||
// Spawn monsters
|
||||
// Set floor info
|
||||
this.floorInfo = GameData.getFloorInfo(this.planeId, this.floorId);
|
||||
if (floorInfo == null) return;
|
||||
|
||||
for (GroupInfo group : floorInfo.getGroups().values()) {
|
||||
// Skip non-server groups
|
||||
if (group.getLoadSide() != GroupLoadSide.Server) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add monsters
|
||||
if (group.getMonsterList() != null && group.getMonsterList().size() > 0) {
|
||||
for (MonsterInfo monsterInfo : group.getMonsterList()) {
|
||||
// Get excels from game data
|
||||
NpcMonsterExcel npcMonsterExcel = GameData.getNpcMonsterExcelMap().get(monsterInfo.getNPCMonsterID());
|
||||
if (npcMonsterExcel == null) continue;
|
||||
|
||||
// Create monster with excels
|
||||
EntityMonster monster = new EntityMonster(this, npcMonsterExcel, monsterInfo.clonePos());
|
||||
monster.getRot().setY((int) (monsterInfo.getRotY() * 1000f));
|
||||
monster.setInstId(monsterInfo.getID());
|
||||
monster.setEventId(monsterInfo.getEventID());
|
||||
monster.setGroupId(group.getId());
|
||||
monster.setWorldLevel(this.getPlayer().getWorldLevel());
|
||||
|
||||
// Add to monsters
|
||||
this.addEntity(monster);
|
||||
}
|
||||
}
|
||||
|
||||
// Add props
|
||||
if (group.getPropList() != null && group.getPropList().size() > 0) {
|
||||
for (PropInfo propInfo : group.getPropList()) {
|
||||
// Get prop excel
|
||||
PropExcel propExcel = GameData.getPropExcelMap().get(propInfo.getPropID());
|
||||
if (propExcel == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create prop from prop info
|
||||
EntityProp prop = new EntityProp(this, propExcel, propInfo.clonePos());
|
||||
prop.setState(propInfo.getState());
|
||||
prop.getRot().set(
|
||||
(int) (propInfo.getRotX() * 1000f),
|
||||
(int) (propInfo.getRotY() * 1000f),
|
||||
(int) (propInfo.getRotZ() * 1000f)
|
||||
);
|
||||
prop.setInstId(propInfo.getID());
|
||||
prop.setGroupId(group.getId());
|
||||
prop.setPropInfo(propInfo);
|
||||
|
||||
// Hacky fixes
|
||||
if (prop.getPropId() == 1003) {
|
||||
// Open simulated universe
|
||||
prop.setState(PropState.Open);
|
||||
} else if (prop.getExcel().getPropType() == PropType.PROP_SPRING) {
|
||||
// Cache teleport anchors
|
||||
this.getHealingSprings().add(prop);
|
||||
}
|
||||
|
||||
// Add trigger
|
||||
if (propInfo.getTrigger() != null) {
|
||||
this.getTriggers().add(propInfo.getTrigger());
|
||||
}
|
||||
|
||||
// Add to monsters
|
||||
this.addEntity(prop);
|
||||
}
|
||||
}
|
||||
|
||||
// Add npcs
|
||||
if (group.getNPCList() != null && group.getNPCList().size() > 0) {
|
||||
for (NpcInfo npcInfo : group.getNPCList()) {
|
||||
// Sanity check
|
||||
if (!GameData.getNpcExcelMap().containsKey(npcInfo.getNPCID())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Dont spawn duplicate NPCs
|
||||
boolean haseDuplicateNpcId = false;
|
||||
for (GameEntity entity : this.getEntities().values()) {
|
||||
if (entity instanceof EntityNpc eNpc && eNpc.getNpcId() == npcInfo.getNPCID()) {
|
||||
haseDuplicateNpcId = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (haseDuplicateNpcId) continue;
|
||||
|
||||
// Create npc from npc info
|
||||
EntityNpc npc = new EntityNpc(this, npcInfo.getNPCID(), npcInfo.clonePos());
|
||||
npc.getRot().setY((int) (npcInfo.getRotY() * 1000f));
|
||||
npc.setInstId(npcInfo.getID());
|
||||
npc.setGroupId(group.getId());
|
||||
|
||||
// Add to monsters
|
||||
this.addEntity(npc);
|
||||
}
|
||||
}
|
||||
// Spawn from groups
|
||||
if (this.getExcel().getPlaneType() != GameModeType.Challenge) {
|
||||
this.initSpawns();
|
||||
}
|
||||
|
||||
// Done
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
private void initSpawns() {
|
||||
for (GroupInfo group : getFloorInfo().getGroups().values()) {
|
||||
// Skip non-server groups
|
||||
if (group.getLoadSide() != GroupLoadSide.Server) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load group
|
||||
this.loadGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadGroup(GroupInfo group) {
|
||||
// Add monsters
|
||||
if (group.getMonsterList() != null && group.getMonsterList().size() > 0) {
|
||||
for (MonsterInfo monsterInfo : group.getMonsterList()) {
|
||||
// Get excels from game data
|
||||
NpcMonsterExcel npcMonsterExcel = GameData.getNpcMonsterExcelMap().get(monsterInfo.getNPCMonsterID());
|
||||
if (npcMonsterExcel == null) continue;
|
||||
|
||||
// Create monster with excels
|
||||
EntityMonster monster = new EntityMonster(this, npcMonsterExcel, monsterInfo.clonePos());
|
||||
monster.getRot().setY((int) (monsterInfo.getRotY() * 1000f));
|
||||
monster.setInstId(monsterInfo.getID());
|
||||
monster.setEventId(monsterInfo.getEventID());
|
||||
monster.setGroupId(group.getId());
|
||||
monster.setWorldLevel(this.getPlayer().getWorldLevel());
|
||||
|
||||
// Add to monsters
|
||||
this.addEntity(monster);
|
||||
}
|
||||
}
|
||||
|
||||
// Add props
|
||||
if (group.getPropList() != null && group.getPropList().size() > 0) {
|
||||
for (PropInfo propInfo : group.getPropList()) {
|
||||
// Get prop excel
|
||||
PropExcel propExcel = GameData.getPropExcelMap().get(propInfo.getPropID());
|
||||
if (propExcel == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create prop from prop info
|
||||
EntityProp prop = new EntityProp(this, propExcel, propInfo.clonePos());
|
||||
prop.setState(propInfo.getState());
|
||||
prop.getRot().set(
|
||||
(int) (propInfo.getRotX() * 1000f),
|
||||
(int) (propInfo.getRotY() * 1000f),
|
||||
(int) (propInfo.getRotZ() * 1000f)
|
||||
);
|
||||
prop.setInstId(propInfo.getID());
|
||||
prop.setGroupId(group.getId());
|
||||
prop.setPropInfo(propInfo);
|
||||
|
||||
// Hacky fixes
|
||||
if (prop.getPropId() == 1003) {
|
||||
// Open simulated universe
|
||||
prop.setState(PropState.Open);
|
||||
} else if (prop.getExcel().getPropType() == PropType.PROP_SPRING) {
|
||||
// Cache teleport anchors
|
||||
this.getHealingSprings().add(prop);
|
||||
}
|
||||
|
||||
// Add trigger
|
||||
if (propInfo.getTrigger() != null) {
|
||||
this.getTriggers().add(propInfo.getTrigger());
|
||||
}
|
||||
|
||||
// Add to monsters
|
||||
this.addEntity(prop);
|
||||
}
|
||||
}
|
||||
|
||||
// Add npcs
|
||||
if (group.getNPCList() != null && group.getNPCList().size() > 0) {
|
||||
for (NpcInfo npcInfo : group.getNPCList()) {
|
||||
// Sanity check
|
||||
if (!GameData.getNpcExcelMap().containsKey(npcInfo.getNPCID())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Dont spawn duplicate NPCs
|
||||
boolean haseDuplicateNpcId = false;
|
||||
for (GameEntity entity : this.getEntities().values()) {
|
||||
if (entity instanceof EntityNpc eNpc && eNpc.getNpcId() == npcInfo.getNPCID()) {
|
||||
haseDuplicateNpcId = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (haseDuplicateNpcId) continue;
|
||||
|
||||
// Create npc from npc info
|
||||
EntityNpc npc = new EntityNpc(this, npcInfo.getNPCID(), npcInfo.clonePos());
|
||||
npc.getRot().setY((int) (npcInfo.getRotY() * 1000f));
|
||||
npc.setInstId(npcInfo.getID());
|
||||
npc.setGroupId(group.getId());
|
||||
|
||||
// Add to monsters
|
||||
this.addEntity(npc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setEntryId(int entryId) {
|
||||
this.entryId = entryId;
|
||||
}
|
||||
@@ -293,6 +306,10 @@ public class Scene {
|
||||
}
|
||||
|
||||
public synchronized void addEntity(GameEntity entity) {
|
||||
this.addEntity(entity, false);
|
||||
}
|
||||
|
||||
public synchronized void addEntity(GameEntity entity, boolean sendPacket) {
|
||||
// Dont add if monster id already exists
|
||||
if (entity.getEntityId() != 0) return;
|
||||
// Set entity id and add monster to entity map
|
||||
@@ -300,6 +317,10 @@ public class Scene {
|
||||
this.getEntities().put(entity.getEntityId(), entity);
|
||||
// Entity add callback
|
||||
entity.onAdd();
|
||||
// Send packet
|
||||
if (sendPacket) {
|
||||
player.sendPacket(new PacketSceneGroupRefreshScNotify(entity, null));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeEntity(GameEntity entity) {
|
||||
|
||||
@@ -20,9 +20,9 @@ public class EntityMonster implements GameEntity {
|
||||
@Setter private int instId;
|
||||
@Setter private int eventId;
|
||||
@Setter private int overrideStageId;
|
||||
@Setter private NpcMonsterExcel excel;
|
||||
|
||||
private final Scene scene;
|
||||
private final NpcMonsterExcel excel;
|
||||
private final Position pos;
|
||||
private final Position rot;
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.lunarcore.server.packet.recv;
|
||||
|
||||
import emu.lunarcore.server.game.GameSession;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
import emu.lunarcore.server.packet.Opcodes;
|
||||
import emu.lunarcore.server.packet.PacketHandler;
|
||||
import emu.lunarcore.server.packet.send.PacketGetCurChallengeScRsp;
|
||||
|
||||
@Opcodes(CmdId.GetCurChallengeCsReq)
|
||||
public class HandlerGetCurChallengeCsReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
|
||||
// Send packet first
|
||||
session.send(new PacketGetCurChallengeScRsp(session.getPlayer()));
|
||||
// Update challenge details for client
|
||||
if (session.getPlayer().getChallengeData() != null) {
|
||||
session.getPlayer().getChallengeData().onUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@ public class HandlerLeaveChallengeCsReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
|
||||
// TODO make sure client is in a challenge mode map
|
||||
session.getPlayer().getLineupManager().setCurrentExtraLineup(0);
|
||||
session.getPlayer().getLineupManager().setCurrentExtraLineup(0, false);
|
||||
session.getPlayer().enterScene(100000103, 0, true);
|
||||
session.send(CmdId.LeaveChallengeScRsp);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class HandlerPVEBattleResultCsReq extends PacketHandler {
|
||||
Battle battle = session.getServer().getBattleService().finishBattle(
|
||||
session.getPlayer(),
|
||||
req.getEndStatus(),
|
||||
req.getStt().getBattleAvatarList()
|
||||
req.getStt()
|
||||
);
|
||||
|
||||
if (battle != null) {
|
||||
|
||||
@@ -23,7 +23,7 @@ public class HandlerReplaceLineupCsReq extends PacketHandler {
|
||||
lineupList.add(slot.getId());
|
||||
}
|
||||
|
||||
session.getPlayer().getLineupManager().replaceLineup(req.getIndex(), req.getExtraLineupType().getNumber(), lineupList);
|
||||
session.getPlayer().getLineupManager().replaceLineup(req.getIndex(), req.getExtraLineupTypeValue(), lineupList);
|
||||
session.send(new BasePacket(CmdId.ReplaceLineupScRsp));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.lunarcore.server.packet.send;
|
||||
|
||||
import emu.lunarcore.proto.ChallengeLineupNotifyOuterClass.ChallengeLineupNotify;
|
||||
import emu.lunarcore.proto.ExtraLineupTypeOuterClass.ExtraLineupType;
|
||||
import emu.lunarcore.server.packet.BasePacket;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
|
||||
public class PacketChallengeLineupNotify extends BasePacket {
|
||||
|
||||
public PacketChallengeLineupNotify(ExtraLineupType type) {
|
||||
super(CmdId.ChallengeLineupNotify);
|
||||
|
||||
var data = ChallengeLineupNotify.newInstance()
|
||||
.setExtraLineupType(type);
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.lunarcore.server.packet.send;
|
||||
|
||||
import emu.lunarcore.game.challenge.ChallengeData;
|
||||
import emu.lunarcore.proto.ChallengeSettleNotifyOuterClass.ChallengeSettleNotify;
|
||||
import emu.lunarcore.proto.ItemListOuterClass.ItemList;
|
||||
import emu.lunarcore.server.packet.BasePacket;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
|
||||
public class PacketChallengeSettleNotify extends BasePacket {
|
||||
|
||||
public PacketChallengeSettleNotify(ChallengeData challenge) {
|
||||
super(CmdId.ChallengeSettleNotify);
|
||||
|
||||
var data = ChallengeSettleNotify.newInstance()
|
||||
.setChallengeId(challenge.getExcel().getId())
|
||||
.setIsWin(challenge.isWin())
|
||||
.setReward(ItemList.newInstance())
|
||||
.setStars(challenge.getStars());
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.lunarcore.server.packet.send;
|
||||
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.proto.GetCurChallengeScRspOuterClass.GetCurChallengeScRsp;
|
||||
import emu.lunarcore.server.packet.BasePacket;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
|
||||
public class PacketGetCurChallengeScRsp extends BasePacket {
|
||||
|
||||
public PacketGetCurChallengeScRsp(Player player) {
|
||||
super(CmdId.GetCurChallengeScRsp);
|
||||
|
||||
var data = GetCurChallengeScRsp.newInstance();
|
||||
|
||||
if (player.getChallengeData() != null) {
|
||||
data.setChallengeInfo(player.getChallengeData().toProto());
|
||||
} else {
|
||||
data.setRetcode(1);
|
||||
}
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
@@ -22,15 +22,15 @@ public class PacketStartChallengeScRsp extends BasePacket {
|
||||
public PacketStartChallengeScRsp(Player player, int challengeId) {
|
||||
super(CmdId.StartChallengeScRsp);
|
||||
|
||||
var challengeInfo = ChallengeInfo.newInstance()
|
||||
.setChallengeId(challengeId)
|
||||
.setStatus(ChallengeStatus.CHALLENGE_DOING)
|
||||
.setExtraLineupType(ExtraLineupType.LINEUP_CHALLENGE);
|
||||
var data = StartChallengeScRsp.newInstance();
|
||||
|
||||
var data = StartChallengeScRsp.newInstance()
|
||||
.setLineup(player.getCurrentLineup().toProto().setExtraLineupType(ExtraLineupType.LINEUP_CHALLENGE)) // TODO temporary
|
||||
.setScene(player.getScene().toProto())
|
||||
.setChallengeInfo(challengeInfo);
|
||||
if (player.getChallengeData() != null) {
|
||||
data.setLineup(player.getCurrentLineup().toProto());
|
||||
data.setScene(player.getScene().toProto());
|
||||
data.setChallengeInfo(player.getChallengeData().toProto());
|
||||
} else {
|
||||
data.setRetcode(1);
|
||||
}
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user