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

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();
}
}
}