Vending Machines (#296)

* Vending Machines

* addressed review
This commit is contained in:
DamianX
2019-08-14 10:49:28 +02:00
committed by Pieter-Jan Briers
parent 3c476d2b40
commit 88920696f3
199 changed files with 1217 additions and 2 deletions

View File

@@ -11,6 +11,7 @@ using Content.Client.UserInterface;
using Content.Shared.GameObjects.Components.Chemistry; using Content.Shared.GameObjects.Components.Chemistry;
using Content.Shared.GameObjects.Components.Markers; using Content.Shared.GameObjects.Components.Markers;
using Content.Shared.GameObjects.Components.Research; using Content.Shared.GameObjects.Components.Research;
using Content.Shared.GameObjects.Components.VendingMachines;
using Content.Shared.Interfaces; using Content.Shared.Interfaces;
using Robust.Client.Interfaces; using Robust.Client.Interfaces;
using Robust.Client.Interfaces.Graphics.Overlays; using Robust.Client.Interfaces.Graphics.Overlays;
@@ -105,6 +106,8 @@ namespace Content.Client
factory.Register<SharedSpawnPointComponent>(); factory.Register<SharedSpawnPointComponent>();
factory.Register<SolutionComponent>(); factory.Register<SolutionComponent>();
factory.Register<SharedVendingMachineComponent>();
prototypes.RegisterIgnore("material"); prototypes.RegisterIgnore("material");
IoCManager.Register<IGameHud, GameHud>(); IoCManager.Register<IGameHud, GameHud>();

View File

@@ -0,0 +1,68 @@
using Content.Client.VendingMachines;
using Content.Shared.GameObjects.Components.VendingMachines;
using Robust.Client.GameObjects.Components.UserInterface;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.ViewVariables;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Content.Client.GameObjects.Components.VendingMachines
{
class VendingMachineBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private VendingMachineMenu _menu;
public SharedVendingMachineComponent VendingMachine { get; private set; }
public VendingMachineBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
SendMessage(new SharedVendingMachineComponent.InventorySyncRequestMessage());
}
protected override void Open()
{
base.Open();
if(!Owner.Owner.TryGetComponent(out SharedVendingMachineComponent vendingMachine))
{
return;
}
VendingMachine = vendingMachine;
_menu = new VendingMachineMenu() { Owner = this, Title = Owner.Owner.Name };
_menu.Populate(VendingMachine.Inventory);
_menu.OnClose += Close;
_menu.OpenCentered();
}
public void Eject(string ID)
{
SendMessage(new SharedVendingMachineComponent.VendingMachineEjectMessage(ID));
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
switch(message)
{
case SharedVendingMachineComponent.VendingMachineInventoryMessage msg:
_menu.Populate(msg.Inventory);
break;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if(!disposing) { return; }
_menu?.Dispose();
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
using Content.Client.GameObjects.Components.Doors;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Client.GameObjects.Components.Animations;
using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
using YamlDotNet.RepresentationModel;
using static Content.Shared.GameObjects.Components.VendingMachines.SharedVendingMachineComponent;
namespace Content.Client.GameObjects.Components.VendingMachines
{
public class VendingMachineVisualizer2D : AppearanceVisualizer
{
// TODO: The length of these animations is supposed to be dictated
// by the vending machine's pack prototype's `AnimationDuration`
// but we have no good way of passing that data from the server
// to the client at the moment. Rework Visualizers?
private const string DeniedAnimationKey = "deny";
private const string EjectAnimationKey = "eject";
private Animation _deniedAnimation;
private Animation _ejectAnimation;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_deniedAnimation = new Animation {Length = TimeSpan.FromSeconds(1.2f)};
{
var flick = new AnimationTrackSpriteFlick();
_deniedAnimation.AnimationTracks.Add(flick);
flick.LayerKey = VendingMachineVisualLayers.Base;
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("deny", 0f));
}
_ejectAnimation = new Animation {Length = TimeSpan.FromSeconds(1.2f)};
{
var flick = new AnimationTrackSpriteFlick();
_ejectAnimation.AnimationTracks.Add(flick);
flick.LayerKey = VendingMachineVisualLayers.Base;
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("eject", 0f));
}
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);
if (!entity.HasComponent<AnimationPlayerComponent>())
{
entity.AddComponent<AnimationPlayerComponent>();
}
}
public override void OnChangeData(AppearanceComponent component)
{
var sprite = component.Owner.GetComponent<ISpriteComponent>();
var animPlayer = component.Owner.GetComponent<AnimationPlayerComponent>();
if (!component.TryGetData(VendingMachineVisuals.VisualState, out VendingMachineVisualState state))
{
state = VendingMachineVisualState.Normal;
}
switch (state)
{
case VendingMachineVisualState.Normal:
sprite.LayerSetState(VendingMachineVisualLayers.Base, "normal");
break;
case VendingMachineVisualState.Off:
sprite.LayerSetState(VendingMachineVisualLayers.Base, "off");
break;
case VendingMachineVisualState.Broken:
sprite.LayerSetState(VendingMachineVisualLayers.Base, "broken");
break;
case VendingMachineVisualState.Deny:
if (!animPlayer.HasRunningAnimation(DeniedAnimationKey))
{
animPlayer.Play(_deniedAnimation, DeniedAnimationKey);
}
break;
case VendingMachineVisualState.Eject:
if (!animPlayer.HasRunningAnimation(EjectAnimationKey))
{
animPlayer.Play(_ejectAnimation, EjectAnimationKey);
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
public enum VendingMachineVisualLayers
{
Base,
}
}
}

View File

@@ -0,0 +1,79 @@
using Content.Client.GameObjects.Components.VendingMachines;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using static Content.Shared.GameObjects.Components.VendingMachines.SharedVendingMachineComponent;
namespace Content.Client.VendingMachines
{
class VendingMachineMenu : SS14Window
{
protected override Vector2? CustomSize => (300, 450);
private ItemList _items;
private List<VendingMachineInventoryEntry> _cachedInventory;
#pragma warning disable CS0649
[Dependency]
private IResourceCache _resourceCache;
[Dependency]
private readonly IPrototypeManager _prototypeManager;
#pragma warning restore
public VendingMachineBoundUserInterface Owner { get; set; }
public VendingMachineMenu()
{
}
public VendingMachineMenu(string name) : base(name)
{
}
protected override void Initialize()
{
base.Initialize();
IoCManager.InjectDependencies(this);
_items = new ItemList()
{
SizeFlagsStretchRatio = 8,
SizeFlagsVertical = SizeFlags.FillExpand,
};
_items.OnItemSelected += ItemSelected;
Contents.AddChild(_items);
}
public void Populate(List<VendingMachineInventoryEntry> inventory)
{
_items.Clear();
_cachedInventory = inventory;
foreach (VendingMachineInventoryEntry entry in inventory)
{
Texture icon = null;
if(_prototypeManager.TryIndex(entry.ID, out EntityPrototype prototype))
{
icon = IconComponent.GetPrototypeIcon(prototype, _resourceCache).TextureFor(Direction.South);
}
_items.AddItem($"{entry.ID} ({entry.Amount} left)", icon);
}
}
public void ItemSelected(ItemList.ItemListSelectedEventArgs args)
{
Owner.Eject(_cachedInventory[args.ItemIndex].ID);
}
}
}

View File

@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces;
using Content.Shared.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects.Components.Damage
{
[RegisterComponent]
public class BreakableComponent : Component, IOnDamageBehavior, IExAct
{
#pragma warning disable 649
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
#pragma warning restore 649
/// <inheritdoc />
public override string Name => "Breakable";
public DamageThreshold Threshold { get; private set; }
public DamageType damageType = DamageType.Total;
public int damageValue = 0;
public bool broken = false;
private ActSystem _actSystem;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref damageValue, "thresholdvalue", 100);
serializer.DataField(ref damageType, "thresholdtype", DamageType.Total);
}
public override void Initialize()
{
base.Initialize();
_actSystem = _entitySystemManager.GetEntitySystem<ActSystem>();
}
public List<DamageThreshold> GetAllDamageThresholds()
{
Threshold = new DamageThreshold(damageType, damageValue, ThresholdType.Breakage);
return new List<DamageThreshold>() {Threshold};
}
public void OnDamageThresholdPassed(object obj, DamageThresholdPassedEventArgs e)
{
if (e.Passed && e.DamageThreshold == Threshold && broken == false)
{
broken = true;
_actSystem.HandleBreakage(Owner);
}
}
public void OnExplosion(ExplosionEventArgs eventArgs)
{
var prob = new Random();
switch (eventArgs.Severity)
{
case ExplosionSeverity.Destruction:
_actSystem.HandleBreakage(Owner);
break;
case ExplosionSeverity.Heavy:
_actSystem.HandleBreakage(Owner);
break;
case ExplosionSeverity.Light:
if(prob.Prob(40))
_actSystem.HandleBreakage(Owner);
break;
}
}
}
}

