private static bool ServerCheckCanSpawn(IProtoWorldObject protoObjectToSpawn, Vector2Ushort spawnPosition) { switch (protoObjectToSpawn) { case IProtoCharacterMob _: return(ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn(spawnPosition.ToVector2D(), isPlayer: false)); case IProtoStaticWorldObject protoStaticWorldObject: return(protoStaticWorldObject.CheckTileRequirements(spawnPosition, character: null, logErrors: false)); default: throw new Exception("Unknown object type to spawn: " + protoObjectToSpawn); } }
/// <summary> /// Server spawn callback for mob. /// </summary> /// <param name="trigger">Trigger leading to this spawn.</param> /// <param name="zone">Server zone instance.</param> /// <param name="protoMob">Prototype of character mob object to spawn.</param> /// <param name="tilePosition">Position to try spawn at.</param> protected virtual IGameObjectWithProto ServerSpawnMob( IProtoTrigger trigger, IServerZone zone, IProtoCharacterMob protoMob, Vector2Ushort tilePosition) { var worldPosition = tilePosition.ToVector2D(); if (!ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn(worldPosition, isPlayer: false)) { // position is not valid for spawning return(null); } return(Server.Characters.SpawnCharacter( protoMob, worldPosition)); }
private static bool ServerCheckCanSpawn(IProtoWorldObject protoObjectToSpawn, Vector2Ushort spawnPosition) { return(protoObjectToSpawn switch { IProtoCharacterMob => ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn( spawnPosition.ToVector2D(), isPlayer: false) && !LandClaimSystem.SharedIsLandClaimedByAnyone(spawnPosition), IProtoStaticWorldObject protoStaticWorldObject // Please note: land claim check must be integrated in the object tile requirements => protoStaticWorldObject.CheckTileRequirements( spawnPosition, character: null, logErrors: false), _ => throw new ArgumentOutOfRangeException("Unknown object type to spawn: " + protoObjectToSpawn) });
public static void ServerSpawnBossMinionsOnDeath( Vector2Ushort epicenterPosition, double bossDifficultyCoef, IProtoCharacter minionProto, int minionsDefaultCount, double minionsRadius) { var countToSpawnRemains = minionsDefaultCount; // apply difficulty coefficient countToSpawnRemains = (int)Math.Ceiling(countToSpawnRemains * bossDifficultyCoef); var attemptsRemains = 3000; while (countToSpawnRemains > 0) { attemptsRemains--; if (attemptsRemains <= 0) { // attempts exceeded return; } // calculate random distance from the explosion epicenter var distance = RandomHelper.Range(2, minionsRadius); // ensure we spawn more objects closer to the epicenter var spawnProbability = 1 - (distance / minionsRadius); spawnProbability = Math.Pow(spawnProbability, 1.25); if (!RandomHelper.RollWithProbability(spawnProbability)) { // random skip continue; } var angle = RandomHelper.NextDouble() * MathConstants.DoublePI; var spawnPosition = new Vector2Ushort( (ushort)(epicenterPosition.X + distance * Math.Cos(angle)), (ushort)(epicenterPosition.Y + distance * Math.Sin(angle))); if (ServerTrySpawnMinion(spawnPosition)) { // spawned successfully! countToSpawnRemains--; } } bool ServerTrySpawnMinion(Vector2Ushort spawnPosition) { var worldPosition = spawnPosition.ToVector2D(); if (!ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn(worldPosition, isPlayer: false)) { // position is not valid for spawning return(false); } var spawnedCharacter = ServerCharacters.SpawnCharacter(minionProto, worldPosition); return(spawnedCharacter is not null); } }