import { world, system, BlockPermutation, EntityDamageCause, Player } from "@minecraft/server";
import * as blockData from "../data/block_data.js"
import * as dragonArrays from "../arrays/dragon_arrays.js"
import * as dragonData from "../data/dragon_data.js"
import * as mathUtilities from "../utilities/math_utilities.js"

export function dragonfireMatchTypeOrTag(target,condition) {
	if (!condition) return false;
	if (Array.isArray(condition)) {
		for (const c of condition) {
			if (dragonfireMatchTypeOrTag(target,c)) return true;
		}
		return false;
	}
	if (condition.startsWith("#")) {
		const tagName = condition.substring(1);
		return target.hasTag(tagName);
	}
	return target.typeId === condition;
};
export function dragonfireExcludedTypeOrTag(target,exclude) {
	if (!exclude) return false;
	if (Array.isArray(exclude)) {
		for (const e of exclude) {
			if (dragonfireExcludedTypeOrTag(target,e)) return true;
		}
		return false;
	}
	if (exclude.startsWith("#")) {
		const tagName = exclude.substring(1);
		return target.hasTag(tagName);
	}
	return target.typeId === exclude;
};
function safeResolvePermutation(blockId,stateOverrides) {
	if (!stateOverrides || Object.keys(stateOverrides).length === 0) {
		return BlockPermutation.resolve(blockId);
	}
	try {
		return BlockPermutation.resolve(blockId, stateOverrides);
	} catch (err) {
		const kept = {};
		for (const key of Object.keys(stateOverrides)) {
			const attempt = {...kept, [key]: stateOverrides[key]};
			try {
				BlockPermutation.resolve(blockId, attempt);
				kept[key] = stateOverrides[key];
			} catch (e2) {
				continue;
			}
		}
		return BlockPermutation.resolve(blockId, kept);
	}
};
function buildPermutationWithCopy(blockId, targetBlock, overrideStates) {
	const sourceStates = targetBlock.permutation.getAllStates() || {};
	const merged = Object.assign({}, sourceStates, overrideStates || {});
	return safeResolvePermutation(blockId, merged);
};
export function dragonfireBurningArea(entity,dimension,areaSize) {
	const pos = entity.location;
	const rules = blockData.burnableBlockTypes;
	const regions = areaSize;
	for (const region of regions) {
		for (let x = region.min.x; x >= region.max.x; x--) {
			for (let y = region.min.y; y >= region.max.y; y--) {
				for (let z = region.min.z; z >= region.max.z; z--) {
					const target = dimension.getBlock({
						x: Math.floor(pos.x) + x,
						y: Math.floor(pos.y) + y,
						z: Math.floor(pos.z) + z
					});
					if (!target) continue;
					for (const r of rules) {
						if (!dragonfireMatchTypeOrTag(target,r.replace)) continue;
						if (dragonfireExcludedTypeOrTag(target,r.exclude)) continue;
						// Optional state filter;
						if (r.state) {
							const key = Object.keys(r.state)[0];
							if (target.permutation.getState(key) !== r.state[key]) continue;
						}
						if (r.weight) {
							const percentageChance = r.weight.numerator/r.weight.denominator;
							if (Math.random()>percentageChance) return;
						}
						// Build output permutation
						let perm;
						let toBlock = r.to;
						let stateObj = r.stateOut || {};
						if (r.fromState && r.toState) {
							const fromStateKey = r.fromState.type;
							const fromStateVal = target.permutation.getState(fromStateKey);
							const mapping = r.toState.values;
							if (Array.isArray(mapping[fromStateVal])) {
								const choices = mapping[fromStateVal];
								stateObj[r.toState.type] = choices[Math.floor(Math.random() * choices.length)];
							}
							else if (mapping[fromStateVal] !== undefined) {
								stateObj[r.toState.type] = mapping[fromStateVal];
							}
						}
						if (Array.isArray(r.to)) {
							const option = mathUtilities.pickWeightedOutcome(r.to);
							const states = { ...stateObj, ...mathUtilities.resolvedRandomisedState(option.stateOut) };
							perm = BlockPermutation.resolve(option.block, states);
						}
						/*else {
							perm = BlockPermutation.resolve(toBlock, stateObj);
						}*/
						else {
							const finalStates = { ...stateObj };
							if (r.stateOut) {
								const rand = mathUtilities.resolvedRandomisedState(r.stateOut);
								Object.assign(finalStates, rand);
							}
							perm = safeResolvePermutation(toBlock, finalStates);
						}
						target.setPermutation(perm);
						break;
					}
				}
			}
		}
	}
};
export function dragonEggLaying(dragon,event) {
	const rule = dragonArrays.dragonEggLayingTypes[dragon.typeId];
	if (!rule||event!=rule.layingEvent) return;
	const targetBlock = rule.eggLocation(dragon);
	if (!targetBlock||!rule.eggPlacedAt(dragon)) {
		dragon.dimension.spawnParticle(rule.layParticle,targetBlock.center());
		dragon.triggerEvent(rule.layEventFailure);
		return;
	}
	const entityVariants = dragon.getProperty(rule.entityVariants.state);
	const entityIndex = rule.entityVariants.values.indexOf(entityVariants);
	if (entityIndex<=-1) {
		dragon.dimension.spawnParticle(rule.layParticle,targetBlock.center());
		dragon.triggerEvent(rule.layEventFailure);
		return;
	}
	const blockType = rule.blockVariants[entityIndex];
	const randomStateIndex = Math.floor(Math.random()*rule.blockState.values.length);
	const blockStateValue = rule.blockState.values[randomStateIndex];
	dragon.dimension.spawnParticle(rule.layParticle,targetBlock.center());
	targetBlock.setPermutation(BlockPermutation.resolve(blockType,{[rule.blockState.state]:blockStateValue}));
	dragon.triggerEvent(rule.layEventSuccess);
};






