Water gun cargo crate (#16172)
@@ -45,14 +45,14 @@ public sealed class RandomSpriteSystem : SharedRandomSpriteSystem
|
|||||||
if (_reflection.TryParseEnumReference(layer.Key, out var @enum))
|
if (_reflection.TryParseEnumReference(layer.Key, out var @enum))
|
||||||
{
|
{
|
||||||
if (!sprite.LayerMapTryGet(@enum, out index, logError: true))
|
if (!sprite.LayerMapTryGet(@enum, out index, logError: true))
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!sprite.LayerMapTryGet(layer.Key, out index))
|
else if (!sprite.LayerMapTryGet(layer.Key, out index))
|
||||||
{
|
{
|
||||||
if (layer.Key is not string strKey || !int.TryParse(strKey, out index))
|
if (layer.Key is not { } strKey || !int.TryParse(strKey, out index))
|
||||||
{
|
{
|
||||||
Logger.Error($"Invalid key `{layer.Key}` for entity with random sprite {ToPrettyString(uid)}");
|
Logger.Error($"Invalid key `{layer.Key}` for entity with random sprite {ToPrettyString(uid)}");
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Linq;
|
|
||||||
using Content.Shared.Decals;
|
using Content.Shared.Decals;
|
||||||
using Content.Shared.Sprite;
|
using Content.Shared.Sprite;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
@@ -27,17 +26,29 @@ public sealed class RandomSpriteSystem: SharedRandomSpriteSystem
|
|||||||
if (component.Available.Count == 0)
|
if (component.Available.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var group = _random.Pick(component.Available);
|
var groups = new List<Dictionary<string, (string, string?)>>();
|
||||||
component.Selected.EnsureCapacity(group.Count);
|
if (component.GetAllGroups)
|
||||||
|
|
||||||
foreach (var layer in group)
|
|
||||||
{
|
{
|
||||||
Color? color = null;
|
groups = component.Available;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
groups.Add(_random.Pick(component.Available));
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(layer.Value.Color))
|
component.Selected.EnsureCapacity(groups.Count);
|
||||||
color = _random.Pick(_prototype.Index<ColorPalettePrototype>(layer.Value.Color).Colors.Values);
|
|
||||||
|
|
||||||
component.Selected.Add(layer.Key, (layer.Value.State, color));
|
foreach (var group in groups)
|
||||||
|
{
|
||||||
|
foreach (var layer in group)
|
||||||
|
{
|
||||||
|
Color? color = null;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(layer.Value.Item2))
|
||||||
|
color = _random.Pick(_prototype.Index<ColorPalettePrototype>(layer.Value.Item2).Colors.Values);
|
||||||
|
|
||||||
|
component.Selected.Add(layer.Key, (layer.Value.Item1, color));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dirty(component);
|
Dirty(component);
|
||||||
|
|||||||
@@ -5,6 +5,13 @@ namespace Content.Shared.Sprite;
|
|||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent]
|
||||||
public sealed class RandomSpriteComponent : Component
|
public sealed class RandomSpriteComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not all groups from <see cref="Available"/> are used,
|
||||||
|
/// or if only one is picked at random.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("getAllGroups")]
|
||||||
|
public bool GetAllGroups;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Available colors based on group, parsed layer enum, state, and color.
|
/// Available colors based on group, parsed layer enum, state, and color.
|
||||||
/// Stored as a list so we can have groups of random sprites (e.g. tech_base + tech_flare for holoparasite)
|
/// Stored as a list so we can have groups of random sprites (e.g. tech_base + tech_flare for holoparasite)
|
||||||
|
|||||||
@@ -16,5 +16,8 @@ ent-FunBoardGames = { ent-CrateFunBoardGames }
|
|||||||
ent-FunATV = { ent-CrateFunATV }
|
ent-FunATV = { ent-CrateFunATV }
|
||||||
.desc = { ent-CrateFunATV.desc }
|
.desc = { ent-CrateFunATV.desc }
|
||||||
|
|
||||||
|
ent-FunWaterGuns = { ent-CrateFunWaterGuns }
|
||||||
|
.desc = { ent-CrateFunWaterGuns.desc }
|
||||||
|
|
||||||
ent-FunParty = { ent-CrateFunParty }
|
ent-FunParty = { ent-CrateFunParty }
|
||||||
.desc = { ent-CrateFunParty.desc }
|
.desc = { ent-CrateFunParty.desc }
|
||||||
@@ -37,6 +37,9 @@ ent-CrateFunLightImplants = Light Implants
|
|||||||
ent-CrateFunParty = Party Crate
|
ent-CrateFunParty = Party Crate
|
||||||
.desc = An entire party just waiting for you to open it. Includes party favors, party beverages, and even a cake.
|
.desc = An entire party just waiting for you to open it. Includes party favors, party beverages, and even a cake.
|
||||||
|
|
||||||
|
ent-CrateFunWaterGuns = Water Gun Crate
|
||||||
|
.desc = A summer special with a variety of brightly colored water guns. Water not included.
|
||||||
|
|
||||||
ent-CrateFunSyndicateSegway = Syndicate segway crate
|
ent-CrateFunSyndicateSegway = Syndicate segway crate
|
||||||
.desc = A crate containing a two-wheeler that will help you escape from the security officers. Or not.
|
.desc = A crate containing a two-wheeler that will help you escape from the security officers. Or not.
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,16 @@
|
|||||||
category: Fun
|
category: Fun
|
||||||
group: market
|
group: market
|
||||||
|
|
||||||
|
- type: cargoProduct
|
||||||
|
id: CrateFunWaterGuns
|
||||||
|
icon:
|
||||||
|
sprite: Objects/Weapons/Guns/Pistols/water_pistol.rsi
|
||||||
|
state: display
|
||||||
|
product: CrateFunWaterGuns
|
||||||
|
cost: 750
|
||||||
|
category: Fun
|
||||||
|
group: market
|
||||||
|
|
||||||
- type: cargoProduct
|
- type: cargoProduct
|
||||||
id: FunPlushies
|
id: FunPlushies
|
||||||
icon:
|
icon:
|
||||||
|
|||||||
@@ -186,6 +186,16 @@
|
|||||||
amount: 4
|
amount: 4
|
||||||
- id: KnifePlastic
|
- id: KnifePlastic
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: CrateFunWaterGuns
|
||||||
|
parent: CratePlastic
|
||||||
|
components:
|
||||||
|
- type: StorageFill
|
||||||
|
contents:
|
||||||
|
- id: WeaponWaterBlaster
|
||||||
|
- id: WeaponWaterPistol
|
||||||
|
amount: 5
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: CrateFunSyndicateSegway
|
id: CrateFunSyndicateSegway
|
||||||
parent: CrateLivestock
|
parent: CrateLivestock
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
- type: entity
|
||||||
|
id: WeaponWaterGunBase
|
||||||
|
abstract: true
|
||||||
|
parent: BaseItem
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Pistols/water_pistol.rsi
|
||||||
|
- type: Clothing
|
||||||
|
sprite: Objects/Weapons/Guns/Pistols/water_pistol.rsi
|
||||||
|
slots: BELT
|
||||||
|
- type: Item
|
||||||
|
sprite: Objects/Weapons/Guns/Pistols/water_pistol.rsi
|
||||||
|
size: 10
|
||||||
|
- type: Gun
|
||||||
|
cameraRecoilScalar: 0 #no recoil
|
||||||
|
fireRate: 1
|
||||||
|
selectedMode: SemiAuto
|
||||||
|
availableModes:
|
||||||
|
- SemiAuto
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Weapons/Guns/Gunshots/water_spray.ogg
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
chamber:
|
||||||
|
maxVol: 50 #5 shots
|
||||||
|
- type: SolutionAmmoProvider
|
||||||
|
solutionId: chamber
|
||||||
|
proto: BulletWaterShot
|
||||||
|
- type: SolutionTransfer
|
||||||
|
transferAmount: 10
|
||||||
|
maxTransferAmount: 50
|
||||||
|
minTransferAmount: 5
|
||||||
|
canChangeTransferAmount: true
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.TransferAmountUiKey.Key
|
||||||
|
type: TransferAmountBoundUserInterface
|
||||||
|
- type: DrawableSolution
|
||||||
|
solution: chamber
|
||||||
|
- type: RefillableSolution
|
||||||
|
solution: chamber
|
||||||
|
- type: DrainableSolution
|
||||||
|
solution: chamber
|
||||||
|
- type: ExaminableSolution
|
||||||
|
solution: chamber
|
||||||
|
- type: StaticPrice
|
||||||
|
price: 100
|
||||||
|
- type: PhysicalComposition
|
||||||
|
materialComposition:
|
||||||
|
Plastic: 150
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: WeaponWaterPistol
|
||||||
|
parent: WeaponWaterGunBase
|
||||||
|
name: water pistol
|
||||||
|
description: The dinkiest of water-based weaponry. You swear the trigger doesn't do anything.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Pistols/water_pistol.rsi
|
||||||
|
layers:
|
||||||
|
- state: detail
|
||||||
|
- state: icon
|
||||||
|
map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||||
|
- type: RandomSprite
|
||||||
|
available:
|
||||||
|
- enum.DamageStateVisualLayers.Base:
|
||||||
|
icon: Rainbow
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: WeaponWaterBlaster
|
||||||
|
parent: WeaponWaterGunBase
|
||||||
|
name: water blaster
|
||||||
|
description: With this bad boy, you'll be the cooleste kid at the summer barbecue.
|
||||||
|
components:
|
||||||
|
- type: Gun
|
||||||
|
cameraRecoilScalar: 0 #no recoil
|
||||||
|
fireRate: 2
|
||||||
|
selectedMode: FullAuto
|
||||||
|
availableModes:
|
||||||
|
- FullAuto
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Weapons/Guns/Gunshots/water_spray.ogg
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
chamber:
|
||||||
|
maxVol: 100 #10 shots
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Pistols/soaker.rsi
|
||||||
|
layers:
|
||||||
|
- state: detail1
|
||||||
|
- state: detail2
|
||||||
|
map: ["enum.PowerDeviceVisualLayers.Powered"]
|
||||||
|
- state: icon
|
||||||
|
map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||||
|
- type: Item
|
||||||
|
sprite: Objects/Weapons/Guns/Pistols/soaker.rsi
|
||||||
|
size: 35
|
||||||
|
- type: RandomSprite
|
||||||
|
getAllGroups: true
|
||||||
|
available:
|
||||||
|
- enum.DamageStateVisualLayers.Base:
|
||||||
|
icon: Rainbow
|
||||||
|
- enum.PowerDeviceVisualLayers.Powered:
|
||||||
|
detail2: Sixteen
|
||||||
@@ -598,7 +598,7 @@
|
|||||||
fix1:
|
fix1:
|
||||||
shape:
|
shape:
|
||||||
!type:PhysShapeAabb
|
!type:PhysShapeAabb
|
||||||
bounds: "-0.25,-0.25,0.25,0.25"
|
bounds: "-0.10,-0.30,0.10,0.15"
|
||||||
hard: false
|
hard: false
|
||||||
mask:
|
mask:
|
||||||
- FullTileMask
|
- FullTileMask
|
||||||
|
|||||||
|
After Width: | Height: | Size: 165 B |
|
After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 281 B |
|
After Width: | Height: | Size: 630 B |
|
After Width: | Height: | Size: 613 B |
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC0-1.0",
|
||||||
|
"copyright": "Created by EmoGarbage404 (github) for Space Station 14",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "detail1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "detail2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-left",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-right",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 253 B |
|
After Width: | Height: | Size: 565 B |
|
After Width: | Height: | Size: 220 B |
|
After Width: | Height: | Size: 412 B |
|
After Width: | Height: | Size: 470 B |
|
After Width: | Height: | Size: 504 B |
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC0-1.0",
|
||||||
|
"copyright": "Created by EmoGarbage404 (github) for Space Station 14",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "display"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "detail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-left",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-right",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-BELT",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||