public static ICharacter GetClosestPlayer(ICharacter characterNpc) { byte?tileHeight = null; try { var playersInView = TempListPlayersInView; ServerWorldService.GetCharactersInView(characterNpc, playersInView, onlyPlayerCharacters: true); if (playersInView.Count == 0) { return(null); } ICharacter enemy = null; foreach (var player in playersInView) { if (player.GetPublicState <ICharacterPublicState>().IsDead) { // do not pay attention to dead characters continue; } if (player.ProtoCharacter.GetType() != typeof(PlayerCharacter)) { // don't react on non-player prototype (spectator?) continue; } var playerCharacterTile = player.Tile; if (!tileHeight.HasValue) { var npcTile = characterNpc.Tile; tileHeight = npcTile.Height; } if (playerCharacterTile.Height != tileHeight.Value) { // attack only on the same height characters // unless there is a direct line of sight between the NPC and the target if (AnyObstaclesBetween(characterNpc, player)) { continue; } } enemy = player; break; } return(enemy); } finally { TempListPlayersInView.Clear(); } }
private void ServerUpdateMobDespawn(ICharacter characterMob, TPrivateState privateState, double deltaTime) { if (!this.IsAutoDespawn) { return; } var distanceToSpawnSqr = privateState.SpawnPosition .TileSqrDistanceTo(characterMob.TilePosition); if (distanceToSpawnSqr < DespawnTileDistanceThreshold * DespawnTileDistanceThreshold) { // close to spawn area, no need to despawn privateState.TimerDespawn = 0; return; } // too far from spawn area, should despawn after delay if (privateState.TimerDespawn < DespawnTimeThreshold) { // delay is not finished yet privateState.TimerDespawn += deltaTime; return; } // should despawn // check that nobody is observing the mob var playersInView = TempListPlayersInView; playersInView.Clear(); ServerWorld.GetCharactersInView(characterMob, playersInView, onlyPlayerCharacters: true); foreach (var playerCharacter in playersInView) { if (playerCharacter.ServerIsOnline) { // cannot despawn - scoped by a player return; } } // nobody is observing, can despawn Logger.Important("Mob despawned as it went too far from the spawn position for too long: " + characterMob); ServerWorld.DestroyObject(characterMob); }