diff --git a/src/main/java/emu/lunarcore/game/battle/Battle.java b/src/main/java/emu/lunarcore/game/battle/Battle.java index f13d2a6..e324f22 100644 --- a/src/main/java/emu/lunarcore/game/battle/Battle.java +++ b/src/main/java/emu/lunarcore/game/battle/Battle.java @@ -205,8 +205,8 @@ public class Battle { // Apply food buffs to battle if (player.getFoodBuffs().size() > 0) { - for (int buffId : player.getFoodBuffs().values()) { - this.addBuff(buffId, -1); + for (var buff : player.getFoodBuffs().values()) { + this.addBuff(buff.getBuffId(), -1); } } diff --git a/src/main/java/emu/lunarcore/game/battle/BattleService.java b/src/main/java/emu/lunarcore/game/battle/BattleService.java index ec338a7..8390a78 100644 --- a/src/main/java/emu/lunarcore/game/battle/BattleService.java +++ b/src/main/java/emu/lunarcore/game/battle/BattleService.java @@ -266,6 +266,9 @@ public class BattleService extends BaseGameService { // Sync with player player.sendPacket(new PacketSyncLineupNotify(battle.getLineup())); + + // Clear food buffs for player + player.removeFoodBuffs(1); } // Teleport to anchor if player has lost/retreated. On official servers, the player party is teleported to the nearest anchor. @@ -282,11 +285,6 @@ public class BattleService extends BaseGameService { } } - // Clear food buffs for player - if (player.getFoodBuffs().size() > 0) { - player.getFoodBuffs().clear(); - } - // Challenge if (player.getChallengeInstance() != null) { player.getChallengeInstance().onBattleFinish(battle, result, stats); diff --git a/src/main/java/emu/lunarcore/game/inventory/ItemUseHandler.java b/src/main/java/emu/lunarcore/game/inventory/ItemUseHandler.java index 7cc0130..1700be3 100644 --- a/src/main/java/emu/lunarcore/game/inventory/ItemUseHandler.java +++ b/src/main/java/emu/lunarcore/game/inventory/ItemUseHandler.java @@ -75,10 +75,9 @@ public class ItemUseHandler { // Handle any hp/mp/sp changes the food might give handleTeamSpecificFoodBenefit(player, excel, avatarId, count); - // Add food buffs + // Add food buff to player if (excel.getConsumeType() == 1 || excel.getConsumeType() == 2) { - player.getFoodBuffs().put(excel.getConsumeType(), excel.getMazeBuffID()); - player.save(); + player.addFoodBuff(excel.getConsumeType(), excel.getMazeBuffID()); } // TODO send buff refresh packet diff --git a/src/main/java/emu/lunarcore/game/player/Player.java b/src/main/java/emu/lunarcore/game/player/Player.java index 9497773..d2653e4 100644 --- a/src/main/java/emu/lunarcore/game/player/Player.java +++ b/src/main/java/emu/lunarcore/game/player/Player.java @@ -2,6 +2,8 @@ package emu.lunarcore.game.player; import java.nio.charset.StandardCharsets; import java.util.Base64; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import com.mongodb.client.model.Filters; @@ -45,6 +47,7 @@ import emu.lunarcore.game.rogue.RogueInstance; import emu.lunarcore.game.rogue.RogueManager; import emu.lunarcore.game.rogue.RogueTalentData; import emu.lunarcore.game.scene.Scene; +import emu.lunarcore.game.scene.SceneBuff; import emu.lunarcore.game.scene.entity.EntityProp; import emu.lunarcore.game.scene.entity.GameEntity; import emu.lunarcore.game.scene.triggers.PropTriggerType; @@ -65,10 +68,7 @@ import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.send.*; import emu.lunarcore.util.Position; import emu.lunarcore.util.Utils; -import it.unimi.dsi.fastutil.ints.Int2IntMap; -import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.ints.*; import lombok.Getter; import lombok.Setter; @@ -134,7 +134,7 @@ public class Player implements Tickable { private transient boolean loggedIn; private transient boolean inAnchorRange; private transient int nextBattleId; - private transient Int2IntMap foodBuffs; // TODO + private transient Map foodBuffs; @Setter private transient boolean paused; @@ -142,7 +142,7 @@ public class Player implements Tickable { public Player() { this.curBasicType = GameConstants.TRAILBLAZER_AVATAR_ID; this.gender = PlayerGender.GENDER_MAN; - this.foodBuffs = new Int2IntOpenHashMap(); + this.foodBuffs = new HashMap<>(); this.avatars = new AvatarStorage(this); this.inventory = new Inventory(this); @@ -551,6 +551,49 @@ public class Player implements Tickable { } } + public synchronized boolean addFoodBuff(int type, int mazeBuffId) { + // Get maze excel + var excel = GameData.getMazeBuffExcel(mazeBuffId, 1); + if (excel == null) return false; + + // Create new buff + var buff = new SceneBuff(mazeBuffId); + + int avatarEntityId = getCurrentLeaderAvatar().getEntityId(); + var oldBuff = this.getFoodBuffs().put(type, buff); + + // Send packets + if (oldBuff != null) { + this.sendPacket(new PacketSyncEntityBuffChangeListScNotify(avatarEntityId, oldBuff.getBuffId())); + } + + this.sendPacket(new PacketSyncEntityBuffChangeListScNotify(avatarEntityId, buff)); + return true; + } + + public synchronized boolean removeFoodBuffs(int amount) { + // Sanity check + if (getFoodBuffs().size() == 0) return false; + + // Cache current avatar entity id + int avatarEntityId = getCurrentLeaderAvatar().getEntityId(); + + // Remove and send packet for each buff removed + for (var it = getFoodBuffs().entrySet().iterator(); it.hasNext();) { + var entry = it.next(); + var buff = entry.getValue(); + + if (buff.decrementAndGet() <= 0) { + it.remove(); + this.sendPacket(new PacketSyncEntityBuffChangeListScNotify(avatarEntityId, buff.getBuffId())); + } else { + this.sendPacket(new PacketSyncEntityBuffChangeListScNotify(avatarEntityId, buff)); + } + } + + return true; + } + public EntityProp interactWithProp(int propEntityId) { // Sanity if (this.getScene() == null) return null; @@ -747,7 +790,7 @@ public class Player implements Tickable { // Update stamina this.updateStamina(System.currentTimeMillis()); - + // Check instances if (this.getChallengeInstance() != null && !this.getChallengeInstance().validate(this)) { // Delete instance if it failed to validate (example: missing an excel) diff --git a/src/main/java/emu/lunarcore/game/scene/SceneBuff.java b/src/main/java/emu/lunarcore/game/scene/SceneBuff.java index c09100b..6be86c0 100644 --- a/src/main/java/emu/lunarcore/game/scene/SceneBuff.java +++ b/src/main/java/emu/lunarcore/game/scene/SceneBuff.java @@ -8,6 +8,7 @@ public class SceneBuff { private int casterAvatarId; // Owner avatar id private int buffId; private int buffLevel; + private int count; private float duration; private long createTime; private long expiry; @@ -15,6 +16,7 @@ public class SceneBuff { public SceneBuff(int buffId) { this.buffId = buffId; this.buffLevel = 1; + this.count = 1; this.createTime = System.currentTimeMillis(); this.duration = -1; } @@ -32,6 +34,11 @@ public class SceneBuff { this.expiry = this.createTime + (long) duration; } + public int decrementAndGet() { + this.count--; + return this.count; + } + public boolean isExpired(long timestamp) { return timestamp > this.expiry; } @@ -45,7 +52,7 @@ public class SceneBuff { .setBaseAvatarId(this.getCasterAvatarId()) .setAddTimeMs(this.getCreateTime()) .setLifeTime(this.getDuration()) - .setCount(1); + .setCount(this.getCount()); return proto; }