// This script will make the dragon fight more challenging.
// The dragon regenerates even when the crystals are destroyed. And if the dragon does not take damage for a bit, it will start increasing its max possible health.
// Health (hp) is the dragons current health
// Base hp / Max hp is the maximum possible health the dragon can regenerate to.

// Sorry about the excessive use of var 


var dragonInitialHealth = 300; // What should the starting health (hp) of the dragon be?
var dragonInitialBase = 300; // What should the starting max health (hp) of the dragon be?
var dragonRefreshInterval = 5000; // At what interval (milliseconds) should the dragon stats recalculate and update?
var dragonRegenPerInterval = 5; // How much hp should the dragon gain per interval?
var dragonBaseIncreasePerInterval = 5; // If the dragon did not take damage in the last interval, how much max hp should it gain?
var dragonMaxHealth = 750; // What is the maximum hp the dragon can grow to?

var idjson = {}; // json obj with hexadecimal uuid and Int-array uuid (Do not edit)


onEvent('entity.spawned', event => {

	if(event.entity.type == 'minecraft:ender_dragon' && !idjson.hasOwnProperty(event.entity.id)){ // Check if the entity is an ender dragon and make sure it is unique
		idjson[event.entity.id]="[I;"+event.entity.getFullNBT().UUID.toString().substring(1);	  // Log the Int-array uuid in relation to the hexadecimal uuid
		
		if(event.entity.getHealth() == 200 && event.entity.getMaxHealth() == 200){ // Checking if this is a new dragon or reloaded entity
			event.entity.setMaxHealth(dragonInitialBase);
			event.entity.setHealth(dragonInitialHealth);
			
			var oldhealth = 0; 
			var oldbase = dragonInitialBase; // Initial hp

		} else {
			var oldhealth = 0; 
			var oldbase = event.entity.getMaxHealth(); // Set to what the current max hp of the dragon is			
		}
		
	event.server.schedule(dragonRefreshInterval, cb => { // Essentially a timed loop which repeats at an interval specified previously
			
		var health = event.entity.getHealth();	 // Queries the current hp of the dragon
            
        if (health >= oldhealth && oldbase <= dragonMaxHealth){ // Checking if the dragon took damage in the last interval or is already at the max possible max hp
			event.entity.setMaxHealth(oldbase+dragonBaseIncreasePerInterval);
			  oldbase = oldbase+dragonBaseIncreasePerInterval;
		} else if (oldbase > dragonMaxHealth){ // Check if max hp surpassed the specified limit
		event.entity.setMaxHealth(dragonMaxHealth);
		}	

        event.entity.setHealth(health+dragonRegenPerInterval);
		oldhealth = health+dragonRegenPerInterval; 
		

		
		if(!isNaN(health) && health != 0){ // Check if the dragon is dead / despawned
		bossbar(event);
			cb.reschedule(); // If dragon still exisits, continue the loop
		} else {
			delete idjson[event.entity.id];
			
		}
	})	
		
	}
});

onEvent('entity.attack', event => {
	event.server.scheduleInTicks(1, cb => {
		if (idjson.hasOwnProperty(event.entity.id)){ // Making sure the attacked entity is a dragon
			bossbar(event);	
		}	
	})
});

function bossbar(event){
	var health = event.entity.getHealth();
	var max = event.entity.getMaxHealth();
	entityNBT(event, event.entity.id, "set", "CustomName", '"\\"Ender Dragon - '+Math.round(health)+'/'+max+'\\""'); // Update bossbar text
}

function entityNBT(event, entityid, direction, path, scale){ // Simple function that runs minecraft data commands
	if (direction == "get"){
		return(event.server.runCommandSilent('data get entity @e[limit=1,nbt={UUID:'+idjson[entityid]+'}] '+path)); // Converts hexadecimal uuid to int array to run command
	}
	
	if (direction == "set"){
		event.server.runCommandSilent('data modify entity @e[limit=1,nbt={UUID:'+idjson[entityid]+'}] '+path+' set value '+scale); // Converts hexadecimal uuid to int array to run command
	}	
}
