public override void Update(int deltaTime) { LogicUnit target = owner.target; FixVector3 position = owner.position; if (target != null && target.Alive() && owner.target.id == owner.targetId) { if (inFightInterval) { // Timing interval fightIntervalTimer += deltaTime; if (fightIntervalTimer >= fightInterval) { // Enter fight fightState = FightState.StartSwingPoint; fightIntervalTimer = 0; fightInterval = 0; inFightInterval = false; } } else { fightState = GetCurrentState(fightDurationTimer); fightDurationTimer += deltaTime; if (fightState == FightState.StartSwingPoint) { DebugUtils.Assert(owner.target.id == owner.targetId, string.Format("Fight Status : the soldier {0}'s targetId = {1}, but its target's id = {2}!", owner.id, owner.targetId, owner.target.id)); if (owner.stateListener.PostFightEvent()) { // Trigger skill, will interrupt fight. return; } else { // Save the crit attack performance code isCrit = Formula.TriggerCritical(owner.GetRandomNumber(), owner.GetCriticalChance()); //if ( isCrit ) //{ // hitTime = owner.critHitTime; // fightDuration = owner.critDuration; //} //else { hitTime = owner.attackHitTime; fightDuration = owner.attackDuration; } // Reset direction at attack begin. FixVector3 direction = target.position - position; owner.direction = direction; if (owner.standardAttackType == AttackDistanceType.Melee) { RenderMessage rm = new RenderMessage(); rm.ownerId = owner.id; rm.direction = direction.vector3; rm.type = RenderMessage.Type.SoldierAttack; rm.arguments.Add("isCrit", false); rm.arguments.Add("intervalRate", 1); owner.PostRenderMessage(rm); } else { RenderMessage rm = new RenderMessage(); rm.type = RenderMessage.Type.SoldierSpawnProjectile; rm.ownerId = owner.id; rm.direction = direction.vector3; rm.arguments.Add("projectileMetaId", owner.projectileId); rm.arguments.Add("intervalRate", 1); owner.PostRenderMessage(rm); } } } else if (fightState == FightState.HitPoint) { owner.Fight(isCrit); owner.stateListener.PostUnitFightAfter(); } else if (fightState == FightState.BackSwing) { if (fightDurationTimer >= fightDuration) { fightDurationTimer = 0; fightInterval = owner.GetAttackInterval() - fightDuration; inFightInterval = true; } } } long distance = FixVector3.SqrDistance(target.position, owner.position); long attackDistance = owner.GetAttackArea(); if (distance >= attackDistance) { if ((target.position - owner.targetPosition).magnitude > attackDistance) { owner.Chase(target); } else { // continue fight } } } else { owner.Idle(); } }