diff --git a/Server/src/main/content/region/wilderness/handlers/DeepWildyThreat.kt b/Server/src/main/content/region/wilderness/handlers/DeepWildyThreat.kt index 9bc2f593c..1b0aa0d65 100644 --- a/Server/src/main/content/region/wilderness/handlers/DeepWildyThreat.kt +++ b/Server/src/main/content/region/wilderness/handlers/DeepWildyThreat.kt @@ -1,13 +1,19 @@ package content.region.wilderness.handlers +import content.region.wilderness.handlers.revenants.RevenantController +import content.region.wilderness.handlers.revenants.RevenantNPC import content.region.wilderness.handlers.revenants.RevenantType import core.api.* import core.game.node.entity.Entity import core.game.node.entity.combat.DeathTask import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior import core.game.node.entity.player.Player +import core.game.node.item.Item import core.game.system.command.Privilege import core.game.system.timer.PersistTimer +import core.game.system.timer.impl.Disease +import core.game.world.map.zone.impl.WildernessZone import core.game.world.update.flag.context.Graphics import core.tools.RandomFunction import core.tools.colorize @@ -38,7 +44,6 @@ class DWThreatTimer : PersistTimer(1, "dw-threat"), Commands { var ticksLeft = 0 var lastMessage = 0 var currentRev: NPC? = null - var chats = arrayOf("Leave this place!", "Suffer!", "Death to you!", "Flee, coward!", "Leave my resting place!", "Let me rest in peace!", "You belong to me!") override fun run(entity: Entity): Boolean { if (ticksLeft-- <= 0) return false @@ -59,13 +64,12 @@ class DWThreatTimer : PersistTimer(1, "dw-threat"), Commands { val type = RevenantType.getClosestHigherOrEqual(entity.properties.currentCombatLevel) val npc = NPC.create(type.ids.random(), entity.location) npc.isRespawn = false + npc.behavior = RevGuardianBehavior() npc.init() - npc.attack(entity) - Graphics.send(Graphics(86), npc.location) - ticksLeft -= 500 - sendChat(npc, chats.random()) + npc.setAttribute("dw-threat-target", entity) + RevenantController.unregisterRevenant(npc as RevenantNPC, false) currentRev = npc - } else if (currentRev != null && !currentRev!!.location.withinDistance(entity.location, 25)) { + } else if (currentRev != null && !currentRev!!.location.withinDistance(entity.location, 25) && currentRev!!.properties.teleportLocation == null) { poofClear(currentRev!!) currentRev = null } @@ -74,11 +78,11 @@ class DWThreatTimer : PersistTimer(1, "dw-threat"), Commands { } override fun save(root: JSONObject, entity: Entity) { - root["threat-time-remaining"] = ticksLeft + root["threat-time-remaining"] = ticksLeft.toString() } override fun parse(root: JSONObject, entity: Entity) { - ticksLeft = root.getOrDefault("threat-time-remaining", 3000) as? Int ?: 3000 + ticksLeft = root["threat-time-remaining"]?.toString()?.toIntOrNull() ?: 0 } override fun defineCommands() { @@ -87,4 +91,42 @@ class DWThreatTimer : PersistTimer(1, "dw-threat"), Commands { notify(player, "Current Threat: ${timer.ticksLeft}") } } +} + +class RevGuardianBehavior : NPCBehavior() { + val deathMessages = arrayOf("Curses upon thee!", "Rot in blight!", "Suffer my wrath!", "Nevermore!", "May ye be undone!") + var chats = arrayOf("Leave this place!", "Suffer!", "Death to thee!", "Flee, coward!", "Leave my resting place!", "Let me rest in peace!", "Thou belongeth to me!") + + override fun tick(self: NPC): Boolean { + val target = getAttribute(self, "dw-threat-target", null) ?: return true + if (!target.isActive) { + self.clear() + return true + } + if (target.properties.teleportLocation != null && self.properties.teleportLocation == null) { + if (WildernessZone.isInZone(target.properties.teleportLocation)) + self.properties.teleportLocation = target.properties.teleportLocation + } + sendChat(self, "ticking") + self.attack(target) + return true + } + + override fun onCreation(self: NPC) { + Graphics.send(Graphics(86), self.location) + sendChat(self, chats.random()) + } + + override fun onDeathStarted(self: NPC, killer: Entity) { + val target = getAttribute(self, "dw-threat-target", null) ?: return + sendChat(self, deathMessages.random()) + val disease = getOrStartTimer(target, 25) + disease.hitsLeft = 25 + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + val target = getAttribute(self, "dw-threat-target", null) ?: return + val timer = getOrStartTimer(target) + timer.ticksLeft = 0 + } } \ No newline at end of file diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt index ef861325a..1a1bdc055 100644 --- a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt @@ -35,11 +35,12 @@ class RevenantController : TickListener, Commands { Repository.RENDERABLE_NPCS.add(revenantNPC) } - @JvmStatic fun unregisterRevenant(revenantNPC: RevenantNPC) { + @JvmStatic fun unregisterRevenant(revenantNPC: RevenantNPC, removeRender: Boolean = true) { trackedRevenants.remove(revenantNPC) taskTimeRemaining.remove(revenantNPC) currentTask.remove(revenantNPC) - Repository.RENDERABLE_NPCS.remove(revenantNPC) + if (removeRender) + Repository.RENDERABLE_NPCS.remove(revenantNPC) } val routes = listOf( diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java index 34f921773..67a018d6a 100644 --- a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java @@ -99,7 +99,7 @@ public class RevenantNPC extends AbstractNPC { @Override public void clear() { super.clear(); - RevenantController.unregisterRevenant(this); + RevenantController.unregisterRevenant(this, true); } @Override @@ -125,6 +125,7 @@ public class RevenantNPC extends AbstractNPC { } setAttribute("eat-delay", GameWorld.getTicks() + 6); } + behavior.tick(this); if (aggressiveHandler != null && aggressiveHandler.selectTarget()) { return; } diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantType.java b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantType.java index b2f06aba3..0e7bfb000 100644 --- a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantType.java +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantType.java @@ -2,6 +2,9 @@ package content.region.wilderness.handlers.revenants; import core.cache.def.impl.NPCDefinition; +import java.util.ArrayList; +import java.util.List; + /** * A revenant type. * @author Vexia @@ -66,6 +69,14 @@ public enum RevenantType { NPCDefinition def = NPCDefinition.forId(t.ids[0]); if (def.getCombatLevel() >= combatLevel) return t; } - return null; + return RevenantType.DRAGON; + } + + public static List getAllIds() { + ArrayList ids = new ArrayList<>(); + for (RevenantType t : values()) { + for (int id : t.ids) ids.add(id); + } + return ids; } } diff --git a/Server/src/main/core/game/system/timer/impl/Frozen.kt b/Server/src/main/core/game/system/timer/impl/Frozen.kt index d028259d7..ed99a9253 100644 --- a/Server/src/main/core/game/system/timer/impl/Frozen.kt +++ b/Server/src/main/core/game/system/timer/impl/Frozen.kt @@ -40,7 +40,6 @@ class Frozen : PersistTimer (1, "frozen") { override fun getTimer (vararg args: Any) : RSTimer { val inst = Frozen() - println(args) inst.runInterval = args.getOrNull(0) as? Int ?: 10 inst.shouldApplyImmunity = args.getOrNull(1) as? Boolean ?: false return inst diff --git a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java index fd7211e08..fd67844ea 100644 --- a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java +++ b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java @@ -97,13 +97,13 @@ public final class WildernessZone extends MapZone { boolean isValidTarget = e instanceof NPC && (isDeepWildy || e.asNpc().getName().contains("Revenant") || e.getId() == NPCs.CHAOS_ELEMENTAL_3200); if (isDeepWildy) { - DeepWildyThreat.adjustThreat((Player) killer, 250); + DeepWildyThreat.adjustThreat((Player) killer, 50); } if (!isValidTarget) return; int cEleGloveRate = isDeepWildy ? 50 : 150; - int normalGloveRate = isDeepWildy ? 75 : 150; + int normalGloveRate = isDeepWildy ? 100 : 150; int pvpGearRate = getNewDropRate(e.asNpc().getDefinition().getCombatLevel()); if (isDeepWildy) @@ -114,7 +114,8 @@ public final class WildernessZone extends MapZone { Item reward = new Item(BrawlingGloves.forIndicator(glove).getId()); GroundItemManager.create(reward, e.asNpc().getDropLocation(), killer.asPlayer()); Repository.sendNews(killer.getUsername() + " has received " + reward.getName().toLowerCase() + " from a " + e.asNpc().getName() + "!"); - DeepWildyThreat.adjustThreat((Player) killer, 200); + if (isDeepWildy) + DeepWildyThreat.adjustThreat((Player) killer, 750); } for (int j : PVP_GEAR) { @@ -128,7 +129,8 @@ public final class WildernessZone extends MapZone { } Repository.sendNews(killer.asPlayer().getUsername() + " has received a " + reward.getName() + " from a " + e.asNpc().getName() + "!"); GroundItemManager.create(reward, ((NPC) e).getDropLocation(), killer.asPlayer()); - DeepWildyThreat.adjustThreat((Player) killer, 1000); + if (isDeepWildy) + DeepWildyThreat.adjustThreat((Player) killer, 3000); } } } @@ -307,6 +309,13 @@ public final class WildernessZone extends MapZone { return false; } + public static boolean isInZone (Location l) { + for (ZoneBorders z : INSTANCE.borders) { + if (z.insideBorder(l)) return true; + } + return false; + } + /** * The wilderness level. * @return the level. diff --git a/Server/src/main/core/game/world/update/UpdateSequence.kt b/Server/src/main/core/game/world/update/UpdateSequence.kt index e50650f70..bc17fbd65 100644 --- a/Server/src/main/core/game/world/update/UpdateSequence.kt +++ b/Server/src/main/core/game/world/update/UpdateSequence.kt @@ -33,14 +33,14 @@ class UpdateSequence playersList = renderablePlayers npcList = Repository.renderableNpcs lobbyList!!.map{ PacketRepository.send(ClearMinimapFlag::class.java, PlayerContext(it)) } - - var playerTickStart = System.currentTimeMillis() - renderablePlayers.forEach(Player::tick) - Grafana.playerTickTime = (System.currentTimeMillis() - playerTickStart).toInt() var npcTickStart = System.currentTimeMillis() npcList!!.forEach(NPC::tick) Grafana.npcTickTime = (System.currentTimeMillis() - npcTickStart).toInt() + + var playerTickStart = System.currentTimeMillis() + renderablePlayers.forEach(Player::tick) + Grafana.playerTickTime = (System.currentTimeMillis() - playerTickStart).toInt() } /**