[feat] Loadout, DeathGasps, EnergyDoubleCraftSystem
@@ -130,6 +130,10 @@ namespace Content.Client.Entry
|
||||
_prototypeManager.RegisterIgnore("alertLevels");
|
||||
_prototypeManager.RegisterIgnore("nukeopsRole");
|
||||
|
||||
//WD-EDIT
|
||||
_prototypeManager.RegisterIgnore("loadout");
|
||||
//WD-EDIT
|
||||
|
||||
_componentFactory.GenerateNetIds();
|
||||
_adminManager.Initialize();
|
||||
_screenshotHook.Initialize();
|
||||
|
||||
@@ -179,7 +179,8 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
ICommonSession? player = null,
|
||||
string? nameOverride = null,
|
||||
bool checkRadioPrefix = true,
|
||||
bool ignoreActionBlocker = false
|
||||
bool ignoreActionBlocker = false,
|
||||
bool force = false
|
||||
)
|
||||
{
|
||||
if (HasComp<GhostComponent>(source))
|
||||
@@ -201,7 +202,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanSendInGame(message, shell, player))
|
||||
if (!force && !CanSendInGame(message, shell, player))
|
||||
return;
|
||||
|
||||
ignoreActionBlocker = CheckIgnoreSpeechBlocker(source, ignoreActionBlocker);
|
||||
@@ -233,9 +234,9 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
message = SanitizeInGameICMessage(source, message, out var emoteStr, shouldCapitalize, shouldPunctuate, sanitizeSlang);
|
||||
|
||||
// Was there an emote in the message? If so, send it.
|
||||
if (player != null && emoteStr != message && emoteStr != null)
|
||||
if (emoteStr != message && emoteStr != null)
|
||||
{
|
||||
SendEntityEmote(source, emoteStr, range, nameOverride, ignoreActionBlocker);
|
||||
SendEntityEmote(source, emoteStr, range, nameOverride, ignoreActionBlocker, force: force);
|
||||
}
|
||||
|
||||
// This can happen if the entire string is sanitized out.
|
||||
@@ -262,7 +263,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker);
|
||||
break;
|
||||
case InGameICChatType.Emote:
|
||||
SendEntityEmote(source, message, range, nameOverride, hideLog: hideLog, ignoreActionBlocker: ignoreActionBlocker);
|
||||
SendEntityEmote(source, message, range, nameOverride, hideLog: hideLog, ignoreActionBlocker: ignoreActionBlocker, force: force);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -566,7 +567,8 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
bool hideLog = false,
|
||||
bool checkEmote = true,
|
||||
bool ignoreActionBlocker = false,
|
||||
NetUserId? author = null
|
||||
NetUserId? author = null,
|
||||
bool force = false
|
||||
)
|
||||
{
|
||||
if (!_actionBlocker.CanEmote(source) && !ignoreActionBlocker)
|
||||
|
||||
29
Content.Server/White/Loadout/LoadoutPrototype.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
|
||||
namespace Content.Server.White.Loadout;
|
||||
|
||||
[Prototype("loadout")]
|
||||
public sealed class LoadoutItemPrototype : IPrototype
|
||||
{
|
||||
[IdDataFieldAttribute] public string ID { get; } = default!;
|
||||
|
||||
[DataField("entity", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string EntityId { get; } = default!;
|
||||
|
||||
// WD-Sponsors-Start
|
||||
[DataField("sponsorOnly")]
|
||||
public bool SponsorOnly = false;
|
||||
// WD-Sponsors-End
|
||||
|
||||
[DataField("whitelistJobs", customTypeSerializer: typeof(PrototypeIdListSerializer<JobPrototype>))]
|
||||
public List<string>? WhitelistJobs { get; }
|
||||
|
||||
[DataField("blacklistJobs", customTypeSerializer: typeof(PrototypeIdListSerializer<JobPrototype>))]
|
||||
public List<string>? BlacklistJobs { get; }
|
||||
|
||||
[DataField("speciesRestriction")]
|
||||
public List<string>? SpeciesRestrictions { get; }
|
||||
}
|
||||
97
Content.Server/White/Loadout/LoadoutSystem.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System.Linq;
|
||||
using Content.Server.White.Sponsors;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Server.Storage.EntitySystems;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.White.Loadout;
|
||||
|
||||
// NOTE: Full implementation will be in future, now just sponsor items
|
||||
public sealed class LoadoutSystem : EntitySystem
|
||||
{
|
||||
private const string BackpackSlotId = "back";
|
||||
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
[Dependency] private readonly HandsSystem _handsSystem = default!;
|
||||
[Dependency] private readonly StorageSystem _storageSystem = default!;
|
||||
[Dependency] private readonly SponsorsManager _sponsorsManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(OnPlayerSpawned);
|
||||
}
|
||||
|
||||
private void OnPlayerSpawned(PlayerSpawnCompleteEvent ev)
|
||||
{
|
||||
if (_sponsorsManager.TryGetInfo(ev.Player.UserId, out var sponsor))
|
||||
{
|
||||
foreach (var loadoutId in sponsor.AllowedMarkings)
|
||||
{
|
||||
// NOTE: Now is easy to not extract method because event give all info we need
|
||||
if (_prototypeManager.TryIndex<LoadoutItemPrototype>(loadoutId, out var loadout))
|
||||
{
|
||||
var isSponsorOnly = loadout.SponsorOnly &&
|
||||
!sponsor.AllowedMarkings.Contains(loadoutId);
|
||||
var isWhitelisted = ev.JobId != null &&
|
||||
loadout.WhitelistJobs != null &&
|
||||
!loadout.WhitelistJobs.Contains(ev.JobId);
|
||||
var isBlacklisted = ev.JobId != null &&
|
||||
loadout.BlacklistJobs != null &&
|
||||
loadout.BlacklistJobs.Contains(ev.JobId);
|
||||
var isSpeciesRestricted = loadout.SpeciesRestrictions != null &&
|
||||
loadout.SpeciesRestrictions.Contains(ev.Profile.Species);
|
||||
|
||||
if (isSponsorOnly || isWhitelisted || isBlacklisted || isSpeciesRestricted)
|
||||
continue;
|
||||
|
||||
var entity = Spawn(loadout.EntityId, Transform(ev.Mob).Coordinates);
|
||||
|
||||
// Take in hand if not clothes
|
||||
if (!TryComp<ClothingComponent>(entity, out var clothing))
|
||||
{
|
||||
_handsSystem.TryPickup(ev.Mob, entity);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Automatically search empty slot for clothes to equip
|
||||
string? firstSlotName = null;
|
||||
bool isEquiped = false;
|
||||
foreach (var slot in _inventorySystem.GetSlots(ev.Mob))
|
||||
{
|
||||
if (!clothing.Slots.HasFlag(slot.SlotFlags))
|
||||
continue;
|
||||
|
||||
if (firstSlotName == null)
|
||||
firstSlotName = slot.Name;
|
||||
|
||||
if (_inventorySystem.TryGetSlotEntity(ev.Mob, slot.Name, out var _))
|
||||
continue;
|
||||
|
||||
if (_inventorySystem.TryEquip(ev.Mob, entity, slot.Name, true))
|
||||
{
|
||||
isEquiped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEquiped || firstSlotName == null)
|
||||
continue;
|
||||
|
||||
// Force equip to first valid clothes slot
|
||||
// Get occupied entity -> Insert to backpack -> Equip loadout entity
|
||||
if (_inventorySystem.TryGetSlotEntity(ev.Mob, firstSlotName, out var slotEntity) &&
|
||||
_inventorySystem.TryGetSlotEntity(ev.Mob, BackpackSlotId, out var backEntity) &&
|
||||
_storageSystem.CanInsert(backEntity.Value, slotEntity.Value, out _))
|
||||
{
|
||||
_storageSystem.Insert(backEntity.Value, slotEntity.Value);
|
||||
}
|
||||
_inventorySystem.TryEquip(ev.Mob, entity, firstSlotName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Content.Server/White/Other/EnergySword/DoubleSwordCraft.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server.White.Other.EnergySword;
|
||||
|
||||
public sealed class EnergyDoubleSwordCraftSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<DoubleSwordCraftComponent, InteractUsingEvent>(Combine);
|
||||
}
|
||||
|
||||
private const string NeededEnt = "EnergySword";
|
||||
private const string EnergyDoubleSword = "EnergyDoubleSword";
|
||||
|
||||
private void Combine(EntityUid uid, DoubleSwordCraftComponent component, InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
var user = args.User;
|
||||
var usedEnt = _entityManager.GetComponent<MetaDataComponent>(args.Used).EntityPrototype!.ID;
|
||||
var usedTo = _entityManager.GetComponent<MetaDataComponent>(uid).EntityPrototype!.ID;
|
||||
|
||||
if (usedTo is EnergyDoubleSword)
|
||||
return;
|
||||
|
||||
if (usedEnt != NeededEnt || usedTo != NeededEnt)
|
||||
return;
|
||||
|
||||
DeleteUsed(args.Used, uid);
|
||||
SpawnEnergyDoubleSword(user);
|
||||
}
|
||||
|
||||
|
||||
private void DeleteUsed(EntityUid itemA, EntityUid itemB)
|
||||
{
|
||||
_entityManager.DeleteEntity(itemA);
|
||||
_entityManager.DeleteEntity(itemB);
|
||||
}
|
||||
|
||||
private void SpawnEnergyDoubleSword(EntityUid player)
|
||||
{
|
||||
var transform = CompOrNull<TransformComponent>(player)?.Coordinates;
|
||||
|
||||
if (transform == null)
|
||||
return;
|
||||
|
||||
var weaponEntity = _entityManager.SpawnEntity(EnergyDoubleSword, transform.Value);
|
||||
_handsSystem.PickupOrDrop(player, weaponEntity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Content.Server.White.Other.EnergySword;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class DoubleSwordCraftComponent : Component
|
||||
{
|
||||
}
|
||||
16
Content.Server/White/Other/Lazy/EarsSpawnComponent.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Content.Shared.Actions.ActionTypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.White.Other.Lazy;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class EarsSpawnComponent : Component
|
||||
{
|
||||
[DataField("summonAction")] public InstantAction SummonAction = new()
|
||||
{
|
||||
Icon = new SpriteSpecifier.Texture(new ResPath("Clothing/Head/Hats/witch.rsi/icon.png")),
|
||||
DisplayName = "summon cat ears",
|
||||
Description = "meow!",
|
||||
Event = new SummonActionEarsEvent()
|
||||
};
|
||||
}
|
||||
88
Content.Server/White/Other/Lazy/EarsSpawnSystem.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
namespace Content.Server.White.Other.Lazy;
|
||||
|
||||
public sealed class EarsSpawnSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<EarsSpawnComponent, GetVerbsEvent<AlternativeVerb>>(AddSummonVerb);
|
||||
SubscribeLocalEvent<EarsSpawnComponent, GetItemActionsEvent>(GetSummonAction);
|
||||
SubscribeLocalEvent<EarsSpawnComponent, SummonActionEarsEvent>(OnSummon);
|
||||
}
|
||||
|
||||
private const string Ears = "ClothingHeadHatCatEars";
|
||||
private const string UserNeededKey = "merkkaa";
|
||||
|
||||
private void AddSummonVerb(EntityUid uid, EarsSpawnComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (!args.CanInteract || !args.CanAccess)
|
||||
return;
|
||||
|
||||
AlternativeVerb verb = new()
|
||||
{
|
||||
Act = () =>
|
||||
{
|
||||
AttemptSummon(component, args.User);
|
||||
},
|
||||
Text = Loc.GetString("summon cat ears"),
|
||||
Priority = 2
|
||||
};
|
||||
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
private void OnSummon(EntityUid uid, EarsSpawnComponent component, SummonActionEarsEvent args)
|
||||
{
|
||||
AttemptSummon(component, args.Performer);
|
||||
}
|
||||
|
||||
private void AttemptSummon(EarsSpawnComponent component, EntityUid user)
|
||||
{
|
||||
if (!_blocker.CanInteract(user, component.Owner))
|
||||
return;
|
||||
|
||||
if (TryComp<ActorComponent>(user, out var actorComponent))
|
||||
{
|
||||
var userKey = actorComponent.PlayerSession.Name;
|
||||
if (userKey != UserNeededKey)
|
||||
{
|
||||
_popupSystem.PopupEntity("Вы не являетесь потомком кошко-богини.", user, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SpawnEars(user);
|
||||
}
|
||||
|
||||
private void SpawnEars(EntityUid player)
|
||||
{
|
||||
var transform = CompOrNull<TransformComponent>(player)?.Coordinates;
|
||||
|
||||
if (transform == null)
|
||||
return;
|
||||
|
||||
var ears = _entityManager.SpawnEntity(Ears, transform.Value);
|
||||
_handsSystem.PickupOrDrop(player, ears);
|
||||
}
|
||||
|
||||
private static void GetSummonAction(EntityUid uid, EarsSpawnComponent component, GetItemActionsEvent args)
|
||||
{
|
||||
args.Actions.Add(component.SummonAction);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SummonActionEarsEvent : InstantActionEvent
|
||||
{
|
||||
}
|
||||
98
Content.Server/White/Other/OnDeath.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Ghost.Components;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Mobs;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.White.Other;
|
||||
|
||||
public sealed class OnDeath : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<HumanoidAppearanceComponent, MobStateChangedEvent>(HandleDeathEvent);
|
||||
SubscribeLocalEvent<GhostComponent, ComponentInit>(OnGhosted);
|
||||
}
|
||||
|
||||
private readonly Dictionary<EntityUid, IPlayingAudioStream> _playingStreams = new();
|
||||
private static readonly SoundSpecifier DeathSounds = new SoundCollectionSpecifier("deathSounds");
|
||||
private static readonly SoundSpecifier HeartSounds = new SoundCollectionSpecifier("heartSounds");
|
||||
private static readonly string[] DeathGaspMessages =
|
||||
{
|
||||
"death-gasp-high",
|
||||
"death-gasp-medium",
|
||||
"death-gasp-normal"
|
||||
};
|
||||
|
||||
private void HandleDeathEvent(EntityUid uid, HumanoidAppearanceComponent component, MobStateChangedEvent args)
|
||||
{
|
||||
//^.^
|
||||
switch (args.NewMobState)
|
||||
{
|
||||
case MobState.Invalid:
|
||||
StopPlayingStream(uid);
|
||||
break;
|
||||
case MobState.Alive:
|
||||
StopPlayingStream(uid);
|
||||
break;
|
||||
case MobState.Critical:
|
||||
PlayPlayingStream(uid);
|
||||
break;
|
||||
case MobState.Dead:
|
||||
StopPlayingStream(uid);
|
||||
var deathGaspMessage = SelectRandomDeathGaspMessage();
|
||||
var localizedMessage = LocalizeDeathGaspMessage(deathGaspMessage);
|
||||
SendDeathGaspMessage(uid, localizedMessage);
|
||||
PlayDeathSound(uid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void PlayPlayingStream(EntityUid uid)
|
||||
{
|
||||
if (_playingStreams.TryGetValue(uid, out var currentStream))
|
||||
{
|
||||
currentStream.Stop();
|
||||
}
|
||||
|
||||
var newStream = _audio.PlayEntity(HeartSounds, uid, uid, AudioParams.Default.WithLoop(true));
|
||||
if (newStream != null)
|
||||
{
|
||||
_playingStreams[uid] = newStream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void StopPlayingStream(EntityUid uid)
|
||||
{
|
||||
if (_playingStreams.TryGetValue(uid, out var currentStream))
|
||||
{
|
||||
currentStream.Stop();
|
||||
_playingStreams.Remove(uid);
|
||||
}
|
||||
}
|
||||
|
||||
private string SelectRandomDeathGaspMessage()
|
||||
=> DeathGaspMessages[_random.Next(DeathGaspMessages.Length)];
|
||||
|
||||
private string LocalizeDeathGaspMessage(string message)
|
||||
=> Loc.GetString(message);
|
||||
|
||||
private void SendDeathGaspMessage(EntityUid uid, string message)
|
||||
=> _chat.TrySendInGameICMessage(uid, message, InGameICChatType.Emote, false, force: true);
|
||||
|
||||
private void PlayDeathSound(EntityUid uid)
|
||||
=> _audio.PlayEntity(DeathSounds, uid, uid, AudioParams.Default);
|
||||
|
||||
private void OnGhosted(EntityUid uid, GhostComponent component, ComponentInit args)
|
||||
{
|
||||
StopPlayingStream(uid);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,3 +31,5 @@ marking-FoxEarsMaury-ears_fox_tip = Градиент
|
||||
marking-CatTailDouble = Двойной хвост
|
||||
marking-CatTailDouble-double_tail_cat_back = Первый хвост
|
||||
marking-CatTailDouble-double_tail_cat_front = Второй хвост
|
||||
|
||||
marking-DemonTailWarete = Демонический хвост
|
||||
|
||||
@@ -213,70 +213,29 @@
|
||||
shader: unshaded
|
||||
|
||||
- type: entity
|
||||
name: Double Bladed Energy Sword
|
||||
name: double energy sword
|
||||
parent: EnergySword
|
||||
id: EnergySwordDouble
|
||||
description: Syndicate Command Interns thought that having one blade on the energy sword was not enough. This can be stored in pockets.
|
||||
id: EnergyDoubleSword
|
||||
description: A very dangerous doubled energy sword. Can be stored in pockets when turned off. Makes a lot of noise when used or turned on.
|
||||
components:
|
||||
- type: EnergySword
|
||||
- type: ItemToggle
|
||||
soundActivate:
|
||||
path: /Audio/Weapons/ebladeon.ogg
|
||||
params:
|
||||
volume: 3
|
||||
soundDeactivate:
|
||||
path: /Audio/Weapons/ebladeoff.ogg
|
||||
params:
|
||||
volume: 3
|
||||
- type: ItemToggleMeleeWeapon
|
||||
activatedSoundOnSwing:
|
||||
path: /Audio/Weapons/eblademiss.ogg
|
||||
params:
|
||||
volume: 3
|
||||
variation: 0.250
|
||||
activatedDamage:
|
||||
- type: Sprite
|
||||
sprite: Objects/Weapons/Melee/double_esword.rsi
|
||||
layers:
|
||||
- state: e_sword
|
||||
- state: e_sword_blade
|
||||
visible: false
|
||||
shader: unshaded
|
||||
map: [ "blade" ]
|
||||
- type: Wieldable
|
||||
- type: IncreaseDamageOnWield
|
||||
damage:
|
||||
types:
|
||||
Slash: 12
|
||||
Heat: 12
|
||||
Structural: 15
|
||||
- type: ItemToggleActiveSound
|
||||
activeSound:
|
||||
path: /Audio/Weapons/ebladehum.ogg
|
||||
params:
|
||||
volume: 3
|
||||
- type: ItemToggleDisarmMalus
|
||||
activatedDisarmMalus: 0.7
|
||||
- type: Wieldable
|
||||
- type: MeleeWeapon
|
||||
wideAnimationRotation: -135
|
||||
attackRate: 1.5
|
||||
angle: 100
|
||||
damage:
|
||||
types:
|
||||
Blunt: 4.5
|
||||
- type: Sprite
|
||||
sprite: Objects/Weapons/Melee/e_sword_double.rsi
|
||||
layers:
|
||||
- state: e_sword_double
|
||||
- state: e_sword_double_blade
|
||||
color: "#FFFFFF"
|
||||
visible: false
|
||||
shader: unshaded
|
||||
map: [ "blade" ]
|
||||
- type: Item
|
||||
size: Small
|
||||
sprite: Objects/Weapons/Melee/e_sword_double-inhands.rsi
|
||||
- type: Reflect
|
||||
reflectProb: .75
|
||||
spread: 75
|
||||
- type: UseDelay
|
||||
delay: 1
|
||||
- type: ToggleableLightVisuals
|
||||
spriteLayer: blade
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: inhand-left-blade
|
||||
shader: unshaded
|
||||
right:
|
||||
- state: inhand-right-blade
|
||||
shader: unshaded
|
||||
Slash: 15
|
||||
Heat: 13
|
||||
- type: MeleeWeapon
|
||||
attackRate: 1
|
||||
- type: Reflect
|
||||
enabled: false
|
||||
energeticChance: 0.7
|
||||
kineticChance: 0.7
|
||||
spread: 45
|
||||
|
||||
13
Resources/Prototypes/SoundCollections/white.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
- type: soundCollection
|
||||
id: deathSounds
|
||||
files:
|
||||
- /White/Audio/Death/death.ogg
|
||||
- /White/Audio/Death/death.wav
|
||||
|
||||
- type: soundCollection
|
||||
id: heartSounds
|
||||
files:
|
||||
- /White/Audio/Heart/heart.ogg
|
||||
- /White/Audio/Heart/heart2.wav
|
||||
- /White/Audio/Heart/heart3.ogg
|
||||
- /White/Audio/Heart/heart4.ogg
|
||||
112
Resources/Prototypes/White/Fluff/fluff.yml
Normal file
@@ -0,0 +1,112 @@
|
||||
# DOOMMAX
|
||||
- type: entity
|
||||
parent: ClothingOuterEVASuitBase
|
||||
id: ClothingOuterSuitGlamorous
|
||||
name: glamorous suit
|
||||
description: An emergency suit in cases of... emergencies. But glamorous.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Fluff/DOOMMAX/glamorous.rsi
|
||||
- type: Clothing
|
||||
sprite: White/Fluff/DOOMMAX/glamorous.rsi
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.7
|
||||
sprintModifier: 0.7
|
||||
- type: TemperatureProtection
|
||||
coefficient: 0.7
|
||||
- type: ToggleableClothing
|
||||
clothingPrototype: ClothingHeadHelmetEVA
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
|
||||
- type: entity
|
||||
parent: ClothingOuterHardsuitEVA
|
||||
id: ClothingOuterHardsuitEVAGLAMOUR
|
||||
name: скафандр EVA GLAMOUR
|
||||
description: Улучшеный Скафандр Гламура! Модный, стильный, совершенный! Способен защитить вас от космического вакуума. В этом скафандре все главы будут ваши. На скафандре подписан владелец - Алина Бэккен.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Fluff/DOOMMAX/evaglamour.rsi
|
||||
- type: Clothing
|
||||
sprite: White/Fluff/DOOMMAX/evaglamour.rsi
|
||||
- type: ToggleableClothing
|
||||
clothingPrototype: ClothingHeadHelmetEVAGLAMOUR
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot { }
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHeadHelmetEVA
|
||||
id: ClothingHeadHelmetEVAGLAMOUR
|
||||
name: шлем EVA GLAMOUR
|
||||
description: Гламурный вариант шлема EVA.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Fluff/DOOMMAX/helmetglamour.rsi
|
||||
- type: Clothing
|
||||
sprite: White/Fluff/DOOMMAX/helmetglamour.rsi
|
||||
|
||||
# Maury
|
||||
- type: entity
|
||||
parent: ClothingUniformJumpsuitChemistry
|
||||
id: ClothingUniformJumpsuitMauryZ #Should be ClothingUniformJumpsuitMaury but i`m retard and lazy idiot
|
||||
name: Rupi's chemist uniform
|
||||
description: Обычно NanoTrasen не позволяет сотрудникам изменять выданную им униформу, но по отношению к Руперту они проявили снисходительность.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Fluff/Maury/chemshit.rsi
|
||||
- type: Clothing
|
||||
sprite: White/Fluff/Maury/chemshit.rsi
|
||||
|
||||
# YouWellLeer
|
||||
- type: entity
|
||||
parent: Crowbar
|
||||
id: Sledgebar
|
||||
name: Mjolnir
|
||||
description: Отлично ломает кости ассистентам и клоуну.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Fluff/YouWellLeer/sledgebar.rsi
|
||||
state: icon
|
||||
netsync: false
|
||||
- type: Item
|
||||
sprite: White/Fluff/YouWellLeer/sledgebar.rsi
|
||||
size: 30
|
||||
- type: Wieldable
|
||||
- type: IncreaseDamageOnWield
|
||||
damage:
|
||||
types:
|
||||
Blunt: 10
|
||||
|
||||
# merkkaa
|
||||
- type: entity
|
||||
parent: Bible
|
||||
name: няко библия
|
||||
description: Книга является заметками кошко богини. Её потомки используют эту книгу как Библию.
|
||||
id: BibleNya
|
||||
components:
|
||||
- type: EarsSpawn
|
||||
- type: Sprite
|
||||
netsync: false
|
||||
sprite: White/Fluff/merkkaa/bible.rsi
|
||||
state: icon
|
||||
- type: Item
|
||||
size: 10
|
||||
sprite: White/Fluff/merkkaa/bible.rsi
|
||||
- type: PointLight
|
||||
radius: 2
|
||||
energy: 2
|
||||
color: pink
|
||||
|
||||
# Warete
|
||||
- type: entity
|
||||
parent: ClothingUniformBase
|
||||
id: WareteJumpskirt
|
||||
name: репонит
|
||||
description: Жаростойкая куртка. С предупреждением о возможной взрывоопасности.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Fluff/Warete/warete_jumpsuit.rsi
|
||||
- type: Clothing
|
||||
sprite: White/Fluff/Warete/warete_jumpsuit.rsi
|
||||
41
Resources/Prototypes/White/Fluff/sponsor.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
# DOOMMAX
|
||||
- type: loadout
|
||||
id: SuitGlamorousLoadout
|
||||
entity: ClothingOuterSuitGlamorous
|
||||
sponsorOnly: true
|
||||
blacklistJobs: [Captain, HeadOfPersonnel, ChiefEngineer, ChiefMedicalOfficer, ResearchDirector, HeadOfSecurity, Quartermaster]
|
||||
|
||||
- type: loadout
|
||||
id: ClothingOuterHardsuitEVAGLAMOURsLoadout
|
||||
entity: ClothingOuterHardsuitEVAGLAMOUR
|
||||
sponsorOnly: true
|
||||
whitelistJobs: [Captain, HeadOfPersonnel, ChiefEngineer, ChiefMedicalOfficer, ResearchDirector, HeadOfSecurity, Quartermaster]
|
||||
|
||||
# Maury
|
||||
- type: loadout
|
||||
id: ClothingUniformJumpsuitMaury #Should be ClothingUniformMauryLoadout but like i said i`m retard
|
||||
entity: ClothingUniformJumpsuitMauryZ
|
||||
sponsorOnly: true
|
||||
|
||||
# YouWellLeer
|
||||
- type: loadout
|
||||
id: SledgebarLoadout
|
||||
entity: Sledgebar
|
||||
sponsorOnly: true
|
||||
|
||||
# мурка
|
||||
- type: loadout
|
||||
id: BibleNyaLoadout
|
||||
entity: BibleNya
|
||||
sponsorOnly: true
|
||||
|
||||
- type: loadout # WHITEGPT HUETA ДЛЯ КЛОУНОВ И ВЫШЕ
|
||||
id: WhiteGPTLoadout
|
||||
entity: PersonalNeuralAI
|
||||
sponsorOnly: true
|
||||
|
||||
# Warete
|
||||
- type: loadout
|
||||
id: WareteJumpskirtLoadout
|
||||
entity: WareteJumpskirt
|
||||
sponsorOnly: true
|
||||
@@ -0,0 +1,34 @@
|
||||
- type: marking
|
||||
id: CatTailStripes
|
||||
bodyPart: Tail
|
||||
markingCategory: Tail
|
||||
speciesRestriction: [Human]
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/cat_parts.rsi
|
||||
state: tail_cat_wag_stripes_prime
|
||||
- sprite: White/Mobs/Customization/cat_parts.rsi
|
||||
state: tail_cat_wag_stripes_second
|
||||
|
||||
- type: marking
|
||||
id: CatTailMaury
|
||||
bodyPart: Tail
|
||||
markingCategory: Tail
|
||||
speciesRestriction: [Human]
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/cat_parts.rsi
|
||||
state: tail_cat_wag_z
|
||||
- sprite: White/Mobs/Customization/cat_parts.rsi
|
||||
state: tail_cat_wag_tip
|
||||
|
||||
- type: marking
|
||||
id: CatTailDouble
|
||||
bodyPart: Tail
|
||||
markingCategory: Tail
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/double_cat.rsi
|
||||
state: double_tail_cat_back
|
||||
- sprite: White/Mobs/Customization/double_cat.rsi
|
||||
state: double_tail_cat_front
|
||||
@@ -0,0 +1,25 @@
|
||||
- type: marking
|
||||
id: FoxEars
|
||||
bodyPart: HeadTop
|
||||
markingCategory: HeadTop
|
||||
speciesRestriction: [Human]
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/fox_parts.rsi
|
||||
state: ears_fox_outer
|
||||
- sprite: White/Mobs/Customization/fox_parts.rsi
|
||||
state: ears_fox_inner
|
||||
|
||||
- type: marking
|
||||
id: FoxEarsMaury
|
||||
bodyPart: HeadTop
|
||||
markingCategory: HeadTop
|
||||
speciesRestriction: [Human]
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/fox_parts.rsi
|
||||
state: ears_fox_outer
|
||||
- sprite: White/Mobs/Customization/fox_parts.rsi
|
||||
state: ears_fox_inner
|
||||
- sprite: White/Mobs/Customization/fox_parts.rsi
|
||||
state: ears_fox_tip
|
||||
@@ -0,0 +1,19 @@
|
||||
- type: marking
|
||||
id: DemonHairWarete
|
||||
bodyPart: Hair
|
||||
markingCategory: HeadTop
|
||||
speciesRestriction: [ Human ]
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/warete_hair.rsi
|
||||
state: hair
|
||||
|
||||
- type: marking
|
||||
id: DemonTailWarete
|
||||
bodyPart: Tail
|
||||
markingCategory: Tail
|
||||
speciesRestriction: [Human]
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/demon_tail.rsi
|
||||
state: tail
|
||||
@@ -0,0 +1,22 @@
|
||||
#YouWellLeer
|
||||
- type: marking
|
||||
id: WolfEarsLeer
|
||||
bodyPart: HeadTop
|
||||
markingCategory: HeadTop
|
||||
speciesRestriction: [ Human ]
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/wolf_parts.rsi
|
||||
state: wolf_ears_outer
|
||||
- sprite: White/Mobs/Customization/wolf_parts.rsi
|
||||
state: wolf_ears_inner
|
||||
|
||||
- type: marking
|
||||
id: WolfTailLeer
|
||||
bodyPart: Tail
|
||||
markingCategory: Tail
|
||||
speciesRestriction: [Human]
|
||||
sponsorOnly: true
|
||||
sprites:
|
||||
- sprite: White/Mobs/Customization/wolf_parts.rsi
|
||||
state: wolf_tail
|
||||
|
After Width: | Height: | Size: 231 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 447 B |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 464 B |
@@ -0,0 +1,184 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "icon",
|
||||
"delays": [
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "e_sword"
|
||||
},
|
||||
{
|
||||
"name": "inhand-left",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "inhand-right",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "e_sword_blade",
|
||||
"delays": [
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inhand-left-blade",
|
||||
"directions": 4,
|
||||
"delays": [
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
],
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
],
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
],
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inhand-right-blade",
|
||||
"directions": 4,
|
||||
"delays": [
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
],
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
],
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
],
|
||||
[
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15,
|
||||
0.15,
|
||||
0.05,
|
||||
0.1,
|
||||
0.1,
|
||||
0.05,
|
||||
0.15
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||