View File

@@ -43,7 +43,8 @@ namespace Content.Server.GameObjects
Destruction, Destruction,
Death, Death,
Critical, Critical,
HUDUpdate HUDUpdate,
Breakage,
} }
public class DamageThresholdPassedEventArgs : EventArgs public class DamageThresholdPassedEventArgs : EventArgs

View File

@@ -0,0 +1,194 @@
using System;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components.VendingMachines;
using Content.Shared.VendingMachines;
using Robust.Server.GameObjects.Components.UserInterface;
using Robust.Server.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Timers;
using Robust.Shared.Utility;
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Power;
using Robust.Server.GameObjects;
using Robust.Shared.Log;
namespace Content.Server.GameObjects.Components.VendingMachines
{
[RegisterComponent]
[ComponentReference(typeof(IActivate))]
public class VendingMachineComponent : SharedVendingMachineComponent, IActivate, IExamine, IBreakAct
{
private AppearanceComponent _appearance;
private BoundUserInterface _userInterface;
private PowerDeviceComponent _powerDevice;
private bool _ejecting = false;
private TimeSpan _animationDuration = TimeSpan.Zero;
private string _packPrototypeId;
private string _description;
private string _spriteName;
private bool Powered => _powerDevice.Powered;
private bool _broken = false;
public void Activate(ActivateEventArgs eventArgs)
{
if(!eventArgs.User.TryGetComponent(out IActorComponent actor))
{
return;
}
_userInterface.Open(actor.playerSession);
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _packPrototypeId, "pack", string.Empty);
}
private void InitializeFromPrototype()
{
if (string.IsNullOrEmpty(_packPrototypeId)) { return; }
var prototypeManger = IoCManager.Resolve<IPrototypeManager>();
if (!prototypeManger.TryIndex(_packPrototypeId, out VendingMachineInventoryPrototype packPrototype))
{
return;
}
Owner.Name = packPrototype.Name;
_description = packPrototype.Description;
_animationDuration = TimeSpan.FromSeconds(packPrototype.AnimationDuration);
_spriteName = packPrototype.SpriteName;
if (!string.IsNullOrEmpty(_spriteName))
{
var spriteComponent = Owner.GetComponent<SpriteComponent>();
const string vendingMachineRSIPath = "Buildings/VendingMachines/{0}.rsi";
spriteComponent.BaseRSIPath = string.Format(vendingMachineRSIPath, _spriteName);
}
var inventory = new List<VendingMachineInventoryEntry>();
foreach(var (id, amount) in packPrototype.StartingInventory)
{
inventory.Add(new VendingMachineInventoryEntry(id, amount));
}
Inventory = inventory;
}
public override void Initialize()
{
base.Initialize();
_appearance = Owner.GetComponent<AppearanceComponent>();
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
.GetBoundUserInterface(VendingMachineUiKey.Key);
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
_powerDevice = Owner.GetComponent<PowerDeviceComponent>();
_powerDevice.OnPowerStateChanged += UpdatePower;
InitializeFromPrototype();
}
public override void OnRemove()
{
_appearance = null;
_powerDevice.OnPowerStateChanged -= UpdatePower;
_powerDevice = null;
base.OnRemove();
}
private void UpdatePower(object sender, PowerStateEventArgs args)
{
var state = args.Powered ? VendingMachineVisualState.Normal : VendingMachineVisualState.Off;
TrySetVisualState(state);
}
private void UserInterfaceOnOnReceiveMessage(BoundUserInterfaceMessage message)
{
switch (message)
{
case VendingMachineEjectMessage msg:
TryEject(msg.ID);
break;
case InventorySyncRequestMessage msg:
_userInterface.SendMessage(new VendingMachineInventoryMessage(Inventory));
break;
}
}
public void Examine(FormattedMessage message)
{
if(_description == null) { return; }
message.AddText(_description);
}
private void TryEject(string id)
{
if (_ejecting || _broken)
{
return;
}
VendingMachineInventoryEntry entry = Inventory.Find(x => x.ID == id);
if (entry == null)
{
FlickDenyAnimation();
return;
}
if (entry.Amount <= 0)
{
FlickDenyAnimation();
return;
}
_ejecting = true;
entry.Amount--;
_userInterface.SendMessage(new VendingMachineInventoryMessage(Inventory));
TrySetVisualState(VendingMachineVisualState.Eject);
Timer.Spawn(_animationDuration, () =>
{
TrySetVisualState(VendingMachineVisualState.Normal);
_ejecting = false;
Owner.EntityManager.SpawnEntityAt(id, Owner.Transform.GridPosition);
});
}
private void FlickDenyAnimation()
{
TrySetVisualState(VendingMachineVisualState.Deny);
//TODO: This duration should be a distinct value specific to the deny animation
Timer.Spawn(_animationDuration, () =>
{
TrySetVisualState(VendingMachineVisualState.Normal);
});
}
private void TrySetVisualState(VendingMachineVisualState state)
{
var finalState = state;
if (_broken)
{
finalState = VendingMachineVisualState.Broken;
} else if (_ejecting)
{
finalState = VendingMachineVisualState.Eject;
} else if (!Powered)
{
finalState = VendingMachineVisualState.Off;
}
_appearance.SetData(VendingMachineVisuals.VisualState, finalState);
}
public void OnBreak(BreakageEventArgs eventArgs)
{
_broken = true;
TrySetVisualState(VendingMachineVisualState.Broken);
}
}
}

