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.
6176 lines
212 KiB
6176 lines
212 KiB
using DG.Tweening;
|
|
using DG.Tweening.Core;
|
|
using DG.Tweening.Plugins.Options;
|
|
using IVDataFormat;
|
|
using Spine;
|
|
using Spine.Unity;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.Universal;
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
using UnityEngine.UI;
|
|
using static CreatureBase;
|
|
using Random = UnityEngine.Random;
|
|
using Sequence = DG.Tweening.Sequence;
|
|
using Vector2 = UnityEngine.Vector2;
|
|
using Vector3 = UnityEngine.Vector3;
|
|
|
|
// 전투 제어 매니저.
|
|
public class BattleMgr : Singleton<BattleMgr>
|
|
{
|
|
#region Const & Values
|
|
public static int I_InitCos { get; private set; } = 1;
|
|
|
|
private const int I_MonTypeNormal = 2;
|
|
private const int I_MonTypeElite = 2;
|
|
private const int I_MonTypeBoss = 1;
|
|
private const int I_MonTypeBigBoss = 1;
|
|
private const int I_SummonMin = 5;
|
|
private const int I_SummonMax = 50;
|
|
private const int I_SummonEliteMin = 1;
|
|
private const int I_SummonEliteMax = 3;
|
|
private const int I_ObjMonCnt = (I_MonTypeNormal * I_SummonMax) + (I_MonTypeElite * I_SummonEliteMax) + I_MonTypeBoss + I_MonTypeBigBoss;
|
|
private const int I_ObjDamCnt = 200;
|
|
|
|
private static readonly Vector3 V3_CharOrigin = new Vector3(-0f, -2f, -12f);
|
|
private static readonly Vector3 V3_CharPvp = new Vector3(-10f, 0f, 0f);
|
|
private static readonly Vector3 V3_CharEnemyPvp = new Vector3(10f, 0f, 0f);
|
|
|
|
private static readonly Vector3 V3_SummonMin = new Vector3(-20f, 6f, -40f);//5 -2
|
|
private static readonly Vector3 V3_SummonMax = new Vector3(20f, 8f, 40f);//13 6
|
|
|
|
private static readonly Vector3 V3_DgSummonMin = new Vector3(-20f, 5f, -16f);
|
|
private static readonly Vector3 V3_DgSummonMax = new Vector3(20f, 13f, -16f);
|
|
|
|
private static readonly Vector3[] V3_AddSummons = new Vector3[10]
|
|
{
|
|
new Vector3(-4.5f, 0f, 0f),
|
|
new Vector3(-1.5f, 0f, 0f),
|
|
new Vector3(1.5f, 0f, 0f),
|
|
new Vector3(4.5f, 0f, 0f),
|
|
new Vector3(-3f, 3f, 0f),
|
|
new Vector3(0f, 3f, 0f),
|
|
new Vector3(3f, 3f, 0f),
|
|
new Vector3(-3f, -3f, 0f),
|
|
new Vector3(0f, -3f, 0f),
|
|
new Vector3(3f, -3f, 0f)
|
|
};
|
|
|
|
private static readonly Color CLR_DamNormal = new Color(1f, 1f, 1f);
|
|
private static readonly Color CLR_DamCritical = new Color(1f, 56f / 255f, 0f);
|
|
private static readonly Color CLR_CharDam = new Color(0.8f, 0.8f, 0.8f);
|
|
private const float F_DamNormal = 24f;
|
|
private const float F_DamCritical = 32f;
|
|
|
|
private const float F_AddYCharHp = 2.5f;
|
|
private const float F_AddYNormalHp = 2.2f;
|
|
private const float F_AddYEliteHp = 3.5f;
|
|
private const float F_AddYBossHp = 5.5f;
|
|
private const float F_AddYAwakenStoneBossHp = 7f;
|
|
private const float F_AddXAwakenStoneBossHp = 5.5f;
|
|
|
|
private const float F_AddYCharDam = 3.4f;
|
|
private const float F_AddYNormalDam = 2.6f;
|
|
private const float F_AddYEliteDam = 3.9f;
|
|
private const float F_AddYBossDam = 5.9f;
|
|
|
|
private const float F_AddYCharTalk = 2f;
|
|
|
|
private const float F_CharRangePvp = 3600000f;
|
|
private const float F_MonRangeNormal = 2500000f;
|
|
private const float F_MonRangeElite = 3000000f;
|
|
private const float F_MonRangeBoss = 3500000f;
|
|
|
|
public static bool doNotInterupt { get; private set; } = false;
|
|
#endregion Const & Values
|
|
|
|
#region Battle UI
|
|
[Header("Battle UI")]
|
|
private Camera camMain;
|
|
private Camera camUI;
|
|
[SerializeField]
|
|
private Transform trfStageInfo;
|
|
private TextMeshProUGUI txtBattleStage;
|
|
private TextMeshProUGUI txtBattleTime;
|
|
private Button btnBattleRetry;
|
|
private Image imgBattleRetry;
|
|
|
|
[SerializeField]
|
|
private Sprite sprBattleRetry, sprBattleGo, sprBossElite, sprBoss, sprAuto, sprAutoOff;
|
|
[SerializeField]
|
|
private TextMeshProUGUI txtRetry;
|
|
|
|
private Image imgBattleWave;
|
|
Image imgWaveBoss;
|
|
GameObject goWaveBossArrow;
|
|
Image[] imgWaveCapsule;
|
|
GameObject[] goWaveCapsuleArrow;
|
|
|
|
[Header("Pvp")]
|
|
[SerializeField]
|
|
private Transform trfPvp;
|
|
private TextMeshProUGUI txtPvpTime;
|
|
private Slider sldPvpMyHp, sldPvpEnemyHp;
|
|
|
|
[Header("Skill")]
|
|
[SerializeField]
|
|
private Transform trfRB;
|
|
private ButtonIV[] btnSkillPresets;
|
|
private Button[] btnSkills;
|
|
private GameObject[] goSkillEmptys;
|
|
private Image[] imgSkills;
|
|
private Image[] imgSkillBg;
|
|
private Image[] imgSkillCovers;
|
|
private TextMeshProUGUI[] txtSkills;
|
|
private Image imgBtnAuto;
|
|
private GameObject goAuto;
|
|
[SerializeField]
|
|
private TextMeshProUGUI[] txtTestDps;
|
|
[SerializeField]
|
|
private TextMeshProUGUI[] txtTestDpsDam;
|
|
[SerializeField]
|
|
private TextMeshProUGUI txtNormalAttackDpsDam;
|
|
private BigInteger[] TestDps = new BigInteger[18];
|
|
private BigInteger TestNormalAttackDps = new BigInteger();
|
|
private int timeSec = 0;
|
|
|
|
[Header("Battle Obj")]
|
|
[SerializeField]
|
|
private Canvas canvasUI;
|
|
private Image imgBattleCover;
|
|
private HpBar hpBarChar;
|
|
private HpBar hpBarCharEnemy;
|
|
|
|
private RectTransform trfHpBars;
|
|
[SerializeField]
|
|
private GameObject prfHpEnemy;
|
|
private HpBar[] hpBarEnemies;
|
|
|
|
private RectTransform trfDamages, trfCharDamages;
|
|
[SerializeField]
|
|
private GameObject prfDmgTxt;
|
|
private GameObject[] goDmgTxts;
|
|
private RectTransform[] trfDmgTxts;
|
|
private TextMeshProUGUI[] txtDmgTxts;
|
|
private DOTweenAnimation[] dtaDmgTxts;
|
|
[SerializeField]
|
|
private GameObject prfCharDmgTxt;
|
|
private GameObject[] goCharDmgTxts;
|
|
private RectTransform[] trfCharDmgTxts;
|
|
private TextMeshProUGUI[] txtCharDmgTxts;
|
|
private DOTweenAnimation[] dtaCharDmgTxts;
|
|
|
|
private RectTransform trfTxts;
|
|
private TalkBox talkBox;
|
|
#endregion Battle UI
|
|
|
|
#region UI Values
|
|
private int iLayerBg;
|
|
private int iLayerChar;
|
|
private int iLayerEffect;
|
|
#endregion UI Values
|
|
|
|
#region Battle Scene
|
|
[Header("Battle Scene")]
|
|
[SerializeField]
|
|
private SpriteRenderer srBg;
|
|
[SerializeField]
|
|
private BoxCollider colBg;
|
|
[SerializeField]
|
|
private SpriteRenderer srSkillFade;
|
|
private GameObject goBgEffect;
|
|
|
|
[Header("Battle Scene Friendly")]
|
|
[SerializeField]
|
|
private Transform trfFriendlies;
|
|
[SerializeField]
|
|
private IVCharacter ivChar;
|
|
private Transform trfChar;
|
|
[SerializeField]
|
|
private IVPet[] ivPets;
|
|
[SerializeField]
|
|
private IVGuardian ivGuardian;
|
|
[SerializeField]
|
|
private Light2D lightGlobal;
|
|
[SerializeField]
|
|
private Light2D lightChar;
|
|
[SerializeField]
|
|
private IVSummon[] ivsummons;
|
|
|
|
[Header("Battle Scene Enemy Char")]
|
|
[SerializeField]
|
|
private IVCharacter ivCharEnemy;
|
|
private Transform trfCharEnemy;
|
|
[SerializeField]
|
|
private IVPet[] ivPetsEnemy;
|
|
[SerializeField]
|
|
private IVGuardian ivGuardianEnemy;
|
|
[SerializeField]
|
|
private IVSummon[] ivsummonsEnemy;
|
|
|
|
[Header("Battle Scene Enemy")]
|
|
[SerializeField]
|
|
private Transform trfEnemies;
|
|
[SerializeField]
|
|
private GameObject prfEnemy;
|
|
private GameObject[] goMonsters;
|
|
private Transform[] trfMonsters;
|
|
private IVMonster[] ivMonsters;
|
|
#endregion Battle Scene
|
|
|
|
#region Battle Sound
|
|
[Header("Battle Sound")]
|
|
[SerializeField]
|
|
private AudioSource asSummon;
|
|
[SerializeField]
|
|
private AudioSource asUnsummon;
|
|
[SerializeField]
|
|
private AudioSource asNormalAttack;
|
|
#endregion Battle Sound
|
|
|
|
#region Battle Effect
|
|
[Header("Battle Scene Effect")]
|
|
[SerializeField]
|
|
private Transform trfEffects;
|
|
[SerializeField]
|
|
private ParticleSystem ptcLvUpChar;
|
|
private Transform trfLvUpChar;
|
|
[SerializeField]
|
|
private ParticleSystem[] ptcGoldDrops;
|
|
private Transform[] trfGoldDrops;
|
|
private TweenerCore<Vector3, Vector3, VectorOptions>[] twcGoldDropMoves;
|
|
private TweenerCore<Vector3, Vector3, VectorOptions>[] twcGoldDropScales;
|
|
|
|
[SerializeField]
|
|
private SerializedDictionary<int, IVSkill> dicIvSkill = new SerializedDictionary<int, IVSkill>();
|
|
[SerializeField]
|
|
private SerializedDictionary<int, IVSkill> dicIvSkillEnemy = new SerializedDictionary<int, IVSkill>();
|
|
#endregion Battle Scene
|
|
|
|
#region Battle Values
|
|
public bool BattlePause { get; set; } = false;
|
|
|
|
private int iLoading = 1;
|
|
private float fTick = 0f;
|
|
private float fTickSec = 0f;
|
|
|
|
private int iCosCloth = -1;
|
|
private int iCosWp = -1;
|
|
private int iCosClothEnemy = -1;
|
|
private int iCosWpEnemy = -1;
|
|
private int iCosHairEnemy = -1;
|
|
private int iCosTopEnemy = -1;
|
|
private int iCosEyeEnemy = -1;
|
|
private Texture2D tx2dCloth = null;
|
|
private Texture2D tx2dClothEnemy = null;
|
|
|
|
private int[] iSkillIds;
|
|
private float[] fSkillTimes;
|
|
private float[] fSkillTicks;
|
|
private bool bAutoSkill = true;
|
|
private bool bAutoSkillPrev = true;
|
|
private Dictionary<int, int> dicSkillIndex;
|
|
|
|
private float[] fSkillEnemyTicks;
|
|
private Dictionary<int, int> dicSkillEnemyIndex;
|
|
|
|
private int iBgId = -1;
|
|
private AsyncOperationHandle<Sprite> handleBg;
|
|
private AsyncOperationHandle<SkeletonDataAsset>[] handleSpines = new AsyncOperationHandle<SkeletonDataAsset>[8];
|
|
|
|
private int iStageTimeLeft = 90;
|
|
private int iWave = 1;
|
|
private int iTotalWave = 3;
|
|
private bool bRetry = false;
|
|
private bool bClear = false;
|
|
private bool bChangeArea = false;
|
|
private int iMonsterCount = 0;
|
|
|
|
private float[] fMonSpeedN;
|
|
private float[] fMonSpeedE;
|
|
private float[] fMonSpeedB;
|
|
private int[] iMonGroupN;
|
|
private int[] iMonGroupE;
|
|
private int[] iMonGroupB;
|
|
private BigInteger biMonAtk;
|
|
private BigInteger biMonHp;
|
|
|
|
private Sequence seqStartStage = null;
|
|
private Sequence seqDieStage = null;
|
|
private Sequence seqChangeStage = null;
|
|
private Sequence seqChangeArea = null;
|
|
private Sequence seqDungeonArea = null;
|
|
private Sequence seqDungeonStageArea = null;
|
|
|
|
private int iTalkChar = -1;
|
|
private int iTalkMax = 8;
|
|
private int iFadeCnt = 0;
|
|
private bool BgAndCameraChange = false;
|
|
private int iUseSkillid = -1;
|
|
|
|
public enum BattleType
|
|
{
|
|
Stage = 0,
|
|
GoldDungeon,
|
|
EnhanceStoneDungeon,
|
|
PetDungeon,
|
|
AwakenStoneDungeon,
|
|
AwakenDungeon,
|
|
GuardianDungeon,
|
|
RelicDungeon,
|
|
Pvp = 9
|
|
}
|
|
|
|
public static BattleType CurrentBattleType { get; private set; } = BattleType.Stage;
|
|
dPvpSpec specEnemy = null;
|
|
|
|
// 내가 상대에게 준 총 데미지.
|
|
private BigInteger biBattleDmg;
|
|
// 상대가 나에게 준 총 데미지.
|
|
private BigInteger biBattleDmgEnemy;
|
|
#endregion Battle Values
|
|
|
|
#region Level Up
|
|
[SerializeField]
|
|
LevelUpEffect levelUpEffect;
|
|
|
|
public static void LevelUpEffectOn()
|
|
{
|
|
Instance.levelUpEffect.ShowLevelUp(2f);
|
|
}
|
|
#endregion
|
|
|
|
#region Boss
|
|
[SerializeField]
|
|
SkeletonAnimation bossIncoming;
|
|
#endregion
|
|
|
|
#region Drop Item
|
|
public enum DropItemKind
|
|
{
|
|
Gold,
|
|
Exp,
|
|
Box,
|
|
ColorFlower,
|
|
MemoryPiece,
|
|
TradeEventCoin,
|
|
RaiseEventCoin,
|
|
RouletteEventCoin
|
|
}
|
|
|
|
[SerializeField]
|
|
Transform trfDropItem;
|
|
[SerializeField]
|
|
DropItemObject prfDropItem;
|
|
DropItemObject[] dropItemPool;
|
|
int dropItemPoolCount = 100;
|
|
int dropItemPoolCountNow = 0;
|
|
int[] dropItemCount = new int[8];
|
|
|
|
Stack<int> dropChestKey = new Stack<int>();
|
|
#endregion
|
|
|
|
#region StageSuccessOrFail
|
|
[Header("Success & Fail")]
|
|
[SerializeField]
|
|
GameObject stageSuccessWindow;
|
|
GoodsItem[] stageSuccessGoodsItem;
|
|
|
|
[SerializeField]
|
|
GameObject awakenSuccessWindow;
|
|
TextMeshProUGUI awakenNumber;
|
|
|
|
[SerializeField]
|
|
Canvas canvasStageFail;
|
|
GameObject groupButtonFailed;
|
|
TextMeshProUGUI[] txtLevelUpKind;
|
|
TextMeshProUGUI[] txtLevelUpGo;
|
|
TextMeshProUGUI txtJellySad;
|
|
TextMeshProUGUI txtFailed;
|
|
TextMeshProUGUI txtClose;
|
|
|
|
[SerializeField]
|
|
GameObject[] canvasStageUnlock;
|
|
TextMeshProUGUI[] txtUnlockTitle;
|
|
TextMeshProUGUI[] txtUnlockExplain;
|
|
TextMeshProUGUI[] txtBtnOk;
|
|
TextMeshProUGUI[] txtBtnGo;
|
|
DOTweenAnimation[] dotUnlock;
|
|
[SerializeField]
|
|
Sprite[] sprUnlockContent;
|
|
#endregion
|
|
|
|
int bgShitf = 0;
|
|
|
|
#region Option Values
|
|
[HideInInspector] public bool bOnSkillEffect;
|
|
[HideInInspector] public bool bOnDamageText;
|
|
#endregion Option Values
|
|
|
|
#region Time
|
|
private void Update()
|
|
{
|
|
if (BattlePause) return;
|
|
|
|
fTick += Time.deltaTime;
|
|
fTickSec += Time.deltaTime;
|
|
|
|
if (Input.GetKeyDown(KeyCode.K))
|
|
SetBgCol();
|
|
|
|
// 현재 모드 타임 아웃 체크
|
|
if (fTickSec >= 1f)
|
|
{
|
|
fTickSec -= 1f;
|
|
|
|
iStageTimeLeft--;
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
txtPvpTime.text = iStageTimeLeft.ToString();
|
|
if (iStageTimeLeft <= 0)
|
|
{
|
|
EndPvp();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
if (iStageTimeLeft <= 0)
|
|
{
|
|
FailTimeOut();
|
|
}
|
|
}
|
|
}
|
|
|
|
// 자동 스킬 쿨타임 감소 및 자동 사용 체크 시 시전 대기 스택에 넣기
|
|
if (fTick >= 0.1f)
|
|
{
|
|
fTick -= 0.1f;
|
|
|
|
for (int i = 0; i < fSkillTicks.Length; i++)
|
|
{
|
|
if (iSkillIds[i] < 0)
|
|
continue;
|
|
if (fSkillTicks[i] >= 0f)
|
|
{
|
|
fSkillTicks[i] -= 0.1f;
|
|
SetSkillUi(i);
|
|
if (fSkillTicks[i] <= 0f)
|
|
{
|
|
if (bAutoSkill)
|
|
ivChar.AddSkillAvail(iSkillIds[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
for (int i = 0; i < fSkillEnemyTicks.Length; i++)
|
|
{
|
|
if (specEnemy.skillPreset[i] < 0)
|
|
continue;
|
|
if (fSkillEnemyTicks[i] >= 0f)
|
|
{
|
|
fSkillEnemyTicks[i] -= 0.1f;
|
|
if (fSkillEnemyTicks[i] <= 0f)
|
|
{
|
|
ivCharEnemy.AddSkillAvail(specEnemy.skillPreset[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion Time
|
|
|
|
#region Init
|
|
public static void SLocalize() => Instance.Localize();
|
|
|
|
private void Localize()
|
|
{
|
|
txtLevelUpKind[0].text = FormatString.StringFormat("{0}", LocalizationText.GetText("recommand_grow"));
|
|
txtLevelUpKind[1].text = FormatString.StringFormat("{0} {1}", LocalizationText.GetText("bag_weapon"), LocalizationText.GetText("all_enhance"));
|
|
txtLevelUpKind[2].text = FormatString.StringFormat("{0} {1}", LocalizationText.GetText("skill_title"), LocalizationText.GetText("all_enhance"));
|
|
txtLevelUpKind[3].text = FormatString.StringFormat("{0} {1}", LocalizationText.GetText("pet_title"), LocalizationText.GetText("all_enhance"));
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
txtLevelUpGo[i].text = LocalizationText.GetText("shortcut");
|
|
}
|
|
|
|
txtJellySad.text = LocalizationText.GetText("stage_fail_jelly_dialogue");
|
|
txtFailed.text = LocalizationText.GetText("fail_recommand");
|
|
txtClose.text = LocalizationText.GetText("click_to_close");
|
|
|
|
SetDpsSkill();
|
|
SetRetry();
|
|
bRetry = DataHandler.PlayData.stageRepeat;
|
|
|
|
txtUnlockTitle = new TextMeshProUGUI[canvasStageUnlock.Length];
|
|
txtUnlockExplain = new TextMeshProUGUI[canvasStageUnlock.Length];
|
|
txtBtnOk = new TextMeshProUGUI[canvasStageUnlock.Length];
|
|
txtBtnGo = new TextMeshProUGUI[canvasStageUnlock.Length];
|
|
dotUnlock = new DOTweenAnimation[canvasStageUnlock.Length];
|
|
|
|
for (int i = 0; i < canvasStageUnlock.Length; i++)
|
|
{
|
|
txtUnlockTitle[i] = canvasStageUnlock[i].transform.Find("txtTitle").GetComponent<TextMeshProUGUI>();
|
|
txtUnlockExplain[i] = canvasStageUnlock[i].transform.Find("txtExplain").GetComponent<TextMeshProUGUI>();
|
|
txtBtnOk[i] = canvasStageUnlock[i].transform.Find("btnOk").transform.Find("txt").GetComponent<TextMeshProUGUI>();
|
|
txtBtnGo[i] = canvasStageUnlock[i].transform.Find("btnGo").transform.Find("txt").GetComponent<TextMeshProUGUI>();
|
|
dotUnlock[i] = canvasStageUnlock[i].GetComponent<DOTweenAnimation>();
|
|
|
|
txtBtnOk[i].text = LocalizationText.GetText("all_confirm");
|
|
txtBtnGo[i].text = LocalizationText.GetText("mission_go");
|
|
}
|
|
|
|
txtUnlockTitle[0].text = LocalizationText.GetText("unlock_gold_dg");
|
|
txtUnlockExplain[0].text = LocalizationText.GetText("unlock_gold_explain");
|
|
txtUnlockTitle[1].text = LocalizationText.GetText("unlock_enhancestone_dg");
|
|
txtUnlockExplain[1].text = LocalizationText.GetText("unlock_enhancestone_explain");
|
|
txtUnlockTitle[2].text = LocalizationText.GetText("unlock_pet_dg");
|
|
txtUnlockExplain[2].text = LocalizationText.GetText("unlock_pet_explain");
|
|
txtUnlockTitle[3].text = LocalizationText.GetText("unlock_awakenstone_dg");
|
|
txtUnlockExplain[3].text = LocalizationText.GetText("unlock_awakenstone_explain");
|
|
txtUnlockTitle[4].text = LocalizationText.GetText("unlock_awaken_dg");
|
|
txtUnlockExplain[4].text = LocalizationText.GetText("unlock_awaken_explain");
|
|
txtUnlockTitle[5].text = LocalizationText.GetText("unlock_acc");
|
|
txtUnlockExplain[5].text = LocalizationText.GetText("unlock_acc_explain");
|
|
txtUnlockTitle[6].text = LocalizationText.GetText("unlock_treasure");
|
|
txtUnlockExplain[6].text = LocalizationText.GetText("unlock_treasure_explain");
|
|
}
|
|
|
|
// 클래스 초기화. 게임 처음 시작 시 호출.
|
|
public static void SInit(Camera camui)
|
|
{
|
|
IVCameraController.SSetTrace(false);
|
|
Instance.camMain = Camera.main;
|
|
Instance.camUI = camui;
|
|
Instance.InitObject();
|
|
CustomizeMgr.SInitSkin(Instance.ivChar.GetSkeleton());
|
|
}
|
|
|
|
// 캐릭터 의상 초기화. 클래스 초기화(SInit) 완료 후 (스파인 머테리얼 자동 변경 대기를 위해) 한 프레임 건너뛰고 호출.
|
|
public static void SInitCostume()
|
|
{
|
|
Instance.StartCoroutine(nameof(InitCostume));
|
|
}
|
|
|
|
private IEnumerator InitCostume()
|
|
{
|
|
SetEnemyCostume(DataHandler.PlayEquipCostume.weaponId, DataHandler.PlayEquipCostume.outfitId, 1, 1, 1);
|
|
|
|
I_InitCos++;
|
|
iCosWp = DataHandler.PlayEquipCostume.weaponId;
|
|
AddressableMgr.LoadWeaponSpine(iCosWp, ALoadWeaponComp);
|
|
AddressableMgr.LoadWeaponAdd(iCosWp);
|
|
|
|
I_InitCos++;
|
|
iCosCloth = DataHandler.PlayEquipCostume.outfitId;
|
|
AddressableMgr.LoadClothSpine(iCosCloth, ALoadClothComp);
|
|
AddressableMgr.LoadClothAdd(iCosCloth);
|
|
|
|
while (I_InitCos > 1)
|
|
yield return null;
|
|
yield return null;
|
|
|
|
AddressableMgr.ReleaseClothSpine(iCosClothEnemy);
|
|
AddressableMgr.ReleaseWeaponSpine(iCosWpEnemy);
|
|
iCosClothEnemy = -1;
|
|
iCosWpEnemy = -1;
|
|
yield return null;
|
|
|
|
ivChar.gameObject.SetActive(false);
|
|
ivCharEnemy.gameObject.SetActive(false);
|
|
yield return null;
|
|
I_InitCos--;
|
|
}
|
|
|
|
public static void SInitStage()
|
|
{
|
|
Instance.InitStage();
|
|
}
|
|
|
|
// 스테이지 초기화. 게임 시작시 전투 시작해도 되는 타이밍에 호출(다른 초기화 완료 후).
|
|
private void InitStage()
|
|
{
|
|
iStageTimeLeft = DataHandler.Const.stageTimeout;
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
iWave = 1;
|
|
iTotalWave = GetWaveTotal();
|
|
SetWaveCapsule(iTotalWave);
|
|
GetStageItemAndGetPercent();
|
|
SetStageAreaWave(DataHandler.PlayData.curStage, iWave);
|
|
SetRetry();
|
|
iTalkChar = Random.Range(3, iTalkMax);
|
|
seqStartStage.Play();
|
|
}
|
|
|
|
private void InitDungeonStage(int dungeonLevel)//던전 진입
|
|
{
|
|
SetDungeonSetting(true);
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
SetSkillPreset();
|
|
ResetSkillCooltime();
|
|
iWave = 1;
|
|
bgShitf = 0;
|
|
shim = 0;
|
|
SetWaveCapsule(iTotalWave);
|
|
|
|
SetDungeonWave(dungeonLevel, iWave);
|
|
SetRetry();
|
|
}
|
|
|
|
Vector3 summonPos;
|
|
|
|
// 전투 오브젝트 초기화. 클래스 초기화(SInit)에서 호출.
|
|
private void InitObject()
|
|
{
|
|
iLayerBg = LayerMask.NameToLayer("BG");
|
|
iLayerChar = LayerMask.NameToLayer("Character");
|
|
iLayerEffect = LayerMask.NameToLayer("Effect");
|
|
|
|
#region Char
|
|
trfChar = ivChar.transform;
|
|
IVCameraController.SSetTarget(trfChar);
|
|
|
|
Transform trfbattleui = canvasUI.transform;
|
|
imgBattleCover = trfbattleui.Find("cover").GetComponent<Image>();
|
|
trfHpBars = trfbattleui.Find("HpBars").GetComponent<RectTransform>();
|
|
hpBarChar = trfHpBars.GetChild(0).GetComponent<HpBar>();
|
|
trfDamages = trfbattleui.Find("Damages").GetComponent<RectTransform>();
|
|
trfCharDamages = trfbattleui.Find("CharDamages").GetComponent<RectTransform>();
|
|
trfTxts = trfbattleui.Find("Txts").GetComponent<RectTransform>();
|
|
talkBox = trfTxts.GetChild(0).GetComponent<TalkBox>();
|
|
|
|
hpBarChar.SetCameraTarget(camMain, camUI, trfHpBars, ivChar.transform, F_AddYCharHp);
|
|
talkBox.SetCameraTarget(camMain, camUI, trfTxts, ivChar.transform, F_AddYCharTalk);
|
|
levelUpEffect.SetCameraTarget(camMain, camUI, trfTxts, ivChar.transform, 4f);
|
|
ivChar.Init();
|
|
ivChar.SetComponent(this, hpBarChar);
|
|
ivChar.SetFriendly(true);
|
|
ivChar.SetClassIndex(CreatureBase.eCreatureClass.character, 0);
|
|
for(int i = 0; i < ivsummons.Length; i++)
|
|
ivsummons[i].SetInit(this);
|
|
|
|
for(int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Init();
|
|
ivPets[i].OffPet();
|
|
}
|
|
ivGuardian.Init();
|
|
ivGuardian.OffGuardian();
|
|
#endregion Char
|
|
|
|
#region Enemy Char
|
|
trfCharEnemy = ivCharEnemy.transform;
|
|
|
|
hpBarCharEnemy = trfHpBars.GetChild(1).GetComponent<HpBar>();
|
|
hpBarCharEnemy.SetCameraTarget(camMain, camUI, trfHpBars, ivCharEnemy.transform, F_AddYCharHp);
|
|
|
|
ivCharEnemy.Init();
|
|
ivCharEnemy.SetComponent(this, hpBarCharEnemy);
|
|
ivCharEnemy.SetFriendly(false);
|
|
ivCharEnemy.SetClassIndex(CreatureBase.eCreatureClass.charEnemy, 0);
|
|
for(int i = 0; i < ivsummons.Length; i++)
|
|
ivsummonsEnemy[i].SetInit(this);
|
|
|
|
for(int i = 0; i < ivPetsEnemy.Length; i++)
|
|
{
|
|
ivPetsEnemy[i].Init();
|
|
ivPetsEnemy[i].OffPet();
|
|
}
|
|
ivGuardianEnemy.Init();
|
|
ivGuardianEnemy.OffGuardian();
|
|
#endregion Enemy Char
|
|
|
|
#region Monsters
|
|
hpBarEnemies = new HpBar[I_ObjMonCnt];
|
|
goMonsters = new GameObject[I_ObjMonCnt];
|
|
trfMonsters = new Transform[I_ObjMonCnt];
|
|
ivMonsters = new IVMonster[I_ObjMonCnt];
|
|
|
|
int inormalmax = I_MonTypeNormal * I_SummonMax;
|
|
int ielitemax = inormalmax + (I_MonTypeElite * I_SummonEliteMax);
|
|
int ibossmax = inormalmax + (I_MonTypeElite * I_SummonEliteMax) + I_MonTypeBoss;
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
goMonsters[i] = Instantiate(prfEnemy, trfEnemies);
|
|
goMonsters[i].name = FormatString.CombineAllString("enemy", i.ToString());
|
|
trfMonsters[i] = goMonsters[i].transform;
|
|
ivMonsters[i] = goMonsters[i].GetComponent<IVMonster>();
|
|
|
|
GameObject gohpbar = Instantiate(prfHpEnemy, trfHpBars);
|
|
gohpbar.transform.localScale = Vector3.one;
|
|
gohpbar.name = FormatString.CombineAllString("hpbar", i.ToString());
|
|
hpBarEnemies[i] = gohpbar.GetComponent<HpBar>();
|
|
|
|
ivMonsters[i].Init();
|
|
ivMonsters[i].SetComponent(this, hpBarEnemies[i]);
|
|
|
|
if (i < inormalmax)
|
|
{
|
|
hpBarEnemies[i].SetCameraTarget(camMain, camUI, trfHpBars, trfMonsters[i], F_AddYNormalHp);
|
|
ivMonsters[i].SetClassIndex(CreatureBase.eCreatureClass.normal, i);
|
|
}
|
|
else if (i < ielitemax)
|
|
{
|
|
hpBarEnemies[i].SetCameraTarget(camMain, camUI, trfHpBars, trfMonsters[i], F_AddYEliteHp);
|
|
ivMonsters[i].SetClassIndex(CreatureBase.eCreatureClass.elite, i);
|
|
}
|
|
else if(i<ibossmax)
|
|
{
|
|
hpBarEnemies[i].SetCameraTarget(camMain, camUI, trfHpBars, trfMonsters[i], F_AddYBossHp);
|
|
ivMonsters[i].SetClassIndex(CreatureBase.eCreatureClass.boss, i);
|
|
}
|
|
else
|
|
{
|
|
hpBarEnemies[i].SetCameraTarget(camMain, camUI, trfHpBars, trfMonsters[i], F_AddYAwakenStoneBossHp);
|
|
ivMonsters[i].SetClassIndex(CreatureBase.eCreatureClass.bigboss, i);
|
|
}
|
|
goMonsters[i].SetActive(false);
|
|
hpBarEnemies[i].gameObject.SetActive(false);
|
|
}
|
|
#endregion Monsters
|
|
|
|
#region Effects
|
|
trfLvUpChar = ptcLvUpChar.transform;
|
|
|
|
trfGoldDrops = new Transform[ptcGoldDrops.Length];
|
|
twcGoldDropMoves = new TweenerCore<Vector3, Vector3, VectorOptions>[ptcGoldDrops.Length];
|
|
twcGoldDropScales = new TweenerCore<Vector3, Vector3, VectorOptions>[ptcGoldDrops.Length];
|
|
for (int i = 0; i < ptcGoldDrops.Length; i++)
|
|
{
|
|
trfGoldDrops[i] = ptcGoldDrops[i].transform;
|
|
twcGoldDropMoves[i] = trfGoldDrops[i].DOMove(trfChar.position, 0.3f).SetEase(Ease.InQuad)
|
|
.OnComplete(() =>
|
|
{
|
|
ptcGoldDrops[i].Stop();
|
|
trfGoldDrops[i].gameObject.SetActive(false);
|
|
}).SetAutoKill(false).Pause();
|
|
twcGoldDropScales[i] = trfGoldDrops[i].DOScale(Global.V3_001, 0.25f).SetEase(Ease.InQuad).SetAutoKill(false).Pause();
|
|
}
|
|
|
|
foreach (var item in dicIvSkill)
|
|
item.Value.Init(this);
|
|
foreach (var item in dicIvSkillEnemy)
|
|
item.Value.Init(this);
|
|
#endregion Effects
|
|
|
|
#region Drop Item
|
|
//poolCount 는 변수목록에 있음
|
|
dropItemPool = new DropItemObject[dropItemPoolCount];
|
|
|
|
for (int i = 0; i < dropItemPoolCount; i++)
|
|
{
|
|
dropItemPool[i] = Instantiate(prfDropItem, trfDropItem);
|
|
dropItemPool[i].gameObject.SetActive(false);
|
|
}
|
|
#endregion
|
|
|
|
#region UI
|
|
int ipresetlen = DataHandler.PlayData.skillPresets.Length;
|
|
int iskilllen = DataHandler.PlayData.skillPresets[0].Length;
|
|
btnSkillPresets = new ButtonIV[ipresetlen];
|
|
|
|
btnSkills = new Button[iskilllen];
|
|
goSkillEmptys = new GameObject[iskilllen];
|
|
imgSkills = new Image[iskilllen];
|
|
imgSkillBg = new Image[iskilllen];
|
|
imgSkillCovers = new Image[iskilllen];
|
|
txtSkills = new TextMeshProUGUI[iskilllen];
|
|
|
|
iSkillIds = new int[iskilllen];
|
|
fSkillTimes = new float[iskilllen];
|
|
fSkillTicks = new float[iskilllen];
|
|
dicSkillIndex = new Dictionary<int, int>();
|
|
|
|
fSkillEnemyTicks = new float[iskilllen];
|
|
dicSkillEnemyIndex = new Dictionary<int, int>();
|
|
|
|
int irblen = trfRB.childCount;
|
|
for (int i = 0; i < irblen; i++)
|
|
{
|
|
int index = i;
|
|
if (i < ipresetlen)
|
|
{
|
|
btnSkillPresets[index] = trfRB.GetChild(i).GetComponent<ButtonIV>();
|
|
continue;
|
|
}
|
|
|
|
index -= ipresetlen;
|
|
if (index >= iskilllen)
|
|
break;
|
|
|
|
btnSkills[index] = trfRB.GetChild(i).GetComponent<Button>();
|
|
goSkillEmptys[index] = btnSkills[index].transform.Find("ic").gameObject;
|
|
imgSkills[index] = btnSkills[index].transform.Find("icon").GetComponent<Image>();
|
|
imgSkillBg[index] = btnSkills[index].transform.Find("bg").GetComponent<Image>();
|
|
imgSkillCovers[index] = btnSkills[index].transform.Find("cover").GetComponent<Image>();
|
|
txtSkills[index] = btnSkills[index].transform.Find("txtSec").GetComponent<TextMeshProUGUI>();
|
|
btnSkills[index].interactable = false;
|
|
}
|
|
SetSkillPreset();
|
|
|
|
imgBtnAuto = trfRB.Find("btnAuto").GetComponent<Image>();
|
|
goAuto = imgBtnAuto.transform.GetChild(0).gameObject;
|
|
if (bAutoSkill)
|
|
{
|
|
imgBtnAuto.sprite = sprAuto;
|
|
goAuto.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
imgBtnAuto.sprite = sprAutoOff;
|
|
goAuto.SetActive(false);
|
|
}
|
|
|
|
txtBattleStage = trfStageInfo.Find("txtStage").GetComponent<TextMeshProUGUI>();
|
|
txtBattleTime = trfStageInfo.Find("txtTime").GetComponent<TextMeshProUGUI>();
|
|
btnBattleRetry = trfStageInfo.Find("btnRetry").GetComponent<Button>();
|
|
imgBattleRetry = btnBattleRetry.GetComponent<Image>();
|
|
Transform trfwave = trfStageInfo.Find("WaveBar");
|
|
imgBattleWave = trfwave.Find("WaveBarFill").GetComponent<Image>();
|
|
imgWaveBoss = trfwave.Find("WaveBoss").GetComponent<Image>();
|
|
goWaveBossArrow = trfwave.Find("BossArrow").gameObject;
|
|
Sequence seqboss = DOTween.Sequence()
|
|
.SetAutoKill(false)
|
|
.SetUpdate(true)
|
|
.Append(imgWaveBoss.GetComponent<RectTransform>().DOScale(new Vector3(1.08f, 1.08f, 1f), 0.12f))
|
|
.Append(imgWaveBoss.GetComponent<RectTransform>().DOScale(Vector3.one, 0.12f))
|
|
.AppendInterval(0.76f)
|
|
.SetLoops(-1)
|
|
.Play();
|
|
|
|
Transform trfwavecapsule = trfwave.Find("Content");
|
|
int icaplen = trfwavecapsule.childCount;
|
|
imgWaveCapsule = new Image[icaplen];
|
|
goWaveCapsuleArrow = new GameObject[icaplen];
|
|
for (int i = 0; i < icaplen; i++)
|
|
{
|
|
imgWaveCapsule[i] = trfwavecapsule.GetChild(i).GetComponent<Image>();
|
|
goWaveCapsuleArrow[i] = imgWaveCapsule[i].transform.GetChild(0).gameObject;
|
|
}
|
|
|
|
stageSuccessGoodsItem = stageSuccessWindow.transform.Find("bg").Find("GetGoodsScroll").GetChild(0).GetComponentsInChildren<GoodsItem>(true);
|
|
awakenNumber = awakenSuccessWindow.transform.Find("bg").Find("GetGoodsScroll").GetChild(0).GetChild(1).GetChild(0).GetChild(0).GetComponent<TextMeshProUGUI>();
|
|
|
|
Transform trffail = canvasStageFail.transform;
|
|
groupButtonFailed = trffail.Find("GroupButtonFailed").gameObject;
|
|
txtFailed = trffail.Find("txtFailed").GetComponent<TextMeshProUGUI>();
|
|
txtJellySad = trffail.Find("sadJelly").GetChild(0).GetComponent<TextMeshProUGUI>();
|
|
txtClose = trffail.Find("imgClose").GetChild(0).GetComponent<TextMeshProUGUI>();
|
|
txtLevelUpKind = new TextMeshProUGUI[5];
|
|
txtLevelUpGo = new TextMeshProUGUI[5];
|
|
TextMeshProUGUI[] txtListKindGo = groupButtonFailed.GetComponentsInChildren<TextMeshProUGUI>(true);
|
|
for (int i = 0; i < txtListKindGo.Length; i += 2)
|
|
{
|
|
txtLevelUpKind[i / 2] = txtListKindGo[i];
|
|
txtLevelUpGo[i / 2] = txtListKindGo[i + 1];
|
|
}
|
|
|
|
txtPvpTime = trfPvp.Find("txtTime").GetComponent<TextMeshProUGUI>();
|
|
sldPvpMyHp = trfPvp.Find("sldMyHp").GetComponent<Slider>();
|
|
sldPvpEnemyHp = trfPvp.Find("sldEnemyHp").GetComponent<Slider>();
|
|
|
|
UnlockCheck();
|
|
|
|
Localize();
|
|
#endregion UI
|
|
|
|
#region Txts
|
|
goDmgTxts = new GameObject[I_ObjDamCnt];
|
|
trfDmgTxts = new RectTransform[I_ObjDamCnt];
|
|
txtDmgTxts = new TextMeshProUGUI[I_ObjDamCnt];
|
|
dtaDmgTxts = new DOTweenAnimation[I_ObjDamCnt];
|
|
|
|
goCharDmgTxts = new GameObject[I_ObjDamCnt];
|
|
trfCharDmgTxts = new RectTransform[I_ObjDamCnt];
|
|
txtCharDmgTxts = new TextMeshProUGUI[I_ObjDamCnt];
|
|
dtaCharDmgTxts = new DOTweenAnimation[I_ObjDamCnt];
|
|
|
|
for (int i = 0; i < I_ObjDamCnt; i++)
|
|
{
|
|
goDmgTxts[i] = Instantiate(prfDmgTxt, trfDamages);
|
|
goCharDmgTxts[i] = Instantiate(prfCharDmgTxt, trfCharDamages);
|
|
|
|
goDmgTxts[i].name = FormatString.CombineAllString("txtdam", i.ToString());
|
|
goCharDmgTxts[i].name = FormatString.CombineAllString("txtdam", i.ToString());
|
|
|
|
trfDmgTxts[i] = goDmgTxts[i].GetComponent<RectTransform>();
|
|
txtDmgTxts[i] = goDmgTxts[i].GetComponent<TextMeshProUGUI>();
|
|
dtaDmgTxts[i] = goDmgTxts[i].GetComponent<DOTweenAnimation>();
|
|
|
|
trfCharDmgTxts[i] = goCharDmgTxts[i].GetComponent<RectTransform>();
|
|
txtCharDmgTxts[i] = goCharDmgTxts[i].GetComponent<TextMeshProUGUI>();
|
|
dtaCharDmgTxts[i] = goCharDmgTxts[i].GetComponent<DOTweenAnimation>();
|
|
|
|
goDmgTxts[i].gameObject.SetActive(false);
|
|
goCharDmgTxts[i].gameObject.SetActive(false);
|
|
}
|
|
#endregion Txts
|
|
|
|
#region On Game Start
|
|
seqStartStage = DOTween.Sequence()
|
|
.SetAutoKill(false)
|
|
.SetUpdate(false)
|
|
.AppendCallback(() =>
|
|
{
|
|
imgBattleCover.color = Color.black;
|
|
imgBattleCover.gameObject.SetActive(true);
|
|
IVCameraController.SMoveCamera(V3_CharOrigin);
|
|
iStageTimeLeft = DataHandler.Const.stageTimeout;
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
iWave = 1;
|
|
iTotalWave = GetWaveTotal();
|
|
SetWaveCapsule(iTotalWave);
|
|
SetBg(DataHandler.GetArea(DataHandler.PlayData.curStage).bgId);
|
|
InitMonArea();
|
|
SetStageAreaWave(DataHandler.PlayData.curStage, iWave);
|
|
})
|
|
.Append(imgBattleCover.DOFade(0f, 1f))
|
|
.AppendCallback(() =>
|
|
{
|
|
imgBattleCover.gameObject.SetActive(false);
|
|
ivChar.ResetDebuff();
|
|
ivChar.SetStatus(BuffMgr.Instance.GetCharAtk(), BuffMgr.Instance.GetCharHp(),
|
|
BuffMgr.Instance.GetCharCrtDam(), BuffMgr.Instance.GetCharCrtRate(), BuffMgr.Instance.GetCharMov(), BuffMgr.Instance.GetCharSpd(), GameProperty.Instance.PlayerCharacterAttackRange);
|
|
|
|
ivChar.Summon(new Vector3(10000f, 10000f, 0f), true);
|
|
StartCoroutine(nameof(LightCharOn));
|
|
|
|
SkillFade(false, true);
|
|
})
|
|
.AppendInterval(0.3f)
|
|
.AppendCallback(() =>
|
|
{
|
|
ivChar.transform.position = V3_CharOrigin;
|
|
if (SoundMgr.EfcOn)
|
|
asSummon.Play();
|
|
})
|
|
.AppendInterval(0.5f)
|
|
.AppendCallback(() =>
|
|
{
|
|
ShowTalkBox();
|
|
SummonMonStage();
|
|
IVCameraController.SSetTrace(true);
|
|
BattlePause = false;
|
|
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Summon();
|
|
}
|
|
ivGuardian.Summon();
|
|
})
|
|
.Pause();
|
|
#endregion On Game Start
|
|
|
|
#region On Die Stage
|
|
seqDieStage = DOTween.Sequence()
|
|
.SetAutoKill(false)
|
|
.SetUpdate(false)
|
|
.AppendCallback(() =>
|
|
{
|
|
doNotInterupt = true;
|
|
|
|
// 배틀 멈춤, 카메라 멈춤.
|
|
BattlePause = true;
|
|
IVCameraController.SSetTrace(false);
|
|
StartCoroutine(nameof(LightCharOff));
|
|
})
|
|
.AppendInterval(1f)
|
|
.AppendCallback(() =>
|
|
{
|
|
imgBattleCover.gameObject.SetActive(true);
|
|
})
|
|
.Append(imgBattleCover.DOFade(1f, 0.5f))
|
|
.AppendCallback(() =>
|
|
{
|
|
StopAllSkill();
|
|
UnsummonMon();
|
|
for(int i = 0; i < ivPets.Length; ++i)
|
|
{
|
|
ivPets[i].OffPet();
|
|
}
|
|
|
|
OpenFailScroll();
|
|
|
|
talkBox.HideObject();
|
|
if (BgAndCameraChange)
|
|
{
|
|
ResetBgScroll();
|
|
IVCameraController.CameraXRangeChange(25);
|
|
BgAndCameraChange = false;
|
|
}
|
|
|
|
Vector3 v3spos = (V3_CharOrigin);
|
|
v3spos.z = v3spos.y * 2;
|
|
trfChar.position = v3spos;
|
|
// 카메라 이동.
|
|
IVCameraController.SMoveToCamera(0.8f, trfChar.position);
|
|
|
|
iStageTimeLeft = DataHandler.Const.stageTimeout;
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
iWave = 1;
|
|
iTotalWave = GetWaveTotal();
|
|
SetWaveCapsule(iTotalWave);
|
|
GetStageItemAndGetPercent();
|
|
|
|
if (bChangeArea)
|
|
{
|
|
SetBg(DataHandler.GetArea(DataHandler.PlayData.curStage).bgId);
|
|
InitMonArea();
|
|
}
|
|
SetStageAreaWave(DataHandler.PlayData.curStage, iWave);
|
|
StageMgr.SRefreshStage();
|
|
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.stage);
|
|
SkillFade(false, true);
|
|
})
|
|
.Append(imgBattleCover.DOFade(0f, 0.5f))
|
|
.AppendInterval(2.5f)
|
|
.AppendCallback(() =>
|
|
{
|
|
CloseFailScroll();
|
|
|
|
if (bChangeArea)
|
|
{
|
|
AddressableMgr.SForceUnload();
|
|
}
|
|
imgBattleCover.gameObject.SetActive(false);
|
|
ivChar.ResetDebuff();
|
|
ivChar.SetStatus(BuffMgr.Instance.GetCharAtk(), BuffMgr.Instance.GetCharHp(),
|
|
BuffMgr.Instance.GetCharCrtDam(), BuffMgr.Instance.GetCharCrtRate(), BuffMgr.Instance.GetCharMov(), BuffMgr.Instance.GetCharSpd(), GameProperty.Instance.PlayerCharacterAttackRange);
|
|
|
|
summonPos = ivChar.transform.position;
|
|
ivChar.transform.position = new Vector3(10000f, 10000f, 0f);
|
|
ivChar.Summon();
|
|
StartCoroutine(nameof(LightCharOn));
|
|
})
|
|
.AppendInterval(0.3f)//캐릭터를 소환할때 애니메이션상으로 소환이 안 되는데, 이 타이밍에 옷을 갈아끼우고 애니메이션이 나오도록 함.
|
|
.AppendCallback(() =>
|
|
{
|
|
BattleMgr.SRefreshCharCloth();
|
|
|
|
ivChar.transform.position = summonPos;
|
|
if (SoundMgr.EfcOn)
|
|
asSummon.Play();
|
|
})
|
|
.AppendInterval(0.5f)
|
|
.AppendCallback(() =>
|
|
{
|
|
ShowTalkBox();
|
|
SummonMonStage();
|
|
IVCameraController.SSetTrace(true);
|
|
BattlePause = false;
|
|
|
|
SetCharCostume();
|
|
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Summon();
|
|
}
|
|
ivGuardian.Summon();
|
|
|
|
doNotInterupt = false;
|
|
})
|
|
.Pause();
|
|
#endregion On Die Stage
|
|
|
|
#region On Stage Change
|
|
seqChangeStage = DOTween.Sequence()//반복
|
|
.SetAutoKill(false)
|
|
.SetUpdate(false)
|
|
.AppendCallback(() =>
|
|
{
|
|
doNotInterupt = true;
|
|
|
|
// 배틀 멈춤, 카메라 멈춤.
|
|
BattlePause = true;
|
|
IVCameraController.SSetTrace(false);
|
|
if (bClear)
|
|
{
|
|
bool blvup = AddStageExpGold();
|
|
MissionMgr.SRefreshMission();
|
|
if (blvup)
|
|
{
|
|
PlayPtcLvUp(trfChar.position);
|
|
GameUIMgr.SSetPlayerLv();
|
|
}
|
|
bClear = false;
|
|
}
|
|
})
|
|
.AppendInterval(0.8f)
|
|
.AppendCallback(() =>
|
|
{
|
|
// 소환 해제.
|
|
UnsummonMon();
|
|
if (SoundMgr.EfcOn)
|
|
asUnsummon.Play();
|
|
ivChar.Unsummon();
|
|
allDisableSummons(true);
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Unsummon();
|
|
}
|
|
ivGuardian.Unsummon();
|
|
StartCoroutine(nameof(LightCharOff));
|
|
})
|
|
.AppendInterval(1.2f)
|
|
.AppendCallback(() =>
|
|
{
|
|
CloseSuccessWindow();
|
|
|
|
StopAllSkill();
|
|
talkBox.HideObject();
|
|
})
|
|
.AppendInterval(0.8f)
|
|
.AppendCallback(() =>
|
|
{
|
|
if (isUnlockCheck)
|
|
{
|
|
ContentUnlockCheck(DataHandler.PlayData.clearStage);
|
|
}
|
|
|
|
iStageTimeLeft = DataHandler.Const.stageTimeout;
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
iWave = 1;
|
|
iTotalWave = GetWaveTotal();
|
|
SetWaveCapsule(iTotalWave);
|
|
GetStageItemAndGetPercent();
|
|
SetStageAreaWave(DataHandler.PlayData.curStage, iWave);
|
|
ivChar.ResetDebuff();
|
|
ivChar.SetStatus(BuffMgr.Instance.GetCharAtk(), BuffMgr.Instance.GetCharHp(),
|
|
BuffMgr.Instance.GetCharCrtDam(), BuffMgr.Instance.GetCharCrtRate(), BuffMgr.Instance.GetCharMov(), BuffMgr.Instance.GetCharSpd(), GameProperty.Instance.PlayerCharacterAttackRange);
|
|
|
|
Vector3 v3spos = (V3_CharOrigin);
|
|
v3spos.z = v3spos.y * 2;
|
|
ivChar.Summon(v3spos, true);
|
|
IVCameraController.SMoveToCamera(0.8f, trfChar.position);
|
|
|
|
StartCoroutine(nameof(LightCharOn));
|
|
StageMgr.SRefreshStage();
|
|
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.stage);
|
|
SkillFade(false, true);
|
|
})
|
|
.AppendInterval(0.3f)
|
|
.AppendCallback(() =>
|
|
{
|
|
if (SoundMgr.EfcOn)
|
|
asSummon.Play();
|
|
})
|
|
.AppendInterval(0.5f)
|
|
.AppendCallback(() =>
|
|
{
|
|
ShowTalkBox();
|
|
SummonMonStage();
|
|
IVCameraController.SSetTrace(true);
|
|
BattlePause = false;
|
|
|
|
SetCharCostume();
|
|
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Summon();
|
|
}
|
|
ivGuardian.Summon();
|
|
|
|
doNotInterupt = false;
|
|
})
|
|
.Pause();
|
|
#endregion On Stage Change
|
|
|
|
#region On Area Change
|
|
seqChangeArea = DOTween.Sequence()//진행
|
|
.SetAutoKill(false)
|
|
.SetUpdate(false)
|
|
.AppendCallback(() =>
|
|
{
|
|
doNotInterupt = true;
|
|
|
|
// 배틀 멈춤, 카메라 멈춤.
|
|
BattlePause = true;
|
|
IVCameraController.SSetTrace(false);
|
|
if (bClear)
|
|
{
|
|
MissionMgr.SRefreshMission();
|
|
bool blvup = AddStageExpGold();
|
|
if (blvup)
|
|
{
|
|
PlayPtcLvUp(trfChar.position);
|
|
GameUIMgr.SSetPlayerLv();
|
|
}
|
|
bClear = false;
|
|
}
|
|
})
|
|
.AppendInterval(0.8f)
|
|
.AppendCallback(() =>
|
|
{
|
|
// 소환 해제.
|
|
UnsummonMon();
|
|
if (SoundMgr.EfcOn)
|
|
asUnsummon.Play();
|
|
ivChar.Unsummon();
|
|
allDisableSummons(true);
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Unsummon();
|
|
}
|
|
ivGuardian.Unsummon();
|
|
StartCoroutine("LightCharOff");
|
|
})
|
|
.AppendInterval(1.2f)
|
|
.AppendCallback(() =>
|
|
{
|
|
imgBattleCover.gameObject.SetActive(true);
|
|
CloseSuccessWindow();
|
|
})
|
|
.Append(imgBattleCover.DOFade(1f, 0.5f))
|
|
.AppendCallback(() =>
|
|
{
|
|
StopAllSkill();
|
|
talkBox.HideObject();
|
|
if (BgAndCameraChange)
|
|
{
|
|
ResetBgScroll();
|
|
IVCameraController.CameraXRangeChange(25);
|
|
BgAndCameraChange = false;
|
|
}
|
|
|
|
// 캐릭터 위치 랜덤.
|
|
//Vector3 v3spos = new Vector3(Random.Range(V3_SummonMin.x, V3_SummonMax.x), Random.Range(V3_SummonMin.y, V3_SummonMax.y), 0f);
|
|
Vector3 v3spos = (V3_CharOrigin);
|
|
v3spos.z = v3spos.y * 2;
|
|
trfChar.position = v3spos;
|
|
// 카메라 이동.
|
|
IVCameraController.SMoveCamera(trfChar.position);
|
|
|
|
if (isUnlockCheck)
|
|
{
|
|
ContentUnlockCheck(DataHandler.PlayData.clearStage);
|
|
}
|
|
|
|
iStageTimeLeft = DataHandler.Const.stageTimeout;
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
iWave = 1;
|
|
iTotalWave = GetWaveTotal();
|
|
SetWaveCapsule(iTotalWave);
|
|
GetStageItemAndGetPercent();
|
|
SetBg(DataHandler.GetArea(DataHandler.PlayData.curStage).bgId);
|
|
InitMonArea();
|
|
SetStageAreaWave(DataHandler.PlayData.curStage, iWave);
|
|
StageMgr.SRefreshStage();
|
|
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.stage);
|
|
SkillFade(false, true);
|
|
})
|
|
.AppendInterval(0.2f)
|
|
.Append(imgBattleCover.DOFade(0f, 0.5f))
|
|
.AppendCallback(() =>
|
|
{
|
|
AddressableMgr.SForceUnload();
|
|
imgBattleCover.gameObject.SetActive(false);
|
|
ivChar.ResetDebuff();
|
|
ivChar.SetStatus(BuffMgr.Instance.GetCharAtk(), BuffMgr.Instance.GetCharHp(),
|
|
BuffMgr.Instance.GetCharCrtDam(), BuffMgr.Instance.GetCharCrtRate(), BuffMgr.Instance.GetCharMov(), BuffMgr.Instance.GetCharSpd(), GameProperty.Instance.PlayerCharacterAttackRange);
|
|
ivChar.Summon();
|
|
StartCoroutine("LightCharOn");
|
|
})
|
|
.AppendInterval(0.3f)//캐릭터를 소환할때 애니메이션상으로 소환이 안 되는데, 이 타이밍에 옷을 갈아끼우고 애니메이션이 나오도록 함.
|
|
.AppendCallback(() =>
|
|
{
|
|
BattleMgr.SRefreshCharCloth();
|
|
if (SoundMgr.EfcOn)
|
|
asSummon.Play();
|
|
})
|
|
.AppendInterval(0.5f)
|
|
.AppendCallback(() =>
|
|
{
|
|
ShowTalkBox();
|
|
SummonMonStage();
|
|
IVCameraController.SSetTrace(true);
|
|
BattlePause = false;
|
|
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Summon();
|
|
}
|
|
ivGuardian.Summon();
|
|
|
|
doNotInterupt = false;
|
|
})
|
|
.Pause();
|
|
#endregion On Area Change
|
|
|
|
#region On Dungeon Change
|
|
seqDungeonArea = DOTween.Sequence()//던전 진입시 실행
|
|
.SetAutoKill(false)
|
|
.SetUpdate(false)
|
|
.AppendCallback(() =>
|
|
{
|
|
doNotInterupt = true;
|
|
|
|
// 배틀 멈춤, 카메라 멈춤.
|
|
BattlePause = true;
|
|
IVCameraController.SSetTrace(false);
|
|
if (bClear)
|
|
{
|
|
bClear = false;
|
|
}
|
|
})
|
|
.AppendInterval(0.8f)
|
|
.AppendCallback(() =>
|
|
{
|
|
// 소환 해제.
|
|
UnsummonMon();
|
|
if (SoundMgr.EfcOn)
|
|
asUnsummon.Play();
|
|
ivChar.Unsummon();
|
|
allDisableSummons(true);
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Unsummon();
|
|
}
|
|
ivGuardian.Unsummon();
|
|
})
|
|
.AppendInterval(0.8f)
|
|
.AppendCallback(() =>
|
|
{
|
|
imgBattleCover.gameObject.SetActive(true);
|
|
CloseSuccessWindow();
|
|
})
|
|
.Append(imgBattleCover.DOFade(1f, 0.5f))
|
|
.AppendCallback(() =>
|
|
{
|
|
SetBg(DungeonMgr.GetDungeonBg());
|
|
if (BgAndCameraChange)
|
|
{
|
|
ResetBgScroll();
|
|
IVCameraController.CameraXRangeChange(25);
|
|
BgAndCameraChange = false;
|
|
}
|
|
|
|
StopAllSkill();
|
|
Vector3 v3spos;
|
|
// 캐릭터 위치 랜덤.
|
|
if (DungeonMgr.GetDungeonKind() == DungeonMgr.DungeonKind.EnhanceStoneDG)
|
|
{
|
|
v3spos = new Vector3(-20f, 2f, 0f);
|
|
IVCameraController.CameraXRangeChange(1000);
|
|
BgAndCameraChange = true;
|
|
}
|
|
else if (DungeonMgr.GetDungeonKind() == DungeonMgr.DungeonKind.GuardianDG)
|
|
{
|
|
v3spos = new Vector3(-20f, -6f, 0f);
|
|
GuardianMgr.setActiveRobot(true);
|
|
}
|
|
else
|
|
{
|
|
v3spos = new Vector3(Random.Range(V3_DgSummonMin.x, V3_DgSummonMax.x), Random.Range(V3_DgSummonMin.y, V3_DgSummonMax.y), 0f);
|
|
}
|
|
v3spos.z = v3spos.y * 2;
|
|
trfChar.position = v3spos;
|
|
// 카메라 이동.
|
|
IVCameraController.SMoveCamera(trfChar.position);
|
|
//현재 적과 제한시간과 배경 등등을 설정
|
|
SetDungeonSetting(false);
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
iWave = 1;
|
|
|
|
InitMonDungeon();
|
|
|
|
switch (DungeonMgr.GetDungeonKind())
|
|
{
|
|
case DungeonMgr.DungeonKind.GoldDG:
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.goldDg);//진입브금 * 1부터 시작함(배열상으로는 0)
|
|
break;
|
|
case DungeonMgr.DungeonKind.EnhanceStoneDG:
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.enhanceDg);
|
|
break;
|
|
case DungeonMgr.DungeonKind.PetDG:
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.petDg);
|
|
break;
|
|
case DungeonMgr.DungeonKind.AwakenStoneDG:
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.awakenStoneDg);
|
|
break;
|
|
case DungeonMgr.DungeonKind.AwakenDG:
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.awakenDg);
|
|
break;
|
|
case DungeonMgr.DungeonKind.GuardianDG:
|
|
SoundMgr.SPlayBgm(IVDataFormat.BGM.guardian);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
SkillFade(false, true);
|
|
})
|
|
.AppendInterval(0.2f)
|
|
.Append(imgBattleCover.DOFade(0f, 0.5f))
|
|
.AppendCallback(() =>
|
|
{
|
|
imgBattleCover.gameObject.SetActive(false);
|
|
ivChar.ResetDebuff();
|
|
ivChar.SetStatus(BuffMgr.Instance.GetCharAtk(), BuffMgr.Instance.GetCharHp(),
|
|
BuffMgr.Instance.GetCharCrtDam(), BuffMgr.Instance.GetCharCrtRate(), BuffMgr.Instance.GetCharMov(), BuffMgr.Instance.GetCharSpd(), GameProperty.Instance.PlayerCharacterAttackRange);
|
|
ivChar.Summon();
|
|
})
|
|
.AppendInterval(0.3f)
|
|
.AppendCallback(() =>
|
|
{
|
|
BattleMgr.SRefreshCharCloth();
|
|
if (SoundMgr.EfcOn)
|
|
asSummon.Play();
|
|
})
|
|
.AppendInterval(0.5f)
|
|
.AppendCallback(() =>
|
|
{
|
|
ShowTalkBox();
|
|
SummonMonDungeon();
|
|
IVCameraController.SSetTrace(true);
|
|
BattlePause = false;
|
|
|
|
DungeonMgr.OnOffBtnDungeonOut(true);
|
|
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Summon();
|
|
}
|
|
ivGuardian.Summon();
|
|
|
|
doNotInterupt = false;
|
|
})
|
|
.Pause();
|
|
#endregion
|
|
|
|
#region On Dungeon Stage Change
|
|
seqDungeonStageArea = DOTween.Sequence()//던전 진입시 실행
|
|
.SetAutoKill(false)
|
|
.SetUpdate(false)
|
|
.AppendCallback(() =>
|
|
{
|
|
doNotInterupt = true;
|
|
|
|
// 배틀 멈춤, 카메라 멈춤.
|
|
BattlePause = true;
|
|
IVCameraController.SSetTrace(false);
|
|
})
|
|
.AppendInterval(0.8f)
|
|
.AppendCallback(() =>
|
|
{
|
|
// 골드 획득.
|
|
// 소환 해제.
|
|
UnsummonMon();
|
|
if (SoundMgr.EfcOn)
|
|
asUnsummon.Play();
|
|
ivChar.Unsummon();
|
|
allDisableSummons(true);
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Unsummon();
|
|
}
|
|
ivGuardian.Unsummon();
|
|
})
|
|
.AppendInterval(0.8f)
|
|
.AppendCallback(() =>
|
|
{
|
|
StopAllSkill();
|
|
talkBox.HideObject();
|
|
// 캐릭터 위치 랜덤.
|
|
Vector3 v3spos = new Vector3(Random.Range(V3_SummonMin.x, V3_SummonMax.x), Random.Range(V3_SummonMin.y, V3_SummonMax.y), 0f);
|
|
v3spos.z = v3spos.y * 2;
|
|
trfChar.position = v3spos;
|
|
// 카메라 이동.
|
|
IVCameraController.SMoveToCamera(0.8f, trfChar.position);
|
|
})
|
|
.AppendInterval(0.8f)
|
|
.AppendCallback(() =>
|
|
{
|
|
SetDungeonSetting(false);
|
|
txtBattleTime.text = FormatString.TextTimeSec(iStageTimeLeft);
|
|
iWave = 1;
|
|
|
|
SetDungeonWave(DungeonMgr.GetDungeonLevel(), iWave);
|
|
ivChar.ResetDebuff();
|
|
ivChar.SetStatus(BuffMgr.Instance.GetCharAtk(), BuffMgr.Instance.GetCharHp(),
|
|
BuffMgr.Instance.GetCharCrtDam(), BuffMgr.Instance.GetCharCrtRate(), BuffMgr.Instance.GetCharMov(), BuffMgr.Instance.GetCharSpd(), GameProperty.Instance.PlayerCharacterAttackRange);
|
|
ivChar.Summon();
|
|
SkillFade(false, true);
|
|
//ResetFade();
|
|
})
|
|
.AppendInterval(0.3f)
|
|
.AppendCallback(() =>
|
|
{
|
|
BattleMgr.SRefreshCharCloth();
|
|
//for (int i = 0; i < ivPets.Length; i++)
|
|
//{
|
|
// ivPets[i].Summon();
|
|
//}
|
|
if (SoundMgr.EfcOn)
|
|
asSummon.Play();
|
|
})
|
|
.AppendInterval(0.5f)
|
|
.AppendCallback(() =>
|
|
{
|
|
ShowTalkBox();
|
|
SummonMonDungeon();
|
|
IVCameraController.SSetTrace(true);
|
|
BattlePause = false;
|
|
|
|
for (int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].Summon();
|
|
}
|
|
ivGuardian.Summon();
|
|
|
|
doNotInterupt = false;
|
|
})
|
|
.Pause();
|
|
#endregion
|
|
|
|
iLoading--;
|
|
}
|
|
|
|
private bool AddStageExpGold()
|
|
{
|
|
if (CurrentBattleType != BattleType.Stage) return false;
|
|
|
|
dArea areadata = DataHandler.GetArea(DataHandler.PlayData.curStage);
|
|
|
|
BigInteger gold = areadata.gold;
|
|
gold = gold * (BigInteger)BuffMgr.Instance.GetGoldDropRate() / dConst.RateMax;
|
|
|
|
BigInteger exp = areadata.exp;
|
|
exp = exp * (BigInteger)BuffMgr.Instance.GetExpDropRate() / dConst.RateMax;
|
|
|
|
DataHandler.AddGold(gold);
|
|
|
|
if (!EnhanceMgr.IsMainEnhanceBedgeOn())
|
|
EnhanceMgr.CheckBedge();
|
|
|
|
return DataHandler.AddPlayerExp(exp);
|
|
}
|
|
#endregion Init
|
|
|
|
#region Base
|
|
// 백버튼 처리.
|
|
public static bool SCloseMenu()
|
|
{
|
|
return Instance.CloseMenu();
|
|
}
|
|
|
|
private bool CloseMenu()
|
|
{
|
|
// 스테이지 실패 팝업.
|
|
if (canvasStageFail.enabled)
|
|
{
|
|
CloseFailScroll();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
#endregion Base
|
|
|
|
#region Control Scene
|
|
// 전투 카메라 켜기.
|
|
public static void SSetCameraOn(bool bvalue)
|
|
{
|
|
if (bvalue)
|
|
{
|
|
Instance.camMain.cullingMask |= 1 << Instance.iLayerBg;
|
|
Instance.camMain.cullingMask |= 1 << Instance.iLayerChar;
|
|
Instance.camMain.cullingMask |= 1 << Instance.iLayerEffect;
|
|
}
|
|
else
|
|
{
|
|
Instance.camMain.cullingMask = 0;
|
|
}
|
|
}
|
|
|
|
// 전투 UI 켜기.
|
|
public static void SSetBattleUiOn(bool bvalue)
|
|
{
|
|
Instance.canvasUI.enabled = bvalue;
|
|
}
|
|
|
|
// 스테이지 클리어/실패 UI 켜기.
|
|
public static void SSetClearFailUiOn(bool bvalue)
|
|
{
|
|
Instance.stageSuccessWindow.GetComponent<Canvas>().enabled = bvalue;
|
|
//Instance.canvasStageFail.enabled = bvalue;
|
|
}
|
|
|
|
public static void StatRecalc()
|
|
{
|
|
Instance.ivChar.SetStatus(BuffMgr.Instance.GetCharAtk(), BuffMgr.Instance.GetCharHp(),
|
|
BuffMgr.Instance.GetCharCrtDam(), BuffMgr.Instance.GetCharCrtRate(), BuffMgr.Instance.GetCharMov(), BuffMgr.Instance.GetCharSpd(), GameProperty.Instance.PlayerCharacterAttackRange, true);
|
|
}
|
|
#endregion Control Scene
|
|
|
|
#region Summon
|
|
// 모든 적 소환 해제.
|
|
private void UnsummonMon()
|
|
{
|
|
if (ivCharEnemy.gameObject.activeSelf)
|
|
{
|
|
ivCharEnemy.gameObject.SetActive(false);
|
|
for(int i = 0; i < ivPetsEnemy.Length; ++i)
|
|
{
|
|
ivPetsEnemy[i].OffPet();
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; ++i)
|
|
{
|
|
if (goMonsters[i].activeSelf)
|
|
{
|
|
goMonsters[i].SetActive(false);
|
|
hpBarEnemies[i].HideHpBar();
|
|
}
|
|
}
|
|
iMonsterCount = 0;
|
|
}
|
|
|
|
// 지역별 몬스터 종류 초기화(일반, 엘리트, 보스). 게임 시작시, 지역 변경시 호출.
|
|
private void InitMonArea()
|
|
{
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
ivMonsters[i].SetLoading();
|
|
|
|
dArea areadata = DataHandler.GetArea(DataHandler.PlayData.curStage);
|
|
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[0]))).Completed += ALoadMNm1Com;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[1]))).Completed += ALoadMNm2Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterEpic[0]))).Completed += ALoadMEl1Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterEpic[1]))).Completed += ALoadMEl2Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterBoss[0]))).Completed += ALoadMBsComp;
|
|
}
|
|
|
|
private void InitMonDungeon()
|
|
{
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
ivMonsters[i].SetLoading();
|
|
|
|
dDungeonInfo areadata = DataHandler.GetDungeonTypeInfo(DungeonMgr.GetDungeonKind());
|
|
|
|
switch (DungeonMgr.GetDungeonKind())
|
|
{
|
|
case DungeonMgr.DungeonKind.GoldDG:
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[0]))).Completed += ALoadMDg1Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterBoss[0]))).Completed += ALoadMBsDgComp;
|
|
break;
|
|
case DungeonMgr.DungeonKind.EnhanceStoneDG:
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[0]))).Completed += ALoadMDg1Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[1]))).Completed += ALoadMDg2Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[2]))).Completed += ALoadMDg3Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[3]))).Completed += ALoadMDg4Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[4]))).Completed += ALoadMDg5Comp;
|
|
break;
|
|
case DungeonMgr.DungeonKind.PetDG:
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[0]))).Completed += ALoadMDg1Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[1]))).Completed += ALoadMDg2Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterEpic[0]))).Completed += ALoadMEl1DgComp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterBoss[0]))).Completed += ALoadMBsDgComp;
|
|
break;
|
|
case DungeonMgr.DungeonKind.AwakenStoneDG:
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[0]))).Completed += ALoadMAwBsDgComp;
|
|
break;
|
|
case DungeonMgr.DungeonKind.AwakenDG:
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[0]))).Completed += ALoadMDg1Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[1]))).Completed += ALoadMDg2Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[2]))).Completed += ALoadMDg3Comp;
|
|
break;
|
|
case DungeonMgr.DungeonKind.GuardianDG:
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[0]))).Completed += ALoadMBsDgComp;
|
|
break;
|
|
case DungeonMgr.DungeonKind.relicDG:
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterNormal[0]))).Completed += ALoadMDg1Comp;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>(FormatString.StringFormat(AddressableMgr.PathMon, DataHandler.GetMonsterPath(areadata.monsterBoss[0]))).Completed += ALoadMBsDgComp;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 일반 몬스터1 로드 완료.
|
|
private void ALoadMNm1Com(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = 0;
|
|
int iendindex = istartindex + I_SummonMax;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[0].IsValid())
|
|
Addressables.Release(handleSpines[0]);
|
|
handleSpines[0] = obj;
|
|
}
|
|
|
|
// 일반 몬스터2 로드 완료.
|
|
private void ALoadMNm2Comp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = I_SummonMax;
|
|
int iendindex = istartindex + I_SummonMax;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[1].IsValid())
|
|
Addressables.Release(handleSpines[1]);
|
|
handleSpines[1] = obj;
|
|
}
|
|
|
|
// 엘리트 몬스터1 로드 완료.
|
|
private void ALoadMEl1Comp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = I_MonTypeNormal * I_SummonMax;
|
|
int iendindex = istartindex + I_SummonEliteMax;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[2].IsValid())
|
|
Addressables.Release(handleSpines[2]);
|
|
handleSpines[2] = obj;
|
|
}
|
|
|
|
// 엘리트 몬스터2 로드 완료.
|
|
private void ALoadMEl2Comp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = (I_MonTypeNormal * I_SummonMax) + I_SummonEliteMax;
|
|
int iendindex = istartindex + I_SummonEliteMax;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[3].IsValid())
|
|
Addressables.Release(handleSpines[3]);
|
|
handleSpines[3] = obj;
|
|
}
|
|
|
|
// 보스 몬스터 로드 완료.
|
|
private void ALoadMBsComp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int index = (I_MonTypeNormal * I_SummonMax) + (I_MonTypeElite * I_SummonEliteMax);
|
|
ivMonsters[index].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[4].IsValid())
|
|
Addressables.Release(handleSpines[4]);
|
|
handleSpines[4] = obj;
|
|
}
|
|
|
|
// 던전 몬스터1 로드 완료.
|
|
private void ALoadMDg1Comp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = 0;
|
|
int iendindex = 14;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[0].IsValid())
|
|
Addressables.Release(handleSpines[0]);
|
|
handleSpines[0] = obj;
|
|
}
|
|
|
|
// 던전 몬스터2 로드 완료.
|
|
private void ALoadMDg2Comp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = 14;
|
|
int iendindex = 22;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[1].IsValid())
|
|
Addressables.Release(handleSpines[1]);
|
|
handleSpines[1] = obj;
|
|
}
|
|
|
|
// 던전 몬스터3 로드 완료.
|
|
private void ALoadMDg3Comp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = 22;
|
|
int iendindex = 23;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[2].IsValid())
|
|
Addressables.Release(handleSpines[2]);
|
|
handleSpines[2] = obj;
|
|
}
|
|
|
|
// 던전 몬스터4 로드 완료.
|
|
private void ALoadMDg4Comp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = 23;
|
|
int iendindex = 24;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[3].IsValid())
|
|
Addressables.Release(handleSpines[3]);
|
|
handleSpines[3] = obj;
|
|
}
|
|
|
|
// 던전 몬스터5 로드 완료.
|
|
private void ALoadMDg5Comp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = 24;
|
|
int iendindex = 25;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[4].IsValid())
|
|
Addressables.Release(handleSpines[4]);
|
|
handleSpines[4] = obj;
|
|
}
|
|
|
|
// 엘리트 몬스터1 로드 완료.
|
|
private void ALoadMEl1DgComp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = 25;
|
|
int iendindex = 26;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[5].IsValid())
|
|
Addressables.Release(handleSpines[5]);
|
|
handleSpines[5] = obj;
|
|
}
|
|
|
|
// 보스 몬스터 로드 완료.
|
|
private void ALoadMBsDgComp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int istartindex = 26;
|
|
int iendindex = 27;
|
|
for (int i = istartindex; i < iendindex; i++)
|
|
ivMonsters[i].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[6].IsValid())
|
|
Addressables.Release(handleSpines[6]);
|
|
handleSpines[6] = obj;
|
|
}
|
|
|
|
// 각성석 보스 몬스터 로드 완료.
|
|
private void ALoadMAwBsDgComp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
int index = 27;
|
|
ivMonsters[index].SetMonsterAni(obj.Result);
|
|
|
|
if (handleSpines[7].IsValid())
|
|
Addressables.Release(handleSpines[7]);
|
|
handleSpines[7] = obj;
|
|
}
|
|
|
|
// 각 웨이브 시작시에 몬스터 소환.
|
|
private void SummonMonStage()
|
|
{
|
|
// 소환할 몬스터 수.
|
|
int itotalcount = I_SummonMax;//Random.Range(I_SummonMin, I_SummonMax + 1);
|
|
int ielitecount = 0;
|
|
int ibosscount = 0;
|
|
if (iWave == iTotalWave)
|
|
{
|
|
if (DataHandler.PlayData.curStage % DataHandler.Const.stageMax == 0)
|
|
ibosscount = 1;
|
|
else
|
|
ielitecount = I_SummonEliteMin;//Random.Range(, I_SummonEliteMax + 1);
|
|
|
|
bossIncoming.gameObject.SetActive(true);
|
|
bossIncoming.AnimationState.SetAnimation(0, "animation", false);
|
|
//bossIncoming.DOPlay();
|
|
|
|
SoundMgr.PlaySfx(SoundName.SummonBoss);
|
|
}
|
|
|
|
int spawn = 0;
|
|
|
|
#region Base Position
|
|
// 캐릭터 위치를 참조한 몬스터 소환 위치.
|
|
float fcharx = trfChar.localPosition.x;
|
|
float fchary = trfChar.localPosition.y;
|
|
Vector3 v3posbase = Vector3.zero;
|
|
Vector3 v3posbase2 = Vector3.zero;
|
|
bool bsamex = true;
|
|
|
|
//// 캐릭터가 왼쪽에 있을 경우 오른쪽에만 몬스터 소환.
|
|
//if (fcharx <= -12f)
|
|
//{
|
|
// v3posbase.x = Random.Range(fcharx + 20f, fcharx + 30f); // 10 ~ 20
|
|
// v3posbase2.x = v3posbase.x + 25f; // 15f
|
|
//}
|
|
//// 캐릭터가 오른쪽에 있을 경우 왼쪽에만 몬스터 소환.
|
|
//else if (fcharx >= 12f)
|
|
//{
|
|
// v3posbase.x = Random.Range(fcharx - 30f, fcharx - 20f);
|
|
// v3posbase2.x = v3posbase.x - 25f;
|
|
//}
|
|
// 캐릭터가 중앙에 있을 경우 랜덤으로 좌우 결정.
|
|
//else
|
|
{
|
|
if (spawn == 0/*Random.Range(0, 2) == 1*/)
|
|
{
|
|
v3posbase.x = fcharx - 25f;// Random.Range(fcharx - 30f, fcharx - 20f);
|
|
// 첫 번째 랜덤 좌표와 두 번째 랜덤 좌표를 비교해서 같은 방향인지 체크.
|
|
//if (Random.Range(0, 2) == 1)
|
|
//{
|
|
// v3posbase2.x = Random.Range(fcharx - 30f, fcharx - 20f);
|
|
//}
|
|
//else
|
|
//{
|
|
bsamex = false;
|
|
v3posbase2.x = Random.Range(fcharx + 30f, fcharx + 20f);
|
|
//}
|
|
|
|
spawn++;
|
|
}
|
|
else
|
|
{
|
|
v3posbase.x = fcharx + 25f;// Random.Range(fcharx + 20f, fcharx + 30f);
|
|
// 첫 번째 랜덤 좌표와 두 번째 랜덤 좌표를 비교해서 같은 방향인지 체크.
|
|
//if (Random.Range(0, 2) == 1)
|
|
//{
|
|
bsamex = false;
|
|
v3posbase2.x = Random.Range(fcharx - 30f, fcharx - 20f);
|
|
//}
|
|
//else
|
|
//{
|
|
// v3posbase2.x = Random.Range(fcharx + 20f, fcharx + 30f);
|
|
//}
|
|
|
|
spawn--;
|
|
}
|
|
}
|
|
|
|
// X축으로 같은 방향에 소환될 경우.
|
|
if (bsamex)
|
|
{
|
|
// 캐릭터 위치가 아래쪽이면 간격을 두고 위쪽에만 소환.
|
|
if (fchary <= -13f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
v3posbase2.y = v3posbase.y + 10f;
|
|
}
|
|
// 캐릭터 위치가 위쪽이면 간격을 두고 아래쪽에만 소환.
|
|
else if (fchary >= 7f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
v3posbase2.y = v3posbase.y - 10f;
|
|
}
|
|
// 캐릭터 위치가 중앙 아래쪽이면 서로 반대 방향에 소환.
|
|
else if (fchary <= -3f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
v3posbase2.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
}
|
|
// 캐릭터 위치가 중앙 위쪽이면 서로 반대 방향에 소환.
|
|
else
|
|
{
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
v3posbase2.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
}
|
|
}
|
|
// X축으로 다른 방향에 소환될 경우.
|
|
else
|
|
{
|
|
// 캐릭터 위치가 아래쪽이면 위쪽에만 소환.
|
|
if (fchary <= -13f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
v3posbase2.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
}
|
|
// 캐릭터 위치가 위쪽이면 아래쪽에만 소환.
|
|
else if (fchary >= 7f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
v3posbase2.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
}
|
|
// 캐릭터 위치가 중앙 아래쪽이면 랜덤으로 소환.
|
|
else if (fchary <= -3f)
|
|
{
|
|
if (Random.Range(0, 2) == 1)
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
else
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
|
|
if (Random.Range(0, 2) == 1)
|
|
v3posbase2.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
else
|
|
v3posbase2.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
}
|
|
// 캐릭터 위치가 중앙 위쪽이면 랜덤으로 소환.
|
|
else
|
|
{
|
|
if (Random.Range(0, 2) == 1)
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
else
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
|
|
if (Random.Range(0, 2) == 1)
|
|
v3posbase2.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
else
|
|
v3posbase2.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
}
|
|
}
|
|
|
|
v3posbase.x = Mathf.Clamp(v3posbase.x, V3_SummonMin.x, V3_SummonMax.x);
|
|
v3posbase.y = Mathf.Clamp(v3posbase.y, V3_SummonMin.y, V3_SummonMax.y);
|
|
v3posbase.z = Mathf.Clamp(v3posbase.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase = v3posbase.Clamp(V3_SummonMin, V3_SummonMax);
|
|
v3posbase2.x = Mathf.Clamp(v3posbase2.x, V3_SummonMin.x, V3_SummonMax.x);
|
|
v3posbase2.y = Mathf.Clamp(v3posbase2.y, V3_SummonMin.y, V3_SummonMax.y);
|
|
v3posbase2.z = Mathf.Clamp(v3posbase2.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase2 = v3posbase2.Clamp(V3_SummonMin, V3_SummonMax);
|
|
|
|
// 몬스터 별 위치.
|
|
List<int> indexlist = new List<int>();//V3_AddSummons.Length
|
|
for (int i = 0; i < I_SummonMax; i++)
|
|
indexlist.Add(i);
|
|
#endregion Base Position
|
|
|
|
for (int i = 0; i < itotalcount; i++)
|
|
{
|
|
int index;
|
|
BigInteger biatk;
|
|
//float fdef;
|
|
BigInteger fhp;
|
|
float frange;
|
|
float fspeed;
|
|
int igroup;
|
|
|
|
// 일반 몬스터.
|
|
if (i >= ielitecount + ibosscount)
|
|
{
|
|
int ran = Random.Range(0, I_MonTypeNormal);
|
|
index = GetAvailMonsterIndex(CreatureBase.eCreatureClass.normal, ran);
|
|
biatk = biMonAtk;
|
|
//fdef = fMonDef;
|
|
fhp = biMonHp;
|
|
frange = F_MonRangeNormal;
|
|
fspeed = fMonSpeedN[ran];
|
|
igroup = iMonGroupN[ran];
|
|
}
|
|
// 엘리트 몬스터.
|
|
else if (i >= ibosscount)
|
|
{
|
|
int ran = Random.Range(0, I_MonTypeElite);
|
|
index = GetAvailMonsterIndex(CreatureBase.eCreatureClass.elite, ran);
|
|
biatk = biMonAtk * DataHandler.Const.monEliteAtk / dConst.RateMax;
|
|
//fdef = fMonDef * DataHandler.Const.monEliteDef / dConst.RateMax;
|
|
fhp = biMonHp * DataHandler.Const.monEliteHp / dConst.RateMax;
|
|
frange = F_MonRangeElite;
|
|
fspeed = fMonSpeedE[ran];
|
|
igroup = iMonGroupE[ran];
|
|
}
|
|
// 보스 몬스터.
|
|
else
|
|
{
|
|
index = GetAvailMonsterIndex(CreatureBase.eCreatureClass.boss, 0);
|
|
biatk = biMonAtk * DataHandler.Const.monBossAtk / dConst.RateMax;
|
|
//fdef = fMonDef * DataHandler.Const.monBossDef / dConst.RateMax;
|
|
fhp = biMonHp * DataHandler.Const.monBossHp / dConst.RateMax;
|
|
frange = F_MonRangeBoss;
|
|
fspeed = fMonSpeedB[0];
|
|
igroup = iMonGroupB[0];
|
|
}
|
|
|
|
if (index < 0)
|
|
continue;
|
|
|
|
BigInteger debufbiatk = new BigInteger(BuffMgr.Instance.GetEnemyAtkDec());
|
|
biatk -= debufbiatk;
|
|
if (biatk < 0)
|
|
biatk = 1;
|
|
//fdef -= BuffMgr.Instance.GetEnemyDefDec();
|
|
//if (fdef < 0f)
|
|
// fdef = 1f;
|
|
BigInteger debuffHp = new BigInteger(BuffMgr.Instance.GetEnemyHpDec());
|
|
fhp -= debuffHp;
|
|
if (fhp < 0)
|
|
fhp = 1;
|
|
|
|
int irand = Random.Range(0, indexlist.Count);
|
|
Vector3 v3pos = V3_CharOrigin;//V3_AddSummons[indexlist[irand]%10];
|
|
if (Random.Range(0, 2) == 1)
|
|
{
|
|
v3pos.x += Random.Range(0, 2) == 1 ? 20 : -20;
|
|
|
|
v3pos.x += Random.Range(-5f, 5f);
|
|
v3pos.y += Random.Range(-20f, 16f);
|
|
}
|
|
else
|
|
{
|
|
v3pos.y += Random.Range(0, 2) == 1 ? 13 : -15;
|
|
|
|
v3pos.y += Random.Range(-3f, 3f);
|
|
v3pos.x += Random.Range(-20f, 20f);
|
|
}
|
|
|
|
indexlist.RemoveAt(irand);
|
|
//v3pos += Random.Range(0, 2) == 1 ? v3posbase : v3posbase2;
|
|
//v3pos.x += Random.Range(-0.7f, 0.7f);
|
|
//v3pos.y += Random.Range(-10f, 10f);
|
|
v3pos.z = v3pos.y * 0.1f;
|
|
|
|
if (iWave == iTotalWave)
|
|
{
|
|
if(ivMonsters[index].GetCreatureClass() == eCreatureClass.elite)
|
|
{
|
|
ivMonsters[index].ResetDebuff();
|
|
ivMonsters[index].SetStatus(biatk, fhp, dConst.RateMaxFloat, 0, dConst.RateMaxFloat * 0.1f * fspeed, dConst.RateMax, frange, igroup: igroup);
|
|
hpBarEnemies[i].ReSetoffsetY(ivMonsters[index].GetMonType());
|
|
ivMonsters[index].Summon(v3pos, trfChar.position.x > v3pos.x);
|
|
iMonsterCount++;
|
|
}
|
|
if (ivMonsters[index].GetCreatureClass() == eCreatureClass.boss)
|
|
{
|
|
ivMonsters[index].ResetDebuff();
|
|
ivMonsters[index].SetStatus(biatk, fhp, dConst.RateMaxFloat, 0, dConst.RateMaxFloat * 0.1f * fspeed, dConst.RateMax, frange, igroup: igroup);
|
|
hpBarEnemies[i].ReSetoffsetY(ivMonsters[index].GetMonType());
|
|
ivMonsters[index].Summon(v3pos, trfChar.position.x > v3pos.x);
|
|
iMonsterCount++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ivMonsters[index].ResetDebuff();
|
|
ivMonsters[index].SetStatus(biatk, fhp, dConst.RateMaxFloat, 0, dConst.RateMaxFloat * 0.1f * fspeed, dConst.RateMax, frange, igroup: igroup);
|
|
hpBarEnemies[i].ReSetoffsetY(ivMonsters[index].GetMonType());
|
|
ivMonsters[index].Summon(v3pos, trfChar.position.x > v3pos.x);
|
|
iMonsterCount++;
|
|
}
|
|
|
|
|
|
if (indexlist.Count == 0)
|
|
break;
|
|
}
|
|
}
|
|
|
|
//던전에서 몹 소환하기. 총합 카운트에서 나머지 카운트를 뺸 값이 일반몹 1 이 나오는 양이다.
|
|
private void SummonMonDungeon()
|
|
{
|
|
// 소환할 몬스터 수.
|
|
int itotalcount = 10;
|
|
int dgNorm2Count = 0;
|
|
int dgNorm3Count = 0;
|
|
int dgNorm4Count = 0;
|
|
int dgNorm5Count = 0;
|
|
int ielitecount = 0;
|
|
int ibosscount = 0;
|
|
int ibigbosscount = 0;
|
|
switch (DungeonMgr.GetDungeonKind())
|
|
{
|
|
case DungeonMgr.DungeonKind.GoldDG:
|
|
// 소환할 몬스터 수.
|
|
itotalcount = 10;
|
|
dgNorm2Count = 0;
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
ielitecount = 0;
|
|
ibosscount = 0;
|
|
|
|
if (iWave == iTotalWave)
|
|
{
|
|
ibosscount = 1;
|
|
}
|
|
break;
|
|
case DungeonMgr.DungeonKind.EnhanceStoneDG:
|
|
// 소환할 몬스터 수.
|
|
itotalcount = 1;
|
|
dgNorm2Count = 0;
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
ielitecount = 0;
|
|
ibosscount = 0;
|
|
|
|
switch (iWave)
|
|
{
|
|
case 2:
|
|
dgNorm2Count = 1;
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
break;
|
|
case 3:
|
|
dgNorm2Count = 0;
|
|
dgNorm3Count = 1;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
break;
|
|
case 4:
|
|
dgNorm2Count = 0;
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 1;
|
|
dgNorm5Count = 0;
|
|
break;
|
|
case 5:
|
|
dgNorm2Count = 0;
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 1;
|
|
break;
|
|
}
|
|
break;
|
|
case DungeonMgr.DungeonKind.PetDG:
|
|
// 소환할 몬스터 수.
|
|
itotalcount = 5;
|
|
dgNorm2Count = Random.Range(1, 4);
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
ielitecount = 0;
|
|
ibosscount = 0;
|
|
|
|
if (iWave == iTotalWave)
|
|
{
|
|
if (DungeonMgr.GetDungeonLevel() % 5 == 0)
|
|
{
|
|
ibosscount = 1;
|
|
}
|
|
else
|
|
{
|
|
ielitecount = 1;
|
|
}
|
|
}
|
|
break;
|
|
case DungeonMgr.DungeonKind.AwakenStoneDG://5053 번 언저릿 줄에서 받은 normal 몬스터를 보스 정보로 변환하는 곳이 있다.
|
|
itotalcount = 1;
|
|
dgNorm2Count = 0;
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
ielitecount = 0;
|
|
ibosscount = 0;
|
|
ibigbosscount = 1;
|
|
break;
|
|
case DungeonMgr.DungeonKind.AwakenDG:
|
|
itotalcount = 3;
|
|
dgNorm2Count = 1;
|
|
dgNorm3Count = 1;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
ielitecount = 0;
|
|
ibosscount = 0;
|
|
break;
|
|
case DungeonMgr.DungeonKind.GuardianDG://normal 몬스터 정보로 바꾸고 싶다면 5053 언저릿 줄에 있는 변환하는 코드를 지우고 이쪽의 보스 카운트도 0으로 맞추면 된다.
|
|
itotalcount = 1;
|
|
dgNorm2Count = 0;
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
ielitecount = 0;
|
|
ibosscount = 1;
|
|
break;
|
|
case DungeonMgr.DungeonKind.relicDG:
|
|
// 소환할 몬스터 수.
|
|
itotalcount = 10;
|
|
dgNorm2Count = 0;
|
|
dgNorm3Count = 0;
|
|
dgNorm4Count = 0;
|
|
dgNorm5Count = 0;
|
|
ielitecount = 0;
|
|
ibosscount = 0;
|
|
|
|
if (iWave == iTotalWave)
|
|
{
|
|
ibosscount = 1;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
float fcharx = trfChar.localPosition.x;
|
|
float fchary = trfChar.localPosition.y;
|
|
Vector3 v3posbase = Vector3.zero;
|
|
Vector3 v3posbase2 = Vector3.zero;
|
|
bool bsamex = true;
|
|
List<int> indexlist = new List<int>(V3_AddSummons.Length);
|
|
|
|
switch (DungeonMgr.GetDungeonKind())
|
|
{
|
|
case DungeonMgr.DungeonKind.GoldDG:
|
|
case DungeonMgr.DungeonKind.PetDG:
|
|
case DungeonMgr.DungeonKind.AwakenDG:
|
|
case DungeonMgr.DungeonKind.relicDG:
|
|
#region Base Position
|
|
// 캐릭터 위치를 참조한 몬스터 소환 위치.
|
|
fcharx = trfChar.localPosition.x;
|
|
fchary = trfChar.localPosition.y;
|
|
v3posbase = Vector3.zero;
|
|
v3posbase2 = Vector3.zero;
|
|
bsamex = true;
|
|
|
|
// 캐릭터가 왼쪽에 있을 경우 오른쪽에만 몬스터 소환.
|
|
if (fcharx <= -12f)
|
|
{
|
|
v3posbase.x = Random.Range(fcharx + 10f, fcharx + 20f);
|
|
v3posbase2.x = v3posbase.x + 15f;
|
|
}
|
|
// 캐릭터가 오른쪽에 있을 경우 왼쪽에만 몬스터 소환.
|
|
else if (fcharx >= 12f)
|
|
{
|
|
v3posbase.x = Random.Range(fcharx - 20f, fcharx - 10f);
|
|
v3posbase2.x = v3posbase.x - 15f;
|
|
}
|
|
// 캐릭터가 중앙에 있을 경우 랜덤으로 좌우 결정.
|
|
else
|
|
{
|
|
if (Random.Range(0, 2) == 1)
|
|
{
|
|
v3posbase.x = Random.Range(fcharx - 15f, fcharx - 10f);
|
|
// 첫 번째 랜덤 좌표와 두 번째 랜덤 좌표를 비교해서 같은 방향인지 체크.
|
|
if (Random.Range(0, 2) == 1)
|
|
{
|
|
v3posbase2.x = Random.Range(fcharx - 15f, fcharx - 10f);
|
|
}
|
|
else
|
|
{
|
|
bsamex = false;
|
|
v3posbase2.x = Random.Range(fcharx + 10f, fcharx + 15f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
v3posbase.x = Random.Range(fcharx + 10f, fcharx + 15f);
|
|
// 첫 번째 랜덤 좌표와 두 번째 랜덤 좌표를 비교해서 같은 방향인지 체크.
|
|
if (Random.Range(0, 2) == 1)
|
|
{
|
|
bsamex = false;
|
|
v3posbase2.x = Random.Range(fcharx - 15f, fcharx - 10f);
|
|
}
|
|
else
|
|
{
|
|
v3posbase2.x = Random.Range(fcharx + 10f, fcharx + 15f);
|
|
}
|
|
}
|
|
}
|
|
|
|
// X축으로 같은 방향에 소환될 경우.
|
|
if (bsamex)
|
|
{
|
|
// 캐릭터 위치가 아래쪽이면 간격을 두고 위쪽에만 소환.
|
|
if (fchary <= -13f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
v3posbase2.y = v3posbase.y + 10f;
|
|
}
|
|
// 캐릭터 위치가 위쪽이면 간격을 두고 아래쪽에만 소환.
|
|
else if (fchary >= 7f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
v3posbase2.y = v3posbase.y - 10f;
|
|
}
|
|
// 캐릭터 위치가 중앙 아래쪽이면 서로 반대 방향에 소환.
|
|
else if (fchary <= -3f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
v3posbase2.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
}
|
|
// 캐릭터 위치가 중앙 위쪽이면 서로 반대 방향에 소환.
|
|
else
|
|
{
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
v3posbase2.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
}
|
|
|
|
}
|
|
// X축으로 다른 방향에 소환될 경우.
|
|
else
|
|
{
|
|
// 캐릭터 위치가 아래쪽이면 위쪽에만 소환.
|
|
if (fchary <= -13f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
v3posbase2.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
}
|
|
// 캐릭터 위치가 위쪽이면 아래쪽에만 소환.
|
|
else if (fchary >= 7f)
|
|
{
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
v3posbase2.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
}
|
|
// 캐릭터 위치가 중앙 아래쪽이면 랜덤으로 소환.
|
|
else if (fchary <= -3f)
|
|
{
|
|
if (Random.Range(0, 2) == 1)
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
else
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
|
|
if (Random.Range(0, 2) == 1)
|
|
v3posbase2.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
else
|
|
v3posbase2.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
}
|
|
// 캐릭터 위치가 중앙 위쪽이면 랜덤으로 소환.
|
|
else
|
|
{
|
|
if (Random.Range(0, 2) == 1)
|
|
v3posbase.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
else
|
|
v3posbase.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
|
|
if (Random.Range(0, 2) == 1)
|
|
v3posbase2.y = Random.Range(fchary + 7f, fchary + 12f);
|
|
else
|
|
v3posbase2.y = Random.Range(fchary - 12f, fchary - 7f);
|
|
}
|
|
|
|
}
|
|
|
|
v3posbase.x = Mathf.Clamp(v3posbase.x, V3_SummonMin.x, V3_SummonMax.x);
|
|
v3posbase.y = Mathf.Clamp(v3posbase.y, V3_DgSummonMin.y, V3_DgSummonMax.y);
|
|
v3posbase.z = Mathf.Clamp(v3posbase.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase = v3posbase.Clamp(V3_SummonMin, V3_SummonMax);
|
|
v3posbase2.x = Mathf.Clamp(v3posbase2.x, V3_SummonMin.x, V3_SummonMax.x);
|
|
v3posbase2.y = Mathf.Clamp(v3posbase2.y, V3_DgSummonMin.y, V3_DgSummonMax.y);
|
|
v3posbase2.z = Mathf.Clamp(v3posbase2.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase2 = v3posbase2.Clamp(V3_SummonMin, V3_SummonMax);
|
|
|
|
// 몬스터 별 위치.
|
|
for (int i = 0; i < V3_AddSummons.Length; i++)
|
|
indexlist.Add(i);
|
|
#endregion Base Position
|
|
break;
|
|
case DungeonMgr.DungeonKind.AwakenStoneDG:
|
|
#region Base Position
|
|
// 캐릭터 위치를 참조한 몬스터 소환 위치.
|
|
float charX = trfChar.localPosition.x;
|
|
|
|
if (charX < 0)
|
|
{
|
|
fcharx = -5;
|
|
}
|
|
else
|
|
{
|
|
fcharx = 5;
|
|
}
|
|
|
|
fchary = 0;
|
|
v3posbase = Vector3.zero;
|
|
v3posbase2 = Vector3.zero;
|
|
bsamex = true;
|
|
|
|
v3posbase.x = fcharx;
|
|
v3posbase2.x = v3posbase.x;
|
|
|
|
//v3posbase.x = Mathf.Clamp(v3posbase.x, V3_SummonMin.x, 999f);
|
|
//v3posbase.y = Mathf.Clamp(v3posbase.y, 2f, 2f);
|
|
v3posbase.z = Mathf.Clamp(v3posbase.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase = v3posbase.Clamp(V3_SummonMin, V3_SummonMax);
|
|
//v3posbase2.x = Mathf.Clamp(v3posbase2.x, V3_SummonMin.x, 999f);
|
|
//v3posbase2.y = Mathf.Clamp(v3posbase2.y, 2f, 2f);
|
|
v3posbase2.z = Mathf.Clamp(v3posbase2.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase2 = v3posbase2.Clamp(V3_SummonMin, V3_SummonMax);
|
|
|
|
// 몬스터 별 위치.
|
|
for (int i = 0; i < 1; i++)
|
|
indexlist.Add(1);
|
|
#endregion Base Position
|
|
break;
|
|
case DungeonMgr.DungeonKind.EnhanceStoneDG:
|
|
#region Base Position
|
|
// 캐릭터 위치를 참조한 몬스터 소환 위치.
|
|
fcharx = trfChar.localPosition.x;
|
|
fchary = trfChar.localPosition.y;
|
|
v3posbase = Vector3.zero;
|
|
v3posbase2 = Vector3.zero;
|
|
bsamex = true;
|
|
|
|
v3posbase.x = -15f + (35f * iWave);
|
|
v3posbase2.x = v3posbase.x + 1f;
|
|
|
|
v3posbase.x = Mathf.Clamp(v3posbase.x, V3_SummonMin.x, 999f);
|
|
v3posbase.y = Mathf.Clamp(v3posbase.y, 2f, 2f);
|
|
v3posbase.z = Mathf.Clamp(v3posbase.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase = v3posbase.Clamp(V3_SummonMin, V3_SummonMax);
|
|
v3posbase2.x = Mathf.Clamp(v3posbase2.x, V3_SummonMin.x, 999f);
|
|
v3posbase2.y = Mathf.Clamp(v3posbase2.y, 2f, 2f);
|
|
v3posbase2.z = Mathf.Clamp(v3posbase2.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase2 = v3posbase2.Clamp(V3_SummonMin, V3_SummonMax);
|
|
|
|
// 몬스터 별 위치.
|
|
for (int i = 0; i < 1; i++)
|
|
indexlist.Add(3);
|
|
#endregion Base Position
|
|
break;
|
|
case DungeonMgr.DungeonKind.GuardianDG:
|
|
#region Base Position
|
|
// 캐릭터 위치를 참조한 몬스터 소환 위치.
|
|
fcharx = trfChar.localPosition.x;
|
|
fchary = trfChar.localPosition.y;
|
|
v3posbase = Vector3.zero;
|
|
v3posbase2 = Vector3.zero;
|
|
bsamex = true;
|
|
|
|
v3posbase.x = -3.8f;
|
|
v3posbase2.x = -3.8f;
|
|
|
|
v3posbase.x = Mathf.Clamp(v3posbase.x, V3_SummonMin.x, 999f);
|
|
v3posbase.y = Mathf.Clamp(v3posbase.y, -5.6f, -5.6f);
|
|
v3posbase.z = Mathf.Clamp(v3posbase.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase = v3posbase.Clamp(V3_SummonMin, V3_SummonMax);
|
|
v3posbase2.x = Mathf.Clamp(v3posbase2.x, V3_SummonMin.x, 999f);
|
|
v3posbase2.y = Mathf.Clamp(v3posbase2.y, -5.6f, -5.6f);
|
|
v3posbase2.z = Mathf.Clamp(v3posbase2.z, V3_SummonMin.z, V3_SummonMax.z);
|
|
//v3posbase2 = v3posbase2.Clamp(V3_SummonMin, V3_SummonMax);
|
|
|
|
// 몬스터 별 위치.
|
|
for (int i = 0; i < 1; i++)
|
|
indexlist.Add(3);
|
|
#endregion Base Position
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
for (int i = 0; i < itotalcount; i++)
|
|
{
|
|
int index;
|
|
BigInteger biatk;
|
|
BigInteger fhp;
|
|
float frange;
|
|
float fspeed;
|
|
int igroup;
|
|
|
|
// 일반 몬스터.
|
|
if (i >= dgNorm2Count + dgNorm3Count + dgNorm4Count + dgNorm5Count + ielitecount + ibosscount + ibigbosscount)
|
|
{
|
|
index = GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgN1);
|
|
biatk = biMonAtk;
|
|
fhp = biMonHp;
|
|
frange = F_MonRangeNormal;
|
|
fspeed = fMonSpeedN[0];
|
|
igroup = iMonGroupN[0];
|
|
}
|
|
else if (i >= dgNorm3Count + dgNorm4Count + dgNorm5Count + ielitecount + ibosscount + ibigbosscount)
|
|
{
|
|
index = GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgN2);
|
|
biatk = biMonAtk;
|
|
fhp = biMonHp;
|
|
frange = F_MonRangeNormal;
|
|
fspeed = fMonSpeedN[1];
|
|
igroup = iMonGroupN[1];
|
|
}
|
|
else if (i >= dgNorm4Count + dgNorm5Count + ielitecount + ibosscount + ibigbosscount)
|
|
{
|
|
index = GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgN3);
|
|
biatk = biMonAtk;
|
|
fhp = biMonHp;
|
|
frange = F_MonRangeNormal;
|
|
fspeed = fMonSpeedN[2];
|
|
igroup = iMonGroupN[2];
|
|
}
|
|
else if (i >= dgNorm5Count + ielitecount + ibosscount + ibigbosscount)
|
|
{
|
|
index = GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgN4);
|
|
biatk = biMonAtk;
|
|
fhp = biMonHp;
|
|
frange = F_MonRangeNormal;
|
|
fspeed = fMonSpeedN[3];
|
|
igroup = iMonGroupN[3];
|
|
}
|
|
else if (i >= ielitecount + ibosscount + ibigbosscount)
|
|
{
|
|
index = GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgN5);
|
|
biatk = biMonAtk;
|
|
fhp = biMonHp;
|
|
frange = F_MonRangeNormal;
|
|
fspeed = fMonSpeedN[4];
|
|
igroup = iMonGroupN[4];
|
|
}
|
|
// 엘리트 몬스터.
|
|
else if (i >= ibosscount + ibigbosscount)
|
|
{
|
|
index = GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgE1);
|
|
biatk = biMonAtk * DataHandler.Const.monEliteAtk / dConst.RateMax;
|
|
fhp = biMonHp * DataHandler.Const.monEliteHp / dConst.RateMax;
|
|
frange = F_MonRangeElite;
|
|
fspeed = fMonSpeedE[0];
|
|
igroup = iMonGroupE[0];
|
|
}
|
|
// 보스 몬스터.
|
|
else if(i >= ibigbosscount)
|
|
{
|
|
index = GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgBs);
|
|
biatk = biMonAtk * DataHandler.Const.monBossAtk / dConst.RateMax;
|
|
fhp = biMonHp * DataHandler.Const.monBossHp / dConst.RateMax;
|
|
frange = F_MonRangeBoss;
|
|
fspeed = fMonSpeedB[0];
|
|
igroup = iMonGroupB[0];
|
|
}
|
|
//각성석
|
|
else
|
|
{
|
|
index = GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgAwBs);
|
|
biatk = biMonAtk * DataHandler.Const.monBossAtk / dConst.RateMax;
|
|
fhp = biMonHp * DataHandler.Const.monBossHp / dConst.RateMax;
|
|
frange = F_MonRangeBoss;
|
|
fspeed = fMonSpeedB[0];
|
|
igroup = iMonGroupB[0];
|
|
}
|
|
|
|
if (index < 0)
|
|
continue;
|
|
|
|
int irand = Random.Range(0, indexlist.Count);
|
|
Vector3 v3pos = V3_AddSummons[indexlist[irand]];
|
|
indexlist.RemoveAt(irand);
|
|
v3pos += Random.Range(0, 2) == 1 ? v3posbase : v3posbase2;
|
|
v3pos.x += Random.Range(-0.7f, 0.7f);
|
|
v3pos.y += Random.Range(-0.7f, 0.7f);
|
|
v3pos.z = v3pos.y * 2f;
|
|
|
|
ivMonsters[index].ResetDebuff();
|
|
ivMonsters[index].SetStatus(biatk, fhp, dConst.RateMaxFloat, 0, dConst.RateMaxFloat * 0.1f * fspeed, dConst.RateMax, frange, igroup: igroup);
|
|
if (CurrentBattleType == BattleType.AwakenDungeon)
|
|
{
|
|
if(index == GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass.DgN3))
|
|
{
|
|
ivMonsters[index].SetStatus(biatk, fhp, dConst.RateMaxFloat, 0, dConst.RateMaxFloat * 0.1f * fspeed, dConst.RateMax, frange,false, false, igroup: igroup);
|
|
}
|
|
}
|
|
hpBarEnemies[index].ReSetoffsetY(ivMonsters[index].GetMonType());
|
|
ivMonsters[index].Summon(v3pos, trfChar.position.x > v3pos.x);
|
|
iMonsterCount++;
|
|
|
|
if (indexlist.Count == 0)
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 몬스터 종류별로 소환 가능한 인덱스 가져오기.
|
|
private int GetAvailMonsterIndex(CreatureBase.eCreatureClass cls, int itype)
|
|
{
|
|
switch (cls)
|
|
{
|
|
case CreatureBase.eCreatureClass.normal:
|
|
int itypeminn = itype * I_SummonMax;
|
|
int itypemaxn = itypeminn + I_SummonMax;
|
|
for (int i = itypeminn; i < itypemaxn; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eCreatureClass.elite:
|
|
int itypemine = (I_MonTypeNormal * I_SummonMax) + itype * I_SummonEliteMax;
|
|
int itypemaxe = itypemine + I_SummonEliteMax;
|
|
for (int i = itypemine; i < itypemaxe; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eCreatureClass.boss:
|
|
return (I_MonTypeNormal * I_SummonMax) + (I_MonTypeElite * I_SummonEliteMax);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// 몬스터 던전 종류별로 소환 가능한 인덱스 가져오기.
|
|
private int GetAvailDgMonsterIndex(CreatureBase.eDgCreatureClass cls)
|
|
{
|
|
int itypeminn = 0;
|
|
int itypemaxn = 14;
|
|
switch (cls)
|
|
{
|
|
case CreatureBase.eDgCreatureClass.DgN1:
|
|
itypeminn = 0;
|
|
itypemaxn = 14;
|
|
for (int i = itypeminn; i < itypemaxn; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eDgCreatureClass.DgN2:
|
|
itypeminn = 14;
|
|
itypemaxn = 22;
|
|
for (int i = itypeminn; i < itypemaxn; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eDgCreatureClass.DgN3:
|
|
itypeminn = 22;
|
|
itypemaxn = 23;
|
|
for (int i = itypeminn; i < itypemaxn; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eDgCreatureClass.DgN4:
|
|
itypeminn = 23;
|
|
itypemaxn = 24;
|
|
for (int i = itypeminn; i < itypemaxn; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eDgCreatureClass.DgN5:
|
|
itypeminn = 24;
|
|
itypemaxn = 25;
|
|
for (int i = itypeminn; i < itypemaxn; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eDgCreatureClass.DgE1:
|
|
itypeminn = 25;
|
|
itypemaxn = 26;
|
|
for (int i = itypeminn; i < itypemaxn; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eDgCreatureClass.DgBs:
|
|
itypeminn = 26;
|
|
itypemaxn = 27;
|
|
for (int i = itypeminn; i < itypemaxn; i++)
|
|
{
|
|
if (!goMonsters[i].activeSelf)
|
|
return i;
|
|
}
|
|
break;
|
|
|
|
case CreatureBase.eDgCreatureClass.DgAwBs:
|
|
return 27;
|
|
}
|
|
return -1;
|
|
}
|
|
#endregion Summon
|
|
|
|
#region Die & Fail
|
|
// 시간 경과로 아군 패배.
|
|
private void FailTimeOut()
|
|
{
|
|
ivChar.ChangeState(CreatureBase.eState.die);
|
|
}
|
|
|
|
// 아군 사망시 처리.
|
|
public void DieFriendly()
|
|
{
|
|
iTalkChar = 1; // 패배.
|
|
ShowTalkBox();
|
|
if (Random.Range(0, 2) == 0)
|
|
iTalkChar = Random.Range(3, iTalkMax);
|
|
|
|
int iarea = DataHandler.PlayData.curStage / 100;
|
|
int istage = DataHandler.PlayData.curStage % 100;
|
|
|
|
if (CurrentBattleType != BattleType.Stage)
|
|
bChangeArea = true;
|
|
else
|
|
bChangeArea = istage == 1 && iarea > 1;
|
|
|
|
GameUIMgr.ClosePopupSet();
|
|
|
|
switch (CurrentBattleType)
|
|
{
|
|
case BattleType.Stage:
|
|
DataHandler.FailStage();
|
|
bRetry = true;
|
|
DataHandler.PlayData.stageRepeat = bRetry;
|
|
DataHandler.PlayData.Save();
|
|
SetRetry();
|
|
break;
|
|
case BattleType.GoldDungeon:
|
|
case BattleType.EnhanceStoneDungeon:
|
|
case BattleType.PetDungeon:
|
|
case BattleType.AwakenStoneDungeon:
|
|
case BattleType.AwakenDungeon:
|
|
case BattleType.RelicDungeon:
|
|
CurrentBattleType = BattleType.Stage;
|
|
GameUIMgr.SSetActiveHotTime(true);
|
|
GameUIMgr.SReturnToPreservePreset();
|
|
GameUIMgr.SOnOffDungeonButton(true);
|
|
DungeonMgr.GetSuccessOrFail(false);
|
|
break;
|
|
case BattleType.GuardianDungeon:
|
|
CurrentBattleType = BattleType.Stage;
|
|
GameUIMgr.SSetActiveHotTime(true);
|
|
GameUIMgr.SReturnToPreservePreset();
|
|
GameUIMgr.SOnOffDungeonButton(true);
|
|
//여기요
|
|
DungeonMgr.GetSuccessOrFail(false);
|
|
break;
|
|
case BattleType.Pvp:
|
|
EndPvp();
|
|
return;
|
|
}
|
|
|
|
NoReward();
|
|
seqDieStage.Restart();
|
|
}
|
|
|
|
int waveMonCount = 0;
|
|
int shim = 0;
|
|
|
|
// 적 사망시 처리.
|
|
public void DieEnemy(CreatureBase.eCreatureClass cls, int index)
|
|
{
|
|
iMonsterCount--;
|
|
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
iTalkChar = 0; // 승리.
|
|
ShowTalkBox();
|
|
EndPvp();
|
|
return;
|
|
}
|
|
|
|
if (CurrentBattleType == BattleType.Stage)
|
|
{
|
|
DataHandler.AddPassProgress(eCondition.MonsterCnt, 1);
|
|
DataHandler.AddRecord(eCondition.MonsterCnt);
|
|
if (cls == CreatureBase.eCreatureClass.normal)
|
|
{
|
|
waveMonCount++;
|
|
if (waveMonCount >= 5)
|
|
{
|
|
DropItem(1, index, DropItemKind.Gold);
|
|
DropItem(1, index, DropItemKind.Exp);
|
|
waveMonCount = 0;
|
|
}
|
|
|
|
if (dropItemCount[(int)DropItemKind.Box] > 0)
|
|
{
|
|
int chestPercent = Random.Range(0, 100);
|
|
|
|
if (chestPercent > 95)
|
|
{
|
|
DropItem(1, index, DropItemKind.Box);
|
|
dropItemCount[(int)DropItemKind.Box]--;
|
|
}
|
|
}
|
|
|
|
if (dropItemCount[(int)DropItemKind.TradeEventCoin] > 0)
|
|
{
|
|
int eventPercent = Random.Range(0, 100);
|
|
|
|
if (eventPercent > 95)
|
|
{
|
|
DropItem(1, index, DropItemKind.TradeEventCoin);
|
|
dropItemCount[(int)DropItemKind.TradeEventCoin]--;
|
|
}
|
|
}
|
|
|
|
if (dropItemCount[(int)DropItemKind.RaiseEventCoin] > 0)
|
|
{
|
|
int eventPercent = Random.Range(0, 100);
|
|
|
|
if (eventPercent > 95)
|
|
{
|
|
DropItem(1, index, DropItemKind.RaiseEventCoin);
|
|
dropItemCount[(int)DropItemKind.RaiseEventCoin]--;
|
|
}
|
|
}
|
|
|
|
if (dropItemCount[(int)DropItemKind.RouletteEventCoin] > 0)
|
|
{
|
|
int eventPercent = Random.Range(0, 100);
|
|
|
|
if (eventPercent > 95)
|
|
{
|
|
DropItem(1, index, DropItemKind.RouletteEventCoin);
|
|
dropItemCount[(int)DropItemKind.RouletteEventCoin]--;
|
|
}
|
|
}
|
|
}
|
|
else if (cls == CreatureBase.eCreatureClass.elite)
|
|
{
|
|
DropItem(1, index, DropItemKind.Gold);
|
|
DropItem(1, index, DropItemKind.Exp);
|
|
|
|
while (dropItemCount[(int)DropItemKind.Box] > 0)
|
|
{
|
|
DropItem(1, index, DropItemKind.Box);
|
|
dropItemCount[(int)DropItemKind.Box]--;
|
|
}
|
|
while (dropItemCount[(int)DropItemKind.TradeEventCoin] > 0)
|
|
{
|
|
DropItem(1, index, DropItemKind.TradeEventCoin);
|
|
dropItemCount[(int)DropItemKind.TradeEventCoin]--;
|
|
}
|
|
while (dropItemCount[(int)DropItemKind.RaiseEventCoin] > 0)
|
|
{
|
|
DropItem(1, index, DropItemKind.RaiseEventCoin);
|
|
dropItemCount[(int)DropItemKind.RaiseEventCoin]--;
|
|
}
|
|
while (dropItemCount[(int)DropItemKind.RouletteEventCoin] > 0)
|
|
{
|
|
DropItem(1, index, DropItemKind.RouletteEventCoin);
|
|
dropItemCount[(int)DropItemKind.RouletteEventCoin]--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DropItem(1, index, DropItemKind.Gold);
|
|
DropItem(1, index, DropItemKind.Exp);
|
|
DropItem(1, index, DropItemKind.MemoryPiece);
|
|
dropItemCount[(int)DropItemKind.MemoryPiece]++;
|
|
}
|
|
}
|
|
|
|
if (iMonsterCount <= 0)
|
|
{
|
|
if (iWave >= iTotalWave)
|
|
{
|
|
bClear = true;
|
|
bChangeArea = false;
|
|
ivChar.ChangeState(CreatureBase.eState.idle);
|
|
|
|
switch (CurrentBattleType)
|
|
{
|
|
case BattleType.Stage:
|
|
bChangeArea = !bRetry && DataHandler.PlayData.curStage >= DataHandler.Const.stageMax;
|
|
DataHandler.ClearStage(!bRetry);
|
|
if (bChangeArea)
|
|
{
|
|
iTalkChar = 0; // 승리.
|
|
ShowTalkBox();
|
|
seqChangeArea.Restart(); //?-1 교체
|
|
|
|
ClearReward();
|
|
}
|
|
else
|
|
{
|
|
seqChangeStage.Restart();//1-? 교체
|
|
|
|
ClearReward();
|
|
}
|
|
break;
|
|
|
|
case BattleType.GoldDungeon:
|
|
case BattleType.EnhanceStoneDungeon:
|
|
case BattleType.PetDungeon:
|
|
case BattleType.AwakenStoneDungeon:
|
|
case BattleType.RelicDungeon:
|
|
iTalkChar = 0; // 승리.
|
|
GameUIMgr.ClosePopupSet();
|
|
ShowTalkBox();
|
|
if (DungeonMgr.GetAutoProgress() && DungeonMgr.IsDungeonProgressOK(1))
|
|
{
|
|
//seqChangeArea.Restart();
|
|
}
|
|
else
|
|
{
|
|
seqChangeArea.Restart(); //?-1 교체
|
|
}
|
|
DungeonMgr.GetSuccessOrFail(true);
|
|
break;
|
|
|
|
case BattleType.AwakenDungeon:
|
|
iTalkChar = 0; // 승리.
|
|
ShowTalkBox();
|
|
seqChangeArea.Restart(); //?-1 교체
|
|
DungeonMgr.GetSuccessOrFail(true);
|
|
break;
|
|
case BattleType.GuardianDungeon:
|
|
iTalkChar = 0; // 승리.
|
|
ShowTalkBox();
|
|
seqChangeArea.Restart(); //?-1 교체
|
|
DungeonMgr.GetSuccessOrFail(true);
|
|
break;
|
|
}
|
|
|
|
if (Random.Range(0, 2) == 0)
|
|
iTalkChar = Random.Range(3, iTalkMax);
|
|
|
|
EventMgr.SBadgeCheck();
|
|
}
|
|
else
|
|
{
|
|
iWave++;
|
|
ivChar.SetStatus(BuffMgr.Instance.GetCharAtk(), BuffMgr.Instance.GetCharHp(),
|
|
BuffMgr.Instance.GetCharCrtDam(), BuffMgr.Instance.GetCharCrtRate(), BuffMgr.Instance.GetCharMov(), BuffMgr.Instance.GetCharSpd(), GameProperty.Instance.PlayerCharacterAttackRange, true);
|
|
|
|
switch (CurrentBattleType)
|
|
{
|
|
case BattleType.Stage:
|
|
SummonMonStage();//중간왕과 끝판왕이 있음
|
|
SetStageAreaWave(DataHandler.PlayData.curStage, iWave);
|
|
break;
|
|
|
|
case BattleType.GoldDungeon:
|
|
case BattleType.EnhanceStoneDungeon:
|
|
case BattleType.PetDungeon:
|
|
case BattleType.AwakenStoneDungeon:
|
|
case BattleType.AwakenDungeon:
|
|
case BattleType.GuardianDungeon:
|
|
case BattleType.RelicDungeon:
|
|
SetDungeonWave(DungeonMgr.GetDungeonLevel(), iWave);
|
|
SummonMonDungeon();//왕이 나올지 안 나올지 모름
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UnlockCheck()
|
|
{
|
|
PetMgr.IsUnlock();
|
|
TreasureMgr.IsUnlock();
|
|
DungeonMgr.IsUnlock();
|
|
}
|
|
#endregion Die & Fail
|
|
|
|
bool doNotUnlockCheck = false;
|
|
int goToContent = 0;
|
|
|
|
void ContentUnlockCheck(int stage)
|
|
{
|
|
if (doNotUnlockCheck)
|
|
{
|
|
return;
|
|
}
|
|
UnlockCheck();
|
|
|
|
if (stage == DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GoldDG).openStage)
|
|
{
|
|
goToContent = 0;
|
|
}
|
|
else if (stage == DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.EnhanceStoneDG).openStage)
|
|
{
|
|
goToContent = 1;
|
|
}
|
|
else if (stage == DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.PetDG).openStage)
|
|
{
|
|
goToContent = 2;
|
|
}
|
|
else if (stage == DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenStoneDG).openStage)
|
|
{
|
|
goToContent = 3;
|
|
}
|
|
else if (stage == DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenDG).openStage)
|
|
{
|
|
goToContent = 4;
|
|
}
|
|
else if (stage == DataHandler.Const.gearAccOpenStage)
|
|
{
|
|
goToContent = 5;
|
|
}
|
|
else if (stage == DataHandler.Const.gearTreasureOpenStage)
|
|
{
|
|
goToContent = 6;
|
|
}
|
|
else if(stage > DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GoldDG).openStage &&
|
|
stage > DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.EnhanceStoneDG).openStage &&
|
|
stage > DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.PetDG).openStage &&
|
|
stage > DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenStoneDG).openStage &&
|
|
stage > DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenDG).openStage &&
|
|
stage > DataHandler.Const.gearAccOpenStage &&
|
|
stage > DataHandler.Const.gearTreasureOpenStage)
|
|
{
|
|
doNotUnlockCheck = true;
|
|
return;
|
|
}
|
|
dotUnlock[goToContent].DORewind();
|
|
|
|
canvasStageUnlock[goToContent].SetActive(true);
|
|
|
|
dotUnlock[goToContent].DOPlay();
|
|
isUnlockCheck = false;
|
|
}
|
|
|
|
public void ContentUnlockClose(int index)
|
|
{
|
|
canvasStageUnlock[index].SetActive(false);
|
|
}
|
|
|
|
public static void SContetnUnlockCloseAll()
|
|
{
|
|
for(int i = 0; i < Instance.canvasStageUnlock.Length; i++)
|
|
{
|
|
if (Instance.canvasStageUnlock[i].activeSelf)
|
|
Instance.canvasStageUnlock[i].SetActive(false);
|
|
}
|
|
}
|
|
|
|
public void ContentUnlockGoto(int index)
|
|
{
|
|
switch (index)
|
|
{
|
|
case 0:
|
|
SingleMgr.MoveContent(eEventMoveType.DgGold);
|
|
break;
|
|
case 1:
|
|
SingleMgr.MoveContent(eEventMoveType.DgStone);
|
|
break;
|
|
case 2:
|
|
SingleMgr.MoveContent(eEventMoveType.DgPet);
|
|
break;
|
|
case 3:
|
|
SingleMgr.MoveContent(eEventMoveType.DgAwaken);
|
|
break;
|
|
case 4:
|
|
SingleMgr.MoveContent(eEventMoveType.EnhanceAwakne);
|
|
break;
|
|
case 5:
|
|
SingleMgr.MoveContent(eEventMoveType.BagAccEar);
|
|
break;
|
|
case 6:
|
|
SingleMgr.MoveContent(eEventMoveType.BagTreasure);
|
|
break;
|
|
}
|
|
ContentUnlockClose(index);
|
|
}
|
|
|
|
#region Item Drop
|
|
public void DropItem(int spawnNum, int index, DropItemKind spriteNum)
|
|
{
|
|
for (int i = 0; i < spawnNum; i++)
|
|
{
|
|
if (dropItemPoolCount <= dropItemPoolCountNow) return;
|
|
|
|
dropItemPool[dropItemPoolCountNow].ItemAppear(trfMonsters[index].position, (int)spriteNum);
|
|
dropItemPoolCountNow++;
|
|
}
|
|
}
|
|
|
|
public static void ClearReward()
|
|
{
|
|
for (int i = 0; i < Instance.dropItemPoolCountNow; i++)
|
|
{
|
|
Instance.dropItemPool[i].itemDisappear(Instance.trfChar.position);
|
|
}
|
|
|
|
Instance.stageSuccessWindow.SetActive(true);
|
|
|
|
SoundMgr.PlaySfx(SoundName.GetGoods);
|
|
|
|
dArea areadata = DataHandler.GetArea(DataHandler.PlayData.curStage);
|
|
|
|
BigInteger gold = areadata.gold;
|
|
gold = gold * (BigInteger)BuffMgr.Instance.GetGoldDropRate() / dConst.RateMax;
|
|
|
|
BigInteger exp = areadata.exp;
|
|
exp = exp * (BigInteger)BuffMgr.Instance.GetExpDropRate() / dConst.RateMax;
|
|
|
|
Instance.stageSuccessGoodsItem[0].SetGoods(cGoods.TCurrency, cGoods.CGold, gold);
|
|
Instance.stageSuccessGoodsItem[1].SetGoods(cGoods.TExp, 0, exp);
|
|
|
|
while (Instance.dropChestKey.Count != 0)
|
|
{
|
|
DataHandler.AddBox(Instance.dropChestKey.Pop(), 1);
|
|
}
|
|
|
|
if (DataHandler.GetSysEventTrade().id != 0)
|
|
{
|
|
DataHandler.GetPlayEventTrade().item += Instance.tradeEventItemCount;//이벤트템 획득
|
|
}
|
|
|
|
if (DataHandler.GetSysEventRaise().id != 0)
|
|
{
|
|
DataHandler.GetPlayEventRaise().item += Instance.raiseEventItemCount;//이벤트템 획득
|
|
}
|
|
|
|
if (DataHandler.GetSysEventRoulette().id != 0)
|
|
{
|
|
DataHandler.GetPlayEventRoulette().item += Instance.rouletteEventItemCount;//이벤트템 획득
|
|
}
|
|
|
|
Instance.dropItemPoolCountNow = 0;//2256 번 줄도 수정
|
|
|
|
for (int i = 0; i < Instance.dropItemCount.Length; i++)
|
|
{
|
|
Instance.dropItemCount[i] = 0;
|
|
}
|
|
}
|
|
|
|
public static void NoReward()
|
|
{
|
|
for (int i = 0; i < Instance.dropItemPoolCountNow; i++)
|
|
{
|
|
Instance.dropItemPool[i].HideObject();
|
|
}
|
|
|
|
Instance.dropItemPoolCountNow = 0;
|
|
Instance.dropChestKey.Clear();
|
|
|
|
for (int i = 0; i < Instance.dropItemCount.Length; i++)
|
|
{
|
|
Instance.dropItemCount[i] = 0;
|
|
}
|
|
|
|
Instance.stageSuccessWindow.SetActive(false);
|
|
}
|
|
|
|
public static void NoRewardRepeatDungeon()
|
|
{
|
|
for (int i = 0; i < Instance.dropItemPoolCountNow; i++)
|
|
{
|
|
Instance.dropItemPool[i].HideObject();
|
|
}
|
|
|
|
Instance.dropItemPoolCountNow = 0;
|
|
Instance.dropChestKey.Clear();
|
|
|
|
for (int i = 0; i < Instance.dropItemCount.Length; i++)
|
|
{
|
|
Instance.dropItemCount[i] = 0;
|
|
}
|
|
|
|
}
|
|
#endregion
|
|
|
|
public void RushToEnemy(float fdt, int from=0)
|
|
{
|
|
if (from == 0)
|
|
ivChar.FrontToTarget(fdt);
|
|
else
|
|
ivCharEnemy.FrontToTarget(fdt);
|
|
}
|
|
|
|
public void RushToDir(int dir, float fdt, bool bfright)
|
|
{
|
|
ivChar.MoveToRush(dir, fdt, bfright);
|
|
}
|
|
|
|
#region Damage
|
|
/// <summary>
|
|
/// 특정 개체에게 데미지
|
|
/// </summary>
|
|
public void SendDamage(CreatureBase creature, BigInteger biatk, float fcrtdam, int icrtrate)
|
|
{
|
|
if (creature.IsBattleAvail())
|
|
{
|
|
creature.GetDamage(biatk, fcrtdam, icrtrate);
|
|
}
|
|
}
|
|
|
|
// 아군에게 데미지.
|
|
public void DamageToFriendly(BigInteger biatk, float fcrtdam, int icrtrate)
|
|
{
|
|
if (!ivChar.IsBattleAvail()) return;
|
|
ivChar.GetDamage(biatk, fcrtdam, icrtrate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bonuds에 포함에 포함되면 데미지를 입는다.
|
|
/// </summary>
|
|
public void DamageToFriendly(Bounds bounds, BigInteger biatk, float fcrtdam, int icrtrate, int idamcnt = -1)
|
|
{
|
|
if (!ivChar.IsBattleAvail())
|
|
return;
|
|
if (!bounds.Contains(trfChar.position))
|
|
return;
|
|
if (ivChar.GetIsDamaged() == idamcnt)
|
|
return;
|
|
ivChar.GetDamage(biatk, fcrtdam, icrtrate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bonuds에 포함되고 fdistance 거리 안에 있으면 데미지를 입는다.
|
|
/// </summary>
|
|
/// <param name="fdistance">player와 bounds 사이의 최대 거리</param>
|
|
public void DamageToFreiendlyDt(Bounds bounds, BigInteger biatk, float fcrtdam, int icrtrate, int idamcnt = -1, float fdistance = 0)
|
|
{
|
|
if (!ivChar.IsBattleAvail())
|
|
return;
|
|
if (!bounds.Contains(trfChar.position))
|
|
return;
|
|
if (ivChar.GetIsDamaged() == idamcnt)
|
|
return;
|
|
if (SCalcDistance(bounds.center, ivChar.transform.position) < fdistance)
|
|
return;
|
|
|
|
ivChar.GetDamage(biatk, fcrtdam, icrtrate);
|
|
}
|
|
|
|
// 전체 적에게 데미지.
|
|
public void DamageToEnemyAll(BigInteger biatk, float fcrtdam, int icrtrate)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (ivCharEnemy.IsBattleAvail())
|
|
ivCharEnemy.GetDamage(biatk, fcrtdam, icrtrate);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
ivMonsters[i].GetDamage(biatk, fcrtdam, icrtrate);
|
|
}
|
|
}
|
|
|
|
// 적에게 데미지.
|
|
public void DamageToEnemy(int index, BigInteger biatk, float fcrtdam, int icrtrate, float shake = 0f, int ivibrato = 10, int idnum = -1)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (ivCharEnemy.IsBattleAvail())
|
|
ivCharEnemy.GetDamage(biatk, fcrtdam, icrtrate);
|
|
return;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return;
|
|
if (!ivMonsters[index].IsBattleAvail())
|
|
return;
|
|
|
|
ivMonsters[index].GetDamage(biatk, fcrtdam, icrtrate);
|
|
IVCameraController.SShakeCamera(0.1f, shake, ivibrato);
|
|
}
|
|
|
|
// 일정 범위 내 적에게 데미지.
|
|
public void DamageToEnemy(Bounds bounds, BigInteger biatk, float fcrtdam, int icrtrate,int idnum, int idamcnt = -1, float shake = 0, int ivibrato = 10, Action hitEffect=null)
|
|
{
|
|
int attackCnt = 0;
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!ivCharEnemy.IsBattleAvail())
|
|
return;
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
if (ivCharEnemy.GetIsDamaged() == idamcnt)
|
|
return;
|
|
ivCharEnemy.GetDamage(biatk, fcrtdam, icrtrate);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
if (ivMonsters[i].GetIsDamaged() == idamcnt)
|
|
continue;
|
|
|
|
ivMonsters[i].GetDamage(biatk, fcrtdam, icrtrate, idnum);
|
|
if (hitEffect != null)
|
|
hitEffect();
|
|
attackCnt++;
|
|
if (idamcnt > -1)
|
|
ivMonsters[i].SetIsDamaged(idamcnt);
|
|
}
|
|
if (attackCnt > 0)
|
|
IVCameraController.SShakeCamera(0.2f, shake, ivibrato);
|
|
}
|
|
|
|
// 일정 범위 내 가장 가까운 적에게 데미지
|
|
public void DamageToEnemyTarget(Bounds bounds, BigInteger biatk, float fcrtdam, int icrtrate, float shake = 0f, int ivibrato = 10)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!ivCharEnemy.IsBattleAvail())
|
|
return;
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
ivCharEnemy.GetDamage(biatk, fcrtdam, icrtrate);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
|
|
ivMonsters[i].GetDamage(biatk, fcrtdam, icrtrate);
|
|
IVCameraController.SShakeCamera(0.2f, shake, ivibrato);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 일정 범위 내 가장 가까운 적들에게 데미지
|
|
public void DamageToEnemyTargets(Bounds bounds, int baseTarget, int icount, BigInteger biatk, float fcrtdam, int icrtrate, float shake = 0f, int ivibrato = 10)
|
|
{
|
|
int icnt = 0;
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!ivCharEnemy.IsBattleAvail())
|
|
return;
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
ivCharEnemy.GetDamage(biatk, fcrtdam, icrtrate);
|
|
return;
|
|
}
|
|
|
|
IVCameraController.SShakeCamera(0.2f, shake, ivibrato);
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (icnt == icount)
|
|
return;
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (bounds.Contains(trfMonsters[i].position))
|
|
{
|
|
ivMonsters[i].GetDamage(biatk, fcrtdam, icrtrate);
|
|
icnt++;
|
|
SSetNormalDamage(biatk);
|
|
}
|
|
}
|
|
if(icnt == 0)
|
|
{
|
|
if (!ivMonsters[baseTarget].IsBattleAvail())
|
|
return;
|
|
ivMonsters[baseTarget].GetDamage(biatk, fcrtdam, icrtrate);
|
|
}
|
|
}
|
|
|
|
public void DamageToEnemyDt(Bounds bounds, BigInteger biatk, float fcrtdam, int icrtrate, int idnum, int idamcnt = -1, float shake = 0, int ivibrato = 10, float fdistance=0, Action hitEffect = null)
|
|
{
|
|
int attackCnt = 0;
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!ivCharEnemy.IsBattleAvail())
|
|
return;
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
if (ivCharEnemy.GetIsDamaged() == idamcnt)
|
|
return;
|
|
if (SCalcDistance(bounds.center, ivCharEnemy.transform.position) < fdistance)
|
|
return;
|
|
|
|
ivCharEnemy.GetDamage(biatk, fcrtdam, icrtrate);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
if (ivMonsters[i].GetIsDamaged() == idamcnt)
|
|
continue;
|
|
if (SCalcDistance(bounds.center, ivMonsters[i].transform.position) < fdistance)
|
|
continue;
|
|
|
|
ivMonsters[i].GetDamage(biatk, fcrtdam, icrtrate);
|
|
if (hitEffect != null)
|
|
hitEffect();
|
|
|
|
attackCnt++;
|
|
//SSetTotalDamage(biatk, idnum);
|
|
if (idamcnt > -1)
|
|
ivMonsters[i].SetIsDamaged(idamcnt);
|
|
}
|
|
if (attackCnt > 0)
|
|
IVCameraController.SShakeCamera(0.2f, shake, ivibrato);
|
|
}
|
|
|
|
// 데미지 숫자 표시.
|
|
public void ShowDamage(CreatureBase.eCreatureClass cls, Vector2 v2pos, BigInteger biatkdam, bool bcrt)
|
|
{
|
|
if (!bOnDamageText)
|
|
return;
|
|
|
|
if (cls == CreatureBase.eCreatureClass.character)
|
|
{
|
|
// 플레이어 캐릭터.
|
|
for (int i = 0; i < I_ObjDamCnt; ++i)
|
|
{
|
|
if (goCharDmgTxts[i].activeSelf)
|
|
continue;
|
|
|
|
txtCharDmgTxts[i].color = CLR_CharDam;
|
|
txtCharDmgTxts[i].fontSize = F_DamNormal;
|
|
txtCharDmgTxts[i].text = FormatString.BigIntString1(biatkdam);
|
|
v2pos.y += F_AddYCharDam;
|
|
|
|
Vector2 screenPoint = camMain.WorldToScreenPoint(v2pos);
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(trfCharDamages, screenPoint, camUI, out Vector2 canvasPos);
|
|
trfCharDmgTxts[i].localPosition = canvasPos;
|
|
|
|
goCharDmgTxts[i].SetActive(true);
|
|
dtaCharDmgTxts[i].DORestart(true);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 몬스터 & 적 캐릭터.
|
|
for (int i = 0; i < I_ObjDamCnt; i++)
|
|
{
|
|
if (goDmgTxts[i].activeSelf)
|
|
continue;
|
|
|
|
if (bcrt)
|
|
{
|
|
txtDmgTxts[i].color = CLR_DamCritical;
|
|
txtDmgTxts[i].fontSize = F_DamCritical;
|
|
}
|
|
else
|
|
{
|
|
txtDmgTxts[i].color = CLR_DamNormal;
|
|
txtDmgTxts[i].fontSize = F_DamNormal;
|
|
}
|
|
txtDmgTxts[i].text = FormatString.BigIntString1(biatkdam);
|
|
|
|
switch (cls)
|
|
{
|
|
case CreatureBase.eCreatureClass.charEnemy:
|
|
v2pos.y += F_AddYCharDam;
|
|
break;
|
|
case CreatureBase.eCreatureClass.elite:
|
|
v2pos.y += F_AddYEliteDam;
|
|
break;
|
|
case CreatureBase.eCreatureClass.boss:
|
|
v2pos.y += F_AddYBossDam;
|
|
break;
|
|
default:
|
|
v2pos.y += F_AddYNormalDam;
|
|
break;
|
|
}
|
|
|
|
Vector2 screenPoint = camMain.WorldToScreenPoint(v2pos);
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(trfDamages, screenPoint, camUI, out Vector2 canvasPos);
|
|
trfDmgTxts[i].localPosition = canvasPos;
|
|
|
|
goDmgTxts[i].SetActive(true);
|
|
dtaDmgTxts[i].DORestart(true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
#endregion Damage
|
|
|
|
#region Debuff To Friendly
|
|
// 전체 아군에게 둔화.
|
|
public void DecMovToFriendlyAll(float ftime, float fvalue)
|
|
{
|
|
ivChar.SetDecMove(ftime, fvalue);
|
|
}
|
|
|
|
// 아군에게 둔화.
|
|
public void DecMovToFriendly(float ftime, float fvalue, int idamCnt = -1)
|
|
{
|
|
if (ivChar.GetIsDamaged() == idamCnt)
|
|
return;
|
|
ivChar.SetDecMove(ftime, fvalue);
|
|
}
|
|
|
|
// 일정 범위 내 아군에게 둔화.
|
|
public void DecMovToFriendly(Bounds bounds, float ftime, float fvalue, int idamCnt = -1)
|
|
{
|
|
if (!bounds.Contains(trfChar.position))
|
|
return;
|
|
if (ivChar.GetIsDamaged() == idamCnt)
|
|
return;
|
|
//if (SoundMgr.EfcOn)
|
|
// asNormalAttack.Play();
|
|
ivChar.SetDecMove(ftime, fvalue);
|
|
}
|
|
|
|
// 전체 아군에게 출혈.
|
|
public void DamageSecToFriendlyAll(float ftime, BigInteger biatk, float fcrtdam, int icrtrate)
|
|
{
|
|
ivChar.SetDamageSec(ftime, biatk, fcrtdam, icrtrate);
|
|
}
|
|
|
|
// 아군에게 출혈.
|
|
public void DamageSecToFriendly(float ftime, BigInteger biatk, float fcrtdam, int icrtrate)
|
|
{
|
|
ivChar.SetDamageSec(ftime, biatk, fcrtdam, icrtrate);
|
|
}
|
|
|
|
// 일정 범위 내 아군에게 출혈.
|
|
public void DamageSecToFriendly(Bounds bounds, float ftime, BigInteger biatk, float fcrtdam, int icrtrate, int idamCnt)
|
|
{
|
|
if (!bounds.Contains(trfChar.position))
|
|
return;
|
|
if (ivChar.GetIsDamaged() == idamCnt)
|
|
return;
|
|
ivChar.SetDamageSec(ftime, biatk, fcrtdam, icrtrate);
|
|
}
|
|
|
|
// 전체 아군에게 기절.
|
|
public void StunToFriendlyAll(float ftime)
|
|
{
|
|
ivChar.SetStun(ftime);
|
|
}
|
|
|
|
// 아군에게 기절.
|
|
public void StunToFriendly(float ftime)
|
|
{
|
|
if (SoundMgr.EfcOn)
|
|
//asNormalAttack.Play();
|
|
ivChar.SetStun(ftime);
|
|
}
|
|
|
|
// 일정 범위 내 아군에게 기절.
|
|
public void StunToFriendly(Bounds bounds, float ftime)
|
|
{
|
|
if (!bounds.Contains(trfChar.position))
|
|
return;
|
|
ivChar.SetStun(ftime);
|
|
}
|
|
|
|
// 전체 아군에게 넉백.
|
|
public void PushToFriendlyAll(float fvalue)
|
|
{
|
|
ivChar.PushFrame(fvalue);
|
|
}
|
|
|
|
// 아군에게 넉백.
|
|
public void PushToFriendly(float fvalue, int iDamCnt = -1)
|
|
{
|
|
if (ivChar.GetIsDamaged() == iDamCnt)
|
|
return;
|
|
|
|
ivChar.PushFrame(fvalue);
|
|
}
|
|
|
|
// 일정 범위 내 아군에게 넉백.
|
|
public void PushToFriendly(Bounds bounds, float fvalue, int iDamCnt)
|
|
{
|
|
if (!bounds.Contains(trfChar.position))
|
|
return;
|
|
if (ivChar.GetIsDamaged() == iDamCnt)
|
|
return;
|
|
ivChar.PushFrame(fvalue);
|
|
}
|
|
|
|
// 일정 범위 내 아군 당기기.
|
|
public void PullToFriendly(Bounds bounds, BigInteger bivalue, Transform trfpos)
|
|
{
|
|
if (!bounds.Contains(trfChar.position))
|
|
return;
|
|
ivChar.SetPull(bivalue, trfpos);
|
|
}
|
|
#endregion Debuff To Friendly
|
|
|
|
#region Debuff To Enemy
|
|
// 전체 적에게 둔화.
|
|
public void DecMovToEnemyAll(float ftime, float fvalue)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
ivCharEnemy.SetDecMove(ftime, fvalue);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
ivMonsters[i].SetDecMove(ftime, fvalue);
|
|
}
|
|
}
|
|
|
|
// 적에게 둔화.
|
|
public void DecMovToEnemy(int index, float ftime, float fvalue, int idamCnt = -1)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (ivCharEnemy.GetIsDamaged() == idamCnt)
|
|
return;
|
|
ivCharEnemy.SetDecMove(ftime, fvalue);
|
|
return;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return;
|
|
if (!ivMonsters[index].IsBattleAvail())
|
|
return;
|
|
if (ivMonsters[index].GetIsDamaged() == idamCnt)
|
|
return;
|
|
|
|
ivMonsters[index].SetDecMove(ftime, fvalue);
|
|
}
|
|
|
|
// 일정 범위 내 적에게 둔화.
|
|
public void DecMovToEnemy(Bounds bounds, float ftime, float fvalue, int idamCnt = -1)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
if (ivCharEnemy.GetIsDamaged() == idamCnt)
|
|
return;
|
|
if (SoundMgr.EfcOn)
|
|
//asNormalAttack.Play();
|
|
ivCharEnemy.SetDecMove(ftime, fvalue);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
if (ivMonsters[i].GetIsDamaged() == idamCnt)
|
|
continue;
|
|
if (SoundMgr.EfcOn)
|
|
//asNormalAttack.Play();
|
|
|
|
ivMonsters[i].SetDecMove(ftime, fvalue);
|
|
}
|
|
}
|
|
|
|
// 전체 적에게 출혈.
|
|
public void DamageSecToEnemyAll(float ftime, BigInteger biatk, float fcrtdam, int icrtrate, int idnum)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
ivCharEnemy.SetDamageSec(ftime, biatk, fcrtdam, icrtrate, idnum);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
ivMonsters[i].SetDamageSec(ftime, biatk, fcrtdam, icrtrate, idnum);
|
|
}
|
|
}
|
|
|
|
// 적에게 출혈.
|
|
public void DamageSecToEnemy(int index, float ftime, BigInteger biatk, float fcrtdam, int icrtrate, int idnum)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
ivCharEnemy.SetDamageSec(ftime, biatk, fcrtdam, icrtrate, idnum);
|
|
return;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return;
|
|
if (!ivMonsters[index].IsBattleAvail())
|
|
return;
|
|
|
|
ivMonsters[index].SetDamageSec(ftime, biatk, fcrtdam, icrtrate, idnum);
|
|
}
|
|
|
|
// 일정 범위 내 적에게 출혈.
|
|
public void DamageSecToEnemy(Bounds bounds, float ftime, BigInteger biatk, float fcrtdam, int icrtrate, int idamCnt, int idnum)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
if (ivCharEnemy.GetIsDamaged() == idamCnt)
|
|
return;
|
|
ivCharEnemy.SetDamageSec(ftime, biatk, fcrtdam, icrtrate, idnum);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
if (ivMonsters[i].GetIsDamaged() == idamCnt)
|
|
continue;
|
|
|
|
ivMonsters[i].SetDamageSec(ftime, biatk, fcrtdam, icrtrate, idnum);
|
|
}
|
|
}
|
|
|
|
// 전체 적에게 기절.
|
|
public void StunToEnemyAll(float ftime)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
ivCharEnemy.SetStun(ftime);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
ivMonsters[i].SetStun(ftime);
|
|
}
|
|
}
|
|
|
|
// 적에게 기절.
|
|
public void StunToEnemy(int index, float ftime)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (SoundMgr.EfcOn)
|
|
//asNormalAttack.Play();
|
|
ivCharEnemy.SetStun(ftime);
|
|
return;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return;
|
|
if (!ivMonsters[index].IsBattleAvail())
|
|
return;
|
|
if (SoundMgr.EfcOn)
|
|
//asNormalAttack.Play();
|
|
ivMonsters[index].SetStun(ftime);
|
|
}
|
|
|
|
// 일정 범위 내 적에게 기절.
|
|
public void StunToEnemy(Bounds bounds, float ftime)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
ivCharEnemy.SetStun(ftime);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
ivMonsters[i].SetStun(ftime);
|
|
}
|
|
}
|
|
|
|
// 전체 적에게 넉백.
|
|
public void PushToEnemyAll(float fvalue)
|
|
{
|
|
if (CurrentBattleType == BattleType.GuardianDungeon)
|
|
{
|
|
return;
|
|
}
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
ivCharEnemy.PushFrame(fvalue);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
ivMonsters[i].PushFrame(fvalue);
|
|
}
|
|
}
|
|
|
|
// 적에게 넉백.
|
|
public void PushToEnemy(int index, float fvalue, int iDamCnt = -1)
|
|
{
|
|
if (CurrentBattleType == BattleType.GuardianDungeon)
|
|
{
|
|
return;
|
|
}
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (ivCharEnemy.GetIsDamaged() == iDamCnt)
|
|
return;
|
|
ivCharEnemy.PushFrame(fvalue);
|
|
return;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return;
|
|
if (!ivMonsters[index].IsBattleAvail())
|
|
return;
|
|
if (ivMonsters[index].GetIsDamaged() == iDamCnt)
|
|
return;
|
|
|
|
ivMonsters[index].PushFrame(fvalue);
|
|
}
|
|
|
|
// 일정 범위 내 적에게 넉백.
|
|
public void PushToEnemy(Bounds bounds, float fvalue, int iDamCnt)
|
|
{
|
|
if (CurrentBattleType == BattleType.GuardianDungeon)
|
|
{
|
|
return;
|
|
}
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
if (ivCharEnemy.GetIsDamaged() == iDamCnt)
|
|
return;
|
|
ivCharEnemy.PushFrame(fvalue);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
if (ivMonsters[i].GetIsDamaged() == iDamCnt)
|
|
continue;
|
|
|
|
ivMonsters[i].PushFrame(fvalue);
|
|
}
|
|
}
|
|
|
|
// 일정 범위 내 적 당기기.
|
|
public void PullToEnemy(Bounds bounds,BigInteger bivalue, Transform trfpos)
|
|
{
|
|
if (CurrentBattleType == BattleType.GuardianDungeon)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
ivCharEnemy.SetPull(bivalue, trfpos);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
ivMonsters[i].SetPull(bivalue, trfpos);
|
|
}
|
|
|
|
}
|
|
#endregion Debuff To Enemy
|
|
|
|
#region Heal
|
|
public static void EnhanceHeal(int hpCalc)
|
|
{
|
|
float healPerHP = (hpCalc / (float)BuffMgr.Instance.GetCharHp()) * dConst.RateMaxFloat;
|
|
Instance.HealToFriendly(healPerHP);
|
|
}
|
|
|
|
public void HealToFriendly(float frate)
|
|
{
|
|
if (!ivChar.IsBattleAvail())
|
|
return;
|
|
ivChar.GetHeal(frate);
|
|
}
|
|
|
|
// 아군 회복.
|
|
public void HealToFriendly(Bounds bounds, float frate)
|
|
{
|
|
if (!ivChar.IsBattleAvail())
|
|
return;
|
|
if (!bounds.Contains(trfChar.position))
|
|
return;
|
|
ivChar.GetHeal(frate);
|
|
}
|
|
|
|
// 전체 적 회복.
|
|
public void HealToEnemyAll(float frate)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
ivCharEnemy.GetHeal(frate);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
ivMonsters[i].GetHeal(frate);
|
|
}
|
|
}
|
|
|
|
// 적 회복.
|
|
public void HealToEnemy(int index, float frate)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
ivCharEnemy.GetHeal(frate);
|
|
return;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return;
|
|
if (!ivMonsters[index].IsBattleAvail())
|
|
return;
|
|
ivMonsters[index].GetHeal(frate);
|
|
}
|
|
|
|
// 일정 범위 내 적 회복.
|
|
public void HealToEnemy(Bounds bounds, float frate)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!bounds.Contains(trfCharEnemy.position))
|
|
return;
|
|
ivCharEnemy.GetHeal(frate);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail())
|
|
continue;
|
|
if (!bounds.Contains(trfMonsters[i].position))
|
|
continue;
|
|
ivMonsters[i].GetHeal(frate);
|
|
}
|
|
}
|
|
#endregion Heal
|
|
|
|
#region Target & Position
|
|
/// <summary>
|
|
/// loop all creatures in battle. if func return false, stop loop.
|
|
/// </summary>
|
|
public static void LoopAllCreatures(Func<CreatureBase, bool> func)
|
|
{
|
|
if(Instance.ivChar.IsBattleAvail() && !func(Instance.ivChar)) return;
|
|
if (CurrentBattleType == BattleType.Pvp && Instance.ivCharEnemy.IsBattleAvail() && !func(Instance.ivCharEnemy)) return;
|
|
|
|
for (int i = 0; i < Instance.ivMonsters.Length; ++i)
|
|
{
|
|
if (Instance.ivMonsters[i].IsBattleAvail() && !func(Instance.ivMonsters[i])) return;
|
|
}
|
|
}
|
|
|
|
// 타겟 트랜스폼 인덱스로 가져오기.
|
|
public Transform GetTrfTarget(bool bfriend, int index)
|
|
{
|
|
if (bfriend)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
return trfCharEnemy;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return null;
|
|
return trfMonsters[index];
|
|
}
|
|
else
|
|
{
|
|
return trfChar;
|
|
}
|
|
}
|
|
|
|
// 타겟 인덱스로 가져오기.
|
|
public CreatureBase GetTarget(bool bfriend, int index)
|
|
{
|
|
if (bfriend)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
return ivCharEnemy;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return null;
|
|
return ivMonsters[index];
|
|
}
|
|
else
|
|
{
|
|
return ivChar;
|
|
}
|
|
}
|
|
|
|
public IVCharacter GetPlayer() => ivChar;
|
|
|
|
// 타겟 위치 가져오기.
|
|
public Vector3 GetTargetPos(bool bfriend, int index)
|
|
{
|
|
if (bfriend)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
return trfCharEnemy.position;
|
|
}
|
|
|
|
if (index < 0 || index >= I_ObjMonCnt)
|
|
return Vector3.zero;
|
|
return trfMonsters[index].position;
|
|
}
|
|
else
|
|
{
|
|
return trfChar.position;
|
|
}
|
|
}
|
|
|
|
// 영역 내 타겟 하나.
|
|
public int GetTargetPosInBounds(bool bfriendly, Bounds bounds)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
if(CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
int itarget = -1;
|
|
if (ivChar.IsBattleAvail())
|
|
{
|
|
if (bounds.Contains(trfChar.position))
|
|
{
|
|
itarget = 0;
|
|
}
|
|
}
|
|
return itarget;
|
|
}
|
|
else
|
|
{
|
|
int itarget = -1;
|
|
float fdist = 99999f;
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (ivMonsters[i].IsBattleAvail())
|
|
{
|
|
float fdtemp = SCalcDistance(trfChar.position, trfMonsters[i].position);
|
|
if (bounds.Contains(trfMonsters[i].position) && fdtemp < fdist)
|
|
{
|
|
fdist = fdtemp;
|
|
itarget = i;
|
|
}
|
|
}
|
|
}
|
|
return itarget;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (!ivCharEnemy.IsBattleAvail())
|
|
return -1;
|
|
if (bounds.Contains(trfCharEnemy.position))
|
|
return 0;
|
|
}
|
|
|
|
int itarget = -1;
|
|
float fdist = 99999f;
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (ivMonsters[i].IsBattleAvail())
|
|
{
|
|
float fdtemp = SCalcDistance(trfChar.position, trfMonsters[i].position);
|
|
if (bounds.Contains(trfMonsters[i].position) && fdtemp < fdist)
|
|
{
|
|
fdist = fdtemp;
|
|
itarget = i;
|
|
}
|
|
}
|
|
}
|
|
return itarget;
|
|
}
|
|
}
|
|
|
|
// 타겟 위치 인덱스로 가져오기.
|
|
public Vector3[] GetFriendlyPoses()
|
|
{
|
|
return new Vector3[] { trfChar.position };
|
|
}
|
|
|
|
// 제일 가까운 타겟 인덱스.
|
|
public int GetTargetIndex(bool bfriendly, Transform trf = null)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (ivCharEnemy.IsBattleAvail())
|
|
return 0;
|
|
return -1;
|
|
}
|
|
|
|
int itarget = -1;
|
|
float fdist = 99999f;
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (ivMonsters[i].IsBattleAvail())
|
|
{
|
|
if(trf == null)
|
|
{
|
|
float fdtemp = SCalcDistance(trfChar.position, trfMonsters[i].position);
|
|
if (fdtemp < fdist)
|
|
{
|
|
fdist = fdtemp;
|
|
itarget = i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float fdtemp = SCalcDistance(trf.position, trfMonsters[i].position);
|
|
if (fdtemp < fdist)
|
|
{
|
|
fdist = fdtemp;
|
|
itarget = i;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return itarget;
|
|
}
|
|
else
|
|
{
|
|
if (ivChar.IsBattleAvail())
|
|
return 0;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// 제일 가까운 타겟 인덱스(현재 타겟 제외).
|
|
public int GetTargetIndexExcept(bool bfriendly, int icurtarget)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (icurtarget == 0)
|
|
return -1;
|
|
if (ivCharEnemy.IsBattleAvail())
|
|
return 0;
|
|
return -1;
|
|
}
|
|
|
|
int itarget = -1;
|
|
float fdist = 99999f;
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (i == icurtarget)
|
|
continue;
|
|
if (ivMonsters[i].IsBattleAvail())
|
|
{
|
|
float fdtemp = SCalcDistance(trfChar.position, trfMonsters[i].position);
|
|
if (fdtemp < fdist)
|
|
{
|
|
fdist = fdtemp;
|
|
itarget = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
return itarget;
|
|
}
|
|
else
|
|
{
|
|
if (icurtarget == 0)
|
|
return -1;
|
|
if (ivChar.IsBattleAvail())
|
|
return 0;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public int GetTargetIndexExceptObj(Vector3 objPos, bool bfriendly, int icurtarget)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (icurtarget == 0)
|
|
return -1;
|
|
if (ivCharEnemy.IsBattleAvail())
|
|
return 0;
|
|
return -1;
|
|
}
|
|
|
|
int itarget = -1;
|
|
float fdist = 99999f;
|
|
|
|
for (int i = 0; i < I_ObjMonCnt; i++)
|
|
{
|
|
if (i == icurtarget)
|
|
continue;
|
|
if (ivMonsters[i].IsBattleAvail())
|
|
{
|
|
float fdtemp = SCalcDistance(objPos, trfMonsters[i].position);
|
|
if (fdtemp < fdist)
|
|
{
|
|
fdist = fdtemp;
|
|
itarget = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
return itarget;
|
|
}
|
|
else
|
|
{
|
|
if (icurtarget == 0)
|
|
return -1;
|
|
if (ivChar.IsBattleAvail())
|
|
return 0;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// 제일 가까운 아군들 인덱스.
|
|
public int[] GetFriendlyIndexes(int icount, int ibasetarget)
|
|
{
|
|
int[] itargets = new int[icount];
|
|
for (int i = 1; i < icount; i++)
|
|
{
|
|
itargets[i] = -1;
|
|
}
|
|
itargets[0] = ibasetarget;
|
|
|
|
if (ivChar.IsBattleAvail())
|
|
itargets[0] = 0;
|
|
return itargets;
|
|
}
|
|
|
|
// 타겟 위치 인덱스로 가져오기.
|
|
public Vector3[] GetEnemyPoses(int[] indexes)
|
|
{
|
|
if(indexes == null || indexes.Length == 0) return new Vector3[0];
|
|
|
|
Vector3[] results = new Vector3[indexes.Length];
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
results[0] = trfCharEnemy.position;
|
|
return results;
|
|
}
|
|
|
|
for (int i = 0; i < indexes.Length; i++)
|
|
{
|
|
if (indexes[i] >= 0 && indexes[i] < I_ObjMonCnt)
|
|
results[i] = trfMonsters[indexes[i]].position;
|
|
else
|
|
results[i] = Vector3.zero;
|
|
}
|
|
return results;
|
|
}
|
|
|
|
// 제일 가까운 적들 인덱스.
|
|
public int[] GetEnemyIndexes(int count, int pivotEnemyIdx)
|
|
{
|
|
if(count < 1 || pivotEnemyIdx < 0 || pivotEnemyIdx >= I_ObjMonCnt) return new int[0];
|
|
|
|
int[] targets = new int[count];
|
|
float[] dists = new float[count];
|
|
|
|
targets[0] = pivotEnemyIdx;
|
|
dists[0] = Vector2.SqrMagnitude(trfChar.position - trfMonsters[pivotEnemyIdx].position);
|
|
for (int i = 1; i < count; ++i)
|
|
{
|
|
targets[i] = -1;
|
|
dists[i] = float.MaxValue;
|
|
}
|
|
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
{
|
|
if (ivCharEnemy.IsBattleAvail()) targets[0] = 0;
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < I_ObjMonCnt; ++i)
|
|
{
|
|
if (!ivMonsters[i].IsBattleAvail()) continue;
|
|
|
|
float fdtemp = Vector2.SqrMagnitude(trfChar.position - trfMonsters[i].position); // 거리 저장
|
|
int indextemp = i; // 거리 저장한 id 저장
|
|
for (int j = 1; j < count; ++j)
|
|
{
|
|
if (fdtemp < dists[j] && fdtemp > dists[j - 1]) // 바뀌지 않았고, 측정한 거리가 설정된 거리보다 짧고 이전 거리보다 크면
|
|
{
|
|
targets[j] = indextemp;
|
|
dists[j] = fdtemp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return targets;
|
|
}
|
|
#endregion Target & Position
|
|
|
|
#region Calc.
|
|
// 거리 계산. z축은 무시하고 x, y축만 사용.
|
|
public static float SCalcDistance(Vector3 v3pos1, Vector3 v3pos2)
|
|
{
|
|
v3pos1.z = 0f;
|
|
v3pos2.z = 0f;
|
|
return Vector3.Distance(v3pos1, v3pos2);
|
|
}
|
|
|
|
// 크리티컬인지 계산.
|
|
public static bool SIsCritical(int icrtrate)
|
|
{
|
|
if (icrtrate <= 0)
|
|
return false;
|
|
int irate = icrtrate % dConst.RateMax;
|
|
if (Random.Range(0, dConst.RateMax) < irate)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 크리티컬 데미지 계산.
|
|
public static BigInteger SCalcCrtDam(BigInteger biatk, float fcrtdam, int icrtrate, bool bcrt)
|
|
{
|
|
#if true // 치명타 확률 오버한만큼 데미지 추가 ???
|
|
int icrtmul = icrtrate / dConst.RateMax;
|
|
icrtmul = icrtmul < 1 ? 1 : icrtmul;
|
|
#else
|
|
int icrtmul = 1;
|
|
#endif
|
|
if (bcrt)
|
|
icrtmul++;
|
|
|
|
BigInteger biLastAtk = biatk * icrtmul;
|
|
//@ fcrtdam 현재는 치명타 데미지 증가 스탯을 사용하지 않음. 추후 기획으로 추가되면 적용.
|
|
return biLastAtk;
|
|
}
|
|
#endregion Calc.
|
|
|
|
#region Effect
|
|
// 캐릭터 레벨업 이펙트.
|
|
private void PlayPtcLvUp(Vector3 v3worldpos)
|
|
{
|
|
trfLvUpChar.position = v3worldpos;
|
|
ptcLvUpChar.Play();
|
|
}
|
|
|
|
// 골드 드롭 연출.
|
|
private void PlayPtcGoldDrop(Vector3 v3worldpos)
|
|
{
|
|
for (int i = 0; i < ptcGoldDrops.Length; i++)
|
|
{
|
|
if (ptcGoldDrops[i].isPlaying)
|
|
continue;
|
|
trfGoldDrops[i].position = v3worldpos;
|
|
trfGoldDrops[i].localScale = Global.V3_1;
|
|
ptcGoldDrops[i].Play();
|
|
return;
|
|
}
|
|
}
|
|
|
|
public static bool SGetOnSkillEffect()
|
|
{
|
|
return Instance.bOnSkillEffect;
|
|
}
|
|
|
|
public static void SSetOnSkillEffect(bool bSkill)
|
|
{
|
|
Instance.bOnSkillEffect = bSkill;
|
|
}
|
|
|
|
public static bool SGetOnDamageText()
|
|
{
|
|
return Instance.bOnDamageText;
|
|
}
|
|
|
|
public static void SSetOnDamageText(bool bDamage)
|
|
{
|
|
Instance.bOnDamageText = bDamage;
|
|
}
|
|
|
|
public void SkillFade(bool bfade, bool bforce=false)
|
|
{
|
|
if (bfade)
|
|
{
|
|
iFadeCnt++;
|
|
srSkillFade.DOFade(0.6f, 0.5f);
|
|
}
|
|
else
|
|
{
|
|
iFadeCnt--;
|
|
if(iFadeCnt == 0 || bforce)
|
|
{
|
|
srSkillFade.DOFade(0f, 0.5f);
|
|
iFadeCnt = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ResetFade()
|
|
{
|
|
iFadeCnt = 0;
|
|
srSkillFade.color = Color.clear;
|
|
}
|
|
#endregion Effect
|
|
|
|
#region Wave & Go/Retry
|
|
// 현재 스테이지 웨이브 수 랜덤으로 가져오기.
|
|
private int GetWaveTotal()
|
|
{
|
|
return DataHandler.GetArea(DataHandler.PlayData.curStage).wave;
|
|
}
|
|
|
|
int tradeEventMaxRate = 0;
|
|
int tradeEventRandomRate = 0;
|
|
int tradeEventItemCount = 0;
|
|
|
|
int raiseEventMaxRate = 0;
|
|
int raiseEventRandomRate = 0;
|
|
int raiseEventItemCount = 0;
|
|
|
|
int rouletteEventMaxRate = 0;
|
|
int rouletteEventRandomRate = 0;
|
|
int rouletteEventItemCount = 0;
|
|
|
|
private void GetStageItemAndGetPercent()
|
|
{
|
|
dArea curArea = DataHandler.GetArea(DataHandler.PlayData.curStage);
|
|
|
|
for(int i = 0; i < stageSuccessGoodsItem.Length; i++)
|
|
{
|
|
stageSuccessGoodsItem[i].gameObject.SetActive(false);
|
|
}
|
|
|
|
stageSuccessGoodsItem[0].SetGoods(cGoods.TCurrency, cGoods.CGold, curArea.gold);
|
|
stageSuccessGoodsItem[0].gameObject.SetActive(curArea.gold != 0);
|
|
|
|
stageSuccessGoodsItem[1].SetGoods(cGoods.TExp, 0, curArea.exp);
|
|
stageSuccessGoodsItem[1].gameObject.SetActive(curArea.exp != 0);
|
|
|
|
float fboxrate;
|
|
|
|
if (curArea.normalBoxCnt > 0 && curArea.normalBox != 0)
|
|
{
|
|
fboxrate = DataHandler.Const.normalBoxRate * (BuffMgr.Instance.GetChestDropRate() + dConst.RateMax) / dConst.RateMax;
|
|
stageSuccessGoodsItem[2].SetGoods(cGoods.TBox, curArea.normalBox, curArea.normalBoxCnt);
|
|
stageSuccessGoodsItem[2].gameObject.SetActive(curArea.exp != 0);
|
|
if(Random.Range(0, dConst.RateMax) < fboxrate)
|
|
{
|
|
dropItemCount[(int)DropItemKind.Box]++;
|
|
dropChestKey.Push(curArea.normalBox);
|
|
stageSuccessGoodsItem[2].gameObject.SetActive(true);
|
|
}
|
|
else
|
|
stageSuccessGoodsItem[2].gameObject.SetActive(false);
|
|
|
|
}
|
|
else
|
|
stageSuccessGoodsItem[2].gameObject.SetActive(false);
|
|
|
|
if (curArea.gearBoxCnt > 0 && curArea.gearBox != 0)
|
|
{
|
|
fboxrate = DataHandler.Const.gearBoxRate * (BuffMgr.Instance.GetChestDropRate() + dConst.RateMax) / dConst.RateMax;
|
|
stageSuccessGoodsItem[3].SetGoods(cGoods.TBox, curArea.gearBox, curArea.gearBoxCnt);
|
|
stageSuccessGoodsItem[3].gameObject.SetActive(curArea.exp != 0);
|
|
if (Random.Range(0, dConst.RateMax) < fboxrate)
|
|
{
|
|
dropItemCount[(int)DropItemKind.Box]++;
|
|
dropChestKey.Push(curArea.gearBox);
|
|
stageSuccessGoodsItem[3].gameObject.SetActive(true);
|
|
}
|
|
else
|
|
stageSuccessGoodsItem[3].gameObject.SetActive(false);
|
|
|
|
}
|
|
else
|
|
stageSuccessGoodsItem[3].gameObject.SetActive(false);
|
|
|
|
if (curArea.accBoxCnt > 0 && curArea.accBox != 0)
|
|
{
|
|
fboxrate = DataHandler.Const.gearBoxRate * (BuffMgr.Instance.GetChestDropRate() + dConst.RateMax) / dConst.RateMax;
|
|
stageSuccessGoodsItem[4].SetGoods(cGoods.TBox, curArea.accBox, curArea.accBoxCnt);
|
|
stageSuccessGoodsItem[4].gameObject.SetActive(curArea.exp != 0);
|
|
|
|
if (Random.Range(0, dConst.RateMax) < fboxrate)
|
|
{
|
|
dropItemCount[(int)DropItemKind.Box]++;
|
|
dropChestKey.Push(curArea.accBox);
|
|
stageSuccessGoodsItem[4].gameObject.SetActive(true);
|
|
}
|
|
else
|
|
stageSuccessGoodsItem[4].gameObject.SetActive(false);
|
|
|
|
}
|
|
else
|
|
stageSuccessGoodsItem[4].gameObject.SetActive(false);
|
|
|
|
if (curArea.petBoxCnt > 0 && curArea.petBox != 0)
|
|
{
|
|
fboxrate = DataHandler.Const.petBoxRate * (BuffMgr.Instance.GetChestDropRate() + dConst.RateMax) / dConst.RateMax;
|
|
stageSuccessGoodsItem[5].SetGoods(cGoods.TBox, curArea.petBox, curArea.petBoxCnt);
|
|
stageSuccessGoodsItem[5].gameObject.SetActive(curArea.exp != 0);
|
|
if (Random.Range(0, dConst.RateMax) < fboxrate)
|
|
{
|
|
dropItemCount[(int)DropItemKind.Box]++;
|
|
dropChestKey.Push(curArea.petBox);
|
|
stageSuccessGoodsItem[5].gameObject.SetActive(true);
|
|
}
|
|
else
|
|
stageSuccessGoodsItem[5].gameObject.SetActive(false);
|
|
}
|
|
else
|
|
stageSuccessGoodsItem[5].gameObject.SetActive(false);
|
|
|
|
if (DataHandler.GetSysEventTrade().id != 0)
|
|
{
|
|
tradeEventMaxRate = DataHandler.GetEvents()[(int)eEventMoveType.Exchange].scale1;
|
|
|
|
tradeEventRandomRate = Random.Range(0, IVDataFormat.dConst.RateMax);
|
|
|
|
if (tradeEventRandomRate < tradeEventMaxRate)//2476 번과 함께 수정 필요
|
|
{
|
|
tradeEventItemCount = Random.Range(DataHandler.GetEvents()[(int)eEventMoveType.Exchange].scale2, DataHandler.GetEvents()[(int)eEventMoveType.Exchange].scale3);
|
|
stageSuccessGoodsItem[6].SetGoods(cGoods.TEventTrade, 1, tradeEventItemCount);
|
|
stageSuccessGoodsItem[6].gameObject.SetActive(true);
|
|
dropItemCount[(int)DropItemKind.TradeEventCoin] += tradeEventItemCount / Mathf.Max((DataHandler.GetEvents()[(int)eEventMoveType.Exchange].scale3 / 3), 1) + 1;
|
|
}
|
|
else
|
|
{
|
|
stageSuccessGoodsItem[6].gameObject.SetActive(false);
|
|
}
|
|
|
|
}
|
|
|
|
if (DataHandler.GetSysEventRaise().id != 0)
|
|
{
|
|
raiseEventMaxRate = DataHandler.GetEvents()[(int)eEventMoveType.Raise].scale1;
|
|
|
|
raiseEventRandomRate = Random.Range(0, IVDataFormat.dConst.RateMax);
|
|
|
|
if (raiseEventRandomRate < raiseEventMaxRate)//2476 번과 함께 수정 필요
|
|
{
|
|
raiseEventItemCount = Random.Range(1, DataHandler.GetEvents()[(int)eEventMoveType.Raise].scale2);
|
|
stageSuccessGoodsItem[7].SetGoods(cGoods.TEventRaise, 1, raiseEventItemCount);
|
|
stageSuccessGoodsItem[7].gameObject.SetActive(true);
|
|
dropItemCount[(int)DropItemKind.RaiseEventCoin] = raiseEventItemCount / Mathf.Max((DataHandler.GetEvents()[(int)eEventMoveType.Raise].scale2 / 3), 1) + 1;
|
|
}
|
|
else
|
|
{
|
|
stageSuccessGoodsItem[7].gameObject.SetActive(false);
|
|
}
|
|
|
|
}
|
|
|
|
if (DataHandler.GetSysEventRoulette().id != 0)
|
|
{
|
|
rouletteEventMaxRate = DataHandler.GetEvents()[(int)eEventMoveType.Roulette].scale1;
|
|
|
|
rouletteEventRandomRate = Random.Range(0, IVDataFormat.dConst.RateMax);
|
|
|
|
if (rouletteEventRandomRate < rouletteEventMaxRate)//2476 번과 함께 수정 필요
|
|
{
|
|
rouletteEventItemCount = Random.Range(1, DataHandler.GetEvents()[(int)eEventMoveType.Roulette].scale2);
|
|
stageSuccessGoodsItem[8].SetGoods(cGoods.TEventRoulette, 1, rouletteEventItemCount);
|
|
stageSuccessGoodsItem[8].gameObject.SetActive(true);
|
|
dropItemCount[(int)DropItemKind.RouletteEventCoin] = rouletteEventItemCount / (Mathf.Max(DataHandler.GetEvents()[(int)eEventMoveType.Roulette].scale2 / 3, 1)) + 1;
|
|
}
|
|
else
|
|
{
|
|
stageSuccessGoodsItem[8].gameObject.SetActive(false);
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 6; i < stageSuccessGoodsItem.Length; i++)
|
|
{
|
|
if (stageSuccessGoodsItem[i] == null)
|
|
stageSuccessGoodsItem[i].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
private void SetWaveCapsule(int wave)
|
|
{
|
|
goWaveBossArrow.SetActive(false);
|
|
|
|
for(int i = 0; i < imgWaveCapsule.Length; i++)
|
|
{
|
|
imgWaveCapsule[i].color = Color.white;
|
|
|
|
goWaveCapsuleArrow[i].SetActive(false);
|
|
|
|
if (i < wave - 1)
|
|
{
|
|
imgWaveCapsule[i].gameObject.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
imgWaveCapsule[i].gameObject.SetActive(false);
|
|
}
|
|
|
|
|
|
if (wave == 1)
|
|
{
|
|
imgWaveCapsule[0].gameObject.SetActive(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 웨이브 진행시마다 UI 세팅.
|
|
private void SetStageAreaWave(int iareastage, int iwave)
|
|
{
|
|
int iarea = iareastage / 100;
|
|
int istage = iareastage % 100;
|
|
|
|
dArea areadata = DataHandler.GetArea(DataHandler.PlayData.curStage);
|
|
biMonAtk = areadata.atk;// + (areadata.atkInc * istage);
|
|
biMonHp = areadata.hp;//+ (areadata.hpInc * istage);
|
|
|
|
fMonSpeedN = new float[areadata.monsterNormal.Length];
|
|
fMonSpeedE = new float[areadata.monsterEpic.Length];
|
|
fMonSpeedB = new float[areadata.monsterBoss.Length];
|
|
iMonGroupN = new int[areadata.monsterNormal.Length];
|
|
iMonGroupE = new int[areadata.monsterEpic.Length];
|
|
iMonGroupB = new int[areadata.monsterBoss.Length];
|
|
|
|
for (int i = 0; i< areadata.monsterNormal.Length; i++)
|
|
{
|
|
fMonSpeedN[i] = DataHandler.GetMonsterSpeed(areadata.monsterNormal[i]);
|
|
iMonGroupN[i] = DataHandler.GetMonsterGroup(areadata.monsterNormal[i]);
|
|
}
|
|
for (int i = 0; i < areadata.monsterEpic.Length; i++)
|
|
{
|
|
fMonSpeedE[i] = DataHandler.GetMonsterSpeed(areadata.monsterEpic[i]);
|
|
iMonGroupE[i] = DataHandler.GetMonsterGroup(areadata.monsterEpic[i]);
|
|
}
|
|
for (int i = 0; i < areadata.monsterBoss.Length; i++)
|
|
{
|
|
fMonSpeedB[i] = DataHandler.GetMonsterSpeed(areadata.monsterBoss[i]);
|
|
iMonGroupB[i] = DataHandler.GetMonsterGroup(areadata.monsterBoss[i]);
|
|
}
|
|
|
|
txtBattleStage.text = FormatString.StringFormat(FormatString.AreaStageNoWave, iarea, istage.ToString());
|
|
|
|
imgBattleWave.fillAmount = (iwave - 1) / ((float)iTotalWave - 1);
|
|
|
|
if (iWave != 1)
|
|
{
|
|
goWaveCapsuleArrow[iWave - 2].SetActive(false);
|
|
}
|
|
|
|
if (imgBattleWave.fillAmount != 1)
|
|
{
|
|
SettingBossImage(istage);
|
|
imgWaveCapsule[iWave - 1].color = Global.CLR_WaveProgress;
|
|
goWaveCapsuleArrow[iWave - 1].SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
goWaveBossArrow.SetActive(true);
|
|
}
|
|
}
|
|
|
|
private void SetDungeonWave(int level, int iwave)
|
|
{
|
|
switch (CurrentBattleType)
|
|
{
|
|
case BattleType.GoldDungeon:
|
|
SettingDungeonStat(level, DungeonMgr.DungeonKind.GoldDG);
|
|
SettingDungeonClearReward(DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GoldDG).diffs[level - 1].rewards);
|
|
txtBattleStage.text = FormatString.StringFormat(LocalizationText.GetText("gold_dungeon_leftup"), level.ToString());
|
|
break;
|
|
case BattleType.EnhanceStoneDungeon:
|
|
SettingDungeonStat(level, DungeonMgr.DungeonKind.EnhanceStoneDG);
|
|
SettingDungeonClearReward(DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.EnhanceStoneDG).diffs[level - 1].rewards);
|
|
txtBattleStage.text = FormatString.StringFormat(LocalizationText.GetText("enhance_dungeon_leftup"), level.ToString());
|
|
break;
|
|
case BattleType.PetDungeon:
|
|
SettingDungeonStat(level, DungeonMgr.DungeonKind.PetDG);
|
|
SettingDungeonClearReward(DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.PetDG).diffs[level - 1].rewards);
|
|
txtBattleStage.text = FormatString.StringFormat(LocalizationText.GetText("pet_dungeon_leftup"), Mathf.Ceil((float)level / 10), (level - (Mathf.Ceil((float)level / 10) - 1) * 10));
|
|
break;
|
|
case BattleType.AwakenStoneDungeon:
|
|
SettingDungeonStat(level, DungeonMgr.DungeonKind.AwakenStoneDG);
|
|
SettingDungeonClearReward(DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenStoneDG).diffs[level - 1].rewards);
|
|
txtBattleStage.text = FormatString.StringFormat(LocalizationText.GetText("awaken_stone_dungeon_leftup"), level.ToString());
|
|
break;
|
|
case BattleType.AwakenDungeon:
|
|
SettingDungeonStat(level, DungeonMgr.DungeonKind.AwakenDG);
|
|
txtBattleStage.text = FormatString.StringFormat(LocalizationText.GetText("awaken_dungeon_leftup"), level.ToString());
|
|
break;
|
|
case BattleType.GuardianDungeon:
|
|
SettingDungeonStat(level, DungeonMgr.DungeonKind.GuardianDG);
|
|
txtBattleStage.text = FormatString.StringFormat(LocalizationText.GetText("guardian_dungeon_leftup"), level.ToString());
|
|
break;
|
|
case BattleType.RelicDungeon:
|
|
SettingDungeonStat(level, DungeonMgr.DungeonKind.relicDG);
|
|
SettingDungeonClearReward(DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.relicDG).diffs[level - 1].rewards);
|
|
txtBattleStage.text = FormatString.StringFormat(LocalizationText.GetText("relic_dungeon_leftup"), level.ToString());
|
|
break;
|
|
}
|
|
|
|
if (iTotalWave == 1)
|
|
{
|
|
imgBattleWave.fillAmount = 1;
|
|
imgWaveCapsule[iWave - 1].color = Global.CLR_WaveProgress;
|
|
}
|
|
else
|
|
{
|
|
imgBattleWave.fillAmount = (iwave - 1) / ((float)iTotalWave - 1);
|
|
}
|
|
|
|
if (iWave != 1)
|
|
{
|
|
goWaveCapsuleArrow[iWave - 2].SetActive(false);
|
|
}
|
|
|
|
if (imgBattleWave.fillAmount != 1)
|
|
{
|
|
SettingBossImage(0);
|
|
imgWaveCapsule[iWave - 1].color = Global.CLR_WaveProgress;
|
|
goWaveCapsuleArrow[iWave - 1].SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
goWaveBossArrow.SetActive(true);
|
|
}
|
|
}
|
|
|
|
public void SettingDungeonStat(int level, DungeonMgr.DungeonKind type)
|
|
{
|
|
if (type != DungeonMgr.DungeonKind.EnhanceStoneDG)
|
|
{
|
|
biMonAtk = DataHandler.GetDungeonTypeInfo(type).diffs[level - 1].monAtk;
|
|
biMonHp = DataHandler.GetDungeonTypeInfo(type).diffs[level - 1].monHp;
|
|
}
|
|
else
|
|
{
|
|
biMonAtk = 0;
|
|
biMonHp = DataHandler.GetDungeonTypeInfo(type).diffs[level - 1].monHp + (DataHandler.GetDungeonTypeInfo(type).diffs[level - 1].hpInc * iWave);
|
|
}
|
|
|
|
switch (type)
|
|
{
|
|
case DungeonMgr.DungeonKind.GoldDG:
|
|
case DungeonMgr.DungeonKind.PetDG:
|
|
fMonSpeedE = new float[DataHandler.GetDungeonTypeInfo(type).monsterEpic.Length];
|
|
fMonSpeedB = new float[DataHandler.GetDungeonTypeInfo(type).monsterBoss.Length];
|
|
iMonGroupE = new int[DataHandler.GetDungeonTypeInfo(type).monsterEpic.Length];
|
|
iMonGroupB = new int[DataHandler.GetDungeonTypeInfo(type).monsterBoss.Length];
|
|
|
|
for (int i = 0; i < DataHandler.GetDungeonTypeInfo(type).monsterEpic.Length; i++)
|
|
{
|
|
fMonSpeedE[i] = DataHandler.GetMonsterSpeed(DataHandler.GetDungeonTypeInfo(type).monsterEpic[i]);
|
|
iMonGroupE[i] = DataHandler.GetMonsterGroup(DataHandler.GetDungeonTypeInfo(type).monsterEpic[i]);
|
|
}
|
|
for (int i = 0; i < DataHandler.GetDungeonTypeInfo(type).monsterBoss.Length; i++)
|
|
{
|
|
fMonSpeedB[i] = DataHandler.GetMonsterSpeed(DataHandler.GetDungeonTypeInfo(type).monsterBoss[i]);
|
|
iMonGroupB[i] = DataHandler.GetMonsterGroup(DataHandler.GetDungeonTypeInfo(type).monsterBoss[i]);
|
|
}
|
|
break;
|
|
case DungeonMgr.DungeonKind.GuardianDG:
|
|
fMonSpeedB[0] = DataHandler.GetMonsterSpeed(DataHandler.GetDungeonTypeInfo(type).monsterNormal[0]);
|
|
iMonGroupB[0] = DataHandler.GetMonsterGroup(DataHandler.GetDungeonTypeInfo(type).monsterNormal[0]);
|
|
break;
|
|
case DungeonMgr.DungeonKind.AwakenStoneDG:
|
|
fMonSpeedB[0] = DataHandler.GetMonsterSpeed(DataHandler.GetDungeonTypeInfo(type).monsterNormal[0]);
|
|
iMonGroupB[0] = DataHandler.GetMonsterGroup(DataHandler.GetDungeonTypeInfo(type).monsterNormal[0]);
|
|
break;
|
|
}
|
|
|
|
fMonSpeedN = new float[DataHandler.GetDungeonTypeInfo(type).monsterNormal.Length];
|
|
iMonGroupN = new int[DataHandler.GetDungeonTypeInfo(type).monsterNormal.Length];
|
|
|
|
for (int i = 0; i < DataHandler.GetDungeonTypeInfo(type).monsterNormal.Length; i++)
|
|
{
|
|
fMonSpeedN[i] = DataHandler.GetMonsterSpeed(DataHandler.GetDungeonTypeInfo(type).monsterNormal[i]);
|
|
iMonGroupN[i] = DataHandler.GetMonsterGroup(DataHandler.GetDungeonTypeInfo(type).monsterNormal[i]);
|
|
}
|
|
}
|
|
|
|
public void SettingBossImage(int stage)
|
|
{
|
|
if (stage == DataHandler.Const.stageMax)
|
|
{
|
|
imgWaveBoss.sprite = sprBoss;
|
|
}
|
|
else
|
|
{
|
|
imgWaveBoss.sprite = sprBossElite;
|
|
}
|
|
}
|
|
|
|
// 스테이지 돌파/반복.
|
|
public void BtnRetry()
|
|
{
|
|
bRetry = !bRetry;
|
|
SetRetry();
|
|
|
|
DataHandler.PlayData.stageRepeat = bRetry;
|
|
DataHandler.PlayData.Save();
|
|
if (bRetry)
|
|
{
|
|
GameUIMgr.SOpenToast(LocalizationText.GetText("btn_repeat_alarm"));
|
|
}
|
|
else
|
|
{
|
|
GameUIMgr.SOpenToast(LocalizationText.GetText("btn_progress_alarm"));
|
|
}
|
|
}
|
|
|
|
// 스테이지 돌파/반복 UI 세팅.
|
|
private void SetRetry()
|
|
{
|
|
if (bRetry)
|
|
{
|
|
imgBattleRetry.sprite = sprBattleRetry;
|
|
txtRetry.text = LocalizationText.GetText("all_repeat");
|
|
}
|
|
else
|
|
{
|
|
imgBattleRetry.sprite = sprBattleGo;
|
|
txtRetry.text = LocalizationText.GetText("all_break");
|
|
}
|
|
|
|
}
|
|
|
|
// 스테이지 이동.
|
|
public static bool SGoToStage(int iarea, int istage)
|
|
{
|
|
int icurarea = DataHandler.PlayData.curStage / 100;
|
|
Instance.bChangeArea = icurarea != iarea;
|
|
|
|
if (CurrentBattleType != BattleType.Stage)
|
|
{
|
|
CurrentBattleType = BattleType.Stage;
|
|
Instance.bChangeArea = true;
|
|
//return false;
|
|
}
|
|
|
|
Instance.BattlePause = true;
|
|
DataHandler.GoToStage(iarea, istage);
|
|
|
|
Instance.AStageMoveSave(false);
|
|
|
|
if (Instance.seqStartStage.IsPlaying())
|
|
Instance.seqStartStage.Pause();
|
|
if (Instance.seqDieStage.IsPlaying())
|
|
Instance.seqDieStage.Pause();
|
|
if (Instance.seqChangeStage.IsPlaying())
|
|
Instance.seqChangeStage.Pause();
|
|
if (Instance.seqChangeArea.IsPlaying())
|
|
Instance.seqChangeArea.Pause();
|
|
|
|
if (Instance.bChangeArea)
|
|
Instance.seqChangeArea.Restart();
|
|
else
|
|
Instance.seqChangeStage.Restart();
|
|
return true;
|
|
}
|
|
|
|
nStageRequest stageData = null;
|
|
|
|
//스테이지 서버 통신
|
|
public static void SStageMoveSave(bool isClear)
|
|
{
|
|
Instance.AStageMoveSave(isClear);
|
|
}
|
|
|
|
private void AStageMoveSave(bool isClear)
|
|
{
|
|
stageData = new nStageRequest();
|
|
|
|
stageData.curStage = DataHandler.PlayData.curStage;
|
|
stageData.clearStage = DataHandler.PlayData.clearStage;
|
|
stageData.isClear = isClear;
|
|
if (isClear)
|
|
{
|
|
stageData.curStage--;
|
|
SvConnectManager.Instance.RequestSvPost(false, 0, IVServerFormat.UrlApi.GetUrl(IVServerFormat.UrlApi.CurrentStageSave), typeof(nStageReturn), AStageMoveSaveSucc, AStageMoveSaveFail, stageData, true);
|
|
}
|
|
|
|
}
|
|
|
|
private void AStageMoveSaveFail(IVServerFormat.SvError error, object request)
|
|
{
|
|
stageData = null;
|
|
}
|
|
|
|
bool isUnlockCheck = false;
|
|
|
|
// 스테이지 갱신 교체 통신 성공.
|
|
private void AStageMoveSaveSucc(object result, object request)
|
|
{
|
|
nStageReturn data = result as nStageReturn;
|
|
if (data == null)
|
|
{
|
|
AStageMoveSaveFail(new IVServerFormat.SvError(IVServerFormat.eErrorCode.NULL_OR_EMPTY), request);
|
|
return;
|
|
}
|
|
|
|
isUnlockCheck = true;
|
|
|
|
stageData = null;
|
|
|
|
DataHandler.PlayData.Save();
|
|
//CoverCamera.Release();
|
|
}
|
|
#endregion Wave & Go/Retry
|
|
|
|
#region Pet
|
|
public static void SSetPet(int presetindex)
|
|
{
|
|
for(int i = 0; i < Instance.ivPets.Length; i++)
|
|
{
|
|
int key = DataHandler.PlayData.petPresets[presetindex][i];
|
|
Instance.ivPets[i].SetPet(key);
|
|
}
|
|
}
|
|
|
|
public static void SSetPetFront(bool bfriendly, bool bfrontright)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
for(int i = 0; i < Instance.ivPets.Length; i++)
|
|
{
|
|
Instance.ivPets[i].SetFront(bfrontright);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(int i = 0; i < Instance.ivPetsEnemy.Length; i++)
|
|
{
|
|
Instance.ivPetsEnemy[i].SetFront(bfrontright);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void SChangePetFront(bool bfriendly, bool bfrontright)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
for (int i = 0; i < Instance.ivPets.Length; i++)
|
|
{
|
|
Instance.ivPets[i].ChangeFront(bfrontright);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < Instance.ivPetsEnemy.Length; i++)
|
|
{
|
|
Instance.ivPetsEnemy[i].ChangeFront(bfrontright);
|
|
}
|
|
}
|
|
}
|
|
#endregion Pet
|
|
|
|
#region Guardian
|
|
public static void SinitIVGuardian()
|
|
{
|
|
Instance.ivGuardian.Init();
|
|
}
|
|
|
|
public static void SSetGuardian()
|
|
{
|
|
if(DataHandler.GetPlayGuardian(1) != null)
|
|
{
|
|
int key = DataHandler.GetPlayGuardian(1).lv;
|
|
Instance.ivGuardian.SetGuardian(key);
|
|
}
|
|
}
|
|
|
|
public static void SSetGuardianFront(bool bfriendly, bool bfrontright)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
Instance.ivGuardian.SetFront(bfrontright);
|
|
}
|
|
else
|
|
{
|
|
Instance.ivGuardianEnemy.SetFront(bfrontright);
|
|
}
|
|
}
|
|
|
|
public static void SChangeGuardianFront(bool bfriendly, bool bfrontright)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
Instance.ivGuardian.ChangeFront(bfrontright);
|
|
}
|
|
else
|
|
{
|
|
Instance.ivGuardianEnemy.ChangeFront(bfrontright);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Costume
|
|
public static void SSetCharCostume()
|
|
{
|
|
if (Instance != null)
|
|
Instance.SetCharCostume();
|
|
}
|
|
|
|
public void TestCosLog()
|
|
{
|
|
string strbattle = FormatString.CombineAllString(iCosCloth.ToString(), "/", (tx2dCloth == null ? "null" : tx2dCloth.name));
|
|
string straddressable = AddressableMgr.GetCosInfo(iCosCloth);
|
|
string strchar = ivChar.GetCosInfo();
|
|
GameUIMgr.SOpenPopup1Button(FormatString.CombineAllString(strbattle, FormatString.S_BreakLine, straddressable, FormatString.S_BreakLine, strchar));
|
|
}
|
|
|
|
// 코스튬 세팅.
|
|
private void SetCharCostume()
|
|
{
|
|
int iwp = DataHandler.PlayEquipCostume.weaponId;
|
|
if (iwp != iCosWp)
|
|
{
|
|
I_InitCos++;
|
|
int iwpprev = iCosWp;
|
|
iCosWp = iwp;
|
|
AddressableMgr.LoadWeaponSpine(iCosWp, ALoadWeaponComp);
|
|
AddressableMgr.LoadWeaponAdd(iCosWp);
|
|
// 전투 화면 내 캐릭터는 2번씩 호출.
|
|
AddressableMgr.ReleaseWeaponSpine(iwpprev);
|
|
AddressableMgr.ReleaseWeaponSpine(iwpprev);
|
|
|
|
}
|
|
|
|
int icloth = DataHandler.PlayEquipCostume.outfitId;
|
|
if (icloth != iCosCloth)
|
|
{
|
|
I_InitCos++;
|
|
int iclothprev = iCosCloth;
|
|
iCosCloth = icloth;
|
|
AddressableMgr.LoadClothSpine(iCosCloth, ALoadClothComp);
|
|
AddressableMgr.LoadClothAdd(iCosCloth);
|
|
// 전투 화면 내 캐릭터는 2번씩 호출.
|
|
AddressableMgr.ReleaseClothSpine(iclothprev);
|
|
AddressableMgr.ReleaseClothSpine(iclothprev);
|
|
|
|
SRefreshCharCloth();
|
|
}
|
|
}
|
|
|
|
public static void SRefreshCharCloth()
|
|
{
|
|
Instance.RefreshCharCloth();
|
|
}
|
|
|
|
// 의상만 다시 세팅.
|
|
private void RefreshCharCloth()
|
|
{
|
|
if (tx2dCloth == null)
|
|
{
|
|
I_InitCos++;
|
|
AddressableMgr.LoadClothSpineSoon(iCosCloth, ALoadClothComp);
|
|
}
|
|
else
|
|
{
|
|
ivChar.SetCostume(tx2dCloth);
|
|
}
|
|
}
|
|
|
|
public static void SSetEnemyCostume(int iwp, int icloth, int ihair, int itop, int ieye)
|
|
{
|
|
if (Instance != null)
|
|
Instance.SetEnemyCostume(iwp, icloth, ihair, itop, ieye);
|
|
}
|
|
|
|
// 적 캐릭터 코스튬 세팅.
|
|
private void SetEnemyCostume(int iwp, int icloth, int ihair, int itop, int ieye)
|
|
{
|
|
iCosHairEnemy = ihair;
|
|
iCosTopEnemy = itop;
|
|
iCosEyeEnemy = ieye;
|
|
|
|
if (iwp != iCosWpEnemy)
|
|
{
|
|
I_InitCos++;
|
|
int iwpprev = iCosWpEnemy;
|
|
iCosWpEnemy = iwp;
|
|
AddressableMgr.LoadWeaponSpine(iCosWpEnemy, ALoadWeaponEnemyComp);
|
|
AddressableMgr.ReleaseWeaponSpine(iwpprev);
|
|
}
|
|
|
|
if (icloth != iCosClothEnemy)
|
|
{
|
|
I_InitCos++;
|
|
int iclothprev = iCosClothEnemy;
|
|
iCosClothEnemy = icloth;
|
|
AddressableMgr.LoadClothSpine(iCosClothEnemy, ALoadClothEnemyComp);
|
|
AddressableMgr.ReleaseClothSpine(iclothprev);
|
|
}
|
|
}
|
|
|
|
private void ResetEnemyCostume()
|
|
{
|
|
AddressableMgr.ReleaseWeaponSpine(iCosWpEnemy);
|
|
AddressableMgr.ReleaseClothSpine(iCosClothEnemy);
|
|
iCosHairEnemy = -1;
|
|
iCosTopEnemy = -1;
|
|
iCosEyeEnemy = -1;
|
|
iCosWpEnemy = -1;
|
|
iCosClothEnemy = -1;
|
|
}
|
|
|
|
private void ALoadClothComp(Texture2D obj)
|
|
{
|
|
if (obj != null)
|
|
{
|
|
tx2dCloth = obj;
|
|
ivChar.SetCostume(tx2dCloth);
|
|
}
|
|
I_InitCos--;
|
|
}
|
|
|
|
private void ALoadWeaponComp(Skin obj)
|
|
{
|
|
ivChar.SetWeapon(obj);
|
|
if (tx2dCloth != null)
|
|
ivChar.SetCostume(tx2dCloth);
|
|
|
|
I_InitCos--;
|
|
}
|
|
|
|
private void ALoadClothEnemyComp(Texture2D obj)
|
|
{
|
|
tx2dClothEnemy = obj;
|
|
ivCharEnemy.SetCostume(tx2dClothEnemy);
|
|
I_InitCos--;
|
|
}
|
|
|
|
private void ALoadWeaponEnemyComp(Skin obj)
|
|
{
|
|
ivCharEnemy.SetWeapon(obj);
|
|
if (tx2dClothEnemy != null)
|
|
ivCharEnemy.SetCostume(tx2dClothEnemy);
|
|
|
|
I_InitCos--;
|
|
}
|
|
#endregion Costume
|
|
|
|
#region Skill
|
|
// 모든 스킬 정지.
|
|
private void StopAllSkill()
|
|
{
|
|
foreach (var item in dicIvSkill.Values)
|
|
{
|
|
item.StopSkill();
|
|
}
|
|
|
|
foreach (var item in dicIvSkillEnemy.Values)
|
|
{
|
|
item.StopSkill();
|
|
}
|
|
}
|
|
|
|
public void UseButtonSkill(int key)
|
|
{
|
|
if (iSkillIds[key] == -1)
|
|
return;
|
|
|
|
|
|
ivChar.AddSkillAvail(iSkillIds[key]);
|
|
iUseSkillid = iSkillIds[key];
|
|
SoundMgr.PlaySfx(SoundName.BtnPress);
|
|
}
|
|
|
|
public static int GetUseSkillid()
|
|
{
|
|
return Instance.iUseSkillid;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 스킬 사용.
|
|
/// </summary>
|
|
/// <param name="biatk">시전자의 공격력</param>
|
|
public int UseSkill(bool bfriendly, int key, Transform trfuse, int itarget, Transform trftarget, float icrtdam, int icrtrate, BigInteger biatk)
|
|
{
|
|
// 전투중이 아님.
|
|
if (BattlePause) return 0;
|
|
|
|
int index = GetSkillPresetIndex(bfriendly, key);
|
|
|
|
// 내가 사용한 스킬.
|
|
if (bfriendly)
|
|
{
|
|
// 사용할 수 없는 스킬.
|
|
if (index < 0 || index >= iSkillIds.Length || iSkillIds[index] < 0 || fSkillTicks[index] > 0f || !dicIvSkill.ContainsKey(key))
|
|
return -1;
|
|
|
|
IVSkill ivskill = dicIvSkill[key];
|
|
dSkillActive skilldata = DataHandler.GetSkillActive(key);
|
|
|
|
// NOTE : 플레이어 스킬 데미지 계산.
|
|
float fskilldmg = skilldata.atkValue + (skilldata.atkValueInc * (skilldata.level - 1));
|
|
fskilldmg *= BuffMgr.Instance.GetSkillDamage() / dConst.RateMaxFloat;
|
|
BigInteger biskilldmg = biatk.Multiply(fskilldmg);
|
|
|
|
if (skilldata.debuffType != eSkillDebuff.None)
|
|
{
|
|
BigInteger bidebuff = skilldata.debuffValue + (skilldata.debuffValueInc * (skilldata.level - 1));
|
|
if (skilldata.debuffType == eSkillDebuff.DamageSec)
|
|
bidebuff = biatk * bidebuff / dConst.RateMaxBi;
|
|
ivskill.SetDebuff(bidebuff, skilldata.debuffTime);
|
|
}
|
|
|
|
ivskill.StartSkill(bfriendly, icrtdam, icrtrate, biskilldmg / dConst.RateMax, trfuse, trftarget, itarget, ivChar.IsLookRight);
|
|
|
|
fSkillTicks[index] = fSkillTimes[index];
|
|
SetSkillUi(index);
|
|
|
|
if (Random.Range(0, 5) == 0)
|
|
{
|
|
iTalkChar = 2; // 스킬.
|
|
ShowTalkBox();
|
|
}
|
|
}
|
|
// 적이 사용한 스킬.
|
|
else
|
|
{
|
|
// 사용할 수 없는 스킬.
|
|
if (index < 0 || specEnemy.skillPreset[index] < 0 || fSkillEnemyTicks[index] > 0f || !dicIvSkillEnemy.ContainsKey(key))
|
|
return -1;
|
|
|
|
IVSkill ivskill = dicIvSkillEnemy[key];
|
|
dSkillActive skilldata = DataHandler.GetSkillActive(key);
|
|
|
|
// NOTE: 적 스킬 데미지 계산.
|
|
float fskilldmg = skilldata.atkValue + (skilldata.atkValueInc * (specEnemy.skillLv[index] - 1));
|
|
fskilldmg *= specEnemy.skillDamage / dConst.RateMaxFloat;
|
|
BigInteger biskilldmg = biatk.Multiply(fskilldmg);
|
|
|
|
if (skilldata.debuffType != eSkillDebuff.None)
|
|
{
|
|
BigInteger bidebuff = skilldata.debuffValue + (skilldata.debuffValueInc * (specEnemy.skillLv[index] - 1));
|
|
if (skilldata.debuffType == eSkillDebuff.DamageSec)
|
|
bidebuff = biatk * bidebuff / dConst.RateMaxBi;
|
|
ivskill.SetDebuff(bidebuff, skilldata.debuffTime);
|
|
}
|
|
|
|
ivskill.StartSkill(bfriendly, icrtdam, icrtrate, biskilldmg / dConst.RateMax, trfuse, trftarget, itarget, ivCharEnemy.IsLookRight);
|
|
|
|
fSkillEnemyTicks[index] = specEnemy.skillCool[index];
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
public float GetSkillRange(int id)
|
|
{
|
|
float result = 0;
|
|
if (dicIvSkill.TryGetValue(id, out IVSkill targetSkill))
|
|
{
|
|
result = targetSkill.GetRange();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// 특정 스킬 UI 세팅.
|
|
private void SetSkillUi(int index)
|
|
{
|
|
if (fSkillTicks[index] > 0f)
|
|
{
|
|
if (!imgSkillCovers[index].gameObject.activeSelf)
|
|
{
|
|
btnSkills[index].interactable = false;
|
|
imgSkillCovers[index].gameObject.SetActive(true);
|
|
}
|
|
imgSkillCovers[index].fillAmount = fSkillTicks[index] / fSkillTimes[index];
|
|
txtSkills[index].text = Mathf.CeilToInt(fSkillTicks[index]).ToString();
|
|
}
|
|
else
|
|
{
|
|
if (imgSkillCovers[index].gameObject.activeSelf)
|
|
{
|
|
btnSkills[index].interactable = !bAutoSkill;
|
|
imgSkillCovers[index].gameObject.SetActive(false);
|
|
txtSkills[index].text = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 스킬 프리셋 변경.
|
|
public void ChangeSkillPreset(int index)
|
|
{
|
|
if (CurrentBattleType == BattleType.Stage)
|
|
{
|
|
if (iLoading > 0)
|
|
return;
|
|
iLoading++;
|
|
ivChar.ClearSkillAvail();
|
|
if (index >= DataHandler.PlayData.skillPresets.Length)
|
|
index = 0;
|
|
DataHandler.ChangeSkillPreset(index);
|
|
DataHandler.PlayData.Save();
|
|
SetSkillPreset();
|
|
iLoading--;
|
|
}
|
|
|
|
SoundMgr.PlaySfx(SoundName.BtnPress);
|
|
}
|
|
|
|
// 스킬 프리셋 내용 변경 시 호출.
|
|
public static void SResetSkillPreset()
|
|
{
|
|
if (Instance is null) return;
|
|
|
|
Instance.ivChar.ClearSkillAvail();
|
|
Instance.SetSkillPreset();
|
|
}
|
|
|
|
// 스킬 프리셋 세팅.
|
|
private void SetSkillPreset()
|
|
{
|
|
//현재 선택한 프리셋 버튼만 비활성화
|
|
for (int i = 0; i < btnSkillPresets.Length; i++)
|
|
btnSkillPresets[i].interactable = DataHandler.PlayData.usePreset != i;
|
|
|
|
dicSkillIndex.Clear();
|
|
for (int i = 0; i < btnSkills.Length; i++)
|
|
{
|
|
int key = DataHandler.PlayData.skillPresets[DataHandler.PlayData.usePreset][i];
|
|
|
|
// 빈 스킬 슬롯.
|
|
if (key < 0)
|
|
{
|
|
iSkillIds[i] = -1;
|
|
fSkillTimes[i] = 1f;
|
|
fSkillTicks[i] = 0f;
|
|
|
|
goSkillEmptys[i].SetActive(true);
|
|
imgSkills[i].gameObject.SetActive(false);
|
|
imgSkillBg[i].gameObject.SetActive(false);
|
|
imgSkillCovers[i].gameObject.SetActive(false);
|
|
txtSkills[i].text = null;
|
|
}
|
|
// 스킬 있는 슬롯.
|
|
else
|
|
{
|
|
if (!dicSkillIndex.ContainsKey(key))
|
|
dicSkillIndex.Add(key, i);
|
|
iSkillIds[i] = key;
|
|
fSkillTimes[i] = DataHandler.GetSkillCool(key);
|
|
fSkillTicks[i] = fSkillTimes[i];
|
|
|
|
goSkillEmptys[i].SetActive(false);
|
|
imgSkills[i].gameObject.SetActive(true);
|
|
imgSkillBg[i].gameObject.SetActive(true);
|
|
imgSkillCovers[i].gameObject.SetActive(true);
|
|
imgSkills[i].sprite = AddressableMgr.GetSkillActiveIconS(key);
|
|
imgSkillBg[i].sprite = AddressableMgr.GetGradeIcon(DataHandler.GetSkillRarity(cGoods.TSkillActive, key) + 200);
|
|
}
|
|
btnSkills[i].interactable = false;
|
|
|
|
SetSkillUi(i);
|
|
}
|
|
}
|
|
|
|
// 적 캐릭터 스킬 프리셋 세팅.
|
|
private void SetSkillPresetEnemy()
|
|
{
|
|
dicSkillEnemyIndex.Clear();
|
|
for (int i = 0; i < specEnemy.skillPreset.Length; i++)
|
|
{
|
|
int key = specEnemy.skillPreset[i];
|
|
|
|
// 빈 스킬 슬롯.
|
|
if (key < 0)
|
|
{
|
|
fSkillEnemyTicks[i] = 0f;
|
|
}
|
|
// 스킬 있는 슬롯.
|
|
else
|
|
{
|
|
if (!dicSkillEnemyIndex.ContainsKey(key))
|
|
dicSkillEnemyIndex.Add(key, i);
|
|
fSkillEnemyTicks[i] = specEnemy.skillCool[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ResetSkillCooltime()
|
|
{
|
|
for(int i = 0; i < fSkillTicks.Length; i++)
|
|
{
|
|
fSkillTicks[i] = 0f;
|
|
SetSkillUi(i);
|
|
}
|
|
}
|
|
|
|
public void RecalcSkillCool(int skillKey)
|
|
{
|
|
if (dicSkillIndex.ContainsKey(skillKey))
|
|
{
|
|
int idx = dicSkillIndex[skillKey];
|
|
|
|
FValue coolTime = new FValue(DataHandler.GetSkillCool(skillKey));
|
|
foreach (var buff in GamePlayBuffMgr.Instance.BuffGroup.GetBuffs(eEffectType.PlayerSkillCoolFix))
|
|
{
|
|
coolTime.AddModifiers(buff.Value);
|
|
}
|
|
|
|
fSkillTimes[idx] = coolTime.ModifiedValue;
|
|
fSkillTicks[idx] = Mathf.Min(fSkillTicks[idx], fSkillTimes[idx]);
|
|
SetSkillUi(idx);
|
|
}
|
|
}
|
|
|
|
// 스킬 쿨타임 재계산.
|
|
public void RecalcAllSkillCool()
|
|
{
|
|
foreach (var skillKey in dicSkillIndex.Keys)
|
|
{
|
|
RecalcSkillCool(skillKey);
|
|
}
|
|
}
|
|
|
|
// 프리셋에서의 스킬 인덱스 가져오기.
|
|
private int GetSkillPresetIndex(bool bfriendly, int key)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
if (dicSkillIndex.ContainsKey(key))
|
|
return dicSkillIndex[key];
|
|
}
|
|
else
|
|
{
|
|
if (dicSkillEnemyIndex.ContainsKey(key))
|
|
return dicSkillEnemyIndex[key];
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// 스킬 사거리 가져오기.
|
|
public static int SGetSkillRange(int key)
|
|
{
|
|
if (Instance.dicIvSkill.ContainsKey(key))
|
|
return Instance.dicIvSkill[key].GetRange();
|
|
return 0;
|
|
}
|
|
|
|
// 스킬을 사용할 때 캐릭터 방향 가져오기
|
|
public bool GetIsFront(bool bfriendly) => bfriendly ? ivChar.IsLookRight : ivCharEnemy.IsLookRight;
|
|
|
|
public void OnOffAuto()
|
|
{
|
|
if (CurrentBattleType == BattleType.Pvp)
|
|
return;
|
|
bAutoSkill = !bAutoSkill;
|
|
if (bAutoSkill)
|
|
{
|
|
imgBtnAuto.sprite = sprAuto;
|
|
goAuto.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
imgBtnAuto.sprite = sprAutoOff;
|
|
goAuto.SetActive(false);
|
|
|
|
ivChar.ClearSkillAvail();
|
|
}
|
|
|
|
if (bAutoSkill)
|
|
{
|
|
for(int i = 0; i < iSkillIds.Length; i++)
|
|
{
|
|
ivChar.AddSkillAvail(iSkillIds[i]);
|
|
}
|
|
}
|
|
|
|
SoundMgr.PlaySfx(SoundName.BtnPress);
|
|
}
|
|
|
|
private void OnOffAutoTemp(bool bauto)
|
|
{
|
|
bAutoSkillPrev = bAutoSkill;
|
|
bAutoSkill = bauto;
|
|
if (bauto)
|
|
{
|
|
imgBtnAuto.sprite = sprAuto;
|
|
goAuto.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
imgBtnAuto.sprite = sprAutoOff;
|
|
goAuto.SetActive(false);
|
|
}
|
|
|
|
if (bauto)
|
|
{
|
|
for (int i = 0; i < iSkillIds.Length; i++)
|
|
{
|
|
ivChar.AddSkillAvail(iSkillIds[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ResetAuto()
|
|
{
|
|
if (bAutoSkill != bAutoSkillPrev)
|
|
OnOffAuto();
|
|
}
|
|
|
|
public static bool GetAuto()
|
|
{
|
|
return Instance.bAutoSkill;
|
|
}
|
|
|
|
public static void allDisableSummons(bool bfriendly)
|
|
{
|
|
if (bfriendly)
|
|
{
|
|
for (int i = 0; i < Instance.ivsummons.Length; i++)
|
|
Instance.ivsummons[i].ForceUnSummon();
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < Instance.ivsummonsEnemy.Length; i++)
|
|
Instance.ivsummonsEnemy[i].ForceUnSummon();
|
|
}
|
|
}
|
|
|
|
#endregion Skill
|
|
|
|
#region Bg & Light & Talk
|
|
// 전투화면 배경 세팅.
|
|
private void SetBg(int idx)
|
|
{
|
|
if (idx == iBgId)
|
|
return;
|
|
|
|
iBgId = idx;
|
|
dBg data = DataHandler.GetBg(idx);
|
|
lightGlobal.color = new Color(data.globalLight[0] / 255f, data.globalLight[1] / 255f, data.globalLight[2] / 255f, 1f);
|
|
lightChar.color = new Color(data.charLight[0] / 255f, data.charLight[1] / 255f, data.charLight[2] / 255f, 1f);
|
|
SetBgCol();
|
|
|
|
Addressables.LoadAssetAsync<Sprite>(FormatString.StringFormat(AddressableMgr.PathBg, data.path)).Completed += ALoadBgComp;
|
|
}
|
|
|
|
private void SetBgCol()
|
|
{
|
|
if (CurrentBattleType == BattleType.EnhanceStoneDungeon)
|
|
{
|
|
|
|
colBg.size = new Vector3(20.48f * 6f, 6.6f, 1f);
|
|
colBg.center = new Vector3(40, -0.5f, 0);
|
|
}
|
|
else
|
|
{
|
|
colBg.size = new Vector3(19f, 13f, 1f);
|
|
colBg.center = new Vector3(0, -1f, 0);
|
|
}
|
|
|
|
return;
|
|
}
|
|
public static BoxCollider SGetBgSize()
|
|
{
|
|
return Instance.colBg;
|
|
}
|
|
|
|
// 전투화면 배경 로드 완료.
|
|
private void ALoadBgComp(AsyncOperationHandle<Sprite> obj)
|
|
{
|
|
srBg.sprite = obj.Result;
|
|
|
|
if (handleBg.IsValid())
|
|
Addressables.Release(handleBg);
|
|
|
|
srBg.size = new Vector2(20.48f * 11, 20.48f);
|
|
handleBg = obj;
|
|
}
|
|
|
|
// 조명 조절.
|
|
private IEnumerator LightCharOff()
|
|
{
|
|
while (lightChar.intensity > 0f)
|
|
{
|
|
lightChar.intensity -= Time.deltaTime * 2f;
|
|
yield return null;
|
|
}
|
|
lightChar.intensity = 0f;
|
|
}
|
|
|
|
// 조명 조절.
|
|
private IEnumerator LightCharOn()
|
|
{
|
|
while (lightChar.intensity < 1f)
|
|
{
|
|
lightChar.intensity += Time.deltaTime * 2f;
|
|
yield return null;
|
|
}
|
|
lightChar.intensity = 1f;
|
|
}
|
|
|
|
// 말풍선 표시.
|
|
private void ShowTalkBox()
|
|
{
|
|
if (iTalkChar < 0 || iTalkChar >= iTalkMax)
|
|
{
|
|
iTalkChar = -1;
|
|
return;
|
|
}
|
|
|
|
talkBox.ShowTalkBox(LocalizationText.GetText(FormatString.StringFormat("talkbox{0}", FormatString.TextInt2(iTalkChar))), 2f);
|
|
iTalkChar = -1;
|
|
}
|
|
#endregion Bg & Light & Talk
|
|
|
|
#region Pvp
|
|
public static void SPreparePvp(dPvpSpec specmy, dPvpSpec specenemy)
|
|
{
|
|
Instance.PreparePvp(specmy, specenemy);
|
|
}
|
|
|
|
private void PreparePvp(dPvpSpec specmy, dPvpSpec specenemy)
|
|
{
|
|
seqStartStage.Pause();
|
|
seqDieStage.Pause();
|
|
seqChangeStage.Pause();
|
|
seqChangeArea.Pause();
|
|
|
|
// 배틀 멈춤, 카메라 멈춤.
|
|
BattlePause = true;
|
|
IVCameraController.SSetTrace(false);
|
|
StopAllSkill();
|
|
UnsummonMon();
|
|
NoReward();
|
|
CurrentBattleType = BattleType.Pvp;
|
|
|
|
OnOffAutoTemp(true);
|
|
|
|
specEnemy = specenemy;
|
|
SetSkillPresetEnemy();
|
|
SetSkillPreset();
|
|
for (int i = 0; i < fSkillTicks.Length; i++)
|
|
{
|
|
fSkillTicks[i] = 0f;
|
|
fSkillEnemyTicks[i] = 0f;
|
|
}
|
|
|
|
sldPvpMyHp.value = 1f;
|
|
sldPvpEnemyHp.value = 1f;
|
|
iStageTimeLeft = DataHandler.sysPvp.timeout;
|
|
txtPvpTime.text = iStageTimeLeft.ToString();
|
|
|
|
SetBg(DataHandler.sysPvp.bgId);
|
|
IVCameraController.SMoveCamera(Vector3.zero);
|
|
|
|
///// PVP 펫은 나중에...
|
|
//ivPet.SetPet(specmy.petMain);
|
|
//ivPetEnemy.SetPet(specenemy.petMain);
|
|
//ivPet.Summon();
|
|
//ivPetEnemy.Summon();
|
|
|
|
ivChar.Summon(V3_CharPvp, true);
|
|
ivCharEnemy.Summon(V3_CharEnemyPvp, false);
|
|
ivChar.SetStatus(specmy.charAtk, specmy.charHp, specmy.criticalPower, specmy.criticalRate, specmy.move, specmy.speed, F_CharRangePvp);
|
|
ivCharEnemy.SetStatus(specenemy.charAtk, specenemy.charHp, specenemy.criticalPower, specenemy.criticalRate, specenemy.move, specenemy.speed, F_CharRangePvp);
|
|
|
|
imgBattleCover.color = Color.black;
|
|
imgBattleCover.gameObject.SetActive(true);
|
|
imgBattleCover.DOFade(0f, 1f);
|
|
SkillFade(false, true);
|
|
}
|
|
|
|
public static void SStartPvp()
|
|
{
|
|
Instance.StartPvp();
|
|
}
|
|
|
|
private void StartPvp()
|
|
{
|
|
biBattleDmg = 0L;
|
|
biBattleDmgEnemy = 0L;
|
|
|
|
ivChar.gameObject.SetActive(true);
|
|
ivCharEnemy.gameObject.SetActive(true);
|
|
|
|
imgBattleCover.gameObject.SetActive(false);
|
|
BattlePause = false;
|
|
}
|
|
|
|
private void EndPvp()
|
|
{
|
|
// 배틀 멈춤, 카메라 멈춤.
|
|
BattlePause = true;
|
|
IVCameraController.SSetTrace(false);
|
|
imgBattleCover.gameObject.SetActive(true);
|
|
|
|
CoverCamera.Hold();
|
|
// 결투장 나가기 팝업 닫기.
|
|
GameUIMgr.SClosePopup2Button(cGoods.TPvpTicket);
|
|
|
|
Invoke("EndPvp2", 1f);
|
|
SkillFade(false, true);
|
|
//ResetFade();
|
|
}
|
|
|
|
private void EndPvp2()
|
|
{
|
|
imgBattleCover.DOFade(1f, 0.3f);
|
|
Invoke("EndPvp3", 0.3f);
|
|
|
|
int imyhprate = Mathf.RoundToInt(sldPvpMyHp.value * 100f);
|
|
int ienemyhprate = Mathf.RoundToInt(sldPvpEnemyHp.value * 100f);
|
|
int iresult = imyhprate >= ienemyhprate ? 1 : 2;
|
|
PvpMgr.SResultPvp(iresult, imyhprate, ienemyhprate, biBattleDmg, biBattleDmgEnemy);
|
|
}
|
|
|
|
private void EndPvp3()
|
|
{
|
|
StopAllSkill();
|
|
UnsummonMon();
|
|
for(int i = 0; i < ivPets.Length; i++)
|
|
{
|
|
ivPets[i].OffPet();
|
|
}
|
|
CoverCamera.Release();
|
|
}
|
|
|
|
public static void SExitPvp()
|
|
{
|
|
Instance.ExitPvp();
|
|
}
|
|
|
|
// 결투장 종료시. 스테이지로 돌아가기.
|
|
private void ExitPvp()
|
|
{
|
|
// 배틀 멈춤, 카메라 멈춤.
|
|
BattlePause = true;
|
|
IVCameraController.SSetTrace(false);
|
|
StopAllSkill();
|
|
UnsummonMon();
|
|
|
|
imgBattleCover.gameObject.SetActive(true);
|
|
imgBattleCover.color = Color.black;
|
|
|
|
//ivPetEnemy.SetPet(-1);
|
|
//ivPet.OffPet();
|
|
//ivPetEnemy.OffPet();
|
|
|
|
ResetEnemyCostume();
|
|
ivChar.gameObject.SetActive(false);
|
|
ivCharEnemy.gameObject.SetActive(false);
|
|
|
|
specEnemy = null;
|
|
|
|
CurrentBattleType = BattleType.Stage;
|
|
GameUIMgr.SSetActiveHotTime(true);
|
|
ResetAuto();
|
|
Instance.seqStartStage.Restart();
|
|
}
|
|
|
|
// 결투장 데미지.
|
|
public void AddPvpDamage(bool bfirendly, BigInteger bidmg, float flefthp)
|
|
{
|
|
if (CurrentBattleType != BattleType.Pvp)
|
|
return;
|
|
|
|
// 아군이 데미지를 받았을 때.
|
|
if (bfirendly)
|
|
{
|
|
biBattleDmgEnemy += bidmg;
|
|
sldPvpMyHp.value = flefthp;
|
|
}
|
|
// 적이 데미지를 받았을 때.
|
|
else
|
|
{
|
|
biBattleDmg += bidmg;
|
|
sldPvpEnemyHp.value = flefthp;
|
|
}
|
|
}
|
|
#endregion Pvp
|
|
|
|
#region Test
|
|
public static void SSetTotalDamage(BigInteger dam, int id)
|
|
{
|
|
if (SettingMgr.SGetTest())
|
|
{
|
|
Instance.TestDps[id - 1] += dam;
|
|
activeDps();
|
|
if (Instance.timeSec != 0)
|
|
Instance.txtTestDpsDam[id - 1].text = FormatString.BigIntString1(Instance.TestDps[id - 1] / (BigInteger)Instance.timeSec);
|
|
}
|
|
}
|
|
|
|
public static void SSetNormalDamage(BigInteger dam)
|
|
{
|
|
if (SettingMgr.SGetTest())
|
|
{
|
|
Instance.txtNormalAttackDpsDam.transform.parent.gameObject.SetActive(true);
|
|
Instance.TestNormalAttackDps += dam;
|
|
if (Instance.timeSec != 0)
|
|
Instance.txtNormalAttackDpsDam.text = FormatString.BigIntString1(Instance.TestNormalAttackDps / (BigInteger)Instance.timeSec);
|
|
}
|
|
else
|
|
Instance.txtNormalAttackDpsDam.transform.parent.gameObject.SetActive(false);
|
|
|
|
}
|
|
|
|
public static void MoveToDir(Vector2 moveVec)
|
|
{
|
|
if (!doNotInterupt)
|
|
{
|
|
Instance.ivChar.MoveToDir(moveVec);
|
|
}
|
|
}
|
|
|
|
public static void UpdateDpsOneSec()
|
|
{
|
|
Instance.timeSec++;
|
|
}
|
|
|
|
public static void ResetDps()
|
|
{
|
|
Instance.timeSec = 0;
|
|
for(int i = 0; i< Instance.TestDps.Length; i++)
|
|
{
|
|
Instance.TestDps[i] = 0L;
|
|
}
|
|
Instance.TestNormalAttackDps = 0L;
|
|
}
|
|
|
|
public static void SetDpsSkill()
|
|
{
|
|
ResetDps();
|
|
for (int i = 0; i < Instance.TestDps.Length; i++)
|
|
{
|
|
Instance.txtTestDps[i].text = LocalizationText.GetText(FormatString.CombineAll("active", (i + 1)));
|
|
Instance.txtTestDps[i].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
public static void activeDps()
|
|
{
|
|
for (int i = 0; i < Instance.TestDps.Length; i++)
|
|
{
|
|
if (Instance.TestDps[i] == 0L)
|
|
Instance.txtTestDps[i].gameObject.SetActive(false);
|
|
else
|
|
Instance.txtTestDps[i].gameObject.SetActive(true);
|
|
}
|
|
}
|
|
|
|
public static void SetBattleTypeDungeon(int num)
|
|
{
|
|
GameUIMgr.SSetActiveHotTime(false);
|
|
switch (num)
|
|
{
|
|
case 0:
|
|
CurrentBattleType = BattleType.GoldDungeon;
|
|
break;
|
|
case 1:
|
|
CurrentBattleType = BattleType.EnhanceStoneDungeon;
|
|
break;
|
|
case 2:
|
|
CurrentBattleType = BattleType.PetDungeon;
|
|
break;
|
|
case 3:
|
|
CurrentBattleType = BattleType.AwakenStoneDungeon;
|
|
break;
|
|
case 4:
|
|
CurrentBattleType = BattleType.AwakenDungeon;
|
|
break;
|
|
case 5:
|
|
CurrentBattleType = BattleType.GuardianDungeon;
|
|
break;
|
|
case 6:
|
|
CurrentBattleType = BattleType.RelicDungeon;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static void DungeonStart(int dungeonLevel)
|
|
{
|
|
Instance.BattlePause = true;
|
|
Instance.InitDungeonStage(dungeonLevel);
|
|
DungeonMgr.OnOffBtnDungeonOut(false);
|
|
|
|
Instance.seqChangeArea.Pause();
|
|
Instance.seqChangeStage.Pause();
|
|
Instance.seqDungeonArea.Restart();
|
|
}
|
|
|
|
public static void ChangeBattleTypeNormal()
|
|
{
|
|
MissionMgr.SRefreshMission();
|
|
GameUIMgr.SSetActiveHotTime(true);
|
|
CurrentBattleType = BattleType.Stage;
|
|
}
|
|
#endregion Test
|
|
|
|
#region Succ & Fail
|
|
public static void OpenFailScroll()
|
|
{
|
|
Instance.canvasStageFail.enabled = true;
|
|
Addressables.LoadAssetAsync<SkeletonDataAsset>("effect/game_off/game_off_SkeletonData.asset").Completed += Instance.ALoadExitComp;
|
|
}
|
|
|
|
private AsyncOperationHandle<SkeletonDataAsset> handleSkAnim;
|
|
|
|
public static void CloseFailScroll()
|
|
{
|
|
SkeletonAnimation skanim = Instance.canvasStageFail.transform.Find("skanim").GetComponent<SkeletonAnimation>();
|
|
// 애니메이션 언로드.
|
|
if (skanim.skeletonDataAsset != null)
|
|
{
|
|
CoverCamera.Hold();
|
|
skanim.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
|
|
skanim.skeletonDataAsset.Clear();
|
|
skanim.ClearState();
|
|
skanim.skeletonDataAsset = null;
|
|
if (Instance.handleSkAnim.IsValid())
|
|
Addressables.Release(Instance.handleSkAnim);
|
|
AddressableMgr.SAddUnload();
|
|
CoverCamera.Release();
|
|
}
|
|
|
|
Instance.canvasStageFail.enabled = false;
|
|
}
|
|
|
|
private void ALoadExitComp(AsyncOperationHandle<SkeletonDataAsset> obj)
|
|
{
|
|
SkeletonAnimation skanim = canvasStageFail.transform.Find("skanim").GetComponent<SkeletonAnimation>();
|
|
MeshRenderer renderer = skanim.GetComponent<MeshRenderer>();
|
|
renderer.sortingLayerID = canvasStageFail.sortingLayerID;
|
|
renderer.sortingOrder = 16;
|
|
skanim.skeletonDataAsset = obj.Result;
|
|
skanim.Initialize(true);
|
|
skanim.AnimationState.SetAnimation(0, "idle", true);
|
|
skanim.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
|
|
|
|
handleSkAnim = obj;
|
|
CoverCamera.Release();
|
|
}
|
|
|
|
public static void CloseSuccessWindow()
|
|
{
|
|
Instance.stageSuccessWindow.SetActive(false);
|
|
Instance.awakenSuccessWindow.SetActive(false);
|
|
}
|
|
#endregion Succ & Fail
|
|
|
|
#region Dungeon Reward
|
|
private void SetDungeonSetting(bool start)
|
|
{
|
|
if (start)
|
|
{
|
|
switch (CurrentBattleType)
|
|
{
|
|
case BattleType.GoldDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GoldDG).timeOut;
|
|
iTotalWave = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GoldDG).wave;
|
|
break;
|
|
case BattleType.EnhanceStoneDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.EnhanceStoneDG).timeOut;
|
|
iTotalWave = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.EnhanceStoneDG).wave;
|
|
break;
|
|
case BattleType.PetDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.PetDG).timeOut;
|
|
iTotalWave = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.PetDG).wave;
|
|
break;
|
|
case BattleType.AwakenStoneDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenStoneDG).timeOut;
|
|
iTotalWave = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenStoneDG).wave;
|
|
break;
|
|
case BattleType.AwakenDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenDG).timeOut;
|
|
iTotalWave = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenDG).wave;
|
|
break;
|
|
case BattleType.GuardianDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GuardianDG).timeOut;
|
|
iTotalWave = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GuardianDG).wave;
|
|
break;
|
|
case BattleType.RelicDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.relicDG).timeOut;
|
|
iTotalWave = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.relicDG).wave;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (CurrentBattleType)
|
|
{
|
|
case BattleType.GoldDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GoldDG).timeOut;
|
|
break;
|
|
case BattleType.EnhanceStoneDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.EnhanceStoneDG).timeOut;
|
|
break;
|
|
case BattleType.PetDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.PetDG).timeOut;
|
|
break;
|
|
case BattleType.AwakenStoneDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenStoneDG).timeOut;
|
|
break;
|
|
case BattleType.AwakenDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.AwakenDG).timeOut;
|
|
break;
|
|
case BattleType.GuardianDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.GuardianDG).timeOut;
|
|
break;
|
|
case BattleType.RelicDungeon:
|
|
iStageTimeLeft = DataHandler.GetDungeonTypeInfo(DungeonMgr.DungeonKind.relicDG).timeOut;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void SettingDungeonClearReward(nReward[] data)
|
|
{
|
|
for (int i = 0; i < Instance.stageSuccessGoodsItem.Length; i++)
|
|
{
|
|
Instance.stageSuccessGoodsItem[i].gameObject.SetActive(false);
|
|
}
|
|
|
|
for (int i = 0; i < data.Length; i++)
|
|
{
|
|
Instance.stageSuccessGoodsItem[i].gameObject.SetActive(true);
|
|
|
|
Instance.stageSuccessGoodsItem[i].SetGoods(data[i].rewardType, data[i].rewardId, data[i].rewardCount);
|
|
|
|
if (data[i].rewardCount <= 0)
|
|
{
|
|
Instance.stageSuccessGoodsItem[i].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void GetClearDungeonReward(nReward[] data)
|
|
{
|
|
nGoods[] plusGoods = new nGoods[data.Length];
|
|
|
|
for (int i = 0; i < plusGoods.Length; i++)
|
|
{
|
|
plusGoods[i] = new nGoods();
|
|
plusGoods[i].propertyId = data[i].rewardId;
|
|
plusGoods[i].propertyType = data[i].rewardType;
|
|
plusGoods[i].propertyCount = data[i].rewardCount;
|
|
}
|
|
DataHandler.AddGoods(plusGoods, DataHandler.Goods, true);
|
|
|
|
Instance.stageSuccessWindow.SetActive(true);
|
|
|
|
SoundMgr.PlaySfx(SoundName.GetGoods);
|
|
}
|
|
|
|
public static void GetClearDungeonSkipReward(nReward[] data, int skipCount, float bonus = 1)
|
|
{
|
|
nGoods[] plusGoods = new nGoods[data.Length];
|
|
|
|
for (int i = 0; i < plusGoods.Length; i++)
|
|
{
|
|
plusGoods[i] = new nGoods();
|
|
plusGoods[i].propertyId = data[i].rewardId;
|
|
plusGoods[i].propertyType = data[i].rewardType;
|
|
plusGoods[i].propertyCount = data[i].rewardCount * (int)((bonus+1.0f) * dConst.RateMaxFloat) / dConst.RateMaxBi * skipCount;
|
|
}
|
|
|
|
DataHandler.AddGoods(plusGoods, DataHandler.Goods, true);
|
|
}
|
|
|
|
public static void AwakenSuccessWindowEnable()
|
|
{
|
|
Instance.awakenSuccessWindow.SetActive(true);
|
|
}
|
|
|
|
public static void SetAwakenRewardNumber(int i)
|
|
{
|
|
Instance.awakenNumber.text = i.ToString();
|
|
}
|
|
|
|
public void ResetBgScroll()
|
|
{
|
|
srBg.transform.position = new Vector3(0, 0, 0);
|
|
}
|
|
#endregion
|
|
}
|