mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-13 13:54:37 +01:00
Battles with monsters in mazes now drop items
This commit is contained in:
@@ -36,6 +36,7 @@ public class GameData {
|
|||||||
private static Int2ObjectMap<EquipmentPromotionExcel> equipmentPromotionExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<EquipmentPromotionExcel> equipmentPromotionExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static Int2ObjectMap<MazeBuffExcel> mazeBuffExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<MazeBuffExcel> mazeBuffExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static Int2ObjectMap<CocoonExcel> cocoonExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<CocoonExcel> cocoonExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static Int2ObjectMap<MonsterDropExcel> monsterDropExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
private static Int2ObjectMap<PlayerLevelExcel> playerLevelExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<PlayerLevelExcel> playerLevelExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static Int2ObjectMap<ExpTypeExcel> expTypeExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<ExpTypeExcel> expTypeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
@@ -117,4 +118,8 @@ public class GameData {
|
|||||||
public static CocoonExcel getCocoonExcel(int cocoonId, int worldLevel) {
|
public static CocoonExcel getCocoonExcel(int cocoonId, int worldLevel) {
|
||||||
return cocoonExcelMap.get((cocoonId << 8) + worldLevel);
|
return cocoonExcelMap.get((cocoonId << 8) + worldLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MonsterDropExcel getMonsterDropExcel(int monsterNpcId, int worldLevel) {
|
||||||
|
return monsterDropExcelMap.get((monsterNpcId << 4) + worldLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/main/java/emu/lunarcore/data/excel/MonsterDropExcel.java
Normal file
24
src/main/java/emu/lunarcore/data/excel/MonsterDropExcel.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package emu.lunarcore.data.excel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.lunarcore.data.GameResource;
|
||||||
|
import emu.lunarcore.data.ResourceType;
|
||||||
|
import emu.lunarcore.data.common.ItemParam;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = {"MonsterDrop.json"})
|
||||||
|
public class MonsterDropExcel extends GameResource {
|
||||||
|
private int MonsterTemplateID;
|
||||||
|
private int WorldLevel;
|
||||||
|
private int AvatarExpReward;
|
||||||
|
|
||||||
|
private List<ItemParam> DisplayItemList;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return (MonsterTemplateID << 4) + WorldLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,10 +5,12 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import emu.lunarcore.data.GameData;
|
import emu.lunarcore.data.GameData;
|
||||||
|
import emu.lunarcore.data.common.ItemParam;
|
||||||
import emu.lunarcore.data.excel.MazeBuffExcel;
|
import emu.lunarcore.data.excel.MazeBuffExcel;
|
||||||
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.enums.StageType;
|
||||||
|
import emu.lunarcore.game.inventory.GameItem;
|
||||||
import emu.lunarcore.game.player.Player;
|
import emu.lunarcore.game.player.Player;
|
||||||
import emu.lunarcore.game.player.PlayerLineup;
|
import emu.lunarcore.game.player.PlayerLineup;
|
||||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
@@ -17,6 +19,7 @@ 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.Int2IntOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@@ -28,6 +31,7 @@ public class Battle {
|
|||||||
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;
|
||||||
|
private final List<GameItem> drops;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
|
|
||||||
private Battle(Player player, PlayerLineup lineup) {
|
private Battle(Player player, PlayerLineup lineup) {
|
||||||
@@ -37,6 +41,7 @@ public class Battle {
|
|||||||
this.npcMonsters = new ArrayList<>();
|
this.npcMonsters = new ArrayList<>();
|
||||||
this.buffs = new ArrayList<>();
|
this.buffs = new ArrayList<>();
|
||||||
this.stages = new ArrayList<>();
|
this.stages = new ArrayList<>();
|
||||||
|
this.drops = new ArrayList<>();
|
||||||
this.timestamp = System.currentTimeMillis();
|
this.timestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +89,8 @@ public class Battle {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Battle buffs
|
||||||
|
|
||||||
public MazeBuff addBuff(int buffId, int ownerIndex) {
|
public MazeBuff addBuff(int buffId, int ownerIndex) {
|
||||||
return addBuff(buffId, ownerIndex, 0xffffffff);
|
return addBuff(buffId, ownerIndex, 0xffffffff);
|
||||||
}
|
}
|
||||||
@@ -102,6 +109,51 @@ public class Battle {
|
|||||||
this.buffs.clear();
|
this.buffs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drops
|
||||||
|
|
||||||
|
public void calculateDrops() {
|
||||||
|
// TODO this isnt the right way drops are calculated on the official server... but its good enough for now
|
||||||
|
if (this.getNpcMonsters().size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dropMap = new Int2IntOpenHashMap();
|
||||||
|
|
||||||
|
// Get drops from monsters
|
||||||
|
for (EntityMonster monster : this.getNpcMonsters()) {
|
||||||
|
var dropExcel = GameData.getMonsterDropExcel(monster.getExcel().getId(), monster.getWorldLevel());
|
||||||
|
if (dropExcel == null || dropExcel.getDisplayItemList() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ItemParam param : dropExcel.getDisplayItemList()) {
|
||||||
|
int id = param.getId();
|
||||||
|
int count = Utils.randomRange(0, 3);
|
||||||
|
|
||||||
|
if (id == 2) {
|
||||||
|
count = dropExcel.getAvatarExpReward();
|
||||||
|
}
|
||||||
|
|
||||||
|
dropMap.put(id, count + dropMap.get(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entry : dropMap.int2IntEntrySet()) {
|
||||||
|
if (entry.getIntValue() <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create item and add it to player
|
||||||
|
GameItem item = new GameItem(entry.getIntKey(), entry.getIntValue());
|
||||||
|
|
||||||
|
if (getPlayer().getInventory().addItem(item)) {
|
||||||
|
this.getDrops().add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialization
|
||||||
|
|
||||||
public SceneBattleInfo toProto() {
|
public SceneBattleInfo toProto() {
|
||||||
// Build battle info
|
// Build battle info
|
||||||
var proto = SceneBattleInfo.newInstance()
|
var proto = SceneBattleInfo.newInstance()
|
||||||
|
|||||||
@@ -179,10 +179,10 @@ public class BattleService extends BaseGameService {
|
|||||||
player.sendPacket(new PacketStartCocoonStageScRsp(battle, cocoonId, wave));
|
player.sendPacket(new PacketStartCocoonStageScRsp(battle, cocoonId, wave));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finishBattle(Player player, BattleEndStatus result, RepeatedMessage<AvatarBattleInfo> battleAvatars) {
|
public Battle finishBattle(Player player, BattleEndStatus result, RepeatedMessage<AvatarBattleInfo> battleAvatars) {
|
||||||
// Sanity check to make sure player is in a battle
|
// Sanity check to make sure player is in a battle
|
||||||
if (!player.isInBattle()) {
|
if (!player.isInBattle()) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get battle object and setup variables
|
// Get battle object and setup variables
|
||||||
@@ -199,6 +199,8 @@ public class BattleService extends BaseGameService {
|
|||||||
for (var monster : battle.getNpcMonsters()) {
|
for (var monster : battle.getNpcMonsters()) {
|
||||||
player.getScene().removeEntity(monster);
|
player.getScene().removeEntity(monster);
|
||||||
}
|
}
|
||||||
|
// Drops
|
||||||
|
battle.calculateDrops();
|
||||||
}
|
}
|
||||||
case BATTLE_END_LOSE -> {
|
case BATTLE_END_LOSE -> {
|
||||||
// Set avatar hp to 20% if the player's party is downed
|
// Set avatar hp to 20% if the player's party is downed
|
||||||
@@ -247,6 +249,7 @@ public class BattleService extends BaseGameService {
|
|||||||
|
|
||||||
// Done - Clear battle object from player
|
// Done - Clear battle object from player
|
||||||
player.setBattle(null);
|
player.setBattle(null);
|
||||||
|
return battle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reEnterBattle(Player player, int stageId) {
|
public void reEnterBattle(Player player, int stageId) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package emu.lunarcore.server.packet.recv;
|
package emu.lunarcore.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.lunarcore.game.battle.Battle;
|
||||||
import emu.lunarcore.proto.PVEBattleResultCsReqOuterClass.PVEBattleResultCsReq;
|
import emu.lunarcore.proto.PVEBattleResultCsReqOuterClass.PVEBattleResultCsReq;
|
||||||
import emu.lunarcore.server.game.GameSession;
|
import emu.lunarcore.server.game.GameSession;
|
||||||
import emu.lunarcore.server.packet.CmdId;
|
import emu.lunarcore.server.packet.CmdId;
|
||||||
@@ -14,13 +15,17 @@ public class HandlerPVEBattleResultCsReq extends PacketHandler {
|
|||||||
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
|
||||||
var req = PVEBattleResultCsReq.parseFrom(data);
|
var req = PVEBattleResultCsReq.parseFrom(data);
|
||||||
|
|
||||||
session.getServer().getBattleService().finishBattle(
|
Battle battle = session.getServer().getBattleService().finishBattle(
|
||||||
session.getPlayer(),
|
session.getPlayer(),
|
||||||
req.getEndStatus(),
|
req.getEndStatus(),
|
||||||
req.getStt().getBattleAvatarList()
|
req.getStt().getBattleAvatarList()
|
||||||
);
|
);
|
||||||
|
|
||||||
session.send(new PacketPVEBattleResultScRsp(req));
|
if (battle != null) {
|
||||||
|
session.send(new PacketPVEBattleResultScRsp(req, battle));
|
||||||
|
} else {
|
||||||
|
session.send(new PacketPVEBattleResultScRsp());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package emu.lunarcore.server.packet.send;
|
package emu.lunarcore.server.packet.send;
|
||||||
|
|
||||||
|
import emu.lunarcore.game.battle.Battle;
|
||||||
|
import emu.lunarcore.game.inventory.GameItem;
|
||||||
import emu.lunarcore.proto.ItemListOuterClass.ItemList;
|
import emu.lunarcore.proto.ItemListOuterClass.ItemList;
|
||||||
import emu.lunarcore.proto.PVEBattleResultCsReqOuterClass.PVEBattleResultCsReq;
|
import emu.lunarcore.proto.PVEBattleResultCsReqOuterClass.PVEBattleResultCsReq;
|
||||||
import emu.lunarcore.proto.PVEBattleResultScRspOuterClass.PVEBattleResultScRsp;
|
import emu.lunarcore.proto.PVEBattleResultScRspOuterClass.PVEBattleResultScRsp;
|
||||||
@@ -8,13 +10,30 @@ import emu.lunarcore.server.packet.CmdId;
|
|||||||
|
|
||||||
public class PacketPVEBattleResultScRsp extends BasePacket {
|
public class PacketPVEBattleResultScRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketPVEBattleResultScRsp(PVEBattleResultCsReq req) {
|
public PacketPVEBattleResultScRsp() {
|
||||||
super(CmdId.PVEBattleResultScRsp);
|
super(CmdId.PVEBattleResultScRsp);
|
||||||
|
|
||||||
|
var data = PVEBattleResultScRsp.newInstance()
|
||||||
|
.setRetcode(1);
|
||||||
|
|
||||||
|
this.setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketPVEBattleResultScRsp(PVEBattleResultCsReq req, Battle battle) {
|
||||||
|
super(CmdId.PVEBattleResultScRsp);
|
||||||
|
|
||||||
|
// Item drop list data
|
||||||
|
ItemList dropData = ItemList.newInstance();
|
||||||
|
|
||||||
|
for (GameItem drop : battle.getDrops()) {
|
||||||
|
dropData.addItemList(drop.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Battle result
|
||||||
var data = PVEBattleResultScRsp.newInstance()
|
var data = PVEBattleResultScRsp.newInstance()
|
||||||
.setUnk1(ItemList.newInstance())
|
.setUnk1(ItemList.newInstance())
|
||||||
.setUnk2(ItemList.newInstance())
|
|
||||||
.setUnk3(ItemList.newInstance())
|
.setUnk3(ItemList.newInstance())
|
||||||
|
.setDropData(dropData)
|
||||||
.setResVersion(Integer.toString(req.getClientResVersion()))
|
.setResVersion(Integer.toString(req.getClientResVersion()))
|
||||||
.setBinVersion("")
|
.setBinVersion("")
|
||||||
.setBattleId(req.getBattleId())
|
.setBattleId(req.getBattleId())
|
||||||
|
|||||||
Reference in New Issue
Block a user