// *********************************************************************** // Assembly : Game // Author : Kimch // Created : 2020-11-21 // Description : // Last Modified By : // Last Modified On : // *********************************************************************** // // // *********************************************************************** using System.Collections; using System.Collections.Generic; using UnityEngine; namespace G { /// /// 处理招式逻辑 /// public class Cha_Moves : MonoBehaviour { public enum ArgIndex { Probability = 0, ExtraDamage = 1, ExtraDamagePercent = 2, Cooltime = 3, CooltimePercent = 4, ReduceTime = 5, Amount = 6, Duration = 7, Special1 = 8, Special2 = 9, } public class MovesInfo { public const int MAX_ARGS_COUNT = 10; /// /// /// public int id; /// /// /// public int parentId; /// /// /// public int trigger; /// /// /// public readonly int[] kindArgs = new int[MAX_ARGS_COUNT]; /// /// 1技能 2buff /// public int targetType; /// /// 相关技能参数 /// public int targetId; public int skillKind; public int[] skillKindArgs; /// /// 累计等级 /// public int level; /// /// 生命周期 /// public float lifeTime; /// /// 上次使用时间 /// public float lastApplyTime = -999f; /// /// 概率 /// public int probability { get { return kindArgs[0]; } } /// /// 数量 /// public int amount { get { return kindArgs[6]; } } /// /// 持续时间 /// public float duration { get { return kindArgs[7] * 0.001f; } } /// /// 减少的时间 /// public float reduceTime { get { return kindArgs[5] * 0.001f; } } /// /// 冷却时间 /// public float cooltime { get { return kindArgs[3] * kindArgs[4] * 0.00001f; } } /// /// /// public int extraDamage { get { return kindArgs[1]; } } /// /// /// public int extraDamagePercent { get { return kindArgs[2] - 100; } } /// /// /// public float elapse { get { return Time.time - lastApplyTime; } set { lastApplyTime = Time.time - value; } } /// /// /// public MovesInfo root; public float uiSkillCoolDown; public float uiSkillCoolTime; /// /// 减少 /// /// public void Reduce(float time) { if (root != null) root.Reduce(time); else lastApplyTime -= time; } /// /// /// public void ReduceAll() { lastApplyTime = 0; } /// /// /// /// /// public int GetDamage(int damage) { return damage * kindArgs[2] + kindArgs[1]; } public void OnTrigger() { float reduce = reduceTime; if (reduce > 0f) { Reduce(reduce); } } } /// /// /// #region Field /// /// /// private readonly Dictionary _buffDict = new Dictionary(); /// /// 目标类型 /// private readonly Dictionary> _typeBuffDict = new Dictionary>(); private EntityPlayer _scriptCha; #endregion #region Property /// /// 全局减cd参数 /// public float skillCdRate { get { return (100 - _scriptCha.reduceCd) * 0.01f; } } // 翻滚穿刺 private MovesInfo _dodgeBuff; //跳劈逻辑 private MovesInfo _thumpBuff; /// /// 跳劈暴击 /// private MovesInfo _thumpCriticalBuff; //反击 private MovesInfo _counterBuff; //濒死 private MovesInfo _avoidDeathBuff; /// /// 清cd buff /// private MovesInfo _attackClearSkillCdBuff; /// /// 翻滚穿刺 /// public int dodgeType { get { return _dodgeBuff != null ? 1 : 0; } } /// /// 跳劈 /// public bool canThump { get { if (_thumpBuff != null && Time.time - _thumpBuff.lastApplyTime > _thumpBuff.cooltime) { _thumpBuff.lastApplyTime = Time.time; if (_thumpCriticalBuff != null) { _thumpCriticalBuff.lifeTime = Time.time + _thumpCriticalBuff.duration; } return true; } return false; } } public int thumpType { get { return _thumpBuff.amount; } } public int thumpExtraDamage { get { return _thumpBuff.extraDamage; } } public int thumpExtraDamagePercent { get { return _thumpBuff.extraDamagePercent; } } public int CalcThumpDamage(int damage) { if (_thumpBuff != null) { return _thumpBuff.GetDamage(damage); } return damage; } /// /// 跳劈一秒暴击 /// public bool canCritical { get { if (_thumpCriticalBuff != null && _thumpCriticalBuff.lifeTime - Time.time > 0f) { return true; } return false; } } /// /// 受伤反击 /// public bool counterAttack { get { if (_counterBuff != null && _counterBuff.probability > GlobalUtils.RndHundred) { return true; } return false; } } /// /// 免死 /// public bool avoidDeath { get { if (_avoidDeathBuff != null) { _avoidDeathBuff = null; return true; } return false; } } /// /// /// private MovesInfo _autoCastSkill; /// /// 自动施法 /// public bool autoCastSkill { get { return _scriptCha.autoCastSkill; } set { _scriptCha.autoCastSkill = value; } } #endregion #region Method /// /// /// /// /// public void AddMoves(int id, bool doubleValue) { if (!_buffDict.ContainsKey(id)) { var movesItem = ItemProxy.Instance.GetStaticItem(id); var moves = new MovesInfo { id = movesItem.id, parentId = movesItem.parent, trigger = movesItem.trigger, targetType = movesItem.targetType, targetId = movesItem.targetId, level = doubleValue ? 2 : 1, }; //本体 var args = movesItem.targetArgs; if (args != null) for (int i = Mathf.Min(MovesInfo.MAX_ARGS_COUNT, args.Length) - 1; i >= 0; i--) moves.kindArgs[i] = args[i]; //全局 _scriptCha.ApplyGlobalMovesArgs(movesItem.id, moves.kindArgs); //args = _scriptCha.GetGlobalMovesArgs(movesItem.id); //if (args != null) // for (int i = Mathf.Min(MovesInfo.MAX_ARGS_COUNT, args.Length) - 1; i >= 0; i--) // moves.kindArgs[i] += args[i]; if (moves.parentId > 0 && _buffDict.TryGetValue(moves.parentId, out var parentMoves)) { //get root while (parentMoves.parentId > 0 && _buffDict.TryGetValue(parentMoves.parentId, out parentMoves)) { }; if (parentMoves != null) { moves.root = parentMoves; for (int i = MovesInfo.MAX_ARGS_COUNT - 1; i >= 0; i--) parentMoves.kindArgs[i] += moves.kindArgs[i]; } } AddMoves(moves.trigger, moves); InitMoves(moves, doubleValue); } else { Debug.Log($"武学不能重复学习 {id}"); } } /// /// /// /// /// public void AddMovesByBuff(int id, bool doubleValue) { var buffItem = ItemProxy.Instance.GetStaticItem(id); if (buffItem != null) { var kind = buffItem.kind; var kindArgs = buffItem.kindArgs; if (buffItem.kind == 1) { _scriptCha.AttributeUp(kindArgs[0], (!doubleValue ? kindArgs[1] : kindArgs[1] * 2), 0); } else if (kind == 2) { _scriptCha.AttributeUp(kindArgs[0], 0, (!doubleValue ? kindArgs[1] : kindArgs[1] * 2)); } else if (kind == 3)//特殊类型固定值 { var sf = kindArgs[0]; if (sf == 1) { _scriptCha.HpUp(kindArgs[1], 0); } } else if (kind == 4)//特殊类型百分比 { var sf = kindArgs[0]; if (sf == 1) { _scriptCha.HpUp(0, kindArgs[1]); } } } } /// /// /// /// public void AddMovesBySkill(int id) { } /// /// /// /// /// private void AddMoves(int trigger, MovesInfo moves) { _buffDict.Add(moves.id, moves); if (trigger > 0) { if (_typeBuffDict.TryGetValue(trigger, out List buffList)) { buffList.Add(moves); } else { _typeBuffDict.Add(trigger, new List { moves }); } } } /// /// /// /// /// private void InitMoves(MovesInfo moves, bool doubleValue) { //Skill if (moves.targetType == 1) { var skillItem = ItemProxy.Instance.GetStaticItem(moves.targetId); if (skillItem != null) { moves.skillKind = skillItem.kind; moves.skillKindArgs = skillItem.kindArgs; //添加技能图标 if (moves.trigger == 1) { GlobalNotifier.PostNotification(GlobalDefine.EVENT_SKILL_STATE, moves, "add_skill"); } } } else if (moves.targetType == 2) { var buffItem = ItemProxy.Instance.GetStaticItem(moves.targetId); if (buffItem != null) { moves.skillKind = buffItem.kind; moves.skillKindArgs = buffItem.kindArgs; if (moves.skillKind == 1) { _scriptCha.AttributeUp(moves.skillKindArgs[0], (!doubleValue ? moves.skillKindArgs[1] : moves.skillKindArgs[1] * 2), 0); } else if (moves.skillKind == 2) { _scriptCha.AttributeUp(moves.skillKindArgs[0], 0, (!doubleValue ? moves.skillKindArgs[1] : moves.skillKindArgs[1] * 2)); } else if (moves.skillKind == 3)// { var sf = moves.skillKindArgs[0]; if (sf == 1) { _scriptCha.HpUp(moves.skillKindArgs[1], 0); } } //特殊类型百分比 else if (moves.skillKind == 4)// { var sf = moves.skillKindArgs[0]; if (sf == 1) { _scriptCha.HpUp(0, moves.skillKindArgs[1]); } } } } else { //特殊武学 if (moves.targetId == 10013) { if (moves.parentId == 0) _thumpBuff = moves; } else if (moves.targetId == 10017) { _dodgeBuff = moves; } else if (moves.targetId == 10018) { _attackClearSkillCdBuff = moves; } else if (moves.targetId == 10021) { _thumpCriticalBuff = moves; } else if (moves.targetId == 10026) { _avoidDeathBuff = moves; } else if (moves.targetId == 10027) { if (moves.parentId == 0) _counterBuff = moves; } else if (moves.targetId == 10029) { autoCastSkill = true; _autoCastSkill = moves; } else if (moves.targetId == 10001) { GameLevel.Instance.gameSpeed = 2f; } } } /// /// /// /// /// /// private bool ApplyMoves(MovesInfo moves, int trigger = 0) { if ((moves.trigger & trigger) != 0) { moves.OnTrigger(); //其它 } if (moves.targetType == 1) { // 可以释放 if (moves.parentId == 0) { float cooltime = moves.cooltime * this.skillCdRate;/// (1000 * 100); if (moves.elapse > cooltime && moves.probability > GlobalUtils.RndHundred) { moves.elapse = 0; if (moves.skillKind > 0) _scriptCha.scriptSkill.FireSkill(moves.skillKind, moves.kindArgs); else Debug.LogError("无效技能类型 " + moves.targetId); return true; } } } else if (moves.targetType == 2) { // return true; } return false; } //TODO 采用更新的方法 private void UpdateBuff() { if (_typeBuffDict.TryGetValue(1, out List skillBuffs)) { for (int i = 0; i < skillBuffs.Count; i++) { var buff = skillBuffs[i]; buff.uiSkillCoolTime = buff.cooltime * skillCdRate; buff.uiSkillCoolDown = buff.uiSkillCoolTime - buff.elapse; } } } /// /// 触发类型(4) /// /// private void OnAttack(int style) { if (_typeBuffDict.TryGetValue(4, out List skillBuffs)) foreach (var buff in skillBuffs) { ApplyMoves(buff, 4); // //if (clearCd) //{ // buff.ReduceAll(); //} } //if (_typeBuffDict.TryGetValue(2 | 4, out List buffBuffs)) // foreach (var buff in buffBuffs) // { // ApplyBuff(buff, 4); // } } /// /// 触发类型(16) /// private void OnKill(int type) { if (_attackClearSkillCdBuff != null && _attackClearSkillCdBuff.probability > GlobalUtils.RndHundred) { ReduceAllSkillCD(); } else { int killCooldown = _scriptCha.GetCurrentValue(CombatAttributeId.KillCooldown); if (killCooldown > 0) { ReduceSkillCD(0.01f * killCooldown); } } if (_typeBuffDict.TryGetValue(16, out List skillBuffs)) foreach (var buff in skillBuffs) { ApplyMoves(buff, 16); } } /// /// /// /// private void OnHurt(int damage) { if (this.counterAttack) _scriptCha.scriptSkill.BoomOn(0, true); } /// /// 触发类型(8) /// private void OnDodge(int type) { if (_typeBuffDict.TryGetValue(8, out List skillBuffs)) foreach (var buff in skillBuffs) { ApplyMoves(buff, 8); } } /// /// /// /// /// public bool CastSkill(MovesInfo moves) { if (moves != null && moves.targetType == 1 && moves.parentId == 0) { return ApplyMoves(moves, 0); } return false; } public void AutoCastSkill() { if (autoCastSkill && _typeBuffDict.TryGetValue(1, out List skillBuffs) && skillBuffs != null) { for (int i = 0; i < skillBuffs.Count; i++) { var buff = skillBuffs[i]; if (ApplyMoves(buff, 0)) break; } } } public void ReduceSkillCD(float reduce) { if (_typeBuffDict.TryGetValue(1, out List skillBuffs)) { for (int i = 0; i < skillBuffs.Count; i++) { var buff = skillBuffs[i]; if (reduce > 0f) { buff.Reduce(reduce); } } } } public void ReduceAllSkillCD() { if (_typeBuffDict.TryGetValue(1, out List skillBuffs)) { for (int i = 0; i < skillBuffs.Count; i++) { var buff = skillBuffs[i]; buff.ReduceAll(); } } } #endregion #region Unity private void Awake() { _scriptCha = GetComponent(); _scriptCha.OnAttack += this.OnAttack; _scriptCha.OnDodge += this.OnDodge; _scriptCha.OnHurt += this.OnHurt; _scriptCha.OnKill += this.OnKill; } private void Update() { UpdateBuff(); } #endregion } }