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.
5726 lines
196 KiB
5726 lines
196 KiB
using IVDataFormat;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using Random = UnityEngine.Random;
|
|
|
|
public static class DataHandler
|
|
{
|
|
#region System data
|
|
public static dConst Const { get; private set; } = null;
|
|
|
|
private static dAttend[] sysAttend;
|
|
|
|
public static Dictionary<int, dAwakenReward> SysAwakenRewards = new Dictionary<int, dAwakenReward>();
|
|
|
|
public static Dictionary<int, dBox> SysBoxes = new Dictionary<int, dBox>();
|
|
|
|
private static Dictionary<int, dBg> dicBg = new Dictionary<int, dBg>();
|
|
|
|
private static Dictionary<BGM, dBgm> dicBgm = new Dictionary<BGM, dBgm>()
|
|
{
|
|
{ BGM.intro, new dBgm(BGM.intro, "intro") },
|
|
{ BGM.stage, new dBgm(BGM.stage, "stage") },
|
|
{ BGM.pvp, new dBgm(BGM.pvp, "pvp") },
|
|
};
|
|
|
|
private static dAdBuff[] sysBuff;
|
|
|
|
private static Dictionary<int, dCostumeSet> dicCosClothSet = new Dictionary<int, dCostumeSet>();
|
|
private static Dictionary<int, dCostumeSet> dicCosWeaponSet = new Dictionary<int, dCostumeSet>();
|
|
|
|
public static dAwaken[] sysSkillAwakens = null;
|
|
public static dTotalLvValue[] sysSkillLvEffects = null;
|
|
|
|
public static dAwaken[] sysGearAwakens = null;
|
|
public static dTotalLvValue[] sysGearLvEffects = null;
|
|
|
|
public static dAwaken[] sysPetAwakens = null;
|
|
public static dTotalLvValue[] sysPetLvEffects = null;
|
|
|
|
private static int[] gearTreasureLvUpLvBounds = null;
|
|
private static int[] gearTreasureLvUpSuccRates = null;
|
|
|
|
private static Dictionary<int, dSysGuardian> sysGuardian = new Dictionary<int, dSysGuardian>();
|
|
|
|
public static Dictionary<int, List<dSysRelic>> sysRelicsGroupedByType = new Dictionary<int, List<dSysRelic>>();
|
|
private static int[] sysRelicEnhancePropLvs = null;
|
|
private static int[] sysRelicEnhanceProp = null;
|
|
|
|
private static Dictionary<int, dMonster> dicMonster = new Dictionary<int, dMonster>();
|
|
|
|
public static dArea[] sysAreas = null;
|
|
|
|
public static dPvp sysPvp = null;
|
|
private static dPvpRank[] pvpRanks = null;
|
|
public static dPvpRank pvpMyRank = null;
|
|
|
|
private static int[] extraRarityRates;
|
|
private static Dictionary<int, dExtraAbility> extraAbilities;
|
|
private static Dictionary<eEffectType, int>[] extraAbilityIds;
|
|
|
|
private static Dictionary<int, dQuest> sysQuestDaily = new Dictionary<int, dQuest>();
|
|
private static Dictionary<int, dQuest> sysQuestRepeat = new Dictionary<int, dQuest>();
|
|
private static Dictionary<int, dMission> sysQuestMission = new Dictionary<int, dMission>();
|
|
|
|
private static dGachaLevel[] gachaWeaponLvs;
|
|
private static int[] gachaWeaponGrades;
|
|
private static dGachaLevel[] gachaArmorLvs;
|
|
private static int[] gachaArmorGrades;
|
|
private static dGachaLevel[] gachaAcceLvs;
|
|
private static int[] gachaAcceGrades;
|
|
|
|
private static Dictionary<int, dEvent> dicEvent = new Dictionary<int, dEvent>();
|
|
private static dEventInfo sysEventRoulette;
|
|
private static dEventInfo sysEventTrade;
|
|
private static dEventInfo sysEventRaise;
|
|
private static dRewardEvent sysRewardEvent;
|
|
private static Dictionary<int, dQuest> sysQuestEvent = new Dictionary<int, dQuest>();
|
|
|
|
private static dNotice[] sysNotices;
|
|
private static dChatNotice[] sysChatNotices;
|
|
#endregion System data
|
|
|
|
#region Play data
|
|
public static cPlayData PlayData { get; private set; } = null;
|
|
|
|
private static cTotalRecord PlayerTotalRecord = null;
|
|
private static cDailyRecord PlayerDailyRecord = null;
|
|
|
|
public static cGoodsData Goods { get; private set; } = null;
|
|
|
|
private static cAttend[] playAttend;
|
|
|
|
public static cAwakenData PlayAwaken = null;
|
|
|
|
private static cBoxData PlayBoxes { get; set; } = null;
|
|
|
|
public static cAdBuffLevel PlayBuff { get; set; } = null;
|
|
|
|
public static cPlayCostume PlayEquipCostume { get; private set; } = null;
|
|
|
|
public static Dictionary<int, cPlayGuardian> PlayGuardian = new Dictionary<int, cPlayGuardian>();
|
|
|
|
public static Dictionary<int, cPlayRelic> PlayRelic = new Dictionary<int, cPlayRelic>();
|
|
|
|
public static cPlayerDungeonInfo PlayDgAwaken = null;
|
|
|
|
public static cDungeonPreset PlayDgPreset = null;
|
|
|
|
public static cPvpPlay playPvp = null;
|
|
|
|
private static cQuestDaily[] playQuestDaily;
|
|
private static cQuestRepeat[] playQuestRepeat;
|
|
|
|
private static dMail[] playMails = null;
|
|
|
|
private static cEventItem playEventRoulette;
|
|
private static cEventItem playEventTrade;
|
|
private static cEventItem playEventRaise;
|
|
private static cRewardEvent playEventReward;
|
|
private static cQuestAttend playQuestEventAttend;
|
|
private static Dictionary<int, cQuestEvent> playQuestEvent = new Dictionary<int, cQuestEvent>();
|
|
#endregion
|
|
|
|
#region Union data (System data + Play data)
|
|
private static Dictionary<int, dTitle> dicProfileTitle = new Dictionary<int, dTitle>();
|
|
|
|
private static Dictionary<int, dIcon> dicProfileIcon = new Dictionary<int, dIcon>();
|
|
|
|
private static Dictionary<int, dCharStat> dicCharStatEnhanceGold = new Dictionary<int, dCharStat>();
|
|
|
|
private static Dictionary<int, dCharStat> dicCharStatEnhancePoint = new Dictionary<int, dCharStat>();
|
|
|
|
private static Dictionary<int, dCostume> dicCosCloth = new Dictionary<int, dCostume>();
|
|
private static Dictionary<int, dCostume> dicCosWeapon = new Dictionary<int, dCostume>();
|
|
|
|
private static Dictionary<int, dSkillActive> dicSkillActive = new Dictionary<int, dSkillActive>();
|
|
private static Dictionary<int, dSkillPassive> dicSkillPassive = new Dictionary<int, dSkillPassive>();
|
|
|
|
private static Dictionary<int, Dictionary<int, dGear>> dicGearEquipment = new Dictionary<int, Dictionary<int, dGear>>()
|
|
{
|
|
[cGoods.TBagWeapon] = new Dictionary<int, dGear>(),
|
|
[cGoods.TBagArmorCape] = new Dictionary<int, dGear>(),
|
|
[cGoods.TBagArmorHat] = new Dictionary<int, dGear>(),
|
|
[cGoods.TBagArmorShoes] = new Dictionary<int, dGear>(),
|
|
[cGoods.TBagAcceEar] = new Dictionary<int, dGear>(),
|
|
[cGoods.TBagAcceNeck] = new Dictionary<int, dGear>(),
|
|
[cGoods.TBagAcceRing] = new Dictionary<int, dGear>()
|
|
};
|
|
|
|
private static Dictionary<int, dTreasure> dicGearTreasure = new Dictionary<int, dTreasure>();
|
|
|
|
private static Dictionary<int, dPet> dicPet = new Dictionary<int, dPet>();
|
|
|
|
private static Dictionary<int, dShop> dicShop = new Dictionary<int, dShop>();
|
|
|
|
private static Dictionary<eCondition, dPass> dicPass = new Dictionary<eCondition, dPass>();
|
|
private static dPass passEvent = null;
|
|
private static dPass passEventNext = null;
|
|
#endregion
|
|
|
|
#region ETC
|
|
public static bool bLoadLocalData = false;
|
|
public static bool IsNeedDataSave { get; private set; } = false;
|
|
|
|
private static HashSet<int> boxNew = new HashSet<int>();
|
|
|
|
private static HashSet<int> cosClothNew = new HashSet<int>();
|
|
private static HashSet<int> cosWeaponNew = new HashSet<int>();
|
|
|
|
private static int currentTotalSkillLv = 0;
|
|
|
|
private static Dictionary<int, int> dicGearLast = new Dictionary<int, int>()
|
|
{
|
|
[cGoods.TBagWeapon] = 1,
|
|
[cGoods.TBagArmorCape] = 1,
|
|
[cGoods.TBagArmorHat] = 1,
|
|
[cGoods.TBagArmorShoes] = 1,
|
|
[cGoods.TBagAcceEar] = 1,
|
|
[cGoods.TBagAcceNeck] = 1,
|
|
[cGoods.TBagAcceRing] = 1,
|
|
};
|
|
private static Dictionary<int, int> dicGearLastHave = new Dictionary<int, int>()
|
|
{
|
|
[cGoods.TBagWeapon] = -1,
|
|
[cGoods.TBagArmorCape] = -1,
|
|
[cGoods.TBagArmorHat] = -1,
|
|
[cGoods.TBagArmorShoes] = -1,
|
|
[cGoods.TBagAcceEar] = -1,
|
|
[cGoods.TBagAcceNeck] = -1,
|
|
[cGoods.TBagAcceRing] = -1,
|
|
};
|
|
private static Dictionary<int, int> dicGearLv = new Dictionary<int, int>()
|
|
{
|
|
[cGoods.TBagWeapon] = 0,
|
|
[cGoods.TBagArmorCape] = 0,
|
|
[cGoods.TBagArmorHat] = 0,
|
|
[cGoods.TBagArmorShoes] = 0,
|
|
[cGoods.TBagAcceEar] = 0,
|
|
[cGoods.TBagAcceNeck] = 0,
|
|
[cGoods.TBagAcceRing] = 0,
|
|
};
|
|
private static Dictionary<int, HashSet<int>> dicGearNew = new Dictionary<int, HashSet<int>>()
|
|
{
|
|
[cGoods.TBagWeapon] = new HashSet<int>(),
|
|
[cGoods.TBagArmorCape] = new HashSet<int>(),
|
|
[cGoods.TBagArmorHat] = new HashSet<int>(),
|
|
[cGoods.TBagArmorShoes] = new HashSet<int>(),
|
|
[cGoods.TBagAcceEar] = new HashSet<int>(),
|
|
[cGoods.TBagAcceNeck] = new HashSet<int>(),
|
|
[cGoods.TBagAcceRing] = new HashSet<int>()
|
|
};
|
|
private static int[] arrHaveWeapon = new int[7];
|
|
private static int[,] arrHaveArmor = new int[3, 7];
|
|
private static int[,] arrHaveAcc = new int[3, 7];
|
|
|
|
public static DateTime PvpRankRefreshTime { get; private set; }
|
|
|
|
private static HashSet<int> petNew = new HashSet<int>();
|
|
private static int petLv = 0;
|
|
|
|
private static List<dShop>[] shopGroupedByShopType = new List<dShop>[]
|
|
{
|
|
new List<dShop>(),
|
|
new List<dShop>(),
|
|
new List<dShop>(),
|
|
new List<dShop>(),
|
|
new List<dShop>(),
|
|
new List<dShop>(),
|
|
new List<dShop>(),
|
|
new List<dShop>()
|
|
};
|
|
|
|
public static DateTime MailRefreshTime { get; private set; }
|
|
public static int MailCount { get; private set; }
|
|
public static DateTime MailReadRefreshTime { get; private set; }
|
|
private static dMail[] readMails = null;
|
|
|
|
private static List<nAchivement> listBattleType = new List<nAchivement>();
|
|
private static List<nAchivement> listEquipmentType = new List<nAchivement>();
|
|
private static List<nAchivement> listSummonType = new List<nAchivement>();
|
|
private static List<nAchivement> listDungeonType = new List<nAchivement>();
|
|
private static List<nAchivement> listEtcType = new List<nAchivement>();
|
|
#endregion
|
|
|
|
#region Base
|
|
public static IEnumerator InitSystemData(nSystemData systemData)
|
|
{
|
|
{
|
|
Const = systemData.constData;
|
|
|
|
sysAttend = systemData.sysAttend;
|
|
|
|
LoadExtraAbility(systemData.sysExtraRarity, systemData.sysExtra);
|
|
|
|
sysBuff = systemData.sysBuff;
|
|
|
|
for (int i = 0; i < systemData.sysBox.Length; ++i)
|
|
{
|
|
dBox box = systemData.sysBox[i];
|
|
SysBoxes.Add(box.id, box);
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysProfileTitle.Length; ++i)
|
|
{
|
|
dTitle title = systemData.sysProfileTitle[i];
|
|
dicProfileTitle.SafeInsert(title.id, title);
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysProfileIcon.Length; i++)
|
|
{
|
|
dIcon icon = systemData.sysProfileIcon[i];
|
|
dicProfileIcon.SafeInsert(icon.id, icon);
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysBackground.Length; ++i)
|
|
{
|
|
dBg bg = systemData.sysBackground[i];
|
|
dicBg.SafeInsert(bg.id, bg);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
for (int i = 0; i < systemData.sysCharEnhanceGold.Length; ++i)
|
|
{
|
|
dCharStat stat = systemData.sysCharEnhanceGold[i];
|
|
dicCharStatEnhanceGold.SafeInsert(new KeyValuePair<int, dCharStat>(stat.id, stat));
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysCharEnhancePoint.Length; ++i)
|
|
{
|
|
dCharStat charStat = systemData.sysCharEnhancePoint[i];
|
|
dicCharStatEnhancePoint.SafeInsert(charStat.id, charStat);
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysAwaken.Length; ++i)
|
|
{
|
|
dAwakenReward reward = systemData.sysAwaken[i];
|
|
SysAwakenRewards.Add(i + 1, reward);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
sysPetAwakens = systemData.sysPetAwaken;
|
|
sysPetLvEffects = systemData.sysPetEnhance;
|
|
|
|
for (int i = 0; i < systemData.sysPet.Length; i++)
|
|
{
|
|
dPet pet = systemData.sysPet[i];
|
|
dicPet.SafeInsert(pet.id, pet);
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysGuardian.Length; i++)
|
|
{
|
|
dSysGuardian guardian = systemData.sysGuardian[i];
|
|
sysGuardian.SafeInsert(guardian.guardianType, guardian);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
sysSkillAwakens = systemData.sysCharSkillAwaken;
|
|
sysSkillLvEffects = systemData.sysCharSkillEnhance;
|
|
|
|
for (int i = 0; i < systemData.sysCharSkillPassive.Length; ++i)
|
|
{
|
|
dSkillPassive skill = systemData.sysCharSkillPassive[i];
|
|
dicSkillPassive.SafeInsert(new KeyValuePair<int, dSkillPassive>(skill.id, skill));
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysCharSkillActive.Length; ++i)
|
|
{
|
|
dSkillActive skill = systemData.sysCharSkillActive[i];
|
|
dicSkillActive.SafeInsert(new KeyValuePair<int, dSkillActive>(skill.id, skill));
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
for (int i = 0; i < systemData.sysCostumeOutfit.Length; ++i)
|
|
{
|
|
dCostume costume = systemData.sysCostumeOutfit[i];
|
|
dicCosCloth.SafeInsert(new KeyValuePair<int, dCostume>(costume.id, costume));
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysCostumeOutfitSet.Length; ++i)
|
|
{
|
|
dCostumeSet cosSet = systemData.sysCostumeOutfitSet[i];
|
|
for (int j = 0; j < cosSet.set.Length; ++j)
|
|
{
|
|
// id가 음수이거나, 해당 코스튬이 없는 경우 -1로 설정.
|
|
if (cosSet.set[j] >= 0 && !dicCosCloth.ContainsKey(cosSet.set[j]))
|
|
cosSet.set[j] = -1;
|
|
}
|
|
dicCosClothSet.SafeInsert(new KeyValuePair<int, dCostumeSet>(cosSet.id, cosSet));
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysCostumeWeapon.Length; ++i)
|
|
{
|
|
dCostume costume = systemData.sysCostumeWeapon[i];
|
|
dicCosWeapon.SafeInsert(new KeyValuePair<int, dCostume>(costume.id, costume));
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysCostumeWeaponSet.Length; i++)
|
|
{
|
|
dCostumeSet cosSet = systemData.sysCostumeWeaponSet[i];
|
|
for (int j = 0; j < cosSet.set.Length; ++j)
|
|
{
|
|
// id가 음수이거나, 해당 코스튬이 없는 경우 -1로 설정.
|
|
if (cosSet.set[j] >= 0 && !dicCosWeapon.ContainsKey(cosSet.set[j]))
|
|
cosSet.set[j] = -1;
|
|
}
|
|
dicCosWeaponSet.SafeInsert(new KeyValuePair<int, dCostumeSet>(cosSet.id, cosSet));
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
sysGearAwakens = systemData.sysGearAwaken;
|
|
sysGearLvEffects = systemData.sysGearEnhance;
|
|
|
|
LoadSysGearEquipment(cGoods.TBagWeapon, systemData.sysGearWeapon);
|
|
LoadSysGearEquipment(cGoods.TBagArmorCape, systemData.sysGearCape);
|
|
LoadSysGearEquipment(cGoods.TBagArmorHat, systemData.sysGearHat);
|
|
LoadSysGearEquipment(cGoods.TBagArmorShoes, systemData.sysGearShoes);
|
|
LoadSysGearEquipment(cGoods.TBagAcceEar, systemData.sysGearEarring);
|
|
LoadSysGearEquipment(cGoods.TBagAcceNeck, systemData.sysGearNecklace);
|
|
LoadSysGearEquipment(cGoods.TBagAcceRing, systemData.sysGearRing);
|
|
|
|
gearTreasureLvUpLvBounds = systemData.sysGearTreasureEnhance.lv;
|
|
gearTreasureLvUpSuccRates = systemData.sysGearTreasureEnhance.props;
|
|
|
|
for (int i = 0; i < systemData.sysGearTreasure.Length; ++i)
|
|
{
|
|
dTreasure treasure = systemData.sysGearTreasure[i];
|
|
dicGearTreasure.SafeInsert(treasure.id, treasure);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
sysRelicEnhancePropLvs = systemData.sysRelicEnhance.lv;
|
|
sysRelicEnhanceProp = systemData.sysRelicEnhance.props;
|
|
|
|
for (int i = 0; i < systemData.sysRelic.Length; ++i)
|
|
{
|
|
dSysRelic relic = systemData.sysRelic[i];
|
|
|
|
if(!sysRelicsGroupedByType.ContainsKey(relic.relicType))
|
|
sysRelicsGroupedByType.Add(relic.relicType, new List<dSysRelic>());
|
|
|
|
sysRelicsGroupedByType[relic.relicType].Add(relic);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
for (int i = 0; i < systemData.sysMonster.Length; ++i)
|
|
{
|
|
dMonster monster = systemData.sysMonster[i];
|
|
dicMonster.SafeInsert(monster.id, monster);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
sysAreas = systemData.sysArea;
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
sysPvp = systemData.sysPvp;
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
gachaWeaponLvs = systemData.sysGachaWeaponCount;
|
|
gachaWeaponGrades = systemData.sysGachaWeaponGrade;
|
|
gachaArmorLvs = systemData.sysGachaArmorCount;
|
|
gachaArmorGrades = systemData.sysGachaArmorGrade;
|
|
gachaAcceLvs = systemData.sysGachaAccCount;
|
|
gachaAcceGrades = systemData.sysGachaAccGrade;
|
|
|
|
// notice : call method order must be pass -> shop
|
|
LoadPassSysData(systemData.sysPass);
|
|
LoadShopSysData(systemData.sysShop);
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
for (int i = 0; i < systemData.sysQuestDaily.Length; ++i)
|
|
{
|
|
dQuest quest = systemData.sysQuestDaily[i];
|
|
sysQuestDaily.SafeInsert(quest.id, quest);
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysQuestRepeat.Length; ++i)
|
|
{
|
|
dQuest quest = systemData.sysQuestRepeat[i];
|
|
sysQuestRepeat.SafeInsert(quest.id, quest);
|
|
}
|
|
|
|
for (int i = 0; i < systemData.sysQuestMission.Length; ++i)
|
|
{
|
|
dMission mission = systemData.sysQuestMission[i];
|
|
sysQuestMission.SafeInsert(mission.id, mission);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
for (int i = 0; i < systemData.sysEvent.Length; i++)
|
|
{
|
|
dEvent evn = systemData.sysEvent[i];
|
|
dicEvent.SafeInsert(evn.id, evn);
|
|
}
|
|
|
|
sysEventRoulette = systemData.sysEventRoulette;
|
|
sysEventTrade = systemData.sysEventTrade;
|
|
sysEventRaise = systemData.sysEventRaise;
|
|
sysRewardEvent = systemData.sysEventReward;
|
|
|
|
for (int i = 0; i < systemData.sysQuestEvent.Length; i++)
|
|
{
|
|
dQuest quest = systemData.sysQuestEvent[i];
|
|
sysQuestEvent.SafeInsert(quest.id, quest);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
|
|
{
|
|
sysNotices = systemData.sysNotice;
|
|
sysChatNotices = systemData.sysNoticeChat;
|
|
}
|
|
}
|
|
|
|
public static IEnumerator InitPlayData(nPlayData playData)
|
|
{
|
|
LoadPlayData(playData.playUser);
|
|
|
|
PlayerTotalRecord = playData.playRecordTotal;
|
|
PlayerDailyRecord = playData.playRecordDaily;
|
|
|
|
playAttend = playData.playAttend;
|
|
|
|
LoadGoodsData(playData.playCurrency);
|
|
LoadCostumeData(playData.playCostumeOutfit, playData.playCostumeWeapon);
|
|
LoadPlayBoxData(playData.playBox);
|
|
LoadPlayerTitlesData(playData.playProfileTitle);
|
|
LoadPlayerIconsData(playData.playProfileIcon);
|
|
yield return null;
|
|
|
|
LoadAdBuffData(playData.playBuff);
|
|
LoadCharStatsEnhanceGoldData(playData.playCharEnhanceGold);
|
|
LoadCharStatsEnhancePointData(playData.playCharEnhancePoint);
|
|
LoadAwakenData(playData.playAwaken);
|
|
LoadCostumeEquipStatusData(playData.playCostumeInfo);
|
|
yield return null;
|
|
|
|
LoadPlayGearEquipment(cGoods.TBagWeapon, playData.playGearWeapon);
|
|
LoadPlayGearEquipment(cGoods.TBagArmorCape, playData.playGearCape);
|
|
LoadPlayGearEquipment(cGoods.TBagArmorHat, playData.playGearHat);
|
|
LoadPlayGearEquipment(cGoods.TBagArmorShoes, playData.playGearShoes);
|
|
LoadPlayGearEquipment(cGoods.TBagAcceEar, playData.playGearEarring);
|
|
LoadPlayGearEquipment(cGoods.TBagAcceNeck, playData.playGearNecklace);
|
|
LoadPlayGearEquipment(cGoods.TBagAcceRing, playData.playGearRing);
|
|
LoadPlayGearTreasures(playData.playGearTreasure);
|
|
yield return null;
|
|
|
|
for (int i = 0; i < playData.playRelic.Length; ++i)
|
|
{
|
|
cPlayRelic relic = playData.playRelic[i];
|
|
PlayRelic.SafeInsert(relic.relicType, relic);
|
|
}
|
|
yield return null;
|
|
|
|
LoadPetsPlay(playData.playPet);
|
|
|
|
// load guardian datas
|
|
for (int i = 0; i < playData.playGuardian.Length; ++i)
|
|
{
|
|
cPlayGuardian guardian = playData.playGuardian[i];
|
|
PlayGuardian.SafeInsert(playData.playGuardian[i].guardianType, guardian);
|
|
}
|
|
yield return null;
|
|
|
|
LoadSkillsPlay(playData.playCharSkillPassive, playData.playCharSkillActive);
|
|
yield return null;
|
|
|
|
LoadAwakenDungeonData(playData.playDgAwaken);
|
|
|
|
PlayDgPreset = cDungeonPreset.Load();
|
|
yield return null;
|
|
|
|
LoadPvpData(playData.playPvp, playData.rankPvp);
|
|
yield return null;
|
|
|
|
playQuestDaily = playData.playQuestDaily;
|
|
playQuestRepeat = playData.playQuestRepeat;
|
|
yield return null;
|
|
|
|
// notice : call method order must be pass -> shop
|
|
LoadPassPlayData(playData.playPass);
|
|
LoadShopPlayData(playData.playShop);
|
|
yield return null;
|
|
|
|
playEventRoulette = playData.playEventRoulette;
|
|
playEventTrade = playData.playEventTrade;
|
|
playEventRaise = playData.playEventRaise;
|
|
playEventReward = playData.playEventReward;
|
|
playQuestEventAttend = playData.playQuestEventAttend;
|
|
LoadPlayEventQuestPlay(playData.playQuestEvent);
|
|
yield return null;
|
|
|
|
SetMailCount(playData.mailCount);
|
|
}
|
|
|
|
// 실행 중에 사용한 모든 데이터 초기화. 디바이스에 저장된 데이터를 지우는게 아님. 게임 재시작 등에서 사용.
|
|
public static void ResetAll()
|
|
{
|
|
Const = null;
|
|
PlayData = null;
|
|
PlayEquipCostume = null;
|
|
PlayBuff = null;
|
|
Goods = null;
|
|
SysBoxes.Clear();
|
|
boxNew.Clear();
|
|
PlayBoxes = null;
|
|
|
|
dicCosClothSet.Clear();
|
|
dicCosCloth.Clear();
|
|
cosClothNew.Clear();
|
|
dicCosWeaponSet.Clear();
|
|
dicCosWeapon.Clear();
|
|
cosWeaponNew.Clear();
|
|
|
|
sysAreas = null;
|
|
dicMonster.Clear();
|
|
dicBg.Clear();
|
|
dicBgm.Clear();
|
|
|
|
dicCharStatEnhanceGold.Clear();
|
|
dicCharStatEnhancePoint.Clear();
|
|
PlayAwaken = null;
|
|
|
|
sysSkillAwakens = null;
|
|
sysSkillLvEffects = null;
|
|
dicSkillPassive.Clear();
|
|
dicSkillActive.Clear();
|
|
currentTotalSkillLv = 0;
|
|
|
|
sysPetAwakens = null;
|
|
sysPetLvEffects = null;
|
|
dicPet.Clear();
|
|
petNew.Clear();
|
|
petLv = 0;
|
|
|
|
extraRarityRates = null;
|
|
extraAbilities = null;
|
|
extraAbilityIds = null;
|
|
|
|
sysGearAwakens = null;
|
|
sysGearLvEffects = null;
|
|
foreach (var gears in dicGearEquipment.Values)
|
|
{
|
|
gears.Clear();
|
|
}
|
|
|
|
foreach (var key in dicGearLast.Keys)
|
|
{
|
|
dicGearLast[key] = 1;
|
|
}
|
|
|
|
foreach (var key in dicGearLastHave.Keys)
|
|
{
|
|
dicGearLastHave[key] = -1;
|
|
}
|
|
|
|
foreach (var key in dicGearLv.Keys)
|
|
{
|
|
dicGearLv[key] = 0;
|
|
}
|
|
|
|
foreach (var gears in dicGearNew.Values)
|
|
{
|
|
gears.Clear();
|
|
}
|
|
|
|
gearTreasureLvUpLvBounds = null;
|
|
gearTreasureLvUpSuccRates = null;
|
|
arrHaveWeapon = null;
|
|
arrHaveArmor = null;
|
|
arrHaveAcc = null;
|
|
dicGearTreasure.Clear();
|
|
|
|
dicProfileTitle.Clear();
|
|
dicProfileIcon.Clear();
|
|
sysQuestDaily.Clear();
|
|
sysQuestRepeat.Clear();
|
|
playQuestDaily = null;
|
|
playQuestRepeat = null;
|
|
|
|
sysQuestMission.Clear();
|
|
|
|
sysGuardian = null;
|
|
PlayGuardian = null;
|
|
|
|
//PlayDgGold = null;
|
|
//PlayDgReinStone = null;
|
|
//PlayDgPet = null;
|
|
//PlayDgAwakenStone = null;
|
|
PlayDgAwaken = null;
|
|
PlayDgPreset = null;
|
|
|
|
gachaWeaponLvs = null;
|
|
gachaWeaponGrades = null;
|
|
gachaArmorLvs = null;
|
|
gachaArmorGrades = null;
|
|
gachaAcceLvs = null;
|
|
gachaAcceGrades = null;
|
|
|
|
sysBuff = null;
|
|
sysAttend = null;
|
|
playAttend = null;
|
|
|
|
dicShop.Clear();
|
|
for (int i = 0; i < shopGroupedByShopType.Length; i++)
|
|
shopGroupedByShopType[i].Clear();
|
|
|
|
dicPass.Clear();
|
|
|
|
sysPvp = null;
|
|
playPvp = null;
|
|
pvpMyRank = null;
|
|
pvpRanks = null;
|
|
PvpRankRefreshTime = TimeUtils.Now();
|
|
|
|
passEvent = null;
|
|
passEventNext = null;
|
|
|
|
sysRewardEvent = null;
|
|
playEventReward = null;
|
|
|
|
dicEvent.Clear();
|
|
sysEventTrade = null;
|
|
|
|
MailRefreshTime = TimeUtils.Now();
|
|
MailReadRefreshTime = TimeUtils.Now();
|
|
MailCount = 0;
|
|
playMails = null;
|
|
readMails = null;
|
|
|
|
sysNotices = null;
|
|
sysChatNotices = null;
|
|
|
|
BuffMgr.ResetAll();
|
|
}
|
|
|
|
// 전부 삭제. 로그아웃 등에서 호출.
|
|
public static void DeleteAll()
|
|
{
|
|
ES3.DeleteFile(FormatString.StringFormat(Global.ES3_Server, "1"));
|
|
ES3.DeleteFile(FormatString.StringFormat(Global.ES3_Server, "2"));
|
|
|
|
ES3.DeleteFile(Global.ES3_PlayDatas);
|
|
ES3.DeleteFile(Global.ES3_PlayGoods);
|
|
ES3.DeleteFile(Global.ES3_PlayBox);
|
|
ES3.DeleteFile(Global.ES3_Pass);
|
|
ES3.DeleteFile(Global.ES3_Notice);
|
|
ES3.DeleteFile(Global.ES3_CharAwaken);
|
|
ES3.DeleteFile(Global.ES3_AdBuff);
|
|
ES3.DeleteFile(Global.ES3_DgPreset);
|
|
ES3.DeleteFile(Global.ES3_StartMain);
|
|
}
|
|
|
|
// 데이터 저장.
|
|
public static void SaveData()
|
|
{
|
|
PlayData.Save();
|
|
Goods.Save(PlayData.server);
|
|
PlayBoxes.Save(PlayData.server);
|
|
SavePass();
|
|
}
|
|
|
|
// 데이터 서버 저장시 처리.
|
|
public static void OnSaveDataServer()
|
|
{
|
|
IsNeedDataSave = false;
|
|
}
|
|
#endregion Base
|
|
|
|
#region Play Data
|
|
// 플레이 데이터 불러오기.
|
|
public static void LoadPlayData(cPlayData playdata)
|
|
{
|
|
if (playdata == null && PlayData != null) return;
|
|
|
|
if (playdata != null)
|
|
{
|
|
cPlayData localdata = cPlayData.Load(playdata.server);
|
|
bLoadLocalData = !playdata.forceOverwrite && playdata.lastTime < localdata.lastTime;
|
|
|
|
if (bLoadLocalData && localdata.lastTime > DateTime.MinValue)
|
|
{
|
|
playdata.playerLv = localdata.playerLv;
|
|
playdata.playerExp = localdata.playerExp;
|
|
playdata.playerIcon = localdata.playerIcon;
|
|
playdata.curStage = localdata.curStage;
|
|
playdata.usePreset = localdata.usePreset;
|
|
playdata.skillPresets = localdata.skillPresets;
|
|
playdata.usePetPreset = localdata.usePetPreset;
|
|
playdata.petPresets = localdata.petPresets;
|
|
playdata.lastTime = localdata.lastTime;
|
|
}
|
|
PlayData = playdata;
|
|
PlayData.stageRepeat = localdata.stageRepeat;
|
|
}
|
|
else
|
|
{
|
|
PlayData = cPlayData.Load(1);
|
|
}
|
|
}
|
|
|
|
// 플레이 광고버프레벨 데이터 불러오기.
|
|
private static void LoadAdBuffData(cAdBuffLevel adbuffdata)
|
|
{
|
|
if (adbuffdata != null)
|
|
{
|
|
cAdBuffLevel localdata = cAdBuffLevel.Load(adbuffdata, PlayData.server);
|
|
|
|
PlayBuff = adbuffdata;
|
|
|
|
PlayBuff.atkExp = localdata.atkExp;
|
|
PlayBuff.expExp = localdata.expExp;
|
|
PlayBuff.goldExp = localdata.goldExp;
|
|
|
|
PlayBuff.adTimer[0] = localdata.adTimer[0];
|
|
PlayBuff.adTimer[1] = localdata.adTimer[1];
|
|
PlayBuff.adTimer[2] = localdata.adTimer[2];
|
|
}
|
|
else
|
|
{
|
|
PlayBuff = new cAdBuffLevel();
|
|
}
|
|
}
|
|
|
|
public static void SetPlayRewardEvent(cRewardEvent rewardEvent)
|
|
{
|
|
playEventReward.sid = rewardEvent.sid;
|
|
}
|
|
|
|
public static cRewardEvent GetPlayRewardEvent()
|
|
{
|
|
return playEventReward;
|
|
}
|
|
#endregion Play Data
|
|
|
|
#region Goods 1 (SetGoods, AddGoods)
|
|
// 플레이 재화 불러오기.
|
|
public static void LoadGoodsData(cGoodsData goodsdata)
|
|
{
|
|
if (goodsdata == null && Goods != null) return;
|
|
|
|
if (goodsdata != null)
|
|
{
|
|
cGoodsData localdata = cGoodsData.Load(PlayData.server);
|
|
bLoadLocalData = PlayData.lastTime < localdata.lastTime;
|
|
|
|
if (bLoadLocalData && localdata.lastTime > DateTime.MinValue)
|
|
{
|
|
goodsdata.gold = localdata.gold;
|
|
goodsdata.goldUsed = localdata.gold;
|
|
}
|
|
|
|
Goods = goodsdata;
|
|
}
|
|
else
|
|
{
|
|
Goods = cGoodsData.Load(PlayData.server);
|
|
}
|
|
}
|
|
|
|
// 재화 세팅.
|
|
public static void SetGoods(cGoodsData playcurrency, bool localExclude)
|
|
{
|
|
if (localExclude)
|
|
{
|
|
playcurrency.gold = Goods.gold;
|
|
playcurrency.goldUsed = Goods.goldUsed;
|
|
}
|
|
Goods = playcurrency;
|
|
|
|
GameUIMgr.SSetGoods();
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
public static void AddItem(nGoods target, bool localExclude)
|
|
{
|
|
switch (target.propertyType)
|
|
{
|
|
// 광고 제거.
|
|
case cGoods.TAdsRemove:
|
|
PlayData.adRemove = true;
|
|
break;
|
|
// 재화.
|
|
case cGoods.TCurrency:
|
|
if (target.propertyId == cGoods.CGold && localExclude) AddGold(target.propertyCount);
|
|
else if(target.propertyId == cGoods.CFantasyWorldRing) Goods.fantasyWorldRing += (int)target.propertyCount;
|
|
else if(target.propertyId == cGoods.CMemoryPiece) Goods.memoryPiece += (int)target.propertyCount;
|
|
break;
|
|
// 장비 획득.
|
|
case cGoods.TBagWeapon:
|
|
case cGoods.TBagArmorCape:
|
|
case cGoods.TBagArmorHat:
|
|
case cGoods.TBagArmorShoes:
|
|
case cGoods.TBagAcceEar:
|
|
case cGoods.TBagAcceNeck:
|
|
case cGoods.TBagAcceRing:
|
|
AddGearEquip(target.propertyType, target.propertyId, (int)target.propertyCount);
|
|
break;
|
|
// 보물 획득.
|
|
case cGoods.TBagTreasure:
|
|
AddGearTreasure(target.propertyId, (int)target.propertyCount);
|
|
break;
|
|
// 펫 획득.
|
|
case cGoods.TPet:
|
|
AddPet(target.propertyId);
|
|
break;
|
|
// 펫 스피릿 획득.
|
|
case cGoods.TPetSpirit:
|
|
AddPetSpirit(target.propertyId, (int)target.propertyCount);
|
|
break;
|
|
//던전 티켓 획득
|
|
case cGoods.TRedTicket:
|
|
{
|
|
if(GameModDataGroup.Instance.TryGetModData(DeepCaveDungeonProperty.CodeName, out DeepCaveDungeonData modData))
|
|
modData.EnterTicketCount += (uint)target.propertyCount;
|
|
}
|
|
break;
|
|
case cGoods.TBlueTicket:
|
|
{
|
|
if(GameModDataGroup.Instance.TryGetModData(AtlantisDungeonProperty.CodeName, out AtlantisDungeonData modData))
|
|
modData.EnterTicketCount += (uint)target.propertyCount;
|
|
}
|
|
break;
|
|
case cGoods.TPurpleTicket:
|
|
{
|
|
if (GameModDataGroup.Instance.TryGetModData(ProtectTheMerchantDgProp.CodeName, out ProtectTheMerchantDgData modData))
|
|
modData.EnterTicketCount += (uint)target.propertyCount;
|
|
}
|
|
break;
|
|
case cGoods.TSkyblueTicket:
|
|
{
|
|
if (GameModDataGroup.Instance.TryGetModData(DevelopTheJungleDgProp.CodeName, out DevelopTheJungleDgData modData))
|
|
modData.EnterTicketCount += (uint)target.propertyCount;
|
|
}
|
|
break;
|
|
case cGoods.TGoldKey:
|
|
{
|
|
if (GameModDataGroup.Instance.TryGetModData(HuntEagleDgProp.CodeName, out HuntEagleDgData modData))
|
|
modData.EnterTicketCount += (uint)target.propertyCount;
|
|
}
|
|
break;
|
|
// 결투장 티켓 획득.
|
|
case cGoods.TPvpTicket:
|
|
playPvp.ticket += (int)target.propertyCount;
|
|
break;
|
|
// 코스튬.
|
|
case cGoods.TCosCloth:
|
|
AddCosCloth(target.propertyId);
|
|
break;
|
|
case cGoods.TCosWeapon:
|
|
AddCosWeapon(target.propertyId);
|
|
break;
|
|
// 상자 획득.
|
|
case cGoods.TBox:
|
|
AddBox(target.propertyId, (int)target.propertyCount);
|
|
break;
|
|
// 아이콘 획득.
|
|
case cGoods.TProfileIcon:
|
|
ProfileMgr.SGetIcon(target.propertyId);
|
|
break;
|
|
// 칭호 획득.
|
|
case cGoods.TProfileTitle:
|
|
ProfileMgr.SGetTitle(target.propertyId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 재화 증가. localexclude : 로컬 관리 재화(골드) 증가 안 함.
|
|
public static void AddGoods(IList<nGoods> result, cGoodsData playcurrency, bool localExclude)
|
|
{
|
|
if (result != null)
|
|
{
|
|
// 스탯 재계산 필요. 보유효과, 통합 레벨 효과가 있는 아이템을 처음 획득했을 때 다시 계산.
|
|
for (int i = 0; i < result.Count; ++i)
|
|
{
|
|
AddItem(result[i], localExclude);
|
|
}
|
|
}
|
|
|
|
// 재화 획득 처리. 동료 영혼석 자동 변환 등 때문에 아래에 위치.
|
|
if (playcurrency != null)
|
|
{
|
|
//TODO: this is temp code, because server doesn't know about those goods.
|
|
playcurrency.fantasyWorldRing = Goods.fantasyWorldRing;
|
|
playcurrency.memoryPiece = Goods.memoryPiece;
|
|
|
|
SetGoods(playcurrency, localExclude);
|
|
}
|
|
}
|
|
#endregion Goods 1 (SetGoods, AddGoods)
|
|
|
|
#region Goods 2 (Add/Sub Local)
|
|
// 골드 세팅.
|
|
public static void SetGold(BigInteger curvalue, BigInteger usedvalue)
|
|
{
|
|
Goods.gold = curvalue;
|
|
Goods.goldUsed = usedvalue;
|
|
GameUIMgr.SSetGold(Goods.gold);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 골드 증가.
|
|
public static void AddGold(BigInteger addvalue)
|
|
{
|
|
Goods.gold += addvalue;
|
|
GameUIMgr.SSetGold(Goods.gold);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 골드 감소.
|
|
public static void SubGold(BigInteger subvalue)
|
|
{
|
|
Goods.gold -= subvalue;
|
|
Goods.goldUsed += subvalue;
|
|
GameUIMgr.SSetGold(Goods.gold);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 보석 세팅.
|
|
public static void SetDia(int curvaluep, int curvaluef)
|
|
{
|
|
Goods.diaPaid = curvaluep;
|
|
Goods.diaFree = curvaluef;
|
|
GameUIMgr.SSetDia(Goods.Dia);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 보석 사용.
|
|
public static void SubDia(int subvalue)
|
|
{
|
|
if (subvalue <= Goods.diaFree)
|
|
{
|
|
Goods.diaFree -= subvalue;
|
|
}
|
|
else
|
|
{
|
|
int subdia = subvalue - Goods.diaFree;
|
|
Goods.diaFree = 0;
|
|
Goods.diaPaid -= subdia;
|
|
}
|
|
GameUIMgr.SSetDia(Goods.Dia);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 레벨 포인트 세팅.
|
|
public static void SetLvPoint(int curvalue)
|
|
{
|
|
Goods.point = curvalue;
|
|
GameUIMgr.SSetLvPoint(Goods.point);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 레벨 포인트 획득.
|
|
public static void AddLvPoint(int addvalue)
|
|
{
|
|
IsNeedDataSave = true;
|
|
Goods.point += addvalue;
|
|
GameUIMgr.SSetLvPoint(Goods.point);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 레벨 포인트 사용.
|
|
public static void SubLvPoint(int subvalue)
|
|
{
|
|
Goods.point -= subvalue;
|
|
GameUIMgr.SSetLvPoint(Goods.point);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 강화석 세팅.
|
|
public static void SetEnhanceStone(int curvalue)
|
|
{
|
|
Goods.gearReinStone = curvalue;
|
|
GameUIMgr.SSetEnhanceStone(Goods.gearReinStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 강화석 획득.
|
|
public static void AddEnhanceStone(int addvalue)
|
|
{
|
|
Goods.gearReinStone += addvalue;
|
|
GameUIMgr.SSetEnhanceStone(Goods.gearReinStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 강화석 사용.
|
|
public static void SubEnhanceStone(int subvalue)
|
|
{
|
|
Goods.gearReinStone -= subvalue;
|
|
GameUIMgr.SSetEnhanceStone(Goods.gearReinStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 스킬 강화석 세팅
|
|
public static void SetSkillStone(int curvalue)
|
|
{
|
|
Goods.skillReinStone = curvalue;
|
|
GameUIMgr.SSetSkillStone(Goods.skillReinStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 스킬 강화석 획득
|
|
public static void AddSkillStone(int addvalue)
|
|
{
|
|
Goods.skillReinStone += addvalue;
|
|
GameUIMgr.SSetSkillStone(Goods.skillReinStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 스킬 강화석 사용
|
|
public static void SubSkillStone(int subvalue)
|
|
{
|
|
Goods.skillReinStone -= subvalue;
|
|
GameUIMgr.SSetSkillStone(Goods.skillReinStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 각성석 세팅.
|
|
public static void SetAwakenStone(int curvalue)
|
|
{
|
|
Goods.gearAwakenStone = curvalue;
|
|
GameUIMgr.SSetAwakenStone(Goods.gearAwakenStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 각성석 획득.
|
|
public static void AddAwakenStone(int addvalue)
|
|
{
|
|
Goods.gearAwakenStone += addvalue;
|
|
GameUIMgr.SSetAwakenStone(Goods.gearAwakenStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 각성석 사용.
|
|
public static void SubAwakenStone(int subvalue)
|
|
{
|
|
Goods.gearAwakenStone -= subvalue;
|
|
GameUIMgr.SSetAwakenStone(Goods.gearAwakenStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
public static void SetAwakenSkillStone(int curvalue)
|
|
{
|
|
Goods.skillAwakenStone = curvalue;
|
|
GameUIMgr.SSetAwakenSkillStone(Goods.skillAwakenStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
public static void AddAwakenSkillStone(int addvalue)
|
|
{
|
|
Goods.skillAwakenStone += addvalue;
|
|
GameUIMgr.SSetAwakenSkillStone(Goods.skillAwakenStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
public static void SubAwakenSkillStone(int subvalue)
|
|
{
|
|
Goods.skillAwakenStone -= subvalue;
|
|
GameUIMgr.SSetAwakenSkillStone(Goods.skillAwakenStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 변경석 세팅.
|
|
public static void SetChangeStone(int curvalue)
|
|
{
|
|
Goods.changeStone = curvalue;
|
|
GameUIMgr.SSetChangeStone(Goods.changeStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 변경석 획득.
|
|
public static void AddChangeStone(int addvalue)
|
|
{
|
|
Goods.changeStone += addvalue;
|
|
GameUIMgr.SSetChangeStone(Goods.changeStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 변경석 사용.
|
|
public static void SubChangeStone(int subvalue)
|
|
{
|
|
Goods.changeStone -= subvalue;
|
|
GameUIMgr.SSetChangeStone(Goods.changeStone);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 푸딩 세팅.
|
|
public static void SetPudding(int curvalue)
|
|
{
|
|
Goods.pudding = curvalue;
|
|
GameUIMgr.SSetPudding(Goods.pudding);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 푸딩 획득.
|
|
public static void AddPudding(int addvalue)
|
|
{
|
|
Goods.pudding += addvalue;
|
|
GameUIMgr.SSetPudding(Goods.pudding);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
// 푸딩 사용.
|
|
public static void SubPudding(int subvalue)
|
|
{
|
|
Goods.pudding -= subvalue;
|
|
GameUIMgr.SSetPudding(Goods.pudding);
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
public static void SetFantasyWorldRing(int curvalue)
|
|
{
|
|
curvalue = curvalue < 0 ? 0 : curvalue;
|
|
Goods.fantasyWorldRing = curvalue;
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
|
|
public static void SetMemoryPiece(int curvalue)
|
|
{
|
|
curvalue = curvalue < 0 ? 0 : curvalue;
|
|
Goods.memoryPiece = curvalue;
|
|
Goods.Save(PlayData.server);
|
|
}
|
|
#endregion Goods 2 (Add/Sub Local)
|
|
|
|
#region Goods 3 (Box)
|
|
// 플레이 상자 불러오기.
|
|
private static void LoadPlayBoxData(nIdCnt[] boxdatas)
|
|
{
|
|
if (boxdatas == null && PlayBoxes != null) return;
|
|
|
|
if (boxdatas != null)
|
|
{
|
|
if (bLoadLocalData)
|
|
PlayBoxes = cBoxData.Load(PlayData.server);
|
|
else
|
|
PlayBoxes = new cBoxData(boxdatas);
|
|
}
|
|
else
|
|
{
|
|
PlayBoxes = cBoxData.Load(PlayData.server);
|
|
}
|
|
|
|
foreach (var box in SysBoxes)
|
|
{
|
|
if (!PlayBoxes.dicBoxCount.ContainsKey(box.Key))
|
|
{
|
|
PlayBoxes.dicBoxCount.Add(box.Key, 0);
|
|
}
|
|
}
|
|
|
|
PlayBoxes.Save(PlayData.server);
|
|
}
|
|
|
|
// 모든 상자 수.
|
|
public static nIdCnt[] GetBoxPlayDatas()
|
|
{
|
|
if (PlayBoxes == null)
|
|
return null;
|
|
return PlayBoxes.GetPlayData();
|
|
}
|
|
|
|
// 상자 수.
|
|
public static Dictionary<int, int> GetBoxCounts()
|
|
{
|
|
return PlayBoxes.dicBoxCount;
|
|
}
|
|
|
|
// 현재 상자 소지수.
|
|
public static int GetBoxCount(int key)
|
|
{
|
|
if (PlayBoxes.dicBoxCount.ContainsKey(key))
|
|
return PlayBoxes.dicBoxCount[key];
|
|
return 0;
|
|
}
|
|
|
|
// 상자 소지수 증가.
|
|
public static void AddBox(int key, int addvalue)
|
|
{
|
|
PlayBoxes.dicBoxCount[key] += addvalue;
|
|
IsNeedDataSave = true;
|
|
if (!boxNew.Contains(key))
|
|
boxNew.Add(key);
|
|
// 0개에서 증가하였으면.
|
|
if (PlayBoxes.dicBoxCount[key] == addvalue)
|
|
BagMgr.SSetUpdateConsume();
|
|
PlayBoxes.Save(PlayData.server);
|
|
}
|
|
|
|
// 상자 소지수 감소.
|
|
public static void SubBox(int key, int subvalue)
|
|
{
|
|
if (PlayBoxes.dicBoxCount.ContainsKey(key))
|
|
{
|
|
PlayBoxes.dicBoxCount[key] -= subvalue;
|
|
// 0개로 감소하였으면.
|
|
if (PlayBoxes.dicBoxCount[key] <= 0)
|
|
{
|
|
boxNew.Remove(key);
|
|
BagMgr.SSetUpdateConsume();
|
|
}
|
|
}
|
|
PlayBoxes.Save(PlayData.server);
|
|
}
|
|
|
|
public static bool IsBoxNewHave()
|
|
{
|
|
return boxNew.Count > 0;
|
|
}
|
|
|
|
public static bool IsBoxNew(int key)
|
|
{
|
|
return boxNew.Contains(key);
|
|
}
|
|
|
|
public static bool RemoveBoxNew(int key)
|
|
{
|
|
return boxNew.Remove(key);
|
|
}
|
|
#endregion Goods 3 (Box)
|
|
|
|
#region Costume
|
|
// 플레이 코스튬 데이터 불러오기.
|
|
public static void LoadCostumeEquipStatusData(cPlayCostume costumedata)
|
|
{
|
|
if (PlayEquipCostume != null) return;
|
|
|
|
if (costumedata != null)
|
|
{
|
|
PlayEquipCostume = costumedata;
|
|
}
|
|
else
|
|
{
|
|
PlayEquipCostume = new cPlayCostume();
|
|
}
|
|
}
|
|
|
|
// 코스튬 소지 상태.
|
|
public static void LoadCostumeData(int[] clplaydatas, int[] wpplaydatas)
|
|
{
|
|
// 의상 소지 상태 적용.
|
|
for (int i = 0; i < clplaydatas.Length; ++i)
|
|
{
|
|
if (dicCosCloth.TryGetValue(clplaydatas[i], out dCostume costume))
|
|
{
|
|
costume.have = true;
|
|
BuffMgr.Instance.AddCostumeEfc(costume.abilityType1, costume.abilityValue1, false);
|
|
BuffMgr.Instance.AddCostumeEfc(costume.abilityType2, costume.abilityValue2, false);
|
|
}
|
|
}
|
|
|
|
// 의상 세트 효과 적용.
|
|
foreach (var set in dicCosClothSet.Values)
|
|
{
|
|
if (IsActiveClothCosSetEffect(set.id))
|
|
BuffMgr.Instance.AddCostumeEfc(set.abilityType, set.abilityValue, false);
|
|
}
|
|
|
|
// 무기 소지 상태 적용.
|
|
for (int i = 0; i < wpplaydatas.Length; ++i)
|
|
{
|
|
if (dicCosWeapon.TryGetValue(wpplaydatas[i], out dCostume costume))
|
|
{
|
|
costume.have = true;
|
|
BuffMgr.Instance.AddCostumeEfc(costume.abilityType1, costume.abilityValue1, false);
|
|
BuffMgr.Instance.AddCostumeEfc(costume.abilityType2, costume.abilityValue2, false);
|
|
}
|
|
}
|
|
|
|
// 무기 세트 효과 적용.
|
|
foreach (var set in dicCosWeaponSet.Values)
|
|
{
|
|
if (IsActiveWeaponCosSetEffect(set.id))
|
|
BuffMgr.Instance.AddCostumeEfc(set.abilityType, set.abilityValue, false);
|
|
}
|
|
}
|
|
|
|
public static Dictionary<int, dCostumeSet> GetCosClothSets() => dicCosClothSet;
|
|
public static Dictionary<int, dCostumeSet> GetCosWeaponSets() => dicCosWeaponSet;
|
|
|
|
public static dCostumeSet GetCosClothSet(int setkey)
|
|
{
|
|
if (dicCosClothSet.ContainsKey(setkey))
|
|
return dicCosClothSet[setkey];
|
|
return dicCosClothSet[cGoods.CCosClothSetBase];
|
|
}
|
|
|
|
public static dCostumeSet GetCosWeaponSet(int setkey)
|
|
{
|
|
if (dicCosWeaponSet.ContainsKey(setkey))
|
|
return dicCosWeaponSet[setkey];
|
|
return dicCosWeaponSet[cGoods.CCosWeaponSetBase];
|
|
}
|
|
|
|
public static dCostumeSet GetCosClothSetByItem(int key)
|
|
{
|
|
foreach (var item in dicCosClothSet)
|
|
{
|
|
int[] keys = item.Value.set;
|
|
for (int i = 0; i < keys.Length; i++)
|
|
{
|
|
if (keys[i] == key)
|
|
return item.Value;
|
|
}
|
|
}
|
|
return dicCosClothSet[cGoods.CCosClothSetBase];
|
|
}
|
|
|
|
public static dCostumeSet GetCosWeaponSetByItem(int key)
|
|
{
|
|
foreach (var item in dicCosWeaponSet)
|
|
{
|
|
int[] keys = item.Value.set;
|
|
for (int i = 0; i < keys.Length; i++)
|
|
{
|
|
if (keys[i] == key)
|
|
return item.Value;
|
|
}
|
|
}
|
|
return dicCosWeaponSet[cGoods.CCosWeaponSetBase];
|
|
}
|
|
|
|
public static int GetCosClothId(int key, int ichildindex)
|
|
{
|
|
if (dicCosClothSet.ContainsKey(key))
|
|
return dicCosClothSet[key].set[ichildindex];
|
|
return dicCosClothSet[cGoods.CCosClothSetBase].set[ichildindex];
|
|
}
|
|
|
|
public static int GetCosWeaponId(int key, int ichildindex)
|
|
{
|
|
if (dicCosWeapon.ContainsKey(key))
|
|
return dicCosWeaponSet[key].set[ichildindex];
|
|
return dicCosWeaponSet[cGoods.CCosWeaponSetBase].set[ichildindex];
|
|
}
|
|
|
|
public static dCostume GetCosCloth(int key)
|
|
{
|
|
if (dicCosCloth.ContainsKey(key))
|
|
return dicCosCloth[key];
|
|
return dicCosCloth[cGoods.CCosClothBase];
|
|
}
|
|
|
|
public static dCostume GetCosWeapon(int key)
|
|
{
|
|
if (dicCosWeapon.ContainsKey(key))
|
|
return dicCosWeapon[key];
|
|
return dicCosWeapon[cGoods.CCosWeaponBase];
|
|
}
|
|
|
|
public static string GetCosClothPath(int key)
|
|
{
|
|
if (dicCosCloth.ContainsKey(key))
|
|
return FormatString.CombineAllString(AddressableMgr.PCosCloth, key.ToString());
|
|
return AddressableMgr.PCosClothBase;
|
|
}
|
|
|
|
public static string GetCosWeaponPath(int key)
|
|
{
|
|
if (dicCosWeapon.ContainsKey(key))
|
|
return FormatString.CombineAllString(AddressableMgr.PCosWeapon, key.ToString());
|
|
return AddressableMgr.PCosWeaponBase;
|
|
}
|
|
|
|
public static bool IsCosClothHave(int key)
|
|
{
|
|
if (dicCosCloth.ContainsKey(key))
|
|
return dicCosCloth[key].have;
|
|
return false;
|
|
}
|
|
|
|
public static bool IsCosWeaponHave(int key)
|
|
{
|
|
if (dicCosWeapon.ContainsKey(key))
|
|
return dicCosWeapon[key].have;
|
|
return false;
|
|
}
|
|
|
|
// 의상 세트 이펙트 활성화 상태 체크.
|
|
public static bool IsActiveClothCosSetEffect(int setkey)
|
|
{
|
|
if (!dicCosClothSet.ContainsKey(setkey))
|
|
return false;
|
|
|
|
int[] costumes = dicCosClothSet[setkey].set;
|
|
for (int i = 0; i < costumes.Length; i++)
|
|
{
|
|
if (costumes[i] < 0) continue;
|
|
if (!dicCosCloth[costumes[i]].have)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// 무기 세트 이펙트 활성화 상태 체크.
|
|
public static bool IsActiveWeaponCosSetEffect(int setkey)
|
|
{
|
|
if (!dicCosWeaponSet.ContainsKey(setkey))
|
|
return false;
|
|
|
|
int[] costumes = dicCosWeaponSet[setkey].set;
|
|
for (int k = 0; k < costumes.Length; k++)
|
|
{
|
|
if (costumes[k] < 0)
|
|
continue;
|
|
if (!dicCosWeapon[costumes[k]].have)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// 의상 획득.
|
|
public static bool AddCosCloth(int key)
|
|
{
|
|
if (!dicCosCloth.ContainsKey(key))
|
|
return false;
|
|
if (dicCosCloth[key].have)
|
|
return false;
|
|
|
|
dCostume data = dicCosCloth[key];
|
|
data.have = true;
|
|
cosClothNew.Add(key);
|
|
|
|
BuffMgr.Instance.AddCostumeEfc(data.abilityType1, data.abilityValue1, false);
|
|
BuffMgr.Instance.AddCostumeEfc(data.abilityType2, data.abilityValue2, false);
|
|
|
|
dCostumeSet costumeset = GetCosClothSetByItem(key);
|
|
if (IsActiveClothCosSetEffect(costumeset.id))
|
|
BuffMgr.Instance.AddCostumeEfc(costumeset.abilityType, costumeset.abilityValue, false);
|
|
|
|
return true;
|
|
}
|
|
|
|
// 무기 획득.
|
|
public static bool AddCosWeapon(int key)
|
|
{
|
|
if (!dicCosWeapon.ContainsKey(key))
|
|
return false;
|
|
if (dicCosWeapon[key].have)
|
|
return false;
|
|
|
|
dCostume data = dicCosWeapon[key];
|
|
data.have = true;
|
|
cosWeaponNew.Add(key);
|
|
|
|
BuffMgr.Instance.AddCostumeEfc(data.abilityType1, data.abilityValue1, false);
|
|
BuffMgr.Instance.AddCostumeEfc(data.abilityType2, data.abilityValue2, false);
|
|
|
|
dCostumeSet costumeset = GetCosWeaponSetByItem(key);
|
|
if (IsActiveWeaponCosSetEffect(costumeset.id))
|
|
BuffMgr.Instance.AddCostumeEfc(costumeset.abilityType, costumeset.abilityValue, false);
|
|
|
|
return true;
|
|
}
|
|
|
|
// 코스튬 변경.
|
|
public static void ChangeCustomize(int icloth, int iweapon, int iclrhair, int iclrtop, int iclreye)
|
|
{
|
|
PlayEquipCostume.outfitId = icloth;
|
|
PlayEquipCostume.weaponId = iweapon;
|
|
PlayEquipCostume.hairColor = iclrhair;
|
|
PlayEquipCostume.topColor = iclrtop;
|
|
PlayEquipCostume.eyeColor = iclreye;
|
|
}
|
|
#endregion Costume
|
|
|
|
#region Area & Monster
|
|
public static dArea GetArea(int areastage)
|
|
{
|
|
if (areastage <= 100) return sysAreas[0];
|
|
|
|
int area = GetAreaNumber(areastage) - 1;
|
|
if (areastage >= sysAreas.Length)
|
|
return sysAreas[sysAreas.Length - 1];
|
|
else
|
|
return sysAreas[(area * 50 + areastage % 100) - 1];
|
|
}
|
|
|
|
public static int GetAreaNumber() => GetAreaNumber(PlayData.curStage);
|
|
public static int GetAreaNumber(int areastage) => areastage / 100;
|
|
|
|
public static string GetMonsterPath(int idx)
|
|
{
|
|
if (dicMonster.ContainsKey(idx))
|
|
return dicMonster[idx].path;
|
|
return "null";
|
|
}
|
|
|
|
public static int GetMonsterSpeed(int idx)
|
|
{
|
|
if (dicMonster.ContainsKey(idx))
|
|
return dicMonster[idx].speed;
|
|
return 0;
|
|
}
|
|
|
|
public static int GetMonsterGroup(int idx)
|
|
{
|
|
if (dicMonster.ContainsKey(idx))
|
|
return dicMonster[idx].group;
|
|
return 0;
|
|
}
|
|
|
|
public static dBg GetBg(int idx)
|
|
{
|
|
if (dicBg.ContainsKey(idx))
|
|
return dicBg[idx];
|
|
return dicBg[1];
|
|
}
|
|
|
|
public static string GetBgmPath(BGM bgm)
|
|
{
|
|
if (dicBgm.TryGetValue(bgm, out dBgm targetBgm)) return targetBgm.path;
|
|
else return "intro";
|
|
}
|
|
#endregion Area & Monster
|
|
|
|
#region Stage
|
|
public static bool ClearStage(bool bgonext)
|
|
{
|
|
bool stageClear = false;
|
|
bool bareachange = false;
|
|
if (PlayData.curStage > PlayData.clearStage)
|
|
{
|
|
PlayData.clearStage = PlayData.curStage;
|
|
stageClear = true;
|
|
SetPassProgress(eCondition.StageClear, PlayData.clearStage);
|
|
}
|
|
|
|
if (bgonext)
|
|
{
|
|
// 플레이 데이터의 스테이지 값은 (지역번호 * 100) + 스테이지 번호.
|
|
int iarea = PlayData.curStage / 100;
|
|
int istage = PlayData.curStage % 100;
|
|
if (istage < Const.stageMax)
|
|
{
|
|
PlayData.curStage++;
|
|
}
|
|
else if (iarea < sysAreas.Length)
|
|
{
|
|
bareachange = true;
|
|
iarea++;
|
|
PlayData.curStage = iarea * 100 + 1;
|
|
}
|
|
}
|
|
|
|
BattleMgr.SStageMoveSave(stageClear);
|
|
PlayData.Save();
|
|
return bareachange;
|
|
}
|
|
|
|
public static void FailStage()
|
|
{
|
|
// 플레이 데이터의 스테이지 값은 (지역번호 * 100) + 스테이지 번호.
|
|
int iarea = PlayData.curStage / 100;
|
|
int istage = PlayData.curStage % 100;
|
|
if (istage > 1)
|
|
{
|
|
PlayData.curStage--;
|
|
}
|
|
else if (iarea > 1)
|
|
{
|
|
iarea--;
|
|
PlayData.curStage = iarea * 100 + Const.stageMax;
|
|
}
|
|
PlayData.Save();
|
|
}
|
|
|
|
public static void GoToStage(int iarea, int istage)
|
|
{
|
|
if (iarea > sysAreas.Length)
|
|
iarea = sysAreas.Length;
|
|
if (istage > Const.stageMax)
|
|
istage = Const.stageMax;
|
|
|
|
int iareastage = iarea * 100 + istage;
|
|
int imaxareastage = SettingMgr.SGetTest() ? iareastage : GetMaxStage();
|
|
if (iareastage <= imaxareastage)
|
|
PlayData.curStage = iareastage;
|
|
else
|
|
PlayData.curStage = imaxareastage;
|
|
PlayData.Save();
|
|
}
|
|
|
|
// 플레이 가능한 스테이지인지.
|
|
public static bool IsAvailStage(int iareastage)
|
|
{
|
|
return iareastage <= GetMaxStage();
|
|
}
|
|
|
|
// 클리어한 스테이지인지.
|
|
public static bool IsClearStage(int iareastage)
|
|
{
|
|
return iareastage <= PlayData.clearStage;
|
|
}
|
|
|
|
// 플레이 가능한 최고 스테이지.
|
|
public static int GetMaxStage()
|
|
{
|
|
// 플레이 데이터의 스테이지 값은 (지역번호 * 100) + 스테이지 번호.
|
|
int iarea = PlayData.clearStage / 100;
|
|
int istage = PlayData.clearStage % 100;
|
|
|
|
if (istage < Const.stageMax)
|
|
return PlayData.clearStage + 1;
|
|
if (iarea < sysAreas.Length)
|
|
return (iarea + 1) * 100 + 1;
|
|
return PlayData.clearStage;
|
|
}
|
|
#endregion Stage
|
|
|
|
#region Player Level
|
|
public static BigInteger CalcCharLvUpPriceAccum1(int curlevel, int addlevel, double buyingCntInc, BigInteger buyingCnt)
|
|
{
|
|
if (addlevel < 1) return buyingCnt;
|
|
double targetlv = curlevel + addlevel - 1d;
|
|
targetlv = System.Math.Pow(buyingCntInc, targetlv) - 1d;
|
|
double curlv = curlevel - 1d;
|
|
curlv = System.Math.Pow(buyingCntInc, curlv) - 1d;
|
|
targetlv -= curlv;
|
|
targetlv *= buyingCntInc;
|
|
targetlv /= (buyingCntInc - 1d);
|
|
|
|
return buyingCnt * (BigInteger)(targetlv * 100) / 100;
|
|
}
|
|
|
|
public static float GetPlayerExpRate()
|
|
{
|
|
if (PlayData == null)
|
|
return 0f;
|
|
|
|
int imaxlv = Const.playerMaxLv;
|
|
int iplayerLv = PlayData.playerLv;
|
|
|
|
BigInteger bimaxExp = CalcCharLvUpPriceAccum1(PlayData.playerLv % 1000, 1, (double)Const.playerLvExpInc / dConst.RateMax, DataHandler.PlayerLevelInterval(PlayData.playerLv));
|
|
|
|
if ((iplayerLv == imaxlv && PlayData.playerExp >= bimaxExp) || iplayerLv > imaxlv)
|
|
return 1f;
|
|
|
|
BigInteger birate = PlayData.playerExp * dConst.RateMax / bimaxExp;
|
|
return (float)birate / dConst.RateMaxFloat;
|
|
}
|
|
|
|
public static bool AddPlayerExp(BigInteger iaddexp)
|
|
{
|
|
if (PlayData == null)
|
|
return false;
|
|
|
|
// 최대 레벨이며 경험치 가득 찼을 경우.
|
|
int imaxlv = Const.playerMaxLv;
|
|
int iplayerLv = PlayData.playerLv;
|
|
|
|
BigInteger bimaxExp = CalcCharLvUpPriceAccum1(PlayData.playerLv % 1000, 1, (double)Const.playerLvExpInc / dConst.RateMax, DataHandler.PlayerLevelInterval(PlayData.playerLv));
|
|
|
|
if ((iplayerLv == imaxlv && PlayData.playerExp >= bimaxExp) || iplayerLv > imaxlv)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 현재 레벨부터 최대 레벨 직전 레벨까지.
|
|
int ilvpointadd = 0;
|
|
BigInteger ibefexp = PlayData.playerExp;
|
|
for (int i = iplayerLv - 1; i <= imaxlv; i++)
|
|
{
|
|
BigInteger isubexp = bimaxExp - ibefexp - iaddexp;
|
|
// 레벨업을 못할 경우.
|
|
if (isubexp > 0)
|
|
{
|
|
PlayData.playerExp = ibefexp + iaddexp;
|
|
if (ilvpointadd > 0)
|
|
{
|
|
AddLvPoint(ilvpointadd);
|
|
PlayData.Save();
|
|
}
|
|
|
|
EnhanceMgr.RefreshPlayerExpInfo();
|
|
return ilvpointadd > 0;
|
|
}
|
|
|
|
// 최대 레벨일 경우.
|
|
if (i == imaxlv)
|
|
{
|
|
PlayData.playerExp = bimaxExp;
|
|
if (ilvpointadd > 0)
|
|
{
|
|
AddLvPoint(ilvpointadd);
|
|
PlayData.Save();
|
|
}
|
|
|
|
EnhanceMgr.RefreshPlayerExpInfo();
|
|
return ilvpointadd > 0;
|
|
}
|
|
|
|
// 레벨업 할 경우.
|
|
PlayData.playerLv++;
|
|
// 포인트는 현재 상수로 1씩
|
|
ilvpointadd += 1;
|
|
iaddexp = iaddexp - (bimaxExp - ibefexp);
|
|
ibefexp = 0;
|
|
|
|
SetPassProgress(eCondition.PlayerLv, PlayData.playerLv);
|
|
EnhanceMgr.RefreshPlayerExpInfo();
|
|
BattleMgr.LevelUpEffectOn();
|
|
EnhanceMgr.levelUpScrolRefresh();
|
|
|
|
bimaxExp = CalcCharLvUpPriceAccum1(PlayData.playerLv % 1000, 1, (double)Const.playerLvExpInc / dConst.RateMax, DataHandler.PlayerLevelInterval(PlayData.playerLv));
|
|
|
|
CheckSkillsOpen();
|
|
}
|
|
|
|
if (ilvpointadd > 0)
|
|
{
|
|
AddLvPoint(ilvpointadd);
|
|
PlayData.Save();
|
|
}
|
|
return ilvpointadd > 0;
|
|
}
|
|
#endregion Player Level
|
|
|
|
#region Char Stats
|
|
public static void LoadCharStatsEnhanceGoldData(nIdLv[] playdatas)
|
|
{
|
|
for (int i = 0; i < playdatas.Length; ++i)
|
|
{
|
|
if (dicCharStatEnhanceGold.TryGetValue(playdatas[i].sid, out dCharStat charStat))
|
|
{
|
|
charStat.level = playdatas[i].lv;
|
|
|
|
// 해금 조건이 없거나, 있는데 해금 조건을 만족했을 경우.
|
|
if (charStat.condType == 0 || GetCharStatLevel(charStat.condType) >= charStat.condValue)
|
|
{
|
|
BuffMgr.Instance.ChangeCharStat(charStat.abilityType, charStat.abilityValue + (charStat.abilityValueInc * charStat.level), false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Dictionary<int, dCharStat> GetCharStats()
|
|
{
|
|
return dicCharStatEnhanceGold;
|
|
}
|
|
|
|
public static dCharStat GetCharStat(int key)
|
|
{
|
|
if (dicCharStatEnhanceGold.ContainsKey(key))
|
|
return dicCharStatEnhanceGold[key];
|
|
return null;
|
|
}
|
|
|
|
public static int GetCharStatLevel(int key)
|
|
{
|
|
if (dicCharStatEnhanceGold.ContainsKey(key))
|
|
return dicCharStatEnhanceGold[key].level;
|
|
return 0;
|
|
}
|
|
|
|
public static int GetCharStatUnlockID(eEffectType unlockType)
|
|
{
|
|
int condKey = 1;
|
|
|
|
switch (unlockType)
|
|
{
|
|
case eEffectType.None:
|
|
condKey = 1;
|
|
break;
|
|
case eEffectType.AtkBase:
|
|
condKey = 1;
|
|
break;
|
|
case eEffectType.HpBase:
|
|
condKey = 2;
|
|
break;
|
|
case eEffectType.CrtRate:
|
|
condKey = 3;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return condKey;
|
|
}
|
|
|
|
public static bool LvUpCharStatMulti(int key, int ilevel, int cost, int nextStat)
|
|
{
|
|
if (!dicCharStatEnhanceGold.ContainsKey(key))
|
|
return false;
|
|
|
|
int iprice = cost;
|
|
if (iprice > Goods.gold)
|
|
return false;
|
|
|
|
SubGold(cost);
|
|
dicCharStatEnhanceGold[key].level = ilevel;
|
|
//BuffMgr.Instance.ChangeCharStat(dicCharStat[key].abilityType, dicCharStat[key].abilityValue + (dicCharStat[key].abilityValueInc * ilevel));
|
|
BuffMgr.Instance.ChangeCharStat(dicCharStatEnhanceGold[key].abilityType, nextStat, true);
|
|
|
|
return true;
|
|
}
|
|
|
|
public static void LvUpCharStatServer(int key, int ilevel, BigInteger biprice, int nextStat)
|
|
{
|
|
if (!dicCharStatEnhanceGold.ContainsKey(key)) return;
|
|
|
|
SubGold(biprice);
|
|
dicCharStatEnhanceGold[key].level = ilevel;
|
|
BuffMgr.Instance.ChangeCharStat(dicCharStatEnhanceGold[key].abilityType, nextStat, true);
|
|
}
|
|
#endregion Char Stats
|
|
|
|
#region Char LvPoints
|
|
public static void LoadCharStatsEnhancePointData(nIdLv[] playdatas)
|
|
{
|
|
for (int i = 0; i < playdatas.Length; ++i)
|
|
{
|
|
nIdLv idlv = playdatas[i];
|
|
if (dicCharStatEnhancePoint.TryGetValue(idlv.sid, out dCharStat targetStat))
|
|
{
|
|
targetStat.level = idlv.lv;
|
|
if (PlayData.playerLv >= targetStat.condValue)
|
|
{
|
|
BuffMgr.Instance.ChangeCharLvPoint(targetStat.abilityType, targetStat.abilityValue + (targetStat.abilityValueInc * targetStat.level), false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Dictionary<int, dCharStat> GetCharLvPoints()
|
|
{
|
|
return dicCharStatEnhancePoint;
|
|
}
|
|
|
|
public static dCharStat GetCharLvPoint(int key) => dicCharStatEnhancePoint.SafeGet(key);
|
|
|
|
public static int GetCharLvPointLevel(int key)
|
|
{
|
|
if (dicCharStatEnhancePoint.ContainsKey(key))
|
|
return dicCharStatEnhancePoint[key].level;
|
|
return 0;
|
|
}
|
|
|
|
public static bool LvUpCharLvPointMulti(int key, int ilevel, int cost, int nextStat)
|
|
{
|
|
if (!dicCharStatEnhancePoint.ContainsKey(key))
|
|
return false;
|
|
|
|
int iprice = cost;
|
|
if (iprice > Goods.point)
|
|
return false;
|
|
|
|
SubLvPoint(iprice);
|
|
dicCharStatEnhancePoint[key].level = ilevel;
|
|
//BuffMgr.Instance.ChangeCharLvPoint(dicCharLvPoint[key].abilityType, dicCharLvPoint[key].abilityValue + (dicCharLvPoint[key].abilityValueInc * ilevel));
|
|
BuffMgr.Instance.ChangeCharLvPoint(dicCharStatEnhancePoint[key].abilityType, nextStat, true);
|
|
|
|
return true;
|
|
}
|
|
|
|
public static void LvUpCharPointServer(int key, int ilevel, int iprice, int nextStat)
|
|
{
|
|
if (!dicCharStatEnhancePoint.ContainsKey(key))
|
|
return;
|
|
|
|
//SubLvPoint(iprice);
|
|
dicCharStatEnhancePoint[key].level = ilevel;
|
|
BuffMgr.Instance.ChangeCharLvPoint(dicCharStatEnhancePoint[key].abilityType, nextStat, true);
|
|
}
|
|
|
|
public static void AllResetLvPoint()
|
|
{
|
|
foreach (var item in dicCharStatEnhancePoint)
|
|
{
|
|
dicCharStatEnhancePoint[item.Key].level = 1;
|
|
|
|
}
|
|
|
|
}
|
|
#endregion Char LvPoints
|
|
|
|
#region DungeonInfo
|
|
public static dSysGuardian GetSysGuardian(int type)
|
|
{
|
|
return sysGuardian[type];
|
|
}
|
|
#endregion
|
|
|
|
#region DungeonClear
|
|
public static void LoadAwakenDungeonData(cPlayerDungeonInfo data)
|
|
{
|
|
PlayDgAwaken = data;
|
|
if (data.lv != 1)
|
|
BuffMgr.Instance.ChangeAwakenDungeonStat(data.lv - 1);
|
|
}
|
|
#endregion
|
|
|
|
#region Awaken
|
|
public static void LoadAwakenData(cAwakenData data)
|
|
{
|
|
var localdata = cAwakenData.Load(data);
|
|
PlayAwaken = data;
|
|
data.OnAfterDeserialize();
|
|
PlayAwaken.usePreset = localdata.usePreset;
|
|
PlayAwaken.awakenUnlock = localdata.awakenUnlock;
|
|
EnhanceMgr.StartSetAwakenPreset();
|
|
}
|
|
|
|
public static void SetServerAwakenSlot(cAwakenData data, int preset)
|
|
{
|
|
PlayAwaken = data;
|
|
PlayAwaken.usePreset = preset;
|
|
}
|
|
|
|
public static void AwakenSlotUnlock(int key)
|
|
{
|
|
EnhanceMgr.Instance.SetSelected(key);
|
|
EnhanceMgr.Instance.UnlockSlot(key);
|
|
}
|
|
|
|
public static void btnAwakenPresetSet(int preset, bool isSave)
|
|
{
|
|
PlayAwaken.usePreset = preset;
|
|
if (isSave)
|
|
{
|
|
PlayAwaken.Save();
|
|
}
|
|
}
|
|
|
|
public static Dictionary<int, cPlayGuardian> GetPlayGuardians()
|
|
{
|
|
return PlayGuardian;
|
|
}
|
|
|
|
public static cPlayGuardian GetPlayGuardian(int i)
|
|
{
|
|
if (!PlayGuardian.ContainsKey(i))
|
|
{
|
|
return null;
|
|
}
|
|
return PlayGuardian[i];
|
|
}
|
|
|
|
public static void SetPlayGuardian(int type, cPlayGuardian data)
|
|
{
|
|
PlayGuardian[type] = data;
|
|
}
|
|
|
|
public static void SetPlayGuardianExtra(int type, int[] extra)
|
|
{
|
|
PlayGuardian[type].extras = extra;
|
|
}
|
|
#endregion
|
|
|
|
#region MaskRelic
|
|
public static IList<dSysRelic> GetSysRelicGroup(int relicType)
|
|
{
|
|
return sysRelicsGroupedByType[relicType];
|
|
}
|
|
|
|
public static cPlayRelic GetPlayRelic(int relicType)
|
|
{
|
|
return PlayRelic[relicType];
|
|
}
|
|
|
|
public static void SetPlayRelic(int tab, cPlayRelic saveRelic)
|
|
{
|
|
PlayRelic[tab] = saveRelic;
|
|
}
|
|
|
|
public static bool LvUpRelicEnhance(int key)
|
|
{
|
|
if (!PlayRelic.ContainsKey(key))
|
|
return false;
|
|
|
|
int iprop = GetRelicEnhanceProp(PlayRelic[key].ancientLv);
|
|
if (Random.Range(0, dConst.RateMax) >= iprop)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public static int GetRelicEnhanceProp(int ilevel)
|
|
{
|
|
int imaxindex = sysRelicEnhancePropLvs.Length - 1;
|
|
if (ilevel >= sysRelicEnhancePropLvs[imaxindex])
|
|
return sysRelicEnhanceProp[imaxindex];
|
|
|
|
for (int i = 1; i <= imaxindex; i++)
|
|
{
|
|
if (ilevel < sysRelicEnhancePropLvs[i])
|
|
return sysRelicEnhanceProp[i - 1];
|
|
}
|
|
return 0;
|
|
}
|
|
#endregion
|
|
|
|
#region Extra Ability
|
|
public static void LoadExtraAbility(dExtraRarity[] rates, dExtraAbility[] abilities)
|
|
{
|
|
extraRarityRates = new int[rates.Length];
|
|
extraAbilityIds = new Dictionary<eEffectType, int>[rates.Length];
|
|
extraAbilities = new Dictionary<int, dExtraAbility>();
|
|
|
|
for (int i = 0; i < rates.Length; i++)
|
|
{
|
|
extraAbilityIds[i] = new Dictionary<eEffectType, int>();
|
|
extraRarityRates[i] = rates[i].prop;
|
|
}
|
|
|
|
for (int i = 0; i < abilities.Length; i++)
|
|
{
|
|
int key = abilities[i].id;
|
|
extraAbilities.SafeInsert(new KeyValuePair<int, dExtraAbility>(key, abilities[i]));
|
|
|
|
eEffectType type = abilities[i].abilityType;
|
|
if (extraAbilityIds[0].ContainsKey(type))
|
|
{
|
|
extraAbilityIds[abilities[i].rarity - 1][type] = key;
|
|
}
|
|
else
|
|
{
|
|
for (int j = 0; j < rates.Length; j++)
|
|
{
|
|
extraAbilityIds[j].Add(type, key);
|
|
}
|
|
}
|
|
}
|
|
|
|
BuffMgr.Instance.InitExtra();
|
|
}
|
|
|
|
// 희귀도별 확률.
|
|
public static int GetExtraRarityRate(int irarity)
|
|
{
|
|
if (irarity <= 0 || irarity > cGoods.RMyth)
|
|
return 0;
|
|
return extraRarityRates[irarity - 1];
|
|
}
|
|
|
|
// 전체 희귀도 효과 값.
|
|
public static Dictionary<eEffectType, int>[] GetExtraAbilityIds()
|
|
{
|
|
return extraAbilityIds;
|
|
}
|
|
|
|
// 희귀도별 효과 정보.
|
|
public static dExtraAbility GetExtraAbility(int key)
|
|
{
|
|
if (extraAbilities.ContainsKey(key))
|
|
return extraAbilities[key];
|
|
return null;
|
|
}
|
|
|
|
// 희귀도별 효과 정보.
|
|
public static dExtraAbility GetExtraAbilityByType(int irarity, eEffectType type)
|
|
{
|
|
if (irarity <= 0 || irarity > cGoods.RMyth)
|
|
return null;
|
|
if (!extraAbilityIds[irarity - 1].ContainsKey(type))
|
|
return null;
|
|
int key = extraAbilityIds[irarity - 1][type];
|
|
return extraAbilities[key];
|
|
}
|
|
|
|
// 희귀도별 효과 값.
|
|
public static int GetExtraAbilityValue(int key)
|
|
{
|
|
if (extraAbilities.ContainsKey(key))
|
|
return extraAbilities[key].abilityValue;
|
|
return 0;
|
|
}
|
|
|
|
// 희귀도별 효과 값.
|
|
public static int GetExtraAbilityValueByType(int irarity, eEffectType type)
|
|
{
|
|
if (irarity <= 0 || irarity > cGoods.RMyth)
|
|
return 0;
|
|
if (!extraAbilityIds[irarity - 1].ContainsKey(type))
|
|
return 0;
|
|
int key = extraAbilityIds[irarity - 1][type];
|
|
return extraAbilities[key].abilityValue;
|
|
}
|
|
#endregion Extra Ability
|
|
|
|
#region Bag - Equip
|
|
static void LoadSysGearEquipment(int equipmentType, dGear[] datas)
|
|
{
|
|
if (!dicGearEquipment.TryGetValue(equipmentType, out Dictionary<int, dGear> targetDic)) return;
|
|
|
|
int ilastid = 1;
|
|
int irarity = cGoods.RMyth;
|
|
int igrade = 0;
|
|
|
|
for (int i = 0; i < datas.Length; ++i)
|
|
{
|
|
dGear gear = datas[i];
|
|
targetDic.SafeInsert(gear.id, gear);
|
|
|
|
if ((irarity < gear.rarity) || (irarity == gear.rarity && igrade < gear.grade))
|
|
{
|
|
ilastid = gear.id;
|
|
irarity = gear.rarity;
|
|
igrade = gear.grade;
|
|
}
|
|
}
|
|
|
|
if(dicGearLast.ContainsKey(equipmentType))
|
|
{
|
|
dicGearLast[equipmentType] = ilastid;
|
|
}
|
|
}
|
|
|
|
static void LoadPlayGearEquipment(int equipmentType, nIdLvInfo[] datas)
|
|
{
|
|
if (!dicGearEquipment.TryGetValue(equipmentType, out Dictionary<int, dGear> targetDic)) return;
|
|
|
|
int totalLevelOfPossession = 0;
|
|
int ilastid = -1;
|
|
int irarity = cGoods.RNone;
|
|
int igrade = 0;
|
|
for (int i = 0; i < datas.Length; i++)
|
|
{
|
|
nIdLvInfo lvInfo = datas[i];
|
|
if (!targetDic.TryGetValue(lvInfo.sid, out dGear targetGear)) continue;
|
|
|
|
targetGear.have = lvInfo.have;
|
|
targetGear.count = lvInfo.cnt;
|
|
targetGear.awaken = lvInfo.awaken;
|
|
targetGear.level = lvInfo.lv;
|
|
targetGear.extraEffects = targetGear.maxAwaken > 1 ? lvInfo.extras : null;
|
|
|
|
if (targetGear.have)
|
|
{
|
|
totalLevelOfPossession += targetGear.level;
|
|
if ((irarity < targetGear.rarity) || (irarity == targetGear.rarity && igrade < targetGear.grade))
|
|
{
|
|
ilastid = targetGear.id;
|
|
irarity = targetGear.rarity;
|
|
igrade = targetGear.grade;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dicGearLastHave.ContainsKey(equipmentType))
|
|
{
|
|
dicGearLastHave[equipmentType] = ilastid;
|
|
}
|
|
|
|
CalcGearLevelEffect(equipmentType, totalLevelOfPossession, false);
|
|
CalcGearEquipEffect(equipmentType);
|
|
CalcGearEquipExtra(equipmentType);
|
|
}
|
|
|
|
// 현재 장착중인 장비.
|
|
public static int GetEquipedGear(int itype)
|
|
{
|
|
switch (itype)
|
|
{
|
|
case cGoods.TBagWeapon:
|
|
return PlayData.weapon;
|
|
case cGoods.TBagArmorCape:
|
|
return PlayData.cape;
|
|
case cGoods.TBagArmorHat:
|
|
return PlayData.hat;
|
|
case cGoods.TBagArmorShoes:
|
|
return PlayData.shoes;
|
|
case cGoods.TBagAcceEar:
|
|
return PlayData.earring;
|
|
case cGoods.TBagAcceNeck:
|
|
return PlayData.necklace;
|
|
case cGoods.TBagAcceRing:
|
|
return PlayData.ring;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// 장비 장착.
|
|
public static bool EquipGear(int itype, int key)
|
|
{
|
|
if (!dicGearEquipment.TryGetValue(itype, out Dictionary<int, dGear> gears) ||
|
|
!gears.TryGetValue(key, out dGear targetGear) ||
|
|
!targetGear.have)
|
|
return false;
|
|
|
|
switch (itype)
|
|
{
|
|
case cGoods.TBagWeapon:
|
|
PlayData.weapon = key;
|
|
break;
|
|
case cGoods.TBagArmorCape:
|
|
PlayData.cape = key;
|
|
break;
|
|
case cGoods.TBagArmorHat:
|
|
PlayData.hat = key;
|
|
break;
|
|
case cGoods.TBagArmorShoes:
|
|
PlayData.shoes = key;
|
|
break;
|
|
case cGoods.TBagAcceEar:
|
|
PlayData.earring = key;
|
|
break;
|
|
case cGoods.TBagAcceNeck:
|
|
PlayData.necklace = key;
|
|
break;
|
|
case cGoods.TBagAcceRing:
|
|
PlayData.ring = key;
|
|
break;
|
|
}
|
|
|
|
PlayData.Save();
|
|
CalcGearEquipEffect(itype);
|
|
CalcGearEquipExtra(itype);
|
|
return true;
|
|
}
|
|
|
|
// 장비 플레이 정보 업데이트(합성 후 호출).
|
|
public static void UpdateGearEquipsPlay(int itype, nIdLvInfo[] datas)
|
|
{
|
|
int ilvadd = 0;
|
|
int ilastid = dicGearLastHave[itype];
|
|
int irarity = cGoods.RNone;
|
|
int igrade = 0;
|
|
if (ilastid >= 0)
|
|
{
|
|
irarity = dicGearEquipment[itype][ilastid].rarity;
|
|
igrade = dicGearEquipment[itype][ilastid].grade;
|
|
}
|
|
|
|
for (int i = 0; i < datas.Length; i++)
|
|
{
|
|
int key = datas[i].sid;
|
|
if (!dicGearEquipment[itype].ContainsKey(key))
|
|
continue;
|
|
if (!datas[i].have)
|
|
continue;
|
|
|
|
dGear data = dicGearEquipment[itype][key];
|
|
if (!data.have)
|
|
{
|
|
data.have = true;
|
|
ilvadd += datas[i].lv;
|
|
if ((irarity < data.rarity) || (irarity == data.rarity && igrade < data.grade))
|
|
{
|
|
ilastid = key;
|
|
irarity = data.rarity;
|
|
igrade = data.grade;
|
|
}
|
|
}
|
|
|
|
data.count = datas[i].cnt;
|
|
data.awaken = datas[i].awaken;
|
|
data.level = datas[i].lv;
|
|
if (data.maxAwaken > 1)
|
|
data.extraEffects = datas[i].extras;
|
|
}
|
|
dicGearLastHave[itype] = ilastid;
|
|
|
|
LoadCurGearHave();
|
|
// 레벨 효과 계산.
|
|
CalcGearLevelEffect(itype, ilvadd, false);
|
|
}
|
|
|
|
// 장비 최고 레벨.
|
|
public static int GetGearMaxLv(int itype, int key)
|
|
{
|
|
int index = dicGearEquipment[itype][key].awaken - 1;
|
|
if (index >= sysGearAwakens.Length)
|
|
index = sysGearAwakens.Length - 1;
|
|
else if (index < 0)
|
|
index = 0;
|
|
return sysGearAwakens[index].maxLv;
|
|
}
|
|
|
|
// 장비 각성 단계 정보.
|
|
public static dAwaken GetGearAwakenNext(int itype, int key)
|
|
{
|
|
int index = dicGearEquipment[itype][key].awaken;
|
|
if (index >= sysGearAwakens.Length)
|
|
index = sysGearAwakens.Length - 1;
|
|
else if (index < 0)
|
|
index = 0;
|
|
return sysGearAwakens[index];
|
|
}
|
|
|
|
// 장비 각성 필요 재료.
|
|
public static int[] GetGearAwakenNeeds(int itype, int key)
|
|
{
|
|
int[] ineeds = new int[3] { key, -1, -1 };
|
|
dGear gear = dicGearEquipment[itype][key];
|
|
|
|
int irarity1 = gear.rarity;
|
|
int igrade1 = gear.grade - 1;
|
|
if (igrade1 <= 0)
|
|
{
|
|
irarity1--;
|
|
igrade1 += cGoods.GMax;
|
|
}
|
|
|
|
int irarity2 = gear.rarity;
|
|
int igrade2 = gear.grade - 2;
|
|
if (igrade2 <= 0)
|
|
{
|
|
irarity2--;
|
|
igrade2 += cGoods.GMax;
|
|
}
|
|
|
|
foreach (var item in dicGearEquipment[itype])
|
|
{
|
|
if (item.Value.rarity == irarity1 && item.Value.grade == igrade1)
|
|
{
|
|
ineeds[1] = item.Key;
|
|
if (ineeds[2] >= 0)
|
|
break;
|
|
}
|
|
|
|
if (item.Value.rarity == irarity2 && item.Value.grade == igrade2)
|
|
{
|
|
ineeds[2] = item.Key;
|
|
if (ineeds[1] >= 0)
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ineeds;
|
|
}
|
|
|
|
// 장비 통합 레벨 효과 계산 및 적용.
|
|
private static bool CalcGearLevelEffect(int itype, int iaddlv, bool brecalc)
|
|
{
|
|
int prevlv = dicGearLv[itype];
|
|
dicGearLv[itype] += iaddlv;
|
|
int nextlv = dicGearLv[itype];
|
|
|
|
int prevefc = -1;
|
|
int nextefc = -1;
|
|
for (int i = sysGearLvEffects.Length - 1; i >= 0; i--)
|
|
{
|
|
if (nextefc < 0 && nextlv >= sysGearLvEffects[i].totalLv)
|
|
{
|
|
nextefc = i;
|
|
}
|
|
|
|
if (prevefc < 0 && prevlv >= sysGearLvEffects[i].totalLv)
|
|
{
|
|
prevefc = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 이전 효과와 다르고 적용 효과가 있을 경우.
|
|
if (nextefc != prevefc && nextefc >= 0)
|
|
{
|
|
BuffMgr.Instance.SetGearLv(itype, sysGearLvEffects[nextefc].value, true);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 장비 통합 레벨 정보.
|
|
/// </summary>
|
|
/// <param name="itype">장비 타입. cGoods.TBagX</param>
|
|
/// <returns>0:현재 통합 레벨, 1:현재 단계, 2:현재 단계 효과 값, 3:다음 단계 통합 레벨.</returns>
|
|
public static int[] GetGearTotalLevels(int itype)
|
|
{
|
|
int[] ilvs = new int[4];
|
|
ilvs[0] = dicGearLv[itype];
|
|
|
|
for (int i = sysGearLvEffects.Length - 1; i >= 0; i--)
|
|
{
|
|
if (ilvs[0] >= sysGearLvEffects[i].totalLv)
|
|
{
|
|
ilvs[1] = i + 1;
|
|
ilvs[2] = sysGearLvEffects[i].value;
|
|
if (i < (sysGearLvEffects.Length - 1))
|
|
ilvs[3] = sysGearLvEffects[i + 1].totalLv;
|
|
else
|
|
ilvs[3] = sysGearLvEffects[i].totalLv;
|
|
break;
|
|
}
|
|
}
|
|
return ilvs;
|
|
}
|
|
|
|
// 장비 장착 효과 계산 및 적용.
|
|
private static void CalcGearEquipEffect(int itype)
|
|
{
|
|
int key;
|
|
switch (itype)
|
|
{
|
|
case cGoods.TBagWeapon:
|
|
key = PlayData.weapon;
|
|
break;
|
|
case cGoods.TBagArmorCape:
|
|
key = PlayData.cape;
|
|
break;
|
|
case cGoods.TBagArmorHat:
|
|
key = PlayData.hat;
|
|
break;
|
|
case cGoods.TBagArmorShoes:
|
|
key = PlayData.shoes;
|
|
break;
|
|
case cGoods.TBagAcceEar:
|
|
key = PlayData.earring;
|
|
break;
|
|
case cGoods.TBagAcceNeck:
|
|
key = PlayData.necklace;
|
|
break;
|
|
case cGoods.TBagAcceRing:
|
|
key = PlayData.ring;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
if (key < 0)
|
|
return;
|
|
|
|
dGear gear = dicGearEquipment[itype][key];
|
|
if (gear.abilityType3 != eEffectType.None)
|
|
{
|
|
long ivalue = gear.abilityValue3 + ((gear.abilityValue3 * gear.abilityValueInc3 / dConst.RateDivideLong) * (gear.level - 1));//// (long)MathF.Pow(dConst.RateDivideInt2, gear.level); // (gear.level - 1) * gear.abilityValueInc3 + gear.abilityValue3;
|
|
BuffMgr.Instance.SetGearEquip(itype, gear.abilityType3, ivalue, false);
|
|
}
|
|
if (gear.abilityType2 != eEffectType.None)
|
|
{
|
|
long ivalue = gear.abilityValue2 + ((gear.abilityValue2 * gear.abilityValueInc2 / dConst.RateDivideLong) * (gear.level - 1));// (long)MathF.Pow(dConst.RateDivideInt2, gear.level);
|
|
BuffMgr.Instance.SetGearEquip(itype, gear.abilityType2, ivalue, false);
|
|
}
|
|
if (gear.abilityType1 != eEffectType.None)
|
|
{
|
|
long ivalue = gear.abilityValue1 + ((gear.abilityValue1 * gear.abilityValueInc1 / dConst.RateDivideLong) * (gear.level - 1));// (long)MathF.Pow(dConst.RateDivideInt2, gear.level);
|
|
BuffMgr.Instance.SetGearEquip(itype, gear.abilityType1, ivalue, true);
|
|
}
|
|
}
|
|
|
|
// 장비 추가 효과 계산 및 적용.
|
|
public static void CalcGearEquipExtra(int itype)
|
|
{
|
|
int key;
|
|
switch (itype)
|
|
{
|
|
case cGoods.TBagWeapon:
|
|
key = PlayData.weapon;
|
|
break;
|
|
case cGoods.TBagArmorCape:
|
|
key = PlayData.cape;
|
|
break;
|
|
case cGoods.TBagArmorHat:
|
|
key = PlayData.hat;
|
|
break;
|
|
case cGoods.TBagArmorShoes:
|
|
key = PlayData.shoes;
|
|
break;
|
|
case cGoods.TBagAcceEar:
|
|
key = PlayData.earring;
|
|
break;
|
|
case cGoods.TBagAcceNeck:
|
|
key = PlayData.necklace;
|
|
break;
|
|
case cGoods.TBagAcceRing:
|
|
key = PlayData.ring;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
if (key < 0)
|
|
return;
|
|
|
|
dGear gear = dicGearEquipment[itype][key];
|
|
if (gear.awaken <= 1 || gear.extraEffects == null)
|
|
{
|
|
BuffMgr.Instance.SetGearExtra(itype, 2, eEffectType.None, 0L, false);
|
|
BuffMgr.Instance.SetGearExtra(itype, 1, eEffectType.None, 0L, false);
|
|
BuffMgr.Instance.SetGearExtra(itype, 0, eEffectType.None, 0L, true);
|
|
return;
|
|
}
|
|
|
|
int[] extras = gear.extraEffects;
|
|
for (int i = extras.Length - 1; i >= 0; i--)
|
|
{
|
|
if (extras[i] < 0)
|
|
{
|
|
BuffMgr.Instance.SetGearExtra(itype, i, eEffectType.None, 0L, i == 0);
|
|
}
|
|
else
|
|
{
|
|
dExtraAbility ability = GetExtraAbility(extras[i]);
|
|
BuffMgr.Instance.SetGearExtra(itype, i, ability.abilityType, ability.abilityValue, i == 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Dictionary<int, dGear> GetGearEquips(int itype)
|
|
{
|
|
return dicGearEquipment[itype];
|
|
}
|
|
|
|
public static dGear GetGearEquip(int itype, int key)
|
|
{
|
|
if (dicGearEquipment[itype].ContainsKey(key))
|
|
return dicGearEquipment[itype][key];
|
|
return null;
|
|
}
|
|
|
|
public static int GetGearEquipByGrade(int itype, int irarity, int igrade)
|
|
{
|
|
Dictionary<int, dGear> datas = dicGearEquipment[itype];
|
|
foreach (var item in datas)
|
|
{
|
|
if (item.Value.rarity == irarity && item.Value.grade == igrade)
|
|
return item.Key;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
public static int GetGearEquipLast(int itype)
|
|
{
|
|
return dicGearLast[itype];
|
|
}
|
|
|
|
public static int GetGearEquipRarity(int itype, int key)
|
|
{
|
|
if (dicGearEquipment[itype].ContainsKey(key))
|
|
return dicGearEquipment[itype][key].rarity;
|
|
return 0;
|
|
}
|
|
|
|
public static bool AddGearEquip(int itype, int key, int icount)
|
|
{
|
|
if (!dicGearEquipment[itype].ContainsKey(key))
|
|
return false;
|
|
|
|
if (dicGearEquipment[itype][key].have)
|
|
{
|
|
dicGearEquipment[itype][key].count += icount;
|
|
return false;
|
|
}
|
|
|
|
dGear data = dicGearEquipment[itype][key];
|
|
data.have = true;
|
|
data.level = 1;
|
|
data.awaken = 1;
|
|
data.count = icount - 1;
|
|
addHaveGear(itype, data.rarity);
|
|
if (data.maxAwaken > 1)
|
|
data.extraEffects = new int[3] { -1, -1, -1 };
|
|
dicGearNew[itype].Add(key);
|
|
|
|
if (dicGearLastHave[itype] < 0)
|
|
{
|
|
dicGearLastHave[itype] = data.id;
|
|
}
|
|
else
|
|
{
|
|
dGear datalasthave = dicGearEquipment[itype][dicGearLastHave[itype]];
|
|
if ((datalasthave.rarity < data.rarity) || (datalasthave.rarity == data.rarity && datalasthave.grade < data.grade))
|
|
dicGearLastHave[itype] = data.id;
|
|
}
|
|
|
|
CalcGearLevelEffect(itype, 1, false);
|
|
return true;
|
|
}
|
|
|
|
public static bool SubGearEquip(int itype, int key, int icount)
|
|
{
|
|
if (!dicGearEquipment[itype].ContainsKey(key))
|
|
return false;
|
|
|
|
if (dicGearEquipment[itype][key].count < icount)
|
|
return false;
|
|
|
|
dGear data = dicGearEquipment[itype][key];
|
|
data.count -= icount;
|
|
return true;
|
|
}
|
|
|
|
public static int GetGearLastHaveId(int itype)
|
|
{
|
|
return dicGearLastHave[itype];
|
|
}
|
|
|
|
public static bool IsGearComposable(int itype)
|
|
{
|
|
foreach (var item in dicGearEquipment[itype])
|
|
{
|
|
if (item.Value.count >= Const.gearComposePrice)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static bool IsGearNewHave(int itype)
|
|
{
|
|
return dicGearNew[itype].Count > 0;
|
|
}
|
|
|
|
public static bool IsGearNew(int itype, int key)
|
|
{
|
|
//addHaveGear(itype, GetGearEquip(itype,key).rarity);
|
|
return dicGearNew[itype].Contains(key);
|
|
}
|
|
|
|
public static bool RemoveGearNew(int itype, int key)
|
|
{
|
|
return dicGearNew[itype].Remove(key);
|
|
}
|
|
|
|
public static void LvUpGearEquip(int itype, int key, int ilevel, bool bcalcstat)
|
|
{
|
|
dGear data = dicGearEquipment[itype][key];
|
|
int iaddlevel = ilevel - data.level;
|
|
data.level = ilevel;
|
|
|
|
CalcGearLevelEffect(itype, iaddlevel, bcalcstat);
|
|
if (bcalcstat && key == GetEquipedGear(itype))
|
|
CalcGearEquipEffect(itype);
|
|
}
|
|
|
|
public static void ChangeGearExtras(int itype, int key, int[] extras)
|
|
{
|
|
dicGearEquipment[itype][key].extraEffects = extras;
|
|
}
|
|
|
|
public static void LoadCurGearHave()
|
|
{
|
|
for (int i = 0; i < GetGearEquips(cGoods.TBagWeapon).Count; i++)
|
|
{
|
|
if (GetGearEquip(cGoods.TBagWeapon, i + 1).have)
|
|
addHaveGear(cGoods.TBagWeapon, GetGearEquip(cGoods.TBagWeapon, i + 1).rarity);
|
|
}
|
|
for (int i = 0; i < GetGearEquips(cGoods.TBagArmorCape).Count; i++)
|
|
{
|
|
if (GetGearEquip(cGoods.TBagArmorCape, i + 1).have)
|
|
addHaveGear(cGoods.TBagArmorCape, GetGearEquip(cGoods.TBagArmorCape, i + 1).rarity);
|
|
}
|
|
for (int i = 0; i < GetGearEquips(cGoods.TBagArmorHat).Count; i++)
|
|
{
|
|
if (GetGearEquip(cGoods.TBagArmorHat, i + 1).have)
|
|
addHaveGear(cGoods.TBagArmorHat, GetGearEquip(cGoods.TBagArmorHat, i + 1).rarity);
|
|
}
|
|
for (int i = 0; i < GetGearEquips(cGoods.TBagArmorShoes).Count; i++)
|
|
{
|
|
if (GetGearEquip(cGoods.TBagArmorShoes, i + 1).have)
|
|
addHaveGear(cGoods.TBagArmorShoes, GetGearEquip(cGoods.TBagArmorShoes, i + 1).rarity);
|
|
}
|
|
for (int i = 0; i < GetGearEquips(cGoods.TBagAcceEar).Count; i++)
|
|
{
|
|
if (GetGearEquip(cGoods.TBagAcceEar, i + 1).have)
|
|
addHaveGear(cGoods.TBagAcceEar, GetGearEquip(cGoods.TBagAcceEar, i + 1).rarity);
|
|
}
|
|
for (int i = 0; i < GetGearEquips(cGoods.TBagAcceNeck).Count; i++)
|
|
{
|
|
if (GetGearEquip(cGoods.TBagAcceNeck, i + 1).have)
|
|
addHaveGear(cGoods.TBagAcceNeck, GetGearEquip(cGoods.TBagAcceNeck, i + 1).rarity);
|
|
}
|
|
for (int i = 0; i < GetGearEquips(cGoods.TBagAcceRing).Count; i++)
|
|
{
|
|
if (GetGearEquip(cGoods.TBagAcceRing, i + 1).have)
|
|
addHaveGear(cGoods.TBagAcceRing, GetGearEquip(cGoods.TBagAcceRing, i + 1).rarity);
|
|
}
|
|
}
|
|
|
|
public static void addHaveGear(int type, int rarity)
|
|
{
|
|
switch (type)
|
|
{
|
|
case cGoods.TBagWeapon:
|
|
arrHaveWeapon[rarity - 1]++;
|
|
break;
|
|
case cGoods.TBagArmorCape:
|
|
arrHaveArmor[0, rarity - 1]++;
|
|
break;
|
|
case cGoods.TBagArmorHat:
|
|
arrHaveArmor[1, rarity - 1]++;
|
|
break;
|
|
case cGoods.TBagArmorShoes:
|
|
arrHaveArmor[2, rarity - 1]++;
|
|
break;
|
|
case cGoods.TBagAcceEar:
|
|
arrHaveAcc[0, rarity - 1]++;
|
|
break;
|
|
case cGoods.TBagAcceNeck:
|
|
arrHaveAcc[1, rarity - 1]++;
|
|
break;
|
|
case cGoods.TBagAcceRing:
|
|
arrHaveAcc[2, rarity - 1]++;
|
|
break;
|
|
}
|
|
}
|
|
#endregion Bag - Equip
|
|
|
|
#region Bag - Treasure
|
|
public static void LoadPlayGearTreasures(nIdLvInfo[] playdatas)
|
|
{
|
|
for (int i = 0; i < playdatas.Length; i++)
|
|
{
|
|
var lvInfo = playdatas[i];
|
|
if (!dicGearTreasure.TryGetValue(lvInfo.sid, out dTreasure treasure)) continue;
|
|
|
|
treasure.have = lvInfo.have;
|
|
treasure.count = lvInfo.cnt;
|
|
treasure.level = 0;
|
|
if (treasure.have)
|
|
{
|
|
treasure.level = lvInfo.lv;
|
|
BuffMgr.Instance.SetGearTreasure(treasure.abilityType, GetGearTreasureEffect(treasure.abilityValue, treasure.abilityValueInc, treasure.level), true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void UpdateGearTreasurePlay(nIdLvInfo trsdata)
|
|
{
|
|
dTreasure data = dicGearTreasure[trsdata.sid];
|
|
data.have = trsdata.have;
|
|
data.level = trsdata.lv;
|
|
data.count = trsdata.cnt;
|
|
BuffMgr.Instance.SetGearTreasure(data.abilityType, GetGearTreasureEffect(data.abilityValue, data.abilityValueInc, data.level), true);
|
|
}
|
|
|
|
public static void UpdateGearTreasure(int key, int ilevel, int icount)
|
|
{
|
|
dTreasure data = dicGearTreasure[key];
|
|
data.level = ilevel;
|
|
data.count = icount;
|
|
BuffMgr.Instance.SetGearTreasure(data.abilityType, GetGearTreasureEffect(data.abilityValue, data.abilityValueInc, data.level), true);
|
|
}
|
|
|
|
public static Dictionary<int, dTreasure> GetGearTreasures()
|
|
{
|
|
return dicGearTreasure;
|
|
}
|
|
|
|
public static dTreasure GetGearTreasure(int key)
|
|
{
|
|
if (dicGearTreasure.ContainsKey(key))
|
|
return dicGearTreasure[key];
|
|
return null;
|
|
}
|
|
|
|
public static bool AddGearTreasure(int key, int icount)
|
|
{
|
|
if (!dicGearTreasure.ContainsKey(key))
|
|
return false;
|
|
|
|
if (dicGearTreasure[key].have)
|
|
{
|
|
dicGearTreasure[key].count += icount;
|
|
return false;
|
|
}
|
|
|
|
dTreasure data = dicGearTreasure[key];
|
|
data.have = true;
|
|
data.level = 1;
|
|
data.count = icount - 1;
|
|
BuffMgr.Instance.SetGearTreasure(data.abilityType, GetGearTreasureEffect(data.abilityValue, data.abilityValueInc, data.level), true);
|
|
return true;
|
|
}
|
|
|
|
public static bool allTreasureMax()
|
|
{
|
|
dTreasure curTreasure = new dTreasure();
|
|
for (int i = 0; i < GetGearTreasures().Count; i++)
|
|
{
|
|
curTreasure = GetGearTreasure(i+1);
|
|
if (curTreasure.level != curTreasure.maxLv)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static bool LvUpGearTreasure(int key)
|
|
{
|
|
if (!dicGearTreasure.ContainsKey(key))
|
|
return false;
|
|
|
|
if (dicGearTreasure[key].count <= 0)
|
|
return false;
|
|
|
|
dicGearTreasure[key].count--;
|
|
int iprop = GetGearTreasureProp(dicGearTreasure[key].level);
|
|
if (Random.Range(0, dConst.RateMax) >= iprop)
|
|
return false;
|
|
|
|
dicGearTreasure[key].level++;
|
|
return true;
|
|
}
|
|
|
|
// 보물 효과.
|
|
public static long GetGearTreasureEffect(long ibase, long iinc, int ilevel)
|
|
{
|
|
if (ilevel <= 0)
|
|
return 0;
|
|
ilevel--;
|
|
return (ilevel * iinc) + ibase;
|
|
}
|
|
|
|
// 보물 레벨업 확률.
|
|
public static int GetGearTreasureProp(int ilevel)
|
|
{
|
|
int result = 0;
|
|
for (int i = gearTreasureLvUpLvBounds.Length - 1; i >= 0; --i)
|
|
{
|
|
if (ilevel >= gearTreasureLvUpLvBounds[i])
|
|
{
|
|
result = gearTreasureLvUpSuccRates[i];
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
#endregion Bag - Treasure
|
|
|
|
#region Skill
|
|
public static void LoadSkillsPlay(nIdLvInfo[] playpassives, nIdLvInfo[] playactives)
|
|
{
|
|
int iaddlv = 0;
|
|
for (int i = 0; i < playpassives.Length; ++i)
|
|
{
|
|
// 스킬 id가 존재하고 플레이어 레벨이 오픈 레벨 이상일 경우.
|
|
if (dicSkillPassive.TryGetValue(playactives[i].sid, out var skill) && PlayData.playerLv >= skill.openLv)
|
|
{
|
|
skill.level = playactives[i].lv;
|
|
iaddlv += skill.level;
|
|
|
|
long totalStat = skill.abilityValue + (skill.abilityValueInc * (skill.level - 1));
|
|
BuffMgr.Instance.ChangePassiveStat(skill.abilityType, totalStat, false);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < playactives.Length; ++i)
|
|
{
|
|
// 스킬 id가 존재하고 플레이어 레벨이 오픈 레벨 이상일 경우.
|
|
if (dicSkillActive.TryGetValue(playactives[i].sid, out var skill) && PlayData.playerLv >= skill.openLv)
|
|
{
|
|
skill.level = playactives[i].lv;
|
|
skill.awaken = playactives[i].awaken;
|
|
iaddlv += skill.level;
|
|
}
|
|
}
|
|
|
|
CalcSkillLevelEffect(iaddlv);
|
|
}
|
|
|
|
private static void CheckSkillsOpen()
|
|
{
|
|
foreach (var item in dicSkillPassive)
|
|
{
|
|
if (item.Value.level > 0)
|
|
continue;
|
|
if (PlayData.playerLv < item.Value.openLv)
|
|
continue;
|
|
item.Value.level = 1;
|
|
}
|
|
|
|
foreach (var item in dicSkillActive)
|
|
{
|
|
if (item.Value.level > 0)
|
|
continue;
|
|
if (PlayData.playerLv < item.Value.openLv)
|
|
continue;
|
|
item.Value.level = 1;
|
|
item.Value.awaken = 1;
|
|
}
|
|
}
|
|
|
|
// 스킬 각성 단계 정보.
|
|
public static dAwaken[] GetSkillAwakens()
|
|
{
|
|
return sysSkillAwakens;
|
|
}
|
|
|
|
// 스킬 최고 레벨.
|
|
public static int GetSkillMaxLv(int itype, int key)
|
|
{
|
|
if (itype == cGoods.TSkillPassive)
|
|
{
|
|
return dicSkillPassive[key].maxLv;
|
|
}
|
|
|
|
int index = dicSkillActive[key].awaken - 1;
|
|
if (index >= sysSkillAwakens.Length)
|
|
index = sysSkillAwakens.Length - 1;
|
|
else if (index < 0)
|
|
index = 0;
|
|
return sysSkillAwakens[index].maxLv;
|
|
}
|
|
|
|
// 스킬 각성 단계 정보.
|
|
public static dAwaken GetSkillAwakenNext(int itype, int key)
|
|
{
|
|
if (itype != cGoods.TSkillActive)
|
|
return null;
|
|
|
|
int index = dicSkillActive[key].awaken;
|
|
if (index >= sysSkillAwakens.Length)
|
|
index = sysSkillAwakens.Length - 1;
|
|
else if (index < 0)
|
|
index = 0;
|
|
return sysSkillAwakens[index];
|
|
}
|
|
|
|
// 스킬 각성 필요 재료. 같은 희귀도의 모자, 망토, 신발.
|
|
public static int[] GetSkillAwakenNeeds(int itype, int key)
|
|
{
|
|
if (itype != cGoods.TSkillActive)
|
|
return null;
|
|
|
|
int[] ineeds = new int[3];
|
|
int irarity = dicSkillActive[key].rarity;
|
|
int igrade = dicSkillActive[key].awaken + 1;
|
|
|
|
ineeds[0] = GetGearEquipByGrade(cGoods.TBagArmorHat, irarity, igrade);
|
|
ineeds[1] = GetGearEquipByGrade(cGoods.TBagArmorCape, irarity, igrade);
|
|
ineeds[2] = GetGearEquipByGrade(cGoods.TBagArmorShoes, irarity, igrade);
|
|
return ineeds;
|
|
}
|
|
|
|
// 스킬 통합 레벨 효과 계산 및 적용.
|
|
private static bool CalcSkillLevelEffect(int iaddlv)
|
|
{
|
|
int iprevlv = currentTotalSkillLv;
|
|
currentTotalSkillLv += iaddlv;
|
|
int inextlv = currentTotalSkillLv;
|
|
|
|
int iprevefc = -1;
|
|
int inextefc = -1;
|
|
for (int i = sysSkillLvEffects.Length - 1; i >= 0; i--)
|
|
{
|
|
if (inextefc < 0 && inextlv >= sysSkillLvEffects[i].totalLv)
|
|
{
|
|
inextefc = i;
|
|
}
|
|
if (iprevefc < 0 && iprevlv >= sysSkillLvEffects[i].totalLv)
|
|
{
|
|
iprevefc = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
BuffMgr.Instance.SetSkillLv(sysSkillLvEffects[inextefc].value);
|
|
|
|
// 이전 효과와 다르고 적용 효과가 있을 경우.
|
|
if (inextefc != iprevefc && inextefc >= 0)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 스킬 통합 레벨 정보.
|
|
/// </summary>
|
|
/// <returns>0:현재 통합 레벨, 1:현재 단계, 2:현재 단계 효과 값, 3:다음 단계 통합 레벨.</returns>
|
|
public static int[] GetSkillTotalLevels()
|
|
{
|
|
int[] ilvs = new int[4];
|
|
ilvs[0] = currentTotalSkillLv;
|
|
|
|
for (int i = sysSkillLvEffects.Length - 1; i >= 0; i--)
|
|
{
|
|
if (ilvs[0] >= sysSkillLvEffects[i].totalLv)
|
|
{
|
|
ilvs[1] = i + 1;
|
|
ilvs[2] = sysSkillLvEffects[i].value;
|
|
if (i < (sysSkillLvEffects.Length - 1))
|
|
ilvs[3] = sysSkillLvEffects[i + 1].totalLv;
|
|
else
|
|
ilvs[3] = sysSkillLvEffects[i].totalLv;
|
|
break;
|
|
}
|
|
}
|
|
return ilvs;
|
|
}
|
|
|
|
public static Dictionary<int, dSkillPassive> GetSkillPassives() => dicSkillPassive;
|
|
public static Dictionary<int, dSkillActive> GetSkillActives() => dicSkillActive;
|
|
public static dSkillPassive GetSkillPassive(int key) => dicSkillPassive.SafeGet(key);
|
|
public static dSkillActive GetSkillActive(int key) => dicSkillActive.SafeGet(key);
|
|
|
|
public static int GetSkillRarity(int itype, int key)
|
|
{
|
|
if (itype == cGoods.TSkillActive && dicSkillActive.ContainsKey(key))
|
|
return dicSkillActive[key].rarity;
|
|
if (itype == cGoods.TSkillPassive && dicSkillPassive.ContainsKey(key))
|
|
return dicSkillPassive[key].rarity;
|
|
return 0;
|
|
}
|
|
|
|
public static float GetSkillCool(int key)
|
|
{
|
|
if (!dicSkillActive.ContainsKey(key)) return 99f;
|
|
|
|
float reduceRate = 1f;
|
|
int currentAwakenLevel = dicSkillActive[key].awaken;
|
|
|
|
for (int i = 1; i < currentAwakenLevel; i++)
|
|
{
|
|
reduceRate -= sysSkillAwakens[i].coolTimeDec / dConst.RateMaxFloat;
|
|
}
|
|
|
|
reduceRate = UnityEngine.Mathf.Max(reduceRate, 0.1f);
|
|
|
|
return dicSkillActive[key].coolTime * reduceRate;
|
|
}
|
|
|
|
public static void LvUpSkill(int itype, int key, int ilevel)
|
|
{
|
|
// 액티브.
|
|
if (itype == cGoods.TSkillActive)
|
|
{
|
|
if (!dicSkillActive.ContainsKey(key))
|
|
return;
|
|
|
|
CalcSkillLevelEffect(ilevel - dicSkillActive[key].level);
|
|
dicSkillActive[key].level = ilevel;
|
|
return;
|
|
}
|
|
|
|
// 패시브.
|
|
if (!dicSkillPassive.ContainsKey(key))
|
|
return;
|
|
|
|
CalcSkillLevelEffect(ilevel - dicSkillPassive[key].level);
|
|
dicSkillPassive[key].level = ilevel;
|
|
|
|
long totalStat = dicSkillPassive[key].abilityValue + (dicSkillPassive[key].abilityValueInc * (dicSkillPassive[key].level - 1));
|
|
BuffMgr.Instance.ChangePassiveStat(dicSkillPassive[key].abilityType, totalStat, true);
|
|
}
|
|
|
|
public static void AwakenSkill(int itype, int key, int iawaken)
|
|
{
|
|
if (itype != cGoods.TSkillActive)
|
|
return;
|
|
|
|
// 액티브.
|
|
if (!dicSkillActive.ContainsKey(key))
|
|
return;
|
|
dicSkillActive[key].awaken = iawaken;
|
|
}
|
|
|
|
// 사용중인 프리셋 변경. 플레이 데이터 저장은 별도로 호출 필요.
|
|
public static void ChangeSkillPreset(int presetindex)
|
|
{
|
|
PlayData.usePreset = presetindex;
|
|
}
|
|
|
|
// 프리셋 변경. 플레이 데이터 저장은 별도로 호출 필요.
|
|
public static void EditSkillPreset(int presetindex, int islotindex, int iskillid)
|
|
{
|
|
PlayData.skillPresets[presetindex][islotindex] = iskillid;
|
|
}
|
|
#endregion Skill
|
|
|
|
#region Pet
|
|
public static void LoadPetsPlay(nIdLvInfo[] playpets)
|
|
{
|
|
int addlv = 0;
|
|
for (int i = 0; i < playpets.Length; ++i)
|
|
{
|
|
if (!dicPet.TryGetValue(playpets[i].sid, out var pet)) continue;
|
|
|
|
pet.have = playpets[i].have;
|
|
pet.awaken = playpets[i].awaken;
|
|
pet.level = playpets[i].lv;
|
|
pet.count = playpets[i].cnt;
|
|
if (pet.have)
|
|
addlv += pet.level;
|
|
if (pet.maxAwaken > 1)
|
|
pet.extraEffects = playpets[i].extras;
|
|
}
|
|
|
|
// 레벨 효과 계산.
|
|
CalcPetLevelEffect(addlv, false);
|
|
// 장착 & 추가 효과 계산.
|
|
CalcPetEquipExtra(PlayData.usePetPreset);
|
|
}
|
|
|
|
// 펫 플레이 정보 업데이트(스피릿 합성 후 호출).
|
|
public static void UpdatePetsPlay(nIdLvInfo[] datas)
|
|
{
|
|
int ilvadd = 0;
|
|
for (int i = 0; i < datas.Length; ++i)
|
|
{
|
|
if (!dicPet.TryGetValue(datas[i].sid, out dPet data)) continue;
|
|
|
|
data.count = datas[i].cnt;
|
|
|
|
if (datas[i].have)
|
|
{
|
|
if (!data.have)
|
|
{
|
|
data.have = true;
|
|
ilvadd += datas[i].lv;
|
|
}
|
|
|
|
data.awaken = datas[i].awaken;
|
|
data.level = datas[i].lv;
|
|
if (data.maxAwaken > 1)
|
|
data.extraEffects = datas[i].extras;
|
|
}
|
|
}
|
|
|
|
// 레벨 효과 계산.
|
|
CalcPetLevelEffect(ilvadd, false);
|
|
}
|
|
|
|
// 펫 각성 단계 정보.
|
|
public static dAwaken[] GetPetAwakens()
|
|
{
|
|
return sysPetAwakens;
|
|
}
|
|
|
|
// 펫 최고 레벨.
|
|
public static int GetPetMaxLv(int key)
|
|
{
|
|
int index = dicPet[key].awaken - 1;
|
|
if (index >= sysPetAwakens.Length)
|
|
index = sysPetAwakens.Length - 1;
|
|
else if (index < 0)
|
|
index = 0;
|
|
return sysPetAwakens[index].maxLv;
|
|
}
|
|
|
|
// 펫 각성 단계 정보.
|
|
public static dAwaken GetPetAwakenNext(int key)
|
|
{
|
|
int index = dicPet[key].awaken;
|
|
if (index >= sysPetAwakens.Length)
|
|
index = sysPetAwakens.Length - 1;
|
|
else if (index < 0)
|
|
index = 0;
|
|
return sysPetAwakens[index];
|
|
}
|
|
|
|
// 펫 통합 레벨 효과 계산 및 적용.
|
|
private static bool CalcPetLevelEffect(int iaddlv, bool brecalc)
|
|
{
|
|
int iprevlv = petLv;
|
|
petLv += iaddlv;
|
|
int inextlv = petLv;
|
|
|
|
int iprevefc = -1;
|
|
int inextefc = -1;
|
|
for (int i = sysPetLvEffects.Length - 1; i >= 0; i--)
|
|
{
|
|
if (inextefc < 0 && inextlv >= sysPetLvEffects[i].totalLv)
|
|
{
|
|
inextefc = i;
|
|
}
|
|
if (iprevefc < 0 && iprevlv >= sysPetLvEffects[i].totalLv)
|
|
{
|
|
iprevefc = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 이전 효과와 다르고 적용 효과가 있을 경우.
|
|
if (inextefc != iprevefc && inextefc >= 0)
|
|
{
|
|
BuffMgr.Instance.SetPetLv(sysPetLvEffects[inextefc].value, brecalc);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 펫 통합 레벨 정보.
|
|
/// </summary>
|
|
/// <returns>0:현재 통합 레벨, 1:현재 단계, 2:현재 단계 효과 값, 3:다음 단계 통합 레벨.</returns>
|
|
public static int[] GetPetTotalLevels()
|
|
{
|
|
int[] ilvs = new int[4];
|
|
ilvs[0] = petLv;
|
|
|
|
for (int i = sysPetLvEffects.Length - 1; i >= 0; i--)
|
|
{
|
|
if (ilvs[0] >= sysPetLvEffects[i].totalLv)
|
|
{
|
|
ilvs[1] = i + 1;
|
|
ilvs[2] = sysPetLvEffects[i].value;
|
|
if (i < (sysPetLvEffects.Length - 1))
|
|
ilvs[3] = sysPetLvEffects[i + 1].totalLv;
|
|
else
|
|
ilvs[3] = sysPetLvEffects[i].totalLv;
|
|
break;
|
|
}
|
|
}
|
|
return ilvs;
|
|
}
|
|
|
|
// 펫 장착 효과 계산 및 적용.
|
|
private static void CalcPetEffect(int presetindex, int slotindex, bool brecalc)
|
|
{
|
|
int key = PlayData.petPresets[presetindex][slotindex];
|
|
if (key < 0)
|
|
{
|
|
BuffMgr.Instance.SetPetEquip(slotindex, eEffectType.None, 0L, eEffectType.None, 0L, eEffectType.None, 0L, brecalc);
|
|
return;
|
|
}
|
|
|
|
dPet pet = dicPet[key];
|
|
int ilevel = pet.level - 1;
|
|
BuffMgr.Instance.SetPetEquip(slotindex, pet.abilityType1, ilevel * pet.abilityValueInc1 + pet.abilityValue1,
|
|
pet.abilityType2, ilevel * pet.abilityValueInc2 + pet.abilityValue2, pet.abilityType3, ilevel * pet.abilityValueInc3 + pet.abilityValue3, brecalc);
|
|
}
|
|
|
|
// 펫 추가 효과 계산 및 적용.
|
|
public static void CalcPetExtra(int presetindex, int slotindex, bool brecalc)
|
|
{
|
|
int key = PlayData.petPresets[presetindex][slotindex];
|
|
if (key < 0)
|
|
{
|
|
BuffMgr.Instance.SetPetExtra(slotindex, 2, eEffectType.None, 0L, false);
|
|
BuffMgr.Instance.SetPetExtra(slotindex, 1, eEffectType.None, 0L, false);
|
|
BuffMgr.Instance.SetPetExtra(slotindex, 0, eEffectType.None, 0L, false);
|
|
BuffMgr.Instance.SetPetExtra(slotindex, 3, eEffectType.None, 0L, brecalc);
|
|
return;
|
|
}
|
|
|
|
dPet pet = dicPet[key];
|
|
if (pet.awaken <= 1 || pet.extraEffects == null)
|
|
{
|
|
BuffMgr.Instance.SetPetExtra(slotindex, 2, eEffectType.None, 0L, false);
|
|
BuffMgr.Instance.SetPetExtra(slotindex, 1, eEffectType.None, 0L, false);
|
|
BuffMgr.Instance.SetPetExtra(slotindex, 0, eEffectType.None, 0L, false);
|
|
BuffMgr.Instance.SetPetExtra(slotindex, 3, eEffectType.None, 0L, brecalc);
|
|
return;
|
|
}
|
|
|
|
bool bopenoption = true;
|
|
int[] extras = pet.extraEffects;
|
|
for (int i = extras.Length - 1; i >= 0; i--)
|
|
{
|
|
if (extras[i] < 0)
|
|
{
|
|
BuffMgr.Instance.SetPetExtra(slotindex, i, eEffectType.None, 0L, false);
|
|
bopenoption = false;
|
|
}
|
|
else
|
|
{
|
|
dExtraAbility ability = GetExtraAbility(extras[i]);
|
|
BuffMgr.Instance.SetPetExtra(slotindex, i, ability.abilityType, ability.abilityValue, false);
|
|
if (ability.rarity < cGoods.RLegend)
|
|
bopenoption = false;
|
|
}
|
|
}
|
|
|
|
// 옵션 보유 효과.
|
|
if (bopenoption)
|
|
BuffMgr.Instance.SetPetExtra(slotindex, extras.Length, pet.abilityTypeOption, pet.abilityValueOption, brecalc);
|
|
else
|
|
BuffMgr.Instance.SetPetExtra(slotindex, extras.Length, eEffectType.None, 0L, brecalc);
|
|
}
|
|
|
|
// 펫 장착 & 추가 효과 계산 및 적용.
|
|
public static void CalcPetEquipExtra(int presetindex)
|
|
{
|
|
// 장착 효과 계산.
|
|
CalcPetEffect(presetindex, 0, false);
|
|
CalcPetEffect(presetindex, 1, false);
|
|
CalcPetEffect(presetindex, 2, true);
|
|
|
|
// 추가 효과 계산.
|
|
CalcPetExtra(presetindex, 0, false);
|
|
CalcPetExtra(presetindex, 1, false);
|
|
CalcPetExtra(presetindex, 2, true);
|
|
}
|
|
|
|
public static Dictionary<int, dPet> GetPets()
|
|
{
|
|
return dicPet;
|
|
}
|
|
|
|
public static dPet GetPet(int key)
|
|
{
|
|
if (dicPet.ContainsKey(key))
|
|
return dicPet[key];
|
|
return null;
|
|
}
|
|
|
|
public static int GetPetSpiritCount(int key)
|
|
{
|
|
if (dicPet.ContainsKey(key))
|
|
return dicPet[key].count;
|
|
return 0;
|
|
}
|
|
|
|
public static int GetPetRarity(int key)
|
|
{
|
|
if (dicPet.ContainsKey(key))
|
|
return dicPet[key].rarity;
|
|
return 0;
|
|
}
|
|
|
|
public static bool AddPet(int key)
|
|
{
|
|
if (!dicPet.ContainsKey(key))
|
|
return false;
|
|
|
|
if (dicPet[key].have)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
dPet data = dicPet[key];
|
|
data.have = true;
|
|
data.level = 1;
|
|
data.awaken = 1;
|
|
if (data.maxAwaken > 1)
|
|
data.extraEffects = new int[3] { -1, -1, -1 };
|
|
petNew.Add(key);
|
|
|
|
CalcPetLevelEffect(1, false);
|
|
PetMgr.SSetBadge();
|
|
return true;
|
|
}
|
|
|
|
public static bool AddPetSpirit(int key, int icount)
|
|
{
|
|
if (!dicPet.ContainsKey(key))
|
|
return false;
|
|
|
|
dicPet[key].count += icount;
|
|
return true;
|
|
}
|
|
|
|
public static bool SubPetSpirit(int key, int icount)
|
|
{
|
|
if (!dicPet.ContainsKey(key))
|
|
return false;
|
|
|
|
if (dicPet[key].count < icount)
|
|
return false;
|
|
|
|
dicPet[key].count -= icount;
|
|
return true;
|
|
}
|
|
|
|
// 선택한 희귀도가 합성 가능한지.
|
|
public static bool IsPetSpiritComposable(fRangeRarity rarities)
|
|
{
|
|
if (rarities == fRangeRarity.None)
|
|
return false;
|
|
|
|
bool[] brarities = new bool[cGoods.RMyth + 1]
|
|
{
|
|
false,
|
|
rarities.HasFlag(fRangeRarity.Normal),
|
|
rarities.HasFlag(fRangeRarity.Rare),
|
|
rarities.HasFlag(fRangeRarity.Epic),
|
|
rarities.HasFlag(fRangeRarity.Unique),
|
|
rarities.HasFlag(fRangeRarity.Hero),
|
|
rarities.HasFlag(fRangeRarity.Legend),
|
|
rarities.HasFlag(fRangeRarity.Myth)
|
|
};
|
|
|
|
foreach (var item in dicPet)
|
|
{
|
|
if (!brarities[item.Value.rarity])
|
|
continue;
|
|
if (item.Value.count >= Const.petSpiritComposePrice)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static int GetPetSlot(int key)
|
|
{
|
|
int[] presets = PlayData.petPresets[PlayData.usePetPreset];
|
|
for (int i = 0; i < presets.Length; i++)
|
|
{
|
|
if (key == presets[i])
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
public static bool IsPetNewHave()
|
|
{
|
|
return petNew.Count > 0;
|
|
}
|
|
|
|
public static bool IsPetNew(int key)
|
|
{
|
|
return petNew.Contains(key);
|
|
}
|
|
|
|
public static bool RemovePetNew(int key)
|
|
{
|
|
return petNew.Remove(key);
|
|
}
|
|
|
|
public static void LvUpPet(int key, int ilevel, bool bcalcstat)
|
|
{
|
|
dPet data = dicPet[key];
|
|
int iaddlevel = ilevel - data.level;
|
|
data.level = ilevel;
|
|
|
|
int slotindex = GetEquipedPetIndex(key);
|
|
CalcPetLevelEffect(iaddlevel, bcalcstat);
|
|
if (bcalcstat && slotindex >= 0)
|
|
CalcPetEffect(PlayData.usePetPreset, slotindex, true);
|
|
}
|
|
|
|
public static void AwakenPet(int key, int iawaken, int ispritcnt)
|
|
{
|
|
if (!dicPet.ContainsKey(key))
|
|
return;
|
|
dicPet[key].awaken = iawaken;
|
|
dicPet[key].count = ispritcnt;
|
|
}
|
|
|
|
public static void ChangePetExtras(int key, int[] extras)
|
|
{
|
|
dicPet[key].extraEffects = extras;
|
|
}
|
|
|
|
public static int GetEquipedPetIndex(int key)
|
|
{
|
|
int[] presets = PlayData.petPresets[PlayData.usePetPreset];
|
|
for (int i = 0; i < presets.Length; i++)
|
|
{
|
|
if (key == presets[i])
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// 사용중인 프리셋 변경. 플레이 데이터 저장은 별도로 호출 필요.
|
|
public static void ChangePetPreset(int presetindex)
|
|
{
|
|
PlayData.usePetPreset = presetindex;
|
|
}
|
|
|
|
// 프리셋 변경. 플레이 데이터 저장은 별도로 호출 필요.
|
|
public static void EditPetPreset(int presetindex, int islotindex, int ipetid)
|
|
{
|
|
PlayData.petPresets[presetindex][islotindex] = ipetid;
|
|
}
|
|
#endregion Pet
|
|
|
|
#region Gacha
|
|
// 최대 소환 레벨.
|
|
public static int GetGachaMaxLv(int itype)
|
|
{
|
|
// 0:무기, 1:방어구, 2:악세.
|
|
if (itype == 0) return gachaWeaponLvs.Length;
|
|
else if (itype == 1) return gachaArmorLvs.Length;
|
|
else if (itype == 2) return gachaAcceLvs.Length;
|
|
else return 1;
|
|
}
|
|
|
|
// 소환 레벨별 데이터 가져오기.
|
|
public static dGachaLevel GetGachaLv(int itype, int ilv)
|
|
{
|
|
dGachaLevel[] lvdata;
|
|
|
|
// 0:무기, 1:방어구, 2:악세.
|
|
if (itype == 0) lvdata = gachaWeaponLvs;
|
|
else if (itype == 1) lvdata = gachaArmorLvs;
|
|
else if (itype == 2) lvdata = gachaAcceLvs;
|
|
else return null;
|
|
|
|
if (ilv >= lvdata.Length) return lvdata[lvdata.Length - 1];
|
|
else return lvdata[ilv - 1];
|
|
}
|
|
|
|
// 소환 등급별 확률 데이터 가져오기.
|
|
public static int[] GetGachaGrades(int itype)
|
|
{
|
|
// 0:무기, 1:방어구, 2:악세.
|
|
if (itype == 0) return gachaWeaponGrades;
|
|
else if (itype == 1) return gachaArmorGrades;
|
|
else if (itype == 2) return gachaAcceGrades;
|
|
else return new int[0];
|
|
}
|
|
|
|
// 가챠 레벨, 경험치 세팅.
|
|
public static void SetGachaLvExp(int itype, int ilv, int iexp)
|
|
{
|
|
// 0:무기, 1:방어구, 2:악세.
|
|
if (itype == 0)
|
|
{
|
|
PlayData.gachaWeaponLv = ilv;
|
|
PlayData.gachaWeaponExp = iexp;
|
|
}
|
|
else if (itype == 1)
|
|
{
|
|
PlayData.gachaArmorLv = ilv;
|
|
PlayData.gachaArmorExp = iexp;
|
|
}
|
|
else if (itype == 2)
|
|
{
|
|
PlayData.gachaAccLv = ilv;
|
|
PlayData.gachaAccExp = iexp;
|
|
}
|
|
}
|
|
|
|
// 가챠 보상 레벨 증가.
|
|
public static bool GachaRewardLvUp(int itype)
|
|
{
|
|
// 0:무기, 1:방어구, 2:악세.
|
|
if (itype == 0) return ++PlayData.gachaWeaponReward < PlayData.gachaWeaponLv;
|
|
else if (itype == 1) return ++PlayData.gachaArmorReward < PlayData.gachaArmorLv;
|
|
else if (itype == 2) return ++PlayData.gachaAccReward < PlayData.gachaAccLv;
|
|
else return false;
|
|
}
|
|
#endregion Gacha
|
|
|
|
#region Diary Trip & Life
|
|
|
|
//public static void initTrip()
|
|
//{
|
|
// //int iclearChapter = PlayData.clearTripPiece / (Const.TripMaxsize * Const.TripPieceMaxsize);
|
|
// //int iclearTrip = (PlayData.clearTripPiece % (Const.TripMaxsize * Const.TripPieceMaxsize)) / Const.TripPieceMaxsize;
|
|
// //int iclearTripPiece = (PlayData.clearTripPiece % (Const.TripMaxsize * Const.TripPieceMaxsize)) % Const.TripPieceMaxsize;
|
|
// int icurMaxStage = DataHandler.GetMaxStage();
|
|
// int ichapter = Const.TripMaxsize * Const.TripPieceMaxsize;
|
|
// int itrip = Const.TripPieceMaxsize;
|
|
// int iclear = (icurMaxStage - 100) / 100;
|
|
|
|
// for (int i = 0; i<Const.TripChapterMaxsize; i++)
|
|
// {
|
|
// for(int j = 0; j<Const.TripMaxsize; j++)
|
|
// {
|
|
// for(int k = 0; k<Const.TripPieceMaxsize; k++)
|
|
// {
|
|
// if ((i*ichapter)+(j*itrip)+(k) < iclear)
|
|
// dicTrip[i][j].islock[k] = true;
|
|
// else
|
|
// dicTrip[i][j].islock[k] = false;
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
//// 여정 1~n 장 모두 가져오기
|
|
//public static void LoadTrip(dTrip[][] datas)
|
|
//{
|
|
// dicTrip = datas;
|
|
//}
|
|
//public static dTrip[][] GetTripStep()
|
|
//{
|
|
// return dicTrip;
|
|
//}
|
|
//// 여정 가져오기
|
|
//public static dTrip[] GetTrips(int id)
|
|
//{
|
|
// if (dicTrip[id] != null)
|
|
// return dicTrip[id];
|
|
// return null;
|
|
//}
|
|
//public static dTrip GetTrip(int id, int idx)
|
|
//{
|
|
// if (dicTrip[id][idx] != null)
|
|
// return dicTrip[id][idx];
|
|
// return null;
|
|
//}
|
|
//// 다음 여정조각을 해금 할 수 있는지 체크
|
|
//public static bool nextTripPieceIslock(int id, int idx)
|
|
//{
|
|
// for (int i = 0; i < DataHandler.Const.TripPieceMaxsize; i++)
|
|
// {
|
|
// if (!dicTrip[id][idx].islock[i] && IsClearStage(GetTripStage(id, idx)) && PlayData.tripPiece > 0) // 해금이 잠겨있고, 클리어해야할 스테이지를 넘었을 경우
|
|
// {
|
|
// return true;
|
|
// }
|
|
// }
|
|
// return false;
|
|
//}
|
|
//public static int GetTripStage(int id, int idx)
|
|
//{
|
|
// int istageNum;
|
|
// istageNum = ((idx) * (100) * Const.TripPieceMaxsize * Const.TripMaxsize) + (dicTrip[id][idx].tripPieceCount + 1) * 100 + Const.stageMax;
|
|
// return istageNum;
|
|
//}
|
|
//// 다음 여정 조각 해금
|
|
//public static void tripPieceUnlock(int id, int idx)
|
|
//{
|
|
// if (dicTrip[id][idx] != null)
|
|
// {
|
|
// if (dicTrip[id][idx].tripPieceCount < DataHandler.Const.TripPieceMaxsize && PlayData.tripPiece > 0)
|
|
// {
|
|
// SubTripPiece();
|
|
// dicTrip[id][idx].islock[dicTrip[id][idx].tripPieceCount] = true;
|
|
// DiaryMgr.AllCheckCircle();
|
|
// dicTrip[id][idx].tripPieceCount++;
|
|
// }
|
|
// }
|
|
//}
|
|
//// 챕터를 어디까지 열수 있나 체크 bool [] 로 반환 ex) true true false false false 면 1~6장까지 있을때 2,3장 가능 4, 5, 6장 불가능
|
|
//public static bool[] tripChapterIslock()
|
|
//{
|
|
// bool[] barr = new bool[Const.TripChapterMaxsize - 1];
|
|
// for (int i = 0; i < Const.TripChapterMaxsize - 1; i++)
|
|
// {
|
|
// if (dicTrip[i][Const.TripMaxsize - 1].tripPieceCount == Const.TripPieceMaxsize)
|
|
// barr[i] = true;
|
|
// else
|
|
// barr[i] = false;
|
|
// }
|
|
|
|
// return barr;
|
|
//}
|
|
|
|
//// 여정 조각이 어디까지 해금되어있나 체크
|
|
//public static int GetTripPieceIslock(int id, int idx)
|
|
//{
|
|
// return dicTrip[id][idx].tripPieceCount;
|
|
//}
|
|
|
|
//// id idx 번째 여정의 여정 조각이 어디까지 해금 가능한가 체크
|
|
//public static int GetTripPieceIslockCount(int id, int idx)
|
|
//{
|
|
|
|
// int icurMaxStage = DataHandler.GetMaxStage();
|
|
// //[id][idx] 의 최대 스테이지
|
|
// int iStageMax = id * 3000 + (idx + 1) * Const.TripPieceMaxsize * 100 + Const.stageMax;
|
|
// //[id][idx] 의 최소 스테이지
|
|
// int iStageMin = id * 3000 + (idx + 1) * 100 + Const.stageMax;
|
|
|
|
// // 현재 클리어한 스테이지가 [id][idx] 의 최대 스테이지 보다 크면
|
|
// if (icurMaxStage > iStageMax)
|
|
// return Const.TripPieceMaxsize <= PlayData.tripPiece ? Const.TripPieceMaxsize : PlayData.tripPiece;
|
|
// // 현재 클리어한 스테이지가 [id][idx] 의 최소 스테이지 보다 크면
|
|
// if (icurMaxStage > iStageMin && icurMaxStage < iStageMax)
|
|
// return (icurMaxStage - iStageMin + Const.stageMax)/100;
|
|
// else
|
|
// return 0;
|
|
|
|
|
|
//}
|
|
//public static void AddTripPiece()
|
|
//{
|
|
// if(PlayData.curStage == GetMaxStage()) //+여기서 마지막 스테이지인거 체크
|
|
// {
|
|
// if(PlayData.curStage % 100 == Const.stageMax)
|
|
// {
|
|
// PlayData.tripPiece += 1;
|
|
// DiaryMgr.AllCheckCircle();
|
|
// return;
|
|
// }
|
|
// }
|
|
//}
|
|
//public static void SubTripPiece()
|
|
//{
|
|
// PlayData.tripPiece -= 1;
|
|
// PlayData.Save();
|
|
//}
|
|
|
|
|
|
|
|
//public static void LoadLife(dLife[][] datas)
|
|
//{
|
|
// dicLife = datas;
|
|
//}
|
|
|
|
//public static dLife[][] GetLifeStep()
|
|
//{
|
|
// return dicLife;
|
|
//}
|
|
//// 일 가져오기
|
|
//public static dLife[] GetLives(int id)
|
|
//{
|
|
// if (dicLife[id] != null)
|
|
// return dicLife[id];
|
|
// return null;
|
|
//}
|
|
//public static dLife GetLife(int id, int idx)
|
|
//{
|
|
// return dicLife[id][idx];
|
|
//}
|
|
//public static bool nextLifePieceIslock(int id, int idx)
|
|
//{
|
|
// for (int i = 0; i < DataHandler.Const.LifePieceMaxsize; i++)
|
|
// {
|
|
// if (!dicLife[id][idx].islock[i] && dicLifePiece[id, idx] > 0) // 해금이 잠겨있고 조각이 하나 이상 있으면
|
|
// {
|
|
// return true;
|
|
// }
|
|
// }
|
|
// return false;
|
|
//}
|
|
//public static void AddLifePiece(int id, int idx, int inum)
|
|
//{
|
|
// if(dicLife[id][idx].lifePieceCount >= Const.LifePieceMaxsize)
|
|
// {
|
|
// // 다이아 주는 코드AddDia()
|
|
// }
|
|
// else
|
|
// dicLifePiece[id,idx] += inum;
|
|
//}
|
|
|
|
//// 여정조각 해금
|
|
//public static void LifePieceUnlock(int id, int idx)
|
|
//{
|
|
// if (dicLife[id][idx] != null)
|
|
// {
|
|
// if (dicLifePiece[id,idx] > 0)
|
|
// {
|
|
// dicLife[id][idx].islock[dicLife[id][idx].lifePieceCount] = true;
|
|
// if (dicLife[id][idx].lifePieceCount < DataHandler.Const.LifePieceMaxsize)
|
|
// {
|
|
// dicLifePiece[id, idx]--;
|
|
// dicLife[id][idx].lifePieceCount++;
|
|
// }
|
|
// }
|
|
|
|
// }
|
|
//}
|
|
|
|
//// 플레이가능한 챕터는 어디까지 인가?
|
|
//public static bool[] lifeChapterIslock()
|
|
//{
|
|
// bool[] barr = new bool[Const.LifeChapterMaxsize - 1];
|
|
// for (int i = 0; i < Const.LifeChapterMaxsize - 1; i++)
|
|
// {
|
|
// if (dicLife[i][Const.LifeMaxsize - 1].lifePieceCount == Const.LifePieceMaxsize)
|
|
// barr[i] = true;
|
|
// else
|
|
// barr[i] = false;
|
|
// }
|
|
// return barr;
|
|
//}
|
|
|
|
//// 일상 조각이 어디까지 해금 가능한가 체크
|
|
//public static int GetLifePieceIslockCount(int id, int idx)
|
|
//{
|
|
// int icount = dicLifePiece[id, idx] + dicLife[id][idx].lifePieceCount;
|
|
|
|
// return icount;
|
|
//}
|
|
|
|
|
|
#endregion
|
|
|
|
#region Title
|
|
// 획득한 칭호 불러오기
|
|
public static void LoadPlayerTitlesData(int[] titles)
|
|
{
|
|
for (int i = 0; i < titles.Length; ++i)
|
|
{
|
|
int titleID = titles[i];
|
|
if (dicProfileTitle.TryGetValue(titleID, out dTitle targetTitle))
|
|
{
|
|
targetTitle.have = true;
|
|
BuffMgr.Instance.AddTitleEfc(targetTitle.abilityType, targetTitle.abilityValue, false);
|
|
}
|
|
}
|
|
|
|
foreach (var title in dicProfileTitle.Values)
|
|
{
|
|
if (title.have) continue;
|
|
|
|
var achievement = new nAchivement(title);
|
|
switch (title.category)
|
|
{
|
|
case eContent.Battle: listBattleType.Add(achievement); break;
|
|
case eContent.Equipment: listEquipmentType.Add(achievement); break;
|
|
case eContent.Summon: listSummonType.Add(achievement); break;
|
|
case eContent.Dungeon: listDungeonType.Add(achievement); break;
|
|
case eContent.Etc: listEtcType.Add(achievement); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static dTitle GetPlayerTitle(int key) => dicProfileTitle.SafeGet(key);
|
|
|
|
public static Dictionary<int,dTitle> GetAllPlayerTitle() => dicProfileTitle;
|
|
|
|
public static dTitle[] GetAllPlayerTitleArr()
|
|
{
|
|
dTitle[] datas = new dTitle[dicProfileTitle.Count];
|
|
for(int i = 0; i<dicProfileTitle.Count; i++)
|
|
{
|
|
datas[i] = dicProfileTitle[i+1];
|
|
}
|
|
return datas;
|
|
}
|
|
|
|
public static void EquipPlayerTitle(int key)
|
|
{
|
|
PlayData.playerTitle = key;
|
|
}
|
|
|
|
public static bool AddPlayerTitle(int key)
|
|
{
|
|
if (!dicProfileTitle.ContainsKey(key))
|
|
return false;
|
|
if(dicProfileTitle[key].have)
|
|
return false;
|
|
|
|
dTitle data = dicProfileTitle[key];
|
|
data.have = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
public static void UnlockTitle(int key)
|
|
{
|
|
if (dicProfileTitle.TryGetValue(key, out dTitle title) && title.have)
|
|
BuffMgr.Instance.AddTitleEfc(title.abilityType, title.abilityValue, false);
|
|
}
|
|
|
|
public static void AddTitleBadge()
|
|
{
|
|
nAchivement achive;
|
|
int[] arrSum = new int[5];
|
|
for(int i = 0; i < dicProfileTitle.Count; i++)
|
|
{
|
|
achive = new nAchivement(dicProfileTitle[i + 1]);
|
|
if (!dicProfileTitle[i + 1].have && isClearAchievements(achive) > 0)
|
|
arrSum[(int)(dicProfileTitle[i + 1].category) - 1]++;
|
|
}
|
|
ProfileMgr.addTitleBadge(eContent.Battle, arrSum[0]);
|
|
ProfileMgr.addTitleBadge(eContent.Equipment, arrSum[1]);
|
|
ProfileMgr.addTitleBadge(eContent.Summon, arrSum[2]);
|
|
ProfileMgr.addTitleBadge(eContent.Dungeon, arrSum[3]);
|
|
ProfileMgr.addTitleBadge(eContent.Etc, arrSum[4]);
|
|
}
|
|
#endregion
|
|
|
|
#region Icon
|
|
// 획득한 아이콘 불러오기
|
|
public static void LoadPlayerIconsData(int[] icons)
|
|
{
|
|
for (int i = 0; i < icons.Length; ++i)
|
|
{
|
|
int iconID = icons[i];
|
|
if (dicProfileIcon.TryGetValue(iconID, out dIcon targetIcon))
|
|
targetIcon.have = true;
|
|
}
|
|
|
|
foreach (var icon in dicProfileIcon.Values)
|
|
{
|
|
if (!icon.have)
|
|
listEtcType.Add(new nAchivement(icon));
|
|
}
|
|
}
|
|
|
|
public static void AddIconBadge()
|
|
{
|
|
int badgeCount = 0;
|
|
foreach (var icon in dicProfileIcon.Values)
|
|
{
|
|
if (!icon.have && isClearAchievements(new nAchivement(icon)) > 0) ++badgeCount;
|
|
}
|
|
|
|
ProfileMgr.addIconBadge(badgeCount);
|
|
}
|
|
|
|
public static void EquipPlayerIcon(int key)
|
|
{
|
|
PlayData.playerIcon = key;
|
|
PlayData.Save();
|
|
}
|
|
|
|
public static Dictionary<int, dIcon> GetAllplayerIcon() => dicProfileIcon;
|
|
|
|
public static dIcon GetPlayerIcon(int key) => dicProfileIcon.SafeGet(key);
|
|
|
|
public static bool AddPlayerIcon(int key)
|
|
{
|
|
if (!dicProfileIcon.TryGetValue(key, out dIcon targetIcon) || targetIcon.have) return false;
|
|
targetIcon.have = true;
|
|
return true;
|
|
}
|
|
#endregion
|
|
|
|
#region Record
|
|
public static cTotalRecord GetTotalRecord()
|
|
{
|
|
return PlayerTotalRecord;
|
|
}
|
|
|
|
public static cDailyRecord GetDailyRecord()
|
|
{
|
|
return PlayerDailyRecord;
|
|
}
|
|
|
|
public static void CheckAllAchivement()
|
|
{
|
|
CheckAchivement(eContent.Battle);
|
|
CheckAchivement(eContent.Equipment);
|
|
CheckAchivement(eContent.Summon);
|
|
CheckAchivement(eContent.Dungeon);
|
|
CheckAchivement(eContent.Etc);
|
|
}
|
|
|
|
public static void CheckAchivement(eContent content)
|
|
{
|
|
List<nAchivement> targetList = null;
|
|
switch (content)
|
|
{
|
|
case eContent.Battle: targetList = listBattleType; break;
|
|
case eContent.Equipment: targetList = listEquipmentType; break;
|
|
case eContent.Summon: targetList = listSummonType; break;
|
|
case eContent.Dungeon: targetList = listDungeonType; break;
|
|
case eContent.Etc: targetList = listEtcType; break;
|
|
default: return;
|
|
}
|
|
|
|
int result = targetList.SwapElements((achievement) => isClearAchievements(achievement) <= 0);
|
|
if (result > -1)
|
|
targetList.RemoveRange(result, targetList.Count - result);
|
|
}
|
|
|
|
public static void AddRecord(eCondition condition, int icount = 1)
|
|
{
|
|
switch (condition)
|
|
{
|
|
case eCondition.PlayAtttend:
|
|
PlayerDailyRecord.attendCnt += icount;
|
|
break;
|
|
case eCondition.MonsterCnt:
|
|
PlayerDailyRecord.monsterKill += icount;
|
|
PlayerTotalRecord.monsterKill += icount;
|
|
if(GetQuestMission(PlayerTotalRecord.missionLv) != null && GetQuestMission(PlayerTotalRecord.missionLv).condType == eCondition.MonsterCnt)
|
|
{
|
|
MissionMgr.SSetMissionMonCnt();
|
|
MissionMgr.checkCurMission();
|
|
}
|
|
break;
|
|
case eCondition.PlayTimeM:
|
|
PlayerDailyRecord.playTime += icount;
|
|
PlayerTotalRecord.playTime += icount;
|
|
break;
|
|
case eCondition.EnhanceGoldAtk:
|
|
PlayerDailyRecord.enhanceGoldAtk += icount;
|
|
break;
|
|
case eCondition.EnhanceGoldHp:
|
|
PlayerDailyRecord.enhanceGoldHp += icount;
|
|
break;
|
|
case eCondition.GachaWeapon:
|
|
PlayerDailyRecord.gachaWeaponCnt += icount;
|
|
PlayerTotalRecord.gachaWeaponCnt += icount;
|
|
break;
|
|
case eCondition.GachaArmor:
|
|
PlayerDailyRecord.gachaArmorCnt += icount;
|
|
PlayerTotalRecord.gachaArmorCnt += icount;
|
|
break;
|
|
case eCondition.GachaAcc:
|
|
PlayerDailyRecord.gachaAccCnt += icount;
|
|
PlayerTotalRecord.gachaAccCnt += icount;
|
|
break;
|
|
|
|
case eCondition.GachaTreasure:
|
|
PlayerDailyRecord.gachaTreasureCnt += icount;
|
|
PlayerTotalRecord.gachaTreasureCnt += icount;
|
|
break;
|
|
|
|
case eCondition.EquipComposeWeapon:
|
|
PlayerDailyRecord.composeWeaponCnt += icount;
|
|
PlayerTotalRecord.composeWeaponCnt += icount;
|
|
break;
|
|
case eCondition.EquipComposeArmor:
|
|
PlayerDailyRecord.composeArmorCnt += icount;
|
|
PlayerTotalRecord.composeArmorCnt += icount;
|
|
break;
|
|
case eCondition.EquipComposeAcc:
|
|
PlayerDailyRecord.composeAccCnt += icount;
|
|
PlayerTotalRecord.composeAccCnt += icount;
|
|
break;
|
|
//case eCondition.ComposeIris:
|
|
// PlayerTotalRecord.composeIris += icount;
|
|
// break;
|
|
case eCondition.DailyQuestClear:
|
|
PlayerDailyRecord.clearDailyQuest += icount;
|
|
break;
|
|
case eCondition.DailyQuestClearTotal:
|
|
PlayerTotalRecord.clearDailyQuest += icount;
|
|
break;
|
|
case eCondition.MissionClearLv:
|
|
PlayerTotalRecord.missionLv += icount;
|
|
break;
|
|
case eCondition.PetspiritCompose:
|
|
PlayerTotalRecord.composePetSpirit += icount;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 타입과 값을 받고 클리어 유무를 1이상의 int값으로 반환 1 = 1번클리어 2 = 2번클리어
|
|
public static int isClearAchievements(nAchivement achive, int clearAllDay = 0)
|
|
{
|
|
int bClear = 0;
|
|
|
|
switch (achive.condition)
|
|
{
|
|
case eCondition.PlayerAwaken: return PlayDgAwaken.lv > achive.condValue ? 1 : 0;
|
|
case eCondition.MonsterCnt:
|
|
if (achive.contentType == eContentType.DailyQuest)
|
|
return achive.condValue <= PlayerDailyRecord.monsterKill ? 1 : 0;
|
|
else if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.monsterKill >= sum ? ((PlayerTotalRecord.monsterKill - sum) / achive.condValue) : 0;
|
|
}
|
|
else
|
|
return PlayerTotalRecord.monsterKill >= achive.condValue ? 1 : 0;
|
|
case eCondition.GachaAll:
|
|
if (achive.contentType == eContentType.DailyQuest)
|
|
return achive.condValue <= PlayerDailyRecord.gachaWeaponCnt + PlayerDailyRecord.gachaArmorCnt + PlayerDailyRecord.gachaAccCnt + PlayerDailyRecord.gachaTreasureCnt? 1 : 0;
|
|
else
|
|
return PlayerTotalRecord.gachaWeaponCnt + PlayerTotalRecord.gachaArmorCnt + PlayerTotalRecord.gachaAccCnt + PlayerTotalRecord.gachaTreasureCnt> achive.condValue ? 1 : 0;
|
|
case eCondition.GachaWeapon:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.gachaWeaponCnt >= sum ? ((PlayerTotalRecord.gachaWeaponCnt - sum) / achive.condValue) : 0;
|
|
}
|
|
else
|
|
return PlayerTotalRecord.gachaWeaponCnt >= achive.condValue ? 1 : 0;
|
|
case eCondition.GachaArmor:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.gachaArmorCnt >= sum ? ((PlayerTotalRecord.gachaArmorCnt - sum) / achive.condValue) : 0;
|
|
}
|
|
else
|
|
return PlayerTotalRecord.gachaArmorCnt >= achive.condValue ? 1 : 0;
|
|
case eCondition.GachaAcc:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.gachaAccCnt >= sum ? ((PlayerTotalRecord.gachaAccCnt - sum) / achive.condValue) : 0;
|
|
}
|
|
else
|
|
return PlayerTotalRecord.gachaAccCnt >= achive.condValue ? 1 : 0;
|
|
case eCondition.GachaTreasure:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.gachaTreasureCnt >= sum ? ((PlayerTotalRecord.gachaTreasureCnt - sum) / achive.condValue) : 0;
|
|
}
|
|
else
|
|
return PlayerTotalRecord.gachaTreasureCnt >= achive.condValue ? 1 : 0;
|
|
case eCondition.EnhanceGoldAtk:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return GetCharStat(1).level >= sum ? ((GetCharStat(1).level - sum) / achive.condValue) : 0;
|
|
}
|
|
else
|
|
return GetCharStat(1).level >= achive.condValue ? 1 : 0;
|
|
case eCondition.EnhanceGoldHp:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return GetCharStat(2).level >= sum ? ((GetCharStat(2).level - sum) / achive.condValue) : 0;
|
|
}
|
|
else
|
|
return GetCharStat(2).level >= achive.condValue ? 1 : 0;
|
|
case eCondition.EnhanceGoldAtkCount:
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return GetCharStat(1).level >= sum ? ((GetCharStat(1).level - sum) / achive.condValue) : 0;
|
|
}
|
|
case eCondition.EnhanceGoldHpCount:
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return GetCharStat(2).level >= sum ? ((GetCharStat(2).level - sum) / achive.condValue) : 0;
|
|
}
|
|
case eCondition.DgStagePet:
|
|
{
|
|
uint level = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(ProtectTheMerchantDgProp.CodeName, out ProtectTheMerchantDgData modData))
|
|
level = modData.Level;
|
|
return level > (achive.condValue / 100 - 1) * 10 + achive.condValue % 100 ? 1 : 0;
|
|
}
|
|
case eCondition.EquipComposeAll:
|
|
if (achive.contentType == eContentType.DailyQuest)
|
|
return achive.condValue <= PlayerDailyRecord.composeWeaponCnt + PlayerDailyRecord.composeArmorCnt + PlayerDailyRecord.composeAccCnt ? 1 : 0;
|
|
else
|
|
return bClear;
|
|
case eCondition.EquipComposeWeapon:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.composeWeaponCnt >= sum ? (PlayerTotalRecord.composeWeaponCnt - sum) / achive.condValue : 0;
|
|
}
|
|
else
|
|
return PlayerTotalRecord.composeWeaponCnt >= achive.condValue ? 1 : 0;
|
|
case eCondition.EquipComposeArmor:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.composeArmorCnt >= sum ? (PlayerTotalRecord.composeArmorCnt - sum) / achive.condValue : 0;
|
|
}
|
|
else
|
|
return PlayerTotalRecord.composeArmorCnt >= achive.condValue ? 1 : 0;
|
|
case eCondition.EquipComposeAcc:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
{
|
|
int sum = achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.composeAccCnt >= sum ? (PlayerTotalRecord.composeAccCnt - sum) / achive.condValue : 0;
|
|
}
|
|
else
|
|
return PlayerTotalRecord.composeAccCnt >= achive.condValue ? 1 : 0;
|
|
case eCondition.EventQuestDayClear:
|
|
return GetPlayEventQuestDayClearCount(clearAllDay) >= achive.condValue ? 1 : 0;
|
|
default:
|
|
return GetAchievementValue(achive) >= achive.condValue ? 1 : 0;
|
|
}
|
|
}
|
|
|
|
public static int GetAchievementValue(nAchivement achive)
|
|
{
|
|
int ivalue = 0;
|
|
int cnt = 0;
|
|
int sum = 0;
|
|
|
|
switch (achive.condition)
|
|
{
|
|
// 스테이지, 레벨, 각성, 플레이 시간(분), 플레이 시간, 출석
|
|
case eCondition.StageClear: return GetMaxStage();
|
|
case eCondition.PlayerLv: return PlayData.playerLv;
|
|
case eCondition.PlayerAwaken: return PlayDgAwaken.lv - 1;
|
|
case eCondition.PlayTimeM: return achive.contentType == eContentType.DailyQuest ? PlayerDailyRecord.playTime : PlayerTotalRecord.playTime;
|
|
case eCondition.PlayTimeH: return PlayerTotalRecord.playTime / 60;
|
|
case eCondition.PlayAtttend: return (achive.contentType == eContentType.DailyQuest || achive.contentType == eContentType.QuestMission) ? PlayerDailyRecord.attendCnt : PlayerTotalRecord.attendCnt;
|
|
|
|
// 몬스터 처치 횟수
|
|
case eCondition.MonsterCnt:
|
|
if (achive.contentType == eContentType.DailyQuest)
|
|
return PlayerDailyRecord.monsterKill;
|
|
else if (achive.contentType == eContentType.RepeatQuest)
|
|
return PlayerTotalRecord.monsterKill - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
else
|
|
return PlayerTotalRecord.monsterKill;
|
|
case eCondition.EliteCnt:
|
|
case eCondition.BossCnt:
|
|
return ivalue;
|
|
|
|
// 소환 횟수
|
|
case eCondition.GachaAll:
|
|
if (achive.contentType == eContentType.DailyQuest)
|
|
return PlayerDailyRecord.gachaWeaponCnt + PlayerDailyRecord.gachaArmorCnt + PlayerDailyRecord.gachaAccCnt + PlayerDailyRecord.gachaTreasureCnt;
|
|
else if (achive.contentType == eContentType.RepeatQuest)
|
|
return (PlayerTotalRecord.gachaWeaponCnt + PlayerTotalRecord.gachaArmorCnt + PlayerTotalRecord.gachaAccCnt) - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
else
|
|
return PlayerTotalRecord.gachaWeaponCnt + PlayerTotalRecord.gachaArmorCnt + PlayerTotalRecord.gachaAccCnt;
|
|
case eCondition.GachaWeapon:
|
|
if(achive.contentType == eContentType.RepeatQuest)
|
|
return PlayerTotalRecord.gachaWeaponCnt - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.gachaWeaponCnt;
|
|
case eCondition.GachaArmor:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
return PlayerTotalRecord.gachaArmorCnt - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.gachaArmorCnt;
|
|
case eCondition.GachaAcc:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
return PlayerTotalRecord.gachaAccCnt - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.gachaAccCnt;
|
|
case eCondition.GachaTreasure:
|
|
return PlayerTotalRecord.gachaTreasureCnt;
|
|
|
|
case eCondition.GachaWeaponLv:
|
|
return PlayData.gachaWeaponLv;
|
|
case eCondition.GachaArmorLv:
|
|
return PlayData.gachaArmorLv;
|
|
case eCondition.GachaAccLv:
|
|
return PlayData.gachaAccLv;
|
|
|
|
// 골드 강화 레벨
|
|
case eCondition.EnhanceGoldAll: return GetCharStat(1).level + GetCharStat(2).level + GetCharStat(3).level;
|
|
case eCondition.EnhanceGoldAtk:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
return GetCharStat(1).level - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return GetCharStat(1).level;
|
|
case eCondition.EnhanceGoldHp:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
return GetCharStat(2).level - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return GetCharStat(2).level;
|
|
case eCondition.EnhanceGoldAtkCount: return GetCharStat(1).level - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
case eCondition.EnhanceGoldHpCount: return GetCharStat(2).level - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
|
|
// 포인트 강화 레벨
|
|
case eCondition.EnhancePointAll:
|
|
Dictionary<int, dCharStat> lvpoints = GetCharLvPoints();
|
|
for (int i = 1; i < lvpoints.Count; i++)
|
|
{
|
|
sum += (lvpoints[i].level - 1);
|
|
}
|
|
return sum;
|
|
case eCondition.EnhancePointAtk: return GetCharLvPoint(1).level;
|
|
case eCondition.EnhancePointHp: return GetCharLvPoint(2).level;
|
|
|
|
// 스킬
|
|
case eCondition.SkillEquip:
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
if (PlayData.skillPresets[PlayData.usePreset][i] != -1)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
case eCondition.SkillLvAll: return GetSkillTotalLevels()[0];
|
|
case eCondition.SkillLvActive:
|
|
for (int i = 0; i < dicSkillActive.Count; i++)
|
|
{
|
|
if (dicSkillActive[i + 1].openLv <= PlayData.playerLv)
|
|
sum += dicSkillActive[i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.SkillLvPassive:
|
|
for (int i = 0; i < dicSkillPassive.Count; i++)
|
|
{
|
|
sum += dicSkillPassive[i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
|
|
// 잠재 능력
|
|
case eCondition.ChangeAbility:
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
if (PlayAwaken.extras[PlayAwaken.usePreset][i] != -1)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
|
|
// 특정 코스튬 획득
|
|
case eCondition.CosHave: return GetCosCloth(achive.condValue).have ? 1 : 0;
|
|
case eCondition.CosCnt:
|
|
cnt = 0;
|
|
for (int i = 1; i < dicCosCloth.Count + 1; i++)
|
|
{
|
|
int key = dicCosCloth[i].id;
|
|
if (GetCosCloth(key).have)
|
|
cnt++;
|
|
}
|
|
return cnt;
|
|
case eCondition.CosSetHave: return IsActiveClothCosSetEffect(achive.condValue) ? 1 : 0;
|
|
case eCondition.CosSetCnt:
|
|
for (int i = 1; i < dicCosClothSet.Count + 1; i++)
|
|
{
|
|
int key = dicCosClothSet[i].id;
|
|
if (IsActiveClothCosSetEffect(key))
|
|
cnt++;
|
|
}
|
|
return cnt;
|
|
|
|
// 모든 장비 획득
|
|
case eCondition.EquipHaveAll:
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveWeaponAll, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveArmorAll, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveAccAll, 1, 1)) <= 0)
|
|
return 0;
|
|
return 1;
|
|
case eCondition.EquipHaveD:
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveWeaponD, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveArmorD, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveAccD, 1, 1)) <= 0)
|
|
return 0;
|
|
return 1;
|
|
case eCondition.EquipHaveC:
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveWeaponC, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveArmorC, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveAccC, 1, 1)) <= 0)
|
|
return 0;
|
|
return 1;
|
|
case eCondition.EquipHaveB:
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveWeaponB, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveArmorB, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveAccB, 1, 1)) <= 0)
|
|
return 0;
|
|
return 1;
|
|
case eCondition.EquipHaveA:
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveWeaponA, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveArmorA, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveAccA, 1, 1)) <= 0)
|
|
return 0;
|
|
return 1;
|
|
case eCondition.EquipHaveS:
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveWeaponS, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveArmorS, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveAccS, 1, 1)) <= 0)
|
|
return 0;
|
|
return 1;
|
|
case eCondition.EquipHaveSS:
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveWeaponSS, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveArmorSS, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveAccSS, 1, 1)) <= 0)
|
|
return 0;
|
|
return 1;
|
|
case eCondition.EquipHaveSR:
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveWeaponSR, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveArmorSR, 1, 1)) <= 0)
|
|
return 0;
|
|
if (GetAchievementValue(new nAchivement(eContentType.Title, eCondition.EquipHaveAccSR, 1, 1)) <= 0)
|
|
return 0;
|
|
return 1;
|
|
|
|
// 모든 무기 획득
|
|
case eCondition.EquipHaveWeaponAll:
|
|
sum = 0;
|
|
for (int i = 0; i < arrHaveWeapon.Length; i++)
|
|
{
|
|
sum += arrHaveWeapon[i];
|
|
}
|
|
return sum >= 28 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponD: return arrHaveWeapon[0] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponC: return arrHaveWeapon[1] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponB: return arrHaveWeapon[2] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponA: return arrHaveWeapon[3] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponS: return arrHaveWeapon[4] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponSS: return arrHaveWeapon[5] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponSR: return arrHaveWeapon[6] >= 4 ? 1 : 0;
|
|
|
|
// 모든 방어구 획득
|
|
case eCondition.EquipHaveArmorAll:
|
|
sum = 0;
|
|
foreach (var item in arrHaveArmor)
|
|
{
|
|
sum += item;
|
|
}
|
|
return sum >= 84 ? 1 : 0;
|
|
case eCondition.EquipHaveArmorD: return arrHaveArmor[0, 0] >= 4 && arrHaveArmor[1, 0] >= 4 && arrHaveArmor[2, 0] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveArmorC: return arrHaveArmor[0, 1] >= 4 && arrHaveArmor[1, 1] >= 4 && arrHaveArmor[2, 1] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveArmorB: return arrHaveArmor[0, 2] >= 4 && arrHaveArmor[1, 2] >= 4 && arrHaveArmor[2, 2] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveArmorA: return arrHaveArmor[0, 3] >= 4 && arrHaveArmor[1, 3] >= 4 && arrHaveArmor[2, 3] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveArmorS: return arrHaveArmor[0, 4] >= 4 && arrHaveArmor[1, 4] >= 4 && arrHaveArmor[2, 4] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveArmorSS: return arrHaveArmor[0, 5] >= 4 && arrHaveArmor[1, 5] >= 4 && arrHaveArmor[2, 5] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveArmorSR: return arrHaveArmor[0, 6] >= 4 && arrHaveArmor[1, 6] >= 4 && arrHaveArmor[2, 6] >= 4 ? 1 : 0;
|
|
|
|
// 모든 장신구 획득
|
|
case eCondition.EquipHaveAccAll:
|
|
sum = 0;
|
|
foreach (var item in arrHaveAcc)
|
|
{
|
|
sum += item;
|
|
}
|
|
return sum >= 84 ? 1 : 0;
|
|
case eCondition.EquipHaveAccD: return arrHaveAcc[0, 0] >= 4 && arrHaveAcc[1, 0] >= 4 && arrHaveAcc[2, 0] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveAccC: return arrHaveAcc[0, 1] >= 4 && arrHaveAcc[1, 1] >= 4 && arrHaveAcc[2, 1] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveAccB: return arrHaveAcc[0, 2] >= 4 && arrHaveAcc[1, 2] >= 4 && arrHaveAcc[2, 2] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveAccA: return arrHaveAcc[0, 3] >= 4 && arrHaveAcc[1, 3] >= 4 && arrHaveAcc[2, 3] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveAccS: return arrHaveAcc[0, 4] >= 4 && arrHaveAcc[1, 4] >= 4 && arrHaveAcc[2, 4] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveAccSS: return arrHaveAcc[0, 5] >= 4 && arrHaveAcc[1, 5] >= 4 && arrHaveAcc[2, 5] >= 4 ? 1 : 0;
|
|
case eCondition.EquipHaveAccSR: return arrHaveAcc[0, 6] >= 4 && arrHaveAcc[1, 6] >= 4 && arrHaveAcc[2, 6] >= 4 ? 1 : 0;
|
|
|
|
// 특정 등급의 무기 1개 이상
|
|
case eCondition.EquipHaveWeaponNOne: return arrHaveWeapon[0] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponROne: return arrHaveWeapon[1] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponEOne: return arrHaveWeapon[2] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponUOne: return arrHaveWeapon[3] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponLOne: return arrHaveWeapon[4] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponHOne: return arrHaveWeapon[5] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveWeaponMOne: return arrHaveWeapon[6] >= 1 ? 1 : 0;
|
|
|
|
//특정 등급 귀걸이 1개 이상
|
|
case eCondition.EquipHaveEarNOne: return arrHaveAcc[0, 0] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveEarROne: return arrHaveAcc[0, 1] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveEarEOne: return arrHaveAcc[0, 2] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveEarUOne: return arrHaveAcc[0, 3] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveEarLOne: return arrHaveAcc[0, 4] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveEarHOne: return arrHaveAcc[0, 5] >= 1 ? 1 : 0;
|
|
case eCondition.EquipHaveEarMOne: return arrHaveAcc[0, 6] >= 1 ? 1 : 0;
|
|
|
|
//던전 도전 횟수
|
|
case eCondition.DgTryAll:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(DeepCaveDungeonProperty.CodeName, out DeepCaveDungeonData deepCaveDungeonData))
|
|
result += deepCaveDungeonData.TryCount;
|
|
if (GameModDataGroup.Instance.TryGetModData(AtlantisDungeonProperty.CodeName, out AtlantisDungeonData atlantisDungeonData))
|
|
result += atlantisDungeonData.TryCount;
|
|
if (GameModDataGroup.Instance.TryGetModData(ProtectTheMerchantDgProp.CodeName, out ProtectTheMerchantDgData protectTheMerchantDgData))
|
|
result += protectTheMerchantDgData.TryCount;
|
|
if (GameModDataGroup.Instance.TryGetModData(DevelopTheJungleDgProp.CodeName, out DevelopTheJungleDgData developTheJungleDgData))
|
|
result += developTheJungleDgData.TryCount;
|
|
if (GameModDataGroup.Instance.TryGetModData(HuntEagleDgProp.CodeName, out HuntEagleDgData huntEagleDgData))
|
|
result += huntEagleDgData.TryCount;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgTryGold:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(DeepCaveDungeonProperty.CodeName, out DeepCaveDungeonData deepCaveDungeonData))
|
|
result = deepCaveDungeonData.TryCount;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgTryEnhance:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(AtlantisDungeonProperty.CodeName, out AtlantisDungeonData atlantisDungeonData))
|
|
result += atlantisDungeonData.TryCount;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgTryAwaken:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(DevelopTheJungleDgProp.CodeName, out DevelopTheJungleDgData developTheJungleDgData))
|
|
result += developTheJungleDgData.TryCount;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgTryPet:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(ProtectTheMerchantDgProp.CodeName, out ProtectTheMerchantDgData protectTheMerchantDgData))
|
|
result += protectTheMerchantDgData.TryCount;
|
|
return (int)result;
|
|
}
|
|
|
|
// 던전 스테이지 클리어
|
|
case eCondition.DgClearAll:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(DeepCaveDungeonProperty.CodeName, out DeepCaveDungeonData deepCaveDungeonData))
|
|
result += deepCaveDungeonData.ClearCount;
|
|
if (GameModDataGroup.Instance.TryGetModData(AtlantisDungeonProperty.CodeName, out AtlantisDungeonData atlantisDungeonData))
|
|
result += atlantisDungeonData.ClearCount;
|
|
if (GameModDataGroup.Instance.TryGetModData(ProtectTheMerchantDgProp.CodeName, out ProtectTheMerchantDgData protectTheMerchantDgData))
|
|
result += protectTheMerchantDgData.ClearCount;
|
|
if (GameModDataGroup.Instance.TryGetModData(DevelopTheJungleDgProp.CodeName, out DevelopTheJungleDgData developTheJungleDgData))
|
|
result += developTheJungleDgData.ClearCount;
|
|
if (GameModDataGroup.Instance.TryGetModData(HuntEagleDgProp.CodeName, out HuntEagleDgData huntEagleDgData))
|
|
result += huntEagleDgData.ClearCount;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgClearGold:
|
|
{
|
|
uint result = 0;
|
|
if(GameModDataGroup.Instance.TryGetModData(DeepCaveDungeonProperty.CodeName, out DeepCaveDungeonData deepCaveDungeonData))
|
|
result = deepCaveDungeonData.ClearCount;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgClearEnhance:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(AtlantisDungeonProperty.CodeName, out AtlantisDungeonData atlantisDungeonData))
|
|
result += atlantisDungeonData.ClearCount;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgClearAwaken:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(DevelopTheJungleDgProp.CodeName, out DevelopTheJungleDgData developTheJungleDgData))
|
|
result += developTheJungleDgData.ClearCount;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgClearPet:
|
|
{
|
|
uint result = 0;
|
|
if (GameModDataGroup.Instance.TryGetModData(ProtectTheMerchantDgProp.CodeName, out ProtectTheMerchantDgData protectTheMerchantDgData))
|
|
result += protectTheMerchantDgData.ClearCount;
|
|
return (int)result;
|
|
}
|
|
|
|
case eCondition.DgStageGold:
|
|
{
|
|
uint result = 1;
|
|
if (GameModDataGroup.Instance.TryGetModData(DeepCaveDungeonProperty.CodeName, out DeepCaveDungeonData deepCaveDungeonData))
|
|
result = deepCaveDungeonData.Level;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgStageEnhance:
|
|
{
|
|
uint result = 1;
|
|
if (GameModDataGroup.Instance.TryGetModData(AtlantisDungeonProperty.CodeName, out AtlantisDungeonData atlantisDungeonData))
|
|
result += atlantisDungeonData.Level;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgStageAwaken:
|
|
{
|
|
uint result = 1;
|
|
if (GameModDataGroup.Instance.TryGetModData(DevelopTheJungleDgProp.CodeName, out DevelopTheJungleDgData developTheJungleDgData))
|
|
result += developTheJungleDgData.Level;
|
|
return (int)result;
|
|
}
|
|
case eCondition.DgStagePet:
|
|
{
|
|
uint result = 1;
|
|
if (GameModDataGroup.Instance.TryGetModData(ProtectTheMerchantDgProp.CodeName, out ProtectTheMerchantDgData protectTheMerchantDgData))
|
|
result += protectTheMerchantDgData.Level;
|
|
return (int)result;
|
|
}
|
|
|
|
// 장비 합성
|
|
case eCondition.EquipComposeAll:
|
|
if (achive.contentType == eContentType.DailyQuest)
|
|
return PlayerDailyRecord.composeWeaponCnt + PlayerDailyRecord.composeArmorCnt + PlayerDailyRecord.composeAccCnt;
|
|
else
|
|
return PlayerTotalRecord.composeWeaponCnt + PlayerTotalRecord.composeArmorCnt + PlayerTotalRecord.composeAccCnt;
|
|
case eCondition.EquipComposeWeapon:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
return PlayerTotalRecord.composeWeaponCnt - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.composeWeaponCnt;
|
|
case eCondition.EquipComposeArmor:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
return PlayerTotalRecord.composeArmorCnt - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.composeArmorCnt;
|
|
case eCondition.EquipComposeAcc:
|
|
if (achive.contentType == eContentType.RepeatQuest)
|
|
return PlayerTotalRecord.composeAccCnt - achive.condValue * playQuestRepeat[achive.id - 1].totalCnt;
|
|
return PlayerTotalRecord.composeAccCnt;
|
|
|
|
// 장비 강화 레벨
|
|
case eCondition.EquipLvAll:
|
|
return GetGearTotalLevels(cGoods.TBagWeapon)[0] + GetGearTotalLevels(cGoods.TBagArmorCape)[0] +
|
|
GetGearTotalLevels(cGoods.TBagArmorHat)[0] + GetGearTotalLevels(cGoods.TBagArmorShoes)[0] +
|
|
GetGearTotalLevels(cGoods.TBagAcceEar)[0] + GetGearTotalLevels(cGoods.TBagAcceNeck)[0] +
|
|
GetGearTotalLevels(cGoods.TBagAcceRing)[0];
|
|
case eCondition.EquipLvWeapon: return GetGearTotalLevels(cGoods.TBagWeapon)[0];
|
|
case eCondition.EquipLvArmor: return GetGearTotalLevels(cGoods.TBagArmorCape)[0] + GetGearTotalLevels(cGoods.TBagArmorHat)[0] + GetGearTotalLevels(cGoods.TBagArmorShoes)[0];
|
|
case eCondition.EquipLvAcc: return GetGearTotalLevels(cGoods.TBagAcceEar)[0] + GetGearTotalLevels(cGoods.TBagAcceNeck)[0] + GetGearTotalLevels(cGoods.TBagAcceRing)[0];
|
|
case eCondition.EquipLvTreasure: return ivalue;
|
|
|
|
// 장비 장착
|
|
case eCondition.EquipWeapon: return PlayData.weapon != -1 ? 1 : 0;
|
|
case eCondition.EquipArmorCape: return PlayData.cape != -1 ? 1 : 0;
|
|
case eCondition.EquipArmorHat: return PlayData.hat != -1 ? 1 : 0;
|
|
case eCondition.EquipArmorShoes: return PlayData.shoes != -1 ? 1 : 0;
|
|
case eCondition.EquipAccEar: return PlayData.earring != -1 ? 1 : 0;
|
|
case eCondition.EquipAccNeck: return PlayData.necklace != -1 ? 1 : 0;
|
|
case eCondition.EquipAccRing: return PlayData.ring != -1 ? 1 : 0;
|
|
|
|
// 장비 강화
|
|
case eCondition.EnhanceGear: return ivalue;
|
|
case eCondition.EnhanceWeapon:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagWeapon].Count; i++)
|
|
{
|
|
if(dicGearEquipment[cGoods.TBagWeapon][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagWeapon][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceArmor:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagArmorCape].Count; i++)
|
|
{
|
|
if (dicGearEquipment[cGoods.TBagArmorCape][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagArmorCape][i + 1].level - 1;
|
|
}
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagArmorHat].Count; i++)
|
|
{
|
|
if (dicGearEquipment[cGoods.TBagArmorHat][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagArmorHat][i + 1].level - 1;
|
|
}
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagArmorShoes].Count; i++)
|
|
{
|
|
if (dicGearEquipment[cGoods.TBagArmorShoes][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagArmorShoes][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceArmorCape:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagArmorCape].Count; i++)
|
|
{
|
|
if(dicGearEquipment[cGoods.TBagWeapon][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagWeapon][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceArmorHat:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagArmorHat].Count; i++)
|
|
{
|
|
if(dicGearEquipment[cGoods.TBagArmorHat][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagArmorHat][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceArmorShoes:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagArmorShoes].Count; i++)
|
|
{
|
|
if(dicGearEquipment[cGoods.TBagArmorShoes][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagArmorShoes][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceAcc:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagAcceEar].Count; i++)
|
|
{
|
|
if(dicGearEquipment[cGoods.TBagAcceEar][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagAcceEar][i + 1].level - 1;
|
|
}
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagAcceNeck].Count; i++)
|
|
{
|
|
if(dicGearEquipment[cGoods.TBagAcceNeck][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagAcceNeck][i + 1].level - 1;
|
|
}
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagAcceRing].Count; i++)
|
|
{
|
|
if(dicGearEquipment[cGoods.TBagAcceRing][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagAcceRing][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceAccEar:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagAcceEar].Count; i++)
|
|
{
|
|
if(dicGearEquipment[cGoods.TBagAcceEar][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagAcceEar][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceAccNeck:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagAcceNeck].Count; i++)
|
|
{
|
|
if (dicGearEquipment[cGoods.TBagAcceNeck][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagAcceNeck][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceAccRing:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearEquipment[cGoods.TBagAcceRing].Count; i++)
|
|
{
|
|
if (dicGearEquipment[cGoods.TBagAcceRing][i + 1].have)
|
|
sum += dicGearEquipment[cGoods.TBagAcceRing][i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
case eCondition.EnhanceTreasure:
|
|
sum = 0;
|
|
for (int i = 0; i < dicGearTreasure.Count; i++)
|
|
{
|
|
if(dicGearTreasure[i + 1].have)
|
|
sum += dicGearTreasure[i + 1].level - 1;
|
|
}
|
|
return sum;
|
|
|
|
// 펫
|
|
case eCondition.PetEnhance:
|
|
for (int i = 0; i < dicPet.Count; i++)
|
|
{
|
|
if (dicPet[i + 1].have)
|
|
{
|
|
sum += dicPet[i + 1].level - 1;
|
|
}
|
|
}
|
|
return sum;
|
|
case eCondition.PetHave: return dicPet[achive.condValue].have ? 1 : 0;
|
|
case eCondition.PetspiritCompose: return PlayerTotalRecord.composePetSpirit;
|
|
|
|
// 일일 퀘스트
|
|
case eCondition.DailyQuestClear: return PlayerDailyRecord.clearDailyQuest;
|
|
|
|
// 아이콘, 칭호 장착
|
|
case eCondition.EquipIcon: return PlayData.playerIcon == achive.condValue ? 1 : 0;
|
|
case eCondition.EquipTitle: return PlayData.playerTitle == achive.condValue ? 1 : 0;
|
|
|
|
// 보석, 색상석 사용
|
|
case eCondition.UseDia: return ivalue;
|
|
|
|
// 자동 전투 활성화
|
|
case eCondition.AutoBattle: return BattleMgr.Instance.IsOnAutoSkill ? 1 : 0;
|
|
|
|
// 닉네임 변경
|
|
case eCondition.RenameCnt: return PlayerTotalRecord.renameCnt;
|
|
|
|
// 광고 버프
|
|
case eCondition.ActivateADbuff: return PlayBuff.adTimer[0] > 0 || PlayBuff.adTimer[1] > 0 || PlayBuff.adTimer[2] > 0 ? 1 : 0;
|
|
case eCondition.ActivateADbuffAtk: return PlayBuff.adTimer[0] > 0 ? 1 : 0;
|
|
case eCondition.ActivateADbuffExp: return PlayBuff.adTimer[1] > 0 ? 1 : 0;
|
|
case eCondition.ActivateADbuffGold:return PlayBuff.adTimer[2] > 0 ? 1 : 0;
|
|
case eCondition.ADbuffAtkLv: return PlayBuff.atkLv;
|
|
case eCondition.ADbuffExpLv: return PlayBuff.expLv;
|
|
case eCondition.ADbuffGoldLv: return PlayBuff.goldLv;
|
|
|
|
case eCondition.Etc:
|
|
if (achive.contentType == eContentType.Title) ivalue = dicProfileTitle[achive.id].have ? 1 : 0;
|
|
else if (achive.contentType == eContentType.Icon) ivalue = dicProfileIcon[achive.id].have ? 1 : 0;
|
|
else ivalue = 0;
|
|
return ivalue;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public static int GetAchievementValueWithDay(nAchivement achive, int day)
|
|
{
|
|
switch (achive.condition)
|
|
{
|
|
case eCondition.EventQuestDayClear:
|
|
return GetPlayEventQuestDayClearCount(day);
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Quest
|
|
public static dQuest GetDailyQuest(int id)
|
|
{
|
|
return sysQuestDaily[id];
|
|
}
|
|
|
|
public static Dictionary<int, dQuest> GetDailyQuests()
|
|
{
|
|
return sysQuestDaily;
|
|
}
|
|
|
|
public static dQuest GetRepeatQuest(int id)
|
|
{
|
|
return sysQuestRepeat[id];
|
|
}
|
|
|
|
public static Dictionary<int, dQuest> GetRepeatQuests()
|
|
{
|
|
return sysQuestRepeat;
|
|
}
|
|
|
|
public static void SetDailyQuestPlay(cQuestDaily data)
|
|
{
|
|
playQuestDaily[data.sid - 1] = data;
|
|
}
|
|
|
|
public static void SetDailyQuestAllPlay(cQuestDaily[] datas)
|
|
{
|
|
playQuestDaily = datas;
|
|
}
|
|
|
|
public static cQuestDaily GetDailyQuestPlay(int id)
|
|
{
|
|
return playQuestDaily[id - 1];
|
|
}
|
|
|
|
public static void SetRepeatQuestPlay(cQuestRepeat data)
|
|
{
|
|
playQuestRepeat[data.sid - 1] = data;
|
|
}
|
|
|
|
public static void SetRepeatQuestAllPlay(cQuestRepeat[] datas)
|
|
{
|
|
playQuestRepeat = datas;
|
|
}
|
|
|
|
public static void LoadPlayEventQuestPlay(cQuestEvent[] datas)
|
|
{
|
|
for (int i = 0; i < datas.Length; ++i)
|
|
{
|
|
cQuestEvent quest = datas[i];
|
|
playQuestEvent.SafeInsert(quest.sid, quest);
|
|
}
|
|
}
|
|
|
|
public static cQuestEvent GetPlayEventQuestPlay(int sid)
|
|
{
|
|
return playQuestEvent[sid];
|
|
}
|
|
|
|
public static void SetPlayEventQuestPlay(cQuestEvent eventQuest)
|
|
{
|
|
playQuestEvent[eventQuest.sid] = eventQuest;
|
|
}
|
|
|
|
public static int GetPlayEventQuestDayClearCount(int day)
|
|
{
|
|
int count = 0;
|
|
foreach (var quest in sysQuestEvent.Values)
|
|
{
|
|
if (quest.day == day && playQuestEvent[quest.id].cond > 0)
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
public static cQuestAttend GetPlayEventQuestAttendPlay()
|
|
{
|
|
return playQuestEventAttend;
|
|
}
|
|
#endregion
|
|
|
|
#region Mission
|
|
public static dMission[] GetAllQuestMission()
|
|
{
|
|
return sysQuestMission.Values.ToArray();
|
|
}
|
|
|
|
public static dMission GetQuestMission(int key)
|
|
{
|
|
if (!sysQuestMission.ContainsKey(key))
|
|
return null;
|
|
return sysQuestMission[key];
|
|
}
|
|
#endregion
|
|
|
|
#region AdBuff
|
|
public static dAdBuff[] GetSysAdBuffs()
|
|
{
|
|
return sysBuff;
|
|
}
|
|
|
|
public static dAdBuff GetSysAdBuffLevel(int ilv)
|
|
{
|
|
if (ilv >= sysBuff.Length)
|
|
{
|
|
return sysBuff[sysBuff.Length - 1];
|
|
}
|
|
return sysBuff[ilv - 1];
|
|
}
|
|
|
|
public static int GetSysAdBuffMaxLevel()
|
|
{
|
|
return sysBuff.Length;
|
|
}
|
|
#endregion
|
|
|
|
#region Attend
|
|
public static dAttend[] GetSysAttend()
|
|
{
|
|
return sysAttend;
|
|
}
|
|
#endregion
|
|
|
|
#region Event
|
|
public static Dictionary<int, dEvent> GetEvents()
|
|
{
|
|
return dicEvent;
|
|
}
|
|
|
|
public static dEvent GetEvent(int key) => dicEvent.SafeGet(key);
|
|
|
|
public static dEvent GetEventByKind(eEventMoveType eventkind)
|
|
{
|
|
foreach (var item in dicEvent)
|
|
{
|
|
if (eventkind == item.Value.moveType)
|
|
return item.Value;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static Dictionary<int, dQuest> GetSysEventQuest()
|
|
{
|
|
return sysQuestEvent;
|
|
}
|
|
|
|
public static dQuest GetSysEventGetCompleteAllQuest(int day)//어느 퀘스트가 모두 완료 형식의 퀘스트인지 분간하는 용도. 모두 완료 형식은 날짜 첫번째 퀘스트가 되어야 한다.
|
|
{
|
|
for (int i = 0; i < sysQuestEvent.Count; i++)
|
|
{
|
|
if (day == sysQuestEvent[i + 1].day)
|
|
{
|
|
return sysQuestEvent[i + 1];
|
|
}
|
|
}
|
|
|
|
return sysQuestEvent[1];
|
|
}
|
|
|
|
public static dQuest GetSysEventQuest(int key)
|
|
{
|
|
if (!sysQuestEvent.ContainsKey(key))
|
|
return null;
|
|
return sysQuestEvent[key];
|
|
}
|
|
|
|
public static dEventInfo GetSysEventTrade()
|
|
{
|
|
return sysEventTrade;
|
|
}
|
|
|
|
public static dEventInfo GetSysEventRaise()
|
|
{
|
|
return sysEventRaise;
|
|
}
|
|
|
|
public static dEventInfo GetSysEventRoulette()
|
|
{
|
|
return sysEventRoulette;
|
|
}
|
|
|
|
public static cEventItem GetPlayEventTrade()
|
|
{
|
|
return playEventTrade;
|
|
}
|
|
|
|
public static cEventItem GetPlayEventRaise()
|
|
{
|
|
return playEventRaise;
|
|
}
|
|
|
|
public static void LoadPlayEventRaise(cEventItem eventItem)
|
|
{
|
|
playEventRaise = eventItem;
|
|
}
|
|
|
|
public static void LoadPlayEventRoulette(cEventItem eventItem)
|
|
{
|
|
playEventRoulette = eventItem;
|
|
}
|
|
|
|
public static cEventItem GetPlayEventRoulette()
|
|
{
|
|
return playEventRoulette;
|
|
}
|
|
|
|
public static void SetPlayEventTrade(cEventItem trade)
|
|
{
|
|
playEventTrade = trade;
|
|
}
|
|
|
|
public static dRewardEvent GetRewardEvent()
|
|
{
|
|
return sysRewardEvent;
|
|
}
|
|
#endregion
|
|
|
|
#region Shop
|
|
// 상점 시스템 데이터.
|
|
public static void LoadShopSysData(dShop[] datas)
|
|
{
|
|
for (int i = 0; i < datas.Length; ++i)
|
|
{
|
|
dShop shopItem = datas[i];
|
|
if (shopItem.rewards.Length == 0) continue;
|
|
|
|
shopItem.refreshAt = DateTime.MaxValue;
|
|
dicShop.SafeInsert(shopItem.id, shopItem);
|
|
|
|
int groupIdx = (int)shopItem.shopType;
|
|
if (groupIdx >= 0 && groupIdx < shopGroupedByShopType.Length)
|
|
{
|
|
shopGroupedByShopType[groupIdx].Add(shopItem);
|
|
}
|
|
else if (shopItem.shopType == eShopType.Pass)
|
|
{
|
|
if (TryGetPassById(shopItem.rewards[0].rewardId, out dPass pass))
|
|
{
|
|
int ipage = (int)shopItem.rewards[0].rewardCount;
|
|
if (ipage >= 0 && ipage < pass.shopIds.Length)
|
|
pass.shopIds[ipage] = shopItem.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 상점 플레이 데이터.
|
|
public static void LoadShopPlayData(sShopPlay[] playdatas)
|
|
{
|
|
for (int i = 0; i < playdatas.Length; ++i)
|
|
{
|
|
if (!dicShop.TryGetValue(playdatas[i].sid, out dShop targetShop)) continue;
|
|
|
|
targetShop.buyCnt = playdatas[i].buyCnt;
|
|
targetShop.totalCnt = playdatas[i].totalCnt;
|
|
targetShop.refreshAt = playdatas[i].refreshAt;
|
|
|
|
if (targetShop.refreshAt <= TimeUtils.Now())
|
|
{
|
|
targetShop.buyCnt = 0;
|
|
targetShop.refreshAt = DateTime.MaxValue;
|
|
}
|
|
}
|
|
|
|
// 보석/의상/무기/일반/마일리지 정렬.
|
|
SortShopIdsOrder(eShopType.Dia);
|
|
SortShopIdsOrder(eShopType.CostumeCloth);
|
|
SortShopIdsOrder(eShopType.CostumeWeapon);
|
|
SortShopIdsOrder(eShopType.General);
|
|
SortShopIdsOrder(eShopType.Mileage);
|
|
|
|
// 이벤트/특별패키지/코스튬패키지만 정렬함.
|
|
SortShopIdsOrderLimit(eShopType.Event);
|
|
SortShopIdsOrderLimit(eShopType.SpecialPack);
|
|
SortShopIdsOrderLimit(eShopType.CostumePack);
|
|
}
|
|
|
|
// 상점 아이템 sortOrder 따라 정렬. 플레이 데이터 로딩 후, 구매 제한 횟수 충족 후 호출. 보석/의상/무기/일반/마일리지 정렬.
|
|
private static void SortShopIdsOrder(eShopType shoptype)
|
|
{
|
|
var targetGroup = GetShopGroup(shoptype);
|
|
targetGroup.InsertionSort((s1, s2) => s1.sortOrder >= s2.sortOrder);
|
|
}
|
|
|
|
// 상점 아이템 sortOrder, 구매 완료에 따라 정렬. 플레이 데이터 로딩 후, 구매 제한 횟수 충족 후 호출. 이벤트/특별패키지/코스튬패키지만 정렬함.
|
|
private static void SortShopIdsOrderLimit(eShopType shoptype)
|
|
{
|
|
var targetGroup = GetShopGroup(shoptype);
|
|
targetGroup.InsertionSort((s1, s2) => {
|
|
int s1SortOrder = s1.sortOrder + (s1.buyCnt >= s1.limitCnt ? 100000 : 0);
|
|
int s2SortOrder = s2.sortOrder + (s2.buyCnt >= s2.limitCnt ? 100000 : 0);
|
|
return s1SortOrder >= s2SortOrder; });
|
|
}
|
|
|
|
// 상점 정렬된 ID 목록 가져오기.
|
|
public static List<dShop> GetShopGroup(eShopType shoptype)
|
|
{
|
|
int groupIdx = (int)shoptype;
|
|
if (groupIdx < 0 || groupIdx >= shopGroupedByShopType.Length) return new List<dShop>();
|
|
return shopGroupedByShopType[groupIdx];
|
|
}
|
|
|
|
// 상점 데이터 가져오기.
|
|
public static dShop GetShop(int key)
|
|
{
|
|
return dicShop[key];
|
|
}
|
|
|
|
// 인덱스로 상점 데이터 가져오기.
|
|
public static dShop GetShopByIndex(eShopType shoptype, int index)
|
|
{
|
|
var targetGroup = GetShopGroup(shoptype);
|
|
if (targetGroup is null) return null;
|
|
else return targetGroup[index];
|
|
}
|
|
|
|
// 상점 구매 초기화 처리.
|
|
public static void ResetShop()
|
|
{
|
|
foreach (var item in dicShop.Values)
|
|
{
|
|
if (item.refreshAt <= TimeUtils.Now())
|
|
{
|
|
item.buyCnt = 0;
|
|
item.refreshAt = DateTime.MaxValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 가격 텍스트 가져오기.
|
|
public static string GetShopPrice(int key, int icount)
|
|
{
|
|
if (key < 0 || !dicShop.ContainsKey(key))
|
|
return FormatString.TextPriceCash(9999);
|
|
dShop data = dicShop[key];
|
|
if (data.buyingType == cGoods.TAds)
|
|
return LocalizationText.GetText("adbuff_playad");
|
|
if (data.buyingType == cGoods.TCash)
|
|
{
|
|
if (string.IsNullOrEmpty(data.productId))
|
|
return FormatString.TextPriceCash(data.buyingCnt * icount);
|
|
string strprice = IapMgr.SGetPrice(data.productId);
|
|
if (!string.IsNullOrEmpty(strprice))
|
|
return strprice;
|
|
return FormatString.TextPriceCash(data.buyingCnt * icount);
|
|
}
|
|
return FormatString.TextInt(data.buyingCnt * icount);
|
|
}
|
|
|
|
// 구매 후 처리.
|
|
public static void BuyShop(int key, int ibuycnt, int itotalcnt, DateTime refreshtime)
|
|
{
|
|
if (key < 0 || !dicShop.ContainsKey(key))
|
|
return;
|
|
dShop data = dicShop[key];
|
|
data.buyCnt = ibuycnt;
|
|
data.totalCnt = itotalcnt;
|
|
if (data.refreshType == eRefreshType.None || data.refreshType == eRefreshType.Account)
|
|
data.refreshAt = DateTime.MaxValue;
|
|
else
|
|
data.refreshAt = refreshtime;
|
|
|
|
// 이벤트/특별패키지/코스튬패키지만 정렬함.
|
|
if (data.buyCnt >= data.limitCnt && data.shopType == eShopType.Event || data.shopType == eShopType.SpecialPack || data.shopType == eShopType.CostumePack)
|
|
SortShopIdsOrderLimit(data.shopType);
|
|
}
|
|
#endregion Shop
|
|
|
|
#region Pass
|
|
// 패스 시스템 데이터. 패스ID가 아닌 조건을 키로 사용.
|
|
public static void LoadPassSysData(dPass[] datas)
|
|
{
|
|
for (int i = 0; i < datas.Length; ++i)
|
|
{
|
|
dPass pass = datas[i];
|
|
|
|
int len = ((pass.levels.Length - 1) / pass.passUnit) + 1;
|
|
pass.isPaid = new bool[len];
|
|
pass.haveLvFrees = new int[len];
|
|
pass.haveLvPaids = new int[len];
|
|
pass.shopIds = new int[len];
|
|
pass.shopIds.SetElements(-1);
|
|
pass.refreshAt = pass.endAt;
|
|
|
|
// 1. 일회성 패스, 2. 이벤트 패스.
|
|
if (pass.passType == 1)
|
|
{
|
|
dicPass.SafeInsert(pass.condType, pass);
|
|
}
|
|
else if (pass.passType == 2)
|
|
{
|
|
if (pass.startAt <= TimeUtils.Now()) passEvent = pass;
|
|
else passEventNext = pass;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 패스 플레이 데이터.
|
|
public static void LoadPassPlayData(sPassPlay[] playdatas)
|
|
{
|
|
for (int i = 0; i < playdatas.Length; ++i)
|
|
{
|
|
sPassPlay playData = playdatas[i];
|
|
if (!TryGetPassById(playData.sid, out dPass sysData)) continue;
|
|
|
|
if (playData.refreshAt < sysData.endAt)
|
|
sysData.refreshAt = playData.refreshAt;
|
|
|
|
// 달성도 세팅.
|
|
switch (sysData.condType)
|
|
{
|
|
case eCondition.StageClear:
|
|
sysData.progress = PlayData.clearStage;
|
|
break;
|
|
case eCondition.PlayerLv:
|
|
sysData.progress = PlayData.playerLv;
|
|
break;
|
|
default:
|
|
if (bLoadLocalData)
|
|
sysData.progress = ES3.Load(playData.sid.ToString(), Global.ES3_Pass, 0);
|
|
else
|
|
sysData.progress = playData.progress;
|
|
break;
|
|
}
|
|
|
|
// 유료 구매, 보상 수령 상태.
|
|
if (playData.isPaid != null)
|
|
Array.Copy(playdatas[i].isPaid, sysData.isPaid, sysData.isPaid.Length);
|
|
if (playData.haveLvFrees != null)
|
|
Array.Copy(playdatas[i].haveLvFrees, sysData.haveLvFrees, sysData.haveLvFrees.Length);
|
|
if (playData.haveLvPaids != null)
|
|
Array.Copy(playdatas[i].haveLvPaids, sysData.haveLvPaids, sysData.haveLvPaids.Length);
|
|
|
|
// 달성도 레벨 계산.
|
|
sysData.availLevel = 0;
|
|
while (sysData.progress >= sysData.levels[sysData.availLevel].condValue)
|
|
{
|
|
if (++sysData.availLevel >= sysData.levels.Length)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 패스 목록 가져오기.
|
|
public static Dictionary<eCondition, dPass> GetPasses()
|
|
{
|
|
return dicPass;
|
|
}
|
|
|
|
// 아이디로 패스 가져오기.
|
|
public static bool TryGetPassById(int id, out dPass result)
|
|
{
|
|
result = null;
|
|
if (passEvent != null && id == passEvent.id) result = passEvent;
|
|
else if (passEventNext != null && id == passEventNext.id) result = passEventNext;
|
|
else
|
|
{
|
|
foreach (var item in dicPass.Values)
|
|
{
|
|
if (id == item.id)
|
|
{
|
|
result = item;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return result != null;
|
|
}
|
|
|
|
// 패스 정보 가져오기.
|
|
public static bool TryGetPass(int passtype, eCondition condtype, out dPass result)
|
|
{
|
|
result = null;
|
|
|
|
// 1. 일회성 패스. 2. 이벤트 패스.
|
|
if (passtype == 1 && dicPass.TryGetValue(condtype, out result)) { }
|
|
else if (passtype == 2 && passEvent?.condType == condtype) result = passEvent;
|
|
|
|
return result != null;
|
|
}
|
|
|
|
public static IList<dPass> GetPassesByCond(eCondition condtype)
|
|
{
|
|
var result = new List<dPass>();
|
|
|
|
if (dicPass.TryGetValue(condtype, out dPass pass))
|
|
result.Add(pass);
|
|
|
|
if (passEvent?.condType == condtype)
|
|
result.Add(passEvent);
|
|
|
|
return result;
|
|
}
|
|
|
|
// 패스 진행도. 일반 몬스터 처치 등 자주 처리되는 것이 있을 수 있으므로 여기서 바로 저장하지는 않음.
|
|
public static void SetPassProgress(eCondition condtype, int ivalue)
|
|
{
|
|
foreach (var item in GetPassesByCond(condtype))
|
|
{
|
|
item.progress = ivalue;
|
|
}
|
|
}
|
|
|
|
// 패스 진행도. 일반 몬스터 처치 등 자주 처리되는 것이 있을 수 있으므로 여기서 바로 저장하지는 않음.
|
|
public static void AddPassProgress(eCondition condtype, int ivalue)
|
|
{
|
|
foreach (var item in GetPassesByCond(condtype))
|
|
{
|
|
item.progress += ivalue;
|
|
}
|
|
}
|
|
|
|
// 패스 진행도 계산. 보상 획득 시점, 뱃지 갱신할때 호출.
|
|
public static void CalcPassProgress(int passtype, eCondition condtype)
|
|
{
|
|
if (!TryGetPass(passtype, condtype, out dPass targetPass)) return;
|
|
|
|
// 이미 최고 단계까지 달성했을 경우.
|
|
if (targetPass.availLevel >= targetPass.levels.Length) return;
|
|
|
|
// 달성 단계 다시 계산.
|
|
while (targetPass.progress >= targetPass.levels[targetPass.availLevel].condValue)
|
|
{
|
|
if (++targetPass.availLevel >= targetPass.levels.Length)
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 패스 수령 가능한 보상이 있는지.
|
|
public static bool IsPassRewardAvail(int passtype, eCondition condtype)
|
|
{
|
|
if (!TryGetPass(passtype, condtype, out dPass targetPass)) return false;
|
|
|
|
for (int i = 0; i < targetPass.isPaid.Length; ++i)
|
|
{
|
|
if(IsPassRewardAvail(passtype, condtype, i))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 패스 현재 페이지에 수령 가능한 보상이 있는지.
|
|
public static bool IsPassRewardAvail(int passtype, eCondition condtype, int pageindex)
|
|
{
|
|
if (!TryGetPass(passtype, condtype, out dPass targetPass)) return false;
|
|
if (pageindex >= targetPass.isPaid.Length) return false;
|
|
|
|
int minindexinc = pageindex * targetPass.passUnit;
|
|
// 수령 가능한 최대 항목이 페이지 처음 항목 이전일 경우.
|
|
if (targetPass.availLevel <= minindexinc) return false;
|
|
|
|
int[] targetHaveLv;
|
|
if (targetPass.isPaid[pageindex]) targetHaveLv = targetPass.haveLvPaids;
|
|
else targetHaveLv = targetPass.haveLvFrees;
|
|
|
|
// 페이지에서 수령한 항목이 페이지의 마지막 항목 이전일 경우.
|
|
int maxindexexc = (pageindex + 1) * targetPass.passUnit;
|
|
if (targetHaveLv[pageindex] < maxindexexc)
|
|
{
|
|
// 수령 가능한 항목이 있을 경우.
|
|
if (targetHaveLv[pageindex] < targetPass.availLevel)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// 패스 보상 획득시 처리.
|
|
public static void RecvPassReward(int passtype, eCondition condtype, int pageindex, int level)
|
|
{
|
|
if(!TryGetPass(passtype, condtype, out dPass targetPass)) return;
|
|
|
|
targetPass.haveLvFrees[pageindex] = level;
|
|
if (targetPass.isPaid[pageindex])
|
|
targetPass.haveLvPaids[pageindex] = level;
|
|
}
|
|
|
|
// 패스 구매.
|
|
public static void BuyPass(int passtype, eCondition condtype, int pageindex)
|
|
{
|
|
if (!TryGetPass(passtype, condtype, out dPass targetPass)) return;
|
|
|
|
targetPass.isPaid[pageindex] = true;
|
|
}
|
|
|
|
// 패스 저장.
|
|
private static void SavePass()
|
|
{
|
|
// 일회성 패스.
|
|
foreach (var item in dicPass)
|
|
ES3.Save(item.Value.id.ToString(), item.Value.progress, Global.ES3_Pass);
|
|
|
|
// 이벤트 패스.
|
|
if (passEvent != null)
|
|
ES3.Save(passEvent.id.ToString(), passEvent.progress, Global.ES3_Pass);
|
|
}
|
|
|
|
// 이벤트/반복 패스 갱신(초기화).
|
|
public static bool ResetPass()
|
|
{
|
|
bool breset = false;
|
|
|
|
// 이벤트 패스 갱신.
|
|
// 현재 이벤트 패스가 존재함.
|
|
if (passEvent != null)
|
|
{
|
|
// 이벤트 패스가 종료되었을 때.
|
|
if (passEvent.endAt <= TimeUtils.Now())
|
|
{
|
|
breset = true;
|
|
// 다음 이벤트 패스가 없음.
|
|
if (passEventNext == null)
|
|
{
|
|
passEvent = null;
|
|
}
|
|
// 다음 이벤트 패스가 존재하고, 시작 시간이 되었을 때. 이벤트 패스 교체.
|
|
else if (passEventNext != null && passEventNext.startAt >= TimeUtils.Now())
|
|
{
|
|
passEvent = passEventNext;
|
|
passEventNext = null;
|
|
}
|
|
// 다음 이벤트 패스가 존재하지만, 아직 시작 시간이 아닐 때.
|
|
else
|
|
{
|
|
passEvent = null;
|
|
}
|
|
}
|
|
}
|
|
// 현재 이벤트 패스가 없으며, 다음 이벤트 패스가 존재하고, 시작 시간이 되었을 때. 이벤트 패스 교체.
|
|
else if (passEventNext != null && passEventNext.startAt >= TimeUtils.Now())
|
|
{
|
|
breset = true;
|
|
passEvent = passEventNext;
|
|
passEventNext = null;
|
|
}
|
|
// 다음 이벤트 패스가 존재하지만, 아직 시작 시간이 아닐 때.
|
|
else
|
|
{
|
|
breset = true;
|
|
passEvent = null;
|
|
}
|
|
|
|
return breset;
|
|
}
|
|
#endregion Pass
|
|
|
|
#region Mail
|
|
// 우편 데이터 로드.
|
|
public static void LoadMail(dMail[] mails, bool bupdatecount, bool bserver)
|
|
{
|
|
if (mails == null)
|
|
mails = new dMail[0];
|
|
|
|
playMails = mails;
|
|
|
|
if (bupdatecount)
|
|
MailCount = playMails.Length;
|
|
if (bserver)
|
|
MailRefreshTime = TimeUtils.Now().AddMinutes(5d);
|
|
}
|
|
|
|
// 읽은 우편 데이터 로드.
|
|
public static void LoadMailRead(dMail[] reads, bool bserver)
|
|
{
|
|
if (reads == null)
|
|
reads = new dMail[0];
|
|
|
|
readMails = reads;
|
|
|
|
if (bserver)
|
|
MailReadRefreshTime = TimeUtils.Now().AddMinutes(5d);
|
|
}
|
|
|
|
// 우편 수.
|
|
public static void SetMailCount(int icnt)
|
|
{
|
|
MailCount = icnt;
|
|
if (playMails != null && MailCount != playMails.Length)
|
|
MailRefreshTime = TimeUtils.Now();
|
|
}
|
|
|
|
// 우편 내역 갱신 시간 수정.
|
|
public static void UpdateMailReadTime()
|
|
{
|
|
if (readMails != null)
|
|
MailReadRefreshTime = TimeUtils.Now();
|
|
}
|
|
|
|
// 우편 목록.
|
|
public static dMail[] GetMails()
|
|
{
|
|
return playMails;
|
|
}
|
|
|
|
// 읽은 우편 목록.
|
|
public static dMail[] GetMailReads()
|
|
{
|
|
return readMails;
|
|
}
|
|
|
|
// 우편(인덱스).
|
|
public static dMail GetMailByIndex(int itype, int index)
|
|
{
|
|
if (playMails == null)
|
|
return null;
|
|
|
|
// 읽지 않은 우편.
|
|
if (itype == 0)
|
|
{
|
|
if (index >= playMails.Length)
|
|
return null;
|
|
return playMails[index];
|
|
}
|
|
|
|
// 읽은 우편.
|
|
if (index >= readMails.Length)
|
|
return null;
|
|
return readMails[index];
|
|
}
|
|
|
|
// 우편(인덱스).
|
|
public static dMail GetMailByIndex(int index)
|
|
{
|
|
if (playMails == null || index >= playMails.Length)
|
|
return null;
|
|
return playMails[index];
|
|
}
|
|
|
|
// 읽은 우편(인덱스).
|
|
public static dMail GetMailReadByIndex(int index)
|
|
{
|
|
if (readMails == null || index >= readMails.Length)
|
|
return null;
|
|
return readMails[index];
|
|
}
|
|
#endregion Mail
|
|
|
|
#region Pvp
|
|
// 결투장 데이터.
|
|
public static void LoadPvpData(cPvpPlay _playPvp, dPvpRank pvpmyrank)
|
|
{
|
|
playPvp = _playPvp;
|
|
pvpMyRank = pvpmyrank;
|
|
|
|
playPvp.availWeeklyIndex = -1;
|
|
for (int i = sysPvp.missions.Length - 1; i >= 0; --i)
|
|
{
|
|
if (playPvp.weeklyTry >= sysPvp.missions[i].condValue)
|
|
{
|
|
playPvp.availWeeklyIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
dPvpTier tier = GetPvpTier(pvpMyRank.tier);
|
|
BuffMgr.Instance.SetPvpTier(tier.abilityValue1, tier.abilityValue2, tier.abilityValue3, tier.abilityValue4);
|
|
}
|
|
|
|
// 결투장 플레이 데이터 업데이트.
|
|
public static void UpdatePvpPlay(cPvpPlay pvpplay)
|
|
{
|
|
playPvp = pvpplay;
|
|
|
|
playPvp.availWeeklyIndex = -1;
|
|
for (int i = sysPvp.missions.Length - 1; i >= 0; i--)
|
|
{
|
|
if (playPvp.weeklyTry >= sysPvp.missions[i].condValue)
|
|
{
|
|
playPvp.availWeeklyIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 결투장 프리셋 변경.
|
|
public static void UpdatePvpPreset(int skillpreset, int petpreset, int awakenpreset)
|
|
{
|
|
playPvp.usePreset = skillpreset;
|
|
playPvp.usePetPreset = petpreset;
|
|
playPvp.useExtraPreset = awakenpreset;
|
|
}
|
|
|
|
// 결투장 플레이 랭킹 업데이트.
|
|
public static void UpdatePvpMyRank(dPvpRank pvpmyrank)
|
|
{
|
|
int itierprev = pvpMyRank.tier;
|
|
pvpMyRank = pvpmyrank;
|
|
|
|
// 티어 변경 시 능력치 변경.
|
|
if (itierprev != pvpMyRank.tier)
|
|
{
|
|
dPvpTier tier = GetPvpTier(pvpMyRank.tier);
|
|
BuffMgr.Instance.SetPvpTier(tier.abilityValue1, tier.abilityValue2, tier.abilityValue3, tier.abilityValue4);
|
|
}
|
|
}
|
|
|
|
// 결투장 랭킹 업데이트.
|
|
public static void UpdatePvpRank(dPvpRank[] pvpRanks)
|
|
{
|
|
DataHandler.pvpRanks = pvpRanks;
|
|
PvpRankRefreshTime = TimeUtils.Now().AddMinutes(5d);
|
|
}
|
|
|
|
// 결투장 보상 데이터 가져오기.
|
|
public static dPvpRew GetPvpReward(int index) => sysPvp.missions.ClampGet(index);
|
|
|
|
// 결투장 티어 목록 가져오기.
|
|
public static dPvpTier[] GetPvpTiers() => sysPvp.tier;
|
|
|
|
// 결투장 티어 가져오기.
|
|
public static dPvpTier GetPvpTier(int tier) => sysPvp.tier.ClampGet(tier - 1);
|
|
|
|
// 결투장 티어 가져오기.
|
|
public static bool TryGetPvpRank(int rank, out dPvpRank result)
|
|
{
|
|
result = null;
|
|
int idx = rank - 1;
|
|
if (idx >= 0 && idx < pvpRanks.Length)
|
|
result = pvpRanks[idx];
|
|
return result != null;
|
|
}
|
|
#endregion Pvp
|
|
|
|
#region Notice
|
|
public static void SetNewNotices(dNotice[] newNotices) => sysNotices = newNotices;
|
|
public static dNotice[] GetNotices() => sysNotices;
|
|
public static bool TryGetNotice(int index, out dNotice result) => sysNotices.TryGetValueAt(index, out result);
|
|
|
|
public static void SetNewChatNotices(dChatNotice[] newNotices) => sysChatNotices = newNotices;
|
|
public static dChatNotice[] GetChatNotices() => sysChatNotices;
|
|
#endregion Notice
|
|
|
|
#region LevelUpInterval
|
|
static List<BigInteger> goldAtkLevel1000Interval = new List<BigInteger>();
|
|
static List<BigInteger> goldHPLevel1000Interval = new List<BigInteger>();
|
|
static List<BigInteger> exp1000Interval = new List<BigInteger>();
|
|
|
|
public static BigInteger GetGoldLevelInterval(int Level)
|
|
{
|
|
if (Level / 1000<goldAtkLevel1000Interval.Count)
|
|
{
|
|
return goldAtkLevel1000Interval[Level / 1000];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public static BigInteger GetHpLevelInterval(int Level)
|
|
{
|
|
if (Level / 1000 < goldHPLevel1000Interval.Count)
|
|
{
|
|
return goldHPLevel1000Interval[Level / 1000];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public static BigInteger PlayerLevelInterval(int Level)
|
|
{
|
|
if (Level / 1000 < exp1000Interval.Count)
|
|
{
|
|
return exp1000Interval[Level / 1000];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public static void PutGoldInterval1000()
|
|
{
|
|
dCharStat atkEnhance = GetCharStat(1);
|
|
dCharStat hpEnhance = GetCharStat(2);
|
|
|
|
for (int i = 0; i < atkEnhance.maxLv / 1000; i++)
|
|
{
|
|
double eja = (dConst.RateMaxFloat + (double)(atkEnhance.buyingCntInc - dConst.RateMax)) / dConst.RateMax;
|
|
eja = Math.Pow(eja, 1000 * i);
|
|
BigInteger iprice = atkEnhance.buyingCount * (BigInteger)(eja * dConst.RateMax) / dConst.RateMax;
|
|
|
|
goldAtkLevel1000Interval.Add(iprice);
|
|
}
|
|
|
|
for (int i = 0; i < hpEnhance.maxLv / 1000; i++)
|
|
{
|
|
double eja = (dConst.RateMaxFloat + (double)(hpEnhance.buyingCntInc - dConst.RateMax)) / dConst.RateMax;
|
|
eja = Math.Pow(eja, 1000 * i);
|
|
BigInteger iprice = hpEnhance.buyingCount * (BigInteger)(eja * dConst.RateMax) / dConst.RateMax;
|
|
|
|
goldHPLevel1000Interval.Add(iprice);
|
|
}
|
|
|
|
for(int i = 0; i < Const.playerMaxLv / 1000; i++)
|
|
{
|
|
double eja = (dConst.RateMaxFloat + (double)(Const.playerLvExpInc - dConst.RateMax)) / dConst.RateMax;
|
|
eja = Math.Pow(eja, 1000 * i);
|
|
BigInteger iprice = Const.playerLvExp * (BigInteger)(eja * dConst.RateMax) / dConst.RateMax;
|
|
|
|
exp1000Interval.Add(iprice);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public static BigInteger CalcBattlePower(BigInteger atk, BigInteger hp)
|
|
{
|
|
return (atk * 5) + hp;
|
|
}
|
|
|
|
static bool isNotice = false;
|
|
static DateTime startSvCheck;
|
|
static string updateMsg;
|
|
|
|
public static void SetUpdateNoticeInfo(bool infoNotice, DateTime infoSvCheck, string msg)
|
|
{
|
|
isNotice = infoNotice;
|
|
startSvCheck = infoSvCheck;
|
|
updateMsg = msg;
|
|
}
|
|
|
|
public static void isUpdateNotice()
|
|
{
|
|
if (isNotice)
|
|
{
|
|
SingleMgr.ChangeAlartTrue();
|
|
GameUIMgr.SOpenToastNotice(FormatString.StringFormat(LocalizationText.GetText(updateMsg), FormatString.TextDateTimeUtc9Clock1(startSvCheck)));
|
|
}
|
|
else
|
|
{
|
|
SingleMgr.ChangeAlartFalse();
|
|
GameUIMgr.CloseToastNotice();
|
|
}
|
|
}
|
|
}
|