const ClipContext = Java.loadClass("net.minecraft.world.level.ClipContext")

function calculateViewVector(xRot, yRot) {
    let f = xRot * JavaMath.PI / 180.0;
    let f1 = -yRot * JavaMath.PI / 180.0;
    let f2 = JavaMath.cos(f1);
    let f3 = JavaMath.sin(f1);
    let f4 = JavaMath.cos(f);
    let f5 = JavaMath.sin(f);
    return new Vec3(f3 * f4, -f5, f2 * f4);
}


function rayTrace(entity, distance) {
    let eyePos = entity.getEyePosition(1)
    // let viewVec = entity.getViewVector(1);
    // let viewVec = calculateViewVector(0, entity.getViewYRot(1));
    let viewVec = entity.motionDirection.normal;

    let endVec = eyePos.add(viewVec.x * distance, viewVec.y * distance, viewVec.z * distance);
    return entity.level.clip(new ClipContext(eyePos, endVec, "outline", "none", entity));
}


(function () {
    let ClientboundSetEntityMotionPacket = Java.loadClass('net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket');


StartupEvents.registry('palladium:abilities', (event) => {

    event.create('heroes:wall_climb')

        .icon(palladium.createItemIcon('palladium:vibranium_circuit'))

        .addProperty('climb_speed', 'float', 0.1, 'Duh.')
		.addProperty("data_name", "string", "heroes_climb", "Persistent data used")


		.firstTick((entity, entry, holder, enabled) => {
				if (enabled) {
				entity.server.runCommandSilent("execute as " + entity.uuid + " at @s run scoreboard players set @s Heroes.WallClimb 1");

					}
					})
					
		.lastTick((entity, entry, holder, enabled) => {
				if (enabled) {
					let data_name = entry.getPropertyByName('data_name');
					entity.persistentData[data_name] = 0;
					}
					})
					
        .tick((entity, entry, holder, enabled) => {
            if (enabled) {
				let climb_speed = entry.getPropertyByName('climb_speed');
				let data_name = entry.getPropertyByName('data_name');
		let head_rotation = entity.pitch	
        let level = entity.serverLevel()
		entity.persistentData[data_name] = 0;
		
		
	
				
			let raytrace_block = rayTrace(entity, 1)
			if (raytrace_block.type !== "miss") {
			let currentPosup = new BlockPos(raytrace_block.blockPos);
				
            let blockState = level.getBlock(currentPosup).blockState;
            if (blockState.isCollisionShapeFullBlock(level, currentPosup)) {
				entity.setMotion(0, 0, 0);
				entity.persistentData[data_name] = 1;
				
				if (head_rotation <= -70 && head_rotation >= -90) {
					entity.persistentData[data_name] = 4;
				entity.setMotion(0, climb_speed, 0);
				}
				if (head_rotation <= 90 && head_rotation >= 70) {
					entity.persistentData[data_name] = 4;
				entity.setMotion(0, (climb_speed * -1), 0);
					}
				entity.connection.send(new ClientboundSetEntityMotionPacket(entity));
						}
				}
			}

        })
});
})();

function containsTag(tags, tag) {
    for (let i = 0; i < tags.length; i++) {
        if(tags[i].equals(tag)) {
            return true;
        }
    }
    return false;
}
