diff --git a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs new file mode 100644 index 0000000000..a6463019f1 --- /dev/null +++ b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs @@ -0,0 +1,112 @@ +using Content.Client.GameObjects.Components.Arcade; +using Content.Shared.GameObjects.Components.Arcade; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Vector2 = Robust.Shared.Maths.Vector2; + +namespace Content.Client.Arcade +{ + public class SpaceVillainArcadeMenu : SS14Window + { + protected override Vector2? CustomSize => (400, 200); + public SpaceVillainArcadeBoundUserInterface Owner { get; set; } + + private Label _enemyNameLabel; + private Label _playerInfoLabel; + private Label _enemyInfoLabel; + private Label _playerActionLabel; + private Label _enemyActionLabel; + public SpaceVillainArcadeMenu(SpaceVillainArcadeBoundUserInterface owner) + { + Title = "Space Villain"; + Owner = owner; + + GridContainer grid = new GridContainer(); + grid.Columns = 1; + + GridContainer infoGrid = new GridContainer(); + infoGrid.Columns = 3; + infoGrid.AddChild(new Label{ Text = "Player", Align = Label.AlignMode.Center }); + infoGrid.AddChild(new Label{ Text = "|", Align = Label.AlignMode.Center }); + _enemyNameLabel = new Label{ Align = Label.AlignMode.Center}; + infoGrid.AddChild(_enemyNameLabel); + + _playerInfoLabel = new Label {Align = Label.AlignMode.Center}; + infoGrid.AddChild(_playerInfoLabel); + infoGrid.AddChild(new Label{ Text = "|", Align = Label.AlignMode.Center }); + _enemyInfoLabel = new Label {Align = Label.AlignMode.Center}; + infoGrid.AddChild(_enemyInfoLabel); + CenterContainer centerContainer = new CenterContainer(); + centerContainer.AddChild(infoGrid); + grid.AddChild(centerContainer); + + _playerActionLabel = new Label(); + _playerActionLabel.Align = Label.AlignMode.Center; + grid.AddChild(_playerActionLabel); + + _enemyActionLabel = new Label(); + _enemyActionLabel.Align = Label.AlignMode.Center; + grid.AddChild(_enemyActionLabel); + + GridContainer buttonGrid = new GridContainer(); + buttonGrid.Columns = 3; + Button attack = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Attack); + attack.Text = "ATTACK"; + buttonGrid.AddChild(attack); + + Button heal = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Heal); + heal.Text = "HEAL"; + buttonGrid.AddChild(heal); + + Button recharge = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Recharge); + recharge.Text = "RECHARGE"; + buttonGrid.AddChild(recharge); + + centerContainer = new CenterContainer(); + centerContainer.AddChild(buttonGrid); + grid.AddChild(centerContainer); + + Button newGame = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.NewGame); + newGame.Text = "New Game"; + grid.AddChild(newGame); + + centerContainer = new CenterContainer(); + centerContainer.AddChild(grid); + Contents.AddChild(centerContainer); + } + + private void UpdateMetadata(SharedSpaceVillainArcadeComponent.SpaceVillainArcadeMetaDataUpdateMessage message) + { + Title = message.GameTitle; + _enemyNameLabel.Text = message.EnemyName; + } + + public void UpdateInfo(SharedSpaceVillainArcadeComponent.SpaceVillainArcadeDataUpdateMessage message) + { + if(message is SharedSpaceVillainArcadeComponent.SpaceVillainArcadeMetaDataUpdateMessage metaMessage) UpdateMetadata(metaMessage); + + _playerInfoLabel.Text = $"HP: {message.PlayerHP} MP: {message.PlayerMP}"; + _enemyInfoLabel.Text = $"HP: {message.EnemyHP} MP: {message.EnemyMP}"; + _playerActionLabel.Text = message.PlayerActionMessage; + _enemyActionLabel.Text = message.EnemyActionMessage; + } + + private class ActionButton : Button + { + private SpaceVillainArcadeBoundUserInterface _owner; + private SharedSpaceVillainArcadeComponent.PlayerAction _playerAction; + + public ActionButton(SpaceVillainArcadeBoundUserInterface owner,SharedSpaceVillainArcadeComponent.PlayerAction playerAction) + { + _owner = owner; + _playerAction = playerAction; + OnPressed += Clicked; + } + + private void Clicked(ButtonEventArgs e) + { + _owner.SendAction(_playerAction); + } + } + } +} diff --git a/Content.Client/GameObjects/Components/Arcade/SpaceVillainArcadeBoundUserInterface.cs b/Content.Client/GameObjects/Components/Arcade/SpaceVillainArcadeBoundUserInterface.cs new file mode 100644 index 0000000000..0c053a004d --- /dev/null +++ b/Content.Client/GameObjects/Components/Arcade/SpaceVillainArcadeBoundUserInterface.cs @@ -0,0 +1,55 @@ +using Content.Client.Arcade; +using Content.Shared.GameObjects.Components.Arcade; +using JetBrains.Annotations; +using Robust.Client.GameObjects.Components.UserInterface; +using Robust.Shared.GameObjects.Components.UserInterface; +using Robust.Shared.ViewVariables; + +namespace Content.Client.GameObjects.Components.Arcade +{ + public class SpaceVillainArcadeBoundUserInterface : BoundUserInterface + { + [ViewVariables] private SpaceVillainArcadeMenu _menu; + + //public SharedSpaceVillainArcadeComponent SpaceVillainArcade; + + public SpaceVillainArcadeBoundUserInterface([NotNull] ClientUserInterfaceComponent owner, [NotNull] object uiKey) : base(owner, uiKey) + { + SendAction(SharedSpaceVillainArcadeComponent.PlayerAction.RequestData); + } + + public void SendAction(SharedSpaceVillainArcadeComponent.PlayerAction action) + { + SendMessage(new SharedSpaceVillainArcadeComponent.SpaceVillainArcadePlayerActionMessage(action)); + } + + protected override void Open() + { + base.Open(); + + /*if(!Owner.Owner.TryGetComponent(out SharedSpaceVillainArcadeComponent spaceVillainArcade)) + { + return; + } + + SpaceVillainArcade = spaceVillainArcade;*/ + + _menu = new SpaceVillainArcadeMenu(this); + + _menu.OnClose += Close; + _menu.OpenCentered(); + } + + protected override void ReceiveMessage(BoundUserInterfaceMessage message) + { + if(message is SharedSpaceVillainArcadeComponent.SpaceVillainArcadeDataUpdateMessage msg) _menu.UpdateInfo(msg); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if(!disposing) { return; } + _menu?.Dispose(); + } + } +} diff --git a/Content.Client/IgnoredComponents.cs b/Content.Client/IgnoredComponents.cs index 0453be7b71..6286b4cef3 100644 --- a/Content.Client/IgnoredComponents.cs +++ b/Content.Client/IgnoredComponents.cs @@ -170,6 +170,7 @@ "Firelock", "AtmosPlaque", "Spillable", + "SpaceVillainArcade", "Flammable", "CreamPie", "CreamPied", diff --git a/Content.Server/GameObjects/Components/Arcade/SpaceVillainArcadeComponent.cs b/Content.Server/GameObjects/Components/Arcade/SpaceVillainArcadeComponent.cs new file mode 100644 index 0000000000..1f4a86d531 --- /dev/null +++ b/Content.Server/GameObjects/Components/Arcade/SpaceVillainArcadeComponent.cs @@ -0,0 +1,403 @@ +#nullable enable +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Power.ApcNetComponents; +using Content.Server.GameObjects.Components.VendingMachines; +using Content.Server.Utility; +using Content.Shared.GameObjects.Components; +using Content.Shared.GameObjects.Components.Arcade; +using Content.Shared.Interfaces.GameObjects.Components; +using Robust.Server.GameObjects.Components.UserInterface; +using Robust.Server.GameObjects.EntitySystems; +using Robust.Server.Interfaces.GameObjects; +using Robust.Shared.Audio; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Random; +using Robust.Shared.IoC; +using Robust.Shared.Random; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components.Arcade +{ + [RegisterComponent] + [ComponentReference(typeof(IActivate))] + public class SpaceVillainArcadeComponent : SharedSpaceVillainArcadeComponent, IActivate, IWires + { + [Dependency] private IRobustRandom _random = null!; + + private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered; + + [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(SpaceVillainArcadeUiKey.Key); + [ViewVariables] private bool _overflowFlag; + [ViewVariables] private bool _playerInvincibilityFlag; + [ViewVariables] private bool _enemyInvincibilityFlag; + [ViewVariables] private SpaceVillainGame _game = null!; + + [ViewVariables(VVAccess.ReadWrite)] private List _possibleFightVerbs = null!; + [ViewVariables(VVAccess.ReadWrite)] private List _possibleFirstEnemyNames = null!; + [ViewVariables(VVAccess.ReadWrite)] private List _possibleLastEnemyNames = null!; + [ViewVariables(VVAccess.ReadWrite)] private List _possibleRewards = null!; + + public override void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(ref _possibleFightVerbs, "possibleFightVerbs", new List() + {"Defeat", "Annihilate", "Save", "Strike", "Stop", "Destroy", "Robust", "Romance", "Pwn", "Own"}); + serializer.DataField(ref _possibleFirstEnemyNames, "possibleFirstEnemyNames", new List(){ + "the Automatic", "Farmer", "Lord", "Professor", "the Cuban", "the Evil", "the Dread King", + "the Space", "Lord", "the Great", "Duke", "General" + }); + serializer.DataField(ref _possibleLastEnemyNames, "possibleLastEnemyNames", new List() + { + "Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", + "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn" + }); + serializer.DataField(ref _possibleRewards, "possibleRewards", new List() + { + "ToyMouse", "ToyAi", "ToyNuke", "ToyAssistant", "ToyGriffin", "ToyHonk", "ToyIan", + "ToyMarauder", "ToyMauler", "ToyGygax", "ToyOdysseus", "ToyOwlman", "ToyDeathRipley", + "ToyPhazon", "ToyFireRipley", "ToyReticence", "ToyRipley", "ToySeraph", "ToyDurand", "ToySkeleton" + }); + + _game = new SpaceVillainGame(this); + } + + public void Activate(ActivateEventArgs eventArgs) + { + if(!eventArgs.User.TryGetComponent(out IActorComponent? actor)) + { + return; + } + if (!Powered) + { + return; + } + + var wires = Owner.GetComponent(); + if (wires.IsPanelOpen) + { + wires.OpenInterface(actor.playerSession); + } else + { + UserInterface?.Toggle(actor.playerSession); + } + } + + public override void Initialize() + { + base.Initialize(); + + if (UserInterface != null) + { + UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage; + } + } + + + private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg) + { + if (!Powered) + return; + + if (!(serverMsg.Message is SpaceVillainArcadePlayerActionMessage msg)) return; + + switch (msg.PlayerAction) + { + case PlayerAction.Attack: + _game?.ExecutePlayerAction(msg.PlayerAction); + break; + case PlayerAction.Heal: + _game?.ExecutePlayerAction(msg.PlayerAction); + break; + case PlayerAction.Recharge: + _game?.ExecutePlayerAction(msg.PlayerAction); + break; + case PlayerAction.NewGame: + EntitySystem.Get().PlayFromEntity("/Audio/Effects/Arcade/newgame.ogg", Owner, AudioParams.Default.WithVolume(-4f)); + _game = new SpaceVillainGame(this); + UserInterface?.SendMessage(_game.GenerateMetaDataMessage()); + break; + case PlayerAction.RequestData: + UserInterface?.SendMessage(_game.GenerateMetaDataMessage()); + break; + } + } + + public enum Wires + { + /// + /// Disables Max Health&Mana for both Enemy and Player. + /// + Overflow, + /// + /// Makes Player Invincible. + /// + PlayerInvincible, + /// + /// Makes Enemy Invincible. + /// + EnemyInvincible + } + + public void RegisterWires(WiresComponent.WiresBuilder builder) + { + builder.CreateWire(Wires.Overflow); + builder.CreateWire(Wires.PlayerInvincible); + builder.CreateWire(Wires.EnemyInvincible); + } + + public void WiresUpdate(WiresUpdateEventArgs args) + { + var wire = (Wires) args.Identifier; + var value = args.Action != SharedWiresComponent.WiresAction.Mend; + switch (wire) + { + case Wires.Overflow: + _overflowFlag = value; + break; + case Wires.PlayerInvincible: + _playerInvincibilityFlag = value; + break; + case Wires.EnemyInvincible: + _enemyInvincibilityFlag = value; + break; + } + } + + /// + /// Called when the user wins the game. + /// + public void ProcessWin() + { + var entityManager = IoCManager.Resolve(); + entityManager.SpawnEntity(_random.Pick(_possibleRewards), Owner.Transform.MapPosition); + } + + /// + /// Picks a fight-verb from the list of possible Verbs. + /// + /// A fight-verb. + public string GenerateFightVerb() + { + return _random.Pick(_possibleFightVerbs); + } + + /// + /// Generates an enemy-name comprised of a first- and last-name. + /// + /// An enemy-name. + public string GenerateEnemyName() + { + return $"{_random.Pick(_possibleFirstEnemyNames)} {_random.Pick(_possibleLastEnemyNames)}"; + } + + /// + /// A Class to handle all the game-logic of the SpaceVillain-game. + /// + public class SpaceVillainGame + { + [Dependency] private readonly IRobustRandom _random = default!; + + [ViewVariables] private SpaceVillainArcadeComponent Owner; + + [ViewVariables] public string Name => $"{_fightVerb} {_enemyName}"; + [ViewVariables(VVAccess.ReadWrite)] private int _playerHp = 30; + [ViewVariables(VVAccess.ReadWrite)] private int _playerHpMax = 30; + [ViewVariables(VVAccess.ReadWrite)] private int _playerMp = 10; + [ViewVariables(VVAccess.ReadWrite)] private int _playerMpMax = 10; + [ViewVariables(VVAccess.ReadWrite)] private int _enemyHp = 45; + [ViewVariables(VVAccess.ReadWrite)] private int _enemyHpMax = 45; + [ViewVariables(VVAccess.ReadWrite)] private int _enemyMp = 20; + [ViewVariables(VVAccess.ReadWrite)] private int _enemyMpMax = 20; + [ViewVariables(VVAccess.ReadWrite)] private int _turtleTracker; + + [ViewVariables(VVAccess.ReadWrite)] private string _fightVerb; + [ViewVariables(VVAccess.ReadWrite)] private string _enemyName; + + [ViewVariables] private bool _running = true; + + private string _latestPlayerActionMessage = ""; + private string _latestEnemyActionMessage = ""; + + public SpaceVillainGame(SpaceVillainArcadeComponent owner) : this(owner, owner.GenerateFightVerb(), owner.GenerateEnemyName()){} + + public SpaceVillainGame(SpaceVillainArcadeComponent owner, string fightVerb, string enemyName) + { + IoCManager.InjectDependencies(this); + Owner = owner; + //todo defeat the curse secret game mode + _fightVerb = fightVerb; + _enemyName = enemyName; + } + + /// + /// Validates all vars incase they overshoot their max-values. + /// Does not check if vars surpass 0. + /// + private void ValidateVars() + { + if(Owner._overflowFlag) return; + + if (_playerHp > _playerHpMax) _playerHp = _playerHpMax; + if (_playerMp > _playerMpMax) _playerMp = _playerMpMax; + if (_enemyHp > _enemyHpMax) _enemyHp = _enemyHpMax; + if (_enemyMp > _enemyMpMax) _enemyMp = _enemyMpMax; + } + + /// + /// Called by the SpaceVillainArcadeComponent when Userinput is received. + /// + /// The action the user picked. + public void ExecutePlayerAction(PlayerAction action) + { + if (!_running) return; + + switch (action) + { + case PlayerAction.Attack: + var attackAmount = _random.Next(2, 6); + _latestPlayerActionMessage = $"You attack {_enemyName} for {attackAmount}!"; + EntitySystem.Get().PlayFromEntity("/Audio/Effects/Arcade/player_attack.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f)); + if(!Owner._enemyInvincibilityFlag) _enemyHp -= attackAmount; + _turtleTracker -= _turtleTracker > 0 ? 1 : 0; + break; + case PlayerAction.Heal: + var pointAmount = _random.Next(1, 3); + var healAmount = _random.Next(6, 8); + _latestPlayerActionMessage = $"You use {pointAmount} magic to heal for {healAmount} damage!"; + EntitySystem.Get().PlayFromEntity("/Audio/Effects/Arcade/player_heal.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f)); + if(!Owner._playerInvincibilityFlag) _playerMp -= pointAmount; + _playerHp += healAmount; + _turtleTracker++; + break; + case PlayerAction.Recharge: + var charge_amount = _random.Next(4, 7); + _latestPlayerActionMessage = $"You regain {charge_amount} points"; + EntitySystem.Get().PlayFromEntity("/Audio/Effects/Arcade/player_charge.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f)); + _playerMp += charge_amount; + _turtleTracker -= _turtleTracker > 0 ? 1 : 0; + break; + } + + if (!CheckGameConditions()) + { + _running = false; + return; + } + + ValidateVars(); + ExecuteAiAction(); + + if (!CheckGameConditions()) + { + _running = false; + return; + } + ValidateVars(); + UpdateUi(); + } + + /// + /// Checks the Game conditions and Updates the Ui & Plays a sound accordingly. + /// + /// A bool indicating if the game should continue. + private bool CheckGameConditions() + { + if ((_enemyHp <= 0 || _enemyMp <= 0) && (_playerHp > 0 && _playerMp > 0)) + { + UpdateUi("You won!", $"{_enemyName} dies."); + EntitySystem.Get().PlayFromEntity("/Audio/Effects/Arcade/win.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f)); + Owner.ProcessWin(); + return false; + } + if ((_playerHp <= 0 || _playerMp <= 0) && _enemyHp > 0 && _enemyMp > 0) + { + UpdateUi("You lost!", $"{_enemyName} cheers."); + EntitySystem.Get().PlayFromEntity("/Audio/Effects/Arcade/gameover.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f)); + return false; + } + if ((_playerHp <= 0 || _playerMp <= 0) && (_enemyHp <= 0 || _enemyMp <= 0)) + { + UpdateUi("You lost!", $"{_enemyName} dies, but takes you with him."); + EntitySystem.Get().PlayFromEntity("/Audio/Effects/Arcade/gameover.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f)); + return false; + } + + return true; + } + + /// + /// Updates the UI. + /// + private void UpdateUi() + { + Owner.UserInterface?.SendMessage(GenerateUpdateMessage(_latestPlayerActionMessage, _latestEnemyActionMessage)); + } + + private void UpdateUi(string message1, string message2) + { + _latestPlayerActionMessage = message1; + _latestEnemyActionMessage = message2; + UpdateUi(); + } + + /// + /// Handles the logic of the AI + /// + /// An Enemyaction-message. + private void ExecuteAiAction() + { + if (_turtleTracker >= 4) + { + var boomAmount = _random.Next(5, 10); + _latestEnemyActionMessage = $"{_enemyName} throws a bomb, exploding you for {boomAmount} damage!"; + if (Owner._playerInvincibilityFlag) return; + _playerHp -= boomAmount; + _turtleTracker--; + }else if (_enemyMp <= 5 && _random.Prob(0.7f)) + { + var stealAmount = _random.Next(2, 3); + _latestEnemyActionMessage = $"{_enemyName} steals {stealAmount} of your power!"; + if (Owner._playerInvincibilityFlag) return; + _playerMp -= stealAmount; + _enemyMp += stealAmount; + }else if (_enemyHp <= 10 && _enemyMp > 4) + { + _enemyHp += 4; + _enemyMp -= 4; + _latestEnemyActionMessage = $"{_enemyName} heals for 4 health!"; + } + else + { + var attackAmount = _random.Next(3, 6); + _latestEnemyActionMessage = $"{_enemyName} attacks you for {attackAmount} damage!"; + if (Owner._playerInvincibilityFlag) return; + _playerHp -= attackAmount; + } + } + + /// + /// Generates a Metadata-message based on the objects values. + /// + /// A Metadata-message. + public SpaceVillainArcadeMetaDataUpdateMessage GenerateMetaDataMessage() + { + return new SpaceVillainArcadeMetaDataUpdateMessage(_playerHp, _playerMp, _enemyHp, _enemyMp, _latestPlayerActionMessage, _latestEnemyActionMessage, Name, _enemyName); + } + + /// + /// Creates an Update-message based on the objects values. + /// + /// Content of the Playeraction-field. + /// Content of the Enemyaction-field. + /// + public SpaceVillainArcadeDataUpdateMessage + GenerateUpdateMessage(string playerAction = "", string enemyAction = "") + { + return new SpaceVillainArcadeDataUpdateMessage(_playerHp, _playerMp, _enemyHp, _enemyMp, playerAction, + enemyAction); + } + } + } +} diff --git a/Content.Shared/GameObjects/Components/Arcade/SharedSpaceVillainArcadeComponent.cs b/Content.Shared/GameObjects/Components/Arcade/SharedSpaceVillainArcadeComponent.cs new file mode 100644 index 0000000000..786cf62aac --- /dev/null +++ b/Content.Shared/GameObjects/Components/Arcade/SharedSpaceVillainArcadeComponent.cs @@ -0,0 +1,81 @@ +using System; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Components.UserInterface; +using Robust.Shared.Serialization; + +namespace Content.Shared.GameObjects.Components.Arcade +{ + public class SharedSpaceVillainArcadeComponent : Component + { + public override string Name => "SpaceVillainArcade"; + public override uint? NetID => ContentNetIDs.SPACE_VILLAIN_ARCADE; + + [Serializable, NetSerializable] + public enum PlayerAction + { + Attack, + Heal, + Recharge, + NewGame, + RequestData + } + + [Serializable, NetSerializable] + public enum SpaceVillainArcadeVisualState + { + Normal, + Off, + Broken, + Win, + GameOver, + } + + [Serializable, NetSerializable] + public enum SpaceVillainArcadeUiKey + { + Key, + } + + [Serializable, NetSerializable] + public class SpaceVillainArcadePlayerActionMessage : BoundUserInterfaceMessage + { + public readonly PlayerAction PlayerAction; + public SpaceVillainArcadePlayerActionMessage(PlayerAction playerAction) + { + PlayerAction = playerAction; + } + } + + [Serializable, NetSerializable] + public class SpaceVillainArcadeMetaDataUpdateMessage : SpaceVillainArcadeDataUpdateMessage + { + public readonly string GameTitle; + public readonly string EnemyName; + public SpaceVillainArcadeMetaDataUpdateMessage(int playerHp, int playerMp, int enemyHp, int enemyMp, string playerActionMessage, string enemyActionMessage, string gameTitle, string enemyName) : base(playerHp, playerMp, enemyHp, enemyMp, playerActionMessage, enemyActionMessage) + { + GameTitle = gameTitle; + EnemyName = enemyName; + } + } + + [Serializable, NetSerializable] + public class SpaceVillainArcadeDataUpdateMessage : BoundUserInterfaceMessage + { + public readonly int PlayerHP; + public readonly int PlayerMP; + public readonly int EnemyHP; + public readonly int EnemyMP; + public readonly string PlayerActionMessage; + public readonly string EnemyActionMessage; + public SpaceVillainArcadeDataUpdateMessage(int playerHp, int playerMp, int enemyHp, int enemyMp, string playerActionMessage, string enemyActionMessage) + { + PlayerHP = playerHp; + PlayerMP = playerMp; + EnemyHP = enemyHp; + EnemyMP = enemyMp; + EnemyActionMessage = enemyActionMessage; + PlayerActionMessage = playerActionMessage; + } + } + } +} diff --git a/Content.Shared/GameObjects/ContentNetIDs.cs b/Content.Shared/GameObjects/ContentNetIDs.cs index 7ae6ce8c27..9d47e3ba1a 100644 --- a/Content.Shared/GameObjects/ContentNetIDs.cs +++ b/Content.Shared/GameObjects/ContentNetIDs.cs @@ -75,6 +75,7 @@ public const uint ROTATION = 1069; public const uint MOB_STATE_MANAGER = 1070; public const uint SLIP = 1071; + public const uint SPACE_VILLAIN_ARCADE = 1072; // Net IDs for integration tests. public const uint PREDICTION_TEST = 10001; diff --git a/Resources/Audio/Effects/Arcade/gameover.ogg b/Resources/Audio/Effects/Arcade/gameover.ogg new file mode 100644 index 0000000000..1e430022d7 Binary files /dev/null and b/Resources/Audio/Effects/Arcade/gameover.ogg differ diff --git a/Resources/Audio/Effects/Arcade/newgame.ogg b/Resources/Audio/Effects/Arcade/newgame.ogg new file mode 100644 index 0000000000..428665041a Binary files /dev/null and b/Resources/Audio/Effects/Arcade/newgame.ogg differ diff --git a/Resources/Audio/Effects/Arcade/player_attack.ogg b/Resources/Audio/Effects/Arcade/player_attack.ogg new file mode 100644 index 0000000000..bda8be0d6d Binary files /dev/null and b/Resources/Audio/Effects/Arcade/player_attack.ogg differ diff --git a/Resources/Audio/Effects/Arcade/player_charge.ogg b/Resources/Audio/Effects/Arcade/player_charge.ogg new file mode 100644 index 0000000000..9fc8e275ac Binary files /dev/null and b/Resources/Audio/Effects/Arcade/player_charge.ogg differ diff --git a/Resources/Audio/Effects/Arcade/player_heal.ogg b/Resources/Audio/Effects/Arcade/player_heal.ogg new file mode 100644 index 0000000000..37074b7230 Binary files /dev/null and b/Resources/Audio/Effects/Arcade/player_heal.ogg differ diff --git a/Resources/Audio/Effects/Arcade/win.ogg b/Resources/Audio/Effects/Arcade/win.ogg new file mode 100644 index 0000000000..8fe7429913 Binary files /dev/null and b/Resources/Audio/Effects/Arcade/win.ogg differ diff --git a/Resources/Prototypes/Entities/Constructible/Power/arcade.yml b/Resources/Prototypes/Entities/Constructible/Power/arcade.yml index 18a8757dce..ac425213c2 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/arcade.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/arcade.yml @@ -22,3 +22,12 @@ bodyBroken: arcade - type: Anchorable - type: Pullable + - type: SpaceVillainArcade + - type: Wires + BoardName: "Arcade" + - type: UserInterface + interfaces: + - key: enum.SpaceVillainArcadeUiKey.Key + type: SpaceVillainArcadeBoundUserInterface + - key: enum.WiresUiKey.Key + type: WiresBoundUserInterface