506 lines
18 KiB
C#
506 lines
18 KiB
C#
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; }
|
||
//}
|
||
} |