示例#1
0
        public void DoInstantAction(InstantActionEventArgs args)
        {
            if (!args.Performer.TryGetComponent <SharedActionsComponent>(out var actions))
            {
                return;
            }

            // find all IGhostBooAffected nearby and do boo on them
            var ents = IoCManager.Resolve <IEntityLookup>().GetEntitiesInRange(args.Performer, _radius);

            var booCounter = 0;

            foreach (var ent in ents)
            {
                var ghostBoo = new GhostBooEvent();
                ent.EntityManager.EventBus.RaiseLocalEvent(ent.Uid, ghostBoo);

                if (ghostBoo.Handled)
                {
                    booCounter++;
                }

                if (booCounter >= _maxTargets)
                {
                    break;
                }
            }

            actions.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(_cooldown));
        }
示例#2
0
        public void DoInstantAction(InstantActionEventArgs args)
        {
            if (!args.Performer.TryGetComponent <SharedActionsComponent>(out var actions))
            {
                return;
            }

            // find all IGhostBooAffected nearby and do boo on them
            var ents = IoCManager.Resolve <IEntityLookup>().GetEntitiesInRange(args.Performer, _radius, false);

            var booCounter = 0;

            foreach (var ent in ents)
            {
                var boos = ent.GetAllComponents <IGhostBooAffected>().ToList();
                foreach (var boo in boos)
                {
                    if (boo.AffectedByGhostBoo(args))
                    {
                        booCounter++;
                    }
                }

                if (booCounter >= _maxTargets)
                {
                    break;
                }
            }

            actions.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(_cooldown));
        }
 public void DoInstantAction(InstantItemActionEventArgs args)
 {
     args.Performer.PopupMessageEveryone(Message);
     if (Cooldown > 0)
     {
         args.ItemActions?.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(Cooldown));
     }
 }
示例#4
0
        public void DoTargetEntityAction(TargetEntityActionEventArgs args)
        {
            var disarmedActs = args.Target.GetAllComponents <IDisarmedAct>().ToArray();

            if (disarmedActs.Length == 0 || !args.Performer.InRangeUnobstructed(args.Target))
            {
                return;
            }
            if (!args.Performer.TryGetComponent <SharedActionsComponent>(out var actions))
            {
                return;
            }
            if (args.Target == args.Performer || !args.Performer.CanAttack())
            {
                return;
            }

            var random = IoCManager.Resolve <IRobustRandom>();
            var audio  = EntitySystem.Get <AudioSystem>();
            var system = EntitySystem.Get <MeleeWeaponSystem>();

            var angle = new Angle(args.Target.Transform.MapPosition.Position - args.Performer.Transform.MapPosition.Position);

            actions.Cooldown(ActionType.Disarm, Cooldowns.SecondsFromNow(_cooldown));

            if (random.Prob(_failProb))
            {
                audio.PlayFromEntity("/Audio/Weapons/punchmiss.ogg", args.Performer,
                                     AudioHelpers.WithVariation(0.025f));
                args.Performer.PopupMessageOtherClients(Loc.GetString("{0} fails to disarm {1}!", args.Performer.Name, args.Target.Name));
                args.Performer.PopupMessageCursor(Loc.GetString("You fail to disarm {0}!", args.Target.Name));
                system.SendLunge(angle, args.Performer);
                return;
            }

            system.SendAnimation("disarm", angle, args.Performer, args.Performer, new [] { args.Target });

            var eventArgs = new DisarmedActEventArgs()
            {
                Target = args.Target, Source = args.Performer, PushProbability = _pushProb
            };

            // Sort by priority.
            Array.Sort(disarmedActs, (a, b) => a.Priority.CompareTo(b.Priority));

            foreach (var disarmedAct in disarmedActs)
            {
                if (disarmedAct.Disarmed(eventArgs))
                {
                    return;
                }
            }

            audio.PlayFromEntity("/Audio/Effects/thudswoosh.ogg", args.Performer,
                                 AudioHelpers.WithVariation(0.025f));
        }