export const dragonTypes = { families: ["dragon"] };

export function dragonsMainComponents(dragon) {
	const dragonOnList = dragonArrays.dragonTypesList.includes(dragon.typeId);
	if (!dragonOnList) return;
	const rule = dragonArrays.dragonTypes[dragon.typeId];
	if (!rule) return;
	const data = dragonData.dragonDataTypes[dragon.typeId];
	if (!data) return;
	const isCooldown = dragon.getProperty("megaverse:mob_has_spitting_cooldown");
	const isOnGround = dragon.getProperty("megaverse:is_on_ground");
	let isAttacking,isRangedAttacking;
	let ageVariant,attackState,chargeAmount,movementState,navigationState,isControlledAttacking;
	if (dragon.typeId=="megaverse:fire_dragon") {
		ageVariant = dragon.getProperty("megaverse:age_variant");
		attackState = dragon.getProperty("megaverse:attack_state");
		isControlledAttacking = attackState=="controlled_melee"||attackState=="controlled_ranged";
		chargeAmount = dragon.getProperty("megaverse:charge_amount");
		movementState = dragon.getProperty("megaverse:movement_state");
		navigationState = dragon.getProperty("megaverse:navigation_state");
		if (ageVariant=="baby") return;
		handleArmBlockPositionWrap(data,dragon,ageVariant,isOnGround,"left");
		handleArmBlockPositionWrap(data,dragon,ageVariant,isOnGround,"right");
		handleLegBlockPositionWrap(data,dragon,ageVariant,isOnGround,"left");
		handleLegBlockPositionWrap(data,dragon,ageVariant,isOnGround,"right");
	}
	else {
		const isBaby = dragon.getComponent("minecraft:is_baby");
		if (isBaby) return;
		navigationState = dragon.getProperty("megaverse:mob_navigation_state");
		isRangedAttacking = dragon.getProperty("megaverse:mob_is_spitting");
		chargeAmount = dragon.getProperty("megaverse:dragon_spitting_amount");
	}
	const rideable = dragon.getComponent("rideable");
	if (rideable) {
		const controllingSeat = rideable.controllingSeat;
		//if (controllingSeat == undefined) return;
		const riders = rideable.getRiders();
		if (riders) {
			const controllingRider = riders[controllingSeat];
			if (controllingRider) {
				if (controllingRider instanceof Player) {
					//handleDragonInputControl(rule,dragon,controllingRider,navigationState,isOnGround);
					if (dragon.typeId=="megaverse:fire_dragon") {
						handleDragonAttacks(data,dragon,ageVariant,controllingRider,attackState,isControlledAttacking,chargeAmount);
						handleDragonInputControlForMovement(data,dragon,ageVariant,controllingRider,navigationState,isOnGround);
						handleDragonPitchControl(rule,dragon,controllingRider,movementState,isOnGround,attackState,chargeAmount);
					}
					else {
						handleDraconFire(dragon,controllingRider,isRangedAttacking,isCooldown);
						OldhandleDragonPitchControl(rule,dragon,controllingRider,navigationState,isOnGround,chargeAmount,isRangedAttacking,isCooldown);
					}
				}
			}
			else {
				if (dragon.typeId=="megaverse:fire_dragon") {
					if (attackState=="controlled_ranged") dragon.triggerEvent("minecraft:dragon_controlled_attack");
					handleDragonFollowOwnerFlying(rule,dragon,movementState);
				}
			}
		}
		else {
			if (dragon.typeId=="megaverse:fire_dragon") {
				if (navigationState!="forward") dragon.setProperty("megaverse:navigation_state","forward");
				handleDragonFollowOwnerFlying(rule,dragon,movementState);
			}
		}
	}
	else {
		if (dragon.typeId=="megaverse:fire_dragon") handleDragonFollowOwnerFlying(rule,dragon,movementState);
	}
};

