public static async ETVoid Execute(this ActiveSkillComponent self, string skillId) { ActiveSkillData activeSkillData = Game.Scene.GetComponent <SkillConfigComponent>().GetActiveSkill(skillId); SkillHelper.ExecuteSkillParams excuteSkillParams = new SkillHelper.ExecuteSkillParams(); excuteSkillParams.skillId = skillId; excuteSkillParams.source = self.GetParent <Unit>(); excuteSkillParams.skillLevel = 1; self.currUsingSkillId = skillId; //TODO: 暂时先直接取消之前的行动 self.cancelToken?.Cancel(); Game.EventSystem.Run(EventIdType.CancelPreAction, self.GetParent <Unit>()); CharacterStateComponent characterStateComponent = self.GetParent <Unit>().GetComponent <CharacterStateComponent>(); characterStateComponent.Set(SpecialStateType.NotInControl, true); self.cancelToken = new CancellationTokenSource(); excuteSkillParams.cancelToken = self.cancelToken; await SkillHelper.ExecuteActiveSkill(excuteSkillParams); self.cancelToken = null; characterStateComponent.Set(SpecialStateType.NotInControl, false); self.currUsingSkillId = string.Empty; }
public void Remove(BuffHandlerVar buffHandlerVar) { Buff_GiveSpecialDebuff buff = (Buff_GiveSpecialDebuff)buffHandlerVar.data; if (!buffHandlerVar.GetBufferValue(out BufferValue_TargetUnits targetUnits)) { return; } //if (buff.currStackNum < buff.aimStackNum) return;//叠加层数没达到 foreach (var v in targetUnits.targets) { CharacterStateComponent unitState = v.GetComponent <CharacterStateComponent>(); //从一个特殊效果配置中,拿到对应效果的BuffGroup,添加到角色的BuffMgrComponent中 switch (buff.restrictionType) { case RestrictionType.击退: unitState.Set(SpecialStateType.NotInControl, false); break; case RestrictionType.眩晕: unitState.Set(SpecialStateType.CantDoAction, false); break; } } }
public async ETVoid Execute(string skillId) { try { if (usingSkill) { return; } if (!skillList.ContainsKey(skillId)) { return; } if (!SkillHelper.CheckIfSkillCanUse(skillId, GetParent <Unit>())) { return; } ActiveSkillData activeSkillData = Game.Scene.GetComponent <SkillConfigComponent>().GetActiveSkill(skillId); SkillHelper.ExecuteSkillParams excuteSkillParams = new SkillHelper.ExecuteSkillParams(); excuteSkillParams.skillId = skillId; excuteSkillParams.source = GetParent <Unit>(); excuteSkillParams.skillLevel = 1; usingSkill = true; bool canUse = await SkillHelper.CheckInput(excuteSkillParams); if (GetParent <Unit>() == UnitComponent.Instance.MyUnit) { //联网模式玩家主动使用技能需要等待服务器确认消息,以决定技能是否真的可以使用 tcs = new ETTaskCompletionSource <bool>(); canUse = await tcs.Task; tcs = null; usingSkill = false; } if (!canUse) { return; } usingSkill = false; currUsingSkillId = skillId; // 联网模式非玩家单位使用技能直接跳过检测,因为是收到使用技能的确定消息了才开始执行技能. //TODO: 暂时先直接取消之前的行动 cancelToken?.Cancel(); Game.EventSystem.Run(EventIdType.CancelPreAction, GetParent <Unit>()); CharacterStateComponent characterStateComponent = GetParent <Unit>().GetComponent <CharacterStateComponent>(); characterStateComponent.Set(SpecialStateType.NotInControl, true); cancelToken = new CancellationTokenSource(); excuteSkillParams.cancelToken = cancelToken; await SkillHelper.ExecuteActiveSkill(excuteSkillParams); cancelToken = null; characterStateComponent.Set(SpecialStateType.NotInControl, false); currUsingSkillId = string.Empty; } catch (Exception e) { Log.Error(e.ToString()); } }
async ETVoid PushBack(Unit unit, Vector3 target, Buff_PushBack buff) { CharacterMoveComponent characterMoveComponent = unit.GetComponent <CharacterMoveComponent>(); float moveSpeed = Vector3.Distance(unit.Position, target) / buff.moveDuration; CharacterStateComponent characterStateComponent = unit.GetComponent <CharacterStateComponent>(); characterStateComponent.Set(SpecialStateType.NotInControl, true); //击退效果尝试打断. 以后这里要传参数,代表打断来源,然后下面这个方法里判断来源和技能允许被打断的类型 unit.GetComponent <ActiveSkillComponent>().Interrupt(TypeOfInterruption.FromNotInControl); await characterMoveComponent.PushBackedTo(target, moveSpeed); characterStateComponent.Set(SpecialStateType.NotInControl, false); }
protected override async void Run(ETModel.Session session, M2C_Pushback message) { Unit unit = UnitComponent.Instance.Get(message.Id); CharacterMoveComponent characterMoveComponent = unit.GetComponent <CharacterMoveComponent>(); float moveSpeed = Vector3.Distance(unit.Position, message.MoveTarget.ToV3()) / message.Time; CharacterStateComponent characterStateComponent = unit.GetComponent <CharacterStateComponent>(); characterStateComponent.Set(SpecialStateType.NotInControl, true); await characterMoveComponent.PushBackedTo(message.MoveTarget.ToV3(), moveSpeed); characterStateComponent.Set(SpecialStateType.NotInControl, false); }
async static ETVoid SpellForTime(float value, SkillHelper.ExecuteSkillParams skillParams) { CharacterStateComponent characterStateComponent = skillParams.source.GetComponent <CharacterStateComponent>(); characterStateComponent.Set(SpecialStateType.NotInControl, true); skillParams.cancelToken.Token.Register(() => { characterStateComponent.Set(SpecialStateType.NotInControl, false); }); await TimerComponent.Instance.WaitAsync((long)(value * 1000), skillParams.cancelToken.Token); characterStateComponent.Set(SpecialStateType.NotInControl, false); }
//中断可能正在执行的技能 public void Interrupt(TypeOfInterruption type) { if (!GlobalConfigComponent.Instance.networkPlayMode) { //TODO: 根据当前使用技能允许的可打断类型判定打断是否可以成功 CharacterStateComponent characterStateComponent = GetParent <Unit>().GetComponent <CharacterStateComponent>(); if (characterStateComponent.Get(SpecialStateType.UnStoppable)) { return; // 霸体状态,打断失败 } } cancelToken?.Cancel(); cancelToken = null; }
Quaternion _lastTargetRotation; // used to keep track of the rotation the player last was targeting when getting interupted by getting hit public void ManualAwake() { _character = GetComponent <Character>(); _model = _character.model; _stateComponent = _character.stateComponent; _flagComponent = _character.flagComponent; _collisionTracker = FindObjectOfType <CollisionTracker>(); _lastTargetRotation = transform.rotation; _character.OnCharacterSpawned += (Vector2DInt inSpawnTile) => { currentTile = Match.instance.level.tileMap.GetTile(inSpawnTile); currentTile.SetCharacter(_character); }; }
//中断可能正在执行的技能 public static void Interrupt(this ActiveSkillComponent self, TypeOfInterruption type) { //TODO: 根据当前使用技能允许的可打断类型判定打断是否可以成功 CharacterStateComponent characterStateComponent = self.GetParent <Unit>().GetComponent <CharacterStateComponent>(); if (characterStateComponent.Get(SpecialStateType.UnStoppable)) { return; // 霸体状态,打断失败 } self.cancelToken?.Cancel(); self.cancelToken = null; M2C_InterruptSkill m2c = new M2C_InterruptSkill(); m2c.Frame = Game.Scene.GetComponent <UnitStateMgrComponent>().currFrame; m2c.Id = self.GetParent <Unit>().Id; ETHotfix.MessageHelper.Broadcast(m2c); }
public static bool CalFinalDamage(long sourceUnitId, long destUnitId, DamageData skillDamageValue) { try { CharacterStateComponent unitState = UnitComponent.Instance.Get(destUnitId).GetComponent <CharacterStateComponent>(); if (unitState.Get(SpecialStateType.Die)) { return(false); } if (unitState.Get(SpecialStateType.Invincible)) { //TODO: 提示无敌状态 return(false); } NumericComponent sourceUnitNumericCom = UnitComponent.Instance.Get(sourceUnitId).GetComponent <NumericComponent>(); NumericComponent destUnitNumericCom = UnitComponent.Instance.Get(destUnitId).GetComponent <NumericComponent>(); int rateCharge = 0; //命中判定 float hitRate = sourceUnitNumericCom.GetAsFloat(NumericType.HitRate) - destUnitNumericCom.GetAsFloat(NumericType.DodgeRate); rateCharge = RandomHelper.RandomNumber(0, 100); if (rateCharge / 100.0f > hitRate) { Game.EventSystem.Run(EventIdType.AttackMissing, destUnitId); Log.Debug("Miss! 命中率 " + hitRate); return(false); } //暴击判定 //可能有技能提升效果 if (!skillDamageValue.isCritical) { float criticalRate = sourceUnitNumericCom.GetAsFloat(NumericType.CritRate); rateCharge = RandomHelper.RandomNumber(0, 100); if (rateCharge / 100.0f <= criticalRate) { //暴击判定通过 skillDamageValue.isCritical = true; } } if (skillDamageValue.isCritical) { skillDamageValue.damageValue = Mathf.RoundToInt(skillDamageValue.damageValue * sourceUnitNumericCom.GetAsFloat(NumericType.CritDamagePct)); } NumericType resistType = NumericType.ArmorResist; if (skillDamageValue.damageType != DamageType.Physic) { resistType = NumericType.MagicResist; } skillDamageValue.damageValue = Mathf.RoundToInt(skillDamageValue.damageValue * (100.0f / (destUnitNumericCom.GetAsInt(resistType) + 100.0f))); //预防可能要考虑什么白字红字,黑字粉字等乱七八糟的情况,所以专门用一个List DamageData[] array = new DamageData[1]; array[0] = skillDamageValue; //计算最终伤害加成,减免 for (int i = 0; i < array.Length; i++) { var damage = array[i]; float finalDamagePct = 1 + sourceUnitNumericCom.GetAsFloat(NumericType.FinalDamage_AddPct) - destUnitNumericCom.GetAsFloat(NumericType.FinalDamage_ReducePct); damage.damageValue = Mathf.RoundToInt(array[i].damageValue * finalDamagePct); //限定最小伤害0 damage.damageValue = Mathf.Clamp(array[i].damageValue, 0, int.MaxValue); array[i] = damage; } //给予伤害 Game.EventSystem.Run(EventIdType.GiveDamage, destUnitId, array); //给予吸血,吸法 float xiQu = sourceUnitNumericCom.GetAsFloat(NumericType.HP_LeechRate); if (xiQu > 0) { Game.EventSystem.Run(EventIdType.GiveHealth, sourceUnitId, Mathf.RoundToInt(skillDamageValue.damageValue * xiQu)); } xiQu = sourceUnitNumericCom.GetAsFloat(NumericType.MP_LeechRate); if (xiQu > 0) { Game.EventSystem.Run(EventIdType.GiveMp, sourceUnitId, Mathf.RoundToInt(skillDamageValue.damageValue * xiQu)); } return(true); } catch (Exception e) { Debug.LogError(e.ToString()); return(false); } }