// Script to make flyers fly
// Author: InnerTri

// Imports
// Important Global Variables
import { world } from "@minecraft/server";

// function to make flyers fly (if they should)
// checks for a valid flyer (ridden and being told to ascend),
// and if one is found, adds constant upwards impulse
// fliers are designated by the cyn:flyer family

// NOTE that this also relies on the flyer behavior animation controllers
// to give flyers slow fall, tweaked flight speeds, etc.

// TODO It seems like if two players are on two fliers,
// only one can ascend at a time
// if A presses space, and then B presses space,
// nothing will happen for B
export function flyerFlight() {

	// go through all players
	// note that this list can be empty
	for (let player of world.getAllPlayers()) {
		// prepare to select flyers that are very near to the current player
		let eqo = {
			families: [ "cyn:flyer" ],
			location: player.location,
			maxDistance: 4
		}

		for (let flyer of player.dimension.getEntities(eqo)) {
			// if the flyer is tamed
			if (flyer.hasComponent("minecraft:is_tamed")) {
				// if the flyer CAN BE ridden
				let rideableComponent = flyer.getComponent("minecraft:rideable");
				if (rideableComponent != undefined) {
					// if the flyer IS BEING ridden by the player
					let playerSeat = rideableComponent.getRiders().indexOf(player);
					if (playerSeat > -1) {
						// if the current player is jumping
						if (player.isJumping) {

							// check flyer water state
							// if this flyer is in the water
							if (flyer.isInWater == true) {
								// if this flyer can "fly" in the water
								if (
									(flyer.getProperty("cyn:flyer_water") !== undefined) && 
									(flyer.getProperty("cyn:flyer_water") !== false)
								) 
								{
									// make this flyer go up
									flyer.applyImpulse({ x: 0, y: 0.1, z: 0 });
								}

								// if the flyer is in the water,
								// but not allowed to fly in the water,
								// then do nothing
								return;
							}
							


							// this must be done after all other states!
							// otherwise a flyer who is not allowed to fly
							// in the water, would be able to do so
							// since being in the water IS technically
							// NOT being on the ground!

							// Note that any un-specified fluids like
							// lava... I guess just lava but also any 
							// added ones will be fly-able-in,
							// since like aforementioned,
							// being in lava is NOT being on the ground

							// could do a block-volume check to verify that the flyer
							// is in air (and nothing but), but doesn't seem
							// currently necessary

							// check flyer ground state
							// if this flyer is not on the ground
							if (flyer.isOnGround == false) {
								// if this flyer can fly in the air
								if (
									(flyer.getProperty("cyn:flyer_air") !== undefined) && 
									(flyer.getProperty("cyn:flyer_air") !== false)
								) 
								{
									// make this flyer go up
									flyer.applyImpulse({ x: 0, y: 0.1, z: 0 });
								}

								// if the flyer is in the air,
								// but not allowed to fly in the air,
								// then do nothing
								return;
							}
						}
					}
				}
			}		
		}
	}
}