View File

@@ -24,6 +24,19 @@ namespace Content.Server.GameObjects.EntitySystems
public bool IsSpawnWreck { get; set; } public bool IsSpawnWreck { get; set; }
} }
public class BreakageEventArgs : EventArgs
{
public IEntity Owner { get; set; }
}
public interface IBreakAct
{
/// <summary>
/// Called when object is broken
/// </summary>
void OnBreak(BreakageEventArgs eventArgs);
}
public interface IExAct public interface IExAct
{ {
/// <summary> /// <summary>
@@ -73,6 +86,19 @@ namespace Content.Server.GameObjects.EntitySystems
exAct.OnExplosion(eventArgs); exAct.OnExplosion(eventArgs);
} }
} }
public void HandleBreakage(IEntity owner)
{
var eventArgs = new BreakageEventArgs
{
Owner = owner,
};
var breakActs = owner.GetAllComponents<IBreakAct>().ToList();
foreach (var breakAct in breakActs)
{
breakAct.OnBreak(eventArgs);
}
}
} }
public enum ExplosionSeverity public enum ExplosionSeverity
{ {
@@ -80,4 +106,4 @@ namespace Content.Server.GameObjects.EntitySystems
Heavy, Heavy,
Light, Light,
} }
} }

View File

@@ -0,0 +1,78 @@
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace Content.Shared.GameObjects.Components.VendingMachines
{
public class SharedVendingMachineComponent : Component
{
public override string Name => "VendingMachine";
public override uint? NetID => ContentNetIDs.VENDING_MACHINE;
public List<VendingMachineInventoryEntry> Inventory = new List<VendingMachineInventoryEntry>();
[Serializable, NetSerializable]
public enum VendingMachineVisuals
{
VisualState,
}
[Serializable, NetSerializable]
public enum VendingMachineVisualState
{
Normal,
Off,
Broken,
Eject,
Deny,
}
[Serializable, NetSerializable]
public class VendingMachineEjectMessage : BoundUserInterfaceMessage
{
public readonly string ID;
public VendingMachineEjectMessage(string id)
{
ID = id;
}
}
[Serializable, NetSerializable]
public enum VendingMachineUiKey
{
Key,
}
[Serializable, NetSerializable]
public class InventorySyncRequestMessage : BoundUserInterfaceMessage
{
}
[Serializable, NetSerializable]
public class VendingMachineInventoryMessage : BoundUserInterfaceMessage
{
public readonly List<VendingMachineInventoryEntry> Inventory;
public VendingMachineInventoryMessage(List<VendingMachineInventoryEntry> inventory)
{
Inventory = inventory;
}
}
[Serializable, NetSerializable]
public class VendingMachineInventoryEntry
{
public string ID;
public uint Amount;
public VendingMachineInventoryEntry(string id, uint amount)
{
ID = id;
Amount = amount;
}
}
}
}