function handleDragonFollowOwnerFlying(rule,dragon,movementState) {
	if (!dragon.hasComponent("minecraft:tameable")) return;
	const tameable = dragon.getComponent("minecraft:tameable");
	const followWanderState = dragon.getProperty("megaverse:follow_wander_state");
	const players = dragon.dimension.getPlayers();
	const owner = players.find(player=>player.id==tameable.tamedToPlayerId);
	if (owner instanceof Player) {
		const owner_riding = owner.getComponent("minecraft:riding");
		let owner_ride = owner;
		if (owner_riding) {
			owner_ride = owner_riding.entityRidingOn;
		}
		if (owner_riding&&!owner_ride.isOnGround||owner.isGliding||owner.isFlying) {
			if (followWanderState=="follow_on_air") {
				if (movementState!="air_controlled") dragon.triggerEvent("minecraft:dragon_air_controlled_movement");
				handleDragonFollowOwner(rule,dragon,owner);
				handleDragonLookWithFlying(dragon,owner,owner_riding,owner_ride);
			}
			if (followWanderState=="follow_on_ground") dragon.triggerEvent("minecraft:dragon_start_follow_owner_on_air");
			if (followWanderState=="wander"&&movementState!="on_ground") dragon.triggerEvent("minecraft:dragon_on_ground_movement");
		}
		else {
			if (movementState!="on_ground") dragon.triggerEvent("minecraft:dragon_on_ground_movement");
			if (followWanderState=="follow_on_air") dragon.triggerEvent("minecraft:dragon_start_follow_owner_on_ground");
		}
	}
};
function handleDragonFollowOwner(rule,dragon,owner) {
	const dragon_location = dragon.location;
	const target_location = owner.location;
	const offset_target_location = {
		x:target_location.x,
		y:target_location.y,
		z:target_location.z
	};
	const target_dx = offset_target_location.x-dragon_location.x;
	const target_dy = offset_target_location.y-dragon_location.y;
	const target_dz = offset_target_location.z-dragon_location.z;
	const target_distance = Math.sqrt(target_dx*target_dx+target_dy*target_dy+target_dz*target_dz);
	let base_impulse = 0.2;
	if (target_distance<15) base_impulse = 0.02;
	const distance_multiplier = Math.min(target_distance/10,5); 
	const impulse_strength = base_impulse*distance_multiplier;
	const impulse = {
		x: (target_dx/target_distance)*impulse_strength,
		y: (target_dy/target_distance)*impulse_strength,
		z: (target_dz/target_distance)*impulse_strength
	};
	dragon.applyImpulse(impulse);
};
function handleDragonLookWithFlying(dragon,owner,owner_riding,owner_ride) {
	const dragonPos = dragon.location;
	const targetLocation = owner.location;
	const dx = targetLocation.x-dragonPos.x;
	const dy = targetLocation.y-dragonPos.y;
	const dz = targetLocation.z-dragonPos.z;
	const yaw = Math.atan2(dz,dx)*(180/Math.PI)-90;
	const horizontalDistance = Math.sqrt(dx*dx+dz*dz);
	let pitch = -Math.atan2(dy,horizontalDistance)*(180/Math.PI);
	if (owner.isGliding||owner_riding) {
		pitch = owner_ride.getRotation().x;
	}
	dragon.setRotation({x:pitch,y:yaw});
};


