예제 #1
0
        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);
            }
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        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)
            });
예제 #4
0
        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);
            }
        }