﻿/**
* MyClearRadar 简单好用的雷达显示
* 反馈帖: https://forum.ark.online/forum.php?mod=viewthread&tid=1711
* 版本：v0.1.2 2023.10.30 代码升级为027
* 作者：guangqi.hu
*/

import MyClearCamp from "./MyClearCamp";

class RadarUI extends UIScript {

    public CutCanvas: Canvas = undefined;
    public RadarCanvas: Canvas = undefined;

    public MyPlayer: Player = undefined;

    public Map_Player_Point: Map<Player, TextBlock> = new Map();

    onAwake() {

        this.MyPlayer = Player.localPlayer;
        let WindowSize = WindowUtil.getViewportSize();

        this.rootCanvas.zOrder = -20;
        this.rootCanvas.size = WindowSize;
        this.rootCanvas.zOrder = UILayerTop;
        let _margin = new Margin(0);


        /**外框裁剪容器 */
        this.CutCanvas = Canvas.newObject(this.rootCanvas, "MyCanvas");
        this.CutCanvas.size = new Vector2(400, 400);
        this.CutCanvas.zOrder = 2;
        this.CutCanvas.autoLayoutRule = new UILayout(0, _margin, UILayoutType.Vertical, UILayoutPacket.CenterCenter, new UIHugContent(0, 0), true, false);
        this.CutCanvas.clipEnable = true;

        /**雷达背景图片 */
        let bgp = Image.newObject(this.rootCanvas, "bgp")
        bgp.imageGuid = "86650"
        bgp.imageColor = LinearColor.black;
        bgp.renderOpacity = 0.2;
        bgp.size = this.CutCanvas.size.clone();

        /**中心点图片 */
        let selfImage = Image.newObject(this.rootCanvas, "selfImage");
        selfImage.imageGuid = "114066"
        selfImage.size = new Vector2(64, 64);
        selfImage.zOrder = 1

        /**雷达图谱容器 */
        this.RadarCanvas = Canvas.newObject(this.rootCanvas, "RadarCanvas");
        this.RadarCanvas.size = this.CutCanvas.size.clone();
        this.RadarCanvas.position = Vector2.zero;
        this.CutCanvas.addChild(this.RadarCanvas);

        setInterval(() => {

            WindowSize = WindowUtil.getViewportSize();
            this.CutCanvas.position = new Vector2((WindowSize.clone().x * 0.5) - 305 - this.CutCanvas.size.x, 1);
            // this.CutCanvas.position = new Vector2(WindowSize.x - this.CutCanvas.size.x - 10, 10);
            bgp.position = this.CutCanvas.position
            selfImage.position = this.CutCanvas.position.add(this.CutCanvas.size.clone().multiply(0.5).clone().subtract(selfImage.size.clone().multiply(0.5)));

            this.RadarCanvas.renderTransformAngle = -1 * Camera.currentCamera.worldTransform.rotation.z;

            Player.getAllPlayers().forEach((otherPlayer: Player) => {

                if (otherPlayer != this.MyPlayer) {
                    if (this.Map_Player_Point.get(otherPlayer)) {
                        let otherPlayerPoint = this.Map_Player_Point.get(otherPlayer);

                        if (otherPlayer.character.ragdollEnabled) {
                            otherPlayerPoint.text = "×";
                            if (MyClearRadar.instance.isFriendly(this.MyPlayer, otherPlayer)) {
                                otherPlayerPoint.fontColor = LinearColor.green;
                                otherPlayerPoint.visibility = 0;
                            } else {
                                otherPlayerPoint.visibility = 0;
                                otherPlayerPoint.fontColor = LinearColor.red;
                            }
                        }
                        else {
                            otherPlayerPoint.text = "◆";
                            if (MyClearRadar.instance.isFriendly(this.MyPlayer, otherPlayer)) {
                                otherPlayerPoint.fontColor = LinearColor.green;
                                otherPlayerPoint.visibility = 0;
                            } else {
                                otherPlayerPoint.fontColor = LinearColor.red;
                                if (MyClearRadar.instance.Map_Player_Expose_Temp.get(otherPlayer)) {
                                    otherPlayerPoint.visibility = 0;
                                }
                                else {
                                    otherPlayerPoint.visibility = 1;
                                }
                            }
                        }
                        otherPlayerPoint.position = MyClearRadar.instance.Loc2RadarPos(otherPlayer.character.worldTransform.position);
                        // let deltaVector = otherPlayer.character.worldLocation.clone().subtract(this.MyPlayer.character.worldLocation.clone()).multiply(new Vector(0.1, 0.1, 0)).multiply(MyClearRadar.instance.MapScalRate);
                        // let deltaVector2 = new Vector2(deltaVector.clone().y, -1 * deltaVector.clone().x);
                        // otherPlayerPoint.position = this.RadarCanvas.size.clone().multiply(0.5).clone().subtract(new Vector2(5, 16)).add(deltaVector2);
                    }
                    else {
                        let otherPlayerPoint = TextBlock.newObject(this.rootCanvas, otherPlayer.userId)
                        otherPlayerPoint.fontSize = 32;
                        otherPlayerPoint.text = ""
                        otherPlayerPoint.outlineColor = LinearColor.black;
                        otherPlayerPoint.zOrder = 1
                        otherPlayerPoint.outlineSize = 1
                        otherPlayerPoint.fontColor = LinearColor.green;
                        otherPlayerPoint.textHorizontalLayout = 2;
                        otherPlayerPoint.textJustification = 0;
                        otherPlayerPoint.textVerticalJustification = 0;
                        otherPlayerPoint.textAlign = 0;
                        otherPlayerPoint.textVerticalAlign = 0;
                        otherPlayerPoint.size = new Vector2(32, 32);
                        otherPlayerPoint.visibility = 1;
                        this.RadarCanvas.addChild(otherPlayerPoint);
                        this.Map_Player_Point.set(otherPlayer, otherPlayerPoint);
                    }
                }
            })
        }, 100)

        Player.onPlayerLeave.add((otherPlayer: Player) => {
            if (this.Map_Player_Point.get(otherPlayer)) {
                this.Map_Player_Point.get(otherPlayer).destroyObject();
            }
            this.Map_Player_Point.delete(otherPlayer);
        })


    }
}

