public override Activity Tick(Actor self) { turnActivity = moveActivity = null; attackStatus = AttackStatus.UnableToAttack; foreach (var attack in attackTraits.Where(x => !x.IsTraitDisabled)) { var status = TickAttack(self, attack); attack.IsAniming = status == AttackStatus.Attacking || status == AttackStatus.NeedsToTurn; } if (attackStatus.HasFlag(AttackStatus.Attacking)) { return(this); } if (attackStatus.HasFlag(AttackStatus.NeedsToTurn)) { return(turnActivity); } if (attackStatus.HasFlag(AttackStatus.NeedsToMove)) { return(moveActivity); } return(NextActivity); }
public AttackResult(Vector2Int attackerPosition, Vector2Int defenderPosition, int damageDealt, AttackStatus attackStatus) { mAttackerPosition = attackerPosition; mDefenderPosition = defenderPosition; mAttackStatus = attackStatus; mDamageDealt = damageDealt; }
protected override void Initialize(FSMEvent ev = null) { _eventAttackCross = ev as AnimFSMEventAttackCross; _attackStatus = AttackStatus.PREPARING; Agent.BlackBoard.motionType = MotionType.ATTACK; _startRotation = Agent.Transform.rotation; _startPosition = Agent.Transform.position; if (_eventAttackCross.target != null) { float angle = 0; float distance = 0; Vector3 dir = _eventAttackCross.target.Position - Agent.Transform.position; distance = dir.magnitude; if (distance > 0.1f) { dir.Normalize(); angle = Vector3.Angle(Agent.Transform.forward, dir); if (angle < 40 && Vector3.Angle(Agent.Forward, _eventAttackCross.target.Forward) < 80) { _backHit = true; } } else { dir = Agent.Transform.forward; } _finalRotation.SetLookRotation(dir); if (distance < Agent.BlackBoard.weaponRange) { _finalPosition = _startPosition; } else { _finalPosition = _eventAttackCross.target.transform.position - dir * Agent.BlackBoard.weaponRange; } _moveTime = (_finalPosition - _startPosition).magnitude / 20.0f; _rotationTime = angle / 720.0f; } else { _finalRotation.SetLookRotation(_eventAttackCross.attackDir); _rotationTime = Vector3.Angle(Agent.Transform.forward, _eventAttackCross.attackDir) / 720.0f; _moveTime = 0; } _rotationOk = (_rotationTime == 0); _positionOK = (_moveTime == 0); _currentRotationTime = 0; _currentMoveTime = 0; _isCritical = IsCritical(); _knockdown = IsKnockDown(); _remainAttackCount = 2; }
public void AttackToPlayer(AttackStatus attack_status) { if (attack_status == AttackStatus.Fire) { enemy_boss_controller.GunHold = true; enemy_boss_controller.GunAttack = true; enemy_boss_controller.StrikeAttack = false; enemy_boss_controller.KickAttack = false; } else if (attack_status == AttackStatus.Kick) { enemy_boss_controller.KickAttack = true; enemy_boss_controller.StrikeAttack = false; enemy_boss_controller.GunHold = false; enemy_boss_controller.GunAttack = false; } else if (attack_status == AttackStatus.Strike) { enemy_boss_controller.StrikeAttack = true; enemy_boss_controller.KickAttack = false; enemy_boss_controller.GunHold = false; enemy_boss_controller.GunAttack = false; } else if (attack_status == AttackStatus.None) { enemy_boss_controller.GunHold = false; enemy_boss_controller.GunAttack = false; enemy_boss_controller.KickAttack = false; enemy_boss_controller.StrikeAttack = false; } }
void SwitchATKStatus(AttackStatus _status) { if (mAtkStatus == _status) { return; } mAtkStatus = _status; mAnim.SetBool("InBoxRange", false); mAnim.SetBool("InSwingRange", false); switch (mAtkStatus) { case AttackStatus.boxing: weapon.SetActive(false); mAnim.SetBool("InBoxRange", true); break; case AttackStatus.swing: weapon.SetActive(true); mAnim.SetBool("InSwingRange", true); break; default: break; } }
private void Setup() { _shipLength = 1; _ship = LongShip.CreateShip(_shipLength); _defaultStatus = AttackStatus.NotAttacked; _position = new Position("A", 1); _location = BasicLocation.CreateLocation(_position); }
public void setStatusToAttackTypeMental() { status = AttackStatus.ATTACK_TYPE_MENTAL; UIAttackType.SetActive(false); UIAttackMentalTarget.SetActive(true); UIAttackPhysicalTarget.SetActive(false); UIAttack.SetActive(false); statusText.GetComponent <Text>().text = MentalTargetString; }
public void setStatusToAttacking() { status = AttackStatus.ATTACKING; UIAttackType.SetActive(false); UIAttackMentalTarget.SetActive(false); UIAttackPhysicalTarget.SetActive(false); UIAttack.SetActive(false); statusText.GetComponent <Text>().text = AttackingString; }
public void Finish() { if (Status == AttackStatus.Finished) return; Status = AttackStatus.Finished; if (OnFinish != null) OnFinish.Invoke(); }
public void Finish() { if (Status == AttackStatus.Finished) { return; } Status = AttackStatus.Finished; if (OnFinish != null) { OnFinish.Invoke(); } }
// 阻挡开始 private void BlockStart() { if (attackStatus == AttackStatus.AFTER_ATTACK) { if (originalData.isEnemy) { attackStatus = AttackStatus.CONFIRM_ENEMY; } else { } } blockStatus = BlockStatus.BLOCKING; }
private void MoveToTarget(Vector3 trg) { if (lastRecalTime < Time.time + DELTA_RECALC) { trg = new Vector3(trg.x, owner.transform.position.y, trg.z); lastTargetScanPos = trg; trg = ClaclNearTargetPosition(trg); if ( /*isTooClose && */owner.Control.MoveTo(trg)) { lastRecalTime = Time.time; moveTarget = trg; attackStatus = AttackStatus.move; } } }
public void setStatusToAttackType() { status = AttackStatus.ATTACK_TYPE; UIAttackType.SetActive(true); UIAttackMentalTarget.SetActive(false); UIAttackPhysicalTarget.SetActive(false); UIAttack.SetActive(false); statusText.GetComponent <Text>().text = AttackTypeSelectString; attackTypeText.GetComponent <Text>().text = ""; attackTargetText.GetComponent <Text>().text = ""; attackType = AttackType.NONE; attackTypeMental = AttackTypeMental.NONE; attackTypePhysical = AttackTypePhysical.NONE; }
private void ShowAttackBubble(AttackStatus status) { switch (status) { case AttackStatus.HIT: hitBubble.SetActive(true); break; case AttackStatus.MISS: missBubble.SetActive(true); break; case AttackStatus.CRIT: critBubble.SetActive(true); break; } Invoke("HideAttackBubbles", 1.2f); }
private void MoveToTarget(Vector3 trg) { if (lastRecalTime < Time.time + DELTA_RECALC) { trg = new Vector3(trg.x, owner.transform.position.y, trg.z); lastTargetScanPos = trg; // bool isTooClose = true; trg = ClaclNearTargetPosition(trg); // isTooClose = (moveTarget - trg).sqrMagnitude > 1; // Debug.Log("Start move to target " + trg); if ( /*isTooClose && */owner.Control.MoveTo(trg)) { lastRecalTime = Time.time; moveTarget = trg; attackStatus = AttackStatus.move; } } }
public static string ToMessage(this AttackStatus status, string attacker, string target, int damage) { switch (status) { case AttackStatus.Normal: return(string.Format(DougMessages.UserAttackedTarget, attacker, target, damage)); case AttackStatus.Critical: return(string.Format(DougMessages.CriticalHit, attacker, target, damage)); case AttackStatus.Missed: return(string.Format(DougMessages.Missed, attacker, target)); case AttackStatus.Invincible: return(string.Format(DougMessages.UserIsInvincible, target)); default: throw new ArgumentOutOfRangeException(); } }
public override Activity Tick(Actor self) { turnActivity = moveActivity = null; attackStatus = AttackStatus.UnableToAttack; foreach (var attack in attackTraits.Where(x => !x.IsTraitDisabled)) { var activity = InnerTick(self, attack); attack.IsAttacking = activity == this; } if (attackStatus.HasFlag(AttackStatus.Attacking)) return this; if (attackStatus.HasFlag(AttackStatus.NeedsToTurn)) return turnActivity; if (attackStatus.HasFlag(AttackStatus.NeedsToMove)) return moveActivity; return NextActivity; }
public static AttackStatus Stab(Lobby lobby, Player player) { var stabResult = new AttackStatus { CurrentPlayer = player }; var target = MazeLogic.PlayersOnCell(player, lobby)?.FirstOrDefault(); stabResult.PickChest = LootChest(lobby, player); if (target == null) { stabResult.Result = AttackType.NoAttack; return(stabResult); } stabResult.Target = target; if (target.Chest != null) { DropChest(lobby, target); } if (target.Health > 1) { target.Health--; stabResult.Result = AttackType.Hit; return(stabResult); } else { KillPlayer(lobby, target); } //TODO: Добавить победу //TODO: А еще лучше писать метод, который будет определять, что остался один игрок //stabResult.IsGameEnd ==... KillPlayer(lobby, target); //lobby.Players.Remove(target); stabResult.Result = AttackType.Kill; return(stabResult); }
public override void OnUpdate() { if (_attackStatus == AttackStatus.PREPARING) { bool dontMove = false; if (_rotationOk == false) { _currentRotationTime += Time.deltaTime; if (_currentRotationTime >= _rotationTime) { _currentRotationTime = _rotationTime; _rotationOk = true; } float progress = _currentRotationTime / _rotationTime; Quaternion rotation = Quaternion.Lerp(_startRotation, _finalRotation, progress); Agent.Transform.rotation = rotation; } if (_positionOK == false) { _currentMoveTime += Time.deltaTime; if (_currentMoveTime >= _moveTime) { _currentMoveTime = _moveTime; _positionOK = true; ParticleTools.Instance.Stop(Agent.particleSystemFlashTust); } if (_currentMoveTime > 0) { float progress = _currentMoveTime / _moveTime; Vector3 finalPos = Mathfx.Hermite(_startPosition, _finalPosition, progress); //if (MoveToCollideWithEnemy(finalPos, Transform.forward) == false) if (TransformTools.Instance.MoveOnGround(Agent.transform, Agent.CharacterController, finalPos - Agent.Transform.position, true) == false) { _positionOK = true; ParticleTools.Instance.Stop(Agent.particleSystemFlashTust); } } } if (_rotationOk && _positionOK) { _attackStatus = AttackStatus.ATTACKING; InitializeAttacking(); } } else if (_attackStatus == AttackStatus.ATTACKING) { _currentMoveTime += Time.deltaTime; if (_attackPhaseTime < Time.timeSinceLevelLoad) { //Debug.Log(Time.timeSinceLevelLoad + " attack phase done"); _eventAttackMelee.attackPhaseDone = true; _attackStatus = AttackStatus.FINISHED; } if (_currentMoveTime >= _moveTime) { _currentMoveTime = _moveTime; } if (_currentMoveTime > 0 && _currentMoveTime <= _moveTime) { float progress = Mathf.Min(1.0f, _currentMoveTime / _moveTime); Vector3 finalPos = Mathfx.Hermite(_startPosition, _finalPosition, progress); //if (MoveToCollideWithEnemy(finalPos, Transform.forward) == false) if (TransformTools.Instance.MoveOnGround(Agent.transform, Agent.CharacterController, finalPos - Agent.Transform.position, false) == false) { _currentMoveTime = _moveTime; } } if (_hitTimeStart == false && _hitTime <= Time.timeSinceLevelLoad) { _hitTimeStart = true; HandleAttackResult.DoMeleeDamage(Agent, _eventAttackMelee.target, Agent.BlackBoard.attackerWeapon, _eventAttackMelee.animAttackData, _isCritical, _knockdown, _eventAttackMelee.animAttackData.isFatal); // 显示刀光(方案1:美术做好mesh,参见player) if (_eventAttackMelee.animAttackData.lastAttackInCombo) { HandleTrail.ShowTrail(Agent, _eventAttackMelee.animAttackData, 0.4f); } else { HandleTrail.ShowTrail(Agent, _eventAttackMelee.animAttackData, 0.5f); } /*// 屏幕震动 * if (AnimAttackData.LastAttackInCombo || AnimAttackData.ComboStep == 3) * CameraBehaviour.Instance.ComboShake(AnimAttackData.ComboStep - 3); * * if (Owner.IsPlayer && AnimAttackData.FullCombo) * GuiManager.Instance.ShowComboMessage(AnimAttackData.ComboIndex);*/ } } else if (_attackStatus == AttackStatus.FINISHED && _endOfStateTime <= Time.timeSinceLevelLoad) { IsFinished = true; _eventAttackMelee.IsFinished = true; } }
public override void OnUpdate() { if (_attackStatus == AttackStatus.PREPARING) { bool dontMove = false; if (_rotationOk == false) { _currentRotationTime += Time.deltaTime; if (_currentRotationTime >= _rotationTime) { _currentRotationTime = _rotationTime; _rotationOk = true; } float progress = _currentRotationTime / _rotationTime; Quaternion rotation = Quaternion.Lerp(_startRotation, _finalRotation, progress); Agent.Transform.rotation = rotation; } if (_positionOK == false) { _currentMoveTime += Time.deltaTime; if (_currentMoveTime >= _moveTime) { _currentMoveTime = _moveTime; _positionOK = true; } if (_currentMoveTime > 0) { float progress = _currentMoveTime / _moveTime; Vector3 finalPos = Mathfx.Hermite(_startPosition, _finalPosition, progress); //if (MoveToCollideWithEnemy(finalPos, Transform.forward) == false) if (TransformTools.MoveOnGround(Agent.transform, Agent.CharacterController, finalPos - Agent.Transform.position, true) == false) { _positionOK = true; } } } if (_rotationOk && _positionOK) { _attackStatus = AttackStatus.ATTACKING; InitializeAttacking(); } } else if (_attackStatus == AttackStatus.ATTACKING) { _currentMoveTime += Time.deltaTime; if (_currentMoveTime >= _moveTime) { _currentMoveTime = _moveTime; } if (_currentMoveTime > 0 && _currentMoveTime <= _moveTime) { float progress = Mathf.Min(1.0f, _currentMoveTime / _moveTime); Vector3 finalPos = Mathfx.Hermite(_startPosition, _finalPosition, progress); //if (MoveToCollideWithEnemy(finalPos, Transform.forward) == false) if (TransformTools.MoveOnGround(Agent.transform, Agent.CharacterController, finalPos - Agent.Transform.position, false) == false) { _currentMoveTime = _moveTime; } } if (_hitTimeStart == false && _hitTime <= Time.timeSinceLevelLoad) { _hitTimeStart = true; HandleAttackResult.DoMeleeDamage(Agent, _eventAttackCross.target, Agent.BlackBoard.attackerWeapon, _eventAttackCross.animAttackData, _isCritical, _knockdown, _eventAttackCross.animAttackData.isFatal); } if (_attackPhaseTime < Time.timeSinceLevelLoad) { if (--_remainAttackCount > 0) { // 再次攻击 InitializeAttacking(false); } else { _attackStatus = AttackStatus.FINISHED; } } } else if (_attackStatus == AttackStatus.FINISHED && _endOfStateTime <= Time.timeSinceLevelLoad) { //Debug.Log(Time.timeSinceLevelLoad + " attack finished"); IsFinished = true; _eventAttackCross.IsFinished = true; } }
public void Inited() { Status = AttackStatus.Inited; }
public void Charge() { Status = AttackStatus.Charge; }
public virtual int RangedHit( Mobile m, float dmgBonus,bool pass, ref int amountBlocked, ref int amountAbsorbed ) { Item weapon = this.RangedWeapon; Item ammo = this.RangedAmmo; if(weapon != null) { if (this is Character) if(weapon.InventoryType == InventoryTypes.Thrown) { (this as Character).ConsumeItemByIdUpTo(weapon.Id,1); } else { (this as Character).ConsumeItemByIdUpTo(ammo.Id,1); } float critChance = RangedCriticalChanceCalculation(weapon,m); float dif = SkillDifCalculation(weapon,m); float hitChance = RangedHitChanceCalculation(weapon,m,dif); bool criticalStrike = false; #region critical and hit test int roll =Utility.Random( 100 ); bool test = false; if ((int)critChance >= roll || test) { #region Critical hit trigger done ArrayList al = new ArrayList(); ArrayList pal = new ArrayList(); foreach( AuraReleaseTimer art in aura ) { int a = art.aura.OnCriticalHit; if ( a != -1 ) al.Add( art ); } foreach( PermanentAura art in permanentAura ) { int a = art.aura.OnCriticalHit; if ( a != -1 ) al.Add( art ); } foreach( object obj in al ) { if(obj is AuraReleaseTimer) { AuraReleaseTimer art = (AuraReleaseTimer)obj; int a = art.aura.OnCriticalHit; if ( a != -1 ) if(Triggers[ a ] != null) ( Triggers[ a ] as OnCriticalHitTrigger )( this, m, art.ae ); } if(obj is PermanentAura) { PermanentAura art = (PermanentAura)obj; int a = art.aura.OnCriticalHit; if ( a != -1 ) if(Triggers[ a ] != null) ( Triggers[ a ] as OnCriticalHitTrigger )( this, m, Abilities.abilities[(int)art.Id] ); } } #endregion #region Critical hit done Triggers ArrayList al2 = new ArrayList(); ArrayList pal2 = new ArrayList(); foreach( AuraReleaseTimer art in aura ) { int a = art.aura.OnCriticalHitDone; if ( a != -1 ) al2.Add( art ); } foreach( PermanentAura art in permanentAura) { int a = art.aura.OnCriticalHitDone; if ( a != -1 ) pal2.Add( art ); } foreach( object obj in al2 ) { if(obj is AuraReleaseTimer) { AuraReleaseTimer art = (AuraReleaseTimer)obj; int a = art.aura.OnCriticalHitDone; if ( a != -1 ) if(Triggers[ a ] != null) ( Triggers[ a ] as OnCriticalHitDoneTrigger )(this, m, art.ae ); } if(obj is PermanentAura) { PermanentAura art = (PermanentAura)obj; int a = art.aura.OnCriticalHitDone; if ( a != -1 ) if(Triggers[ a ] != null) ( Triggers[ a ] as OnCriticalHitDoneTrigger )(this, m, Abilities.abilities[(int)art.Id] ); } } #endregion /*bovie*/ /*bovie*/ lastAttack = AttackStatus.Critical; m.lastAttackToMe = AttackStatus.Critical; criticalStrike = true; } else if((int)hitChance >= roll) { lastAttack = AttackStatus.NormalHit; m.lastAttackToMe = AttackStatus.NormalHit; } else { lastAttack = AttackStatus.Loose; m.lastAttackToMe = AttackStatus.Loose; return 0; } #endregion if (!pass) { float dodgeChance = RangedDodgeChanceCalculation(m,dif); #region Dodge test roll = Utility.Random( 100 ); if (dodgeChance >= roll) { lastAttack = AttackStatus.Dodge; m.lastAttackToMe = AttackStatus.Dodge; return 0; } #endregion } float damage = RangedDamageDoneCalculation(m,dmgBonus,criticalStrike,weapon); float blockChance = RangedBlockChanceCalculation(m,dif); if (!pass) { #region Block test + block reduction roll = Utility.Random( 100 ); if (blockChance >= roll) { lastAttack = AttackStatus.Block; m.lastAttackToMe = AttackStatus.Block; amountBlocked = m.Block + m.Str/30; damage -= amountBlocked; #region talents // shield specialization if ( m.HaveTalent(Talents.ShieldSpecialization) ) { AuraEffect af = (AuraEffect)m.GetTalentEffect(Talents.ShieldSpecialization); roll = Utility.Random( 100 ); if ( roll < af.H ) { m.GainMana(m,(Abilities.abilities[af.AdditionalSpell] as SpellTemplate).S1); } } #endregion } #endregion } #region Armor reduction float armor = ArmorReductionCalculation(m); damage = damage * (1 - armor); #endregion #region immune if (m.ImmunePhysicalDamage) { lastAttack = AttackStatus.Immune; m.lastAttackToMe = AttackStatus.Immune; return 0; } #endregion #region absorb damage =(int)m.DamageAbsorbCombat(damage); if ( damage < 0 ) { this.lastAttack = AttackStatus.Absorb; m.lastAttackToMe = AttackStatus.Absorb; return 0; } #endregion #region Targets modificators damage = RangedDamageTakenCalculation(m,damage); #endregion damage = m.ManaShieldLost(this,(int)damage); #region other effects switch (this.Classe) { #region warrior case Classes.Warrior: if ( this.HaveTalent( Talents.UnbridledWrath) ) { AuraEffect ae = (AuraEffect)this.GetTalentEffect( Talents.UnbridledWrath ); roll = Utility.Random( 100 ); if(roll < ae.H) { this.GainMana(this,1); } } break; #endregion } #endregion if ( damage > 0 && this is Character) this.SkillUpWeapon(weapon); return (int)damage; } else return 0; }
public void Start() { this.attackStatus = AttackStatus.Attacking; }
public void Pause() { this.attackStatus = AttackStatus.Stopping; }
protected virtual Activity InnerTick(Actor self, AttackBase attack) { if (IsCanceled) return NextActivity; var type = Target.Type; if (!Target.IsValidFor(self) || type == TargetType.FrozenActor) return NextActivity; if (attack.Info.AttackRequiresEnteringCell && !positionable.CanEnterCell(Target.Actor.Location, null, false)) return NextActivity; // Drop the target if it moves under the shroud / fog. // HACK: This would otherwise break targeting frozen actors // The problem is that Shroud.IsTargetable returns false (as it should) for // frozen actors, but we do want to explicitly target the underlying actor here. if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.Info.HasTraitInfo<FrozenUnderFogInfo>() && !self.Owner.CanTargetActor(Target.Actor)) return NextActivity; // Drop the target once none of the weapons are effective against it var armaments = attack.ChooseArmamentsForTarget(Target, forceAttack).ToList(); if (armaments.Count == 0) return NextActivity; // Update ranges minRange = armaments.Max(a => a.Weapon.MinRange); maxRange = armaments.Min(a => a.MaxRange()); if (!Target.IsInRange(self.CenterPosition, maxRange) || Target.IsInRange(self.CenterPosition, minRange)) { // Try to move within range, drop the target otherwise if (move == null) return NextActivity; attackStatus |= AttackStatus.NeedsToMove; moveActivity = ActivityUtils.SequenceActivities(move.MoveWithinRange(Target, minRange, maxRange), this); return NextActivity; } var desiredFacing = (Target.CenterPosition - self.CenterPosition).Yaw.Facing; if (facing.Facing != desiredFacing) { attackStatus |= AttackStatus.NeedsToTurn; turnActivity = ActivityUtils.SequenceActivities(new Turn(self, desiredFacing), this); return NextActivity; } attackStatus |= AttackStatus.Attacking; attack.DoAttack(self, Target, armaments); return this; }
public void MeleeCombatSlice() { Running = true; if (AttackTarget != null && AttackTarget.ImmuneAttack) { if ( combatTimer != null ) combatTimer.Stop(); combatTimer = null; this.lastAttack = AttackStatus.Immune; return; } if ( AttackTarget == null ) { if ( combatTimer != null ) combatTimer.Stop(); combatTimer = null; return; } if ( AttackTarget.HitPoints > 0 && HitPoints > 0 ) { UpdateXYZ(); if ( !( AttackTarget is Character ) ) AttackTarget.UpdateXYZ(); float dist = Distance( AttackTarget ); // Console.WriteLine("target {0},{1},{2} dist = {3}", AttackTarget.X, AttackTarget.Y, AttackTarget.Z, dist ); // Console.WriteLine("from {0},{1},{2} dist = {3}", X, Y, Z, dist ); if ( dist > combatReach && dist < 8 * ( combatReach + AttackTarget.CombatReach ) ) { if(this.AttackTarget != null) { ArrayList NAEbuff = (ArrayList)NextAttackEffects.Clone(); foreach(NextAttackEffect nae in NAEbuff) { this.OnSpellTemplateResults(nae.spell,this.AttackTarget); this.NextAttackSpellGo(nae); } NAEbuff.Clear(); } //FaitFace( target ); int amountAbsorbed = 0; int amountBlocked = 0; int degats = Hit( AttackTarget, ref amountAbsorbed, ref amountBlocked ); AIState = AIStates.Fighting; MoveTo( (float)( X + ( AttackTarget.X - X ) * 0.02f ), (float)( Y + ( AttackTarget.Y - Y ) * 0.02f ), (float)( AttackTarget.Z ) ); int offset = 4; if ( degats <= 0 ) Converter.ToBytes( 0x22, tempBuff, ref offset ); else Converter.ToBytes( 0x22, tempBuff, ref offset ); Converter.ToBytes( Guid, tempBuff, ref offset ); Converter.ToBytes( AttackTarget.Guid, tempBuff, ref offset ); if ( degats < 0 ) Converter.ToBytes( 0, tempBuff, ref offset ); else Converter.ToBytes( degats, tempBuff, ref offset ); Converter.ToBytes( (byte)1, tempBuff, ref offset ); Converter.ToBytes( 0, tempBuff, ref offset ); if ( degats > 0 ) Converter.ToBytes( (float)degats/*DamageType*/, tempBuff, ref offset ); else Converter.ToBytes( 0, tempBuff, ref offset ); // Converter.ToBytes( 0/*DamageType*/, tempBuff, ref offset ); // float ang = (float)Math.Atan2( AttackTarget.Y - Y, AttackTarget.X - X ); if ( degats < 0 ) Converter.ToBytes( 0, tempBuff, ref offset ); else Converter.ToBytes( degats, tempBuff, ref offset ); // Converter.ToBytes( amountAbsorbed, tempBuff, ref offset );// damage absorbed // Converter.ToBytes( 0, tempBuff, ref offset ); // new victim state Converter.ToBytes( 0, tempBuff, ref offset ); // additional spell damage id Converter.ToBytes( 0, tempBuff, ref offset ); // additional spell damage id #region Degats types if ( degats >= 0 ) Converter.ToBytes( 1, tempBuff, ref offset ); else if ( degats == -1 ) Converter.ToBytes( 2, tempBuff, ref offset );// dodge else if ( degats == - 2 ) Converter.ToBytes( 9, tempBuff, ref offset );// parry else if ( degats == - 3 ) Converter.ToBytes( 4, tempBuff, ref offset );// interrupted else if ( degats == - 4 || amountBlocked > 0 ) Converter.ToBytes( 5, tempBuff, ref offset );// block else if ( degats == - 5 ) Converter.ToBytes( 6, tempBuff, ref offset );// evade else if ( degats == - 6 ) Converter.ToBytes( 7, tempBuff, ref offset );// immune else if ( degats == - 7 ) Converter.ToBytes( 8, tempBuff, ref offset );// deflect #endregion if ( degats == 0 ) Converter.ToBytes( 0xffffffff, tempBuff, ref offset ); else Converter.ToBytes( 0, tempBuff, ref offset ); Converter.ToBytes( 0, tempBuff, ref offset ); Converter.ToBytes( 0, tempBuff, ref offset ); //HexViewer.View( tempBuff, 0, offset ); ToAllPlayerNear( OpCodes.SMSG_ATTACKERSTATEUPDATE, tempBuff, offset ); AttackTarget.LooseHits( this, degats, true ); if ( AttackTarget.Dead ) { int off = 4; Converter.ToBytes( Guid, tempBuff, ref off ); Converter.ToBytes( AttackTarget.Guid, tempBuff, ref off ); ToAllPlayerNear( OpCodes.SMSG_ATTACKSTOP, tempBuff, off ); if ( combatTimer != null ) combatTimer.Stop(); AttackTarget = null; } } else { float less = 1.0f; if ( dist > 20 ) less = 0.5f; double angle = (float)Math.Atan2( AttackTarget.Y - Y, AttackTarget.X - X ); angle += Math.PI; MoveTo( (float)( AttackTarget.X + Math.Cos( angle ) * ( combatReach + AttackTarget.CombatReach ) * 1.5 * less ), (float)( AttackTarget.Y + Math.Sin( angle ) * ( combatReach + AttackTarget.CombatReach ) * 1.5 * less ), (float)( AttackTarget.Z ) ); AIState = AIStates.Attack; } } if ( ( this as BaseCreature ).IsStillActive() ) ChooseAttackMode(); }
protected virtual void OnShootEnd(Unit obj) { attackStatus = AttackStatus.none; owner.OnShootEnd -= OnShootEnd; }
protected void DoShoot(bool shallStop = false) { if (target == null) { End(EndCause.no); return; } var dir = target.transform.position - owner.transform.position; dir.y = 0; // Debug.Log("shhot dir: " + dir); owner.Control.SetToDirection(dir); //dir = new Vector3(dir.x,owner.transform.position.y,dir.z); // Debug.Log("attack: " + dir + " " + dir.sqrMagnitude); owner.TryAttack(dir,0, target); owner.OnShootEnd += OnShootEnd; attackStatus = AttackStatus.shoot; if (shallStop) { ((AgentControl)owner.Control).Stop(false); } }
protected virtual void MoveEnd() { attackStatus = AttackStatus.none; }
void StatusUpdate() { // Clarity Variables bool canJump = jumpCountLeft > 0 && !(attackDurationLeft > 0) && !isGrappling; bool hasJumped = !(jumpCountLeft == jumpCount); // Moving isMoving = bodyPhysics.velocity.x != 0; currentRunVelocity = !isGrounded && Mathf.Abs(bodyPhysics.velocity.x) > runVelocity? Mathf.Abs(bodyPhysics.velocity.x) : runVelocity ; // Jumping jumpCountLeft = isGrounded? jumpCount : !hasJumped? jumpCount - 1 : jumpCountLeft ; isJumping = jumpDurationLeft > 0; jumpDurationLeft = isJumping? jumpDurationLeft -= Time.deltaTime : 0 ; isJumpStopping = isJumping && (!(jumpDurationLeft > 0) || !isJumpInputHeld); if (isJumpInputTapped && canJump) { jumpVelocity = isGrounded? groundedJumpVelocity : midairJumpVelocity ; jumpDuration = isGrounded ? groundedJumpDuration : midairJumpDuration ; ChangeGravity(jumpGravity); jumpDurationLeft = jumpDuration; jumpCountLeft -= 1; } if (isJumping) { Move(jumpVelocity / jumpDuration, MovementType.Jump); } if (isJumpStopping) { RevertGravity(); float endingLength = isJumpInputHeld? jumpCompleteVelocity : jumpCancelVelocity ; Move(endingLength, MovementType.Jump); jumpDurationLeft = 0; } // Attacking attackDurationLeft -= isAttacking? !(attackDelayLeft > 0)? Time.deltaTime : 0 : attackDurationLeft ; attackDelayLeft -= isAttacking? Time.deltaTime : attackDelayLeft ; if ((isNarrowInputTapped || isWideInputTapped) && !isAttacking) { attackWeapon = hasSawblade? PlayerWeapon.Sawblade : PlayerWeapon.Kick ; attackType = isNarrowInputTapped? AttackType.Narrow : AttackType.Wide ; attackDelayLeft = hasSawblade? shotDelay : kickDelay ; attackDurationLeft = !hasSawblade? kickDuration : attackDurationLeft ; } isAttacking = isAttacking || attackDelayLeft > 0 || attackDurationLeft > 0; attackStatus = attackDelayLeft <= 0? AttackStatus.Fire : AttackStatus.Set ; if (isAttacking && attackStatus == AttackStatus.Fire) { if (attackWeapon == PlayerWeapon.Sawblade) { Attack(attackWeapon, attackType); } else if (attackDurationLeft == kickDuration) { Debug.Log(attackWeapon); Attack(attackWeapon, attackType); } } if (!(attackDelayLeft > 0 || attackDurationLeft > 0)) { isAttacking = false; attackWeapon = PlayerWeapon.None; attackStatus = AttackStatus.Set; } // Grapple isGrappling = currentGrappleVelocity != Vector2.zero && grappleObject != null; if (isGrappleInputTapped && grappleObject != null && !isGrappling) { Grapple(grappleObject); } else if (grappleObject == null) { currentGrappleVelocity = Vector2.zero; } // Shredder Moves }
public virtual int Hit( Mobile m, float dmgBonus,bool pass, ref int amountBlocked, ref int amountAbsorbed ) { Item weapon = activeWeapon; if ( Level < m.Level - 7 ) { lastAttack = AttackStatus.Dodge; m.lastAttackToMe = AttackStatus.Dodge; return -1; } float critChance = CriticalChanceCalculation(weapon,m); float dif = SkillDifCalculation(weapon,m); float hitChance = HitChanceCalculation(weapon,m,dif); bool criticalStrike = false; #region critical and hit test int roll =Utility.Random( 100 ); if ((int)critChance >= roll ) { #region Critical hit trigger done ArrayList al = new ArrayList(); ArrayList pal = new ArrayList(); foreach( AuraReleaseTimer art in aura ) { int a = art.aura.OnCriticalHit; if ( a != -1 ) al.Add( art ); } foreach( PermanentAura art in permanentAura ) { int a = art.aura.OnCriticalHit; if ( a != -1 ) al.Add( art ); } foreach( object obj in al ) { if(obj is AuraReleaseTimer) { AuraReleaseTimer art = (AuraReleaseTimer)obj; int a = art.aura.OnCriticalHit; if ( a != -1 ) if(Triggers[ a ] != null) ( Triggers[ a ] as OnCriticalHitTrigger )( this, m, art.ae ); } if(obj is PermanentAura) { PermanentAura art = (PermanentAura)obj; int a = art.aura.OnCriticalHit; if ( a != -1 ) if(Triggers[ a ] != null) ( Triggers[ a ] as OnCriticalHitTrigger )( this, m, Abilities.abilities[(int)art.Id] ); } } #endregion #region Critical hit done Triggers ArrayList al2 = new ArrayList(); ArrayList pal2 = new ArrayList(); foreach( AuraReleaseTimer art in aura ) { int a = art.aura.OnCriticalHitDone; if ( a != -1 ) al2.Add( art ); } foreach( PermanentAura art in permanentAura) { int a = art.aura.OnCriticalHitDone; if ( a != -1 ) pal2.Add( art ); } foreach( object obj in al2 ) { if(obj is AuraReleaseTimer) { AuraReleaseTimer art = (AuraReleaseTimer)obj; int a = art.aura.OnCriticalHitDone; if ( a != -1 ) if(Triggers[ a ] != null) ( Triggers[ a ] as OnCriticalHitDoneTrigger )(this, m, art.ae ); } if(obj is PermanentAura) { PermanentAura art = (PermanentAura)obj; int a = art.aura.OnCriticalHitDone; if ( a != -1 ) if(Triggers[ a ] != null) ( Triggers[ a ] as OnCriticalHitDoneTrigger )(this, m, Abilities.abilities[(int)art.Id] ); } } #endregion /*bovie*/ /*bovie*/ lastAttack = AttackStatus.Critical; m.lastAttackToMe = AttackStatus.Critical; criticalStrike = true; } else if((int)hitChance <= roll) { lastAttack = AttackStatus.NormalHit; m.lastAttackToMe = AttackStatus.NormalHit; } else { lastAttack = AttackStatus.Loose; m.lastAttackToMe = AttackStatus.Loose; return 0; } #endregion if (!pass) { float parryChance = ParryChanceCalculation(m,dif); #region Parry test roll = Utility.Random( 100 ); if (parryChance >= roll) { lastAttack = AttackStatus.Parry; m.lastAttackToMe = AttackStatus.Parry; return -2; } #endregion float dodgeChance = DodgeChanceCalculation(m,dif); #region Dodge test roll = Utility.Random( 100 ); if (dodgeChance >= roll) { lastAttack = AttackStatus.Dodge; m.lastAttackToMe = AttackStatus.Dodge; return -1; } #endregion } float damage = DamageDoneCalculation(m,dmgBonus,criticalStrike,weapon); float blockChance = BlockChanceCalculation(m,dif); if (!pass) { #region Block test + block reduction roll = Utility.Random( 100 ); // shield specialization if (blockChance >= roll) { lastAttack = AttackStatus.Block; m.lastAttackToMe = AttackStatus.Block; amountBlocked = m.Block + m.Str/30; damage -= amountBlocked; #region talents // shield specialization if ( m.HaveTalent(Talents.ShieldSpecialization) ) { AuraEffect af = (AuraEffect)m.GetTalentEffect(Talents.ShieldSpecialization); roll = Utility.Random( 100 ); if ( roll < af.H ) { m.GainMana(m,(Abilities.abilities[af.AdditionalSpell] as SpellTemplate).S1); } } #endregion } #endregion } #region Armor reduction float armor = ArmorReductionCalculation(m); damage = damage * (1 - armor); #endregion #region immune if (m.ImmunePhysicalDamage) { lastAttack = AttackStatus.Immune; m.lastAttackToMe = AttackStatus.Immune; return 0; } #endregion #region absorb amountAbsorbed = (int)damage; damage =(int)m.DamageAbsorbCombat(damage); amountAbsorbed -= (int)damage; if ( damage < 0 ) { this.lastAttack = AttackStatus.Absorb; m.lastAttackToMe = AttackStatus.Absorb; return 0; } #endregion #region Targets modificators damage = DamageTakenCalculation(m,damage); #endregion damage = m.ManaShieldLost(this,(int)damage); #region other effects switch (this.Classe) { #region warrior case Classes.Warrior: // deep wounds if (this.lastAttack == AttackStatus.Critical) { /*if ( src.HaveTalent( Talents.DeepWounds) ) { AuraEffect ae = (AuraEffect)src.GetTalentEffect( Talents.DeepWounds ); AuraEffect af = (AuraEffect)Abilities.abilities[ae.AdditionalSpell]; float modif = (float)ae.S1/100; af.ApplyDot(this, m, (int)(damage*modif), af.T1, af.Duration(this)); }*/ if ( m.HaveTalent( Talents.BloodCraze) ) { AuraEffect ae = (AuraEffect)m.GetTalentEffect( Talents.BloodCraze ); SpellTemplate st = (SpellTemplate)Abilities.abilities[ae.AdditionalSpell]; HotAura aura = new HotAura(st,m,m,(int)(m.BaseHitPoints*((float)st.S1/100)/(st.Duration(m)/st.T1)),st.Duration(m),st.T1); } } //Mace specialization /*if ( src.HaveTalent( Talents.MaceSpecialization) && weapon.SubClass == 4 ) { AuraEffect ae = (AuraEffect)src.GetTalentEffect( Talents.MaceSpecialization ); roll = Utility.Random( 100 ); if(roll < ae.H) { AuraEffect af = (AuraEffect)Abilities.abilities[ae.AdditionalSpell]; Aura aura = new Aura(); aura.ForceStun = true; m.AddAura(this, af,aura,true); } }*/ //int SwordSpecializationEffect = 0x14af5e; /*if ( src.HaveTalent( Talents.SwordSpecialization) && weapon.SubClass == 15 ) { AuraEffect ae = (AuraEffect)src.GetTalentEffect( Talents.SwordSpecialization ); roll = Utility.Random( 100 ); if(roll < ae.H) { this.AdditionnalStates.Add(SwordSpecializationEffect); } }*/ if ( this.HaveTalent( Talents.UnbridledWrath) ) { AuraEffect ae = (AuraEffect)this.GetTalentEffect( Talents.UnbridledWrath ); roll = Utility.Random( 100 ); if(roll < ae.H) { this.GainMana(this,1); } } break; #endregion } #endregion if ( damage > 0 ) this.SkillUpWeapon(weapon); return (int)damage; }
protected virtual AttackStatus TickAttack(Actor self, AttackFrontal attack) { if (!target.IsValidFor(self)) { return(AttackStatus.UnableToAttack); } if (attack.Info.AttackRequiresEnteringCell && !positionable.CanEnterCell(target.Actor.Location, null, false)) { return(AttackStatus.UnableToAttack); } if (!attack.Info.TargetFrozenActors && !forceAttack && target.Type == TargetType.FrozenActor) { // Try to move within range, drop the target otherwise if (move == null) { return(AttackStatus.UnableToAttack); } var rs = revealsShroud .Where(Exts.IsTraitEnabled) .MaxByOrDefault(s => s.Range); // Default to 2 cells if there are no active traits var sightRange = rs != null ? rs.Range : WDist.FromCells(2); attackStatus |= AttackStatus.NeedsToMove; QueueChild(self, move.MoveWithinRange(target, sightRange, target.CenterPosition, Color.Red), true); return(AttackStatus.NeedsToMove); } // Drop the target once none of the weapons are effective against it var armaments = attack.ChooseArmamentsForTarget(target, forceAttack).ToList(); if (armaments.Count == 0) { return(AttackStatus.UnableToAttack); } // Update ranges minRange = armaments.Max(a => a.Weapon.MinRange); maxRange = armaments.Min(a => a.MaxRange()); var pos = self.CenterPosition; var mobile = move as Mobile; if (!target.IsInRange(pos, maxRange) || (minRange.Length != 0 && target.IsInRange(pos, minRange)) || (mobile != null && !mobile.CanInteractWithGroundLayer(self))) { // Try to move within range, drop the target otherwise if (move == null) { return(AttackStatus.UnableToAttack); } attackStatus |= AttackStatus.NeedsToMove; var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target; QueueChild(self, move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red), true); return(AttackStatus.NeedsToMove); } if (!attack.TargetInFiringArc(self, target, attack.Info.FacingTolerance)) { var desiredFacing = (attack.GetTargetPosition(pos, target) - pos).Yaw.Facing; attackStatus |= AttackStatus.NeedsToTurn; QueueChild(self, new Turn(self, desiredFacing), true); return(AttackStatus.NeedsToTurn); } attackStatus |= AttackStatus.Attacking; DoAttack(self, attack, armaments); return(AttackStatus.Attacking); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); return(this); } if (IsCanceling) { return(NextActivity); } bool targetIsHiddenActor; target = RecalculateTarget(self, out targetIsHiddenActor); if (!targetIsHiddenActor && target.Type == TargetType.Actor) { lastVisibleTarget = Target.FromTargetPositions(target); lastVisibleMaximumRange = attackTraits.Where(x => !x.IsTraitDisabled) .Min(x => x.GetMaximumRangeVersusTarget(target)); lastVisibleOwner = target.Actor.Owner; lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes(); } var oldUseLastVisibleTarget = useLastVisibleTarget; useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); // If we are ticking again after previously sequencing a MoveWithRange then that move must have completed // Either we are in range and can see the target, or we've lost track of it and should give up if (wasMovingWithinRange && targetIsHiddenActor) { return(NextActivity); } // Update target lines if required if (useLastVisibleTarget != oldUseLastVisibleTarget) { self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, Color.Red, false); } // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) { return(NextActivity); } wasMovingWithinRange = false; var pos = self.CenterPosition; var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target; // We don't know where the target actually is, so move to where we last saw it if (useLastVisibleTarget) { // We've reached the assumed position but it is not there or we can't move any further - give up if (checkTarget.IsInRange(pos, lastVisibleMaximumRange) || move == null || lastVisibleMaximumRange == WDist.Zero) { return(NextActivity); } // Move towards the last known position wasMovingWithinRange = true; QueueChild(self, move.MoveWithinRange(target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red), true); return(this); } attackStatus = AttackStatus.UnableToAttack; foreach (var attack in attackTraits.Where(x => !x.IsTraitDisabled)) { var status = TickAttack(self, attack); attack.IsAiming = status == AttackStatus.Attacking || status == AttackStatus.NeedsToTurn; } if (attackStatus.HasFlag(AttackStatus.NeedsToMove)) { wasMovingWithinRange = true; } if (attackStatus >= AttackStatus.NeedsToTurn) { return(this); } return(NextActivity); }
public Attack(AttackType attackType) { this.attackType = attackType; this.attackStatus = AttackStatus.Attacking; }
public void Wait() { Status = AttackStatus.Wait; }
public void Process() { Status = /*Handler.IsDelay ? AttackStatus.Delay : */ AttackStatus.Process; }
protected void DoShoot(bool shallStop = false) { var dir = target.transform.position - owner.transform.position; dir.y = 0; // Debug.Log("shhot dir: " + dir); owner.Control.SetToDirection(dir); //dir = new Vector3(dir.x,owner.transform.position.y,dir.z); owner.TryAttack(dir, target); owner.OnShootEnd += OnShootEnd; attackStatus = AttackStatus.shoot; if (shallStop) { ((AgentControl)owner.Control).Stop(false); } }
public void Process() { Status = /*Handler.IsDelay ? AttackStatus.Delay : */AttackStatus.Process; }
public virtual int AttackSwing( Mobile target,bool pass ) { #region immune test if (this.ImmuneAttack) { this.lastAttack = AttackStatus.Immune; return 0; } #endregion if(this.AttackTarget != null) { ArrayList NAEbuff = (ArrayList)NextAttackEffects.Clone(); foreach(NextAttackEffect nae in NAEbuff) { this.OnSpellTemplateResults(nae.spell,this.AttackTarget); this.NextAttackSpellGo(nae); } NAEbuff.Clear(); } int amountAbsorbed = 0; int amountBlocked = 0; int degats = Hit( target, 0f, pass, ref amountBlocked, ref amountAbsorbed ); int offset = 4; if ( degats <= 0 ) Converter.ToBytes( 0x22, tempBuff, ref offset ); else Converter.ToBytes( 0x22, tempBuff, ref offset ); Converter.ToBytes( Guid, tempBuff, ref offset ); Converter.ToBytes( target.Guid, tempBuff, ref offset ); if ( degats < 0 ) Converter.ToBytes( 0, tempBuff, ref offset ); else Converter.ToBytes( degats, tempBuff, ref offset ); Converter.ToBytes( (byte)1, tempBuff, ref offset ); Converter.ToBytes( 0, tempBuff, ref offset ); if ( degats > 0 ) Converter.ToBytes( (float)degats/*DamageType*/, tempBuff, ref offset ); else Converter.ToBytes( 0, tempBuff, ref offset ); // Converter.ToBytes( 0/*DamageType*/, tempBuff, ref offset ); // float ang = (float)Math.Atan2( AttackTarget.Y - Y, AttackTarget.X - X ); if ( degats < 0 ) Converter.ToBytes( 0, tempBuff, ref offset ); else Converter.ToBytes( degats, tempBuff, ref offset ); // Converter.ToBytes( amountAbsorbed, tempBuff, ref offset );// damage absorbed // Converter.ToBytes( 0, tempBuff, ref offset ); // new victim state Converter.ToBytes( 0, tempBuff, ref offset ); // additional spell damage id Converter.ToBytes( 0, tempBuff, ref offset ); // additional spell damage id #region Degats types if ( degats >= 0 ) Converter.ToBytes( 1, tempBuff, ref offset ); else if ( degats == -1 ) Converter.ToBytes( 2, tempBuff, ref offset );// dodge else if ( degats == - 2 ) Converter.ToBytes( 9, tempBuff, ref offset );// parry else if ( degats == - 3 ) Converter.ToBytes( 4, tempBuff, ref offset );// interrupted else if ( degats == - 4 || amountBlocked > 0 ) Converter.ToBytes( 5, tempBuff, ref offset );// block else if ( degats == - 5 ) Converter.ToBytes( 6, tempBuff, ref offset );// evade else if ( degats == - 6 ) Converter.ToBytes( 7, tempBuff, ref offset );// immune else if ( degats == - 7 ) Converter.ToBytes( 8, tempBuff, ref offset );// deflect #endregion if ( degats == 0 ) Converter.ToBytes( 0xffffffff, tempBuff, ref offset ); else Converter.ToBytes( 0, tempBuff, ref offset ); Converter.ToBytes( 0, tempBuff, ref offset ); Converter.ToBytes( 0, tempBuff, ref offset ); ToAllPlayerNear( OpCodes.SMSG_ATTACKERSTATEUPDATE, tempBuff, offset ); target.LooseHits( this, degats, true ); return degats; }
public void Process() { Status = AttackStatus.Process; }
protected override void Initialize(FSMEvent ev = null) { _eventAttackMelee = ev as AnimFSMEventAttackMelee; _attackStatus = AttackStatus.PREPARING; Agent.BlackBoard.motionType = MotionType.ATTACK; _startRotation = Agent.Transform.rotation; _startPosition = Agent.Transform.position; if (_eventAttackMelee.target != null) { float angle = 0; float distance = 0; Vector3 finalDir = _eventAttackMelee.target.Position - Agent.Transform.position; distance = finalDir.magnitude; if (distance > 0.1f) { finalDir.Normalize(); angle = Vector3.Angle(Agent.Transform.forward, finalDir); if (angle < 40 && Vector3.Angle(Agent.Forward, _eventAttackMelee.target.Forward) < 80) { _backHit = true; } } else { finalDir = Agent.Transform.forward; } _finalRotation.SetLookRotation(finalDir); if (distance < Agent.BlackBoard.weaponRange || Agent.BlackBoard.allowedFlashToWeaponRange == false || distance > Agent.BlackBoard.combatRange * 1.2f) { _finalPosition = _startPosition; _rotationTime = angle / 720.0f; } else { // flash if (distance >= Agent.BlackBoard.weaponRange * 1.5) { if (Agent.BlackBoard.showMotionEffect) { ParticleTools.Instance.Play(Agent.particleSystemFlashTust, (_eventAttackMelee.target.Position - Agent.Position).RadianInXZ()); } } _finalPosition = _eventAttackMelee.target.transform.position - finalDir * Agent.BlackBoard.weaponRange; Agent.Transform.LookAt(_eventAttackMelee.target.transform); _rotationTime = 0; } _moveTime = (_finalPosition - _startPosition).magnitude / 20.0f; } else { _finalRotation.SetLookRotation(_eventAttackMelee.attackDir); _rotationTime = Vector3.Angle(Agent.Transform.forward, _eventAttackMelee.attackDir) / 720.0f; _moveTime = 0; } _rotationOk = (_rotationTime == 0); _positionOK = (_moveTime == 0); _currentRotationTime = 0; _currentMoveTime = 0; _isCritical = IsCritical(); _knockdown = IsKnockDown(); _hitTimeStart = false; }
public BasicLocationObject(Position position) { _position = position; _status = AttackStatus.NotAttacked; _occupant = null; }
protected virtual AttackStatus TickAttack(Actor self, AttackBase attack) { if (IsCanceled) { return(AttackStatus.UnableToAttack); } var type = Target.Type; if (!Target.IsValidFor(self) || type == TargetT.FrozenActor) { return(AttackStatus.UnableToAttack); } if (attack.Info.AttackRequiresEnteringCell && !positionable.CanEnterCell(Target.Actor.Location, null, false)) { return(AttackStatus.UnableToAttack); } //Drop the target if it moves under the shroud / fog. if (!attack.Info.IgnoresVisibility && type == TargetT.Actor && !Target.Actor.Info.HasTraitInfo <FrozenUnderFogInfo>() && !Target.Actor.CanBeViewedByPlayer(self.Owner)) { return(AttackStatus.UnableToAttack); } //Drop the target once none of the weapons are effective against it var armaments = attack.ChooseArmamentsForTarget(Target, forceAttack).ToList(); if (armaments.Count == 0) { return(AttackStatus.UnableToAttack); } //Update ranges minRange = armaments.Max(a => a.Weapon.MinRange); maxRange = armaments.Min(a => a.MaxRange()); var pos = self.CenterPosition; var mobile = move as Mobile; if (!Target.IsInRange(pos, maxRange) || (minRange.Length != 0 && Target.IsInRange(pos, minRange)) || (mobile != null && !mobile.CanInteractWithGroundLayer(self))) { //Try to move within range,drop the target otherwise. if (move == null) { return(AttackStatus.UnableToAttack); } attackStatus |= AttackStatus.NeedsToMove; moveActivity = ActivityUtils.SequenceActivities(move.MoveWithinRange(Target, minRange, maxRange), this); return(AttackStatus.NeedsToMove); } var targetedPosition = attack.GetTargetPosition(pos, Target); var desiredFacing = (targetedPosition - pos).Yaw.Facing; if (!Util.FacingWithinTolerance(facing.Facing, desiredFacing, facingTolerance)) { attackStatus |= AttackStatus.NeedsToTurn; turnActivity = ActivityUtils.SequenceActivities(new Turn(self, desiredFacing), this); return(AttackStatus.NeedsToTurn); } attackStatus |= AttackStatus.Attacking; attack.DoAttack(self, Target, armaments); return(AttackStatus.Attacking); }
protected virtual Activity InnerTick(Actor self, AttackBase attack) { if (IsCanceled) { return(NextActivity); } var type = Target.Type; if (!Target.IsValidFor(self) || type == TargetType.FrozenActor) { return(NextActivity); } if (attack.Info.AttackRequiresEnteringCell && !positionable.CanEnterCell(Target.Actor.Location, null, false)) { return(NextActivity); } // Drop the target if it moves under the shroud / fog. // HACK: This would otherwise break targeting frozen actors // The problem is that Shroud.IsTargetable returns false (as it should) for // frozen actors, but we do want to explicitly target the underlying actor here. if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.Info.HasTraitInfo <FrozenUnderFogInfo>() && !self.Owner.CanTargetActor(Target.Actor)) { return(NextActivity); } // Drop the target once none of the weapons are effective against it var armaments = attack.ChooseArmamentsForTarget(Target, forceAttack).ToList(); if (armaments.Count == 0) { return(NextActivity); } // Update ranges minRange = armaments.Max(a => a.Weapon.MinRange); maxRange = armaments.Min(a => a.MaxRange()); var mobile = move as Mobile; if (!Target.IsInRange(self.CenterPosition, maxRange) || Target.IsInRange(self.CenterPosition, minRange) || (mobile != null && !mobile.CanInteractWithGroundLayer(self))) { // Try to move within range, drop the target otherwise if (move == null) { return(NextActivity); } attackStatus |= AttackStatus.NeedsToMove; moveActivity = ActivityUtils.SequenceActivities(move.MoveWithinRange(Target, minRange, maxRange), this); return(NextActivity); } var desiredFacing = (Target.CenterPosition - self.CenterPosition).Yaw.Facing; if (facing.Facing != desiredFacing) { attackStatus |= AttackStatus.NeedsToTurn; turnActivity = ActivityUtils.SequenceActivities(new Turn(self, desiredFacing), this); return(NextActivity); } attackStatus |= AttackStatus.Attacking; attack.DoAttack(self, Target, armaments); return(this); }