Пример #1
0
        public static void OnCharacterDeath(ICharacter deadCharacter)
        {
            var publicState = deadCharacter.GetPublicState <ICharacterPublicState>();

            if (!publicState.IsDead)
            {
                publicState.CurrentStats.ServerSetHealthCurrent(0);
                return;
            }

            // recreate physics (as dead character doesn't have any physics)
            deadCharacter.ProtoCharacter.SharedCreatePhysics(deadCharacter);

            if (deadCharacter.ProtoCharacter is IProtoCharacterMob protoCharacterMob)
            {
                Api.SafeInvoke(() => CharacterDeath?.Invoke(deadCharacter));
                protoCharacterMob.ServerOnDeath(deadCharacter);
                return;
            }

            // player character death
            // remember the death position (useful for the respawn)
            var privateState = PlayerCharacter.GetPrivateState(deadCharacter);

            privateState.LastDeathPosition = deadCharacter.TilePosition;
            privateState.LastDeathTime     = Api.Server.Game.FrameTime;
            ServerTimersSystem.AddAction(
                delaySeconds: PlayerTeleportToGraveyardDelaySeconds,
                () =>
            {
                if (!publicState.IsDead)
                {
                    // player has already respawned
                    return;
                }

                CharacterDespawnSystem.ServerTeleportPlayerCharacterToServiceArea(deadCharacter);
                CharacterRespawnSystem.ServerRemoveStatusEffectsOnRespawn(deadCharacter);
            });

            var isPvPdeath = CharacterDamageTrackingSystem.ServerGetPvPdamagePercent(deadCharacter)
                             >= 0.5;

            // register death (required even if the player is not a newbie)
            NewbieProtectionSystem.ServerRegisterDeath(deadCharacter,
                                                       isPvPdeath,
                                                       out var shouldSufferDeathConsequences);

            if (shouldSufferDeathConsequences)
            {
                DropPlayerLoot(deadCharacter);
            }
            else
            {
                Api.Logger.Important("Player character is dead - newbie PvP case, no loot drop or other consequences",
                                     deadCharacter);
            }

            Api.SafeInvoke(() => CharacterDeath?.Invoke(deadCharacter));
        }
Пример #2
0
        protected override bool ServerIsCompleted(ICharacter character, PlayerTaskState state)
        {
            if (!character.ServerIsOnline ||
                character.TilePosition == CharacterDespawnSystem.ServerGetServiceAreaPosition())
            {
                return(false);
            }

            return(character.Tile.ProtoTile == this.ProtoTile);
        }
Пример #3
0
        /// <summary>
        /// Barrier (a circle impenetrable area) is present only in PvE to prevent players from rushing
        /// into the boss area before the boss is spawned.
        /// </summary>
        private void ServerCreateBossAreaBarrier(ILogicObject worldEvent)
        {
            var publicState = GetPublicState(worldEvent);

            if (publicState.ServerBarrierPhysicsBody is not null)
            {
                return;
            }

            // create the barrier
            publicState.ServerBarrierPhysicsBody = this.SharedCreateBarrierPhysicsBody(worldEvent);

            var activeEventPosition = publicState.AreaCirclePosition;
            var barrierRadius       = this.AreaBarrierRadius + 1;

            if (barrierRadius > byte.MaxValue)
            {
                Logger.Error(
                    "The boss area circle should never have a radius larger than 255 tiles as it prevents players despawn in PvE: "
                    + worldEvent);
                barrierRadius = byte.MaxValue;
            }

            var barrierRadiusSqr = barrierRadius * barrierRadius;

            // despawn all player characters inside the barrier or very close to it
            using var tempCharacters = Api.Shared.GetTempList <ICharacter>();
            Server.World.GetCharactersInRadius(activeEventPosition,
                                               tempCharacters,
                                               (byte)barrierRadius,
                                               onlyPlayers: true);

            foreach (var character in tempCharacters.AsList())
            {
                CharacterDespawnSystem.DespawnCharacter(character);
            }

            // despawn all vehicles inside the barrier or very close to it
            using var tempListVehicles = Api.Shared.GetTempList <IDynamicWorldObject>();
            foreach (var protoVehicle in Api.FindProtoEntities <IProtoVehicle>())
            {
                tempListVehicles.Clear();
                protoVehicle.GetAllGameObjects(tempListVehicles.AsList());
                foreach (var vehicle in tempListVehicles.AsList())
                {
                    if (vehicle.TilePosition.TileSqrDistanceTo(activeEventPosition)
                        <= barrierRadiusSqr)
                    {
                        VehicleGarageSystem.ServerPutIntoGarage(vehicle);
                    }
                }
            }

            // Please note: NPC characters that are stuck inside the area are pushed outside it by the physics engine
        }
Пример #4
0
        public override void SharedUpdate(double deltaTime)
        {
            this.timeRemains -= deltaTime;
            if (this.timeRemains > 0)
            {
                return;
            }

            PlayerCharacter.GetPrivateState(this.Character).SetCurrentActionState(null);

            if (Api.IsServer)
            {
                CharacterDespawnSystem.DespawnCharacter(this.Character);
            }
        }
Пример #5
0
        public static void SpawnPlayer(ICharacter character, bool isRespawn)
        {
            ServerAddTorchItemIfNoItems(character);

            if (character.IsInitialized &&
                CharacterCreationSystem.SharedIsCharacterCreated(character))
            {
                PlacePlayer(character, isRespawn);
            }
            else
            {
                // first time spawn, requires character creation
                CharacterDespawnSystem.DespawnCharacter(character);
            }
        }
Пример #6
0
        public static void OnCharacterInitialize(ICharacter character)
        {
            if (character.IsNpc)
            {
                return;
            }

            if (PlayerCharacter.GetPublicState(character).IsDead)
            {
                CharacterDespawnSystem.ServerTeleportPlayerCharacterToServiceArea(character);
                CharacterRespawnSystem.ServerRemoveStatusEffectsOnRespawn(character);
            }
            else if (PlayerCharacter.GetPrivateState(character).IsDespawned)
            {
                CharacterDespawnSystem.ServerTeleportPlayerCharacterToServiceArea(character);
            }
        }
Пример #7
0
            public override void ServerInitialize(IServerConfiguration serverConfiguration)
            {
                base.ServerInitialize(serverConfiguration);

                CharacterStyleSystem.ServerCharacterAppearanceSelected
                    += ServerCharacterAppearanceSelectedHandler;

                foreach (var character in Server.Characters.EnumerateAllPlayerCharacters(onlyOnline: false))
                {
                    var privateState = PlayerCharacter.GetPrivateState(character);
                    if (!privateState.IsDespawned &&
                        !SharedIsCharacterCreated(character))
                    {
                        // despawn all invalid characters
                        CharacterDespawnSystem.DespawnCharacter(character);
                    }
                }
            }
Пример #8
0
 public string Execute([CurrentCharacterIfNull] ICharacter player)
 {
     CharacterDespawnSystem.DespawnCharacter(player);
     return(player + " despawned");
 }