OneShotOneKill/Assets/Script/Info/InGameInfo.cs

438 lines
16 KiB
C#
Raw Normal View History

2026-01-07 21:27:42 +00:00
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;
// FisherYates 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
}