function handleDraconFire(dragon,player,isRangedAttacking,isCooldown) {
	if (player.isJumping&&!isRangedAttacking&&!isCooldown) {
		dragon.triggerEvent("minecraft:dracon_spit_start");
	}
};
function handleDragonAttacks(data,dragon,ageVariant,player,attackState,isControlledAttacking,chargeAmount) {
	const dragonViewDir = dragon.getViewDirection();
	let dragonData,head_xz_view_offset=0,head_y_view_offset=0,bite_max_distance=0,bite_area_max_range=0,bite_end_time=0,bite_min_damage=0,bite_max_damage=0,bite_sound_definitions;
	if (ageVariant=="adult") dragonData = data.age_types.adult;
	if (ageVariant=="juvenile") dragonData = data.age_types.juvenile;
	head_xz_view_offset = dragonData.head_xz_view_offset;
	head_y_view_offset = dragonData.head_y_view_offset;
	bite_max_distance = dragonData.bite_max_distance;
	bite_area_max_range = dragonData.bite_area_max_range;
	bite_end_time = dragonData.bite_end_time;
	bite_min_damage = dragonData.bite_min_damage;
	bite_max_damage = dragonData.bite_max_damage;
	bite_sound_definitions = dragonData.bite_sound_definitions;
	const head_coords = mathUtilities.executeRotatedWithCaret(dragon,0,0,0,0,dragonViewDir.x*head_xz_view_offset,head_y_view_offset,dragonViewDir.z*head_xz_view_offset);
	const raycast_block = dragon.dimension.getBlockFromRay(head_coords,player.getViewDirection(),{includePassableBlocks:true,maxDistance:bite_max_distance});
	if (player.isJumping&&!isControlledAttacking) {
		if (raycast_block) {
			system.runTimeout(() => { 
				return dragon.setProperty("megaverse:attack_state","controlled"); 
			},bite_end_time*20);
			const adjusted_target_area = dragon.dimension.getBlock({...head_coords,y:head_coords.y-head_y_view_offset});
			handleDragonBite(dragon,adjusted_target_area,dragon.dimension,bite_area_max_range,bite_min_damage,bite_max_damage,bite_sound_definitions);
			return dragon.setProperty("megaverse:attack_state","controlled_melee");
		}
		else return dragon.setProperty("megaverse:attack_state","controlled_ranged");
	}
	else if (player.isJumping&&isControlledAttacking) return;
	else if (!player.isJumping&&attackState=="controlled_ranged") return dragon.setProperty("megaverse:attack_state","controlled");
};
export function handleDragonBite(dragon,target_area,dimension,bite_area_max_range,bite_min_damage,bite_max_damage,bite_sound_definitions) {
	const mobs = target_area.dimension.getEntities({families:["mob"],location:target_area.center(),maxDistance:bite_area_max_range});
	const players = target_area.dimension.getEntities({type:"player",location:target_area.center(),maxDistance:bite_area_max_range});
	const bite_damage = mathUtilities.randomInteger(bite_min_damage,bite_max_damage);
	const pitch_range = mathUtilities.randomInteger(bite_sound_definitions.pitch_range.min,bite_sound_definitions.pitch_range.max);
	dimension.playSound(bite_sound_definitions.name,dragon.location,{pitch:pitch_range,volume:bite_sound_definitions.volume});
	dimension.spawnParticle("megaverse:smoldering_fog",target_area.center());
	mobs.forEach((mob) => {
		mob.dimension.spawnParticle("megaverse:dracan_naphtha_impact",mob.location);
		mob.applyDamage(bite_damage,{damagingEntity:dragon,cause:EntityDamageCause.entityAttack});
	});
	players.forEach((player) => {
		player.dimension.spawnParticle("megaverse:dracan_naphtha_impact",player.location);
		player.applyDamage(bite_damage,{damagingEntity:dragon,cause:EntityDamageCause.entityAttack});
	});
};

