From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: jmp <jasonpenilla2@me.com>
Date: Thu, 20 Aug 2020 17:38:12 -0700
Subject: [PATCH] Customizable wither health and healing

Adds the ability to customize the health of the wither, as well as the amount that it heals, and how often.

diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java b/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java
index 4c0a555cdb5bc34c73040b9533beaee56cbce70a..beb4d59faf4bd7501468b2eaa0e866613625e963 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java
@@ -207,6 +207,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
         skull.setPositionRaw(headX, headY, headZ);
         world.addEntity(skull);
     }
+
+    @Override
+    public void initAttributes() {
+        this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(world.purpurConfig.witherMaxHealth);
+    }
     // Purpur end
 
     @Override
@@ -411,7 +416,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
 
             this.setInvul(i);
             if (this.ticksLived % 10 == 0) {
-                this.heal(10.0F, EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit
+                this.heal(this.getMaxHealth() / 33, EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit // Purpur - use max health for healing instead of a constant
             }
 
         } else {
@@ -520,8 +525,10 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
                 }
             }
 
-            if (this.ticksLived % 20 == 0) {
-                this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
+            // Purpur start - customizable heal rate and amount
+            if (this.ticksLived % world.purpurConfig.witherHealthRegenDelay == 0) {
+                this.heal(world.purpurConfig.witherHealthRegenAmount, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
+                // Purpur end
             }
 
             //this.bossBattle.setProgress(this.getHealth() / this.getMaxHealth()); // Paper - Moved down
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 66074748c6fd366caf58170de478a01d3adb1430..4b851fe1f266dd646e51730d41fbe269ad2c9791 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -933,10 +933,21 @@ public class PurpurWorldConfig {
     public boolean witherRidable = false;
     public boolean witherRidableInWater = false;
     public double witherMaxY = 256D;
+    public float witherHealthRegenAmount = 1.0f;
+    public int witherHealthRegenDelay = 20;
+    public double witherMaxHealth = 300.0D;
     private void witherSettings() {
         witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
         witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
         witherMaxY = getDouble("mobs.wither.ridable-max-y", witherMaxY);
+        witherHealthRegenAmount = (float) getDouble("mobs.wither.health-regen-amount", witherHealthRegenAmount);
+        witherHealthRegenDelay = getInt("mobs.wither.health-regen-delay", witherHealthRegenDelay);
+        if (PurpurConfig.version < 8) {
+            double oldValue = getDouble("mobs.wither.max-health", witherMaxHealth);
+            set("mobs.wither.attributes.max-health", oldValue);
+            set("mobs.wither.max-health", null);
+        }
+        witherMaxHealth = getDouble("mobs.wither.attributes.max-health", witherMaxHealth);
     }
 
     public boolean witherSkeletonRidable = false;