@Component
export default class MyClearRadar extends mw.Script {

    /**雷达缩放比，比例越小，可以看得越远 */
    public MapScalRate: number = 0.35;

    public static instance: MyClearRadar;

    public radarUI: RadarUI = undefined;

    public Map_Player_Expose_Temp: Map<Player, number> = new Map();

    /** 当脚本被实例后，会在第一帧更新前调用此函数 */
    protected onStart(): void {
        MyClearRadar.instance = this;

        this.radarUI = UIService.create(RadarUI)
        UIService.showUI(this.radarUI);

        Event.addClientListener("exposeSelf", (_exposedPlayer: Player) => {
            Player.getAllPlayers().forEach((player) => {
                this.exposePlayer(player, _exposedPlayer);
            })
        })
    }

    /**检测是否为友方 */
    public isFriendly(player1: Player, player2: Player): boolean {
        return MyClearCamp.instance.isFriendly(player1.userId, player2.userId);
    }

    /**向指定玩家在雷达上暴露一个玩家，无论敌我
     * @param Targetplayer 需要暴露的玩家 
     * @param exposeTime 需要暴露的时间，秒，不填则为3秒，新的会把旧的顶掉
     */
    @RemoteFunction(mw.Client)
    public exposePlayer(player: Player, Targetplayer: Player, exposeTime?: number) {
        if (exposeTime == undefined) {
            exposeTime = 3;
        }
        exposeTime *= 1000;

        if (this.Map_Player_Expose_Temp.get(Targetplayer)) {
            clearTimeout(this.Map_Player_Expose_Temp.get(Targetplayer));
            this.Map_Player_Expose_Temp.delete(Targetplayer);
        }

        let exposeTimeout = setTimeout(() => {
            this.Map_Player_Expose_Temp.delete(Targetplayer);
        }, exposeTime);

        this.Map_Player_Expose_Temp.set(Targetplayer, exposeTimeout);
    }

    /**将世界loc转换成与自己相对的雷达位置 */
    public Loc2RadarPos(loc: Vector): Vector2 {
        let deltaVector = loc.clone().subtract(this.radarUI.MyPlayer.character.worldTransform.position.clone()).multiply(new Vector(0.1, 0.1, 0)).multiply(MyClearRadar.instance.MapScalRate);
        let deltaVector2 = new Vector2(deltaVector.clone().y, -1 * deltaVector.clone().x);
        let pos = this.radarUI.RadarCanvas.size.clone().multiply(0.5).clone().subtract(new Vector2(5, 16)).add(deltaVector2);
        return pos;
    }

}