protected override void ServerSpawnBossEventObjects( ILogicObject activeEvent, Vector2D circlePosition, ushort circleRadius, List <IWorldObject> spawnedObjects) { foreach (var protoObjectToSpawn in this.SpawnPreset) { TrySpawn(); void TrySpawn() { const int maxAttempts = 3000; var attempt = 0; do { // select random position inside the circle // (the circle is expanded proportionally by the number of attempts performed) var spawnPosition = SharedCircleLocationHelper.SharedSelectRandomPositionInsideTheCircle( circlePosition, this.SpawnRadiusMax * (attempt / (double)maxAttempts)); if (!this.ServerIsValidSpawnPosition(spawnPosition)) { // doesn't match any specific checks determined by the inheritor (such as a zone test) continue; } var spawnedObject = Server.Characters.SpawnCharacter((IProtoCharacter)protoObjectToSpawn, spawnPosition); spawnedObjects.Add(spawnedObject); Logger.Important($"Spawned world object: {spawnedObject} for active event {activeEvent}"); if (spawnedObject.ProtoGameObject is IProtoCharacterMob protoCharacterMob) { protoCharacterMob.ServerSetSpawnState(spawnedObject, MobSpawnState.Spawning); } break; }while (++attempt < maxAttempts); if (attempt == maxAttempts) { Logger.Error($"Cannot spawn world object: {protoObjectToSpawn} for active event {activeEvent}"); } } } this.DestroySalt(circlePosition, circleRadius); }
protected virtual void ServerSpawnObjects( ILogicObject activeEvent, Vector2Ushort circlePosition, ushort circleRadius, List <IWorldObject> spawnedObjects) { var sqrMinDistanceBetweenSpawnedObjects = this.MinDistanceBetweenSpawnedObjects * this.MinDistanceBetweenSpawnedObjects; foreach (var protoObjectToSpawn in this.SpawnPreset) { TrySpawn(); void TrySpawn() { var attempts = 2_000; do { var spawnPosition = SharedCircleLocationHelper.SharedSelectRandomPositionInsideTheCircle( circlePosition, circleRadius); if (!this.ServerIsValidSpawnPosition(spawnPosition)) { // doesn't match any specific checks determined by the inheritor (such as a zone test) continue; } var isTooClose = false; foreach (var obj in spawnedObjects) { if (spawnPosition.TileSqrDistanceTo(obj.TilePosition) > sqrMinDistanceBetweenSpawnedObjects) { continue; } isTooClose = true; break; } if (isTooClose) { continue; } if (!ServerCheckCanSpawn(protoObjectToSpawn, spawnPosition)) { // doesn't match the tile requirements or inside a claimed land area continue; } if (Server.World.IsObservedByAnyPlayer(spawnPosition)) { // observed by players continue; } var spawnedObject = ServerTrySpawn(protoObjectToSpawn, spawnPosition); spawnedObjects.Add(spawnedObject); Logger.Important($"Spawned world object: {spawnedObject} for active event {activeEvent}"); break; }while (--attempts > 0); if (attempts == 0) { Logger.Error($"Cannot spawn world object: {protoObjectToSpawn} for active event {activeEvent}"); } } } }