using System.Collections.Generic; using BrewMonster; using BrewMonster.Scripts; using BrewMonster.Scripts.Extensions; using BrewMonster.UI; using CSNetwork.GPDataType; using TMPro; using UnityEngine; using UnityEngine.U2D; using UnityEngine.UI; namespace PerfectWorld.UI.MiniMap { public class CDlgMiniMap : AUIDialog { public struct MARK { public int nNPC; public string strName; public A3DVECTOR3 vecPos; public int mapID; // 地图ID // map ID (exposed for USER_LAYOUT save) public MARK(int nNPC, string strName, A3DVECTOR3 vecPos, int mapID) { this.nNPC = nNPC; this.strName = strName; this.vecPos = vecPos; this.mapID = mapID; } } [SerializeField] private Vector3 _debugHostPlayerPos; [SerializeField] private RectTransform _hostPlayerIcon; [SerializeField] private byte nRow, nCol; // number of rows and cols in the current map instances.txt [SerializeField] private TMP_Text txtHostPos; [SerializeField] private Image _imageMiniMapPrefab; [SerializeField] private List _listImageMiniMap = new(); [SerializeField] private RectTransform _transformMiniMapParent; // reference to unity sprite atlas [SerializeField] private SpriteAtlas _spriteAtlas; private List m_vecMark = new(); private List m_vecNPCMark = new(); private Dictionary m_TexMap = new(); private List _texToDelete = new(); // list of texture to delete from m_TexMap, use in update functions. private float m_fZoom = 1.0f; private bool m_bShowMark = true; private bool m_bShowTargetArrow = true; // map state private bool isShowMiniMap = true; CECHostPlayer m_pHostPlayer; Vector3Int _lastIntHostPos = Vector3Int.zero; private int m_nMode; // TODO: currently, there is only get logic, not set logic private void Awake() { LoadAllMiniMapTextures(); } void Update() { UpdateMiniMap(); } /// /// We keep the player icon at the center of the minimap. Then we update the position of the map itself. /// TODO: We have to keep track of the NPC icons on the map also. /// private void UpdateMiniMap() { m_pHostPlayer = GetHostPlayer(); if (m_pHostPlayer == null) return; // TODO: This should be the position of the host player, not hardcoded. Transform hostTransform = m_pHostPlayer.transform; Vector3 vecPosHost = hostTransform.position; Vector3Int currentIntHostPos = new Vector3Int(Mathf.RoundToInt(vecPosHost.x) / 10 + 400, Mathf.RoundToInt(vecPosHost.y) / 10, Mathf.RoundToInt(vecPosHost.z) / 10 + 550); if (currentIntHostPos != _lastIntHostPos) { txtHostPos.text = $"{currentIntHostPos.x}, {currentIntHostPos.z}, ↑{currentIntHostPos.y}"; _lastIntHostPos = currentIntHostPos; } Vector2 hostPlayerPos = new Vector2(vecPosHost.x / 2, vecPosHost.z / 2); _transformMiniMapParent.anchoredPosition = -hostPlayerPos; _hostPlayerIcon.localRotation = Quaternion.Euler(0, 0, -hostTransform.localRotation.eulerAngles.y); } /// /// Get the Host Player instance. /// /// private CECHostPlayer GetHostPlayer() { return CECGameRun.Instance.GetHostPlayer(); } // change radar mode public int GetMode() { return m_nMode; } /// Returns the list of user-placed marks on the minimap (for layout save/load). public List GetMarks() => m_vecMark; // keep this so we can load all textures of other map also. [ContextMenu("LoadAllMiniMapTextures")] public void LoadAllMiniMapTextures() { // delete all images in parent foreach(Transform child in _transformMiniMapParent) { Destroy(child.gameObject); } Sprite pSprite = null; for(int r = 0; r < nRow + 3; r++) { for(int c = 0; c < nCol + 3; c++) { string strIndex = $"{r:D2}{c:D2}"; pSprite = _spriteAtlas.GetSprite(strIndex); var image = Instantiate(_imageMiniMapPrefab, _transformMiniMapParent); image.sprite = pSprite; image.name = strIndex; image.gameObject.SetActive(true); } } } // this is for debuging/testing while this feature was in development [ContextMenu("MoveHostPlayerIconToPos")] public void MoveHostPlayerIconToPos() { Vector2 hostPlayerPos = new Vector2(_debugHostPlayerPos.x / 2, _debugHostPlayerPos.z / 2); _transformMiniMapParent.anchoredPosition = -hostPlayerPos; } } }