mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-23 10:44:36 +01:00
Fix debuffs from summoned skills not expiring
This commit is contained in:
@@ -59,6 +59,7 @@ import emu.lunarcore.proto.SimpleAvatarInfoOuterClass.SimpleAvatarInfo;
|
||||
import emu.lunarcore.proto.SimpleInfoOuterClass.SimpleInfo;
|
||||
import emu.lunarcore.server.game.GameServer;
|
||||
import emu.lunarcore.server.game.GameSession;
|
||||
import emu.lunarcore.server.game.Tickable;
|
||||
import emu.lunarcore.server.packet.BasePacket;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
import emu.lunarcore.server.packet.send.*;
|
||||
@@ -73,7 +74,7 @@ import lombok.Setter;
|
||||
|
||||
@Entity(value = "players", useDiscriminator = false)
|
||||
@Getter
|
||||
public class Player {
|
||||
public class Player implements Tickable {
|
||||
@Id private int uid;
|
||||
@Indexed private String accountUid;
|
||||
private String name;
|
||||
@@ -519,27 +520,26 @@ public class Player {
|
||||
return amount;
|
||||
}
|
||||
|
||||
private void updateStamina() {
|
||||
// Get current timestamp
|
||||
long time = System.currentTimeMillis();
|
||||
private void updateStamina(long timestamp) {
|
||||
// Setup on change flag
|
||||
boolean hasChanged = false;
|
||||
|
||||
// Check if we can add stamina
|
||||
while (time >= this.nextStaminaRecover) {
|
||||
while (timestamp >= this.nextStaminaRecover) {
|
||||
// Add stamina
|
||||
if (this.stamina < GameConstants.MAX_STAMINA) {
|
||||
this.stamina += 1;
|
||||
hasChanged = true;
|
||||
} else if (this.stamina < GameConstants.MAX_STAMINA_RESERVE) {
|
||||
double rate = LunarCore.getConfig().getServerOptions().getStaminaReserveRecoveryRate();
|
||||
double amount = (time - this.nextStaminaRecover) / (rate * 1000D);
|
||||
double amount = (timestamp - this.nextStaminaRecover) / (rate * 1000D);
|
||||
this.staminaReserve = Math.min(this.staminaReserve + amount, GameConstants.MAX_STAMINA_RESERVE);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
// Calculate next stamina recover time
|
||||
if (this.stamina >= GameConstants.MAX_STAMINA) {
|
||||
this.nextStaminaRecover = time;
|
||||
this.nextStaminaRecover = timestamp;
|
||||
}
|
||||
|
||||
this.nextStaminaRecover += LunarCore.getConfig().getServerOptions().getStaminaRecoveryRate() * 1000;
|
||||
@@ -722,12 +722,12 @@ public class Player {
|
||||
}
|
||||
}
|
||||
|
||||
public void onTick() {
|
||||
public void onTick(long timestamp, long delta) {
|
||||
// Update stamina
|
||||
this.updateStamina();
|
||||
this.updateStamina(timestamp);
|
||||
// Scene update
|
||||
if (this.getScene() != null) {
|
||||
this.getScene().onTick();
|
||||
this.getScene().onTick(timestamp, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,7 +746,7 @@ public class Player {
|
||||
this.getRogueManager().loadFromDatabase();
|
||||
|
||||
// Update stamina
|
||||
this.updateStamina();
|
||||
this.updateStamina(System.currentTimeMillis());
|
||||
|
||||
// Check instances
|
||||
if (this.getChallengeInstance() != null && !this.getChallengeInstance().validate(this)) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
import emu.lunarcore.proto.SceneEntityGroupInfoOuterClass.SceneEntityGroupInfo;
|
||||
import emu.lunarcore.proto.SceneGroupStateOuterClass.SceneGroupState;
|
||||
import emu.lunarcore.proto.SceneInfoOuterClass.SceneInfo;
|
||||
import emu.lunarcore.server.game.Tickable;
|
||||
import emu.lunarcore.server.packet.send.PacketActivateFarmElementScRsp;
|
||||
import emu.lunarcore.server.packet.send.PacketRefreshTriggerByClientScNotify;
|
||||
import emu.lunarcore.server.packet.send.PacketSceneGroupRefreshScNotify;
|
||||
@@ -29,7 +30,7 @@ import lombok.Getter;
|
||||
import us.hebi.quickbuf.RepeatedInt;
|
||||
|
||||
@Getter
|
||||
public class Scene {
|
||||
public class Scene implements Tickable {
|
||||
private final Player player;
|
||||
private final MazePlaneExcel excel;
|
||||
private final FloorInfo floorInfo;
|
||||
@@ -352,13 +353,20 @@ public class Scene {
|
||||
|
||||
// Player events
|
||||
|
||||
public void onTick() {
|
||||
@Override
|
||||
public synchronized void onTick(long timestamp, long delta) {
|
||||
// Remove summoned unit if it expired
|
||||
if (this.getPlayerSummon() != null) {
|
||||
if (this.getPlayerSummon().isExpired()) {
|
||||
this.removeSummonUnit();
|
||||
}
|
||||
}
|
||||
// Tick entities
|
||||
for (GameEntity entity : this.getEntities().values()) {
|
||||
if (entity instanceof Tickable tickableEntity) {
|
||||
tickableEntity.onTick(timestamp, delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBattleStart(Battle battle) {
|
||||
|
||||
@@ -21,6 +21,10 @@ public class SceneBuff {
|
||||
this.expiry = this.createTime + duration;
|
||||
}
|
||||
|
||||
public boolean isExpired(long timestamp) {
|
||||
return timestamp > this.expiry;
|
||||
}
|
||||
|
||||
// Serialization
|
||||
|
||||
public BuffInfo toProto() {
|
||||
|
||||
@@ -10,6 +10,8 @@ import emu.lunarcore.game.scene.triggers.PropTriggerType;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||
import emu.lunarcore.proto.SceneNpcMonsterInfoOuterClass.SceneNpcMonsterInfo;
|
||||
import emu.lunarcore.server.game.Tickable;
|
||||
import emu.lunarcore.server.packet.send.PacketSyncEntityBuffChangeListScNotify;
|
||||
import emu.lunarcore.util.Position;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
@@ -17,7 +19,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
public class EntityMonster implements GameEntity {
|
||||
public class EntityMonster implements GameEntity, Tickable {
|
||||
@Setter private NpcMonsterExcel excel;
|
||||
@Setter private int entityId;
|
||||
@Setter private int worldLevel;
|
||||
@@ -56,7 +58,7 @@ public class EntityMonster implements GameEntity {
|
||||
}
|
||||
}
|
||||
|
||||
public SceneBuff addBuff(int caster, int buffId, int duration) {
|
||||
public synchronized SceneBuff addBuff(int caster, int buffId, int duration) {
|
||||
if (this.buffs == null) {
|
||||
this.buffs = new Int2ObjectOpenHashMap<>();
|
||||
}
|
||||
@@ -69,12 +71,12 @@ public class EntityMonster implements GameEntity {
|
||||
return buff;
|
||||
}
|
||||
|
||||
public void applyBuffs(Battle battle) {
|
||||
public synchronized void applyBuffs(Battle battle) {
|
||||
if (this.buffs == null) return;
|
||||
|
||||
for (var entry : this.buffs.int2ObjectEntrySet()) {
|
||||
// Check expiry for buff
|
||||
if (entry.getValue().getExpiry() < battle.getTimestamp()) {
|
||||
if (entry.getValue().isExpired(battle.getTimestamp())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -99,6 +101,26 @@ public class EntityMonster implements GameEntity {
|
||||
// Try to fire any triggers
|
||||
getScene().invokePropTrigger(PropTriggerType.MONSTER_DIE, this.getGroupId(), this.getInstId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onTick(long timestamp, long delta) {
|
||||
// Check if we need to remove any buffs
|
||||
if (this.buffs != null && this.buffs.size() > 0) {
|
||||
var it = this.buffs.values().iterator();
|
||||
|
||||
while (it.hasNext()) {
|
||||
var buff = it.next();
|
||||
|
||||
if (buff.isExpired(timestamp)) {
|
||||
// Safely remove from iterator
|
||||
it.remove();
|
||||
|
||||
// Send packet to notify the client that we are removing the buff
|
||||
getScene().getPlayer().sendPacket(new PacketSyncEntityBuffChangeListScNotify(this.getEntityId(), buff.getBuffId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SceneEntityInfo toSceneEntityProto() {
|
||||
|
||||
@@ -27,6 +27,7 @@ public class GameServer extends KcpServer {
|
||||
|
||||
private final Int2ObjectMap<Player> players;
|
||||
private final Timer gameLoopTimer;
|
||||
private long lastTickTime;
|
||||
|
||||
// Managers
|
||||
@Getter private final GameServerPacketHandler packetHandler;
|
||||
@@ -56,6 +57,7 @@ public class GameServer extends KcpServer {
|
||||
this.shopService = new ShopService(this);
|
||||
|
||||
// Game loop
|
||||
this.lastTickTime = System.currentTimeMillis();
|
||||
this.gameLoopTimer = new Timer();
|
||||
this.gameLoopTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
@@ -173,10 +175,14 @@ public class GameServer extends KcpServer {
|
||||
}
|
||||
|
||||
private void onTick() {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
long delta = timestamp - lastTickTime;
|
||||
this.lastTickTime = timestamp;
|
||||
|
||||
synchronized (this.players) {
|
||||
for (Player player : this.players.values()) {
|
||||
try {
|
||||
player.onTick();
|
||||
player.onTick(timestamp, delta);
|
||||
} catch (Exception e) {
|
||||
LunarCore.getLogger().error("[UID: " + player.getUid() + "] Player tick error: ", e);
|
||||
}
|
||||
|
||||
7
src/main/java/emu/lunarcore/server/game/Tickable.java
Normal file
7
src/main/java/emu/lunarcore/server/game/Tickable.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package emu.lunarcore.server.game;
|
||||
|
||||
public interface Tickable {
|
||||
|
||||
public void onTick(long timestamp, long delta);
|
||||
|
||||
}
|
||||
@@ -12,7 +12,20 @@ public class PacketSyncEntityBuffChangeListScNotify extends BasePacket {
|
||||
super(CmdId.SyncEntityBuffChangeListScNotify);
|
||||
|
||||
var buffChange = EntityBuffChangeInfo.newInstance().setEntityId(entityId)
|
||||
.setBuffChangeInfo(buff.toProto())
|
||||
.setAddBuffInfo(buff.toProto())
|
||||
.setEntityId(entityId);
|
||||
|
||||
var data = SyncEntityBuffChangeListScNotify.newInstance()
|
||||
.addEntityBuffInfoList(buffChange);
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
|
||||
public PacketSyncEntityBuffChangeListScNotify(int entityId, int removeBuffId) {
|
||||
super(CmdId.SyncEntityBuffChangeListScNotify);
|
||||
|
||||
var buffChange = EntityBuffChangeInfo.newInstance().setEntityId(entityId)
|
||||
.setRemoveBuffId(removeBuffId)
|
||||
.setEntityId(entityId);
|
||||
|
||||
var data = SyncEntityBuffChangeListScNotify.newInstance()
|
||||
|
||||
Reference in New Issue
Block a user