//------------------------------------------------------------------------------------------------------------------------------------------------
// PA2 Extras - Drop Handler
//------------------------------------------------------------------------------------------------------------------------------------------------
// Author: RicTheCoder
//
// This script includes a bunch of things, the ability to quickly fix blocks that are either bugged and should drop, or drops that should drop
// but for some reason never were added (no reason why some blocks like Reinforced Deepslate shouldn't be mineable, at least with silk touch).
//
// It also handles mob drops to fix things such as wrong signature heads, which is a issue in vanilla itself and was never fixed.
//
// Features:
// - Setting any list to an empty array will not even check for items in them
// - Fixes some weird drop issues like with the Redstone Beacon
// - Prevents item duping with Draconic Evolution items when dropping the blocks added here
// - Fixes the issue with 'Alchemical Collection' by auto learning blocks being broken (this is just a quick fix, only applies when AC is active)
// - Fixes modular router messing Draconic Evolution weapons and other tools with highly advanced NBT tags
// - Fixes weird breaking limitations of blocks such as Dark Matter Pedestal
//
// [#] The trials blocks (vaults and spawner) only drop if they have injected their items and are now empty, so only after becoming inactive,
// this prevents breaking something accidently, they also can't be broken until then unless in creative (also prevents other accidents...)
//------------------------------------------------------------------------------------------------------------------------------------------------

// Items that should actually drop
// - Items in here will drop when destroyed regardless of the tool used (this is just a quick fix for some blocks that are either bugged or don't drop nicely)
// - The ones on this list will drop with or without silk touch
const drops = [
	"outer_end:rose_crystal_lamp",
	"outer_end:mint_crystal_lamp",
	"outer_end:cobalt_crystal_lamp",
	"cyclic:redstone_beacon",
	"phantasm:oblivion"
];

// Same as above but requires silk touch for the drop to happen
const dropsSilk = [
	"minecraft:reinforced_deepslate", 
	"trials:trial_spawner",
	"trials:trial_vault",
	"trials:trial_vault_ominous"
	
	// QUICK NOTE: Trial spawners and vaults can drop but if they are dropped they will never work again, 
	// the purpose is to be cosmetic, as they are nice for some builds
]

// Blocks that should be broken when Sneak + Break (for blocks that are hard coded to specific tools)
// - The block will run the normal break situation if it is broken while sneaking
// - Block drops based on the drop from running 'setblock ... destroy'
const forceBreak = [
	"projecte:dm_pedestal"
]

// Some tools of some mods can cause double drops, such as the ones from Draconic Evolution
// add the mod id/namespace or the item id to prevent that
const doubleDropFix = ["draconicevolution"]

// Make this false to not apply the fix for 'Alchemical Collection'
const fixACEnchant = true;

// Fixes the modular router dropping the wrong draconic equipment (and sometimes Mekanism)
const fixMRWrongDrop = true;

// If the trials content is dropped, activate this to only allow for them to be obtainable when already inactive
const trialInactiveOnly = true;

//---[CODE]---------------------------------------------------------------------------------------------------------------------------------------

// Block Break Functions
function breakBlock(event, heldItem, silk) {
	if (global.dropped === true) // Locker used to prevent the tools that drop twice for some reason
	{
		global.dropped = false;
		return;
	}
	
	// The Trial active drop prevention
	if (trialInactiveOnly && event.block.getId().startsWith("trials:trial_"))
	{
		event.block.getBlockState().getProperties().forEach(prop => {
			if (prop.getName() === "trials_active" && event.block.getBlockState().getValue(prop) === true)
				event.cancel();
			
			if (prop.getName() === "trials_ejecting" && event.block.getBlockState().getValue(prop) === true)
				event.cancel();
		});
	}
	
	// The Drop Fix
	let fixDrop = doubleDropFix.length !== 0 && ( doubleDropFix.includes(heldItem.getMod()) || doubleDropFix.includes(heldItem.getId()) );
	
	if (fixDrop) // Fixes double dropping
	{
		if (global.dropped === false)
		{
			event.block.popItem(event.block.getItem().withCount(1));
			global.dropped = true;
		}
	}
	else if (!silk || (silk && heldItem.hasEnchantment("minecraft:silk_touch", 1)))
		event.block.popItem(event.block.getItem().withCount(1));
}

// The block event registration
BlockEvents.broken(event => {
	// Checks for Modular Routers
	if (fixMRWrongDrop && event.block.getId() === "modularrouters:modular_router")
	{
		// Schedules the break fix for 1 tick later
		event.player.getServer().schedule(1, callback => {
			let pos = `${event.block.getX()} ${event.block.getY()} ${event.block.getZ()}`;
			
			event.player.runCommandSilent(`execute if data block ${pos} Buffer.Items[0] run summon minecraft:item ${pos} {Tags:["pa2.mrfix"],Item:{id:"minecraft:barrier",Count:1b}}`);
			event.player.runCommandSilent(`execute if data block ${pos} Buffer.Items[0] run data modify entity @e[tag=pa2.mrfix,limit=1] Item set from block ${pos} Buffer.Items[0]`);
			event.player.runCommandSilent(`execute if data block ${pos} Buffer.Items[0] run data remove block ${pos} Buffer.Items[0]`);
			
			if (!event.player.creative)
				event.player.runCommandSilent(`setblock ${pos} air destroy`);
			else
				event.player.runCommandSilent(`setblock ${pos} air`);
			
			console.log(event.block.getId());
		});
		
		// Cancels the event
		event.cancel();
	}
	
	// Ignore Creative Players
	if (event.player.creative)
		return;
	
	let heldItem = event.player.getMainHandItem();
	
	// Non Silk Touch Drops
	if (drops.length !== 0 && drops.includes(event.block.getId()))
	{
		breakBlock(event, heldItem, false);
		return;
	}
	
	// Silk Touch Drops
	if (dropsSilk.length !== 0 && dropsSilk.includes(event.block.getId()))
	{
		breakBlock(event, heldItem, true);
		return;
	}
	
	// Checks for Alchemical Collection usage
	if (fixACEnchant && heldItem.nbt && heldItem.nbt.AlchemicalCollectionEnabled && heldItem.nbt.AlchemicalCollectionEnabled == 1)
		event.player.runCommandSilent(`projecte knowledge learn @s ${event.block.getItem().getId()}`); // Force learns the item being broken with AC active
});

// Block left click event
BlockEvents.leftClicked(event => {
	// Ignore Creative Players and non Sneaking players
	if (event.getEntity().creative || !event.getEntity().isCrouching())
		return;
	
	// Checks if its a force break block
	if (forceBreak.length !== 0 && forceBreak.includes(event.block.getId()))
	{
		let pos = `${event.block.getX()} ${event.block.getY()} ${event.block.getZ()}`;
		event.getEntity().runCommandSilent(`setblock ${pos} air destroy`);
	}
});