View File

@@ -23,5 +23,6 @@
public const uint LATHE_DATABASE = 1017; public const uint LATHE_DATABASE = 1017;
public const uint MATERIAL_STORAGE = 1018; public const uint MATERIAL_STORAGE = 1018;
public const uint HAND_TELEPORTER = 1019; public const uint HAND_TELEPORTER = 1019;
public const uint VENDING_MACHINE = 1020;
} }
} }

View File

@@ -0,0 +1,41 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YamlDotNet.RepresentationModel;
namespace Content.Shared.VendingMachines
{
[Serializable, NetSerializable, Prototype("vendingMachineInventory")]
public class VendingMachineInventoryPrototype : IPrototype, IIndexedPrototype
{
private string _id;
private string _name;
private string _description;
private double _animationDuration;
private string _spriteName;
private Dictionary<string, uint> _startingInventory;
public string ID => _id;
public string Name => _name;
public string Description => _description;
public double AnimationDuration => _animationDuration;
public string SpriteName => _spriteName;
public Dictionary<string, uint> StartingInventory => _startingInventory;
public void LoadFrom(YamlMappingNode mapping)
{
var serializer = YamlObjectSerializer.NewReader(mapping);
serializer.DataField(ref _id, "id", string.Empty);
serializer.DataField(ref _name, "name", string.Empty);
serializer.DataField(ref _description, "description", string.Empty);
serializer.DataField<double>(ref _animationDuration, "animationDuration", 0);
serializer.DataField(ref _spriteName, "spriteName", string.Empty);
serializer.DataField(ref _startingInventory, "startingInventory", new Dictionary<string, uint>());
}
}
}

