mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-16 23:34:50 +01:00
Implement drops from cocoons/world bosses
This commit is contained in:
@@ -20,6 +20,7 @@ public class GameConstants {
|
|||||||
public static final int MAX_AVATARS_IN_TEAM = 4;
|
public static final int MAX_AVATARS_IN_TEAM = 4;
|
||||||
public static final int DEFAULT_TEAMS = 6;
|
public static final int DEFAULT_TEAMS = 6;
|
||||||
public static final int MAX_MP = 5; // Client doesnt like more than 5
|
public static final int MAX_MP = 5; // Client doesnt like more than 5
|
||||||
|
public static final int FARM_ELEMENT_STAMINA_COST = 30;
|
||||||
|
|
||||||
// Chat/Social
|
// Chat/Social
|
||||||
public static final int MAX_FRIENDSHIPS = 100;
|
public static final int MAX_FRIENDSHIPS = 100;
|
||||||
|
|||||||
@@ -61,6 +61,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<MappingInfoExcel> mappingInfoExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static Int2ObjectMap<MonsterDropExcel> monsterDropExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<MonsterDropExcel> monsterDropExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
private static Int2ObjectMap<PlayerLevelExcel> playerLevelExcelMap = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<PlayerLevelExcel> playerLevelExcelMap = new Int2ObjectOpenHashMap<>();
|
||||||
@@ -219,6 +220,10 @@ public class GameData {
|
|||||||
return cocoonExcelMap.get((cocoonId << 8) + worldLevel);
|
return cocoonExcelMap.get((cocoonId << 8) + worldLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MappingInfoExcel getMappingInfoExcel(int mappingInfoId, int worldLevel) {
|
||||||
|
return mappingInfoExcelMap.get((mappingInfoId << 8) + worldLevel);
|
||||||
|
}
|
||||||
|
|
||||||
public static MonsterDropExcel getMonsterDropExcel(int monsterNpcId, int worldLevel) {
|
public static MonsterDropExcel getMonsterDropExcel(int monsterNpcId, int worldLevel) {
|
||||||
return monsterDropExcelMap.get((monsterNpcId << 4) + worldLevel);
|
return monsterDropExcelMap.get((monsterNpcId << 4) + worldLevel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import lombok.Getter;
|
|||||||
@ResourceType(name = {"CocoonConfig.json"})
|
@ResourceType(name = {"CocoonConfig.json"})
|
||||||
public class CocoonExcel extends GameResource {
|
public class CocoonExcel extends GameResource {
|
||||||
private int ID;
|
private int ID;
|
||||||
|
private int MappingInfoID;
|
||||||
private int WorldLevel;
|
private int WorldLevel;
|
||||||
private int PropID;
|
private int PropID;
|
||||||
private int StaminaCost;
|
private int StaminaCost;
|
||||||
|
|||||||
166
src/main/java/emu/lunarcore/data/excel/MappingInfoExcel.java
Normal file
166
src/main/java/emu/lunarcore/data/excel/MappingInfoExcel.java
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
package emu.lunarcore.data.excel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.lunarcore.GameConstants;
|
||||||
|
import emu.lunarcore.data.GameData;
|
||||||
|
import emu.lunarcore.data.GameResource;
|
||||||
|
import emu.lunarcore.data.ResourceType;
|
||||||
|
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||||
|
import emu.lunarcore.data.common.ItemParam;
|
||||||
|
import emu.lunarcore.game.drops.DropParam;
|
||||||
|
import emu.lunarcore.game.enums.ItemMainType;
|
||||||
|
import emu.lunarcore.game.enums.ItemRarity;
|
||||||
|
import emu.lunarcore.game.enums.ItemSubType;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = {"MappingInfo.json"}, loadPriority = LoadPriority.LOW)
|
||||||
|
public class MappingInfoExcel extends GameResource {
|
||||||
|
private int ID;
|
||||||
|
private int WorldLevel;
|
||||||
|
private String FarmType; // is enum
|
||||||
|
private List<ItemParam> DisplayItemList;
|
||||||
|
|
||||||
|
private transient List<DropParam> dropList;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return (ID << 8) + WorldLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
// Temp way to pre-calculate drop list
|
||||||
|
this.dropList = new ArrayList<>(this.getDisplayItemList().size());
|
||||||
|
|
||||||
|
var equipmentDrops = new IntArrayList();
|
||||||
|
var relicDrops = new Int2ObjectOpenHashMap<IntList>();
|
||||||
|
|
||||||
|
for (var itemParam : this.getDisplayItemList()) {
|
||||||
|
// Add item param if the amount is already set in the excel
|
||||||
|
if (itemParam.getCount() > 0) {
|
||||||
|
dropList.add(new DropParam(itemParam.getId(), itemParam.getCount()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplier. TODO drop rate is not correct
|
||||||
|
int multiplier = 1;
|
||||||
|
if (FarmType == null) {
|
||||||
|
// Skip
|
||||||
|
} else if (FarmType.equals("RELIC")) {
|
||||||
|
multiplier = 4;
|
||||||
|
} else if (FarmType.equals("COCOON2")) {
|
||||||
|
multiplier = 3;
|
||||||
|
} else if (FarmType.equals("ELEMENT")) {
|
||||||
|
multiplier = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Random credits
|
||||||
|
if (itemParam.getId() == GameConstants.MATERIAL_COIN_ID) {
|
||||||
|
// TODO drop rate is not correct
|
||||||
|
DropParam drop = new DropParam(itemParam.getId(), 0);
|
||||||
|
drop.setMinCount((50 + (this.getWorldLevel() * 10)) * multiplier);
|
||||||
|
drop.setMaxCount((100 + (this.getWorldLevel() * 10)) * multiplier);
|
||||||
|
dropList.add(drop);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get item excel
|
||||||
|
ItemExcel itemExcel = GameData.getItemExcelMap().get(itemParam.getId());
|
||||||
|
if (itemExcel == null) continue;
|
||||||
|
|
||||||
|
// Hacky way of calculating drops
|
||||||
|
if (itemExcel.getItemSubType() == ItemSubType.RelicSetShowOnly) {
|
||||||
|
// Get relic base id from relic display id
|
||||||
|
int baseRelicId = (itemParam.getId() / 10) % 1000;
|
||||||
|
int baseRarity = itemParam.getId() % 10;
|
||||||
|
|
||||||
|
// Add relics from the set
|
||||||
|
int relicStart = 20001 + (baseRarity * 10000) + (baseRelicId * 10);
|
||||||
|
int relicEnd = relicStart + 3;
|
||||||
|
for (;relicStart < relicEnd; relicStart++) {
|
||||||
|
ItemExcel relicExcel = GameData.getItemExcelMap().get(relicStart);
|
||||||
|
if (relicExcel == null) break;
|
||||||
|
|
||||||
|
relicDrops
|
||||||
|
.computeIfAbsent(baseRarity, r -> new IntArrayList())
|
||||||
|
.add(relicStart);
|
||||||
|
}
|
||||||
|
} else if (itemExcel.getItemMainType() == ItemMainType.Material) {
|
||||||
|
// Calculate amount to drop by purpose level
|
||||||
|
DropParam drop = switch (itemExcel.getPurposeType()) {
|
||||||
|
// Avatar exp. TODO drop rate is not correct
|
||||||
|
case 1 -> new DropParam(itemParam.getId(), 1);
|
||||||
|
// Boss materials
|
||||||
|
case 2 -> new DropParam(itemParam.getId(), this.getWorldLevel());
|
||||||
|
// Trace materials. TODO drop rate is not correct
|
||||||
|
case 3 -> {
|
||||||
|
var dropInfo = new DropParam(itemParam.getId(), 1);
|
||||||
|
|
||||||
|
if (itemExcel.getRarity() == ItemRarity.VeryRare) {
|
||||||
|
dropInfo.setChance((this.getWorldLevel() - 3) * 75);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield dropInfo;
|
||||||
|
}
|
||||||
|
// Boss Trace materials. TODO drop rate is not correct
|
||||||
|
case 4 -> new DropParam(itemParam.getId(), (this.getWorldLevel() * 0.5) + 0.5);
|
||||||
|
// Lightcone exp. TODO drop rate is not correct
|
||||||
|
case 5 -> new DropParam(itemParam.getId(), 1);
|
||||||
|
// Lucent afterglow
|
||||||
|
case 11 -> new DropParam(itemParam.getId(), 4 + this.getWorldLevel());
|
||||||
|
// Unknown
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (drop != null) {
|
||||||
|
dropList.add(drop);
|
||||||
|
}
|
||||||
|
} else if (itemExcel.getItemMainType() == ItemMainType.Equipment) {
|
||||||
|
// Lightcones
|
||||||
|
equipmentDrops.add(itemParam.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add equipment drops
|
||||||
|
if (equipmentDrops.size() > 0) {
|
||||||
|
DropParam drop = new DropParam();
|
||||||
|
drop.getItems().addAll(equipmentDrops);
|
||||||
|
drop.setCount(1);
|
||||||
|
drop.setChance((this.getWorldLevel() * 10) + 40);
|
||||||
|
dropList.add(drop);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add relic drops
|
||||||
|
if (relicDrops.size() > 0) {
|
||||||
|
for (var entry : relicDrops.int2ObjectEntrySet()) {
|
||||||
|
// Add items to drop param
|
||||||
|
DropParam drop = new DropParam();
|
||||||
|
drop.getItems().addAll(entry.getValue());
|
||||||
|
|
||||||
|
// Set count by rarity
|
||||||
|
double amount = switch (entry.getIntKey()) {
|
||||||
|
case 4:
|
||||||
|
yield (this.getWorldLevel() * 0.5) - 0.5;
|
||||||
|
case 3:
|
||||||
|
yield (this.getWorldLevel() * 0.5) + (this.getWorldLevel() == 2 ? 1.0 : 0);
|
||||||
|
case 2:
|
||||||
|
yield (6 - this.getWorldLevel()) + 0.5 - (this.getWorldLevel() == 1 ? 3.75 : 0);
|
||||||
|
default:
|
||||||
|
yield this.getWorldLevel() == 1 ? 6 : 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set amount
|
||||||
|
if (amount > 0) {
|
||||||
|
drop.setCount(amount);
|
||||||
|
dropList.add(drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,11 @@ public class Battle {
|
|||||||
@Setter private int levelOverride;
|
@Setter private int levelOverride;
|
||||||
@Setter private int roundsLimit;
|
@Setter private int roundsLimit;
|
||||||
|
|
||||||
|
// Used for calculating cocoon/farm element drops
|
||||||
|
@Setter private int mappingInfoId;
|
||||||
|
@Setter private int worldLevel;
|
||||||
|
@Setter private int cocoonWave;
|
||||||
|
|
||||||
private Battle(Player player, PlayerLineup lineup) {
|
private Battle(Player player, PlayerLineup lineup) {
|
||||||
this.id = player.getNextBattleId();
|
this.id = player.getNextBattleId();
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
|||||||
@@ -119,8 +119,16 @@ public class BattleService extends BaseGameService {
|
|||||||
|
|
||||||
// Add npc monsters
|
// Add npc monsters
|
||||||
for (var monster : monsters) {
|
for (var monster : monsters) {
|
||||||
|
// Add npc monster
|
||||||
battle.getNpcMonsters().add(monster);
|
battle.getNpcMonsters().add(monster);
|
||||||
|
|
||||||
|
// Check farm element
|
||||||
|
if (monster.getFarmElementId() != 0) {
|
||||||
|
battle.setMappingInfoId(monster.getFarmElementId());
|
||||||
|
battle.setWorldLevel(monster.getWorldLevel());
|
||||||
|
battle.setStaminaCost(GameConstants.FARM_ELEMENT_STAMINA_COST);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle monster buffs
|
// Handle monster buffs
|
||||||
// TODO handle multiple waves properly
|
// TODO handle multiple waves properly
|
||||||
monster.applyBuffs(battle);
|
monster.applyBuffs(battle);
|
||||||
@@ -213,6 +221,9 @@ public class BattleService extends BaseGameService {
|
|||||||
|
|
||||||
// Build battle from cocoon data
|
// Build battle from cocoon data
|
||||||
Battle battle = new Battle(player, player.getLineupManager().getCurrentLineup(), stages);
|
Battle battle = new Battle(player, player.getLineupManager().getCurrentLineup(), stages);
|
||||||
|
battle.setMappingInfoId(cocoonExcel.getMappingInfoID());
|
||||||
|
battle.setCocoonWave(wave);
|
||||||
|
battle.setWorldLevel(worldLevel);
|
||||||
battle.setStaminaCost(cost);
|
battle.setStaminaCost(cost);
|
||||||
|
|
||||||
player.setBattle(battle);
|
player.setBattle(battle);
|
||||||
@@ -338,8 +349,18 @@ public class BattleService extends BaseGameService {
|
|||||||
|
|
||||||
// Create new battle for player
|
// Create new battle for player
|
||||||
Battle battle = new Battle(player, player.getCurrentLineup(), stage);
|
Battle battle = new Battle(player, player.getCurrentLineup(), stage);
|
||||||
|
battle.setStaminaCost(GameConstants.FARM_ELEMENT_STAMINA_COST);
|
||||||
player.setBattle(battle);
|
player.setBattle(battle);
|
||||||
|
|
||||||
|
// Get mapping info id
|
||||||
|
int mappingInfoId = ((stageId / 10) % 100) + 1100;
|
||||||
|
int mappingInfoLevel = stageId % 10;
|
||||||
|
var mappingInfoExcel = GameData.getMappingInfoExcel(mappingInfoId, mappingInfoLevel);
|
||||||
|
if (mappingInfoExcel != null && mappingInfoExcel.getFarmType() != null && mappingInfoExcel.getFarmType().equals("ELEMENT")) {
|
||||||
|
battle.setMappingInfoId(mappingInfoId);
|
||||||
|
battle.setWorldLevel(mappingInfoLevel);
|
||||||
|
}
|
||||||
|
|
||||||
// Send packet
|
// Send packet
|
||||||
player.sendPacket(new PacketReEnterLastElementStageScRsp(battle));
|
player.sendPacket(new PacketReEnterLastElementStageScRsp(battle));
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/main/java/emu/lunarcore/game/drops/DropMap.java
Normal file
11
src/main/java/emu/lunarcore/game/drops/DropMap.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package emu.lunarcore.game.drops;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
|
|
||||||
|
public class DropMap extends Int2IntOpenHashMap {
|
||||||
|
private static final long serialVersionUID = -4186524272780523459L;
|
||||||
|
|
||||||
|
public FastEntrySet entries() {
|
||||||
|
return this.int2IntEntrySet();
|
||||||
|
}
|
||||||
|
}
|
||||||
99
src/main/java/emu/lunarcore/game/drops/DropParam.java
Normal file
99
src/main/java/emu/lunarcore/game/drops/DropParam.java
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
package emu.lunarcore.game.drops;
|
||||||
|
|
||||||
|
import emu.lunarcore.data.GameData;
|
||||||
|
import emu.lunarcore.data.excel.ItemExcel;
|
||||||
|
import emu.lunarcore.util.Utils;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class DropParam {
|
||||||
|
@Setter(AccessLevel.NONE)
|
||||||
|
private IntList items;
|
||||||
|
|
||||||
|
private int minCount;
|
||||||
|
private int maxCount;
|
||||||
|
private int chance;
|
||||||
|
|
||||||
|
public DropParam() {
|
||||||
|
this.items = new IntArrayList();
|
||||||
|
this.chance = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DropParam(int itemId, int count) {
|
||||||
|
this();
|
||||||
|
this.getItems().add(itemId);
|
||||||
|
this.setCount(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DropParam(int itemId, double count) {
|
||||||
|
this();
|
||||||
|
this.getItems().add(itemId);
|
||||||
|
this.setCount(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(int count) {
|
||||||
|
this.minCount = count;
|
||||||
|
this.maxCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(double count) {
|
||||||
|
if (count % 1 == 0) {
|
||||||
|
this.setCount((int) count);
|
||||||
|
} else {
|
||||||
|
this.setMaxCount((int) Math.ceil(count));
|
||||||
|
this.setMinCount((int) Math.floor(count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int generateItemId() {
|
||||||
|
if (this.items == null || this.items.size() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.items.size() == 1) {
|
||||||
|
return this.items.getInt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils.randomElement(this.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int generateCount() {
|
||||||
|
if (this.maxCount > this.minCount) {
|
||||||
|
return Utils.randomRange(this.minCount, this.maxCount);
|
||||||
|
}
|
||||||
|
return this.maxCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void roll(DropMap drops) {
|
||||||
|
// Check drop chance
|
||||||
|
if (this.chance < 1000) {
|
||||||
|
int random = Utils.randomRange(0, 999);
|
||||||
|
if (random > this.chance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get count
|
||||||
|
int count = generateCount();
|
||||||
|
|
||||||
|
// Generate item(s)
|
||||||
|
while (count > 0) {
|
||||||
|
int itemId = generateItemId();
|
||||||
|
|
||||||
|
ItemExcel excel = GameData.getItemExcelMap().get(itemId);
|
||||||
|
if (excel == null) break;
|
||||||
|
|
||||||
|
if (excel.isEquippable()) {
|
||||||
|
drops.addTo(itemId, 1);
|
||||||
|
count--;
|
||||||
|
} else {
|
||||||
|
drops.addTo(itemId, count);
|
||||||
|
count -= count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,13 +6,13 @@ import java.util.List;
|
|||||||
import emu.lunarcore.GameConstants;
|
import emu.lunarcore.GameConstants;
|
||||||
import emu.lunarcore.data.GameData;
|
import emu.lunarcore.data.GameData;
|
||||||
import emu.lunarcore.data.common.ItemParam;
|
import emu.lunarcore.data.common.ItemParam;
|
||||||
|
import emu.lunarcore.data.excel.ItemExcel;
|
||||||
import emu.lunarcore.game.battle.Battle;
|
import emu.lunarcore.game.battle.Battle;
|
||||||
import emu.lunarcore.game.inventory.GameItem;
|
import emu.lunarcore.game.inventory.GameItem;
|
||||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
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.util.Utils;
|
import emu.lunarcore.util.Utils;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
|
||||||
|
|
||||||
public class DropService extends BaseGameService {
|
public class DropService extends BaseGameService {
|
||||||
|
|
||||||
@@ -20,15 +20,12 @@ public class DropService extends BaseGameService {
|
|||||||
super(server);
|
super(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO this isnt the right way drops are calculated on the official server... but its good enough for now
|
||||||
public void calculateDrops(Battle battle) {
|
public void calculateDrops(Battle battle) {
|
||||||
// TODO this isnt the right way drops are calculated on the official server... but its good enough for now
|
// Setup drop map
|
||||||
if (battle.getNpcMonsters().size() == 0) {
|
var dropMap = new DropMap();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var dropMap = new Int2IntOpenHashMap();
|
// Calculate drops from monsters
|
||||||
|
|
||||||
// Get drops from monsters
|
|
||||||
for (EntityMonster monster : battle.getNpcMonsters()) {
|
for (EntityMonster monster : battle.getNpcMonsters()) {
|
||||||
var dropExcel = GameData.getMonsterDropExcel(monster.getExcel().getId(), monster.getWorldLevel());
|
var dropExcel = GameData.getMonsterDropExcel(monster.getExcel().getId(), monster.getWorldLevel());
|
||||||
if (dropExcel == null || dropExcel.getDisplayItemList() == null) {
|
if (dropExcel == null || dropExcel.getDisplayItemList() == null) {
|
||||||
@@ -43,22 +40,50 @@ public class DropService extends BaseGameService {
|
|||||||
count = dropExcel.getAvatarExpReward();
|
count = dropExcel.getAvatarExpReward();
|
||||||
}
|
}
|
||||||
|
|
||||||
dropMap.put(id, count + dropMap.get(id));
|
dropMap.addTo(id, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var entry : dropMap.int2IntEntrySet()) {
|
// Mapping info
|
||||||
|
if (battle.getMappingInfoId() > 0) {
|
||||||
|
var mapInfoExcel = GameData.getMappingInfoExcel(battle.getMappingInfoId(), battle.getWorldLevel());
|
||||||
|
if (mapInfoExcel != null) {
|
||||||
|
int rolls = Math.max(battle.getCocoonWave(), 1);
|
||||||
|
for (var dropParam : mapInfoExcel.getDropList()) {
|
||||||
|
for (int i = 0; i < rolls; i++) {
|
||||||
|
dropParam.roll(dropMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (dropMap.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create drops
|
||||||
|
for (var entry : dropMap.entries()) {
|
||||||
if (entry.getIntValue() <= 0) {
|
if (entry.getIntValue() <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create item and add it to player
|
// Create item and add it to player
|
||||||
GameItem item = new GameItem(entry.getIntKey(), entry.getIntValue());
|
ItemExcel excel = GameData.getItemExcelMap().get(entry.getIntKey());
|
||||||
|
if (excel == null) continue;
|
||||||
if (battle.getPlayer().getInventory().addItem(item)) {
|
|
||||||
battle.getDrops().add(item);
|
// Add item
|
||||||
|
if (excel.isEquippable()) {
|
||||||
|
for (int i = 0; i < entry.getIntValue(); i++) {
|
||||||
|
battle.getDrops().add(new GameItem(excel, 1));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
battle.getDrops().add(new GameItem(excel, entry.getIntValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to inventory
|
||||||
|
battle.getPlayer().getInventory().addItems(battle.getDrops());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO filler
|
// TODO filler
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import java.util.Base64;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
|
private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
|
||||||
|
|
||||||
@@ -175,6 +177,10 @@ public class Utils {
|
|||||||
public static <T> T randomElement(List<T> list) {
|
public static <T> T randomElement(List<T> list) {
|
||||||
return list.get(ThreadLocalRandom.current().nextInt(0, list.size()));
|
return list.get(ThreadLocalRandom.current().nextInt(0, list.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int randomElement(IntList list) {
|
||||||
|
return list.getInt(ThreadLocalRandom.current().nextInt(0, list.size()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if an integer array contains a value
|
* Checks if an integer array contains a value
|
||||||
|
|||||||
Reference in New Issue
Block a user