438 lines
16 KiB
C#
438 lines
16 KiB
C#
|
|
using CodeStage.AntiCheat.Detectors;
|
|||
|
|
using CodeStage.AntiCheat.ObscuredTypes;
|
|||
|
|
using Newtonsoft.Json;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Data;
|
|||
|
|
using System.Linq;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|||
|
|
using Random = UnityEngine.Random;
|
|||
|
|
|
|||
|
|
public partial class InGameInfo : MyCoroutine
|
|||
|
|
{
|
|||
|
|
public static InGameInfo Ins;
|
|||
|
|
public TextAsset ta_StageData;
|
|||
|
|
public Material mat_Dissolve;
|
|||
|
|
public BackGroundSetting m_BackGroundSetting;
|
|||
|
|
public Transform[] tfs_ProjectileStart; // 0 왼쪽, 1 중앙, 2 오른쪽, 3 몹 중앙
|
|||
|
|
public PCActor m_PCActor { get { return IngameUIManager.Ins.m_PCActor; } }
|
|||
|
|
|
|||
|
|
ToolData m_ToolData;
|
|||
|
|
|
|||
|
|
|
|||
|
|
private void Awake() { Ins = this; }
|
|||
|
|
|
|||
|
|
void Set_Init()
|
|||
|
|
{
|
|||
|
|
AddrResourceMgr.Ins.LoadObject<GameObject>("MainUI/GameUI.prefab", handle =>
|
|||
|
|
{
|
|||
|
|
if (handle.IsDone && handle.Status == AsyncOperationStatus.Succeeded)
|
|||
|
|
{
|
|||
|
|
DSUtil.Get_Clone(handle.Result);
|
|||
|
|
//InappInfo.Ins.Check_Retrieved();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator Start()
|
|||
|
|
{
|
|||
|
|
m_ToolData = JsonConvert.DeserializeObject<ToolData>(ta_StageData.text);
|
|||
|
|
|
|||
|
|
DataCheckMgr.Ins.Set();
|
|||
|
|
Set_Init();
|
|||
|
|
|
|||
|
|
while (!TableChecker.Ins.CheckAllLoad()) yield return new WaitForSeconds(0.1f);
|
|||
|
|
|
|||
|
|
//var lst = table_effectlist.Ins.Get_DataList(1);
|
|||
|
|
//for (int i = 0; i < lst.Count; i++)
|
|||
|
|
//{
|
|||
|
|
// dic_str_Effect.Add(lst[i].s_EffectPrefab, new List<GameObject>());
|
|||
|
|
// for (int j = 0; j < lst[i].n_PreLoadCount; j++)
|
|||
|
|
// Load_Effect(lst[i].s_EffectPrefab, effect => { effect.transform.position = Vector3.one * 100000f; });
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
ObscuredCheatingDetector.StartDetection(OnCheaterDetected);
|
|||
|
|
SpeedHackDetector.StartDetection(OnCheaterDetected);
|
|||
|
|
|
|||
|
|
//while (DSUtil.CheckNull(NewGameUI.Ins)) yield return null;
|
|||
|
|
|
|||
|
|
if (MyValue.m_MyStageData.m_EnterType != eStageEnterType.Normal)
|
|||
|
|
{
|
|||
|
|
while (!LobbyUIManager.Ins) yield return null;
|
|||
|
|
Start_Game_byTool();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (!IngameUIManager.Ins) yield return null;
|
|||
|
|
|
|||
|
|
dic_EnemyActor.Add(eRole.Mob, new List<Actor> { m_PCActor });
|
|||
|
|
dic_EnemyActor.Add(eRole.PC, MonsterNodeControler.Ins.Get_AllActor().ToList());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void OnCheaterDetected()
|
|||
|
|
{
|
|||
|
|
Time.timeScale = 0f;
|
|||
|
|
Popup.Ins.Set(ePopupType.One, -99, DSUtil.Quit, DSUtil.Quit);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Set_TimeScale(float _scale, float _delay) { Set_Coroutine(() => { Time.timeScale = _scale; }, _delay); }
|
|||
|
|
|
|||
|
|
#region 탐험
|
|||
|
|
public void Return_To_Lobby()
|
|||
|
|
{
|
|||
|
|
IngameUIManager.Ins.Return_To_Lobby();
|
|||
|
|
switch (MyValue.m_MyStageData.m_EnterType)
|
|||
|
|
{
|
|||
|
|
case eStageEnterType.Normal:
|
|||
|
|
LobbyUIManager.Ins.Set();
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (MonsterNodeControler.Ins) MonsterNodeControler.Ins.AllOff(); // 몬스터 끄기
|
|||
|
|
EffectMgr.Ins.AllOff(); // 이펙트 끄기
|
|||
|
|
ProjectileMgr.Ins.AllOff(); // 투사체 끄기
|
|||
|
|
}
|
|||
|
|
public void Start_Game()
|
|||
|
|
{
|
|||
|
|
Start_Game_Common();
|
|||
|
|
}
|
|||
|
|
public void Start_Game_byTool()
|
|||
|
|
{
|
|||
|
|
LobbyUIManager.Ins.gameObject.SetActive(false);
|
|||
|
|
IngameUIManager.Ins.gameObject.SetActive(true);
|
|||
|
|
Start_Game_Common();
|
|||
|
|
}
|
|||
|
|
void Start_Game_Common()
|
|||
|
|
{
|
|||
|
|
var pcid = MyValue.sdata.PCID;
|
|||
|
|
switch (MyValue.m_MyStageData.m_EnterType)
|
|||
|
|
{
|
|||
|
|
default:
|
|||
|
|
Set_StageData(MyValue.m_MyStageData.m_Chapter, MyValue.m_MyStageData.m_Stage);
|
|||
|
|
break;
|
|||
|
|
case eStageEnterType.Tool_Mob:
|
|||
|
|
Set_StageData(1, 1);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_BackGroundSetting.Set();
|
|||
|
|
IngameUIManager.Ins.Active_ExporeButton();
|
|||
|
|
Init_CardData(); // Actor Set_Equipment() 전 호출해야 됨
|
|||
|
|
m_PCActor.Set(0, table_pclist.Ins.Get_Data_orNull(pcid), IngameUIManager.Ins.PC_HUD_HPShield, MyValue.sdata);
|
|||
|
|
|
|||
|
|
Init_IngameDatas();
|
|||
|
|
|
|||
|
|
if (MyValue.m_MyStageData.m_EnterType == eStageEnterType.Tool_Mob)
|
|||
|
|
IngameUIManager.Ins.Skip_Expore();
|
|||
|
|
}
|
|||
|
|
public void Init_IngameDatas()
|
|||
|
|
{ // 탐험 입장 시 1번 호출
|
|||
|
|
PCLv = 1;
|
|||
|
|
dic_goodsAmount.Clear();
|
|||
|
|
|
|||
|
|
Set_Texts();
|
|||
|
|
Set_PCLvInfo();
|
|||
|
|
IngameUIManager.Ins.m_PCMainStatUI.Set(m_PCActor.Get_ActorStatInfo());
|
|||
|
|
IngameUIManager.Ins.m_GainCardList.Set(list_GainCard); // Actor Set_Equipment() 후 호출됨
|
|||
|
|
DefeatUI.Ins.Init();
|
|||
|
|
IngameUIManager.Ins.m_DungeonInfo.Set();
|
|||
|
|
|
|||
|
|
m_PCActor.Init_IngameDatas();
|
|||
|
|
if (MonsterNodeControler.Ins) MonsterNodeControler.Ins.Init_IngameDatas();
|
|||
|
|
}
|
|||
|
|
void Init_CardData()
|
|||
|
|
{
|
|||
|
|
m_lvupcardcount = 0;
|
|||
|
|
list_GainCard.Clear();
|
|||
|
|
}
|
|||
|
|
void Set_StageData(int chapter, int stage)
|
|||
|
|
{
|
|||
|
|
IngameStageData data = null;
|
|||
|
|
switch (MyValue.m_MyStageData.m_EnterType)
|
|||
|
|
{
|
|||
|
|
default:
|
|||
|
|
data = m_ToolData.Get_IngameStageData(chapter, stage);
|
|||
|
|
data.Init();
|
|||
|
|
if (data == null)
|
|||
|
|
{
|
|||
|
|
Popup.Ins.Set($"{stage} 스테이지 데이터가 없습니다.");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
MyValue.m_MyStageData.m_StageData = data;
|
|||
|
|
IngameUIManager.Ins.m_DungeonInfo.m_DungeonProcess.Set_ExtraMark();
|
|||
|
|
}
|
|||
|
|
public void Add_BattlePatternData(int patternid, BattlePatternData bpdata)
|
|||
|
|
{
|
|||
|
|
var data = m_ToolData.MonsterPattern.Find(f => f.m_PatternID == patternid);
|
|||
|
|
if (data != null) m_ToolData.MonsterPattern.Remove(data);
|
|||
|
|
m_ToolData.MonsterPattern.Add(bpdata);
|
|||
|
|
}
|
|||
|
|
public BattlePatternData Get_BattlePatternData(int patternid)
|
|||
|
|
{
|
|||
|
|
var rtndata = m_ToolData.MonsterPattern.Find(f => f.m_PatternID == patternid);
|
|||
|
|
return rtndata;
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
#region 몬스터 조우
|
|||
|
|
ObscuredInt _pclv; public int PCLv { get { return _pclv; } set { _pclv = value; _pclv.RandomizeCryptoKey(); } }
|
|||
|
|
ObscuredInt _lvupcardcount; public int m_lvupcardcount { get { return _lvupcardcount; } set { _lvupcardcount = value; _lvupcardcount.RandomizeCryptoKey(); } }
|
|||
|
|
Dictionary<int, ObscuredInt> dic_goodsAmount = new Dictionary<int, ObscuredInt>();
|
|||
|
|
List<CardListTableData> list_GainCard = new List<CardListTableData>();
|
|||
|
|
public List<CardListTableData> Get_ListGainCard() { return list_GainCard; }
|
|||
|
|
Dictionary<eRole, List<Actor>> dic_EnemyActor = new Dictionary<eRole, List<Actor>>();
|
|||
|
|
public void Init_EveryMeetMonster()
|
|||
|
|
{ // 몬스터 만났을 때마다 한 번 실행되는 함수
|
|||
|
|
m_PCActor.Init_EveryMeetMonster();
|
|||
|
|
if (MonsterNodeControler.Ins) MonsterNodeControler.Ins.Init_EveryMeetMonster();
|
|||
|
|
|
|||
|
|
m_PCActor.OnEvent_RunSkillCard();
|
|||
|
|
}
|
|||
|
|
public void BattleStart_AfterMakeMob()
|
|||
|
|
{ // 몬스터, 보스 노드 만날 시 최초 한 번 실행
|
|||
|
|
OnEvent_MakeMob();
|
|||
|
|
Set_Battle(true);
|
|||
|
|
Init_EveryMeetMonster();
|
|||
|
|
MonsterNodeControler.Ins.Check_LineAllDead();
|
|||
|
|
OnEvent_AfterLineChange();
|
|||
|
|
}
|
|||
|
|
public void Set_Texts()
|
|||
|
|
{
|
|||
|
|
IngameUIManager.Ins.Set_Texts(Get_GoodsAmount(MyValue.ItemID_Gold), Get_GoodsAmount(MyValue.ItemID_Soul),
|
|||
|
|
(int)m_PCActor.Get_ActorStatInfo().Get_TotalStat(eStat.Potion));
|
|||
|
|
}
|
|||
|
|
public void Set_PCLvInfo(Action<bool> actgageend = null)
|
|||
|
|
{
|
|||
|
|
IngameUIManager.Ins.m_PCMainStatUI.Set_Lv(PCLv, Get_GoodsAmount(MyValue.ItemID_Exp), actgageend);
|
|||
|
|
}
|
|||
|
|
public void Set_Battle(bool battle)
|
|||
|
|
{
|
|||
|
|
m_PCActor.Set_Battle(battle);
|
|||
|
|
if (MonsterNodeControler.Ins) MonsterNodeControler.Ins.Set_Battle(battle);
|
|||
|
|
}
|
|||
|
|
public int Get_GoodsAmount(int itemid) { return dic_goodsAmount.ContainsKey(itemid) ? dic_goodsAmount[itemid] : 0; }
|
|||
|
|
public void Add_Goods(int itemid, int v)
|
|||
|
|
{
|
|||
|
|
if (!dic_goodsAmount.ContainsKey(itemid))
|
|||
|
|
dic_goodsAmount.Add(itemid, 0);
|
|||
|
|
dic_goodsAmount[itemid] += v;
|
|||
|
|
dic_goodsAmount[itemid].RandomizeCryptoKey();
|
|||
|
|
|
|||
|
|
Set_Texts();
|
|||
|
|
|
|||
|
|
if (itemid == MyValue.ItemID_Exp)
|
|||
|
|
Set_PCLvInfo(Check_PCLvUp);
|
|||
|
|
}
|
|||
|
|
void Check_PCLvUp(bool isLvUp)
|
|||
|
|
{
|
|||
|
|
if (isLvUp)
|
|||
|
|
{
|
|||
|
|
SelectCardUI.Ins.Set(true);
|
|||
|
|
++PCLv;
|
|||
|
|
m_PCActor.OnEvent_LvUp();
|
|||
|
|
Set_PCLvInfo(Check_PCLvUp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public void Add_Potion(int amount, int maxpotion = 0)
|
|||
|
|
{
|
|||
|
|
if (maxpotion > 0) m_PCActor.Get_ActorStatInfo().Set_Stat(true, eStat.MaxPotion, maxpotion);
|
|||
|
|
m_PCActor.Get_ActorStatInfo().Set_Stat(true, eStat.Potion, amount);
|
|||
|
|
Set_Texts();
|
|||
|
|
}
|
|||
|
|
public void Use_Potion()
|
|||
|
|
{
|
|||
|
|
var potion = 10; // 테스트 : 물약 회복량
|
|||
|
|
m_PCActor.Use_Potion(false, potion);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void PCLvUp_Imm()
|
|||
|
|
{
|
|||
|
|
var expdata = table_BattleLevelUp.Ins.Get_Data_orNull(PCLv);
|
|||
|
|
if (expdata != null)
|
|||
|
|
{
|
|||
|
|
var remainExp = expdata.n_TotalExp - Get_GoodsAmount(MyValue.ItemID_Exp);
|
|||
|
|
Add_Goods(MyValue.ItemID_Exp, remainExp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public void Heal_PC(eHealType healType, int heal)
|
|||
|
|
{
|
|||
|
|
m_PCActor.Heal(healType, heal);
|
|||
|
|
m_PCActor.Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
|
|||
|
|
}
|
|||
|
|
public void Add_Card(CardListTableData card, bool islvupcard)
|
|||
|
|
{
|
|||
|
|
if (islvupcard) ++m_lvupcardcount;
|
|||
|
|
list_GainCard.Add(card);
|
|||
|
|
IngameUIManager.Ins.m_GainCardList.Set(list_GainCard);
|
|||
|
|
if (ServerInfo.Ins.m_ServerData != null) ServerInfo.Ins.m_ServerData.Add_Card(card.n_ID);
|
|||
|
|
m_PCActor.Add_CardSkill(card);
|
|||
|
|
|
|||
|
|
Set_Texts();
|
|||
|
|
IngameUIManager.Ins.m_PCMainStatUI.Set(m_PCActor.Get_ActorStatInfo());
|
|||
|
|
}
|
|||
|
|
public void Add_Card_Random(eGrade grade) { m_PCActor.Add_Card_Random(grade); }
|
|||
|
|
|
|||
|
|
public void Revive_PC() { m_PCActor.Revive_byDefeatUI(); }
|
|||
|
|
|
|||
|
|
public void OnEvent_MakeMob()
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < list_GainCard.Count; i++)
|
|||
|
|
{
|
|||
|
|
var temp = list_GainCard[i];
|
|||
|
|
switch (temp.e_CardType)
|
|||
|
|
{
|
|||
|
|
case eCardType.G3_DodgeFirstRangedAttack:
|
|||
|
|
MonsterNodeControler.Ins.OnEvent_CheckCard(temp);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public void OnEvent_Mob_ShootProjectile(MobActor mob)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < list_GainCard.Count; i++)
|
|||
|
|
{
|
|||
|
|
var temp = list_GainCard[i];
|
|||
|
|
switch (temp.e_CardType)
|
|||
|
|
{
|
|||
|
|
case eCardType.G4_RangedAttackFrontEnemyDamageShare:
|
|||
|
|
if (mob.IsMiddleLine() && mob.Get_AttackType() == eAttackType.Range)
|
|||
|
|
{
|
|||
|
|
var frontmob = Get_Enemy_orNull(eRole.PC, mob.Get_MobIndex() - 3);
|
|||
|
|
if (frontmob != null && !frontmob.IsDead())
|
|||
|
|
{
|
|||
|
|
var dmg = (int)(mob.Get_ActorStatInfo().Get_Damage() * temp.Get_FloatValue2());
|
|||
|
|
mob.Shoot_Projectile_FixedDmg(temp.e_CardType, temp.s_Projectile, dmg, frontmob);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case eCardType.G1_RangedFirstAttackHitFrontAlly:
|
|||
|
|
if (mob.IsMiddleLine() && mob.Get_AttackType() == eAttackType.Range && mob.Get_AttackCount() == 1)
|
|||
|
|
{
|
|||
|
|
var carddata = m_PCActor.Get_CardSkillData_orNull(temp.e_CardType);
|
|||
|
|
if (carddata != null)
|
|||
|
|
{
|
|||
|
|
var frontmob = Get_Enemy_orNull(eRole.PC, mob.Get_MobIndex() - 3);
|
|||
|
|
if (frontmob != null && !frontmob.IsDead())
|
|||
|
|
frontmob.Get_Dmg((int)(mob.Get_ActorStatInfo().Get_Damage() * temp.Get_FloatValue2()));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public void OnEvent_MeetNode(eStageNodeType nodeType)
|
|||
|
|
{
|
|||
|
|
m_PCActor.OnEvent_MeetNode(nodeType);
|
|||
|
|
}
|
|||
|
|
public void OnEvent_AfterLineChange()
|
|||
|
|
{
|
|||
|
|
if (MyValue.m_MyStageData.m_EnterType == eStageEnterType.Tool_Mob) return;
|
|||
|
|
|
|||
|
|
m_PCActor.OnEvent_AfterLineChange();
|
|||
|
|
Get_AllEnemies(eRole.PC).ForEach(f => f.OnEvent_AfterLineChange());
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 타겟 찾기
|
|||
|
|
public List<Actor> Get_AllEnemies(eRole role) { return dic_EnemyActor[role]; }
|
|||
|
|
public List<Actor> Get_RandomAliveEnemies(eRole role, int count)
|
|||
|
|
{
|
|||
|
|
if (!dic_EnemyActor.TryGetValue(role, out var enemies))
|
|||
|
|
return new List<Actor>();
|
|||
|
|
|
|||
|
|
// 살아있는 적만 필터
|
|||
|
|
var aliveList = enemies.Where(e => e != null && !e.IsDead()).ToList();
|
|||
|
|
|
|||
|
|
if (aliveList.Count <= count)
|
|||
|
|
return aliveList;
|
|||
|
|
|
|||
|
|
// Fisher–Yates Shuffle (부분 셔플)
|
|||
|
|
for (int i = 0; i < count; i++)
|
|||
|
|
{
|
|||
|
|
int rand = Random.Range(i, aliveList.Count);
|
|||
|
|
(aliveList[i], aliveList[rand]) = (aliveList[rand], aliveList[i]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return aliveList.GetRange(0, count);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public List<Actor> Get_LineMobs(params eMobBattlePos[] pos)
|
|||
|
|
{
|
|||
|
|
var enemies = Get_AllEnemies(eRole.PC);
|
|||
|
|
return enemies.FindAll(f => !f.IsDead() && pos.Contains(f.Get_Line()));
|
|||
|
|
}
|
|||
|
|
public List<Actor> Get_Ally(eRole role)
|
|||
|
|
{
|
|||
|
|
var actors = dic_EnemyActor[role == eRole.PC ? eRole.Mob : eRole.PC];
|
|||
|
|
return actors.FindAll(f => !f.IsDead());
|
|||
|
|
}
|
|||
|
|
public Actor Get_Enemy_orNull(eRole role, bool cantsettarget = false)
|
|||
|
|
{
|
|||
|
|
if (role == eRole.PC)
|
|||
|
|
{ // PC가 몬스터 선택 (정인호 : 옵션 연계 필요)
|
|||
|
|
if (cantsettarget)
|
|||
|
|
{
|
|||
|
|
var mobs = Get_LineMobs(eMobBattlePos.Frontline, eMobBattlePos.Middleline);
|
|||
|
|
var aliveMobs = mobs.FindAll(m => !m.IsDead());
|
|||
|
|
return aliveMobs.Count == 0 ? null : aliveMobs[Random.Range(0, aliveMobs.Count)];
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
var mobs = Get_LineMobs(eMobBattlePos.Frontline);
|
|||
|
|
var aliveMobs = mobs.FindAll(m => !m.IsDead());
|
|||
|
|
return aliveMobs.Count == 0 ? null : aliveMobs[Random.Range(0, aliveMobs.Count)];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
return m_PCActor;
|
|||
|
|
}
|
|||
|
|
public Actor Get_Enemy_orNull(eRole role, int index)
|
|||
|
|
{
|
|||
|
|
var all = Get_AllEnemies(role);
|
|||
|
|
return all.Find(f => f.Get_MobIndex() == index);
|
|||
|
|
}
|
|||
|
|
public Actor[] Get_Mobs_4Nearby(int mobIndex)
|
|||
|
|
{
|
|||
|
|
// 기본 패턴: 상하좌우
|
|||
|
|
int[] offsets = { -1, 1, -3, 3 };
|
|||
|
|
|
|||
|
|
// 특수 처리: 위치별로 제외 인덱스 조정
|
|||
|
|
List<int> targetIndices = new List<int> { mobIndex };
|
|||
|
|
foreach (int offset in offsets)
|
|||
|
|
{
|
|||
|
|
int idx = mobIndex + offset;
|
|||
|
|
|
|||
|
|
// 좌우 경계 처리 (열 구분)
|
|||
|
|
int col = mobIndex % 3;
|
|||
|
|
if ((col == 0 && offset == -1) || (col == 2 && offset == 1))
|
|||
|
|
continue; // 왼쪽 끝에서 왼쪽으로 가거나, 오른쪽 끝에서 오른쪽으로 가는 경우 제외
|
|||
|
|
|
|||
|
|
// 범위 제한
|
|||
|
|
if (idx < 0 || idx > 8)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
targetIndices.Add(idx);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 대상들 가져오기 (null은 제외)
|
|||
|
|
var mobs = targetIndices.Select(i => Get_Enemy_orNull(eRole.PC, i)).Where(t => t != null && !t.IsDead()).ToArray();
|
|||
|
|
return mobs;
|
|||
|
|
}
|
|||
|
|
public Actor Get_RandomEnemy_orNull(eRole role)
|
|||
|
|
{
|
|||
|
|
var enemies = Get_AllEnemies(role);
|
|||
|
|
enemies = enemies.FindAll(f => !f.IsDead());
|
|||
|
|
if (enemies.Count > 0)
|
|||
|
|
return enemies[Random.Range(0, enemies.Count)];
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
public List<Actor> Get_Enemies_byAttackType(eRole role, eAttackType attackType)
|
|||
|
|
{
|
|||
|
|
var enemies = Get_AllEnemies(role);
|
|||
|
|
return enemies.FindAll(f => !f.IsDead() && f.Get_AttackType() == attackType);
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
}
|