View File

@@ -0,0 +1,338 @@
- type: entity
id: VendingMachine
name: vending machine
components:
- type: Clickable
- type: Sprite
sprite: Buildings/VendingMachines/empty.rsi
layers:
- state: normal
map: ["enum.VendingMachineVisualLayers.Base"]
- type: Icon
sprite: Buildings/VendingMachines/empty.rsi
state: normal
- type: BoundingBox
- type: Collidable
- type: SnapGrid
offset: Center
- type: Damageable
- type: Breakable
- type: Appearance
visuals:
- type: VendingMachineVisualizer2D
- type: UserInterface
interfaces:
- key: enum.VendingMachineUiKey.Key
type: VendingMachineBoundUserInterface
- type: PowerDevice
priority: Low
- type: entity
parent: VendingMachine
id: vending_machine_ammo
name: AmmoVend
components:
- type: VendingMachine
pack: AmmoVend
- type: Icon
sprite: Buildings/VendingMachines/ammo.rsi
- type: entity
parent: VendingMachine
id: vending_machine_booze
name: Booze-O-Mat
components:
- type: VendingMachine
pack: Booze-O-Mat
- type: Icon
sprite: Buildings/VendingMachines/boozeomat.rsi
- type: entity
parent: VendingMachine
id: vending_machine_cart
name: PTech
components:
- type: VendingMachine
pack: PTech
- type: Icon
sprite: Buildings/VendingMachines/cart.rsi
- type: entity
parent: VendingMachine
id: vending_machine_chapel
name: PietyVend
components:
- type: VendingMachine
pack: PietyVend
- type: Icon
sprite: Buildings/VendingMachines/chapel.rsi
- type: entity
parent: VendingMachine
id: vending_machine_cigs
name: Cigarette machine
components:
- type: VendingMachine
pack: Cigarette machine
- type: Icon
sprite: Buildings/VendingMachines/cigs.rsi
- type: entity
parent: VendingMachine
id: vending_machine_coffee
name: Hot Drinks machine
components:
- type: VendingMachine
pack: Hot Drinks machine
- type: Icon
sprite: Buildings/VendingMachines/dinnerware.rsi
- type: entity
parent: VendingMachine
id: vending_machine_cola
name: Robust Softdrinks
components:
- type: VendingMachine
pack: Robust Softdrinks
- type: Icon
sprite: Buildings/VendingMachines/discount.rsi
- type: entity
parent: VendingMachine
id: vending_machine_dinnerware
name: Dinnerware
components:
- type: VendingMachine
pack: Dinnerware
- type: Icon
sprite: Buildings/VendingMachines/dinnerware.rsi
- type: entity
parent: VendingMachine
id: vending_machine_discount
name: Discount Dan's
components:
- type: VendingMachine
pack: Discount Dan's
- type: Icon
sprite: Buildings/VendingMachines/discount.rsi
- type: entity
parent: VendingMachine
id: vending_machine_engivend
name: Engi-Vend
components:
- type: VendingMachine
pack: Engi-Vend
- type: Icon
sprite: Buildings/VendingMachines/engivend.rsi
- type: entity
parent: VendingMachine
id: vending_machine_hats
name: Hatlord 9000
components:
- type: VendingMachine
pack: Hatlord 9000
- type: Icon
sprite: Buildings/VendingMachines/hats.rsi
- type: entity
parent: VendingMachine
id: vending_machine_magivend
name: MagiVend
components:
- type: VendingMachine
pack: MagiVend
- type: Icon
sprite: Buildings/VendingMachines/magivend.rsi
- type: entity
parent: VendingMachine
id: vending_machine_medical
name: NanoMed Plus
components:
- type: VendingMachine
pack: NanoMed Plus
- type: Icon
sprite: Buildings/VendingMachines/medical.rsi
- type: entity
parent: VendingMachine
id: vending_machine_mining
name: Dwarven Mining Equipment
components:
- type: VendingMachine
pack: Dwarven Mining Equipment
- type: Icon
sprite: Buildings/VendingMachines/mining.rsi
- type: entity
parent: VendingMachine
id: vending_machine_nazi
name: Nazivend
components:
- type: VendingMachine
pack: Nazivend
- type: Icon
sprite: Buildings/VendingMachines/nazi.rsi
- type: entity
parent: VendingMachine
id: vending_machine_nutri
name: NutriMax
components:
- type: VendingMachine
pack: NutriMax
- type: Icon
sprite: Buildings/VendingMachines/nutri.rsi
- type: entity
parent: VendingMachine
id: vending_machine_robotics
name: Robotech Deluxe
components:
- type: VendingMachine
pack: Robotech Deluxe
- type: Icon
sprite: Buildings/VendingMachines/robotics.rsi
- type: entity
parent: VendingMachine
id: vending_machine_sales
name: Sales
components:
- type: VendingMachine
pack: Sales
- type: Icon
sprite: Buildings/VendingMachines/sale.rsi
- type: entity
parent: VendingMachine
id: vending_machine_sec
name: SecTech
components:
- type: VendingMachine
pack: SecTech
- type: Icon
sprite: Buildings/VendingMachines/sec.rsi
- type: entity
parent: VendingMachine
id: vending_machine_seeds
name: MegaSeed Servitor
components:
- type: VendingMachine
pack: MegaSeed Servitor
- type: Icon
sprite: Buildings/VendingMachines/seeds.rsi
- type: entity
parent: VendingMachine
id: vending_machine_shoes
name: Shoelord 9000
components:
- type: VendingMachine
pack: Shoelord 9000
- type: Icon
sprite: Buildings/VendingMachines/shoes.rsi
- type: entity
parent: VendingMachine
id: vending_machine_smartfridge
name: SmartFridge
components:
- type: VendingMachine
pack: SmartFridge
- type: Icon
sprite: Buildings/VendingMachines/smartfridge.rsi
- type: entity
parent: VendingMachine
id: vending_machine_snack
name: Getmore Chocolate Corp
components:
- type: VendingMachine
pack: Getmore Chocolate Corp
- type: Icon
sprite: Buildings/VendingMachines/snack.rsi
- type: entity
parent: VendingMachine
id: vending_machine_soviet
name: KomradeVendtink
components:
- type: VendingMachine
pack: KomradeVendtink
- type: Icon
sprite: Buildings/VendingMachines/soviet.rsi
- type: entity
parent: VendingMachine
id: vending_machine_sovietsoda
name: BODA
components:
- type: VendingMachine
pack: BODA
- type: Icon
sprite: Buildings/VendingMachines/sovietsoda.rsi
- type: entity
parent: VendingMachine
id: vending_machine_suits
name: Suitlord 9000
components:
- type: VendingMachine
pack: Suitlord 9000
- type: Icon
sprite: Buildings/VendingMachines/suits.rsi
- type: entity
parent: VendingMachine
id: vending_machine_theater
name: AutoDrobe
components:
- type: VendingMachine
pack: AutoDrobe
- type: Icon
sprite: Buildings/VendingMachines/theater.rsi
- type: entity
parent: VendingMachine
id: vending_machine_vendomat
name: Vendomat
components:
- type: VendingMachine
pack: Vendomat
- type: Icon
sprite: Buildings/VendingMachines/vendomat.rsi
- type: entity
parent: VendingMachine
id: vending_machine_vox
name: Trader Supply
components:
- type: VendingMachine
pack: Trader Supply
- type: Icon
sprite: Buildings/VendingMachines/vox.rsi
- type: entity
parent: VendingMachine
id: vending_machine_wallmed
name: NanoMed
components:
- type: VendingMachine
pack: NanoMed
- type: Icon
sprite: Buildings/VendingMachines/wallmed.rsi
- type: entity
parent: VendingMachine
id: vending_machine_youtool
name: YouTool
components:
- type: VendingMachine
pack: YouTool
- type: Icon
sprite: Buildings/VendingMachines/youtool.rsi

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: AmmoVend
name: AmmoVend
description: A generic ammunition vending machine.
spriteName: ammo

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Booze-O-Mat
name: Booze-O-Mat
description: A vending machine containing multiple drinks for bartending.
spriteName: boozeomat

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: PTech
name: PTech
description: A vending machine containing Personal Data Assistant cartridges.
spriteName: cart

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: PietyVend
name: PietyVend
description: "A vending machine containing religious supplies and clothing. A label reads: \"A holy vendor for a pious man.\""
spriteName: chapel

