예제 #1
0
        private void GenerateInputCommand(IConsoleShell shell, string argstr, string[] args)
        {
            var localPlayer = _playerManager.LocalPlayer;

            if (localPlayer is null)
            {
                return;
            }

            var pent = localPlayer.ControlledEntity;

            if (pent is null)
            {
                return;
            }

            BoundKeyFunction keyFunction = new BoundKeyFunction(args[0]);
            BoundKeyState    state       = args[1] == "u" ? BoundKeyState.Up: BoundKeyState.Down;

            var pxform = Transform(pent.Value);
            var wPos   = pxform.WorldPosition + new Vector2(float.Parse(args[2]), float.Parse(args[3]));
            var coords = EntityCoordinates.FromMap(EntityManager, pent.Value, new MapCoordinates(wPos, pxform.MapID));

            var funcId = _inputManager.NetworkBindMap.KeyFunctionID(keyFunction);

            var message = new FullInputCmdMessage(_timing.CurTick, _timing.TickFraction, funcId, state,
                                                  coords, new ScreenCoordinates(0, 0, default), EntityUid.Invalid);

            HandleInputCommand(localPlayer.Session, keyFunction, message);
        }
예제 #2
0
        private void OnKeyBindStateChanged(ViewportBoundKeyEventArgs args)
        {
            if (_baseClient.RunLevel != ClientRunLevel.InGame)
            {
                return;
            }

            if (!_entitySystemManager.TryGetEntitySystem <InputSystem>(out var inputSystem))
            {
                return;
            }

            var keyArgs       = args.KeyEventArgs;
            var inputFunction = _inputManager.NetworkBindMap.KeyFunctionID(keyArgs.Function);

            EntityCoordinates coords = EntityCoordinates.Invalid;
            EntityUid         entity = EntityUid.Invalid;

            if (args.Viewport is ScalingViewport viewport)
            {
                MapCoordinates mapCoords = viewport.ScreenToMap(keyArgs.PointerLocation.Position);

                entity = GetEntityUnderMouse(viewport, keyArgs.PointerLocation.Position, mapCoords);
                coords = _mapManager.TryFindGridAt(mapCoords, out var grid) ? grid.MapToGrid(mapCoords) :
                         EntityCoordinates.FromMap(_mapManager, mapCoords);
            }

            var message = new FullInputCmdMessage(_gameTiming.CurTick, _gameTiming.TickFraction, inputFunction, keyArgs.State, coords, keyArgs.PointerLocation, entity);

            if (inputSystem.HandleInputCommand(_playerManager.LocalPlayer.Session, keyArgs.Function, message))
            {
                keyArgs.Handle();
            }
        }
예제 #3
0
    private void OnPlaceDecalAction(PlaceDecalActionEvent args)
    {
        if (args.Handled)
        {
            return;
        }

        if (!_mapMan.TryFindGridAt(args.Target, out var grid))
        {
            return;
        }

        args.Handled = true;

        var coords = EntityCoordinates.FromMap(grid.GridEntityId, args.Target, EntityManager);

        if (args.Snap)
        {
            var newPos = new Vector2(
                (float)(MathF.Round(coords.X - 0.5f, MidpointRounding.AwayFromZero) + 0.5),
                (float)(MathF.Round(coords.Y - 0.5f, MidpointRounding.AwayFromZero) + 0.5)
                );
            coords = coords.WithPosition(newPos);
        }

        coords = coords.Offset(new Vector2(-0.5f, -0.5f));

        var decal = new Decal(coords.Position, args.DecalId, args.Color, Angle.FromDegrees(args.Rotation), args.ZIndex, args.Cleanable);

        RaiseNetworkEvent(new RequestDecalPlacementEvent(decal, coords));
    }
    public bool TryPickup(EntityUid uid, EntityUid entity, Hand hand, bool checkActionBlocker = true, bool animateUser = false, SharedHandsComponent?handsComp = null, ItemComponent?item = null)
    {
        if (!Resolve(uid, ref handsComp, false))
        {
            return(false);
        }

        if (!Resolve(entity, ref item, false))
        {
            return(false);
        }

        if (!CanPickupToHand(uid, entity, hand, checkActionBlocker, handsComp, item))
        {
            return(false);
        }

        // animation
        var xform            = Transform(uid);
        var coordinateEntity = xform.ParentUid.IsValid() ? xform.ParentUid : uid;
        var initialPosition  = EntityCoordinates.FromMap(EntityManager, coordinateEntity, Transform(entity).MapPosition);

        PickupAnimation(entity, initialPosition, xform.LocalPosition, animateUser ? null : uid);
        DoPickup(uid, hand, entity, handsComp);

        return(true);
    }
예제 #5
0
        protected EntityCoordinates ScreenToCursorGrid(ScreenCoordinates coords)
        {
            var mapCoords = pManager.eyeManager.ScreenToMap(coords.Position);

            if (!pManager.MapManager.TryFindGridAt(mapCoords, out var grid))
            {
                return(EntityCoordinates.FromMap(pManager.EntityManager, pManager.MapManager, mapCoords));
            }

            return(EntityCoordinates.FromMap(pManager.EntityManager, grid.GridEntityId, mapCoords));
        }
예제 #6
0
        protected override void HandlePickupAnimation(EntityUid entity)
        {
            var initialPosition = EntityCoordinates.FromMap(_entities.GetComponent<TransformComponent>(Owner).Parent?.Owner ?? Owner, _entities.GetComponent<TransformComponent>(entity).MapPosition);

            var finalPosition = _entities.GetComponent<TransformComponent>(Owner).LocalPosition;

            if (finalPosition.EqualsApprox(initialPosition.Position))
                return;

            _entities.EntityNetManager!.SendSystemNetworkMessage(
                new PickupAnimationMessage(entity, finalPosition, initialPosition));
        }
예제 #7
0
    /// <summary>
    ///     This function actually spawns the explosion. It returns an <see cref="Explosion"/> instance with
    ///     information about the affected tiles for the explosion system to process. It will also trigger the
    ///     camera shake and sound effect.
    /// </summary>
    private Explosion?SpawnExplosion(MapCoordinates epicenter,
                                     ExplosionPrototype type,
                                     float totalIntensity,
                                     float slope,
                                     float maxTileIntensity,
                                     float tileBreakScale,
                                     int maxTileBreak,
                                     bool canCreateVacuum)
    {
        if (!_mapManager.MapExists(epicenter.MapId))
        {
            return(null);
        }

        var results = GetExplosionTiles(epicenter, type.ID, totalIntensity, slope, maxTileIntensity);

        if (results == null)
        {
            return(null);
        }

        var(area, iterationIntensity, spaceData, gridData, spaceMatrix) = results.Value;

        RaiseNetworkEvent(GetExplosionEvent(epicenter, type.ID, spaceMatrix, spaceData, gridData.Values, iterationIntensity));

        // camera shake
        CameraShake(iterationIntensity.Count * 2.5f, epicenter, totalIntensity);

        //For whatever bloody reason, sound system requires ENTITY coordinates.
        var mapEntityCoords = EntityCoordinates.FromMap(EntityManager, _mapManager.GetMapEntityId(epicenter.MapId), epicenter);

        // play sound.
        var audioRange = iterationIntensity.Count * 5;
        var filter     = Filter.Pvs(epicenter).AddInRange(epicenter, audioRange);

        SoundSystem.Play(type.Sound.GetSound(), filter, mapEntityCoords, _audioParams);

        return(new Explosion(this,
                             type,
                             spaceData,
                             gridData.Values.ToList(),
                             iterationIntensity,
                             epicenter,
                             spaceMatrix,
                             area,
                             tileBreakScale,
                             maxTileBreak,
                             canCreateVacuum,
                             EntityManager,
                             _mapManager));
    }
        protected override void HandlePickupAnimation(IEntity entity)
        {
            var initialPosition = EntityCoordinates.FromMap(Owner.Transform.Parent?.Owner ?? Owner, entity.Transform.MapPosition);

            var finalPosition = Owner.Transform.LocalPosition;

            if (finalPosition.EqualsApprox(initialPosition.Position))
            {
                return;
            }

            Owner.EntityManager.EntityNetManager !.SendSystemNetworkMessage(
                new PickupAnimationMessage(entity.Uid, finalPosition, initialPosition));
        }
