Remove FoodContainer, add whitelists, replace with SpawnItemsOnUse (#4358)
This commit is contained in:
@@ -57,7 +57,6 @@ namespace Content.Client.Entry
|
||||
"CablePlacer",
|
||||
"Drink",
|
||||
"Food",
|
||||
"FoodContainer",
|
||||
"MagicMirror",
|
||||
"FloorTile",
|
||||
"ShuttleController",
|
||||
@@ -277,6 +276,7 @@ namespace Content.Client.Entry
|
||||
"Advertise",
|
||||
"PowerNetworkBattery",
|
||||
"BatteryCharger",
|
||||
"SpawnItemsOnUse"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
using System;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Rounding;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Client.Nutrition.Visualizers
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public sealed class FoodContainerVisualizer : AppearanceVisualizer
|
||||
{
|
||||
[DataField("base_state", required: true)]
|
||||
private string? _baseState;
|
||||
|
||||
[DataField("steps", required: true)]
|
||||
private int _steps;
|
||||
|
||||
[DataField("mode")]
|
||||
private FoodContainerVisualMode _mode = FoodContainerVisualMode.Rounded;
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
|
||||
if (!component.TryGetData<int>(FoodContainerVisuals.Current, out var current))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!component.TryGetData<int>(FoodContainerVisuals.Capacity, out var capacity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int step;
|
||||
|
||||
switch (_mode)
|
||||
{
|
||||
case FoodContainerVisualMode.Discrete:
|
||||
step = Math.Min(_steps - 1, current);
|
||||
break;
|
||||
case FoodContainerVisualMode.Rounded:
|
||||
step = ContentHelpers.RoundToLevels(current, capacity, _steps);
|
||||
break;
|
||||
default:
|
||||
throw new NullReferenceException();
|
||||
}
|
||||
|
||||
sprite.LayerSetState(0, $"{_baseState}-{step}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Server.Hands.Components;
|
||||
using Content.Server.Items;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.Nutrition.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// This container acts as a master object for things like Pizza, which holds slices.
|
||||
/// </summary>
|
||||
/// TODO: Perhaps implement putting food back (pizza boxes) but that really isn't mandatory.
|
||||
/// This doesn't even need to have an actual Container for right now.
|
||||
[RegisterComponent]
|
||||
public sealed class FoodContainer : SharedFoodContainerComponent, IUse
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
public override string Name => "FoodContainer";
|
||||
|
||||
private AppearanceComponent? _appearance;
|
||||
[DataField("prototypes")]
|
||||
private Dictionary<string, int>? _prototypes = default;
|
||||
[DataField("capacity")]
|
||||
private uint _capacity = 5;
|
||||
|
||||
public int Capacity => (int)_capacity;
|
||||
[ViewVariables]
|
||||
public int Count => _count;
|
||||
|
||||
private int _count = 0;
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
Owner.TryGetComponent(out _appearance);
|
||||
_count = Capacity;
|
||||
UpdateAppearance();
|
||||
|
||||
}
|
||||
|
||||
bool IUse.UseEntity(UseEntityEventArgs eventArgs)
|
||||
{
|
||||
if (!eventArgs.User.TryGetComponent(out HandsComponent? handsComponent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var itemToSpawn = Owner.EntityManager.SpawnEntity(GetRandomPrototype(), Owner.Transform.Coordinates);
|
||||
handsComponent.PutInHandOrDrop(itemToSpawn.GetComponent<ItemComponent>());
|
||||
_count--;
|
||||
if (_count < 1)
|
||||
{
|
||||
Owner.Delete();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private string? GetRandomPrototype()
|
||||
{
|
||||
var defaultProto = _prototypes?.Keys.FirstOrDefault();
|
||||
|
||||
if (defaultProto == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DebugTools.AssertNotNull(_prototypes);
|
||||
|
||||
if (_prototypes!.Count == 1)
|
||||
{
|
||||
return defaultProto;
|
||||
}
|
||||
|
||||
var probResult = _random.Next(0, 100);
|
||||
var total = 0;
|
||||
foreach (var item in _prototypes)
|
||||
{
|
||||
total += item.Value;
|
||||
if (probResult < total)
|
||||
{
|
||||
return item.Key;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultProto;
|
||||
}
|
||||
|
||||
private void UpdateAppearance()
|
||||
{
|
||||
_appearance?.SetData(FoodContainerVisuals.Current, Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ using Content.Shared.Item;
|
||||
using Content.Shared.Notification;
|
||||
using Content.Shared.Notification.Managers;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Audio;
|
||||
@@ -47,10 +48,16 @@ namespace Content.Server.Storage.Components
|
||||
|
||||
[DataField("occludesLight")]
|
||||
private bool _occludesLight = true;
|
||||
|
||||
[DataField("quickInsert")]
|
||||
private bool _quickInsert; //Can insert storables by "attacking" them with the storage entity
|
||||
private bool _quickInsert = false; // Can insert storables by "attacking" them with the storage entity
|
||||
|
||||
[DataField("areaInsert")]
|
||||
private bool _areaInsert; //"Attacking" with the storage entity causes it to insert all nearby storables after a delay
|
||||
private bool _areaInsert = false; // "Attacking" with the storage entity causes it to insert all nearby storables after a delay
|
||||
|
||||
[DataField("whitelist")]
|
||||
private EntityWhitelist? _whitelist = null;
|
||||
|
||||
private bool _storageInitialCalculated;
|
||||
private int _storageUsed;
|
||||
[DataField("capacity")]
|
||||
@@ -123,6 +130,11 @@ namespace Content.Server.Storage.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_whitelist != null && !_whitelist.IsValid(entity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Sound;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Server.Storage.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Spawns items when used in hand.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public class SpawnItemsOnUseComponent : Component
|
||||
{
|
||||
public override string Name => "SpawnItemsOnUse";
|
||||
|
||||
/// <summary>
|
||||
/// The list of entities to spawn, with amounts and orGroups.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[DataField("items", required: true)]
|
||||
public List<EntitySpawnEntry> Items = new List<EntitySpawnEntry>();
|
||||
|
||||
/// <summary>
|
||||
/// A sound to play when the items are spawned. For example, gift boxes being unwrapped.
|
||||
/// </summary>
|
||||
[DataField("sound")]
|
||||
public SoundSpecifier? Sound = null;
|
||||
|
||||
/// <summary>
|
||||
/// How many uses before the item should delete itself.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[DataField("uses")]
|
||||
public int Uses = 1;
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@ namespace Content.Server.Storage.Components
|
||||
{
|
||||
public override string Name => "StorageFill";
|
||||
|
||||
[DataField("contents")] private List<StorageFillEntry> _contents = new();
|
||||
[DataField("contents")] private List<EntitySpawnEntry> _contents = new();
|
||||
|
||||
public IReadOnlyList<StorageFillEntry> Contents => _contents;
|
||||
public IReadOnlyList<EntitySpawnEntry> Contents => _contents;
|
||||
|
||||
void IMapInit.MapInit()
|
||||
{
|
||||
@@ -39,7 +39,6 @@ namespace Content.Server.Storage.Components
|
||||
var alreadySpawnedGroups = new List<string>();
|
||||
foreach (var storageItem in _contents)
|
||||
{
|
||||
if (string.IsNullOrEmpty(storageItem.PrototypeId)) continue;
|
||||
if (!string.IsNullOrEmpty(storageItem.GroupId) &&
|
||||
alreadySpawnedGroups.Contains(storageItem.GroupId)) continue;
|
||||
|
||||
@@ -58,50 +57,5 @@ namespace Content.Server.Storage.Components
|
||||
if (!string.IsNullOrEmpty(storageItem.GroupId)) alreadySpawnedGroups.Add(storageItem.GroupId);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[DataDefinition]
|
||||
public struct StorageFillEntry : IPopulateDefaultValues
|
||||
{
|
||||
[DataField("id", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string? PrototypeId;
|
||||
|
||||
[DataField("prob")] public float SpawnProbability;
|
||||
|
||||
/// <summary>
|
||||
/// The probability that an item will spawn. Takes decimal form so 0.05 is 5%, 0.50 is 50% etc.
|
||||
/// </summary>
|
||||
[DataField("orGroup")] public string GroupId;
|
||||
|
||||
/// <summary>
|
||||
/// orGroup signifies to pick between entities designated with an ID.
|
||||
///
|
||||
/// <example>
|
||||
/// <para>To define an orGroup in a StorageFill component you
|
||||
/// need to add it to the entities you want to choose between and
|
||||
/// add a prob field. In this example there is a 50% chance the storage
|
||||
/// spawns with Y or Z.
|
||||
///
|
||||
/// </para>
|
||||
/// <code>
|
||||
/// - type: StorageFill
|
||||
/// contents:
|
||||
/// - name: X
|
||||
/// - name: Y
|
||||
/// prob: 0.50
|
||||
/// orGroup: YOrZ
|
||||
/// - name: Z
|
||||
/// orGroup: YOrZ
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[DataField("amount")] public int Amount;
|
||||
|
||||
public void PopulateDefaultValues()
|
||||
{
|
||||
Amount = 1;
|
||||
SpawnProbability = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
59
Content.Server/Storage/EntitySpawnEntry.cs
Normal file
59
Content.Server/Storage/EntitySpawnEntry.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Server.Storage
|
||||
{
|
||||
/// <summary>
|
||||
/// Dictates a list of items that can be spawned.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataDefinition]
|
||||
public struct EntitySpawnEntry : IPopulateDefaultValues
|
||||
{
|
||||
[DataField("id", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string PrototypeId;
|
||||
|
||||
/// <summary>
|
||||
/// The probability that an item will spawn. Takes decimal form so 0.05 is 5%, 0.50 is 50% etc.
|
||||
/// </summary>
|
||||
[DataField("prob")]
|
||||
public float SpawnProbability;
|
||||
|
||||
/// <summary>
|
||||
/// orGroup signifies to pick between entities designated with an ID.
|
||||
///
|
||||
/// <example>
|
||||
/// <para>To define an orGroup in a StorageFill component you
|
||||
/// need to add it to the entities you want to choose between and
|
||||
/// add a prob field. In this example there is a 50% chance the storage
|
||||
/// spawns with Y or Z.
|
||||
///
|
||||
/// </para>
|
||||
/// <code>
|
||||
/// - type: StorageFill
|
||||
/// contents:
|
||||
/// - name: X
|
||||
/// - name: Y
|
||||
/// prob: 0.50
|
||||
/// orGroup: YOrZ
|
||||
/// - name: Z
|
||||
/// orGroup: YOrZ
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[DataField("orGroup")]
|
||||
public string? GroupId;
|
||||
|
||||
[DataField("amount")]
|
||||
public int Amount;
|
||||
|
||||
public void PopulateDefaultValues()
|
||||
{
|
||||
Amount = 1;
|
||||
SpawnProbability = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using JetBrains.Annotations;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Server.Storage
|
||||
namespace Content.Server.Storage.EntitySystems
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class ItemCounterSystem : SharedItemCounterSystem
|
||||
@@ -0,0 +1,68 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Storage.Components;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Storage.EntitySystems
|
||||
{
|
||||
public class SpawnItemsOnUseSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SpawnItemsOnUseComponent, UseInHandEvent>(OnUseInHand);
|
||||
}
|
||||
|
||||
private void OnUseInHand(EntityUid uid, SpawnItemsOnUseComponent component, UseInHandEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
var owner = EntityManager.GetEntity(uid);
|
||||
var alreadySpawnedGroups = new List<string>();
|
||||
IEntity? entityToPlaceInHands = null;
|
||||
foreach (var storageItem in component.Items)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(storageItem.GroupId) &&
|
||||
alreadySpawnedGroups.Contains(storageItem.GroupId)) continue;
|
||||
|
||||
if (storageItem.SpawnProbability != 1f &&
|
||||
!_random.Prob(storageItem.SpawnProbability))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var i = 0; i < storageItem.Amount; i++)
|
||||
{
|
||||
entityToPlaceInHands = EntityManager.SpawnEntity(storageItem.PrototypeId, args.User.Transform.Coordinates);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(storageItem.GroupId)) alreadySpawnedGroups.Add(storageItem.GroupId);
|
||||
}
|
||||
|
||||
if (component.Sound != null)
|
||||
SoundSystem.Play(Filter.Pvs(owner), component.Sound.GetSound());
|
||||
|
||||
component.Uses--;
|
||||
if (component.Uses == 0)
|
||||
{
|
||||
args.Handled = true;
|
||||
owner.Delete();
|
||||
}
|
||||
|
||||
if (entityToPlaceInHands != null
|
||||
&& args.User.TryGetComponent<SharedHandsComponent>(out var hands))
|
||||
{
|
||||
hands.TryPutInAnyHand(entityToPlaceInHands);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using Robust.Server.Player;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Server.Storage
|
||||
namespace Content.Server.Storage.EntitySystems
|
||||
{
|
||||
[UsedImplicitly]
|
||||
internal sealed class StorageSystem : EntitySystem
|
||||
@@ -54,7 +54,7 @@ namespace Content.Server.Storage
|
||||
{
|
||||
storageComp.HandleEntityMaybeInserted(message);
|
||||
}
|
||||
|
||||
|
||||
if (oldParentEntity.TryGetComponent<StorageCounterComponent>(out var newStorageComp))
|
||||
{
|
||||
newStorageComp.ContainerUpdateAppearance(message.Container);
|
||||
@@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Nutrition.Components
|
||||
{
|
||||
public abstract class SharedFoodContainerComponent : Component
|
||||
{
|
||||
}
|
||||
|
||||
[NetSerializable, Serializable]
|
||||
public enum FoodContainerVisualMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Discrete: 50 eggs in a carton -> down to 25, will show 12/12 until it gets below max
|
||||
/// Rounded: 50 eggs in a carton -> down to 25, will round it to 6 of 12
|
||||
/// </summary>
|
||||
Discrete,
|
||||
Rounded,
|
||||
}
|
||||
|
||||
[NetSerializable, Serializable]
|
||||
public enum FoodContainerVisuals
|
||||
{
|
||||
Capacity,
|
||||
Current,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
# Base
|
||||
|
||||
- type: Tag
|
||||
id: Donut
|
||||
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: FoodDonutBase
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
count: 8
|
||||
- type: Item
|
||||
size: 8
|
||||
- type: Tag
|
||||
tags:
|
||||
- Pizza
|
||||
|
||||
- type: entity
|
||||
parent: FoodPizzaBase
|
||||
@@ -37,6 +40,9 @@
|
||||
Quantity: 5
|
||||
- type: Item
|
||||
size: 1
|
||||
- type: Tag
|
||||
tags:
|
||||
- Pizza
|
||||
|
||||
# Pizza
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: FoodBoxDonut
|
||||
name: donutbox
|
||||
name: donut box
|
||||
description: Mmm, Donuts.
|
||||
components:
|
||||
- type: Sprite
|
||||
@@ -17,6 +17,9 @@
|
||||
state: box
|
||||
- type: Storage
|
||||
capacity: 6
|
||||
whitelist:
|
||||
tags:
|
||||
- Donut
|
||||
- type: Item
|
||||
sprite: Objects/Consumable/Food/Baked/donut.rsi
|
||||
size: 6
|
||||
@@ -48,7 +51,7 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: FoodContainerEgg
|
||||
name: eggbox
|
||||
name: egg carton
|
||||
description: Don't drop 'em!
|
||||
components:
|
||||
- type: Sprite
|
||||
@@ -57,6 +60,9 @@
|
||||
state: box-closed
|
||||
- type: Storage
|
||||
capacity: 12
|
||||
whitelist:
|
||||
tags:
|
||||
- Egg
|
||||
- type: Item
|
||||
sprite: Objects/Consumable/Food/egg.rsi
|
||||
size: 12
|
||||
@@ -114,6 +120,7 @@
|
||||
- type: entity
|
||||
parent: FoodContainerEgg
|
||||
id: EggBoxBroken
|
||||
suffix: Broken
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
@@ -261,6 +268,9 @@
|
||||
sprite: Objects/Consumable/Food/Baked/donkpocket.rsi
|
||||
state: box
|
||||
- type: Storage
|
||||
whitelist:
|
||||
tags:
|
||||
- DonkPocket
|
||||
capacity: 6
|
||||
- type: Item
|
||||
sprite: Objects/Consumable/Food/Baked/donkpocket.rsi
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# Base
|
||||
|
||||
- type: Tag
|
||||
id: Egg
|
||||
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: FoodEggBase
|
||||
@@ -66,7 +63,7 @@
|
||||
- type: Puddle
|
||||
variants: 4
|
||||
state: egg
|
||||
|
||||
|
||||
- type: entity
|
||||
name: eggshells
|
||||
parent: BaseItem
|
||||
@@ -86,6 +83,9 @@
|
||||
reagents:
|
||||
- ReagentId: Egg
|
||||
Quantity: 1
|
||||
- type: Tag
|
||||
tags:
|
||||
- Egg
|
||||
|
||||
# Egg
|
||||
|
||||
|
||||
@@ -4,10 +4,15 @@
|
||||
id: PackPaperRolling
|
||||
description: "A pack of thin pieces of paper used to make fine smokeables."
|
||||
components:
|
||||
# I know but it just works.
|
||||
- type: FoodContainer
|
||||
prototypes:
|
||||
PaperRolling: 100
|
||||
- type: Storage
|
||||
whitelist:
|
||||
tags:
|
||||
- RollingPaper
|
||||
capacity: 16
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: PaperRolling
|
||||
amount: 8
|
||||
- type: Sprite
|
||||
sprite: Objects/Consumable/Smokeables/Cigarettes/paper.rsi
|
||||
state: cigpapers
|
||||
@@ -29,6 +34,10 @@
|
||||
state: cigpaper
|
||||
- type: Item
|
||||
sprite: Objects/Consumable/Smokeables/Cigarettes/paper.rsi
|
||||
size: 2
|
||||
- type: Tag
|
||||
tags:
|
||||
- RollingPaper
|
||||
|
||||
- type: entity
|
||||
id: CigaretteFilter
|
||||
|
||||
@@ -4,9 +4,15 @@
|
||||
id: MonkeyCubeBox
|
||||
description: Drymate brand monkey cubes. Just add water!
|
||||
components:
|
||||
- type: FoodContainer
|
||||
prototypes:
|
||||
MonkeyCubeWrapper: 100
|
||||
- type: Storage
|
||||
whitelist:
|
||||
tags:
|
||||
- MonkeyCube
|
||||
capacity: 30
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: MonkeyCubeWrapped
|
||||
amount: 6
|
||||
- type: Sprite
|
||||
sprite: Objects/Misc/monkeycube.rsi
|
||||
state: box
|
||||
@@ -14,13 +20,18 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
name: monkey cube
|
||||
id: MonkeyCubeWrapper
|
||||
suffix: Wrapped
|
||||
id: MonkeyCubeWrapped
|
||||
description: Unwrap this to get a monkey cube.
|
||||
components:
|
||||
- type: FoodContainer
|
||||
capacity: 1
|
||||
prototypes:
|
||||
MonkeyCube: 100
|
||||
- type: SpawnItemsOnUse
|
||||
items:
|
||||
- id: MonkeyCube
|
||||
sound:
|
||||
path: /Audio/Effects/unwrap.ogg
|
||||
- type: Sprite
|
||||
sprite: Objects/Misc/monkeycube.rsi
|
||||
state: wrapper
|
||||
- type: Tag
|
||||
tags:
|
||||
- MonkeyCube
|
||||
|
||||
@@ -58,6 +58,12 @@
|
||||
- type: Tag
|
||||
id: DoorElectronics
|
||||
|
||||
- type: Tag
|
||||
id: Donut
|
||||
|
||||
- type: Tag
|
||||
id: Egg
|
||||
|
||||
- type: Tag
|
||||
id: ExplosivePassable
|
||||
|
||||
@@ -84,13 +90,19 @@
|
||||
|
||||
- type: Tag
|
||||
id: JawsOfLife
|
||||
|
||||
|
||||
- type: Tag
|
||||
id: MonkeyCube
|
||||
|
||||
- type: Tag
|
||||
id: NoSpinOnThrow
|
||||
|
||||
- type: Tag
|
||||
id: Ore
|
||||
|
||||
- type: Tag
|
||||
id: Pizza
|
||||
|
||||
- type: Tag
|
||||
id: PlantAnalyzer
|
||||
|
||||
@@ -103,6 +115,9 @@
|
||||
- type: Tag
|
||||
id: Powerdrill
|
||||
|
||||
- type: Tag
|
||||
id: RollingPaper
|
||||
|
||||
- type: Tag
|
||||
id: Screwdriver
|
||||
|
||||
|
||||
Reference in New Issue
Block a user