import { _decorator, Vec3,Node, geometry, PhysicsSystem, PhysicsRayResult} from 'cc';
import { PoolManager } from '../../core/manager/PoolManager';
import { Game } from '../../game/Game';
import { Enemy, EPartType } from '../../game/Enemy';
import { Gun3 } from './Gun3';
import { BulletBase } from '../base/BulletBase';
import { GunBase } from '../base/GunBase';
import { Sundries } from '../../game/Sundries';
const { ccclass, property } = _decorator;

//玩家所用子弹 连狙子弹
@ccclass('Bullet3')
export class Bullet3 extends BulletBase {
    //是否必死 必死的子弹不会回收 要自己控制
    private isRemoveDead: boolean = false;
    //射击方向的位置
    private vector: Vec3 = null;

    /**
     * 初始化一个子弹
     */
    /**
     * 初始化一个子弹
     * @param gun 属于哪把枪
     * @param isRemoveDead 是否不受控制的子弹自己管理
     */
    public init(gun:GunBase,isRemoveDead:boolean = true){
        this.gunBase = gun;
        this.isDead = false;
        this.isRemoveDead = isRemoveDead;
    }

    /**
     * 设置子弹开始位置和射击方向
     * @param v 射向的方向
     */
    public setBulletVector(v: Vec3){
        const bulletSpeed = this.gunBase.data.bulletSpeed / 3;
        this.vector = v.clone().multiplyScalar(bulletSpeed);
        this.node.forward = v;
        this.rayPreCheck(bulletSpeed / 60);
    }

    /**
     * 射击速度发生改变
     */
    public speedChange() {
        const bulletSpeed = this.gunBase.data.bulletSpeed;
        if(this.vector) {
           this.vector = this.vector.normalize().multiplyScalar(bulletSpeed);
        }
    }
    /**
     * 实时帧更新
     */
    public update(deltaTime: number) {
        if(Game.I.isGameOver 
            || Game.I.isPause) {
            this.isDead = true;
            PoolManager.putNode(this.node);
            return;
        }
        if(this.vector) {
            const moveDelta = this.vector.clone().multiplyScalar(deltaTime);
            this.node.worldPosition = this.node.worldPosition.add(moveDelta);
            this.rayPreCheck(moveDelta.length());
        }
    }

    /**
     * 检测射击
     * @param b 
     * @param len 检测
     */
    private rayPreCheck(len: number) {
        const p = this.node.worldPosition;
        const ray = geometry.Ray.create(p.x, p.y, p.z, this.vector.x, this.vector.y, this.vector.z);
        const phy:PhysicsSystem = PhysicsSystem.instance;
        const isHit = phy.raycast(ray, 0xffffff, len);
        if (isHit && phy.raycastResults.length > 0) {
            //先查找 要检测的物体 对象上带args参数的就是优先检测的
            let targetResult: PhysicsRayResult | null = null;
            for (const result of phy.raycastResults) {
                if (result.collider["args"]) {
                    targetResult = result;
                    break;
                }
            }
            targetResult = targetResult ?? phy.raycastResults[0];
            //targetResult.collider.getComponent(RigidBody).applyForce(this.vector, targetResult.hitPoint); 
            this.addHitImpact(targetResult);
            const args:any = targetResult.collider["args"];
            if(args){
                let [type,cls] = args;
                let attack: number = this.gunBase.data.attack;
                if(cls instanceof Enemy){
                    const e: Enemy = cls as Enemy;
                    //爆头击杀
                    let isHeadShot:boolean = false;
                    if(type == EPartType.head){
                        Game.I.player.headShotNum += 1;
                        attack = Game.I.player.pData.headshotDmgMul * attack;
                        isHeadShot = true;
                    }
                    //打到了盾兵上的盾
                    if(type == EPartType.shield 
                        && e.shieldHp > 0){
                        e.shieldHp -= attack;
                        return;
                    }
                    //坦克是单独的碰撞体
                    if(e.isTank()){
                        if(type == EPartType.tank){
                        e.subHP(attack,this.gunBase.data,false);
                        }
                    }else{
                        e.subHP(attack,this.gunBase.data,isHeadShot);
                    }
                }else if(cls instanceof Sundries){
                    const sundrie: Sundries = cls as Sundries;
                    sundrie.subHP(attack,this.gunBase.data);
                }
            }
            //自动回收了子弹
            this.autoRecycle();
        }
    }
}