Ejemplo n.º 1
0
        private void ClientRemote_OnExplosion(
            Vector2D explosionWorldPosition)
        {
            var protoBomb = ProtoObjectBomb;

            SharedExplosionHelper.ClientExplode(explosionWorldPosition,
                                                protoBomb.ExplosionPreset,
                                                protoBomb.VolumeExplosion);
        }
Ejemplo n.º 2
0
        protected virtual void ClientExplodeAt(
            IProtoItemWeapon protoWeapon,
            Vector2D shotSourcePosition,
            Vector2D explosionWorldPosition)
        {
            var timeToHit = WeaponSystemClientDisplay.SharedCalculateTimeToHit(protoWeapon.FireTracePreset
                                                                               ?? this.FireTracePreset,
                                                                               shotSourcePosition,
                                                                               explosionWorldPosition);

            ClientTimersSystem.AddAction(timeToHit,
                                         () => SharedExplosionHelper.ClientExplode(explosionWorldPosition,
                                                                                   this.ExplosionPreset,
                                                                                   this.VolumeExplosion));
        }
Ejemplo n.º 3
0
        protected override void ClientExplodeAt(
            IProtoItemWeapon protoWeapon,
            Vector2D shotSourcePosition,
            Vector2D explosionWorldPosition)
        {
            var timeToHit = WeaponSystemClientDisplay.SharedCalculateTimeToHit(protoWeapon.FireTracePreset
                                                                               ?? this.FireTracePreset,
                                                                               shotSourcePosition,
                                                                               explosionWorldPosition);

            ClientTimersSystem.AddAction(
                timeToHit,
                () =>
            {
                SharedExplosionHelper.ClientExplode(explosionWorldPosition,
                                                    this.ExplosionPreset,
                                                    this.VolumeExplosion);

                // add more explosions in the X pattern as it's a fragmentation grenade
                ClientTimersSystem.AddAction(
                    0.2,
                    () =>
                {
                    SharedExplosionHelper.ClientExplode(explosionWorldPosition + (1, 1),
                                                        this.ExplosionPreset,
                                                        volume: 0);

                    SharedExplosionHelper.ClientExplode(explosionWorldPosition + (1, -1),
                                                        this.ExplosionPreset,
                                                        volume: 0);

                    SharedExplosionHelper.ClientExplode(explosionWorldPosition + (-1, 1),
                                                        this.ExplosionPreset,
                                                        volume: 0);

                    SharedExplosionHelper.ClientExplode(explosionWorldPosition + (-1, -1),
                                                        this.ExplosionPreset,
                                                        volume: 0);
                });
Ejemplo 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,
                    () =>
                {
                    SharedExplosionHelper.ServerExplode(
                        character: character,
                        protoExplosive: this,
                        protoWeapon: protoWeapon,
                        explosionPreset: this.ExplosionPreset,
                        epicenterPosition: endPosition,
                        damageDescriptionCharacters: this.OverrideDamageDescription,
                        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.OverrideDamageDescription.RangeMax)
                                       + 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));
        }
Ejemplo n.º 5
0
        private void ServerExplode(IItem item)
        {
            Server.Items.DestroyItem(item);

            // explode a primitive bomb in player position
            var character = item.Container.OwnerAsCharacter;

            if (character is null)
            {
                return;
            }

            var characterPublicState = character.GetPublicState <PlayerCharacterPublicState>();

            if (!characterPublicState.IsDead)
            {
                // ensure the wearer is killed by the explosion
                characterPublicState.CurrentStats.ServerSetHealthCurrent(0);
            }

            var targetPosition = character.Position;

            var protoBomb = ProtoObjectBomb;

            SharedExplosionHelper.ServerExplode(
                character: character,
                protoExplosive: protoBomb,
                protoWeapon: null,
                explosionPreset: protoBomb.ExplosionPreset,
                epicenterPosition: targetPosition,
                damageDescriptionCharacters: protoBomb.DamageDescriptionCharacters,
                physicsSpace: Server.World.GetPhysicsSpace(),
                executeExplosionCallback: protoBomb.ServerExecuteExplosion);

            // notify all characters about the explosion
            using var charactersObserving = Api.Shared.GetTempList <ICharacter>();
            const byte explosionEventRadius = 40;

            Server.World.GetCharactersInRadius(targetPosition.ToVector2Ushort(),
                                               charactersObserving,
                                               radius: explosionEventRadius,
                                               onlyPlayers: true);

            this.CallClient(charactersObserving.AsList(),
                            _ => _.ClientRemote_OnExplosion(targetPosition));

            // activate the raidblock if possible (the code is similar to ProtoObjectEplosive)
            var explosionRadius = (int)Math.Ceiling(protoBomb.DamageRadius);
            var bounds          = new RectangleInt(x: (int)Math.Round(character.Position.X - explosionRadius),
                                                   y: (int)Math.Round(character.Position.Y - explosionRadius),
                                                   width: 2 * explosionRadius,
                                                   height: 2 * explosionRadius);

            if (RaidingProtectionSystem.SharedCanRaid(bounds,
                                                      showClientNotification: false))
            {
                // try activate the raidblock
                LandClaimSystem.ServerOnRaid(bounds, character, isStructureDestroyed: false);
            }
            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 was not applied.
                if (LandClaimSystem.SharedIsLandClaimedByAnyone(bounds))
                {
                    using var tempPlayers = Api.Shared.GetTempList <ICharacter>();
                    Server.World.GetScopedByPlayers(character, tempPlayers);
                    RaidingProtectionSystem.ServerNotifyShowNotificationRaidingNotAvailableNow(
                        tempPlayers.AsList());
                }
            }
        }