You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
863 lines
29 KiB
863 lines
29 KiB
using DG.Tweening; |
|
using LitJson; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using UnityEngine; |
|
using UnityEngine.AI; |
|
using UnityEngine.Events; |
|
using UnityEngine.Serialization; |
|
|
|
public delegate bool ItemUse(string idx, int value); |
|
public delegate bool HoldingItemCheck(string idx); |
|
|
|
[System.Serializable] |
|
public class ItemUseRegister |
|
{ |
|
public ItemUse OnItemUse; |
|
public System.Action<MapDoor.Teleport> OnTeleport; |
|
public System.Action<bool> OnLock; |
|
} |
|
|
|
public enum MapEvent { DoorNearSave, DoorConnect, DoorState, DoorInit, Register_OnItemUse } |
|
public enum MapDirection { Left, Right, Down, Up } |
|
public enum DoorType { Door, DoorBreak, DoorLock, Wall, WallBreak, Boss } |
|
|
|
|
|
public class MapManager : ResourcePool |
|
{ |
|
public Transform targetCamera; |
|
[Space(10)] |
|
public TiltCamera tiltCamera; |
|
[Space(10)] |
|
public SoundPlayer_BGM spBGM; |
|
[Space(10)] |
|
public InputController prefabPlayer; |
|
public Vector3 scaleCharacter = new Vector3(1.3f, 1.3f, 1.3f); |
|
[HideInInspector] |
|
public InputController player; |
|
public bool START_ENTER = true; |
|
private void Start() |
|
{ |
|
QualitySettings.vSyncCount = 0; |
|
//Application.targetFrameRate = 60; |
|
|
|
items_Passive = DataManager.Instance.dataItem.ListGet().FindAll(a => a.type.Equals("Passive")); |
|
items_Active = DataManager.Instance.dataItem.ListGet().FindAll(a => a.type.Equals("Active")); |
|
items_Weapon = DataManager.Instance.dataItem.ListGet().FindAll(a => a.type.Equals("Weapon")); |
|
items_Armor = DataManager.Instance.dataItem.ListGet().FindAll(a => a.type.Equals("Armor")); |
|
items_Accessory = DataManager.Instance.dataItem.ListGet().FindAll(a => a.type.Equals("Accessory")); |
|
items_Use = DataManager.Instance.dataItem.ListGet().FindAll(a => a.type.Equals("Use") || a.type.Equals("Pickup")); |
|
|
|
items_All = new List<ItemData>(); |
|
items_All.AddRange(items_Passive); |
|
items_All.AddRange(items_Active); |
|
items_All.AddRange(items_Weapon); |
|
items_All.AddRange(items_Armor); |
|
items_All.AddRange(items_Accessory); |
|
|
|
EventManager.Instance.Add("PrefabCreate", PrefabCreate); |
|
EventManager.Instance.Add("PrefabCreateLocal", PrefabCreateLocal); |
|
|
|
EventManager.Instance.Add("IngameCommand", IngameCommand); |
|
|
|
if (START_ENTER) |
|
DungeonEnter("Proto"); |
|
} |
|
|
|
Dictionary<MapTile.Type, List<Material>> dicMaterials = new Dictionary<MapTile.Type, List<Material>>(); |
|
void MaterialLoad(string dungeonName) |
|
{ |
|
List<Material> materials = Resources.LoadAll<Material>($"Prefab/Map/{dungeonName}/Material").ToList(); |
|
dicMaterials.Clear(); |
|
int max = Util.EnumUtil<MapTile.Type>.Length(); |
|
for (int i = 0; i < max; i++) |
|
dicMaterials.Add((MapTile.Type)i, materials.FindAll(a => a.name.Contains($"{(MapTile.Type)i}"))); |
|
|
|
} |
|
public Dictionary<MapTile.Type, List<Material>> MaterialGet(string dungeonName) |
|
{ |
|
if (dicMaterials.Count == 0 || this.dungeonName != dungeonName) |
|
MaterialLoad(this.dungeonName = dungeonName); |
|
|
|
return dicMaterials; |
|
} |
|
|
|
List<GameObject> obstacles = new List<GameObject>(); |
|
void ObstacleLoad(string dungeonName) |
|
{ |
|
obstacles = Resources.LoadAll<GameObject>($"Prefab/Map/{dungeonName}/Obstacle").ToList(); |
|
} |
|
public List<GameObject> ObstacleGet(string dungeonName) |
|
{ |
|
if (obstacles.Count == 0 || this.dungeonName != dungeonName) |
|
ObstacleLoad(dungeonName); |
|
|
|
return obstacles; |
|
} |
|
|
|
private void OnDestroy() |
|
{ |
|
EventManager.Instance.Remove("PrefabCreate", PrefabCreate); |
|
EventManager.Instance.Remove("PrefabCreateLocal", PrefabCreateLocal); |
|
|
|
EventManager.Instance.Remove("IngameCommand", IngameCommand); |
|
} |
|
void PrefabCreate(object value) |
|
{ |
|
EventManager.ObjectCreate data = (EventManager.ObjectCreate)value; |
|
data.create = ObjectCreate(data.prefab, data.target, data.scale, data.pos, true); |
|
} |
|
void PrefabCreateLocal(object value) |
|
{ |
|
EventManager.ObjectCreate data = (EventManager.ObjectCreate)value; |
|
data.create = ObjectCreateLocalPos(data.prefab, data.target, data.scale, data.pos, true); |
|
} |
|
|
|
static public List<Vector2> dirs = new List<Vector2>() { new Vector2(-1, 0), new Vector2(1, 0), new Vector2(0, -1), new Vector2(0, 1) }; |
|
List<Vector2> dirsRandom; |
|
/// <summary> |
|
/// 다음에 생성 될 좌표의 목록을 생성합니다. |
|
/// </summary> |
|
void DirectionIndex(bool INIT, bool SHUFFLE) |
|
{ |
|
if (INIT) |
|
{ |
|
dirsRandom = new List<Vector2>(); |
|
for (int i = 0; i < 5; i++) |
|
dirsRandom.AddRange(dirs); |
|
} |
|
|
|
if (SHUFFLE) |
|
dirsRandom = Util.ListShuffle<Vector2>.Shuffle(dirsRandom); |
|
} |
|
/// <summary> |
|
/// 좌표 주변에 생성 가능한 좌표가 있는지 확인 |
|
/// </summary> |
|
/// <param name="idx"></param> |
|
/// <param name="cntMax"></param> |
|
/// <returns></returns> |
|
bool DirectionCheck(Vector2 idx, int cntMax) |
|
{ |
|
//cntMax = cntMax < 4 ? cntMax : 4; |
|
|
|
int cnt = -1; |
|
for(int i = 0; i < dirs.Count; i++) |
|
cnt += idxsDic.ContainsKey(idx + dirs[i]) ? 1 : 0; |
|
|
|
return cnt < cntMax; |
|
} |
|
[Space(10)] |
|
public Vector2 idxMin = new Vector2(-4, -3); |
|
public Vector2 idxMax = new Vector2(4, 3); |
|
/// <summary> |
|
/// 맵의 생성 범위 내의 좌표인지를 확인합니다. |
|
/// </summary> |
|
/// <param name="idx"></param> |
|
/// <returns></returns> |
|
public bool CheckIndexRange(Vector2 idx) |
|
{ |
|
return (idxMin.x <= idx.x && idx.x <= idxMax.x) && (idxMin.y <= idx.y && idx.y <= idxMax.y); |
|
} |
|
|
|
EventConnect ecMapEvent = new EventConnect(); |
|
[Space(10)] |
|
public string dungeonName = "Proto"; |
|
public DataDungeon dataDungeon; |
|
public int floor = 0;//현재 층 |
|
public FloorData floorData = new FloorData(); |
|
/// <summary> |
|
/// 던전 진입, 해당 던전의 정보 및 1층의 블럭 생성 |
|
/// </summary> |
|
/// <param name="name">던전 이름</param> |
|
public void DungeonEnter(string name) |
|
{ |
|
dungeonName = name; |
|
floor = 0; |
|
dataDungeon = DataManager.Instance.dataDungeon.Load(dungeonName); |
|
|
|
Generate_Block();//던전 입장 |
|
} |
|
/// <summary> |
|
/// 던전을 1층 내려갑니다. |
|
/// </summary> |
|
void FloorGoDown() |
|
{ |
|
Fade.DOFade(1, 0.25f).SetEase(Ease.Linear).OnComplete(() => |
|
{ |
|
Generate_Block();//층 내려감 |
|
}); |
|
} |
|
/// <summary> |
|
/// 아래층이 존재하는지 확인합니다, |
|
/// </summary> |
|
/// <param name="goDOWN"></param> |
|
/// <returns></returns> |
|
bool FloorCheck(bool goDOWN = true) |
|
{ |
|
floor += goDOWN ? 1 : 0; |
|
return floor < dataDungeon.floors.Count; |
|
} |
|
|
|
[Space(10)] |
|
public GameObject effectPortal; |
|
//[Space(10)] |
|
//public HPBarBoss barBoss; |
|
//public void BossMonsterAppear(Character boss) |
|
//{ |
|
// barBoss.Setting(boss); |
|
//} |
|
|
|
[System.Serializable] |
|
public class MapInitializedEvent : UnityEvent<MapManager> { } |
|
[FormerlySerializedAs("onMapInitialized")] |
|
[Space(10)] |
|
[SerializeField] |
|
private MapInitializedEvent OnMapInitialized = new MapInitializedEvent(); |
|
public HoldingItemCheck OnHoldingItemCheck; |
|
|
|
public Dictionary<Vector2, MapBlock> blocks = new Dictionary<Vector2, MapBlock>(); |
|
[Space(10)] |
|
public CanvasGroup Fade; |
|
/// <summary> |
|
/// 맵의 생성을 시작합니다. |
|
/// </summary> |
|
public void Generate_Block(string thema = "Proto") |
|
{ |
|
floorData = dataDungeon.floors[floor]; |
|
floorData.LoadAll($"{thema}"); |
|
ecMapEvent.Invoke((int)MapEvent.DoorInit, null); |
|
|
|
blkCurrent = null; |
|
blocks.Clear(); |
|
ecMapEvent.Clear(); |
|
ObjectAllHide(); |
|
|
|
DirectionIndex(true, false); |
|
|
|
Generate_IndexAll(); |
|
|
|
int cnt = 0; |
|
//일반 블럭 생성 |
|
List<MapBlock.Type> types_Default = floorData.DefaultTypeGet(); |
|
for (int i = 0; i < all.Count; i++) |
|
BlockCreate(all[i], i * 10, types_Default, ref cnt); |
|
|
|
//특수 블럭 생성 |
|
MapBlock blk = null; |
|
List<MapBlock.Type> specials = floorData.SpecialTypeGet(); |
|
if (0 < specials.Count) |
|
{ |
|
ecMapEvent.Invoke((int)MapEvent.DoorNearSave, blocks); |
|
List<MapBlock> blocksOrder = blocks.Values.ToList().FindAll(a => a.blkType <= MapBlock.Type.Monster && (0 < a.dirEmpty.Count && a.dirEmpty.Count < 4)); |
|
|
|
Debug.LogWarning($"생성해야 하는 특수 블럭 {specials.Count} 개\n특수 블럭 생성 가능한 위치 {blocksOrder.Count} 개"); |
|
|
|
MapBlock blkConnect = null; |
|
Vector2 idx = Vector2.zero; |
|
for (int i = 0; i < specials.Count; i++) |
|
{ |
|
if (0 == blocksOrder.Count) |
|
{ |
|
Debug.LogWarning($"{i}/{specials} : 특수 블럭의 생성 공간이 부족합니다."); |
|
break; |
|
} |
|
|
|
//연결 블럭 |
|
blkConnect = blocksOrder[Random.Range(0, blocksOrder.Count)]; |
|
idx = blkConnect.NearEmptyIndex_Get();//생성될 좌표 |
|
|
|
if (blocks.ContainsKey(idx)) |
|
{ |
|
i--; |
|
} |
|
else |
|
{ |
|
//생성 블럭 |
|
blk = ObjectCreateLocalPos(floorData.PrefabGet(specials[i]), transform, Vector3.one, Vector3.zero).GetComponent<MapBlock>(); |
|
blk.OnInitialized(this, blocks.Count, idx, specials[i]);//특수블럭 초기화 |
|
ecMapEvent.Add(blk.OnEvent); |
|
//문 연결 |
|
blk.Door_Connect(blkConnect); |
|
blkConnect.Door_Connect(blk); |
|
|
|
blocks.Add(idx, blk); |
|
blocksOrder.Remove(blkConnect); |
|
} |
|
} |
|
} |
|
|
|
//맵 생성 완료, 플레이어 와 카메라를 첫 블럭으로 이동 |
|
blk = blocks.Values.ToList()[0]; |
|
|
|
MapDoor.Teleport tel = new MapDoor.Teleport(); |
|
blk.gameObject.SetActive(false); |
|
tel.blk = blk; |
|
tel.door = null; |
|
|
|
if (player == null) |
|
player = ObjectCreateLocalPos(prefabPlayer.gameObject, null, scaleCharacter, new Vector3(-0.5f, 0, -3f)).GetComponent<InputController>(); |
|
OnMapInitialized.Invoke(this); |
|
|
|
if (floor == 0) |
|
player.character.OnInitialized(prefabPlayer.character.HP, prefabPlayer.character.HP_Max);//플레이어 생성 |
|
else |
|
player.gameObject.SetActive(true); |
|
player.Teleport(tel); |
|
|
|
OnHoldingItemCheck = player.character.skill.HoldingItemCheck; |
|
|
|
spBGM.Play(); |
|
|
|
all = null; |
|
idxsDic = null; |
|
} |
|
/// <summary> |
|
/// 일반 블럭 들을 생성합니다 |
|
/// </summary> |
|
/// <param name="idxs">좌표 목록</param> |
|
/// <param name="number">경로의 넘버링</param> |
|
/// <param name="types_Default">타입 목록</param> |
|
/// <param name="cnt">생성 갯수</param> |
|
void BlockCreate(List<Vector2> idxs, int number, List<MapBlock.Type> types_Default, ref int cnt) |
|
{ |
|
//연결통로, 몬스터 방 -> 보스 방 까지의 경로 생성 |
|
MapBlock blk = null; |
|
for (int i = 0; i < idxs.Count; i++) |
|
{ |
|
//Debug.LogWarning($"{idxs[i]}"); |
|
MapBlock.Type type = i == 0 ? MapBlock.Type.None : (idxBoss == idxs[i] ? MapBlock.Type.Boss : types_Default[cnt]); |
|
if (blocks.ContainsKey(idxs[i])) |
|
{ |
|
blk = blocks[idxs[i]]; |
|
blk.OnInitialized(this, i + number, idxs[i], type);//블럭 초기화 |
|
} |
|
else |
|
{ |
|
GameObject prefab = null; |
|
if (i == 0 && idxs[i] == Vector2.zero) |
|
prefab = floorData.PrefabGet(MapBlock.Type.Empty); |
|
else |
|
prefab = floorData.PrefabGet(type); |
|
|
|
blk = ObjectCreateLocalPos(prefab, transform, Vector3.one, Vector3.zero).GetComponent<MapBlock>(); |
|
blocks.Add(idxs[i], blk); |
|
|
|
blk.OnInitialized(this, i + number, idxs[i], type);//블럭 초기화 |
|
cnt++; |
|
} |
|
|
|
ecMapEvent.Add(blk.OnEvent); |
|
} |
|
|
|
ecMapEvent.Invoke((int)MapEvent.DoorConnect, blocks); |
|
} |
|
|
|
Vector2 idxBoss = Vector2.zero; |
|
Dictionary<Vector2, Vector2> idxsDic; |
|
List<List<Vector2>> all = new List<List<Vector2>>(); |
|
/// <summary> |
|
/// 좌표를 생성합니다. |
|
/// </summary> |
|
void Generate_IndexAll() |
|
{ |
|
idxsDic = new Dictionary<Vector2, Vector2>(); |
|
idxsDic.Add(Vector2.zero, Vector2.zero); |
|
|
|
all = new List<List<Vector2>>(); |
|
int max = (int)(floorData.cntDefault * floorData.rateMax); |
|
int cntRemain = floorData.cntDefault; |
|
int cntFind = cntRemain <= max ? cntRemain : (cntRemain - max < 0 ? cntRemain : max); |
|
|
|
Vector2 idxStart = Vector2.zero; |
|
List<Vector2> idxSearch = new List<Vector2>(); |
|
idxSearch.Add(idxStart); |
|
|
|
int cntTry = 1; |
|
int cntLength = 0; |
|
while (0 < cntRemain && 0 < idxSearch.Count) |
|
{ |
|
List<Vector2> idxs = Generate_Index(idxStart, cntFind, cntTry); |
|
if (idxs.Count == 1) |
|
{ |
|
idxSearch.Remove(idxStart); |
|
|
|
//Debug.LogWarning($"실패, 남은 목록 : {idxSearch.Count}"); |
|
|
|
if (idxSearch.Count == 0 && cntTry < 3) |
|
{ |
|
cntTry++; |
|
for (int i = 0; i < all.Count; i++) |
|
{ |
|
idxSearch.AddRange(all[i]); |
|
idxSearch.Remove(all[i][all[i].Count - 1]); |
|
} |
|
idxSearch = idxSearch.Distinct().ToList(); |
|
|
|
//Debug.LogWarning($"재탐색, 목록 : {idxSearch.Count}, {cntTry}"); |
|
} |
|
} |
|
else |
|
{ |
|
all.Add(idxs); |
|
|
|
cntRemain -= idxs.Count - 1; |
|
cntFind = cntRemain <= max ? cntRemain : (cntRemain - max < 0 ? cntRemain : max); |
|
|
|
idxSearch.AddRange(idxs); |
|
idxSearch.Remove(idxs[idxs.Count - 1]); |
|
idxSearch = idxSearch.Distinct().ToList(); |
|
|
|
Vector2 idxChk = idxs[idxs.Count - 1]; |
|
int tmp = (int)(Mathf.Abs(idxChk.x) + Mathf.Abs(idxChk.y)); |
|
if (cntLength < tmp) |
|
{ |
|
//Debug.LogWarning($"{cntLength}({idxBoss}) < {tmp}({idxChk})"); |
|
cntLength = tmp; |
|
idxBoss = idxChk; |
|
} |
|
else if (cntLength == tmp) |
|
{ |
|
idxBoss = Random.Range(0, 100) < 50 ? idxBoss : idxChk; |
|
} |
|
|
|
//Debug.LogWarning($"성공, 남은 목록 : {idxSearch.Count}"); |
|
} |
|
|
|
if (0 < idxSearch.Count) |
|
idxStart = idxSearch[Random.Range(0, idxSearch.Count)]; |
|
} |
|
|
|
for (int i = 0; i < all.Count; i++) |
|
idxSearch.AddRange(all[i]); |
|
idxSearch = idxSearch.Distinct().ToList(); |
|
|
|
if (floorData.cntDefault == idxSearch.Count) |
|
{ |
|
Debug.LogWarning($"생성 완료 결과 : {floorData.cntDefault} == {idxSearch.Count}"); |
|
} |
|
else |
|
{ |
|
Debug.LogError($"생성 실패 결과 : {floorData.cntDefault} == {idxSearch.Count}"); |
|
|
|
Generate_IndexAll(); |
|
} |
|
} |
|
/// <summary> |
|
/// idxStart 를 시작으로 cnt 개의 좌표를 생성합니다. |
|
/// </summary> |
|
/// <param name="idxStart">시작 좌표</param> |
|
/// <param name="cnt">생성 갯수</param> |
|
/// <param name="cntAround">생성 제한, 주변의 블럭 최소수</param> |
|
/// <returns></returns> |
|
List<Vector2> Generate_Index(Vector2 idxStart, int cnt, int cntAround = 1) |
|
{ |
|
Vector2 idx = idxStart; |
|
List<Vector2> idxs = new List<Vector2>(); |
|
idxs.Add(idx); |
|
if (!idxsDic.ContainsKey(idx)) |
|
idxsDic.Add(idx, idx); |
|
|
|
Vector2 idxT; |
|
bool PASS = true; |
|
|
|
DirectionIndex(false, true); |
|
|
|
int j = 0; |
|
Vector2 dirBefore = Vector2.zero; |
|
for (int i = 1; i < cnt && PASS; i++) |
|
{ |
|
PASS = false; |
|
|
|
if (j == dirsRandom.Count) |
|
{ |
|
j = 0; |
|
dirsRandom = Util.ListShuffle<Vector2>.Shuffle(dirsRandom); |
|
} |
|
|
|
for (; j < dirsRandom.Count; j++) |
|
{ |
|
if (dirBefore == Vector2.zero) |
|
{ |
|
idxT = dirsRandom[j]; |
|
idxT = idxT + idx;//생성해야 될 위치 |
|
|
|
dirBefore = Random.Range(0, 100) < 70 ? dirsRandom[j] : Vector2.zero; |
|
} |
|
else |
|
{ |
|
idxT = dirBefore; |
|
idxT = idxT + idx;//생성해야 될 위치 |
|
|
|
dirBefore = Random.Range(0, 100) < 70 ? dirBefore : Vector2.zero; |
|
} |
|
|
|
if (!idxsDic.ContainsKey(idxT) && DirectionCheck(idxT, cntAround) && CheckIndexRange(idxT)) |
|
{ |
|
//해당 위치에 생성 가능 |
|
idx = idxT; |
|
idxsDic.Add(idx, idx); |
|
idxs.Add(idx); |
|
|
|
PASS = true; |
|
j++; |
|
|
|
Generate_Blocked_Init(); |
|
|
|
break; |
|
} |
|
else |
|
{ |
|
if (Generate_Blocked(idxT - idx)) |
|
{ |
|
//해당 위치에 생성 불가능 |
|
PASS = false; |
|
|
|
break; |
|
} |
|
else |
|
{ |
|
PASS = true; |
|
} |
|
|
|
if (j + 1 == dirsRandom.Count) |
|
{ |
|
j = 0; |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (!PASS) |
|
{ |
|
//Debug.LogWarning($"기본 위치 생성 실패, 중복된 경로 존재"); |
|
|
|
//return Generate_Index(idxStart, cnt); |
|
return idxs; |
|
} |
|
else |
|
return idxs; |
|
} |
|
|
|
[System.Serializable] |
|
public class MapClearedEvent : UnityEvent<MapManager> { } |
|
[FormerlySerializedAs("onMapCleared")] |
|
[Space(10)] |
|
[SerializeField] |
|
private MapClearedEvent OnMapCleared = new MapClearedEvent(); |
|
/// <summary> |
|
/// 층의 클리어를 확인합니다. |
|
/// </summary> |
|
/// <param name="DIE">플레이어의 죽음</param> |
|
public void MapCleared(bool DIE = false) |
|
{ |
|
if (FloorCheck() && !DIE) |
|
FloorGoDown();//현재 층을 클리어 |
|
else |
|
OnMapCleared.Invoke(this);//플레이어 죽음 |
|
} |
|
|
|
Dictionary<Vector2, bool> dicCheck = new Dictionary<Vector2, bool>(); |
|
/// <summary> |
|
/// 주변에 생성 가능한 위치가 있었기에 확인을 위한 데이터를 초기화 합니다. |
|
/// </summary> |
|
void Generate_Blocked_Init() |
|
{ |
|
var list = dicCheck.Keys.ToList(); |
|
for (int i = 0; i < list.Count; i++) |
|
dicCheck[list[i]] = false; |
|
} |
|
/// <summary> |
|
/// 주변에 생성 가능한 위치가 있는지 확인 합니다. |
|
/// 사방이 막혔다면 True 를 리턴합니다. |
|
/// </summary> |
|
/// <param name="dir"></param> |
|
/// <returns></returns> |
|
bool Generate_Blocked(Vector2 dir) |
|
{ |
|
dicCheck[dir] = true; |
|
return 4 == dicCheck.Values.Count(a => a == true); |
|
} |
|
|
|
[Space(10)] |
|
public MapBlock blkCurrent; |
|
|
|
[System.Serializable] |
|
public class MapChangedEvent : UnityEvent<MapBlock> { } |
|
[FormerlySerializedAs("onMapChanged")] |
|
[Space(10)] |
|
[SerializeField] |
|
private MapChangedEvent OnMapChanged = new MapChangedEvent(); |
|
/// <summary> |
|
/// 생성 완료 및 플레이어의 블럭 이동시 호출 됩니다. |
|
/// </summary> |
|
/// <param name="blk"></param> |
|
public void MapBlockChanged(MapBlock blk, System.Action OnEnd = null) |
|
{ |
|
if (blkCurrent != null) |
|
blkCurrent.TintFade(0.8f); |
|
blk.TintFade(0); |
|
|
|
MapBlock blkBefore = blkCurrent; |
|
blkCurrent = blk; |
|
blkCurrent.Setting(dungeonName);//블럭 이동 |
|
|
|
//카메라를 이동한 블럭으로 이동합니다. |
|
targetCamera.DOMove(blkCurrent.transform.position, 0.5f).OnComplete(() => |
|
{ |
|
if (blkBefore != null) |
|
blkBefore.gameObject.SetActive(false); |
|
|
|
if (OnEnd != null) |
|
OnEnd(); |
|
|
|
Fade.DOFade(0, 0.25f); |
|
|
|
OnMapChanged.Invoke(blkCurrent); |
|
}); |
|
} |
|
|
|
Bundle<MapTile> dicTile = new Bundle<MapTile>(); |
|
public MapTile CreateTile(Transform target, GameObject prefab, Vector3 scale, Vector3 pos) |
|
{ |
|
GameObject obj = ObjectCreateLocalPos(prefab, target, scale, pos, true); |
|
|
|
MapTile tile = dicTile.Get(obj.name); |
|
if (tile == null) |
|
{ |
|
tile = obj.GetComponent<MapTile>(); |
|
dicTile.Add(tile.name, tile); |
|
} |
|
|
|
return tile; |
|
} |
|
|
|
/// <summary> |
|
/// 플레이어가 있는 위치 이외의 블럭을 하이드 시킨다. |
|
/// </summary> |
|
public void MapBlockHide() |
|
{ |
|
//return; |
|
|
|
List<MapBlock> blks = new List<MapBlock>(blocks.Values); |
|
for (int i = 0; i < blks.Count; i++) |
|
blks[i].gameObject.SetActive(blkCurrent == blks[i]); |
|
} |
|
|
|
[Space(10)] |
|
public Character mob; |
|
public void MonsterCreate_Designate() |
|
{ |
|
if (mob != null) |
|
{ |
|
blkCurrent.CLEAR = false; |
|
blkCurrent.ecMapBlock.Invoke((int)MapEvent.DoorState, false); |
|
|
|
appear.cnt = 1; |
|
appear.mobNames.Clear(); |
|
appear.mobNames.Add(mob.name); |
|
blkCurrent.Monster_Create(appear); |
|
} |
|
} |
|
public List<Character> mobs; |
|
Bundle<Character> dicMonster = new Bundle<Character>(); |
|
/// <summary> |
|
/// 몬스터를 생성합니다. |
|
/// </summary> |
|
/// <param name="blk">생성될 맵 블럭</param> |
|
/// <param name="prefabMonset">몬스터 프리팹</param> |
|
/// <param name="pos">생성 위치</param> |
|
/// <returns></returns> |
|
public Character MonsterCreate(MapBlock blk, GameObject prefabMonset, Vector3 pos) |
|
{ |
|
GameObject obj = ObjectCreate(prefabMonset, blk.transform, scaleCharacter, pos, true); |
|
|
|
Character Monster = dicMonster.Get(obj.name); |
|
if (Monster == null) |
|
{ |
|
Monster = obj.GetComponent<Character>(); |
|
dicMonster.Add(Monster.name, Monster); |
|
} |
|
|
|
return Monster; |
|
} |
|
|
|
Bundle<DropItem> dicDrop = new Bundle<DropItem>(); |
|
/// <summary> |
|
/// 드롭아이템을 생성합니다. |
|
/// </summary> |
|
/// <param name="blk">생성될 블럭</param> |
|
/// <param name="prefab">드롭아이템 프리팹</param> |
|
/// <param name="pos">생성 위치</param> |
|
/// <returns></returns> |
|
public DropItem DropItemCreate(MapBlock blk, GameObject prefab, Vector3 pos) |
|
{ |
|
GameObject obj = ObjectCreate(prefab, blk.transform, Vector3.one, pos, true); |
|
|
|
DropItem drop = dicDrop.Get(obj.name); |
|
if (drop == null) |
|
{ |
|
drop = obj.GetComponent<DropItem>(); |
|
dicDrop.Add(drop.name, drop); |
|
} |
|
|
|
return drop; |
|
} |
|
[Space(10)] |
|
public DropItemData dropItem; |
|
public List<ItemData> items_All; |
|
public List<ItemData> items_Weapon; |
|
public List<ItemData> items_Armor; |
|
public List<ItemData> items_Accessory; |
|
public List<ItemData> items_Passive; |
|
public List<ItemData> items_Active; |
|
public List<ItemData> items_Use; |
|
|
|
List<ItemData> listItems = new List<ItemData>(); |
|
//public void HoldinCheckList(List<ItemData> items, string idx) |
|
//{ |
|
// ItemData item = items.Find(a => a.idx.Equals(idx)); |
|
|
|
// if(item != null) |
|
// items.Remove(item); |
|
//} |
|
//public void HoldinCheck(string idx) |
|
//{ |
|
// HoldinCheckList(items_Weapon, idx); |
|
// HoldinCheckList(items_Equip, idx); |
|
// HoldinCheckList(items_Passive, idx); |
|
//} |
|
//public void DropItemCreate(List<ItemData> items) |
|
//{ |
|
// if (items.Count == 0) |
|
// return; |
|
|
|
// ItemData item = items[Random.Range(0, items.Count)]; |
|
// blkCurrent.OnDropItem_Create(player.transform, item); |
|
// HoldinCheckList(items, item.idx); |
|
//} |
|
/// <summary> |
|
/// 현재 맵에 존재하는 모든 블럭에서 해당 아이템이 드랍되었는지 확인합니다. |
|
/// </summary> |
|
/// <param name="idxItem">확인할 아이템 IDX</param> |
|
/// <returns>true - 드랍되어 있음</returns> |
|
bool DropCheck_All(string idxItem) |
|
{ |
|
foreach(KeyValuePair<Vector2, MapBlock> blk in blocks) |
|
{ |
|
if (blk.Value.HoldingItemCheck(idxItem)) |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
/// <summary> |
|
/// 장착중인 아이템 및 드랍된 아이템 의 중첩드랍을 확인 하며 |
|
/// 어느쪽에도 해당하지 않는 아이템을 넘깁니다. |
|
/// </summary> |
|
/// <param name="items">드랍 리스트</param> |
|
/// <param name="tierMin">최소 티어</param> |
|
/// <param name="tierMax">최대 티어</param> |
|
/// <param name="target">생성 위치</param> |
|
/// <param name="CREATE">생성 유무</param> |
|
/// <returns></returns> |
|
public ItemData DuplicateItemCheck(List<ItemData> items, int tierMin = 0, int tierMax = 999, Transform target = null, bool CREATE = true) |
|
{ |
|
listItems.Clear(); |
|
|
|
for (int i = 0; i < items.Count; i++) |
|
{ |
|
if (tierMin <= items[i].tier && items[i].tier <= tierMax) |
|
{ |
|
if (items[i].type.Equals("Use") || items[i].type.Equals("Pickup")) |
|
{ |
|
listItems.Add(items[i]); |
|
continue; |
|
} |
|
//if (!OnHoldingItemCheck(items[i].idx) && !blkCurrent.HoldingItemCheck(items[i].idx)) |
|
if (!OnHoldingItemCheck(items[i].idx) && !DropCheck_All(items[i].idx)) |
|
listItems.Add(items[i]); |
|
} |
|
} |
|
|
|
if (listItems.Count < 1) |
|
return null; |
|
|
|
ItemData data = listItems[Random.Range(0, listItems.Count)]; |
|
if (0 < listItems.Count && CREATE) |
|
blkCurrent.OnDropItem_Create(target == null ? player.transform : target, data.idx); |
|
|
|
return data; |
|
} |
|
//public void DropItemCreate() |
|
//{ |
|
// blkCurrent.OnDropItem_Create(player.transform, dropItem); |
|
//} |
|
|
|
AppearList appear = new AppearList(); |
|
void Update() |
|
{ |
|
if (Input.GetKeyDown(KeyCode.F8)) |
|
{ |
|
//ecMapEvent.Invoke((int)MapEvent.DoorInit, null); |
|
blkCurrent.CLEAR = false; |
|
blkCurrent.ecMapBlock.Invoke((int)MapEvent.DoorInit, false); |
|
|
|
appear.cnt = 1; |
|
appear.mobNames.Clear(); |
|
appear.mobNames.Add(mobs[Random.Range(0, mobs.Count)].name); |
|
blkCurrent.Monster_Create(appear); |
|
} |
|
|
|
if (Input.GetKeyDown(KeyCode.F1)) |
|
DuplicateItemCheck(items_Use); |
|
if (Input.GetKeyDown(KeyCode.F2)) |
|
DuplicateItemCheck(items_Weapon); |
|
if (Input.GetKeyDown(KeyCode.F3)) |
|
DuplicateItemCheck(items_Accessory); |
|
if (Input.GetKeyDown(KeyCode.F4)) |
|
DuplicateItemCheck(items_Armor); |
|
if (Input.GetKeyDown(KeyCode.F5)) |
|
DuplicateItemCheck(items_Passive); |
|
if (Input.GetKeyDown(KeyCode.F6)) |
|
DuplicateItemCheck(items_Active); |
|
|
|
//if (Input.GetKeyDown(KeyCode.F12)) |
|
// Generate_Block();//치트, 맵 재설정 |
|
} |
|
|
|
public void IngameCommand(object value) |
|
{ |
|
string command = (string)value; |
|
|
|
string[] split = command.Split(':'); |
|
switch(split[0]) |
|
{ |
|
case "Monster": |
|
{ |
|
blkCurrent.CLEAR = false; |
|
blkCurrent.ecMapBlock.Invoke((int)MapEvent.DoorInit, false); |
|
|
|
appear.cnt = 1; |
|
appear.mobNames.Clear(); |
|
appear.mobNames.Add(split[1]); |
|
blkCurrent.Monster_Create(appear); |
|
} |
|
break; |
|
case "Item": |
|
{ |
|
ItemData itemData = DataManager.Instance.dataItem.Search(split[1]); |
|
if(itemData != null) |
|
blkCurrent.OnDropItem_Create(player.transform, itemData.idx); |
|
else |
|
Debug.LogWarning($"Can't Find Item IDX : {split[1]}"); |
|
} |
|
break; |
|
default: |
|
{ |
|
Debug.LogWarning($"Wrong input : {command}"); |
|
} |
|
break; |
|
} |
|
} |
|
}
|
|
|