Added ::permadeath [player] admin command to wipe a player's save

Fixed some HCIM death bugs where state was not cleared
This commit is contained in:
Player Name 2024-03-31 14:29:26 +00:00 committed by Ryan
parent 2da47d8353
commit ee9d386bc9
4 changed files with 86 additions and 31 deletions

View file

@ -0,0 +1,47 @@
package core.api.utils.Permadeath
import core.api.*
import core.game.node.entity.player.Player
import core.game.node.entity.player.VarpManager
import core.game.node.entity.player.info.login.PlayerSaver
import core.game.node.entity.player.link.SavedData
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.player.link.quest.QuestRepository
import core.game.node.entity.skill.Skills
import core.game.world.map.Location
fun permadeath(target: Player) {
teleport(target, Location.create(3094, 3107, 0))
target.equipment.clear()
target.inventory.clear()
if (isUsingSecondaryBankAccount(target)) {
toggleBankAccount(target)
}
target.bank.clear()
target.bankSecondary.clear()
target.skills = Skills(target)
target.clearAttributes()
target.savedData = SavedData(target)
target.questRepository = QuestRepository(target)
target.varpManager = VarpManager(target)
target.varpMap.clear()
target.saveVarp.clear()
if (target.familiarManager.hasFamiliar()) {
target.familiarManager.dismiss()
}
val petKeys = target.familiarManager.petDetails.keys.toList()
for (key in petKeys) {
target.familiarManager.removeDetails(key)
}
for (type in DiaryType.values()) {
val diary = target.achievementDiaryManager.getDiary(type)
for (level in 0 until diary.levelStarted.size) {
for (task in 0 until diary.taskCompleted[level].size) {
diary.resetTask(target, level, task)
}
}
}
target.musicPlayer.clearUnlocked()
PlayerSaver(target).save()
target.clear()
}

View file

@ -69,7 +69,6 @@ import core.game.node.entity.combat.CombatSwingHandler;
import content.global.handlers.item.equipment.EquipmentDegrader;
import core.game.node.entity.combat.graves.Grave;
import core.game.node.entity.combat.graves.GraveController;
import core.game.node.entity.player.info.login.PlayerSaver;
import core.game.node.entity.state.State;
import core.game.node.entity.state.StateRepository;
import core.game.world.GameWorld;
@ -88,6 +87,7 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
import static core.api.ContentAPIKt.*;
import static core.api.utils.Permadeath.PermadeathKt.permadeath;
import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE;
import static core.game.system.command.sets.StatAttributeKeysKt.STATS_DEATHS;
import static core.tools.GlobalsKt.colorize;
@ -315,7 +315,7 @@ public class Player extends Entity {
public byte[] opCounts = new byte[255];
public int invalidPacketCount = 0;
public int invalidPacketCount = 0;
/**
* Constructs a new {@code Player} {@code Object}.
@ -597,7 +597,7 @@ public class Player extends Entity {
@Override
public void finalizeDeath(Entity killer) {
if (!isPlaying()) return; //if the player has already been full cleared, it has already disconnected. This code is probably getting called because something is maintaining a stale reference.
if (!isPlaying()) return; //if the player has already been full cleared, it has already disconnected. This code is probably getting called because something is maintaining a stale reference.
GlobalStats.incrementDeathCount();
settings.setSpecialEnergy(100);
settings.updateRunEnergy(settings.getRunEnergy() - 100);
@ -626,19 +626,7 @@ public class Player extends Entity {
String gender = this.isMale() ? "man " : "woman ";
if (getAttributes().containsKey("permadeath")) {
Repository.sendNews("Permadeath Hardcore Iron" + gender + " " + this.getUsername() + " has fallen. Total Level: " + this.getSkills().getTotalLevel()); // Not enough room for XP
equipment.clear();
inventory.clear();
bank.clear();
skills = new Skills(this);
clearAttributes();
setAttribute("/save:permadeath", true);
savedData = new SavedData(this);
questRepository = new QuestRepository(this);
varpManager = new VarpManager(this);
varpMap.clear();
saveVarp.clear();
new PlayerSaver(this).save();
clear();
permadeath(this);
return;
} else {
Repository.sendNews("Hardcore Iron " + gender + " " + this.getUsername() + " has fallen. Total Level: " + this.getSkills().getTotalLevel()); // Not enough room for XP

View file

@ -95,6 +95,13 @@ public final class MusicPlayer {
}
}
/**
* Clears the unlocked songs. This should only be used in the permadeath code.
*/
public void clearUnlocked() {
this.unlocked.clear();
}
/**
* Checks if the player has enough songs unlocked for the Air guitar emote.
* @return {@code True} if so.

View file

@ -1,42 +1,39 @@
package core.game.system.command.sets
import content.global.handlers.iface.RulesAndInfo
import content.global.skill.farming.timers.*
import content.minigame.fishingtrawler.TrawlerLoot
import content.region.misthalin.draynor.quest.anma.AnmaCutscene
import core.ServerConstants
import core.api.*
import core.api.InputType
import core.api.utils.Permadeath.permadeath
import core.cache.def.impl.NPCDefinition
import core.cache.def.impl.SceneryDefinition
import core.cache.def.impl.VarbitDefinition
import core.game.bots.AIRepository
import core.game.component.Component
import core.game.ge.GrandExchange
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.info.Rights
import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import core.game.node.scenery.Scenery
import core.game.system.command.CommandMapping
import core.game.system.command.Privilege
import core.game.system.communication.CommunicationInfo
import core.game.world.map.RegionManager
import core.game.world.map.build.DynamicRegion
import core.game.world.repository.Repository
import core.plugin.Initializable
import core.tools.Log
import core.tools.StringUtils
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.rs09.consts.Components
import core.ServerConstants
import core.game.bots.AIRepository
import core.api.utils.PlayerCamera
import content.global.ame.RandomEvents
import content.region.misthalin.draynor.quest.anma.AnmaCutscene
import core.game.ge.GrandExchange
import content.global.handlers.iface.RulesAndInfo
import content.minigame.fishingtrawler.TrawlerLoot
import core.game.system.command.CommandMapping
import core.game.system.command.Privilege
import core.game.world.repository.Repository
import core.tools.Log
import core.tools.colorize
import java.awt.HeadlessException
import java.awt.Toolkit
import java.awt.datatransfer.StringSelection
import content.global.skill.farming.timers.*
@Initializable
class MiscCommandSet : CommandSet(Privilege.ADMIN){
@ -377,6 +374,22 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
}
}
/**
* Permadeaths a player, resetting their save
*/
define("permadeath", Privilege.ADMIN, "::permadeath <lt>PLAYER<gt>", "Permadeaths PLAYER (self if omitted), completely wiping their save."){player,args ->
var target = player
if (args.size > 1) {
val n = args.slice(1 until args.size).joinToString("_")
val foundtarget = Repository.getPlayerByName(n)
if (foundtarget == null) {
reject(player, "Invalid player \"${n}\" or player not online")
}
target = foundtarget!!
}
permadeath(target)
}
define("log", Privilege.ADMIN){player,_ ->
var log: ArrayList<String>? = player.getAttribute("loc-log")
log = log ?: ArrayList<String>()