diff --git a/Server/src/main/java/core/game/node/entity/npc/bosses/corp/CorporealBeastNPC.java b/Server/src/main/java/core/game/node/entity/npc/bosses/corp/CorporealBeastNPC.java
index cdb03ce13..260cf8b4a 100644
--- a/Server/src/main/java/core/game/node/entity/npc/bosses/corp/CorporealBeastNPC.java
+++ b/Server/src/main/java/core/game/node/entity/npc/bosses/corp/CorporealBeastNPC.java
@@ -42,7 +42,7 @@ public final class CorporealBeastNPC extends AbstractNPC {
/**
* The dark energy core NPC.
*/
- private NPC darkEnergyCore;
+ public NPC darkEnergyCore;
/**
* Constructs a new {@code CorporealBeastNPC} {@code Object}.
@@ -65,29 +65,7 @@ public final class CorporealBeastNPC extends AbstractNPC {
super.init();
configureBossData();
}
-
- @Override
- public void handleTickActions() {
- for(Player player : getViewport().getCurrentPlane().getPlayers()){
- if(player.getFamiliarManager().hasFamiliar() && RandomFunction.random(100) < 10){
- int heal = player.getFamiliarManager().getFamiliar().getSkills().getLifepoints() / 4;
- super.getSkills().heal(heal);
- player.sendMessage("
Your familiar was devoured by the Corporeal Beast, healing it by "+heal+" HP.");
- player.getFamiliarManager().dismiss();
- }
- }
- if (getSkills().getLifepoints() < getSkills().getMaximumLifepoints()) {
- if (getViewport().getCurrentPlane().getPlayers().isEmpty()) {
- super.fullRestore();
- if (darkEnergyCore != null) {
- darkEnergyCore.clear();
- darkEnergyCore = null;
- }
- }
- }
- super.handleTickActions();
- }
-
+
@Override
public CombatSwingHandler getSwingHandler(boolean swing) {
return combatHandler;
diff --git a/Server/src/main/java/core/game/world/map/zone/ZoneRestriction.java b/Server/src/main/java/core/game/world/map/zone/ZoneRestriction.java
index fb600ce2d..036e43ad1 100644
--- a/Server/src/main/java/core/game/world/map/zone/ZoneRestriction.java
+++ b/Server/src/main/java/core/game/world/map/zone/ZoneRestriction.java
@@ -29,7 +29,12 @@ public enum ZoneRestriction {
/**
* No cannons allowed.
*/
- CANNON, ;
+ CANNON,
+ /**
+ * Do not spawn a grave if a player dies here
+ */
+ GRAVES,
+ ;
/**
* Gets the restriction flag.
diff --git a/Server/src/main/kotlin/rs09/game/content/zone/CorpAreaController.kt b/Server/src/main/kotlin/rs09/game/content/zone/CorpAreaController.kt
new file mode 100644
index 000000000..1973b27b5
--- /dev/null
+++ b/Server/src/main/kotlin/rs09/game/content/zone/CorpAreaController.kt
@@ -0,0 +1,70 @@
+package rs09.game.content.zone
+
+import api.*
+import core.game.node.entity.Entity
+import core.game.node.entity.npc.bosses.corp.CorporealBeastNPC
+import core.game.node.entity.player.Player
+import core.game.node.entity.skill.summoning.familiar.Familiar
+import core.game.world.map.zone.ZoneBorders
+import core.game.world.map.zone.ZoneRestriction
+import rs09.tools.secondsToTicks
+
+class CorpAreaController : MapArea, TickListener {
+ companion object {
+ var activePlayers = ArrayList()
+ var corpBeast: CorporealBeastNPC? = null
+ var borders = ZoneBorders(2974, 4369, 3007, 4400)
+ }
+
+ override fun defineAreaBorders(): Array {
+ return arrayOf(borders)
+ }
+
+ override fun getRestrictions(): Array {
+ return arrayOf(ZoneRestriction.GRAVES, ZoneRestriction.RANDOM_EVENTS)
+ }
+
+ override fun areaEnter(entity: Entity) {
+ if (entity is Player) {
+ activePlayers.add(entity)
+ }
+ else if (entity is Familiar) {
+ entity.setAttribute("corp-time-remaining", secondsToTicks(10)) //Familiars last about 10 seconds, based on https://www.youtube.com/watch?v=kOd6q5Q5ZKI
+ }
+ else if (entity is CorporealBeastNPC) {
+ corpBeast = entity
+ }
+ }
+
+ override fun areaLeave(entity: Entity, logout: Boolean) {
+ if (entity is Player) {
+ activePlayers.remove(entity)
+ }
+ }
+
+ override fun tick() {
+ if (activePlayers.size == 0) {
+ corpBeast?.let {
+ it.skills.lifepoints = it.skills.maximumLifepoints
+ if (it.darkEnergyCore != null) {
+ it.darkEnergyCore.clear()
+ it.darkEnergyCore = null
+ }
+ }
+ }
+
+ if (corpBeast?.isActive == true && activePlayers.isNotEmpty()) {
+ for (player in activePlayers.toTypedArray()) {
+ val familiar = player.familiarManager.familiar ?: continue
+ val timeRemaining = getAttribute(familiar, "corp-time-remaining", -1)
+ if (timeRemaining == 0 && borders.insideBorder(familiar)) {
+ val healBy = familiar.skills.lifepoints / 4
+ player.familiarManager.dismiss()
+ corpBeast?.skills?.heal(healBy)
+ sendMessage(familiar.owner, "The Beast devoured your familiar!")
+ }
+ setAttribute(familiar, "corp-time-remaining", timeRemaining - 1)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/player/graves/GraveController.kt b/Server/src/main/kotlin/rs09/game/node/entity/player/graves/GraveController.kt
index 85171079d..ba950a59c 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/player/graves/GraveController.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/player/graves/GraveController.kt
@@ -12,6 +12,7 @@ import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.map.Location
+import core.game.world.map.zone.ZoneRestriction
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.rs09.consts.Items
@@ -222,6 +223,8 @@ class GraveController : PersistWorld, TickListener, InteractionListener, Command
return false
if (player.ironmanManager.mode == IronmanMode.HARDCORE)
return false
+ if (player.zoneMonitor.isRestricted(ZoneRestriction.GRAVES))
+ return false
return true
}