580 lines
17 KiB
C#
580 lines
17 KiB
C#
using cfg.VehicleCfg;
|
|
using cfg.VihecleCultivateCfg;
|
|
using Framework;
|
|
using Gameplay.Net;
|
|
using PhxhSDK;
|
|
using System.Collections.Generic;
|
|
|
|
public class VehicleCultivateManager : Singlenton<VehicleCultivateManager>, IInitable
|
|
{
|
|
private List<VehicleTreeNode> vehicleTreeNodes = new List<VehicleTreeNode>();
|
|
Dictionary<long, VehicleTreeNode> vehicleNodesMap = new Dictionary<long, VehicleTreeNode>();
|
|
|
|
private List<VehicleComponentTreeNode> vehicleComponentTreeNodes = new List<VehicleComponentTreeNode>();
|
|
Dictionary<long, VehicleComponentTreeNode> vehicleComponentNodesMap = new Dictionary<long, VehicleComponentTreeNode>();
|
|
|
|
|
|
#region IInitable
|
|
public void Init()
|
|
{
|
|
vehicleTreeNodes.Clear();
|
|
vehicleNodesMap.Clear();
|
|
vehicleComponentTreeNodes.Clear();
|
|
vehicleComponentNodesMap.Clear();
|
|
|
|
LoadVehicleTreeNode();
|
|
}
|
|
|
|
public void Release()
|
|
{
|
|
vehicleTreeNodes.Clear();
|
|
vehicleNodesMap.Clear();
|
|
vehicleComponentTreeNodes.Clear();
|
|
vehicleComponentNodesMap.Clear();
|
|
}
|
|
#endregion
|
|
|
|
public TreeNodeBase Get(long id)
|
|
{
|
|
if (vehicleNodesMap.TryGetValue(id, out var node))
|
|
{
|
|
return node;
|
|
}
|
|
if(vehicleComponentNodesMap.TryGetValue(id, out var componentNode))
|
|
{
|
|
return componentNode;
|
|
}
|
|
|
|
DebugUtil.LogError("VehicleCultivateManager.Get: id not found: {0}", id);
|
|
return null;
|
|
}
|
|
|
|
|
|
//TODO 将表内容转换为树节点类型存储
|
|
void LoadVehicleTreeNode()
|
|
{
|
|
var Table = TableManager.Instance.Tables.VehicleConfig;
|
|
for (int i = 0; i < Table.DataList.Count; i++)
|
|
{
|
|
VehicleTreeNode node = new VehicleTreeNode();
|
|
|
|
node.ID = Table.DataList[i].ID;
|
|
node.Type = VehicleTreeNodeType.Vehicle;
|
|
node.ParentID = Table.DataList[i].ParentId;
|
|
vehicleTreeNodes.Add(node);
|
|
vehicleNodesMap.Add(Table.DataList[i].ID, node);
|
|
}
|
|
|
|
var TableComponent = TableManager.Instance.Tables.VehicleComponent;
|
|
for (int i = 0; i < TableComponent.DataList.Count; i++)
|
|
{
|
|
VehicleComponentTreeNode node = new VehicleComponentTreeNode();
|
|
|
|
node.ID = TableComponent.DataList[i].ComponentID;
|
|
node.Type = VehicleTreeNodeType.Component;
|
|
node.ParentID = TableComponent.DataList[i].ParentComponentID;
|
|
|
|
vehicleComponentTreeNodes.Add(node);
|
|
vehicleComponentNodesMap.Add(TableComponent.DataList[i].ComponentID, node);
|
|
}
|
|
|
|
foreach(var node in vehicleComponentTreeNodes)
|
|
{
|
|
//将部件节点添加到各节点的子节点列表
|
|
if (node.ParentID == 0)
|
|
{
|
|
var vehicle = Get(node.VehicleID) as VehicleTreeNode;
|
|
vehicle?.ComponentChildren.Add(node.ID);
|
|
}
|
|
else
|
|
{
|
|
var component = Get(node.ParentID) as VehicleComponentTreeNode;
|
|
component?.ComponentChildren.Add(node.ID);
|
|
}
|
|
}
|
|
|
|
foreach(var node in vehicleTreeNodes)
|
|
{
|
|
//载具节点添加到各节点的子节点列表
|
|
if (node.ParentID != 0)
|
|
{
|
|
if (TableManager.Instance.Tables.VehicleConfig.GetOrDefault((int)node.ID)?.ParentType == cfg.VihecleCultivateCfg.ParentType.Component)
|
|
{
|
|
var parent = Get(node.ParentID);
|
|
parent?.VehicleChildren.Add(node.ID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取载具森林
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public VehicleTreeNode GetVehicleForest(cfg.VihecleCultivateCfg.VehicleType vehicleType)
|
|
{
|
|
VehicleTreeNode root = new VehicleTreeNode();
|
|
root.ID = 0;
|
|
|
|
foreach (var node in vehicleTreeNodes)
|
|
{
|
|
var vehicleCfg = TableManager.Instance.Tables.VehicleConfig.GetOrDefault((int)node.ID);
|
|
if (vehicleCfg == null)
|
|
{
|
|
DebugUtil.LogError("VehicleCultivateManager.GetVehicleForest: vehicleCfg is null");
|
|
continue;
|
|
}
|
|
else if (vehicleType != VehicleType.None && vehicleCfg.VehicleType != vehicleType)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (vehicleCfg.ParentType == cfg.VihecleCultivateCfg.ParentType.None)//如果前置类型为空 则为无前置根节点
|
|
{
|
|
root.VehicleChildren.Add(node.ID);
|
|
}
|
|
else if (vehicleCfg.ParentType == ParentType.Component)//如果前置为部件,则不是根节点
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
//TODO 其他方式解锁载具判断
|
|
DebugUtil.LogWarning("载具解锁判断未实现");
|
|
root.VehicleChildren.Add(node.ID);
|
|
}
|
|
}
|
|
|
|
return root;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 根据载具ID获取局部科技树内的子孙节点
|
|
/// </summary>
|
|
/// <param name="ID"></param>
|
|
/// <returns></returns>
|
|
public List<TreeNodeBase> GetPartialTree(int ID)
|
|
{
|
|
List<TreeNodeBase> retList = new List<TreeNodeBase>();
|
|
Queue<TreeNodeBase> queue = new Queue<TreeNodeBase>();
|
|
TreeNodeBase root = Get(ID);
|
|
if (root != null)
|
|
{
|
|
queue.Enqueue(root);
|
|
bool isRoot = true;
|
|
while (queue.Count > 0)
|
|
{
|
|
TreeNodeBase node = queue.Dequeue();
|
|
retList.Add(node);
|
|
if (node.Type == VehicleTreeNodeType.Vehicle && !isRoot)
|
|
continue;
|
|
|
|
isRoot = false;
|
|
|
|
List<TreeNodeBase> children = node.GetChildNodes();
|
|
foreach (var child in children)
|
|
{
|
|
queue.Enqueue(child);
|
|
}
|
|
}
|
|
}
|
|
return retList;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 查找载具升级树中的子节点载具
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public List<VehicleTreeNode> GetVehicleChildren(long id)
|
|
{
|
|
List<VehicleTreeNode> retList = new List<VehicleTreeNode>();
|
|
VehicleTreeNode root = Get(id) as VehicleTreeNode;
|
|
|
|
if (root != null)
|
|
{
|
|
retList.AddRange(root.VehicleChildren.ConvertAll(x => Get(x) as VehicleTreeNode));
|
|
}
|
|
return retList;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 查找载具升级树中的父节点载具
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public VehicleTreeNode GetVehicleParent(long id)
|
|
{
|
|
VehicleTreeNode node = Get(id) as VehicleTreeNode;
|
|
if (node != null)
|
|
{
|
|
var parent = node.GetDirectVehicleParentNode() as VehicleTreeNode;
|
|
|
|
return parent;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据ID判断升级节点状态
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public TreeNodeState GetTreeNodeState(long id)
|
|
{
|
|
var node = Get(id);
|
|
if (node.IsUpgraded())
|
|
{
|
|
return TreeNodeState.Upgraded;
|
|
}
|
|
else
|
|
{
|
|
if (node is VehicleTreeNode vehicleNode)
|
|
{
|
|
if (TableManager.Instance.Tables.VehicleConfig.GetOrDefault((int)id)?.ParentType == cfg.VihecleCultivateCfg.ParentType.Component)
|
|
{
|
|
var parent = Get(vehicleNode.ParentID);
|
|
if (parent.IsUpgraded())
|
|
{
|
|
return TreeNodeState.Upgradable;
|
|
}
|
|
else
|
|
{
|
|
return TreeNodeState.Locked;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//TODO 其他方式解锁载具判断
|
|
DebugUtil.LogWarning("载具解锁判断未实现");
|
|
return TreeNodeState.Upgradable;
|
|
}
|
|
}
|
|
else if (node is VehicleComponentTreeNode componentNode)
|
|
{
|
|
var parent = Get(componentNode.ParentID);
|
|
if (parent.IsUpgraded())
|
|
{
|
|
return TreeNodeState.Upgradable;
|
|
}
|
|
else
|
|
{
|
|
return TreeNodeState.Locked;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugUtil.LogError("VehicleCultivateManager.GetTreeNodeState: node is null");
|
|
return TreeNodeState.None;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class VehicleTreeNode : TreeNodeBase
|
|
{
|
|
public long ParentID { get; set; }
|
|
public long ParentVehicleID { get; set; }
|
|
|
|
|
|
public override List<TreeNodeBase> GetChildNodes()
|
|
{
|
|
List<TreeNodeBase> ret= new();
|
|
ret.AddRange(VehicleChildren.ConvertAll(x => VehicleCultivateManager.Instance.Get(x)));
|
|
return ret;
|
|
}
|
|
|
|
public override TreeNodeBase GetDirectVehicleParentNode()
|
|
{
|
|
if (ParentID != 0 && TableManager.Instance.Tables.VehicleConfig.GetOrDefault((int)ID)?.ParentType == cfg.VihecleCultivateCfg.ParentType.Component)
|
|
{
|
|
var componentNode = VehicleCultivateManager.Instance.Get(ParentID);
|
|
if (componentNode != null)
|
|
{
|
|
return componentNode.GetDirectVehicleParentNode();
|
|
}
|
|
else
|
|
{
|
|
DebugUtil.LogError("VehicleTreeNode.GetParentNode: componentNode is null");
|
|
return null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
public override bool IsUpgraded()
|
|
{
|
|
//载具是否强化直接查找PartCharacter内是否有该载具的强化数据
|
|
var data = Actor.Instance.Character.GetVehicleDevelopment((uint)ID);
|
|
if(data != null)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算当前载具属性
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public VehicleAttribute CalculateVehicleAttribute()
|
|
{
|
|
VehicleTreeNode root = this;
|
|
Queue<TreeNodeBase> queue = new Queue<TreeNodeBase>();
|
|
|
|
bool isRoot = true;
|
|
VehicleAttribute ret = new VehicleAttribute();
|
|
while (queue.Count > 0)
|
|
{
|
|
var node = queue.Dequeue();
|
|
if (node is VehicleTreeNode vehicleNode && isRoot)//如果是载具根节点,获取基础属性
|
|
{
|
|
isRoot = false;
|
|
var cfg = TableManager.Instance.Tables.VehicleConfig.GetOrDefault((int)vehicleNode.ID);
|
|
if (cfg != null)
|
|
{
|
|
ret.Add(new VehicleAttribute(cfg));
|
|
}
|
|
foreach (var child in vehicleNode.VehicleChildren)
|
|
{
|
|
queue.Enqueue(VehicleCultivateManager.Instance.Get(child));
|
|
}
|
|
|
|
}
|
|
else if (node is VehicleComponentTreeNode componentNode && node.IsUpgraded())//如果是强化过的部件,加上部件属性
|
|
{
|
|
var cfg = TableManager.Instance.Tables.VehicleComponent.GetOrDefault((int)componentNode.ID);
|
|
if (cfg != null)
|
|
{
|
|
ret.Add(new VehicleAttribute(cfg));
|
|
}
|
|
foreach (var child in componentNode.ComponentChildren)
|
|
{
|
|
queue.Enqueue(VehicleCultivateManager.Instance.Get(child));
|
|
}
|
|
}
|
|
}
|
|
|
|
//TODO 如果有其他属性加成,再加上
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
public class VehicleComponentTreeNode : TreeNodeBase
|
|
{
|
|
public long VehicleID { get; set; }
|
|
/// <summary>
|
|
/// 父部件ID
|
|
/// </summary>
|
|
public long ParentID { get; set; }
|
|
|
|
|
|
|
|
public override List<TreeNodeBase> GetChildNodes()
|
|
{
|
|
List<TreeNodeBase> ret = new();
|
|
ret.AddRange(ComponentChildren.ConvertAll(x => VehicleCultivateManager.Instance.Get(x)));
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取载具父节点
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override TreeNodeBase GetDirectVehicleParentNode()
|
|
{
|
|
if(ParentID == 0)//直接与载具关联
|
|
{
|
|
var parentID = VehicleID;
|
|
return VehicleCultivateManager.Instance.Get(parentID);
|
|
}
|
|
else//与部件关联
|
|
{
|
|
var parentComponentNode = VehicleCultivateManager.Instance.Get(ParentID);
|
|
if(parentComponentNode != null)//获取部件的父节点
|
|
{
|
|
return parentComponentNode.GetDirectVehicleParentNode();
|
|
}
|
|
else
|
|
{
|
|
DebugUtil.LogError("VehicleComponentTreeNode.GetParentNode: parentComponentNode is null");
|
|
var parentVehicleNode = VehicleCultivateManager.Instance.Get(VehicleID);
|
|
return parentVehicleNode;//返回载具节点
|
|
}
|
|
}
|
|
}
|
|
|
|
public override bool IsUpgraded()
|
|
{
|
|
//载具部件检查需要去找到对应的载具节点下是否有该强化部件
|
|
var vehicleNode = GetDirectVehicleParentNode() as VehicleTreeNode;
|
|
if(vehicleNode != null)
|
|
{
|
|
var ID = vehicleNode.ID;
|
|
var data = Actor.Instance.Character.GetVehicleDevelopment((uint)ID);
|
|
if (data != null)
|
|
{
|
|
return data.UpgradedComponents.Contains((uint)this.ID);
|
|
}
|
|
else
|
|
{
|
|
//未找到强化载具数据 默认未强化
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugUtil.LogError("VehicleComponentTreeNode.IsUpgraded: vehicleNode is null");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
public enum VehicleTreeNodeType
|
|
{
|
|
Vehicle,
|
|
Component
|
|
}
|
|
public enum TreeNodeState
|
|
{
|
|
None,//无
|
|
Upgradable,//可升级
|
|
Upgraded,//已升级
|
|
Locked//未解锁
|
|
}
|
|
public class VehicleAttribute
|
|
{
|
|
/// <summary>
|
|
/// 防御力
|
|
/// </summary>
|
|
public int Defense;
|
|
/// <summary>
|
|
/// 血量
|
|
/// </summary>
|
|
public int Hp;
|
|
/// <summary>
|
|
/// 伤害
|
|
/// </summary>
|
|
public int Damage;
|
|
/// <summary>
|
|
/// 换弹时间
|
|
/// </summary>
|
|
public float ReloadTime;
|
|
/// <summary>
|
|
/// 射速
|
|
/// </summary>
|
|
public float FireRate;
|
|
/// <summary>
|
|
/// 士气压制
|
|
/// </summary>
|
|
public int MoraleDamage;
|
|
/// <summary>
|
|
/// 对人伤害
|
|
/// </summary>
|
|
public float ScaleForHuman;
|
|
/// <summary>
|
|
/// 对载具伤害
|
|
/// </summary>
|
|
public float ScaleForVehicle;
|
|
/// <summary>
|
|
/// 暴击率
|
|
/// </summary>
|
|
public float CriticalRate;
|
|
/// <summary>
|
|
/// 暴击伤害
|
|
/// </summary>
|
|
public float CriticalDamage;
|
|
|
|
public VehicleAttribute()
|
|
{
|
|
Defense = 0;
|
|
Hp = 0;
|
|
Damage = 0;
|
|
ReloadTime = 0;
|
|
FireRate = 0;
|
|
MoraleDamage = 0;
|
|
ScaleForHuman = 0;
|
|
ScaleForVehicle = 0;
|
|
CriticalRate = 0;
|
|
CriticalDamage = 0;
|
|
}
|
|
|
|
public VehicleAttribute(DataVehicleComponent cfg)
|
|
{
|
|
Damage = cfg.Damage;
|
|
Defense = cfg.Defense;
|
|
Hp = cfg.HP;
|
|
ReloadTime = cfg.ReloadTime;
|
|
FireRate = cfg.FireRate;
|
|
MoraleDamage = cfg.MoraleDamage;
|
|
ScaleForHuman = cfg.ScaleForHuman;
|
|
ScaleForVehicle = cfg.ScaleForVehicle;
|
|
CriticalRate = cfg.CriticalRate;
|
|
CriticalDamage = cfg.CriticalScale;
|
|
}
|
|
|
|
public VehicleAttribute(DataVehicle cfg)
|
|
{
|
|
Damage = 0;
|
|
Defense = cfg.Defense;
|
|
Hp = cfg.HP;
|
|
ReloadTime = 0;
|
|
FireRate = 0;
|
|
MoraleDamage = 0;
|
|
ScaleForHuman = 0;
|
|
ScaleForVehicle = 0;
|
|
CriticalRate = cfg.CriticalRate;
|
|
CriticalDamage = cfg.CriticalScale;
|
|
}
|
|
|
|
public void Add(VehicleAttribute attribute)
|
|
{
|
|
Defense += attribute.Defense;
|
|
Hp += attribute.Hp;
|
|
Damage += attribute.Damage;
|
|
ReloadTime += attribute.ReloadTime;
|
|
FireRate += attribute.FireRate;
|
|
MoraleDamage += attribute.MoraleDamage;
|
|
ScaleForHuman += attribute.ScaleForHuman;
|
|
ScaleForVehicle += attribute.ScaleForVehicle;
|
|
CriticalRate += attribute.CriticalRate;
|
|
CriticalDamage += attribute.CriticalDamage;
|
|
}
|
|
}
|
|
public abstract class TreeNodeBase
|
|
{
|
|
public long ID { get; set; }
|
|
public VehicleTreeNodeType Type { get; set; }
|
|
|
|
/// <summary>
|
|
/// 载具树子节点
|
|
/// </summary>
|
|
public List<long> VehicleChildren = new List<long>();
|
|
/// <summary>
|
|
/// 部件树子节点
|
|
/// </summary>
|
|
public List<long> ComponentChildren = new List<long>();
|
|
|
|
public abstract List<TreeNodeBase> GetChildNodes();
|
|
|
|
/// <summary>
|
|
/// 获取最近载具父节点
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public abstract TreeNodeBase GetDirectVehicleParentNode();
|
|
|
|
/// <summary>
|
|
/// 节点是否已升级
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public abstract bool IsUpgraded();
|
|
}
|