Esempio n. 1
0
        private void ServerExplode(IStaticWorldObject worldObject, ICharacter character)
        {
            try
            {
                Logger.Important(worldObject + " exploded");
                this.ServerSendObjectDestroyedEvent(worldObject);

                ExplosionHelper.ServerExplode(
                    character: character,
                    protoExplosive: this,
                    protoWeapon: null,
                    explosionPreset: this.ExplosionPreset,
                    epicenterPosition: worldObject.TilePosition.ToVector2D() + this.Layout.Center,
                    damageDescriptionCharacters: this.damageDescriptionCharacters,
                    physicsSpace: worldObject.PhysicsBody.PhysicsSpace,
                    executeExplosionCallback: this.ServerExecuteExplosion);

                if (this.IsActivatesRaidModeForLandClaim)
                {
                    var explosionRadius = (int)Math.Ceiling(this.DamageRadius);
                    var bounds          = new RectangleInt(x: worldObject.TilePosition.X - explosionRadius,
                                                           y: worldObject.TilePosition.Y - explosionRadius,
                                                           width: 2 * explosionRadius,
                                                           height: 2 * explosionRadius);

                    if (RaidingProtectionSystem.SharedCanRaid(bounds,
                                                              showClientNotification: false))
                    {
                        // try activate the raidblock
                        LandClaimSystem.ServerOnRaid(bounds, character);
                    }
                    else
                    {
                        // Raiding is not possible now due to raiding window
                        // Find if there is any land claim and in that case notify nearby players
                        // that the damage to objects there were not applied.
                        if (LandClaimSystem.SharedIsLandClaimedByAnyone(bounds))
                        {
                            using var tempPlayers = Api.Shared.GetTempList <ICharacter>();
                            Server.World.GetScopedByPlayers(worldObject, tempPlayers);
                            RaidingProtectionSystem.ServerNotifyShowNotificationRaidingNotAvailableNow(
                                tempPlayers.AsList());
                        }
                    }
                }
            }
            finally
            {
                Server.World.DestroyObject(worldObject);
            }
        }
        private void ServerExplode(IStaticWorldObject worldObject, ICharacter character)
        {
            Logger.Important(worldObject + " exploded");

            this.ServerSendObjectDestroyedEvent(worldObject);

            ExplosionHelper.ServerExplode(
                character: character,
                protoObjectExplosive: this,
                explosionPreset: this.ExplosionPreset,
                epicenterPosition: worldObject.TilePosition.ToVector2D() + this.Layout.Center,
                damageDescriptionCharacters: this.damageDescriptionCharacters,
                physicsSpace: worldObject.PhysicsBody.PhysicsSpace,
                executeExplosionCallback: this.ServerExecuteExplosion);

            Server.World.DestroyObject(worldObject);

            LandClaimSystem.ServerOnRaid(worldObject.TilePosition, this.DamageRadius, character);
        }
Esempio n. 3
0
        protected override void ServerOnDynamicObjectZeroStructurePoints(
            WeaponFinalCache weaponCache,
            ICharacter byCharacter,
            IWorldObject targetObject)
        {
            var vehicle = (IDynamicWorldObject)targetObject;

            // explode
            using var scopedBy = Api.Shared.GetTempList <ICharacter>();
            Server.World.GetCharactersInRadius(vehicle.TilePosition,
                                               scopedBy,
                                               radius: this.DestroyedExplosionRadius,
                                               onlyPlayers: true);

            this.CallClient(scopedBy.AsList(),
                            _ => _.ClientRemote_VehicleExploded(vehicle.Position));

            ExplosionHelper.ServerExplode(
                character:
                null, // yes, no damaging character here otherwise it will not receive the damage if staying close
                protoExplosive: null,
                protoWeapon: null,
                explosionPreset: this.DestroyedExplosionPreset,
                epicenterPosition: vehicle.Position
                + this.SharedGetObjectCenterWorldOffset(targetObject),
                damageDescriptionCharacters: this.DestroyedVehicleDamageDescriptionCharacters,
                physicsSpace: targetObject.PhysicsBody.PhysicsSpace,
                executeExplosionCallback: this.ServerExecuteVehicleExplosion);

            // destroy the vehicle completely after short explosion delay
            ServerTimersSystem.AddAction(
                this.DestroyedExplosionPreset.ServerDamageApplyDelay,
                () => base.ServerOnDynamicObjectZeroStructurePoints(weaponCache,
                                                                    byCharacter,
                                                                    targetObject));
        }
Esempio n. 4
0
        private void ServerExplodeAt(WeaponFinalCache weaponCache, Vector2D endPosition, bool isHit)
        {
            var character   = weaponCache.Character;
            var protoWeapon = (IProtoItemWeaponRanged)weaponCache.ProtoWeapon;

            var shotSourcePosition = WeaponSystemClientDisplay.SharedCalculateWeaponShotWorldPositon(
                character,
                protoWeapon,
                character.ProtoCharacter,
                character.Position,
                hasTrace: true);

            if (isHit)
            {
                // offset end position a bit towards the source position
                // this way the explosion will definitely happen outside the hit object
                endPosition -= 0.1 * (endPosition - shotSourcePosition).Normalized;
            }

            var timeToHit = WeaponSystemClientDisplay.SharedCalculateTimeToHit(
                protoWeapon.FireTracePreset
                ?? this.FireTracePreset,
                shotSourcePosition,
                endPosition);

            // We're using a check here similar to the one in WeaponSystem.
            // Ensure that player can hit objects only on the same height level
            // and can fire through over the pits (the cliffs of the lower heights).
            var anyCliffIsAnObstacle = character.Tile.Height
                                       != Server.World.GetTile(endPosition.ToVector2Ushort()).Height;

            if (!WeaponSystem.SharedHasTileObstacle(
                    character.Position,
                    character.Tile.Height,
                    endPosition,
                    character.PhysicsBody.PhysicsSpace,
                    anyCliffIsAnObstacle: anyCliffIsAnObstacle))
            {
                ServerTimersSystem.AddAction(
                    timeToHit,
                    () =>
                {
                    ExplosionHelper.ServerExplode(
                        character: character,
                        protoExplosive: this,
                        protoWeapon: protoWeapon,
                        explosionPreset: this.ExplosionPreset,
                        epicenterPosition: endPosition,
                        damageDescriptionCharacters: this.DamageDescription,
                        physicsSpace: Server.World.GetPhysicsSpace(),
                        executeExplosionCallback: this.ServerExecuteExplosion);
                });
            }

            // notify other characters about the explosion
            using var charactersObserving = Api.Shared.GetTempList <ICharacter>();
            var explosionEventRadius = Math.Max(protoWeapon.SoundPresetWeaponDistance.max,
                                                this.FireRangeMax)
                                       + this.DamageRadius;

            Server.World.GetCharactersInRadius(endPosition.ToVector2Ushort(),
                                               charactersObserving,
                                               radius: (byte)Math.Min(byte.MaxValue, explosionEventRadius),
                                               onlyPlayers: true);

            charactersObserving.Remove(character);

            this.CallClient(charactersObserving.AsList(),
                            _ => _.ClientRemote_OnExplosion(protoWeapon,
                                                            shotSourcePosition,
                                                            endPosition));
        }