// ***********************************************************************
// Assembly : Game
// Author : Kimch
// Created : 2021-03-26
// Description :
// Last Modified By :
// Last Modified On :
// ***********************************************************************
//
//
// ***********************************************************************
using CodeStage.AntiCheat.ObscuredTypes;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace G
{
///
///
///
public class PetProxy : F.GameProxy
{
public class PetInfo
{
///
///
///
public readonly ItemPet item;
public readonly PetSkillInfo mainSkill;
public readonly List skills = new List();
///
///
///
ItemPetLevel currLevelItem => ItemProxy.Instance.GetStaticItem(grade);
///
/// id
///
public int id => item.id;
///
///
///
public string name
{
get
{
var saveName = ArchiveProxy.Instance.GetString(this.id);
if (!string.IsNullOrEmpty(saveName))
return saveName;
return item.name;
}
set
{
ArchiveProxy.Instance.SetString(this.id, value);
}
}
///
///
///
public string[] icon
{
get { return item.icon; }
}
private ObscuredInt _friend = -1;
///
///
///
public int friend
{
get => _friend;
private set { _friend = value; }
}
private ObscuredInt _friendMax = 0;
///
///
///
public int friendMax
{
get { return _friendMax; }
private set { _friendMax = value; }
}
///
///
///
public int friendId
{
get { return item.active[0]; }
}
///
///
///
///
public bool AddFriend(int value)
{
if (isUnlock)
{
friend += value;
bool result = isFriend;
SaveLocal();
return result;
}
return false;
}
///
/// 已结交
///
public bool isFriend
{
get
{
if (grade > 0)
return true;
if (isUnlock && friend >= friendMax)
{
grade = 1;
MissionProxy.Instance.OnEvent(MissionProxy.解锁宠物数量);
return true;
}
return false;
}
}
///
///
///
public bool isUnlock
{
get
{
if (this.friend >= 0)
{
return true;
}
else
{
var mission = MissionProxy.Instance.GetMission(item.unlock);
if (mission != null && mission.isCompleted)
{
this.friend = 0;
return true;
}
return false;
}
}
}
///
///
///
public string unlockText
{
get
{
var mission = MissionProxy.Instance.GetMission(item.unlock);
if (mission != null)
{
return mission.description;
}
return "";
}
}
///
///
///
public ItemAccess access
{
get { return ItemProxy.Instance.GetStaticItem(item.access); }
}
private ObscuredInt _grade = 0;
///
/// 等级
///
public int grade
{
get { return _grade; }
private set
{
if (value <= gradeMax && value != grade)
{
_grade = value;
attributes.Clear();
var sources = item.attributes;
if (sources != null)
for (int i = 0; i < sources.Length; i++)
{
attributes.Add(new CombatAttribute
{
id = (CombatAttributeId)sources[i][0],
value = sources[i][1] + value * sources[i][2],
});
}
}
}
}
///
/// 等级上限
///
public int gradeMax
{
get;
private set;
}
///
///
///
public bool isMaxGrade => grade >= gradeMax;
///
///
///
///
///
public bool AddGrade(int value)
{
bool result = true;
int tmpGrade = this.grade + value;
int tmpGradeMax = this.gradeMax;
if (tmpGrade > tmpGradeMax)
{
tmpGrade = tmpGradeMax;
}
this.grade = tmpGrade;
SaveLocal();
MissionProxy.Instance.OnEvent(MissionProxy.宠物升级次数);
return result;
}
private ObscuredInt _exp = 0;
///
///
///
public int exp
{
get { return _exp; }
private set { _exp = value; }
}
///
///
///
public int expMax
{
get
{
var levelItem = this.currLevelItem;
return levelItem != null ? levelItem.exp : 1;
}
}
///
///
///
///
///
public bool AddExp(int value)
{
bool result = false;
int tmpExp = this.exp + value;
int tmpExpMax = this.expMax;
int tmpLevel = this.grade;
if (tmpExp >= tmpExpMax)
{
tmpExp -= tmpExpMax;
tmpLevel += 1;
result = true;
}
this.exp = tmpExp;
this.grade = tmpLevel;
SaveLocal();
MissionProxy.Instance.OnEvent(MissionProxy.宠物升级次数);
return result;
}
///
/// 伤害
///
public int damage
{
get;
set;
}
///
/// 速度
///
public float speed
{
get { return item.speed * 0.001f; }
}
///
///
///
public int splash => item.splash;
///
///
///
public int bullet => item.bullet;
///
///
///
public float bulletDamage
{
get
{
if (grade > 0)
return currLevelItem.damage * 0.01f;
return item.damage * 0.01f;
}
}
///
///
///
public float bulletSpeed
{
get
{
if (grade > 0)
return currLevelItem.bulletSpeed * 0.001f;
return item.bulletSpeed * 0.001f;
}
}
///
///
///
public int bulletNumber
{
get
{
if (grade > 0)
return currLevelItem.bulletNumber;
return item.bulletNumber;
}
}
///
///
///
public int bulletLayer
{
get { return item.bulletLayer; }
}
///
///
///
public int combatValue
{
get
{
int result = item.combatValue;
int tmpGrade = this.grade;
if (tmpGrade > 0)
{
var levelItem = this.currLevelItem;
if (levelItem != null)
result += levelItem.combatValue;
for (int i = 0; i < attributes.Count; i++)
{
var attr = attributes[i];
result += attr.combatValue;
}
}
for (int i = 0; i < skills.Count; i++)
{
if (skills[i] != null && tmpGrade >= i * 10)
result += skills[i].combatValue;
}
return result;
}
}
///
///
///
public readonly List attributes = new List();
///
/// 出战中
///
public bool isBattling
{
get { return this == PetProxy.Instance.battlePet; }
set
{
PetProxy.Instance.battlePet = value ? this : null;
}
}
public PetInfo(ItemPet petItem)
{
this.item = petItem;
friendMax = petItem.active[1];
gradeMax = ItemProxy.Instance.GetStaticItems().Count;
if (petItem.mainSkills != null)
mainSkill = new PetSkillInfo(ItemProxy.Instance.GetStaticItem(petItem.mainSkills[0]));
for (int i = 0; i < petItem.skills.Length; i++)
{
var petSkillItem = ItemProxy.Instance.GetStaticItem(petItem.skills[i]);
skills.Add(new PetSkillInfo(petSkillItem));
}
LoadLocal();
}
///
///
///
///
///
public void Set(int level, int exp)
{
this.grade = level;
this.exp = exp;
MissionProxy.Instance.OnEvent(MissionProxy.解锁宠物数量);
SaveLocal();
}
///
///
///
public void Reset()
{
grade = 0;
exp = 0;
}
///
///
///
///
public bool Active()
{
return AddFriend(friendMax);
}
///
///
///
///
public int Upgrade()
{
if (grade > 0 && grade < gradeMax)
{
var up = AddExp(100);
if (up)
{
Instance.UpdateAttributes(true);
}
return up ? 2 : 1;
}
return 0;
}
public IList CheckSkill()
{
var tmpGrade = this.grade;
for (int i = 0; i < skills.Count; i++)
{
skills[i].grade = tmpGrade < i * 10 ? i * 10 : 0;
}
return skills;
}
///
///
///
///
public bool CheckUpgrade()
{
if (this.isFriend)
{
var costs = CalcUpgradeCost();
return MoneyProxy.Instance.CheckMoney(costs);
}
return false;
}
static readonly Item.ItemInfo[] _UpgradeCost = new Item.ItemInfo[0];
public IList CalcUpgradeCost()
{
//_UpgradeCost[0].Set(20, grade / 10 + 1);
//_UpgradeCost[1].Set(1, grade * 100);
return _UpgradeCost;
}
///
///
///
public Item.ItemInfo recastCostLow
{
get
{
var petConst = ItemProxy.Instance.GetStaticItem(1);
var cost = petConst.recastCostInfo1;
cost.count = item.skills.Length;
return cost;
}
}
///
///
///
public Item.ItemInfo recastCostHigh
{
get
{
var petConst = ItemProxy.Instance.GetStaticItem(1);
var cost = petConst.recastCostInfo2;
cost.count = item.skills.Length;
return cost;
}
}
///
///
///
///
public bool CheckRecast()
{
return grade >= Mathf.Min(30, (skills.Count - 1) * 10);
}
///
///
///
public void ApplyRecast()
{
//防止错误
if (_RecastedPetSkills[0] == null)
{
return;
}
skills.Clear();
for (int i = 0; i < 8; i++)
{
if (_RecastedPetSkills[i] != null)
{
skills.Add(_RecastedPetSkills[i]);
}
}
SaveLocal();
ResetRecast();
Instance.UpdateAttributes(true);
}
///
///
///
public void ResetRecast()
{
for (int i = 0; i < 8; i++)
{
_RecastedPetSkills[i] = null;
}
//int skillCount = skills.Count;
//for (int i = 0; i < skillCount; i++)
//{
// _RecastedPetSkills[i] = skills[i];
//}
}
///
///
///
public IList recastSkills
{
get
{
if (_RecastedPetSkills[0] == null)
{
return null;
}
return _RecastedPetSkills;
}
}
static readonly PetSkillInfo[] _RecastedPetSkills = new PetSkillInfo[8];
///
///
///
///
public PetSkillInfo[] RecastSkills(bool high, bool[] lockFilter)
{
int skillCount = skills.Count;
for (int i = 0; i < skillCount; i++)
{
if (_RecastedPetSkills[i] == null)
{
_RecastedPetSkills[i] = skills[i];
}
}
for (int i = 0; i < 8; i++)
{
if (!lockFilter[i])
_RecastedPetSkills[i] = null;
}
for (int i = 0; i < skillCount; i++)
{
if (_RecastedPetSkills[i] == null)
{
var rndSkill = GetRandomSkill(high, i);
_RecastedPetSkills[i] = rndSkill;
}
}
MissionProxy.Instance.OnEvent(MissionProxy.宠物技能洗练);
return _RecastedPetSkills;
}
///
///
///
///
///
///
PetSkillInfo GetRandomSkill(bool high, int index)
{
var petConst = ItemProxy.Instance.GetStaticItem(1);
var skillPool = high ? petConst.skillPool2 : petConst.skillPool1;
if (skillPool.Length <= index)
return null;
int resultId = 0;
int loop = 0;
do
{
loop++;
resultId = 0;
int skillId = GlobalUtils.GetRandom(skillPool);
for (int i = 0; i < 8; i++)
{
if (_RecastedPetSkills[i] != null && _RecastedPetSkills[i].id == skillId)
{
resultId = -1;
break;
}
}
if (resultId == 0)
{
resultId = skillId;
}
} while (resultId < 0 && loop < 1000);
var petSkillItem = ItemProxy.Instance.GetStaticItem(resultId);
return new PetSkillInfo(petSkillItem);
}
public int GetAttributes(List results)
{
if (grade > 0)
{
for (int i = 0; i < attributes.Count; i++)
{
var attr = attributes[i];
results.Add(attr);
}
}
return this.combatValue;
}
void SaveLocal()
{
var dataList = ArchiveProxy.Instance.GetIntList(this.id);
if (dataList != null)
{
dataList.Clear();
dataList.Add(friend);
dataList.Add(grade);
dataList.Add(exp);
dataList.Add(skills.Count);
for (int i = 0; i < skills.Count; i++)
{
dataList.Add(skills[i].id);
}
ArchiveProxy.Instance.SetIntList(this.id, dataList);
}
}
void LoadLocal()
{
var dataList = ArchiveProxy.Instance.GetIntList(this.id);
if (dataList != null && dataList.Count > 0)
{
int index = 0;
friend = dataList[index++];
grade = dataList[index++];
exp = dataList[index++];
skills.Clear();
int skillCount = dataList.SafeGet(index++);
for (int i = 0; i < skillCount; i++)
{
var skillItem = ItemProxy.Instance.GetStaticItem(dataList.SafeGet(index++));
if (skillItem != null)
skills.Add(new PetSkillInfo(skillItem));
}
}
}
}
///
///
///
public class PetSkillInfo
{
public readonly ItemPetSkill item;
///
///
///
public int id => item.id;
///
///
///
public int combatValue => item.combatValue;
public int grade
{
get;
set;
}
public bool isUnlock => grade == 0;
public PetSkillInfo(ItemPetSkill petSkillItem)
{
this.item = petSkillItem;
}
}
#region Field
///
/// 上战宠物
///
private int _battlePetId;
///
///
///
readonly Dictionary _pets = new Dictionary(8);
int _feedTimestamp;
#endregion
#region Property
///
///
///
public PetInfo battlePet
{
get { _pets.TryGetValue(_battlePetId, out var result); return result; }
set
{
_battlePetId = value != null ? value.item.id : 0;
SaveLocal();
}
}
public int petFeedTimestamp => _feedTimestamp;
///
///
///
public int combatValue => PlayerProxy.Instance.GetCombatValue(PlayerProxy.ATTRIBUTES_INDEX_PET);
#endregion
#region Method
///
///
///
///
public IReadOnlyCollection GetAllPets()
{
return _pets.Values;
}
///
///
///
///
///
public PetInfo GetPet(int id)
{
_pets.TryGetValue(id, out var result);
return result;
}
///
///
///
///
public int GetPetCombatValue()
{
return PlayerProxy.Instance.GetCombatValue(PlayerProxy.ATTRIBUTES_INDEX_PET);
}
///
///
///
///
///
public int UpgradePet(PetInfo pet, bool ad)
{
if (pet.isMaxGrade)
{
return 0;
}
if (ad)
{
int feedCount = TimeProxy.Instance.GetTimes(TimeProxy.宠物升级);
if (feedCount <= 0)
return 0;
}
int result = 1;
if (pet.AddGrade(ad ? 2 : 1))
{
result = 2;
}
if (ad)
{
TimeProxy.Instance.CostTimes(TimeProxy.宠物升级);
}
else
{
_feedTimestamp = Launch.Timestamp + 60 * 60 * 8;
}
SaveLocal();
UpdateAttributes(true);
return result;
}
public int GetRedPoint()
{
var remainTime = petFeedTimestamp - Launch.Timestamp;
if (remainTime <= 0)
{
return 1;
}
//foreach (var pet in _pets.Values)
//{
// if (pet.CheckUpgrade())
// {
// return 1;
// }
//}
return 0;
}
public void UpdateAttributes(bool sendNotification)
{
int combatValue = 0;
var results = F.ListPool.Get();
foreach (var pet in _pets.Values)
{
if (pet != null && pet.isFriend)
{
combatValue += pet.GetAttributes(results);
}
}
PlayerProxy.Instance.UpdatePetCombatValue(results, combatValue, sendNotification);
F.ListPool.Release(results);
}
const string ARCHIVE_KEY = "pet";
const string ARCHIVE_KEY_V1 = "pet_v1";
///
///
///
private void LoadLocal()
{
var petItems = ItemProxy.Instance.GetStaticItems();
_pets.Clear();
for (int i = 0; i < petItems.Count; i++)
{
var petItem = petItems[i];
_pets.Add(petItem.id, new PetInfo(petItem));
}
var dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY_V1);
if (dataList != null && dataList.Count > 0)
{
int index = 0;
_battlePetId = dataList[index++];
_feedTimestamp = dataList.SafeGet(index++);
}
else
{
dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY);
if (dataList != null && dataList.Count > 0)
{
int index = 0;
dataList.SafeGet(index++);
int petLevel = dataList.SafeGet(index++);
int petExp = dataList.SafeGet(index++);
if (petLevel > 0)
{
_pets[12000].Set(petLevel, 0);
}
else if (petExp > 0)
{
_pets[12000].Set(1, 0);
}
}
}
ArchiveProxy.Instance.RemoveIntList(ARCHIVE_KEY);
UpdateAttributes(false);
}
///
///
///
private void SaveLocal()
{
var dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY_V1);
if (dataList != null)
{
dataList.Clear();
dataList.Add(_battlePetId);
dataList.Add(_feedTimestamp);
ArchiveProxy.Instance.SetIntList(ARCHIVE_KEY_V1, dataList);
}
}
#endregion
#region Unity && Proxy
public static PetProxy Instance
{
get { return GetInstance(); }
}
public override void LoadCompleted()
{
}
public override void ReadArchive()
{
LoadLocal();
}
#endregion
}
}