예제 #9
0
        public bool OnButtonPressed(GUIBoundKeyEventArgs args, IEntity?item)
        {
            if (item == null)
            {
                return(false);
            }

            if (args.Function == ContentKeyFunctions.ExamineEntity)
            {
                _entitySystemManager.GetEntitySystem <ExamineSystem>()
                .DoExamine(item);
            }
            else if (args.Function == ContentKeyFunctions.OpenContextMenu)
            {
                _entitySystemManager.GetEntitySystem <VerbSystem>()
                .OpenContextMenu(item, _uiMgr.ScreenToUIPosition(args.PointerLocation));
            }
            else if (args.Function == ContentKeyFunctions.ActivateItemInWorld)
            {
                var inputSys = _entitySystemManager.GetEntitySystem <InputSystem>();

                var func   = args.Function;
                var funcId = _inputManager.NetworkBindMap.KeyFunctionID(args.Function);


                var mousePosWorld = _eyeManager.ScreenToMap(args.PointerLocation);

                var coordinates = _mapManager.TryFindGridAt(mousePosWorld, out var grid) ? grid.MapToGrid(mousePosWorld) :
                                  EntityCoordinates.FromMap(_mapManager, mousePosWorld);

                var message = new FullInputCmdMessage(_gameTiming.CurTick, _gameTiming.TickFraction, funcId, BoundKeyState.Down,
                                                      coordinates, args.PointerLocation, item.Uid);

                // client side command handlers will always be sent the local player session.
                var session = _playerManager.LocalPlayer?.Session;
                if (session == null)
                {
                    return(false);
                }

                inputSys.HandleInputCommand(session, func, message);
            }
            else
            {
                return(false);
            }
            args.Handle();
            return(true);
        }
        private void SingularityQuery()
        {
            var currentEyeLoc = _eyeManager.CurrentEye.Position;

            var singuloComponents = _componentManager.EntityQuery <IClientSingularityInstance>();

            foreach (var singuloInterface in singuloComponents)
            {
                var singuloComponent = (Component)singuloInterface;
                var singuloEntity    = singuloComponent.Owner;
                if (!_singularities.Keys.Contains(singuloEntity.Uid) && singuloEntity.Transform.Coordinates.InRange(_entityManager, EntityCoordinates.FromMap(_entityManager, singuloEntity.Transform.ParentUid, currentEyeLoc), _maxDist))
                {
                    _singularities.Add(singuloEntity.Uid, new SingularityShaderInstance(singuloEntity.Transform.MapPosition.Position, singuloInterface.Level));
                }
            }

            var activeShaderUids = _singularities.Keys;

            foreach (var activeSinguloUid in activeShaderUids)
            {
                if (_entityManager.TryGetEntity(activeSinguloUid, out IEntity? singuloEntity))
                {
                    if (!singuloEntity.Transform.Coordinates.InRange(_entityManager, EntityCoordinates.FromMap(_entityManager, singuloEntity.Transform.ParentUid, currentEyeLoc), _maxDist))
                    {
                        _singularities.Remove(activeSinguloUid);
                    }
                    else
                    {
                        if (!singuloEntity.TryGetComponent <IClientSingularityInstance>(out var singuloInterface))
                        {
                            _singularities.Remove(activeSinguloUid);
                        }
                        else
                        {
                            var shaderInstance = _singularities[activeSinguloUid];
                            shaderInstance.CurrentMapCoords = singuloEntity.Transform.MapPosition.Position;
                            shaderInstance.Level            = singuloInterface.Level;
                        }
                    }
                }
                else
                {
                    _singularities.Remove(activeSinguloUid);
                }
            }
        }
예제 #11
0
        private bool HandleDrop(ICommonSession?session, EntityCoordinates coords, EntityUid uid)
        {
            var ent = ((IPlayerSession?)session)?.AttachedEntity;

            if (ent == null || !ent.IsValid())
            {
                return(false);
            }

            if (!ent.TryGetComponent(out HandsComponent? handsComp))
            {
                return(false);
            }

            if (handsComp.ActiveHand == null || handsComp.GetActiveHand == null)
            {
                return(false);
            }

            // It's important to note that the calculations are done in map coordinates (they're absolute).
            // They're translated back to EntityCoordinates at the end.
            var entMap       = ent.Transform.MapPosition;
            var targetPos    = coords.ToMapPos(EntityManager);
            var dropVector   = targetPos - entMap.Position;
            var targetVector = Vector2.Zero;

            if (dropVector != Vector2.Zero)
            {
                var targetLength = MathF.Min(dropVector.Length, SharedInteractionSystem.InteractionRange - 0.001f); // InteractionRange is reduced due to InRange not dealing with floating point error
                var newCoords    = new MapCoordinates(dropVector.Normalized * targetLength + entMap.Position, entMap.MapId);
                var rayLength    = Get <SharedInteractionSystem>().UnobstructedDistance(entMap, newCoords, ignoredEnt: ent);
                targetVector = dropVector.Normalized * rayLength;
            }

            var resultMapCoordinates = new MapCoordinates(entMap.Position + targetVector, entMap.MapId);
            var resultEntCoordinates = EntityCoordinates.FromMap(coords.GetParent(EntityManager), resultMapCoordinates);

            handsComp.Drop(handsComp.ActiveHand, resultEntCoordinates);

            return(true);
        }
