diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index 82b2e07b13..c45ca75acd 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -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(); diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 6e5f3b9efd..5d4a2e8495 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -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(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) diff --git a/Content.Server/White/Loadout/LoadoutPrototype.cs b/Content.Server/White/Loadout/LoadoutPrototype.cs new file mode 100644 index 0000000000..7f07c93f17 --- /dev/null +++ b/Content.Server/White/Loadout/LoadoutPrototype.cs @@ -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))] + public string EntityId { get; } = default!; + + // WD-Sponsors-Start + [DataField("sponsorOnly")] + public bool SponsorOnly = false; + // WD-Sponsors-End + + [DataField("whitelistJobs", customTypeSerializer: typeof(PrototypeIdListSerializer))] + public List? WhitelistJobs { get; } + + [DataField("blacklistJobs", customTypeSerializer: typeof(PrototypeIdListSerializer))] + public List? BlacklistJobs { get; } + + [DataField("speciesRestriction")] + public List? SpeciesRestrictions { get; } +} diff --git a/Content.Server/White/Loadout/LoadoutSystem.cs b/Content.Server/White/Loadout/LoadoutSystem.cs new file mode 100644 index 0000000000..df3379ff3b --- /dev/null +++ b/Content.Server/White/Loadout/LoadoutSystem.cs @@ -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(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(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(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); + } + } + } + } +} diff --git a/Content.Server/White/Other/EnergySword/DoubleSwordCraft.cs b/Content.Server/White/Other/EnergySword/DoubleSwordCraft.cs new file mode 100644 index 0000000000..a785efae33 --- /dev/null +++ b/Content.Server/White/Other/EnergySword/DoubleSwordCraft.cs @@ -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(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(args.Used).EntityPrototype!.ID; + var usedTo = _entityManager.GetComponent(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(player)?.Coordinates; + + if (transform == null) + return; + + var weaponEntity = _entityManager.SpawnEntity(EnergyDoubleSword, transform.Value); + _handsSystem.PickupOrDrop(player, weaponEntity); + } +} diff --git a/Content.Server/White/Other/EnergySword/DoubleSwordCraftComponent.cs b/Content.Server/White/Other/EnergySword/DoubleSwordCraftComponent.cs new file mode 100644 index 0000000000..0889949221 --- /dev/null +++ b/Content.Server/White/Other/EnergySword/DoubleSwordCraftComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Server.White.Other.EnergySword; + +[RegisterComponent] +public sealed class DoubleSwordCraftComponent : Component +{ +} diff --git a/Content.Server/White/Other/Lazy/EarsSpawnComponent.cs b/Content.Server/White/Other/Lazy/EarsSpawnComponent.cs new file mode 100644 index 0000000000..e43a788bf4 --- /dev/null +++ b/Content.Server/White/Other/Lazy/EarsSpawnComponent.cs @@ -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() + }; +} diff --git a/Content.Server/White/Other/Lazy/EarsSpawnSystem.cs b/Content.Server/White/Other/Lazy/EarsSpawnSystem.cs new file mode 100644 index 0000000000..a678685c67 --- /dev/null +++ b/Content.Server/White/Other/Lazy/EarsSpawnSystem.cs @@ -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>(AddSummonVerb); + SubscribeLocalEvent(GetSummonAction); + SubscribeLocalEvent(OnSummon); + } + + private const string Ears = "ClothingHeadHatCatEars"; + private const string UserNeededKey = "merkkaa"; + + private void AddSummonVerb(EntityUid uid, EarsSpawnComponent component, GetVerbsEvent 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(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(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 +{ +} diff --git a/Content.Server/White/Other/OnDeath.cs b/Content.Server/White/Other/OnDeath.cs new file mode 100644 index 0000000000..6bccbdb90c --- /dev/null +++ b/Content.Server/White/Other/OnDeath.cs @@ -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(HandleDeathEvent); + SubscribeLocalEvent(OnGhosted); + } + + private readonly Dictionary _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); + } + +} diff --git a/Resources/Locale/ru-RU/markings/cat.ftl b/Resources/Locale/ru-RU/markings/cat.ftl index c21792d3d2..fc9ad16452 100644 --- a/Resources/Locale/ru-RU/markings/cat.ftl +++ b/Resources/Locale/ru-RU/markings/cat.ftl @@ -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 = Демонический хвост diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index a070a55199..26a574213f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -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 diff --git a/Resources/Prototypes/SoundCollections/white.yml b/Resources/Prototypes/SoundCollections/white.yml new file mode 100644 index 0000000000..101633f733 --- /dev/null +++ b/Resources/Prototypes/SoundCollections/white.yml @@ -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 diff --git a/Resources/Prototypes/White/Fluff/fluff.yml b/Resources/Prototypes/White/Fluff/fluff.yml new file mode 100644 index 0000000000..b6956c071f --- /dev/null +++ b/Resources/Prototypes/White/Fluff/fluff.yml @@ -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 diff --git a/Resources/Prototypes/White/Fluff/sponsor.yml b/Resources/Prototypes/White/Fluff/sponsor.yml new file mode 100644 index 0000000000..50a7bedc22 --- /dev/null +++ b/Resources/Prototypes/White/Fluff/sponsor.yml @@ -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 diff --git a/Resources/Prototypes/White/Mobs/Customization/Markings/cat_parts.yml b/Resources/Prototypes/White/Mobs/Customization/Markings/cat_parts.yml new file mode 100644 index 0000000000..d61d9031b0 --- /dev/null +++ b/Resources/Prototypes/White/Mobs/Customization/Markings/cat_parts.yml @@ -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 diff --git a/Resources/Prototypes/White/Mobs/Customization/Markings/fox_parts.yml b/Resources/Prototypes/White/Mobs/Customization/Markings/fox_parts.yml new file mode 100644 index 0000000000..941d4cf2fe --- /dev/null +++ b/Resources/Prototypes/White/Mobs/Customization/Markings/fox_parts.yml @@ -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 diff --git a/Resources/Prototypes/White/Mobs/Customization/Markings/warete_parts.yml b/Resources/Prototypes/White/Mobs/Customization/Markings/warete_parts.yml new file mode 100644 index 0000000000..00c02ad11a --- /dev/null +++ b/Resources/Prototypes/White/Mobs/Customization/Markings/warete_parts.yml @@ -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 diff --git a/Resources/Prototypes/White/Mobs/Customization/Markings/wolf_parts.yml b/Resources/Prototypes/White/Mobs/Customization/Markings/wolf_parts.yml new file mode 100644 index 0000000000..56fae23a64 --- /dev/null +++ b/Resources/Prototypes/White/Mobs/Customization/Markings/wolf_parts.yml @@ -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 diff --git a/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/e_sword.png b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/e_sword.png new file mode 100644 index 0000000000..dac5aed98e Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/e_sword.png differ diff --git a/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/e_sword_blade.png b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/e_sword_blade.png new file mode 100644 index 0000000000..f73c0beeae Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/e_sword_blade.png differ diff --git a/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/icon.png b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/icon.png new file mode 100644 index 0000000000..f73c0beeae Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-left-blade.png b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-left-blade.png new file mode 100644 index 0000000000..0ce936e47d Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-left-blade.png differ diff --git a/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-left.png b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-left.png new file mode 100644 index 0000000000..e1f16d118b Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-right-blade.png b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-right-blade.png new file mode 100644 index 0000000000..0ce936e47d Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-right-blade.png differ diff --git a/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-right.png b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-right.png new file mode 100644 index 0000000000..fe248fdc6e Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/meta.json b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/meta.json new file mode 100644 index 0000000000..1860940661 --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Melee/double_esword.rsi/meta.json @@ -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 + ] + ] + } + ] +} diff --git a/Resources/White/Audio/Death/death.ogg b/Resources/White/Audio/Death/death.ogg new file mode 100644 index 0000000000..ae7c2b90c9 Binary files /dev/null and b/Resources/White/Audio/Death/death.ogg differ diff --git a/Resources/White/Audio/Death/death.wav b/Resources/White/Audio/Death/death.wav new file mode 100644 index 0000000000..dbd2948f2c Binary files /dev/null and b/Resources/White/Audio/Death/death.wav differ diff --git a/Resources/White/Audio/Death/death_alarm_legacy.ogg b/Resources/White/Audio/Death/death_alarm_legacy.ogg new file mode 100644 index 0000000000..a3b2b07d73 Binary files /dev/null and b/Resources/White/Audio/Death/death_alarm_legacy.ogg differ diff --git a/Resources/White/Audio/Heart/heart.ogg b/Resources/White/Audio/Heart/heart.ogg new file mode 100644 index 0000000000..ecff18cb25 Binary files /dev/null and b/Resources/White/Audio/Heart/heart.ogg differ diff --git a/Resources/White/Audio/Heart/heart2.wav b/Resources/White/Audio/Heart/heart2.wav new file mode 100644 index 0000000000..a38293f53d Binary files /dev/null and b/Resources/White/Audio/Heart/heart2.wav differ diff --git a/Resources/White/Audio/Heart/heart3.ogg b/Resources/White/Audio/Heart/heart3.ogg new file mode 100644 index 0000000000..31fa3dc349 Binary files /dev/null and b/Resources/White/Audio/Heart/heart3.ogg differ diff --git a/Resources/White/Audio/Heart/heart4.ogg b/Resources/White/Audio/Heart/heart4.ogg new file mode 100644 index 0000000000..de30bd61fc Binary files /dev/null and b/Resources/White/Audio/Heart/heart4.ogg differ