function handleDragonInputControlForMovement(data,dragon,ageVariant,player,navigationState,isOnGround) {
	const movement = player.inputInfo.getMovementVector();
	if (!movement) return;
	let dragonData;
	if (ageVariant=="adult") dragonData = data.age_types.adult;
	if (ageVariant=="juvenile") dragonData = data.age_types.juvenile;
	const normalizedX = Math.abs(movement.x)>=dragonData.controlled_inputs.input_threshold?(movement.x>0?1:-1):0;
	const normalizedY = Math.abs(movement.y)>=dragonData.controlled_inputs.input_threshold?(movement.y>0?1:-1):0;
	const inputKey = `${normalizedX},${normalizedY}`;
	const inputType = dragonData.controlled_inputs.input_directions[inputKey];// ?? "noAcceleration";
	if (inputType=="none"&&navigationState!="none") return dragon.setProperty("megaverse:navigation_state","none");
	if (inputType=="forward"&&navigationState!="forward") return dragon.setProperty("megaverse:navigation_state","forward");
	if (inputType=="backward"&&navigationState!="backward") return dragon.setProperty("megaverse:navigation_state","backward");
	if (inputType=="left"&&navigationState!="left") return dragon.setProperty("megaverse:navigation_state","left");
	if (inputType=="right"&&navigationState!="right") return dragon.setProperty("megaverse:navigation_state","right");
	if (inputType=="forward_left"&&navigationState!="forward_left") return dragon.setProperty("megaverse:navigation_state","forward_left");
	if (inputType=="forward_right"&&navigationState!="forward_right") return dragon.setProperty("megaverse:navigation_state","forward_right");
	if (inputType=="backward_left"&&navigationState!="backward_left") return dragon.setProperty("megaverse:navigation_state","backward_left");
	if (inputType=="backward_right"&&navigationState!="backward_right") return dragon.setProperty("megaverse:navigation_state","backward_right");
};
function handleDragonPitchControl(rule,dragon,player,movementState,isOnGround,attackState,chargeAmount) {
	player.playAnimation("animation.megaverse.fire_dragon.rotations_rider",{stopExpression:"!q.is_riding||v.is_first_person"});
	const pitch = player.getRotation().x;
	let altitude = -dragon.getVelocity().y;
	if (pitch<-67.5) altitude = 0.06;
	if (pitch>=-67.5&&pitch<-22.5) altitude = 0.03;
	if (pitch>=35&&pitch<45&&!isOnGround) altitude = -0.03;
	if (pitch>=45&&pitch<67.5&&!isOnGround) altitude = -0.06;
	if (pitch>=67.5&&!isOnGround) altitude = -0.09;
	if (attackState!="controlled_ranged") {
		if (pitch<-22.5&&movementState!="air_controlled") dragon.triggerEvent("minecraft:dragon_air_controlled_movement");
		if (!isOnGround) {
			if (pitch>=-22.5&&pitch<=35&&movementState!="hover_controlled") dragon.triggerEvent("minecraft:dragon_hover_controlled_movement");
			if (pitch>35&&movementState!="air_controlled") dragon.triggerEvent("minecraft:dragon_air_controlled_movement");
		}
		else if (pitch>=-22.5&&movementState!="ground_controlled") dragon.triggerEvent("minecraft:dragon_ground_controlled_movement");
	}
	else {
		if (!isOnGround) {
			if (movementState!="hover_controlled") dragon.triggerEvent("minecraft:dragon_hover_controlled_movement");
			altitude = -dragon.getVelocity().y;
		}
		else {
			if (movementState!="ground_controlled") dragon.triggerEvent("minecraft:dragon_ground_controlled_movement");
			altitude = 0;
		}
	}
	player.onScreenDisplay.setActionBar({rawtext:[{translate:"action.interact.megaverse:charge"}, {text:": "},{text:`${Math.round(chargeAmount*100)/100}`},{text:"\n"},{translate:"action.interact.megaverse:on_ground"},{text:": "},{text:`${isOnGround}`},{text:"\n"},{translate:"action.interact.megaverse:altitude"},{text:": "},{text:`${altitude}`},{text:"\n"},{translate:"action.interact.megaverse:dragon_head"},{text:": "},{text:`${Math.round(dragon.getRotation().x*10)/10}`}]});
	//player.runCommand(`title @s actionbar V: ${message} Y: ${Math.round(dragon.getRotation().x*10)/10} C: ${Math.round(chargeAmount*100)/100}`);
	if (altitude!=0) return dragon.applyImpulse({x:0,y:altitude,z:0});
};
/* Note: Max Y Velocity for Dracon base is 0.6
player.sendMessage(`VC: ${Math.round(dragon.getVelocity().y*10)/10}`);

function lerp(a,b,t) {
	return a+(b-a)*t;
};*/
function handleArmBlockPositionWrap(data,dragon,ageVariant,isOnGround,side) {
	if (!isOnGround) return;
	const dragon_coords = dragon.location;
	let dragonData,arm_angle=0,arm_depth=0,arm_forward_offset=0,arm_side_offset=0;
	if (ageVariant=="adult") dragonData = data.age_types.adult;
	if (ageVariant=="juvenile") dragonData = data.age_types.juvenile;
	arm_angle = dragonData.arm_angle;
	arm_depth = dragonData.arm_depth;
	arm_forward_offset = dragonData.arm_forward_offset;
	const arm_multiplier = side=="left"?dragonData.left_arm_multiplier:side=="right"?dragonData.right_arm_multiplier:0;
	arm_side_offset = dragonData.arm_side_offset*arm_multiplier; 
	const target_start_coordinates = mathUtilities.executeRotatedWithCaret(dragon,0,arm_side_offset,arm_angle,arm_forward_offset,0,0,0);
	const downward_vector3 = {x: 0, y: -1, z: 0};
	const raycasted_block = dragon.dimension.getBlockFromRay(target_start_coordinates,downward_vector3,{includePassableBlocks:false,maxDistance:arm_depth});
	let block,far_enough,hit_location,new_arm_block_position;
	if (raycasted_block) {
		block = raycasted_block.block;
		far_enough = true;
		hit_location = {...block.location,y:block.location.y+0.98};
	}
	else {
		far_enough = false;
		hit_location = {...target_start_coordinates,y:target_start_coordinates.y-arm_depth};
	}
	if (far_enough) {
		new_arm_block_position = Math.round((target_start_coordinates.y)-hit_location.y);
	}
	else { new_arm_block_position = arm_depth; }
	dragon.setProperty(`megaverse:${side}_arm_block_position`,new_arm_block_position);
};
function handleLegBlockPositionWrap(data,dragon,ageVariant,isOnGround,side) {
	if (!isOnGround) return;
	const dragon_coords = dragon.location;
	let dragonData,leg_angle=0,leg_depth=0,leg_backward_offset=0,leg_side_offset=0,leg_y_offset=0;
	if (ageVariant=="adult") dragonData = data.age_types.adult;
	if (ageVariant=="juvenile") dragonData = data.age_types.juvenile;
	leg_angle = dragonData.leg_angle;
	leg_depth = dragonData.leg_depth;
	leg_backward_offset = dragonData.leg_backward_offset;
	const leg_multiplier = side=="left"?dragonData.left_leg_multiplier:side=="right"?dragonData.right_leg_multiplier:0;
	leg_side_offset = dragonData.leg_side_offset*leg_multiplier; 
	leg_y_offset = dragonData.leg_y_offset;
	const target_start_coordinates = mathUtilities.executeRotatedWithCaret(dragon,0,leg_side_offset,leg_angle,leg_backward_offset,0,leg_y_offset,0);
	const downward_vector3 = {x:0,y:-1,z:0};
	const raycasted_block = dragon.dimension.getBlockFromRay(target_start_coordinates,downward_vector3,{includePassableBlocks:false,maxDistance:leg_depth});
	let block,far_enough,hit_location,new_leg_block_position;
	if (raycasted_block) {
		block = raycasted_block.block;
		far_enough = true;
		hit_location = {...block.location,y:block.location.y+0.98};
	}
	else {
		far_enough = false;
		hit_location = {...target_start_coordinates,y:target_start_coordinates.y-leg_depth};
	}
	if (far_enough) {
		new_leg_block_position = Math.round((target_start_coordinates.y)-hit_location.y);
	}
	else { new_leg_block_position = leg_depth; }
	dragon.setProperty(`megaverse:${side}_leg_block_position`,new_leg_block_position);
};