示例#5
0
        public void DoInstantAction(InstantActionEventArgs args)
        {
            if (!EntitySystem.Get <ActionBlockerSystem>().CanSpeak(args.Performer))
            {
                return;
            }
            if (!args.Performer.TryGetComponent <HumanoidAppearanceComponent>(out var humanoid))
            {
                return;
            }
            if (!args.Performer.TryGetComponent <SharedActionsComponent>(out var actions))
            {
                return;
            }

            if (_random.Prob(.01f) && !string.IsNullOrWhiteSpace(_wilhelm))
            {
                SoundSystem.Play(Filter.Pvs(args.Performer), _wilhelm, args.Performer, AudioParams.Default.WithVolume(Volume));
            }
            else
            {
                switch (humanoid.Sex)
                {
                case Sex.Male:
                    if (_male == null)
                    {
                        break;
                    }
                    SoundSystem.Play(Filter.Pvs(args.Performer), _random.Pick(_male), args.Performer,
                                     AudioHelpers.WithVariation(Variation).WithVolume(Volume));
                    break;

                case Sex.Female:
                    if (_female == null)
                    {
                        break;
                    }
                    SoundSystem.Play(Filter.Pvs(args.Performer), _random.Pick(_female), args.Performer,
                                     AudioHelpers.WithVariation(Variation).WithVolume(Volume));
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }



            actions.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(_cooldown));
        }
        public void DoInstantAction(InstantActionEventArgs args)
        {
            var entManager = IoCManager.Resolve <IEntityManager>();

            if (entManager.TryGetComponent(args.Performer, out GuardianHostComponent? hostComponent) &&
                hostComponent.HostedGuardian != null)
            {
                EntitySystem.Get <GuardianSystem>().ToggleGuardian(hostComponent);
                args.PerformerActions?.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(Cooldown));
            }
            else
            {
                args.Performer.PopupMessage(Loc.GetString("guardian-missing-invalid-action"));
            }
        }
        //Rubber-band snapping items into player's hands, originally was a workaround, later found it works quite well with stuns
        //Not sure if needs fixing

        public void DoInstantAction(InstantActionEventArgs args)
        {
            var caster = args.Performer;

            if (!caster.TryGetComponent(out HandsComponent? handsComponent))
            {
                caster.PopupMessage(Loc.GetString("spell-fail-no-hands"));
                return;
            }

            if (!EntitySystem.Get <ActionBlockerSystem>().CanInteract(caster))
            {
                return;
            }

            // TODO: Nix when we get EntityPrototype serializers
            if (!IoCManager.Resolve <IPrototypeManager>().HasIndex <EntityPrototype>(ItemProto))
            {
                Logger.Error($"Invalid prototype {ItemProto} supplied for {nameof(GiveItemSpell)}");
                return;
            }

            // TODO: Look this is shitty and ideally a test would do it
            var spawnedProto = caster.EntityManager.SpawnEntity(ItemProto, caster.Transform.MapPosition);

            if (!spawnedProto.TryGetComponent(out ItemComponent? itemComponent))
            {
                Logger.Error($"Tried to use {nameof(GiveItemSpell)} but prototype has no {nameof(ItemComponent)}?");
                spawnedProto.Delete();
                return;
            }

            args.PerformerActions?.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(CoolDown));

            if (CastMessage != null)
            {
                caster.PopupMessageEveryone(CastMessage);
            }

            handsComponent.PutInHandOrDrop(itemComponent);

            if (CastSound != null)
            {
                SoundSystem.Play(Filter.Pvs(caster), CastSound, caster);
            }
        }
        public void DoTargetEntityAction(TargetEntityActionEventArgs args)
        {
            var disarmedActs = args.Target.GetAllComponents <IDisarmedAct>().ToArray();

            if (!args.Performer.InRangeUnobstructed(args.Target))
            {
                return;
            }

            if (disarmedActs.Length == 0)
            {
                if (args.Performer.TryGetComponent(out ActorComponent? actor))
                {
                    // Fall back to a normal interaction with the entity
                    var player      = actor.PlayerSession;
                    var coordinates = args.Target.Transform.Coordinates;
                    var target      = args.Target.Uid;
                    EntitySystem.Get <InteractionSystem>().HandleUseInteraction(player, coordinates, target);
                    return;
                }

                return;
            }

            if (!args.Performer.TryGetComponent <SharedActionsComponent>(out var actions))
            {
                return;
            }
            if (args.Target == args.Performer || !EntitySystem.Get <ActionBlockerSystem>().CanAttack(args.Performer))
            {
                return;
            }

            var random = IoCManager.Resolve <IRobustRandom>();
            var system = EntitySystem.Get <MeleeWeaponSystem>();

            var diff  = args.Target.Transform.MapPosition.Position - args.Performer.Transform.MapPosition.Position;
            var angle = Angle.FromWorldVec(diff);

            actions.Cooldown(ActionType.Disarm, Cooldowns.SecondsFromNow(_cooldown));

            if (random.Prob(_failProb))
            {
                SoundSystem.Play(Filter.Pvs(args.Performer), PunchMissSound.GetSound(), args.Performer, AudioHelpers.WithVariation(0.025f));

                args.Performer.PopupMessageOtherClients(Loc.GetString("disarm-action-popup-message-other-clients",
                                                                      ("performerName", args.Performer.Name),
                                                                      ("targetName", args.Target.Name)));
                args.Performer.PopupMessageCursor(Loc.GetString("disarm-action-popup-message-cursor",
                                                                ("targetName", args.Target.Name)));
                system.SendLunge(angle, args.Performer);
                return;
            }

            system.SendAnimation("disarm", angle, args.Performer, args.Performer, new[] { args.Target });

            var eventArgs = new DisarmedActEvent()
            {
                Target = args.Target, Source = args.Performer, PushProbability = _pushProb
            };

            IoCManager.Resolve <IEntityManager>().EventBus.RaiseLocalEvent(args.Target.Uid, eventArgs);

            // Check if the event has been handled, and if so, do nothing else!
            if (eventArgs.Handled)
            {
                return;
            }

            // Sort by priority.
            Array.Sort(disarmedActs, (a, b) => a.Priority.CompareTo(b.Priority));

            // TODO: Remove this shit.
            foreach (var disarmedAct in disarmedActs)
            {
                if (disarmedAct.Disarmed(eventArgs))
                {
                    return;
                }
            }

            SoundSystem.Play(Filter.Pvs(args.Performer), DisarmSuccessSound.GetSound(), args.Performer.Transform.Coordinates, AudioHelpers.WithVariation(0.025f));
        }
        public async Task GrantsAndRevokesItemActions()
        {
            var serverOptions = new ServerIntegrationOptions {
                ExtraPrototypes = PROTOTYPES
            };
            var clientOptions = new ClientIntegrationOptions {
                ExtraPrototypes = PROTOTYPES
            };

            var(client, server) = await StartConnectedServerClientPair(serverOptions : serverOptions, clientOptions : clientOptions);

            await server.WaitIdleAsync();

            await client.WaitIdleAsync();

            var serverPlayerManager = server.ResolveDependency <Robust.Server.Interfaces.Player.IPlayerManager>();
            var serverEntManager    = server.ResolveDependency <IEntityManager>();
            var serverGameTiming    = server.ResolveDependency <IGameTiming>();

            var cooldown = Cooldowns.SecondsFromNow(30, serverGameTiming);

            ServerActionsComponent serverActionsComponent = null;
            ClientActionsComponent clientActionsComponent = null;
            IEntity serverPlayerEnt  = null;
            IEntity serverFlashlight = null;

            await server.WaitAssertion(() =>
            {
                serverPlayerEnt        = serverPlayerManager.GetAllPlayers().Single().AttachedEntity;
                serverActionsComponent = serverPlayerEnt.GetComponent <ServerActionsComponent>();

                // spawn and give them an item that has actions
                serverFlashlight = serverEntManager.SpawnEntity("TestFlashlight",
                                                                new EntityCoordinates(new EntityUid(1), (0, 0)));
                Assert.That(serverFlashlight.TryGetComponent <ItemActionsComponent>(out var itemActions));
                // we expect this only to have a toggle light action initially
                var actionConfigs = itemActions.ActionConfigs.ToList();
                Assert.That(actionConfigs.Count == 1);
                Assert.That(actionConfigs[0].ActionType == ItemActionType.ToggleLight);
                Assert.That(actionConfigs[0].Enabled);

                // grant an extra item action, before pickup, initially disabled
                itemActions.GrantOrUpdate(ItemActionType.DebugToggle, false);
                serverPlayerEnt.GetComponent <HandsComponent>().PutInHand(serverFlashlight.GetComponent <ItemComponent>(), false);
                // grant an extra item action, after pickup, with a cooldown
                itemActions.GrantOrUpdate(ItemActionType.DebugInstant, cooldown: cooldown);

                Assert.That(serverActionsComponent.TryGetItemActionStates(serverFlashlight.Uid, out var state));
                // they should have been granted all 3 actions
                Assert.That(state.Count == 3);
                Assert.That(state.TryGetValue(ItemActionType.ToggleLight, out var toggleLightState));
                Assert.That(toggleLightState.Equals(new ActionState(true)));
                Assert.That(state.TryGetValue(ItemActionType.DebugInstant, out var debugInstantState));
                Assert.That(debugInstantState.Equals(new ActionState(true, cooldown: cooldown)));
                Assert.That(state.TryGetValue(ItemActionType.DebugToggle, out var debugToggleState));
                Assert.That(debugToggleState.Equals(new ActionState(false)));
            });

            await server.WaitRunTicks(5);

            await client.WaitRunTicks(5);

            // check that client has the actions, and toggle the light on via the action slot it was auto-assigned to
            var       clientPlayerMgr  = client.ResolveDependency <IPlayerManager>();
            var       clientUIMgr      = client.ResolveDependency <IUserInterfaceManager>();
            var       clientEntMgr     = client.ResolveDependency <IEntityManager>();
            EntityUid clientFlashlight = default;
            await client.WaitAssertion(() =>
            {
                var local              = clientPlayerMgr.LocalPlayer;
                var controlled         = local.ControlledEntity;
                clientActionsComponent = controlled.GetComponent <ClientActionsComponent>();

                var lightEntry = clientActionsComponent.ItemActionStates()
                                 .Where(entry => entry.Value.ContainsKey(ItemActionType.ToggleLight))
                                 .FirstOrNull();
                clientFlashlight = lightEntry.Value.Key;
                Assert.That(lightEntry, Is.Not.Null);
                Assert.That(lightEntry.Value.Value.TryGetValue(ItemActionType.ToggleLight, out var lightState));
                Assert.That(lightState.Equals(new ActionState(true)));
                Assert.That(lightEntry.Value.Value.TryGetValue(ItemActionType.DebugInstant, out var debugInstantState));
                Assert.That(debugInstantState.Equals(new ActionState(true, cooldown: cooldown)));
                Assert.That(lightEntry.Value.Value.TryGetValue(ItemActionType.DebugToggle, out var debugToggleState));
                Assert.That(debugToggleState.Equals(new ActionState(false)));

                var actionsUI = clientUIMgr.StateRoot.Children.FirstOrDefault(c => c is ActionsUI) as ActionsUI;
                Assert.That(actionsUI, Is.Not.Null);

                var toggleLightSlot = actionsUI.Slots.FirstOrDefault(slot => slot.Action is ItemActionPrototype
                {
                    ActionType: ItemActionType.ToggleLight
                });
                Assert.That(toggleLightSlot, Is.Not.Null);

                clientActionsComponent.AttemptAction(toggleLightSlot);
            });
示例#10
0
        public void DoTargetEntityAction(TargetEntityActionEventArgs args)
        {
            var disarmedActs = args.Target.GetAllComponents <IDisarmedAct>().ToArray();

            if (!args.Performer.InRangeUnobstructed(args.Target))
            {
                return;
            }

            if (disarmedActs.Length == 0)
            {
                if (args.Performer.TryGetComponent(out ActorComponent? actor))
                {
                    // Fall back to a normal interaction with the entity
                    var player      = actor.PlayerSession;
                    var coordinates = args.Target.Transform.Coordinates;
                    var target      = args.Target.Uid;
                    EntitySystem.Get <InteractionSystem>().HandleClientUseItemInHand(player, coordinates, target);
                    return;
                }

                return;
            }

            if (!args.Performer.TryGetComponent <SharedActionsComponent>(out var actions))
            {
                return;
            }
            if (args.Target == args.Performer || !args.Performer.CanAttack())
            {
                return;
            }

            var random = IoCManager.Resolve <IRobustRandom>();
            var audio  = EntitySystem.Get <AudioSystem>();
            var system = EntitySystem.Get <MeleeWeaponSystem>();

            var diff  = args.Target.Transform.MapPosition.Position - args.Performer.Transform.MapPosition.Position;
            var angle = Angle.FromWorldVec(diff);

            actions.Cooldown(ActionType.Disarm, Cooldowns.SecondsFromNow(_cooldown));

            if (random.Prob(_failProb))
            {
                SoundSystem.Play(Filter.Pvs(args.Performer), "/Audio/Weapons/punchmiss.ogg", args.Performer,
                                 AudioHelpers.WithVariation(0.025f));
                args.Performer.PopupMessageOtherClients(Loc.GetString("{0} fails to disarm {1}!", args.Performer.Name, args.Target.Name));
                args.Performer.PopupMessageCursor(Loc.GetString("You fail to disarm {0}!", args.Target.Name));
                system.SendLunge(angle, args.Performer);
                return;
            }

            system.SendAnimation("disarm", angle, args.Performer, args.Performer, new [] { args.Target });

            var eventArgs = new DisarmedActEventArgs()
            {
                Target = args.Target, Source = args.Performer, PushProbability = _pushProb
            };

            // Sort by priority.
            Array.Sort(disarmedActs, (a, b) => a.Priority.CompareTo(b.Priority));

            foreach (var disarmedAct in disarmedActs)
            {
                if (disarmedAct.Disarmed(eventArgs))
                {
                    return;
                }
            }

            SoundSystem.Play(Filter.Pvs(args.Performer), "/Audio/Effects/thudswoosh.ogg", args.Performer.Transform.Coordinates,
                             AudioHelpers.WithVariation(0.025f));
        }