/*
 * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
 *
 * Copyright (c) 2015 - 2026 CCBlueX
 *
 * LiquidBounce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * LiquidBounce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
 */

package net.ccbluex.liquidbounce.features.module.modules.movement.speed.modes.grim

import net.ccbluex.liquidbounce.config.types.group.Mode
import net.ccbluex.liquidbounce.config.types.group.ModeValueGroup
import net.ccbluex.liquidbounce.event.events.PlayerTickEvent
import net.ccbluex.liquidbounce.event.handler
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.decoration.ArmorStand
import net.minecraft.world.phys.Vec2
import kotlin.math.cos
import kotlin.math.sin

class SpeedGrimCollide(override val parent: ModeValueGroup<*>) : Mode("GrimCollide") {

    private val speed by float("BoostSpeed", 0.08F, 0.01F..0.08F, "b/t")

    /**
     * 0.5f shrink box can bypass newest versions of GrimAC (e.g., 2.3.73)
     * 1f shrink box can bypass older GrimAC versions
     */

    private val shrinkBox by float("ShrinkBox", 0.5f, 0.1f..2f)

    /**
     * Grim Collide mode for the Speed module.
     * The simulation when colliding with another player basically gives lenience.
     *
     * We can exploit this by increasing our speed by
     * 0.08 when we collide with any entity.
     *
     * This only works on client version being 1.9+.
     */
    @Suppress("unused")
    private val tickHandler = handler<PlayerTickEvent> {
        if (player.input.moveVector == Vec2.ZERO) {
            return@handler
        }

        val box = player.boundingBox.inflate(shrinkBox.toDouble())

        val collisions = world.getEntities(player, box) { entity ->
            entity is LivingEntity && entity !is ArmorStand
        }.count {
            box.intersects(it.boundingBox)
        }

        // Grim gives 0.08 leniency per entity which is customizable by speed.
        val yaw = Math.toRadians(player.yRot.toDouble())
        val boost = this.speed * collisions
        player.push(-sin(yaw) * boost, 0.0, cos(yaw) * boost)
    }

}