View File

@@ -0,0 +1,6 @@
- type: vendingMachineInventory
id: Cigarette machine
name: Cigarette machine
description: A vending machine containing smoking supplies.
animationDuration: 2.1
spriteName: cigs

View File

@@ -0,0 +1,6 @@
- type: vendingMachineInventory
id: Hot Drinks machine
name: Hot Drinks machine
description: A vending machine that dispenses hot drinks.
animationDuration: 3.4
spriteName: coffee

View File

@@ -0,0 +1,6 @@
- type: vendingMachineInventory
id: Robust Softdrinks
name: Robust Softdrinks
description: A softdrink vendor provided by Robust Industries, LLC.
animationDuration: 1.1
spriteName: cola

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Dinnerware
name: Dinnerware
description: A vending machine containing kitchen and restaurant equipment.
spriteName: dinnerware

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Discount Dan's
name: Discount Dan's
description: A vending machine containing discount snacks from the infamous 'Discount Dan' franchise.
spriteName: discount

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: empty vending machine
name: empty vending machine
description: Just add capitalism!
spriteName: empty

View File

@@ -0,0 +1,6 @@
- type: vendingMachineInventory
id: Engi-Vend
name: Engi-Vend
description: Spare tool vending. What? Did you expect some witty description?
animationDuration: 2.1
spriteName: engivend

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Hatlord 9000
name: Hatlord 9000
description: A vending machine containing hats.
spriteName: hats

