mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-13 00:47:50 +00:00
Keep ability cooldowns across logout
Dimension change and teleport were already fixed, but disconnect still cleared cooldowns and login cleared them again, and they were never written to NBT - so relogging reset every cooldown. They are absolute world-time deadlines, so they now persist and are restored on load.
This commit is contained in:
1 parent
aaf6734bd9
commit
3565c66cf8
1 file changed
+39
-5
@@ -832,9 +832,8 @@ public class PlayerAbilityData extends AbstractDataAbilities implements IPlayerA
|
||||
currentTarget = null;
|
||||
lastAbilityActivationTime = -1;
|
||||
|
||||
// Clear cooldowns (fresh start after relog)
|
||||
cooldownEndTime = 0;
|
||||
resetAllPerAbilityCooldowns();
|
||||
// Cooldowns are absolute world-time deadlines and are restored from NBT, so relogging
|
||||
// must not clear them or it becomes a way to bypass them.
|
||||
interruptCooldownRolled = false;
|
||||
|
||||
// Reset sync tracking so next sync sends fresh state
|
||||
@@ -852,9 +851,10 @@ public class PlayerAbilityData extends AbstractDataAbilities implements IPlayerA
|
||||
if (currentAbility != null && currentAbility.isExecuting()) {
|
||||
interruptCurrentAbility(null, 0);
|
||||
}
|
||||
// Clear any remaining transient state (cooldowns, chains, locks)
|
||||
// Clear any remaining transient state (chains, locks)
|
||||
// Don't clear toggles — they were already saved to NBT by this point
|
||||
onEntityReconstructed(true, false);
|
||||
// Don't clear cooldowns — they persist across sessions
|
||||
onEntityReconstructed(false, false);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
@@ -1048,6 +1048,22 @@ public class PlayerAbilityData extends AbstractDataAbilities implements IPlayerA
|
||||
toggleList.appendTag(toggleNbt);
|
||||
}
|
||||
compound.setTag("ActiveToggles", toggleList);
|
||||
|
||||
// Cooldowns are absolute world-time deadlines, so they stay meaningful across sessions
|
||||
NBTTagCompound cooldowns = new NBTTagCompound();
|
||||
cooldowns.setLong("GlobalEnd", cooldownEndTime);
|
||||
cooldowns.setInteger("GlobalDuration", globalCooldownDuration);
|
||||
NBTTagList perAbilityList = new NBTTagList();
|
||||
for (Map.Entry<String, Long> entry : perAbilityCooldownEndTimes.entrySet()) {
|
||||
NBTTagCompound cooldownNbt = new NBTTagCompound();
|
||||
cooldownNbt.setString("Key", entry.getKey());
|
||||
cooldownNbt.setLong("End", entry.getValue());
|
||||
Integer duration = perAbilityCooldownDurations.get(entry.getKey());
|
||||
cooldownNbt.setInteger("Duration", duration == null ? 0 : duration);
|
||||
perAbilityList.appendTag(cooldownNbt);
|
||||
}
|
||||
cooldowns.setTag("PerAbility", perAbilityList);
|
||||
compound.setTag("AbilityCooldowns", cooldowns);
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
@@ -1082,6 +1098,24 @@ public class PlayerAbilityData extends AbstractDataAbilities implements IPlayerA
|
||||
setToggleEntryDirect(key, state);
|
||||
}
|
||||
}
|
||||
|
||||
if (compound.hasKey("AbilityCooldowns")) {
|
||||
cooldownEndTime = 0;
|
||||
globalCooldownDuration = 0;
|
||||
resetAllPerAbilityCooldowns();
|
||||
|
||||
NBTTagCompound cooldowns = compound.getCompoundTag("AbilityCooldowns");
|
||||
cooldownEndTime = cooldowns.getLong("GlobalEnd");
|
||||
globalCooldownDuration = cooldowns.getInteger("GlobalDuration");
|
||||
NBTTagList perAbilityList = cooldowns.getTagList("PerAbility", 10); // 10 = TAG_COMPOUND
|
||||
for (int i = 0; i < perAbilityList.tagCount(); i++) {
|
||||
NBTTagCompound entry = perAbilityList.getCompoundTagAt(i);
|
||||
String key = entry.getString("Key");
|
||||
if (key == null || key.isEmpty()) continue;
|
||||
perAbilityCooldownEndTimes.put(key, entry.getLong("End"));
|
||||
perAbilityCooldownDurations.put(key, entry.getInteger("Duration"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user