function OldhandleDragonPitchControl(rule,dragon,player,navigationState,isOnGround,chargeAmount,isRangedAttacking,isCooldown) {
	player.playAnimation("animation.megaverse.dracon.rotations_rider",{stopExpression: "!q.is_riding||v.is_first_person"});
	const pitch = player.getRotation().x;
	let altitude = -dragon.getVelocity().y;
	let message = "Slow";
	if (pitch<-67.5) {
		altitude = 0.06;
		message = "Fast";
	}
	if (pitch>=-67.5&&pitch<-22.5) {
		altitude = 0.03;
		message = "Medium";
	}
	if (pitch>=35&&!isOnGround) {
		altitude = -0.03;
		message = "Glide";
	}
	if (!isRangedAttacking&&!isCooldown) {
		if (pitch<-22.5&&navigationState!="air_controlled") dragon.triggerEvent("minecraft:dragon_air_controlled");
		else if (pitch<35&&!isOnGround&&navigationState!="air_controlled") dragon.triggerEvent("minecraft:dragon_air_controlled");
		if (pitch>=35&&isOnGround&&navigationState!="grounded") dragon.triggerEvent("minecraft:dragon_grounded");
	}
	else {
		altitude = -dragon.getVelocity().y;
	}
	player.onScreenDisplay.setActionBar({rawtext:[{translate:"action.interact.megaverse:charge"}, {text:": "},{text:`${Math.round(chargeAmount*100)/100}`},{text:"\n"},{translate:"action.interact.megaverse:on_ground"},{text:": "},{text:`${isOnGround}`},{text:"\n"},{translate:"action.interact.megaverse:altitude"},{text:": "},{text:`${altitude}`},{text:"\n"},{translate:"action.interact.megaverse:dragon_head"},{text:": "},{text:`${Math.round(dragon.getRotation().x*10)/10}`}]});
	if (altitude!=0) return dragon.applyImpulse({x:0,y:altitude,z:0});
};
/*
function handleDragonInputControl(rule,dragon,player,navigationState,isOnGround) {
	const movement = player.inputInfo.getMovementVector();
	if (!movement) return;
	const normalizedX = Math.abs(movement.x) >= rule.threshold ? (movement.x > 0 ? 1 : -1) : 0;
	const normalizedY = Math.abs(movement.y) >= rule.threshold ? (movement.y > 0 ? 1 : -1) : 0;
	const inputKey = `${normalizedX},${normalizedY}`;
	const inputType = rule.inputDirections[inputKey] ?? "noAcceleration";
	const acceleration = rule[inputType]??0;
	// Get forward direction
	const forward = dragon.getViewDirection();
	// Calculate right vector (perpendicular to forward vector on XZ plane)
	const right = { x: forward.z, y: 0, z: -forward.x };
	// Calculate final direction vector from input
	let moveDir = { x: 0, y: 0, z: 0 };
	if (normalizedY !== 0) {
		moveDir.x += forward.x * normalizedY;
		moveDir.z += forward.z * normalizedY;
	}
	if (normalizedX !== 0) {
		moveDir.x += right.x * normalizedX;
		moveDir.z += right.z * normalizedX;
	}
	// Normalize moveDir to prevent faster diagonals
	const magnitude = Math.hypot(moveDir.x, moveDir.z);
	if (magnitude > 0) {
		moveDir.x /= magnitude;
		moveDir.z /= magnitude;
	}
	// Apply scale depending on ground status
	const scale = dragon.isInWater?rule.movementOnWater:isOnGround?rule.movementOnGround:rule.movementOnAir;
	// Final impulse
	dragon.applyImpulse({
		x: moveDir.x*acceleration*scale,
		y: 0,
		z: moveDir.z*acceleration*scale
	});
};
function handleDragonPitchControl(rule,dragon,player,movementState,isOnGround,attackState,chargeAmount) {
	player.playAnimation("animation.megaverse.dracon.rotations_rider",{stopExpression: "!q.is_riding||v.is_first_person"});
	const pitch = player.getRotation().x;
	let altitude = -dragon.getVelocity().y;
	let message = "Steady";
	if (pitch<-67.5) {
		altitude = 0.06;
		message = "Ascend Fast";
	}
	if (pitch>=-67.5&&pitch<-22.5) {
		altitude = 0.03;
		message = "Ascend Slow";
	}
	if (pitch>=35&&pitch<45&&!isOnGround) {
		altitude = -0.03;
		message = "Glide";
	}
	if (pitch>=45&&pitch<67.5&&!isOnGround) {
		altitude = -0.06;
		message = "Dive Slow";
	}
	if (pitch>=67.5&&!isOnGround) {
		altitude = -0.09;
		message = "Dive Fast";
	}
	if (attackState!="controlled_ranged") {
		if (pitch<-22.5&&movementState!="air_controlled") dragon.triggerEvent("minecraft:dragon_air_controlled_movement");
		else if (pitch>=-22.5&&pitch<=35&&!isOnGround&&movementState!="hover_controlled") dragon.triggerEvent("minecraft:dragon_hover_controlled_movement");
		if (pitch>35&&!isOnGround&&movementState!="air_controlled") dragon.triggerEvent("minecraft:dragon_air_controlled_movement");
		if (pitch>35&&isOnGround&&movementState!="ground_controlled") dragon.triggerEvent("minecraft:dragon_ground_controlled_movement");
	}
	else {
		if (!isOnGround&&movementState!="hover_controlled") dragon.triggerEvent("minecraft:dragon_hover_controlled_movement");
		altitude = -dragon.getVelocity().y;
	}
	player.onScreenDisplay.setActionBar({rawtext:[{translate:"action.interact.megaverse:fuel"}, {text:" "},{text:`${Math.round(chargeAmount*100)/100}`}, {text:" "},{text:`${movementState}`}]});
	//player.runCommand(`title @s actionbar V: ${message} Y: ${Math.round(dragon.getRotation().x*10)/10} C: ${Math.round(chargeAmount*100)/100}`);
	if (altitude!=0) return dragon.applyImpulse({x:0,y:altitude,z:0});
};
*/