View File

@@ -0,0 +1,6 @@
- type: vendingMachineInventory
id: MagiVend
name: MagiVend
description: A mystical vending machine containing magical garments and magic supplies.
animationDuration: 1.5
spriteName: magivend

View File

@@ -0,0 +1,6 @@
- type: vendingMachineInventory
id: NanoMed Plus
name: NanoMed Plus
description: A vending machine containing medical supplies.
animationDuration: 1.8
spriteName: medical

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Dwarven Mining Equipment
name: Dwarven Mining Equipment
description: Get your mining equipment here, and above all keep digging!
spriteName: mining

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Nazivend
name: Nazivend
description: "A vending machine containing Nazi German supplies. A label reads: \"Remember the gorillions lost.\""
spriteName: nazi

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: NutriMax
name: NutriMax
description: A vending machine containing nutritional substances for plants and botanical tools.
spriteName: nutri

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Robotech Deluxe
name: Robotech Deluxe
description: A vending machine containing nutritional substances for plants and botanical tools.
spriteName: robotics

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Sales
name: Sales
description: Buy, sell, repeat.
spriteName: sale

View File

@@ -0,0 +1,6 @@
- type: vendingMachineInventory
id: SecTech
name: SecTech
description: "A vending machine containing Security equipment. A label reads \"SECURITY PERSONNEL ONLY\"."
animationDuration: 1.4
spriteName: sec

