public override void Update(GameTime gameTime) { if (IsDestroyed) { return; } if (_waitMilliSeconds > 0) { _waitMilliSeconds -= (float)gameTime.ElapsedGameTime.TotalMilliseconds; return; } if (_parasitiferCharacter != null) { PositionInWorld = _parasitiferCharacter.PositionInWorld; if (_parasitiferCharacter.IsDeathInvoked) { _parasitiferCharacter = null; _isDestroyed = true; } else { _parasticTime += (float)gameTime.ElapsedGameTime.TotalMilliseconds; if (_parasticTime >= BelongMagic.ParasiticInterval) { _parasticTime -= BelongMagic.ParasiticInterval; UseMagic(BelongMagic.ParasiticMagic); CharacterHited(_parasitiferCharacter, MagicManager.GetEffectAmount(BelongMagic, BelongCharacter), MagicManager.GetEffectAmount2(BelongMagic, BelongCharacter), BelongMagic.EffectMana, false); if (BelongMagic.ParasiticMaxEffect > 0 && _totalParasticEffect >= BelongMagic.ParasiticMaxEffect) { _parasitiferCharacter = null; _isDestroyed = true; } } } } if (_paths != null) { if (_paths.Count > 1) { var beginPosition = _paths.First.Value; var endPosition = _paths.First.Next.Value; var distance = Vector2.Distance(beginPosition, endPosition); MoveTo(endPosition - beginPosition, (float)gameTime.ElapsedGameTime.TotalSeconds); if (MovedDistance >= distance) { _paths.RemoveFirst(); MovedDistance = 0; PositionInWorld = endPosition; if (_paths.Count < 2) { if (_destroyOnEnd || BelongMagic.MeteorMove > 0) { Destroy(); } CheckCharacterHited(); } } } } else { if (!IsInDestroy) { if (BelongMagic.FollowMouse > 0) { var mouseState = Mouse.GetState(); var mouseScreenPosition = new Vector2(mouseState.X, mouseState.Y); var mouseWorldPosition = Globals.TheCarmera.ToWorldPosition(mouseScreenPosition); var direction = mouseWorldPosition - PositionInWorld; MoveDirection = direction.Length() > 25 ? direction : Vector2.Zero; } else if (BelongMagic.RandomMoveDegree > 0) { while (MoveDirection == Vector2.Zero) { MoveDirection = new Vector2((float)Globals.TheRandom.Next(-100, 100) / 100.0f, (float)Globals.TheRandom.Next(-100, 100) / 100.0f); } var perpendicular1 = new Vector2(MoveDirection.Y, -MoveDirection.X); var perpendicular2 = new Vector2(-MoveDirection.Y, MoveDirection.X); var random = (Globals.TheRandom.Next(2) == 0 ? perpendicular1 : perpendicular2) * Globals.TheRandom.Next(BelongMagic.RandomMoveDegree); MoveDirection += random; } if (BelongMagic.MoveImitateUser > 0) { PositionInWorld += (BelongCharacter.PositionInWorld - _lastUserWorldPosition); _lastUserWorldPosition = BelongCharacter.PositionInWorld; } if (BelongMagic.CircleMoveColockwise > 0 || BelongMagic.CircleMoveAnticlockwise > 0) { var dir = PositionInWorld - BelongCharacter.PositionInWorld; if (dir != Vector2.Zero) { dir.Normalize(); dir = BelongMagic.CircleMoveColockwise > 0 ? new Vector2(-dir.Y, dir.X) : new Vector2(dir.Y, -dir.X); _circleMoveDir = dir; } } if (_isInMoveBack) { //Move back to magic user. var dir = BelongCharacter.PositionInWorld - PositionInWorld; MoveDirection = dir; if (dir.Length() < 20) { _isInMoveBack = false; _isDestroyed = true; } } } if (BelongMagic.MoveKind == 16) { if (MovedDistance > 200f) //First move 200, than find target { if (BelongCharacter.IsPlayer || BelongCharacter.IsFriend) { if (_closedCharecter == null || _closedCharecter.IsDeath) { _closedCharecter = NpcManager.GetClosestEnemyTypeCharacter(PositionInWorld); } } else { _closedCharecter = Globals.ThePlayer; } if (_closedCharecter != null) { MoveDirection = _closedCharecter.PositionInWorld - PositionInWorld; } } MoveToNoNormalizeDirection(RealMoveDirection, (float)gameTime.ElapsedGameTime.TotalSeconds, MagicManager.GetSpeedRatio(RealMoveDirection)); } else if (_isInDestroy) { //Stop moving when in destroy. } else { MoveToNoNormalizeDirection(RealMoveDirection, (float)gameTime.ElapsedGameTime.TotalSeconds); } } if (BelongMagic.MoveKind == 13 || BelongMagic.MoveKind == 23) { PositionInWorld = BelongCharacter.PositionInWorld; } if (!_isInDestroy) { if (BelongMagic.RangeEffect > 0) { _rangeElapsedMilliseconds += (float)gameTime.ElapsedGameTime.TotalMilliseconds; if (_rangeElapsedMilliseconds >= BelongMagic.RangeTimeInerval) { _rangeElapsedMilliseconds -= BelongMagic.RangeTimeInerval; if (BelongMagic.RangeAddLife > 0 || BelongMagic.RangeAddMana > 0 || BelongMagic.RangeAddThew > 0 || BelongMagic.RangeSpeedUp > 0) { foreach (var target in NpcManager.FindFriendInTileDistance(BelongCharacter, TilePosition, BelongMagic.RangeRadius)) { if (BelongMagic.RangeAddLife > 0) { target.AddLife(BelongMagic.RangeAddLife); } if (BelongMagic.RangeAddMana > 0) { target.AddMana(BelongMagic.RangeAddMana); } if (BelongMagic.RangeAddThew > 0) { target.AddThew(BelongMagic.RangeAddThew); } if (BelongMagic.RangeSpeedUp > 0 && target.SppedUpByMagicSprite == null) { target.SppedUpByMagicSprite = this; } } } if (BelongMagic.RangeFreeze > 0 || BelongMagic.RangePoison > 0 || BelongMagic.RangePetrify > 0 || BelongMagic.RangeDamage > 0) { foreach (var target in NpcManager.FindEnemiesInTileDistance(BelongCharacter, TilePosition, BelongMagic.RangeRadius)) { if (BelongMagic.RangeFreeze > 0) { target.SetFrozenSeconds(BelongMagic.RangeFreeze / 1000.0f, BelongMagic.NoSpecialKindEffect == 0); } if (BelongMagic.RangePoison > 0) { target.SetPoisonSeconds(BelongMagic.RangePoison / 1000.0f, BelongMagic.NoSpecialKindEffect == 0); } if (BelongMagic.RangePetrify > 0) { target.SetPetrifySeconds(BelongMagic.RangePetrify / 1000.0f, BelongMagic.NoSpecialKindEffect == 0); } if (BelongMagic.RangeDamage > 0) { CharacterHited(target, BelongMagic.RangeDamage, BelongMagic.Effect2, 0); AddDestroySprite(MagicManager.EffectSprites, target.PositionInWorld, BelongMagic.VanishImage, BelongMagic.VanishSound); } } } } } if (BelongMagic.FlyMagic != null) { _flyMagicElapsedMilliSeconds += (float)gameTime.ElapsedGameTime.TotalMilliseconds; if (_flyMagicElapsedMilliSeconds >= BelongMagic.FlyInterval) { _flyMagicElapsedMilliSeconds -= BelongMagic.FlyInterval; var dir = RealMoveDirection == Vector2.Zero ? PositionInWorld - BelongCharacter.PositionInWorld : RealMoveDirection; MagicManager.UseMagic(BelongCharacter, BelongMagic.FlyMagic, PositionInWorld, PositionInWorld + dir); } } } if (IsInDestroy) { if (BelongMagic.MoveKind == 15) { var end = false; foreach (var sprite in _superModeDestroySprites) { sprite.Update(gameTime); if (!sprite.IsInPlaying) { end = true; break; } } if (end) { _isDestroyed = true; } } else { if (!IsInPlaying) { _isDestroyed = true; } } } else if (_paths != null) { //do nothing } else if (BelongMagic.MoveKind == 15) { if (!IsInPlaying) { Destroy(); } } else if (BelongMagic.MoveKind == 22) //Summon { if (_summonElapsedMilliseconds < BelongMagic.KeepMilliseconds) { _summonElapsedMilliseconds += (float)gameTime.ElapsedGameTime.TotalMilliseconds; if (!IsInPlaying) { Texture = Asf.Empty; } } else { Destroy(); } } else { var checkHit = true; switch (BelongMagic.MoveKind) { case 13: case 20: //transport case 21: //Controling others case 22: case 23: //Time stoper checkHit = false; break; default: CheckCharacterHited(); break; } if (checkHit && CheckDestroyForObstacleInMap()) { Destroy(); } else if (!IsInPlaying) { if (BelongMagic.MoveBack > 0) { if (Velocity == 0.0f) { Velocity = Globals.MagicBasespeed * BelongMagic.Speed; } _isInMoveBack = true; } else if (_destroyOnEnd) { Destroy(); } else { _isDestroyed = true; } } } base.Update(gameTime); }
public override void Update(GameTime gameTime) { if (_controledMagicSprite != null) { base.Update(gameTime); return; } //Find follow target if (!IsFollowTargetFound || // Not find target. FollowTarget == null || // Follow target not assign. FollowTarget.IsDeathInvoked || //Follow target is death. !FollowTarget.IsVisible || (IsEnemy && FollowTarget.IsEnemy) || // Follow target relation changed (IsFighterFriend && (FollowTarget.IsFighterFriend || FollowTarget.IsPlayer)) || // Follow target relation changed IsAIDisabled) //Npc AI is disabled. { if (IsEnemy) { if (StopFindingTarget == 0) { FollowTarget = IsAIDisabled ? null : NpcManager.GetLiveClosestPlayerOrFighterFriend(PositionInWorld, true, false); } else if (FollowTarget != null && FollowTarget.IsDeathInvoked) { FollowTarget = null; } } else if (IsFighterFriend) { if (StopFindingTarget == 0) { FollowTarget = IsAIDisabled ? null : NpcManager.GetClosestEnemyTypeCharacter(PositionInWorld, true, false); } else if (FollowTarget != null && FollowTarget.IsDeathInvoked) { FollowTarget = null; } //Fighter friend may be parter if (FollowTarget == null && IsPartner) { //Can't find enemy, move to player MoveToPlayer(); } } else if (IsNoneFighter) { if (StopFindingTarget == 0) { FollowTarget = IsAIDisabled ? null : NpcManager.GetLiveClosestNonneturalFighter(PositionInWorld); } else if (FollowTarget != null && FollowTarget.IsDeathInvoked) { FollowTarget = null; } } else if (IsPartner) { MoveToPlayer(); } } if (!CheckKeepDistanceWhenFriendDeath() && !KeepDistanceWhenLifeLow() && MagicToUseWhenLifeLow != null && LifeMax > 0 && Life / (float)LifeMax <= LifeLowPercent / 100.0f) { PerformeAttack(PositionInWorld + Utils.GetDirection8(CurrentDirection), MagicToUseWhenLifeLow); } else { //Follow target PerformeFollow(); } //Attack interval if (_idledFrame < Idle) { _idledFrame++; } if (IsFollowTargetFound) { //Character found follow target and move to follow target. //This may cause character move far away from the initial base tile position. //Assing ActionPathTilePositionList value to null, //when get next time, new path is generated use new base tile postion. ActionPathTilePositionList = null; } ////Follow target not found, do something else. if ((FollowTarget == null || !IsFollowTargetFound) && !(IsFighterKind && IsAIDisabled)) //Fighter can't move when AI diaabled { var isFlyer = Kind == (int)CharacterKind.Flyer; const int randWalkPosibility = 400; const int flyerRandWalkPosibility = 20; if (Action == (int)ActionType.LoopWalk && FixedPathTilePositionList != null) { //Loop walk along FixedPos LoopWalk(FixedPathTilePositionList, isFlyer ? flyerRandWalkPosibility : randWalkPosibility, ref _currentFixedPosIndex, isFlyer); } else { switch ((CharacterKind)Kind) { case CharacterKind.Normal: case CharacterKind.Fighter: case CharacterKind.GroundAnimal: case CharacterKind.Eventer: case CharacterKind.Flyer: { switch ((ActionType)Action) { case ActionType.RandWalk: RandWalk(ActionPathTilePositionList, isFlyer ? flyerRandWalkPosibility : randWalkPosibility, isFlyer); break; } } break; case CharacterKind.AfraidPlayerAnimal: { KeepMinTileDistance(Globals.PlayerTilePosition, VisionRadius); } break; } } } base.Update(gameTime); }