예제 #12
0
        /// <summary>
        /// Allows a user to pick up entities by clicking them, or pick up all entities in a certain radius
        /// around a click.
        /// </summary>
        /// <returns></returns>
        private async void AfterInteract(EntityUid uid, ServerStorageComponent storageComp, AfterInteractEvent eventArgs)
        {
            if (!eventArgs.CanReach)
            {
                return;
            }

            if (storageComp.CancelToken != null)
            {
                storageComp.CancelToken.Cancel();
                storageComp.CancelToken = null;
                return;
            }

            // Pick up all entities in a radius around the clicked location.
            // The last half of the if is because carpets exist and this is terrible
            if (storageComp.AreaInsert && (eventArgs.Target == null || !HasComp <ItemComponent>(eventArgs.Target.Value)))
            {
                var validStorables = new List <EntityUid>();
                foreach (var entity in _entityLookupSystem.GetEntitiesInRange(eventArgs.ClickLocation, storageComp.AreaInsertRadius, LookupFlags.None))
                {
                    if (entity == eventArgs.User ||
                        !HasComp <ItemComponent>(entity) ||
                        !_interactionSystem.InRangeUnobstructed(eventArgs.User, entity))
                    {
                        continue;
                    }

                    validStorables.Add(entity);
                }

                //If there's only one then let's be generous
                if (validStorables.Count > 1)
                {
                    storageComp.CancelToken = new CancellationTokenSource();
                    var doAfterArgs = new DoAfterEventArgs(eventArgs.User, 0.2f * validStorables.Count, storageComp.CancelToken.Token, uid)
                    {
                        BreakOnStun     = true,
                        BreakOnDamage   = true,
                        BreakOnUserMove = true,
                        NeedHand        = true,
                    };

                    await _doAfterSystem.WaitDoAfter(doAfterArgs);
                }

                // TODO: Make it use the event DoAfter
                var successfullyInserted          = new List <EntityUid>();
                var successfullyInsertedPositions = new List <EntityCoordinates>();
                foreach (var entity in validStorables)
                {
                    // Check again, situation may have changed for some entities, but we'll still pick up any that are valid
                    if (_containerSystem.IsEntityInContainer(entity) ||
                        entity == eventArgs.User ||
                        !HasComp <ItemComponent>(entity))
                    {
                        continue;
                    }

                    if (TryComp <TransformComponent>(uid, out var transformOwner) && TryComp <TransformComponent>(entity, out var transformEnt))
                    {
                        var position = EntityCoordinates.FromMap(transformOwner.Parent?.Owner ?? uid, transformEnt.MapPosition);

                        if (PlayerInsertEntityInWorld(uid, eventArgs.User, entity, storageComp))
                        {
                            successfullyInserted.Add(entity);
                            successfullyInsertedPositions.Add(position);
                        }
                    }
                }

                // If we picked up atleast one thing, play a sound and do a cool animation!
                if (successfullyInserted.Count > 0)
                {
                    if (storageComp.StorageInsertSound is not null)
                    {
                        SoundSystem.Play(storageComp.StorageInsertSound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, AudioParams.Default);
                    }
                    RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(uid, successfullyInserted, successfullyInsertedPositions));
                }
                return;
            }
            // Pick up the clicked entity
            else if (storageComp.QuickInsert)
            {
                if (eventArgs.Target is not {
                    Valid : true
                } target)
                {
                    return;
                }

                if (_containerSystem.IsEntityInContainer(target) ||
                    target == eventArgs.User ||
                    !HasComp <ItemComponent>(target))
                {
                    return;
                }

                if (TryComp <TransformComponent>(uid, out var transformOwner) && TryComp <TransformComponent>(target, out var transformEnt))
                {
                    var parent = transformOwner.ParentUid;

                    var position = EntityCoordinates.FromMap(
                        parent.IsValid() ? parent : uid,
                        transformEnt.MapPosition);
                    if (PlayerInsertEntityInWorld(uid, eventArgs.User, target, storageComp))
                    {
                        RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(uid,
                                                                            new List <EntityUid> {
                            target
                        },
                                                                            new List <EntityCoordinates> {
                            position
                        }));
                    }
                }
            }
            return;
        }
    // All smite verbs have names so invokeverb works.
    private void AddSmiteVerbs(GetVerbsEvent <Verb> args)
    {
        if (!EntityManager.TryGetComponent <ActorComponent?>(args.User, out var actor))
        {
            return;
        }

        var player = actor.PlayerSession;

        if (!_adminManager.HasAdminFlag(player, AdminFlags.Fun))
        {
            return;
        }

        Verb explode = new()
        {
            Text        = "Explode",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/VerbIcons/smite.svg.192dpi.png",
            Act         = () =>
            {
                var coords = Transform(args.Target).MapPosition;
                Timer.Spawn(_gameTiming.TickPeriod,
                            () => _explosionSystem.QueueExplosion(coords, ExplosionSystem.DefaultExplosionPrototypeId,
                                                                  4, 1, 2, maxTileBreak: 0), // it gibs, damage doesn't need to be high.
                            CancellationToken.None);

                if (TryComp(args.Target, out SharedBodyComponent? body))
                {
                    body.Gib();
                }
            },
            Impact  = LogImpact.Extreme,
            Message = "Explode them.",
        };

        args.Verbs.Add(explode);

        Verb chess = new()
        {
            Text        = "Chess Dimension",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Fun/Tabletop/chessboard.rsi/chessboard.png",
            Act         = () =>
            {
                _godmodeSystem.EnableGodmode(args.Target); // So they don't suffocate.
                EnsureComp <TabletopDraggableComponent>(args.Target);
                RemComp <PhysicsComponent>(args.Target);   // So they can be dragged around.
                var xform = Transform(args.Target);
                _popupSystem.PopupEntity(Loc.GetString("admin-smite-chess-self"), args.Target, Filter.Entities(args.Target));
                _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-chess-others", ("name", args.Target)), xform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target));
                var board   = Spawn("ChessBoard", xform.Coordinates);
                var session = _tabletopSystem.EnsureSession(Comp <TabletopGameComponent>(board));
                xform.Coordinates   = EntityCoordinates.FromMap(_mapManager, session.Position);
                xform.WorldRotation = Angle.Zero;
            },
            Impact  = LogImpact.Extreme,
            Message = "Banishment to the Chess Dimension.",
        };

        args.Verbs.Add(chess);

        if (TryComp <FlammableComponent>(args.Target, out var flammable))
        {
            Verb flames = new()
            {
                Text        = "Set Alight",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/Alerts/Fire/fire.png",
                Act         = () =>
                {
                    // F**k you. Burn Forever.
                    flammable.FireStacks = 99999.9f;
                    _flammableSystem.Ignite(args.Target);
                    var xform = Transform(args.Target);
                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-set-alight-self"), args.Target, Filter.Entities(args.Target));
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-set-alight-others", ("name", args.Target)), xform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target));
                },
                Impact  = LogImpact.Extreme,
                Message = "Makes them burn.",
            };
            args.Verbs.Add(flames);
        }

        Verb monkey = new()
        {
            Text        = "Monkeyify",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Mobs/Animals/monkey.rsi/dead.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminMonkeySmite");
            },
            Impact  = LogImpact.Extreme,
            Message = "Monkey mode.",
        };

        args.Verbs.Add(monkey);

        if (TryComp <DiseaseCarrierComponent>(args.Target, out var carrier))
        {
            Verb lungCancer = new()
            {
                Text        = "Lung Cancer",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Mobs/Species/Human/organs.rsi/lung-l.png",
                Act         = () =>
                {
                    _diseaseSystem.TryInfect(carrier, _prototypeManager.Index <DiseasePrototype>("StageIIIALungCancer"),
                                             1.0f, true);
                },
                Impact  = LogImpact.Extreme,
                Message = "Stage IIIA Lung Cancer, for when they really like the hit show Breaking Bad.",
            };
            args.Verbs.Add(lungCancer);
        }

        if (TryComp <DamageableComponent>(args.Target, out var damageable) &&
            TryComp <MobStateComponent>(args.Target, out var mobState))
        {
            Verb hardElectrocute = new()
            {
                Text        = "Electrocute",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/icon.png",
                Act         = () =>
                {
                    int damageToDeal;
                    var critState = mobState._highestToLowestStates.Where(x => x.Value.IsCritical()).FirstOrNull();
                    if (critState is null)
                    {
                        // We can't crit them so try killing them.
                        var deadState = mobState._highestToLowestStates.Where(x => x.Value.IsDead()).FirstOrNull();
                        if (deadState is null)
                        {
                            return; // whelp.
                        }
                        damageToDeal = deadState.Value.Key - (int)damageable.TotalDamage;
                    }
                    else
                    {
                        damageToDeal = critState.Value.Key - (int)damageable.TotalDamage;
                    }

                    if (damageToDeal <= 0)
                    {
                        damageToDeal = 100; // murder time.
                    }
                    if (_inventorySystem.TryGetSlots(args.Target, out var slotDefinitions))
                    {
                        foreach (var slot in slotDefinitions)
                        {
                            if (!_inventorySystem.TryGetSlotEntity(args.Target, slot.Name, out var slotEnt))
                            {
                                continue;
                            }

                            RemComp <InsulatedComponent>(slotEnt.Value); // Fry the gloves.
                        }
                    }

                    _electrocutionSystem.TryDoElectrocution(args.Target, null, damageToDeal,
                                                            TimeSpan.FromSeconds(30), true);
                },
                Impact  = LogImpact.Extreme,
                Message = "Electrocutes them, rendering anything they were wearing useless.",
            };
            args.Verbs.Add(hardElectrocute);
        }

        if (TryComp <CreamPiedComponent>(args.Target, out var creamPied))
        {
            Verb creamPie = new()
            {
                Text        = "Creampie",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Objects/Consumable/Food/Baked/pie.rsi/plain-slice.png",
                Act         = () =>
                {
                    _creamPieSystem.SetCreamPied(args.Target, creamPied, true);
                },
                Impact  = LogImpact.Extreme,
                Message = "A cream pie, condensed into a button.",
            };
            args.Verbs.Add(creamPie);
        }

        if (TryComp <BloodstreamComponent>(args.Target, out var bloodstream))
        {
            Verb bloodRemoval = new()
            {
                Text        = "Remove blood",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Fluids/tomato_splat.rsi/puddle-1.png",
                Act         = () =>
                {
                    _bloodstreamSystem.SpillAllSolutions(args.Target, bloodstream);
                    var xform = Transform(args.Target);
                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-blood-self"), args.Target, Filter.Entities(args.Target));
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-blood-others", ("name", args.Target)), xform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target));
                },
                Impact  = LogImpact.Extreme,
                Message = "Removes their blood. All of it.",
            };
            args.Verbs.Add(bloodRemoval);
        }

        // bobby...
        if (TryComp <BodyComponent>(args.Target, out var body))
        {
            Verb vomitOrgans = new()
            {
                Text        = "Vomit organs",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Fluids/vomit_toxin.rsi/vomit_toxin-1.png",
                Act         = () =>
                {
                    _vomitSystem.Vomit(args.Target, -1000, -1000); // You feel hollow!
                    var organs    = _bodySystem.GetComponentsOnMechanisms <TransformComponent>(args.Target, body);
                    var baseXform = Transform(args.Target);
                    foreach (var(xform, mechanism) in organs)
                    {
                        if (HasComp <BrainComponent>(xform.Owner) || HasComp <EyeComponent>(xform.Owner))
                        {
                            continue;
                        }

                        mechanism.Part?.RemoveMechanism(mechanism);
                        xform.Coordinates = baseXform.Coordinates.Offset(_random.NextVector2(0.5f, 0.75f));
                    }

                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-vomit-organs-self"), args.Target, Filter.Entities(args.Target));
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-vomit-organs-others", ("name", args.Target)), baseXform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target));
                },
                Impact  = LogImpact.Extreme,
                Message = "Causes them to vomit, including their internal organs.",
            };
            args.Verbs.Add(vomitOrgans);

            Verb handRemoval = new()
            {
                Text        = "Remove hands",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/fist.svg.192dpi.png",
                Act         = () =>
                {
                    var baseXform = Transform(args.Target);
                    foreach (var part in body.GetPartsOfType(BodyPartType.Hand))
                    {
                        body.RemovePart(part);
                        Transform(part.Owner).Coordinates = baseXform.Coordinates;
                    }
                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-hands-self"), args.Target, Filter.Entities(args.Target));
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-hands-others", ("name", args.Target)), baseXform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target));
                },
                Impact  = LogImpact.Extreme,
                Message = "Removes the target's hands.",
            };
            args.Verbs.Add(handRemoval);
        }

        if (TryComp <PhysicsComponent>(args.Target, out var physics))
        {
            Verb pinball = new()
            {
                Text        = "Pinball",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Objects/Fun/toys.rsi/basketball.png",
                Act         = () =>
                {
                    var xform    = Transform(args.Target);
                    var fixtures = Comp <FixturesComponent>(args.Target);
                    xform.Anchored     = false; // Just in case.
                    physics.BodyType   = BodyType.Dynamic;
                    physics.BodyStatus = BodyStatus.InAir;
                    physics.WakeBody();
                    foreach (var(_, fixture) in fixtures.Fixtures)
                    {
                        if (!fixture.Hard)
                        {
                            continue;
                        }
                        fixture.Restitution = 1.1f;
                    }

                    physics.LinearVelocity  = _random.NextVector2(1.5f, 1.5f);
                    physics.AngularVelocity = MathF.PI * 12;
                    physics.LinearDamping   = 0.0f;
                    physics.AngularDamping  = 0.0f;
                },
                Impact  = LogImpact.Extreme,
                Message =
                    "Turns them into a super bouncy ball, flinging them around until they clip through the station into the abyss.",
            };
            args.Verbs.Add(pinball);

            Verb yeet = new()
            {
                Text        = "Yeet",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/VerbIcons/eject.svg.192dpi.png",
                Act         = () =>
                {
                    var xform    = Transform(args.Target);
                    var fixtures = Comp <FixturesComponent>(args.Target);
                    xform.Anchored     = false; // Just in case.
                    physics.BodyType   = BodyType.Dynamic;
                    physics.BodyStatus = BodyStatus.InAir;
                    physics.WakeBody();
                    foreach (var(_, fixture) in fixtures.Fixtures)
                    {
                        fixture.Hard = false;
                    }

                    physics.LinearVelocity  = _random.NextVector2(8.0f, 8.0f);
                    physics.AngularVelocity = MathF.PI * 12;
                    physics.LinearDamping   = 0.0f;
                    physics.AngularDamping  = 0.0f;
                },
                Impact  = LogImpact.Extreme,
                Message = "Banishes them into the depths of space by turning on no-clip and tossing them.",
            };
            args.Verbs.Add(yeet);
        }

        Verb bread = new()
        {
            Text        = "Become Bread",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Consumable/Food/Baked/bread.rsi/plain.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminBreadSmite");
            },
            Impact  = LogImpact.Extreme,
            Message = "It turns them into bread. Really. That's all it does.",
        };

        args.Verbs.Add(bread);

        if (TryComp <ActorComponent>(args.Target, out var actorComponent))
        {
            Verb ghostKick = new()
            {
                Text        = "Ghostkick",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/gavel.svg.192dpi.png",
                Act         = () =>
                {
                    _ghostKickManager.DoDisconnect(actorComponent.PlayerSession.ConnectedClient, "Smitten.");
                },
                Impact  = LogImpact.Extreme,
                Message = "Silently kicks the user, dropping their connection.",
            };
            args.Verbs.Add(ghostKick);
        }

        if (TryComp <InventoryComponent>(args.Target, out var inventory))
        {
            Verb nyanify = new()
            {
                Text        = "Nyanify",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Clothing/Head/Hats/catears.rsi/icon.png",
                Act         = () =>
                {
                    var ears = Spawn("ClothingHeadHatCatEars", Transform(args.Target).Coordinates);
                    EnsureComp <UnremoveableComponent>(ears);
                    _inventorySystem.TryUnequip(args.Target, "head", true, true, false, inventory);
                    _inventorySystem.TryEquip(args.Target, ears, "head", true, true, false, inventory);
                },
                Impact  = LogImpact.Extreme,
                Message = "Forcibly adds cat ears. There is no escape.",
            };
            args.Verbs.Add(nyanify);

            Verb killSign = new()
            {
                Text        = "Kill sign",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Objects/Misc/killsign.rsi/icon.png",
                Act         = () =>
                {
                    EnsureComp <KillSignComponent>(args.Target);
                },
                Impact  = LogImpact.Extreme,
                Message = "Marks a player for death by their fellows.",
            };
            args.Verbs.Add(killSign);

            // TODO: Port cluwne outfit.
            Verb clown = new()
            {
                Text        = "Clown",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Objects/Fun/bikehorn.rsi/icon.png",
                Act         = () =>
                {
                    SetOutfitCommand.SetOutfit(args.Target, "ClownGear", EntityManager, (_, clothing) =>
                    {
                        if (HasComp <ClothingComponent>(clothing))
                        {
                            EnsureComp <UnremoveableComponent>(clothing);
                        }
                        EnsureComp <ClumsyComponent>(args.Target);
                    });
                },
                Impact  = LogImpact.Extreme,
                Message = "Clowns them. The suit cannot be removed.",
            };
            args.Verbs.Add(clown);
        }

        Verb angerPointingArrows = new()
        {
            Text        = "Anger Pointing Arrows",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/Misc/pointing.rsi/pointing.png",
            Act         = () =>
            {
                EnsureComp <PointingArrowAngeringComponent>(args.Target);
            },
            Impact  = LogImpact.Extreme,
            Message = "Angers the pointing arrows, causing them to assault this entity.",
        };

        args.Verbs.Add(angerPointingArrows);

        Verb dust = new()
        {
            Text        = "Dust",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Materials/materials.rsi/ash.png",
            Act         = () =>
            {
                EntityManager.QueueDeleteEntity(args.Target);
                Spawn("Ash", Transform(args.Target).Coordinates);
                _popupSystem.PopupEntity(Loc.GetString("admin-smite-turned-ash-other", ("name", args.Target)), args.Target, Filter.Pvs(args.Target));
            },
            Impact  = LogImpact.Extreme,
            Message = "Reduces the target to a small pile of ash.",
        };

        args.Verbs.Add(dust);

        Verb youtubeVideoSimulation = new()
        {
            Text        = "Buffering",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/Misc/buffering_smite_icon.png",
            Act         = () =>
            {
                EnsureComp <BufferingComponent>(args.Target);
            },
            Impact  = LogImpact.Extreme,
            Message = "Causes the target to randomly start buffering, freezing them in place for a short timespan while they load.",
        };

        args.Verbs.Add(youtubeVideoSimulation);

        Verb instrumentation = new()
        {
            Text        = "Become Instrument",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Fun/Instruments/h_synthesizer.rsi/icon.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminInstrumentSmite");
            },
            Impact  = LogImpact.Extreme,
            Message = "It turns them into a supersynth. Really. That's all it does.",
        };

        args.Verbs.Add(instrumentation);

        Verb noGravity = new()
        {
            Text        = "Remove gravity",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Structures/Machines/gravity_generator.rsi/off.png",
            Act         = () =>
            {
                var grav = EnsureComp <MovementIgnoreGravityComponent>(args.Target);
                grav.Weightless = true;
            },
            Impact  = LogImpact.Extreme,
            Message = "Grants them anti-gravity.",
        };

        args.Verbs.Add(noGravity);
    }
