Files
JJBB/Assets/Project/Script/Player/Skill/SkillData.cs
2024-08-23 15:49:34 +08:00

506 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Games.GlobeDefine;
using GCGame.Table;
using Module.Log;
using System.Collections.Generic;
using UnityEngine;
namespace Games.SkillModle
{
public enum SKILLSELLOGIC
{
SELLOGIC_INVALID = -1,
SELLOGIC_SINGLE = 0,
SELLOGIC_MULTI = 1,
SELLOGIC_ALL = 2
}
public enum SKILLUSEFAILTYPE
{
CE_ERROR_ELSE = -1, //其他错误
CE_OK = 0, //技能释放成功
CE_TARGET_ERROR = 1, //技能释放目标错误
CE_NO_SKILLEX_CONFIG = 2, //SkillEx未配置
CE_NO_SKILLBASE_CONFIG = 3, //SkillBase未配置
CE_IN_ESCORT_SKILL_LIMIT = 4, //跑商不能使用位移技能
CE_IN_BUFF_LIMIT_SKILL = 5, //有buff限制技能BuffLimitSkill.txt
CE_SCENE_INVALID = 6, //场景无效
CE_MOUNT_FREEZE = 7, //上下马冻结期不能使用技能
CE_SKILL_CONDI_CHECK_FAILED = 8, //技能释放条件检测未通过
CE_IN_DEATH = 9, //死亡状态不能释放技能
CE_ROLE_NOT_ACTIVE = 10, //角色未激活
CE_IS_PASSIVITY = 11, //被动技能不能主动释放
CE_IN_MAINSCENE = 12, //主城不能释放技能
CE_SCENE_NOT_ALLOWED_XP_SKILL = 13, //当前场景不能使用xp技能
CE_CUR_SKILL_CANNOT_BREAK = 14, //正在使用的技能不能被打断
CE_NOT_HAVE_THIS_SKILL = 15, //没有学习该技能
CE_IMPACT_SKILL_DISABLED = 16, //有禁止使用该技能的buff
CE_TARGET_IN_HIDING = 17, //不能对隐身目标使用技能
CE_DISTANCE_NOT_ENOUGH = 18, //距离不够
CE_SCENE_NOT_ALLOWED_PK = 19, //当前场景不能PK
CE_SCENE_NOT_ALLOWED_ATK_NEW_ROLE = 20, //新手保护
CE_TARGET_ROLE_CANNOT_PK = 21, //目标角色不满足PK条件
CE_PUBLIC_CD_NOT_COOL = 22, //公共CD未冷却
CE_SKILL_CD_NOT_COOL = 23, //技能CD未冷却
CE_BACKSWINGCD1_NOT_COOL = 24, //后摇CD1未冷却
CE_BACKSWINGCD2_NOT_COOL = 25, //后摇CD2未冷却
CE_SKILL_DES_POS_CHECK_FAILED = 26, //技能释放点检测失败
CE_DEPLETE_CHECK_FAILED = 27, //技能消耗检测失败
CE_IS_NOT_WANTED_UNIT = 28, // 非技能预期目标
CE_SKILL_STAGE_CHECK_FAILED = 29, // 连段技能判断失败
CE_SKILL_HAS_TYPE_SKILL_LIMIT = 30 // 技能使用时,角色状态不对
}
public enum SKILLFINISHREASON
{
BREAK = 1,
FINISH = 2
}
public enum SKILLUSETYPE
{
SHUNFA = 0, //瞬发
YINCHANG = 1, //吟唱
BEIDONG = 2 //被动
}
public enum SKILLBASEID
{
XFZBASEID = 104, //摩诃无量的的baseID
YTWJID = 307, //以退为进baseID
YGSDID = 204, //阳关三叠baseID
HDWLID = 306, //画地为牢
ZLZ = 404 //祝融掌
}
public enum SKILLDEFINE
{
MAX_SKILLNUM = 20, //主角最大技能数
MAX_PET_SKILLNUM = 2, //宠物最大技能数
PUBLICCDID = 14 //公共冷却ID
}
//每个int位表示一种类别 符合两种及以上的累加
public enum SKILLCLASS
{
ACTIVE = 1, //主动技
PASSIVITY = 2, //被动技
AUTOREPEAT = 4, //自动连续技
XP = 8, //XP技
CHONGFENG = 16, //冲锋技
DUTIAO = 32, //读条
MASTERSKILL = 64, //师门技能
GAINSKILL = 128, //加持技能
SIMPLEATTACK = 256, //普攻技能
SPECIALSKILL = 512 //玄女锁链连续技
}
//技能范围特效 类别
public enum SKILLRANGEEFFECTTYPE
{
INVALID = -1,
RING = 0, //环
CIRCLE = 1, //圆
RECT = 2, //矩形
ARROWS = 3 //箭头
}
public enum SKILLRANGEEFFECTTAR
{
INVAILD = -1,
SELF = 0, //自身
SELECTTARGET = 1 //选中目标
}
public enum SKILLRANGEEFFECTID
{
INVALID = -1,
RINGEFFECTID = 100, //环
CIRCLEEFFECTID = 101, //圆
RECTEFFECTID = 102, //矩形
ARROWSEFFECTID = 103 //箭头
}
public class OwnSkillData
{
/// <summary>
/// 总技能释放间隔时间
/// </summary>
public float Cooldown { get; private set; }
/// <summary>
/// 当前技能释放间隔时间
/// </summary>
public float CurrentCooldown
{
get { return Mathf.Max(0f, _currentCooldown); }
}
/// <summary>
/// 真实的cd残余时间可能小于0 - 以允许部分需要cd结束再延迟的检查正常使用
/// </summary>
private float _currentCooldown;
// ******** 连段技能的记录 ********
// 注:连段技能由客户端实行数据预测,不等服务器返回再更新
/// <summary>
/// 当前连段开始时间
/// </summary>
private float _comboStartTime = float.NegativeInfinity;
/// <summary>
/// 连段到下一段所需时间
/// </summary>
public float ComboTime { get; private set; }
/// <summary>
/// 连读残余允许时间
/// </summary>
public float ComboRemain
{
get
{
UpdateCombo();
// 注如果Combo超时UpdateCombo后_comboStartTime会重置
if (_comboStartTime < 0f)
return float.NegativeInfinity;
else
return _comboStartTime + ComboTime - Time.time;
}
}
/// <summary>
/// 技能cd流逝速度校正值列表
/// </summary>
private List<MyTuple<int, float>> _cooldownModifiers;
/// <summary>
/// 当前cd时间流逝速度
/// </summary>
public float CooldownModifier { get; private set; }
/// <summary>
/// 当前最后一次连段是否已经执行
/// </summary>
public bool FullCombo { get; private set; }
public int exSkillLevel { get; private set; }
public int SkillId { get; private set; }
public void SetSkillId(int newExId, int newExLevel)
{
// SkillBase是否更新为其他技能
var newSkill = false;
if (SkillId != newExId)
{
var inCombo = ComboExTable != SkillExTable;
SkillExTable = newExId < 0 ? null : TableManager.GetSkillExByID(newExId, 0);
if (SkillExTable != null)
{
if (SkillBaseTable == null || SkillBaseTable.Id != SkillExTable.BaseId)
{
newSkill = true;
SkillBaseTable = TableManager.GetSkillBaseByID(SkillExTable.BaseId, 0);
}
if (inCombo)
{
ComboExTable = TableManager.GetSkillExByID(SkillExTable.MultiNextSkillId, 0);
if (ComboExTable != null)
ComboBaseTable = TableManager.GetSkillBaseByID(ComboExTable.BaseId, 0);
else
{
ComboExTable = SkillExTable;
ComboBaseTable = SkillBaseTable;
LogModule.ErrorLog(string.Format("技能Ex{0}无法正确获得连段技能!", SkillExTable.SkillExID));
}
}
else
{
ComboExTable = SkillExTable;
ComboBaseTable = SkillBaseTable;
}
}
else
{
SkillBaseTable = null;
ComboExTable = null;
ComboBaseTable = null;
}
}
// 试图更新当前的Ex等级
if (SkillId != newExId || exSkillLevel != newExLevel)
{
if (SkillExTable == null)
{
ComboExTableFinal = null;
BaseExTableFinal = null;
SkillLevelTable = null;
Cooldown = default(float);
}
else
{
if (newExLevel > 0)
{
BaseExTableFinal = TableManager.GetSkillExByID(SkillExTable.SkillExID + newExLevel, 0) ??
CommonUtility.GetSkillMaxLevelByBaseId(SkillExTable.BaseId);
ComboExTableFinal = SkillExTable == ComboExTable ? BaseExTableFinal : TableManager.GetSkillExByID(BaseExTableFinal.MultiNextSkillId, 0);
}
else
{
ComboExTableFinal = ComboExTable;
BaseExTableFinal = SkillExTable;
}
SkillLevelTable = TableManager.GetSkillLevelUpByID(BaseExTableFinal.SkillExID, 0);
var cdTable = TableManager.GetCoolDownTimeByID(BaseExTableFinal.CDTimeId, 0);
Cooldown = cdTable.CDTime.ToClientTime();
}
}
if (newSkill)
{
_currentCooldown = float.NegativeInfinity;
_cooldownModifiers = new List<MyTuple<int, float>>();
SetCooldownRate();
CleanComboState();
}
SkillId = SkillExTable == null ? GlobeVar.INVALID_ID : SkillExTable.SkillExID;
exSkillLevel = newExLevel;
}
// 连段技能的第一段数据表 - 不会受到ExSkillLevel校正
public Tab_SkillEx SkillExTable { get; private set; }
public Tab_SkillBase SkillBaseTable { get; private set; }
// 当前连段技能Base数据表
// 注:连段现在不可支持两段以上连段的情况,支持两段以上需要很多特殊处理
public Tab_SkillEx _comboextable;
public Tab_SkillEx ComboExTable { get; private set; }
public Tab_SkillBase ComboBaseTable { get; private set; }
// 受到加成修正之后的数据表
public Tab_SkillEx BaseExTableFinal { get; private set; }
public Tab_SkillEx ComboExTableFinal { get; private set; }
public Tab_SkillLevelUp SkillLevelTable { get; private set; }
public int PriorityAutoCombat
{
get { return ComboBaseTable == null ? 0 : ComboBaseTable.PriorityAutoFight; }
}
public bool IsValid()
{
return SkillId > -1;
}
/// <summary>
/// 该技能是否为连段技能
/// </summary>
public bool IsComboSkill()
{
return SkillExTable.HasNextCombo();
}
/// <summary>
/// 是否Cd结束允许添加额外等待时间
/// </summary>
public bool IsCooldownFinish(float extraTime = 0f)
{
return _currentCooldown + extraTime <= 0f;
}
/// <summary>
/// 设置技能当前释放间隔时间
/// </summary>
public void SetCooldown(float currentCooldown)
{
// 若技能进入cd由于服务器同步信息或其他原因技能连段重置
if (currentCooldown > 0)
CleanComboState();
_currentCooldown = currentCooldown;
}
/// <summary>
/// 设置技能刚刚被释放
/// </summary>
public void ResetCooldown()
{
_currentCooldown = Cooldown;
//if (SkillBaseTable != ComboBaseTable)
CleanComboState();
}
/// <summary>
/// 更新技能冷却时间
/// </summary>
public void UpdateCooldown()
{
if (IsValid())
_currentCooldown -= Time.unscaledDeltaTime * CooldownModifier;
}
private void SetCooldownRate()
{
CooldownModifier = 1f;
for (var i = 0; i < _cooldownModifiers.Count; i++)
CooldownModifier *= _cooldownModifiers[i].second;
}
/// <summary>
/// 增加一个技能冷却校正
/// </summary>
public void AddCooldownModifier(int handle, float value)
{
if (IsValid())
{
_cooldownModifiers.Add(new MyTuple<int, float>(handle, value));
SetCooldownRate();
}
}
/// <summary>
/// 移除一个技能冷却校正
/// </summary>
public void RemoveCooldownModifier(int handle)
{
if (IsValid())
{
var index = _cooldownModifiers.FindIndex(a => a.first == handle);
if (index >= 0)
{
_cooldownModifiers.RemoveAt(index);
SetCooldownRate();
}
}
}
/// <summary>
/// 立刻减少cd时间
/// </summary>
public void SubstractCooldown(float time)
{
if (IsValid())
_currentCooldown -= time * CooldownModifier;
}
/// <summary>
/// 清除当前技能
/// </summary>
public void CleanUp()
{
SkillId = -1;
_currentCooldown = float.NegativeInfinity;
CleanComboState();
}
// 注一般调用这个技能前应该已经进行过一次UpdateCombo操作因此不判定连段跌落的情况
public void AddCombo()
{
if (!SkillBaseTable.SkillClass.ContainFlag((int)SKILLCLASS.SIMPLEATTACK))
{
// 如果当前技能仍然可以连段
if (ComboExTable.HasNextCombo())
{
//var cdTable = TableManager.GetCoolDownTimeByID(ComboExTable.NextSkillCDTimeId, 0);
//ComboTime = 3.0f;//cdTable.CDTime.ToClientTime();
//int use_multi_id = 0;
var base_id = ComboExTable.NextStageSkillId;
if (base_id > 0)
{
var ownSkill = GameManager.gameManager.PlayerDataPool.GetOwnSkillInfo(base_id);
//use_multi_id = ownSkill.SkillId;
if (ownSkill != null)
{
ownSkill.ComboTime = 3.0f;
ownSkill._comboStartTime = Time.time;
}
}
//ComboExTable = TableManager.GetSkillExByID(use_multi_id, 0);
//ComboExTableFinal = TableManager.GetSkillExByID(use_multi_id, 0);
////ComboExTable = TableManager.GetSkillExByID(ComboExTable.MultiNextSkillId, 0);
////ComboExTableFinal = TableManager.GetSkillExByID(ComboExTableFinal.MultiNextSkillId, 0);
//ComboBaseTable = TableManager.GetSkillBaseByID(ComboExTable.BaseId, 0);
//_comboStartTime = Time.time;
_currentCooldown = Cooldown;
}
else
FullCombo = true;
//{
// // 如果技能是连段技能回滚到第一段增加一次假cd时间
// if (ComboExTable != SkillExTable)
// CleanComboState();
//}
}
}
public OwnSkillData GetComboSkill()
{
if (!SkillBaseTable.SkillClass.ContainFlag((int)SKILLCLASS.SIMPLEATTACK))
{
if (ComboExTable.HasNextCombo())
{
var base_id = ComboExTable.NextStageSkillId;
if (base_id > 0)
{
return GameManager.gameManager.PlayerDataPool.GetOwnSkillInfo(base_id);
}
}
}
return null;
}
/// <summary>
/// 更新连段状态
/// </summary>
public void UpdateCombo()
{
// 普攻不使用Combo逻辑
// 非连段不使用Combo逻辑
if (!SkillBaseTable.SkillClass.ContainFlag((int)SKILLCLASS.SIMPLEATTACK)
)// && IsComboSkill()
{
// Combo衔接超时的情况特殊预测当前连段
// 注客户端会先走预测Cooldown然后等待服务器返回的真实Cooldown
if (ComboExTable != SkillExTable && (_comboStartTime < 0f || _comboStartTime + ComboTime < Time.time))
{
ResetCooldown();
//CleanComboState();
}
}
}
public void CleanComboState()
{
ComboTime = 0f;
ComboExTable = SkillExTable;
ComboExTableFinal = BaseExTableFinal;
ComboBaseTable = SkillBaseTable;
_comboStartTime = float.NegativeInfinity;
FullCombo = false;
}
}
public struct ShowDamageInfo
{
public int showValue;
public int showTime;
public float interval;
public Tab_DamageBoardType damageType;
public float nextShowTime;
}
/// <summary>
/// 用于GC_SYN_SKILLINFO的临时数据
/// </summary>
// 注:由于协议是动态生成的,因此暂时
public struct SyncSkillData
{
public int index;
public int skillId;
public int skillBaseId;
public float cooldown;
}
//public struct MultiShowDamageBoard //多次显示
//{
// public void CleanUp()
// {
// ShowValue = 0;
// ShowTimes = -1;
// ShowInter = -1.0f;
// DamageType = GameDefine_Globe.DAMAGEBOARD_TYPE.PLAYER_TYPE_INVALID;
// NextShowTime = 0;
// }
//
// public int ShowValue { get; set; }
//
// public int ShowTimes { get; set; }
//
// public float ShowInter { get; set; }
//
// public GameDefine_Globe.DAMAGEBOARD_TYPE DamageType { get; set; }
//
// public float NextShowTime { get; set; }
//}
}