View File

@@ -0,0 +1,6 @@
- type: vendingMachineInventory
id: MegaSeed Servitor
name: MegaSeed Servitor
description: "A vending machine containing Security equipment. A label reads \"SECURITY PERSONNEL ONLY\"."
animationDuration: 1.3
spriteName: seeds

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Shoelord 9000
name: Shoelord 9000
description: A vending machine containing footwear.
spriteName: shoes

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: SmartFridge
name: SmartFridge
description: A refrigerated storage unit for storing medicine and chemicals.
spriteName: smartfridge

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Getmore Chocolate Corp
name: Getmore Chocolate Corp
description: A vending machine containing snacks.
spriteName: snack

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: KomradeVendtink
name: KomradeVendtink
description: Rodina-mat' zovyot!
spriteName: soviet

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: BODA
name: BODA
description: An old vending machine containing sweet water.
spriteName: sovietsoda

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Suitlord 9000
name: Suitlord 9000
description: A vending machine containing jumpsuits and dress garments.
spriteName: suits

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: AutoDrobe
name: AutoDrobe
description: A vending machine containing costumes.
spriteName: theater

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Vendomat
name: Vendomat
description: A vending machine containing generic parts.
spriteName: vendomat

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: Trader Supply
name: Trader Supply
description: Make much coin.
spriteName: vox

View File

@@ -0,0 +1,5 @@
- type: vendingMachineInventory
id: NanoMed
name: NanoMed
description: Wall-mounted medical equipment dispenser.
spriteName: wallmed

View File

@@ -0,0 +1,13 @@
- type: vendingMachineInventory
id: YouTool
name: YouTool
description: "A vending machine containing standard tools. A label reads: \"Tools for tools.\""
animationDuration: 1.1
spriteName: youtool
startingInventory:
CableStack: 10
Crowbar: 5
Welder: 3
Wirecutter: 5
Wrench: 5
Screwdriver: 5

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "deny", "directions": 1, "delays": [[0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]]}, {"name": "normal", "directions": 1, "delays": [[0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "deny", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "eject", "directions": 1, "delays": [[1.0, 0.5, 0.1, 0.1, 0.1, 1.0, 0.1, 0.1, 0.1, 0.3]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "deny", "directions": 1, "delays": [[0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.1, 0.05, 0.1, 0.05, 0.1, 0.05, 0.1, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05]]}, {"name": "normal", "directions": 1, "delays": [[2.0, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 2.0, 0.05, 0.05, 2.0, 0.05, 0.05, 0.05, 2.0, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 2.0, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.5, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 1.0, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "eject", "directions": 1, "delays": [[1.0, 0.2, 0.1, 0.1, 0.1, 0.1, 1.0, 0.1, 0.1, 0.1]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "eject", "directions": 1, "delays": [[0.1, 0.4, 2.0, 0.2, 0.1, 0.1, 0.5, 0.5, 0.1, 0.1, 0.9]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "eject", "directions": 1, "delays": [[0.5, 0.1, 1.0, 0.1, 0.1]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 950 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "eject", "directions": 1, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "normal", "directions": 1, "delays": [[4.0, 0.1, 0.6]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "deny", "directions": 1, "delays": [[0.1, 0.1, 0.1]]}, {"name": "eject", "directions": 1, "delays": [[0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.5, 0.1, 1.0, 0.1, 0.1]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "normal", "directions": 1, "delays": [[2.0, 0.1, 0.2, 0.1]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]}

Some files were not shown because too many files have changed in this diff Show More