예제 #14
0
    // All smite verbs have names so invokeverb works.
    private void AddSmiteVerbs(GetVerbsEvent <Verb> args)
    {
        if (!EntityManager.TryGetComponent <ActorComponent?>(args.User, out var actor))
        {
            return;
        }

        var player = actor.PlayerSession;

        if (!_adminManager.HasAdminFlag(player, AdminFlags.Fun))
        {
            return;
        }

        // 1984.
        if (HasComp <IMapComponent>(args.Target) || HasComp <IMapGridComponent>(args.Target))
        {
            return;
        }

        Verb explode = new()
        {
            Text        = "Explode",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/VerbIcons/smite.svg.192dpi.png",
            Act         = () =>
            {
                var coords = Transform(args.Target).MapPosition;
                Timer.Spawn(_gameTiming.TickPeriod,
                            () => _explosionSystem.QueueExplosion(coords, ExplosionSystem.DefaultExplosionPrototypeId,
                                                                  4, 1, 2, maxTileBreak: 0), // it gibs, damage doesn't need to be high.
                            CancellationToken.None);

                if (TryComp(args.Target, out SharedBodyComponent? body))
                {
                    body.Gib();
                }
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-explode-description")
        };

        args.Verbs.Add(explode);

        Verb chess = new()
        {
            Text        = "Chess Dimension",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Fun/Tabletop/chessboard.rsi/chessboard.png",
            Act         = () =>
            {
                _godmodeSystem.EnableGodmode(args.Target); // So they don't suffocate.
                EnsureComp <TabletopDraggableComponent>(args.Target);
                RemComp <PhysicsComponent>(args.Target);   // So they can be dragged around.
                var xform = Transform(args.Target);
                _popupSystem.PopupEntity(Loc.GetString("admin-smite-chess-self"), args.Target,
                                         Filter.Entities(args.Target), PopupType.LargeCaution);
                _popupSystem.PopupCoordinates(
                    Loc.GetString("admin-smite-chess-others", ("name", args.Target)), xform.Coordinates,
                    Filter.PvsExcept(args.Target), PopupType.MediumCaution);
                var board   = Spawn("ChessBoard", xform.Coordinates);
                var session = _tabletopSystem.EnsureSession(Comp <TabletopGameComponent>(board));
                xform.Coordinates   = EntityCoordinates.FromMap(_mapManager, session.Position);
                xform.WorldRotation = Angle.Zero;
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-chess-dimension-description")
        };

        args.Verbs.Add(chess);

        if (TryComp <FlammableComponent>(args.Target, out var flammable))
        {
            Verb flames = new()
            {
                Text        = "Set Alight",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/Alerts/Fire/fire.png",
                Act         = () =>
                {
                    // F**k you. Burn Forever.
                    flammable.FireStacks = 99999.9f;
                    _flammableSystem.Ignite(args.Target);
                    var xform = Transform(args.Target);
                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-set-alight-self"), args.Target,
                                             Filter.Entities(args.Target), PopupType.LargeCaution);
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-set-alight-others", ("name", args.Target)), xform.Coordinates,
                                                  Filter.PvsExcept(args.Target), PopupType.MediumCaution);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-set-alight-description")
            };
            args.Verbs.Add(flames);
        }

        Verb monkey = new()
        {
            Text        = "Monkeyify",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Mobs/Animals/monkey.rsi/dead.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminMonkeySmite");
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-monkeyify-description")
        };

        args.Verbs.Add(monkey);

        Verb disposalBin = new()
        {
            Text        = "Garbage Can",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Structures/Piping/disposal.rsi/disposal.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminDisposalsSmite");
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-garbage-can-description")
        };

        args.Verbs.Add(disposalBin);

        if (TryComp <DiseaseCarrierComponent>(args.Target, out var carrier))
        {
            Verb lungCancer = new()
            {
                Text        = "Lung Cancer",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Mobs/Species/Human/organs.rsi/lung-l.png",
                Act         = () =>
                {
                    _diseaseSystem.TryInfect(carrier, _prototypeManager.Index <DiseasePrototype>("StageIIIALungCancer"),
                                             1.0f, true);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-lung-cancer-description")
            };
            args.Verbs.Add(lungCancer);
        }

        if (TryComp <DamageableComponent>(args.Target, out var damageable) &&
            TryComp <MobStateComponent>(args.Target, out var mobState))
        {
            Verb hardElectrocute = new()
            {
                Text        = "Electrocute",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/icon.png",
                Act         = () =>
                {
                    int damageToDeal;
                    var critState = mobState._highestToLowestStates.Where(x => x.Value == DamageState.Critical).FirstOrNull();
                    if (critState is null)
                    {
                        // We can't crit them so try killing them.
                        var deadState = mobState._highestToLowestStates.Where(x => x.Value == DamageState.Dead).FirstOrNull();
                        if (deadState is null)
                        {
                            return; // whelp.
                        }
                        damageToDeal = deadState.Value.Key - (int)damageable.TotalDamage;
                    }
                    else
                    {
                        damageToDeal = critState.Value.Key - (int)damageable.TotalDamage;
                    }

                    if (damageToDeal <= 0)
                    {
                        damageToDeal = 100; // murder time.
                    }
                    if (_inventorySystem.TryGetSlots(args.Target, out var slotDefinitions))
                    {
                        foreach (var slot in slotDefinitions)
                        {
                            if (!_inventorySystem.TryGetSlotEntity(args.Target, slot.Name, out var slotEnt))
                            {
                                continue;
                            }

                            RemComp <InsulatedComponent>(slotEnt.Value); // Fry the gloves.
                        }
                    }

                    _electrocutionSystem.TryDoElectrocution(args.Target, null, damageToDeal,
                                                            TimeSpan.FromSeconds(30), true);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-electrocute-description")
            };
            args.Verbs.Add(hardElectrocute);
        }

        if (TryComp <CreamPiedComponent>(args.Target, out var creamPied))
        {
            Verb creamPie = new()
            {
                Text        = "Creampie",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Objects/Consumable/Food/Baked/pie.rsi/plain-slice.png",
                Act         = () =>
                {
                    _creamPieSystem.SetCreamPied(args.Target, creamPied, true);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-creampie-description")
            };
            args.Verbs.Add(creamPie);
        }

        if (TryComp <BloodstreamComponent>(args.Target, out var bloodstream))
        {
            Verb bloodRemoval = new()
            {
                Text        = "Remove blood",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Fluids/tomato_splat.rsi/puddle-1.png",
                Act         = () =>
                {
                    _bloodstreamSystem.SpillAllSolutions(args.Target, bloodstream);
                    var xform = Transform(args.Target);
                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-blood-self"), args.Target,
                                             Filter.Entities(args.Target), PopupType.LargeCaution);
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-blood-others", ("name", args.Target)), xform.Coordinates,
                                                  Filter.PvsExcept(args.Target), PopupType.MediumCaution);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-remove-blood-description")
            };
            args.Verbs.Add(bloodRemoval);
        }

        // bobby...
        if (TryComp <BodyComponent>(args.Target, out var body))
        {
            Verb vomitOrgans = new()
            {
                Text        = "Vomit organs",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Fluids/vomit_toxin.rsi/vomit_toxin-1.png",
                Act         = () =>
                {
                    _vomitSystem.Vomit(args.Target, -1000, -1000); // You feel hollow!
                    var organs    = _bodySystem.GetComponentsOnMechanisms <TransformComponent>(args.Target, body);
                    var baseXform = Transform(args.Target);
                    foreach (var(xform, mechanism) in organs)
                    {
                        if (HasComp <BrainComponent>(xform.Owner) || HasComp <EyeComponent>(xform.Owner))
                        {
                            continue;
                        }

                        mechanism.Part?.RemoveMechanism(mechanism);
                        xform.Coordinates = baseXform.Coordinates.Offset(_random.NextVector2(0.5f, 0.75f));
                    }

                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-vomit-organs-self"), args.Target,
                                             Filter.Entities(args.Target), PopupType.LargeCaution);
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-vomit-organs-others", ("name", args.Target)), baseXform.Coordinates,
                                                  Filter.PvsExcept(args.Target), PopupType.MediumCaution);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-vomit-organs-description")
            };
            args.Verbs.Add(vomitOrgans);

            Verb handsRemoval = new()
            {
                Text        = "Remove hands",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/AdminActions/remove-hands.png",
                Act         = () =>
                {
                    var baseXform = Transform(args.Target);
                    foreach (var part in body.GetPartsOfType(BodyPartType.Hand))
                    {
                        body.RemovePart(part);
                        Transform(part.Owner).Coordinates = baseXform.Coordinates;
                    }
                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-hands-self"), args.Target,
                                             Filter.Entities(args.Target), PopupType.LargeCaution);
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-hands-others", ("name", args.Target)), baseXform.Coordinates,
                                                  Filter.PvsExcept(args.Target), PopupType.Medium);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-remove-hands-description")
            };
            args.Verbs.Add(handsRemoval);

            Verb handRemoval = new()
            {
                Text        = "Remove hands",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/AdminActions/remove-hand.png",
                Act         = () =>
                {
                    var baseXform = Transform(args.Target);
                    foreach (var part in body.GetPartsOfType(BodyPartType.Hand))
                    {
                        body.RemovePart(part);
                        Transform(part.Owner).Coordinates = baseXform.Coordinates;
                        break;
                    }
                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-hands-self"), args.Target,
                                             Filter.Entities(args.Target), PopupType.LargeCaution);
                    _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-hands-others", ("name", args.Target)), baseXform.Coordinates,
                                                  Filter.PvsExcept(args.Target), PopupType.Medium);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-remove-hand-description")
            };
            args.Verbs.Add(handRemoval);

            Verb stomachRemoval = new()
            {
                Text        = "Stomach Removal",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Mobs/Species/Human/organs.rsi/stomach.png",
                Act         = () =>
                {
                    foreach (var part in body.Parts)
                    {
                        foreach (var mechanism in part.Key.Mechanisms)
                        {
                            if (HasComp <StomachComponent>(mechanism.Owner))
                            {
                                QueueDel(mechanism.Owner);
                            }
                        }
                    }

                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-stomach-removal-self"), args.Target,
                                             Filter.Entities(args.Target), PopupType.LargeCaution);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-stomach-removal-description"),
            };
            args.Verbs.Add(stomachRemoval);

            Verb lungRemoval = new()
            {
                Text        = "Lungs Removal",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Mobs/Species/Human/organs.rsi/lung-r.png",
                Act         = () =>
                {
                    foreach (var part in body.Parts)
                    {
                        foreach (var mechanism in part.Key.Mechanisms)
                        {
                            if (HasComp <LungComponent>(mechanism.Owner))
                            {
                                QueueDel(mechanism.Owner);
                            }
                        }
                    }

                    _popupSystem.PopupEntity(Loc.GetString("admin-smite-lung-removal-self"), args.Target,
                                             Filter.Entities(args.Target), PopupType.LargeCaution);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-lung-removal-description"),
            };
            args.Verbs.Add(lungRemoval);
        }

        if (TryComp <PhysicsComponent>(args.Target, out var physics))
        {
            Verb pinball = new()
            {
                Text        = "Pinball",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Objects/Fun/toys.rsi/basketball.png",
                Act         = () =>
                {
                    var xform    = Transform(args.Target);
                    var fixtures = Comp <FixturesComponent>(args.Target);
                    xform.Anchored     = false; // Just in case.
                    physics.BodyType   = BodyType.Dynamic;
                    physics.BodyStatus = BodyStatus.InAir;
                    physics.WakeBody();
                    foreach (var(_, fixture) in fixtures.Fixtures)
                    {
                        if (!fixture.Hard)
                        {
                            continue;
                        }
                        fixture.Restitution = 1.1f;
                    }

                    physics.LinearVelocity  = _random.NextVector2(1.5f, 1.5f);
                    physics.AngularVelocity = MathF.PI * 12;
                    physics.LinearDamping   = 0.0f;
                    physics.AngularDamping  = 0.0f;
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-pinball-description")
            };
            args.Verbs.Add(pinball);

            Verb yeet = new()
            {
                Text        = "Yeet",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/VerbIcons/eject.svg.192dpi.png",
                Act         = () =>
                {
                    var xform    = Transform(args.Target);
                    var fixtures = Comp <FixturesComponent>(args.Target);
                    xform.Anchored     = false; // Just in case.
                    physics.BodyType   = BodyType.Dynamic;
                    physics.BodyStatus = BodyStatus.InAir;
                    physics.WakeBody();
                    foreach (var(_, fixture) in fixtures.Fixtures)
                    {
                        fixture.Hard = false;
                    }

                    physics.LinearVelocity  = _random.NextVector2(8.0f, 8.0f);
                    physics.AngularVelocity = MathF.PI * 12;
                    physics.LinearDamping   = 0.0f;
                    physics.AngularDamping  = 0.0f;
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-yeet-description")
            };
            args.Verbs.Add(yeet);
        }

        Verb bread = new()
        {
            Text        = "Become Bread",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Consumable/Food/Baked/bread.rsi/plain.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminBreadSmite");
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-become-bread-description")
        };

        args.Verbs.Add(bread);

        Verb mouse = new()
        {
            Text        = "Become Mouse",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Mobs/Animals/mouse.rsi/icon-0.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminMouseSmite");
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-become-mouse-description")
        };

        args.Verbs.Add(mouse);

        if (TryComp <ActorComponent>(args.Target, out var actorComponent))
        {
            Verb ghostKick = new()
            {
                Text        = "Ghostkick",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Interface/gavel.svg.192dpi.png",
                Act         = () =>
                {
                    _ghostKickManager.DoDisconnect(actorComponent.PlayerSession.ConnectedClient, "Smitten.");
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-ghostkick-description")
            };
            args.Verbs.Add(ghostKick);
        }

        if (TryComp <InventoryComponent>(args.Target, out var inventory))
        {
            Verb nyanify = new()
            {
                Text        = "Nyanify",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Clothing/Head/Hats/catears.rsi/icon.png",
                Act         = () =>
                {
                    var ears = Spawn("ClothingHeadHatCatEars", Transform(args.Target).Coordinates);
                    EnsureComp <UnremoveableComponent>(ears);
                    _inventorySystem.TryUnequip(args.Target, "head", true, true, false, inventory);
                    _inventorySystem.TryEquip(args.Target, ears, "head", true, true, false, inventory);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-nyanify-description")
            };
            args.Verbs.Add(nyanify);

            Verb killSign = new()
            {
                Text        = "Kill sign",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Objects/Misc/killsign.rsi/icon.png",
                Act         = () =>
                {
                    EnsureComp <KillSignComponent>(args.Target);
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-kill-sign-description")
            };
            args.Verbs.Add(killSign);

            // TODO: Port cluwne outfit.
            Verb clown = new()
            {
                Text        = "Clown",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Objects/Fun/bikehorn.rsi/icon.png",
                Act         = () =>
                {
                    SetOutfitCommand.SetOutfit(args.Target, "ClownGear", EntityManager, (_, clothing) =>
                    {
                        if (HasComp <ClothingComponent>(clothing))
                        {
                            EnsureComp <UnremoveableComponent>(clothing);
                        }
                        EnsureComp <ClumsyComponent>(args.Target);
                    });
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-clown-description")
            };
            args.Verbs.Add(clown);

            Verb maiden = new()
            {
                Text        = "Maid",
                Category    = VerbCategory.Smite,
                IconTexture = "/Textures/Clothing/Uniforms/Jumpskirt/janimaid.rsi/icon.png",
                Act         = () =>
                {
                    SetOutfitCommand.SetOutfit(args.Target, "JanitorMaidGear", EntityManager, (_, clothing) =>
                    {
                        if (HasComp <ClothingComponent>(clothing))
                        {
                            EnsureComp <UnremoveableComponent>(clothing);
                        }
                        EnsureComp <ClumsyComponent>(args.Target);
                    });
                },
                Impact  = LogImpact.Extreme,
                Message = Loc.GetString("admin-smite-maid-description")
            };
            args.Verbs.Add(maiden);
        }

        Verb angerPointingArrows = new()
        {
            Text        = "Anger Pointing Arrows",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/Misc/pointing.rsi/pointing.png",
            Act         = () =>
            {
                EnsureComp <PointingArrowAngeringComponent>(args.Target);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-anger-pointing-arrows-description")
        };

        args.Verbs.Add(angerPointingArrows);

        Verb dust = new()
        {
            Text        = "Dust",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Materials/materials.rsi/ash.png",
            Act         = () =>
            {
                EntityManager.QueueDeleteEntity(args.Target);
                Spawn("Ash", Transform(args.Target).Coordinates);
                _popupSystem.PopupEntity(Loc.GetString("admin-smite-turned-ash-other", ("name", args.Target)), args.Target,
                                         Filter.Pvs(args.Target), PopupType.LargeCaution);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-dust-description"),
        };

        args.Verbs.Add(dust);

        Verb youtubeVideoSimulation = new()
        {
            Text        = "Buffering",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/Misc/buffering_smite_icon.png",
            Act         = () =>
            {
                EnsureComp <BufferingComponent>(args.Target);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-buffering-description"),
        };

        args.Verbs.Add(youtubeVideoSimulation);

        Verb instrumentation = new()
        {
            Text        = "Become Instrument",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Fun/Instruments/h_synthesizer.rsi/icon.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminInstrumentSmite");
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-become-instrument-description"),
        };

        args.Verbs.Add(instrumentation);

        Verb noGravity = new()
        {
            Text        = "Remove gravity",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Structures/Machines/gravity_generator.rsi/off.png",
            Act         = () =>
            {
                var grav = EnsureComp <MovementIgnoreGravityComponent>(args.Target);
                grav.Weightless = true;

                Dirty(grav);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-remove-gravity-description"),
        };

        args.Verbs.Add(noGravity);

        Verb reptilian = new()
        {
            Text        = "Reptilian Species Swap",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Objects/Fun/toys.rsi/plushie_lizard.png",
            Act         = () =>
            {
                _polymorphableSystem.PolymorphEntity(args.Target, "AdminLizardSmite");
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-reptilian-species-swap-description"),
        };

        args.Verbs.Add(reptilian);

        Verb locker = new()
        {
            Text        = "Locker stuff",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Structures/Storage/closet.rsi/generic.png",
            Act         = () =>
            {
                var xform  = Transform(args.Target);
                var locker = Spawn("ClosetMaintenance", xform.Coordinates);
                if (TryComp <EntityStorageComponent>(locker, out var storage))
                {
                    _entityStorageSystem.ToggleOpen(args.Target, locker, storage);
                    _entityStorageSystem.Insert(args.Target, locker, storage);
                    _entityStorageSystem.ToggleOpen(args.Target, locker, storage);
                }
                _weldableSystem.ForceWeldedState(locker, true);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-locker-stuff-description"),
        };

        args.Verbs.Add(locker);

        Verb headstand = new()
        {
            Text        = "Headstand",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/VerbIcons/refresh.svg.192dpi.png",
            Act         = () =>
            {
                EnsureComp <HeadstandComponent>(args.Target);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-headstand-description"),
        };

        args.Verbs.Add(headstand);

        Verb zoomIn = new()
        {
            Text        = "Zoom in",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/AdminActions/zoom.png",
            Act         = () =>
            {
                var eye = EnsureComp <EyeComponent>(args.Target);

                eye.Zoom *= Vector2.One * 0.2f;

                Dirty(eye);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-zoom-in-description"),
        };

        args.Verbs.Add(zoomIn);

        Verb flipEye = new()
        {
            Text        = "Flip eye",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/AdminActions/flip.png",
            Act         = () =>
            {
                var eye = EnsureComp <EyeComponent>(args.Target);

                eye.Zoom *= -1;

                Dirty(eye);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-flip-eye-description"),
        };

        args.Verbs.Add(flipEye);

        Verb runWalkSwap = new()
        {
            Text        = "Run Walk Swap",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/AdminActions/run-walk-swap.png",
            Act         = () =>
            {
                var movementSpeed = EnsureComp <MovementSpeedModifierComponent>(args.Target);
                (movementSpeed.BaseSprintSpeed, movementSpeed.BaseWalkSpeed) = (movementSpeed.BaseWalkSpeed, movementSpeed.BaseSprintSpeed);

                Dirty(movementSpeed);

                _popupSystem.PopupEntity(Loc.GetString("admin-smite-run-walk-swap-prompt"), args.Target,
                                         Filter.Entities(args.Target), PopupType.LargeCaution);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-run-walk-swap-description"),
        };

        args.Verbs.Add(runWalkSwap);

        Verb backwardsAccent = new()
        {
            Text        = "Speak Backwards",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/AdminActions/help-backwards.png",
            Act         = () =>
            {
                EnsureComp <BackwardsAccentComponent>(args.Target);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-speak-backwards-description"),
        };

        args.Verbs.Add(backwardsAccent);

        Verb disarmProne = new()
        {
            Text        = "Disarm Prone",
            Category    = VerbCategory.Smite,
            IconTexture = "/Textures/Interface/Actions/disarm.png",
            Act         = () =>
            {
                EnsureComp <DisarmProneComponent>(args.Target);
            },
            Impact  = LogImpact.Extreme,
            Message = Loc.GetString("admin-smite-disarm-prone-description"),
        };

        args.Verbs.Add(disarmProne);
    }
}
        private void SingularityQuery()
        {
            var currentEyeLoc = _eyeManager.CurrentEye.Position;
            var currentMap    = _eyeManager.CurrentMap; //TODO: support multiple viewports once it is added

            var singuloComponents = _componentManager.EntityQuery <IClientSingularityInstance>();

            foreach (var singuloInterface in singuloComponents) //Add all singulos that are not added yet but qualify
            {
                var singuloComponent = (Component)singuloInterface;
                var singuloEntity    = singuloComponent.Owner;
                if (!_singularities.Keys.Contains(singuloEntity.Uid) && singuloEntity.Transform.MapID == currentMap && singuloEntity.Transform.Coordinates.InRange(_entityManager, EntityCoordinates.FromMap(_entityManager, singuloEntity.Transform.ParentUid, currentEyeLoc), _maxDist))
                {
                    _singularities.Add(singuloEntity.Uid, new SingularityShaderInstance(singuloEntity.Transform.MapPosition.Position, singuloInterface.Level));
                }
            }

            var activeShaderUids = _singularities.Keys;

            foreach (var activeSinguloUid in activeShaderUids) //Remove all singulos that are added and no longer qualify
            {
                if (_entityManager.TryGetEntity(activeSinguloUid, out IEntity? singuloEntity))
                {
                    if (singuloEntity.Transform.MapID != currentMap || !singuloEntity.Transform.Coordinates.InRange(_entityManager, EntityCoordinates.FromMap(_entityManager, singuloEntity.Transform.ParentUid, currentEyeLoc), _maxDist))
                    {
                        _singularities.Remove(activeSinguloUid);
                    }
                    else
                    {
                        if (!singuloEntity.TryGetComponent <IClientSingularityInstance>(out var singuloInterface))
                        {
                            _singularities.Remove(activeSinguloUid);
                        }
                        else
                        {
                            var shaderInstance = _singularities[activeSinguloUid];
                            shaderInstance.CurrentMapCoords = singuloEntity.Transform.MapPosition.Position;
                            shaderInstance.Level            = singuloInterface.Level;
                        }
                    }
                }
                else
                {
                    _singularities.Remove(activeSinguloUid);
                }
            }
        }
예제 #16
0
        public override void Update(float frameTime)
        {
            base.Update(frameTime);

            if (!_gameTiming.IsFirstTimePredicted)
            {
                return;
            }

            var state = _inputSystem.CmdStates.GetState(EngineKeyFunctions.Use);

            if (!_combatModeSystem.IsInCombatMode() || state != BoundKeyState.Down)
            {
                _shotCounter = 0;
                _blocked     = false;
                return;
            }

            var entity = _playerManager.LocalPlayer?.ControlledEntity;

            if (!EntityManager.TryGetComponent(entity, out SharedHandsComponent? hands))
            {
                return;
            }

            if (!hands.TryGetActiveHeldEntity(out var held) || !EntityManager.TryGetComponent(held, out ClientRangedWeaponComponent? weapon))
            {
                _blocked = true;
                return;
            }

            switch (weapon.FireRateSelector)
            {
            case FireRateSelector.Safety:
                _blocked = true;
                return;

            case FireRateSelector.Single:
                if (_shotCounter >= 1)
                {
                    _blocked = true;
                    return;
                }

                break;

            case FireRateSelector.Automatic:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (_blocked)
            {
                return;
            }

            var mapCoordinates = _eyeManager.ScreenToMap(_inputManager.MouseScreenPosition);
            EntityCoordinates coordinates;

            if (_mapManager.TryFindGridAt(mapCoordinates, out var grid))
            {
                coordinates = EntityCoordinates.FromMap(grid.GridEntityId, mapCoordinates);
            }
            else
            {
                coordinates = EntityCoordinates.FromMap(_mapManager.GetMapEntityId(mapCoordinates.MapId), mapCoordinates);
            }

            SyncFirePos(coordinates);
        }