Port boxer from Nyano (#9080)
23
Content.Server/Abilities/Boxer/Boxer/BoxerComponent.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
|
||||||
|
namespace Content.Server.Abilities.Boxer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Added to the boxer on spawn.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class BoxerComponent : Component
|
||||||
|
{
|
||||||
|
[DataField("modifiers", required: true)]
|
||||||
|
public DamageModifierSet UnarmedModifiers = default!;
|
||||||
|
|
||||||
|
[DataField("rangeBonus")]
|
||||||
|
public float RangeBonus = 1.5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Damage modifier with boxing glove stam damage.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("boxingGlovesModifier")]
|
||||||
|
public float BoxingGlovesModifier = 1.75f;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
|
||||||
|
namespace Content.Server.Abilities.Boxer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Boxer gets a bonus for these, and their fists, but not other unarmed weapons.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class BoxingGlovesComponent : Component
|
||||||
|
{}
|
||||||
|
}
|
||||||
51
Content.Server/Abilities/Boxer/BoxingSystem.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using Content.Server.Weapon.Melee;
|
||||||
|
using Content.Server.Stunnable;
|
||||||
|
using Content.Shared.Inventory.Events;
|
||||||
|
using Content.Server.Weapon.Melee.Components;
|
||||||
|
using Content.Server.Clothing.Components;
|
||||||
|
using Content.Server.Damage.Components;
|
||||||
|
using Content.Server.Damage.Events;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Containers;
|
||||||
|
|
||||||
|
namespace Content.Server.Abilities.Boxer
|
||||||
|
{
|
||||||
|
public sealed class BoxingSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly StunSystem _stunSystem = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||||
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<BoxerComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<BoxerComponent, MeleeHitEvent>(ApplyBoxerModifiers);
|
||||||
|
SubscribeLocalEvent<BoxingGlovesComponent, StaminaMeleeHitEvent>(OnStamHit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInit(EntityUid uid, BoxerComponent boxer, ComponentInit args)
|
||||||
|
{
|
||||||
|
if (TryComp<MeleeWeaponComponent>(uid, out var meleeComp))
|
||||||
|
meleeComp.Range *= boxer.RangeBonus;
|
||||||
|
}
|
||||||
|
private void ApplyBoxerModifiers(EntityUid uid, BoxerComponent component, MeleeHitEvent args)
|
||||||
|
{
|
||||||
|
if (component.UnarmedModifiers == default!)
|
||||||
|
{
|
||||||
|
Logger.Warning("BoxerComponent on " + uid + " couldn't get damage modifiers. Know that adding components with damage modifiers through VV or similar is unsupported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.ModifiersList.Add(component.UnarmedModifiers);
|
||||||
|
}
|
||||||
|
private void OnStamHit(EntityUid uid, BoxingGlovesComponent component, StaminaMeleeHitEvent args)
|
||||||
|
{
|
||||||
|
_containerSystem.TryGetContainingContainer(uid, out var equipee);
|
||||||
|
if (TryComp<BoxerComponent>(equipee?.Owner, out var boxer))
|
||||||
|
args.Multiplier *= boxer.BoxingGlovesModifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using Content.Shared.Sound;
|
||||||
|
|
||||||
namespace Content.Server.Damage.Components;
|
namespace Content.Server.Damage.Components;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
@@ -5,4 +7,10 @@ public sealed class StaminaDamageOnHitComponent : Component
|
|||||||
{
|
{
|
||||||
[ViewVariables(VVAccess.ReadWrite), DataField("damage")]
|
[ViewVariables(VVAccess.ReadWrite), DataField("damage")]
|
||||||
public float Damage = 30f;
|
public float Damage = 30f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Play a sound when this knocks down an entity.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("knockdownSound")]
|
||||||
|
public SoundSpecifier? KnockdownSound;
|
||||||
}
|
}
|
||||||
|
|||||||
30
Content.Server/Damage/Events/StaminaMeleeHitEvent.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Robust.Shared.Collections;
|
||||||
|
using Content.Server.Damage.Components;
|
||||||
|
|
||||||
|
namespace Content.Server.Damage.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The components in the list are going to be hit,
|
||||||
|
/// give opportunities to change the damage or other stuff.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class StaminaMeleeHitEvent : HandledEntityEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// List of hit stamina components.
|
||||||
|
public ValueList<StaminaComponent> HitList;
|
||||||
|
|
||||||
|
/// <summmary>
|
||||||
|
/// The multiplier. Generally, try to use *= or /= instead of overwriting.
|
||||||
|
/// </summary>
|
||||||
|
public float Multiplier = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The flat modifier. Generally, try to use += or -= instead of overwriting.
|
||||||
|
/// </summary>
|
||||||
|
public float FlatModifier = 0;
|
||||||
|
|
||||||
|
public StaminaMeleeHitEvent(ValueList<StaminaComponent> hitList)
|
||||||
|
{
|
||||||
|
HitList = hitList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,10 +5,13 @@ using Content.Server.Weapon.Melee;
|
|||||||
using Content.Shared.Alert;
|
using Content.Shared.Alert;
|
||||||
using Content.Shared.Rounding;
|
using Content.Shared.Rounding;
|
||||||
using Content.Shared.Stunnable;
|
using Content.Shared.Stunnable;
|
||||||
|
using Content.Shared.Sound;
|
||||||
using Robust.Shared.Collections;
|
using Robust.Shared.Collections;
|
||||||
using Robust.Shared.Physics.Dynamics;
|
using Robust.Shared.Physics.Dynamics;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
|
||||||
|
|
||||||
namespace Content.Server.Damage.Systems;
|
namespace Content.Server.Damage.Systems;
|
||||||
|
|
||||||
@@ -70,10 +73,22 @@ public sealed class StaminaSystem : EntitySystem
|
|||||||
toHit.Add(stam);
|
toHit.Add(stam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hitEvent = new StaminaMeleeHitEvent(toHit);
|
||||||
|
RaiseLocalEvent(uid, hitEvent, false);
|
||||||
|
|
||||||
|
if (hitEvent.Handled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var damage = component.Damage;
|
||||||
|
|
||||||
|
damage *= hitEvent.Multiplier;
|
||||||
|
|
||||||
|
damage += hitEvent.FlatModifier;
|
||||||
|
|
||||||
foreach (var comp in toHit)
|
foreach (var comp in toHit)
|
||||||
{
|
{
|
||||||
var oldDamage = comp.StaminaDamage;
|
var oldDamage = comp.StaminaDamage;
|
||||||
TakeStaminaDamage(comp.Owner, component.Damage / toHit.Count, comp);
|
TakeStaminaDamage(comp.Owner, damage / toHit.Count, comp, component.KnockdownSound);
|
||||||
if (comp.StaminaDamage.Equals(oldDamage))
|
if (comp.StaminaDamage.Equals(oldDamage))
|
||||||
{
|
{
|
||||||
_popup.PopupEntity(Loc.GetString("stamina-resist"), comp.Owner, Filter.Entities(args.User));
|
_popup.PopupEntity(Loc.GetString("stamina-resist"), comp.Owner, Filter.Entities(args.User));
|
||||||
@@ -100,7 +115,7 @@ public sealed class StaminaSystem : EntitySystem
|
|||||||
_alerts.ShowAlert(uid, AlertType.Stamina, (short) severity);
|
_alerts.ShowAlert(uid, AlertType.Stamina, (short) severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TakeStaminaDamage(EntityUid uid, float value, StaminaComponent? component = null)
|
public void TakeStaminaDamage(EntityUid uid, float value, StaminaComponent? component = null, SoundSpecifier? knockdownSound = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref component, false) || component.Critical) return;
|
if (!Resolve(uid, ref component, false) || component.Critical) return;
|
||||||
|
|
||||||
@@ -131,6 +146,8 @@ public sealed class StaminaSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
if (component.StaminaDamage >= component.CritThreshold)
|
if (component.StaminaDamage >= component.CritThreshold)
|
||||||
{
|
{
|
||||||
|
if (knockdownSound != null)
|
||||||
|
SoundSystem.Play(knockdownSound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, knockdownSound.Params);
|
||||||
EnterStamCrit(uid, component);
|
EnterStamCrit(uid, component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.CombatMode;
|
|
||||||
using Content.Server.Hands.Components;
|
using Content.Server.Hands.Components;
|
||||||
using Content.Server.Pulling;
|
using Content.Server.Pulling;
|
||||||
using Content.Server.Storage.Components;
|
using Content.Server.Storage.Components;
|
||||||
|
using Content.Server.Weapon.Melee.Components;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.DragDrop;
|
using Content.Shared.DragDrop;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Interaction.Events;
|
using Content.Shared.Interaction.Events;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.Item;
|
using Content.Shared.Item;
|
||||||
using Content.Shared.Pulling.Components;
|
using Content.Shared.Pulling.Components;
|
||||||
using Content.Shared.Weapons.Melee;
|
using Content.Shared.Weapons.Melee;
|
||||||
@@ -32,6 +33,8 @@ namespace Content.Server.Interaction
|
|||||||
[Dependency] private readonly PullingSystem _pullSystem = default!;
|
[Dependency] private readonly PullingSystem _pullSystem = default!;
|
||||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||||
|
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||||
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -259,17 +262,23 @@ namespace Content.Server.Interaction
|
|||||||
|
|
||||||
// TODO: Make this saner?
|
// TODO: Make this saner?
|
||||||
// Attempt to do unarmed combat. We don't check for handled just because at this point it doesn't matter.
|
// Attempt to do unarmed combat. We don't check for handled just because at this point it doesn't matter.
|
||||||
|
|
||||||
|
var used = user;
|
||||||
|
|
||||||
|
if (_inventory.TryGetSlotEntity(user, "gloves", out var gloves) && HasComp<MeleeWeaponComponent>(gloves))
|
||||||
|
used = (EntityUid) gloves;
|
||||||
|
|
||||||
if (wideAttack)
|
if (wideAttack)
|
||||||
{
|
{
|
||||||
var ev = new WideAttackEvent(user, user, coordinates);
|
var ev = new WideAttackEvent(used, user, coordinates);
|
||||||
RaiseLocalEvent(user, ev, false);
|
RaiseLocalEvent(used, ev, false);
|
||||||
if (ev.Handled)
|
if (ev.Handled)
|
||||||
_adminLogger.Add(LogType.AttackUnarmedWide, LogImpact.Low, $"{ToPrettyString(user):user} wide attacked at {coordinates}");
|
_adminLogger.Add(LogType.AttackUnarmedWide, LogImpact.Low, $"{ToPrettyString(user):user} wide attacked at {coordinates}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var ev = new ClickAttackEvent(user, user, coordinates, target);
|
var ev = new ClickAttackEvent(used, user, coordinates, target);
|
||||||
RaiseLocalEvent(user, ev, false);
|
RaiseLocalEvent(used, ev, false);
|
||||||
if (ev.Handled)
|
if (ev.Handled)
|
||||||
{
|
{
|
||||||
if (target != null)
|
if (target != null)
|
||||||
|
|||||||
BIN
Resources/Audio/Weapons/boxingbell.ogg
Normal file
BIN
Resources/Audio/Weapons/boxingpunch1.ogg
Normal file
BIN
Resources/Audio/Weapons/boxingpunch2.ogg
Normal file
BIN
Resources/Audio/Weapons/boxingpunch3.ogg
Normal file
@@ -6,4 +6,8 @@ slash.ogg taken from https://github.com/tgstation/tgstation/blob/5d264fbea0124e5
|
|||||||
|
|
||||||
tap.ogg taken from https://github.com/tgstation/tgstation/blob/803ca4537df35cf252b056d8460d510be8a4f353/sound/weapons/tap.ogg under CC BY-SA 3.0
|
tap.ogg taken from https://github.com/tgstation/tgstation/blob/803ca4537df35cf252b056d8460d510be8a4f353/sound/weapons/tap.ogg under CC BY-SA 3.0
|
||||||
|
|
||||||
|
BoxingPunch 1, 2, and 3 taken from Ryan Conway at https://freesound.org/people/ryanconway/sounds/260739/ under CC BY 3.0
|
||||||
|
|
||||||
|
boxingbell.ogg taken from Herkules92 at https://freesound.org/people/Herkules92/sounds/520998/ under CC0 1.0
|
||||||
|
|
||||||
block_metal1.ogg taken from https://github.com/Citadel-Station-13/Citadel-Station-13/commit/31c5996a5db8cce0cb431cb1dc20d99cac83f268 under CC BY-SA 3.0
|
block_metal1.ogg taken from https://github.com/Citadel-Station-13/Citadel-Station-13/commit/31c5996a5db8cce0cb431cb1dc20d99cac83f268 under CC BY-SA 3.0
|
||||||
@@ -8,13 +8,23 @@
|
|||||||
sprite: Clothing/Hands/Gloves/boxing.rsi
|
sprite: Clothing/Hands/Gloves/boxing.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Hands/Gloves/boxing.rsi
|
sprite: Clothing/Hands/Gloves/boxing.rsi
|
||||||
|
- type: BoxingGloves
|
||||||
|
- type: StaminaDamageOnHit
|
||||||
|
damage: 8 #Stam damage values seem a bit higher than regular damage because of the decay, etc
|
||||||
|
knockdownSound: /Audio/Weapons/boxingbell.ogg
|
||||||
|
- type: MeleeWeapon
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Blunt: 0.6
|
||||||
|
hitSound:
|
||||||
|
collection: BoxingHit
|
||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberMaterial: fibers-leather
|
fiberMaterial: fibers-leather
|
||||||
fiberColor: fibers-red
|
fiberColor: fibers-red
|
||||||
- type: FingerprintMask
|
- type: FingerprintMask
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingHandsBase
|
parent: ClothingHandsGlovesBoxingRed
|
||||||
id: ClothingHandsGlovesBoxingBlue
|
id: ClothingHandsGlovesBoxingBlue
|
||||||
name: blue boxing gloves
|
name: blue boxing gloves
|
||||||
description: Blue gloves for competitive boxing.
|
description: Blue gloves for competitive boxing.
|
||||||
@@ -31,7 +41,7 @@
|
|||||||
- type: FingerprintMask
|
- type: FingerprintMask
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingHandsBase
|
parent: ClothingHandsGlovesBoxingRed
|
||||||
id: ClothingHandsGlovesBoxingGreen
|
id: ClothingHandsGlovesBoxingGreen
|
||||||
name: green boxing gloves
|
name: green boxing gloves
|
||||||
description: Green gloves for competitive boxing.
|
description: Green gloves for competitive boxing.
|
||||||
@@ -48,7 +58,7 @@
|
|||||||
- type: FingerprintMask
|
- type: FingerprintMask
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingHandsBase
|
parent: ClothingHandsGlovesBoxingRed
|
||||||
id: ClothingHandsGlovesBoxingYellow
|
id: ClothingHandsGlovesBoxingYellow
|
||||||
name: yellow boxing gloves
|
name: yellow boxing gloves
|
||||||
description: Yellow gloves for competitive boxing.
|
description: Yellow gloves for competitive boxing.
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
- type: entity
|
||||||
|
parent: ClothingUniformBase
|
||||||
|
id: UniformShortsRed
|
||||||
|
name: boxing shorts
|
||||||
|
description: These are shorts, not boxers.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Clothing/Uniforms/Shorts/Color/red.rsi
|
||||||
|
- type: Clothing
|
||||||
|
sprite: Clothing/Uniforms/Shorts/Color/red.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: ClothingUniformBase
|
||||||
|
id: UniformShortsRedWithTop
|
||||||
|
name: boxing shorts with top
|
||||||
|
description: These are shorts, not boxers.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Clothing/Uniforms/Shorts/Color/red_female.rsi
|
||||||
|
- type: Clothing
|
||||||
|
sprite: Clothing/Uniforms/Shorts/Color/red_female.rsi
|
||||||
@@ -662,6 +662,21 @@
|
|||||||
- type: Icon
|
- type: Icon
|
||||||
state: pda-reporter
|
state: pda-reporter
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BasePDA
|
||||||
|
id: BoxerPDA
|
||||||
|
name: boxer PDA
|
||||||
|
description: Float like a butterfly, ringtone like a bee.
|
||||||
|
components:
|
||||||
|
- type: PDA
|
||||||
|
id: BoxerIDCard
|
||||||
|
- type: Appearance
|
||||||
|
visuals:
|
||||||
|
- type: PDAVisualizer
|
||||||
|
state: pda-boxer
|
||||||
|
- type: Icon
|
||||||
|
state: pda-boxer
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BasePDA
|
parent: BasePDA
|
||||||
id: DetectivePDA
|
id: DetectivePDA
|
||||||
|
|||||||
@@ -511,6 +511,18 @@
|
|||||||
- type: PresetIdCard
|
- type: PresetIdCard
|
||||||
job: Reporter
|
job: Reporter
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: IDCardStandard
|
||||||
|
id: BoxerIDCard
|
||||||
|
name: boxer ID card
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: default
|
||||||
|
- state: idboxer
|
||||||
|
- type: PresetIdCard
|
||||||
|
job: Boxer
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: IDCardStandard
|
parent: IDCardStandard
|
||||||
id: DetectiveIDCard
|
id: DetectiveIDCard
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
Passenger: [ -1, -1 ]
|
Passenger: [ -1, -1 ]
|
||||||
Bartender: [ 1, 2 ]
|
Bartender: [ 1, 2 ]
|
||||||
Botanist: [ 2, 2 ]
|
Botanist: [ 2, 2 ]
|
||||||
|
Boxer: [ 2, 2 ] #Wildcard for this map
|
||||||
Chef: [ 2, 3 ]
|
Chef: [ 2, 3 ]
|
||||||
Clown: [ 1, 1 ]
|
Clown: [ 1, 1 ]
|
||||||
Janitor: [ 1, 2 ]
|
Janitor: [ 1, 2 ]
|
||||||
|
|||||||
32
Resources/Prototypes/Roles/Jobs/Wildcards/boxer.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
- type: job
|
||||||
|
id: Boxer
|
||||||
|
name: "boxer"
|
||||||
|
startingGear: BoxerGear
|
||||||
|
setPreference: false
|
||||||
|
departments:
|
||||||
|
- Civilian
|
||||||
|
icon: "Boxer"
|
||||||
|
supervisors: "the head of personnel"
|
||||||
|
access:
|
||||||
|
- Service
|
||||||
|
special:
|
||||||
|
- !type:AddComponentSpecial
|
||||||
|
components:
|
||||||
|
- type: Boxer
|
||||||
|
modifiers:
|
||||||
|
coefficients: #Remember these only apply to unarmed
|
||||||
|
Blunt: 1.5
|
||||||
|
Slash: 1.5
|
||||||
|
Piercing: 1.5
|
||||||
|
|
||||||
|
- type: startingGear
|
||||||
|
id: BoxerGear
|
||||||
|
equipment:
|
||||||
|
jumpsuit: UniformShortsRed
|
||||||
|
back: ClothingBackpackFilled
|
||||||
|
id: BoxerPDA
|
||||||
|
ears: ClothingHeadsetService
|
||||||
|
gloves: ClothingHandsGlovesBoxingRed
|
||||||
|
innerclothingskirt: UniformShortsRedWithTop
|
||||||
|
satchel: ClothingBackpackSatchelFilled
|
||||||
|
duffelbag: ClothingBackpackDuffelFilled
|
||||||
@@ -4,3 +4,10 @@
|
|||||||
- /Audio/Weapons/genhit1.ogg
|
- /Audio/Weapons/genhit1.ogg
|
||||||
- /Audio/Weapons/genhit2.ogg
|
- /Audio/Weapons/genhit2.ogg
|
||||||
- /Audio/Weapons/genhit3.ogg
|
- /Audio/Weapons/genhit3.ogg
|
||||||
|
|
||||||
|
- type: soundCollection
|
||||||
|
id: BoxingHit
|
||||||
|
files:
|
||||||
|
- /Audio/Weapons/boxingpunch1.ogg
|
||||||
|
- /Audio/Weapons/boxingpunch2.ogg
|
||||||
|
- /Audio/Weapons/boxingpunch3.ogg
|
||||||
|
|||||||
|
After Width: | Height: | Size: 531 B |
|
After Width: | Height: | Size: 265 B |
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "https://github.com/tgstation/tgstation/commit/beaea876ea426c0e215cee64619862dc19bd9cd8",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-INNERCLOTHING",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "https://github.com/tgstation/tgstation/commit/beaea876ea426c0e215cee64619862dc19bd9cd8",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-INNERCLOTHING",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Resources/Textures/Interface/Misc/job_icons.rsi/Boxer.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
@@ -16,6 +16,9 @@
|
|||||||
{
|
{
|
||||||
"name": "Botanist"
|
"name": "Botanist"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Boxer"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "AtmosphericTechnician"
|
"name": "AtmosphericTechnician"
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
Resources/Textures/Markers/jobs.rsi/boxer.png
Normal file
|
After Width: | Height: | Size: 734 B |
@@ -25,6 +25,9 @@
|
|||||||
{
|
{
|
||||||
"name": "botanist"
|
"name": "botanist"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "boxer"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "captain"
|
"name": "captain"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,6 +29,9 @@
|
|||||||
{
|
{
|
||||||
"name": "pda-bartender"
|
"name": "pda-bartender"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "pda-boxer"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "pda-captain"
|
"name": "pda-captain"
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
Resources/Textures/Objects/Devices/pda.rsi/pda-boxer.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
Resources/Textures/Objects/Misc/id_cards.rsi/idboxer.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
@@ -46,6 +46,9 @@
|
|||||||
{
|
{
|
||||||
"name": "idbotanist"
|
"name": "idbotanist"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "idboxer"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "idcaptain"
|
"name": "idcaptain"
|
||||||
},
|
},
|
||||||
|
|||||||