diff --git a/Content.Client/_Goobstation/VehicleSystem.cs b/Content.Client/_Goobstation/VehicleSystem.cs new file mode 100644 index 00000000000..2d0575c1f5c --- /dev/null +++ b/Content.Client/_Goobstation/VehicleSystem.cs @@ -0,0 +1,105 @@ +using System.Numerics; +using System.Collections.Generic; +using Robust.Shared.Maths; +using Robust.Shared.Physics.Components; +using Robust.Shared.Physics.Systems; +using Robust.Shared.GameObjects; +using Content.Shared.Vehicles; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; + +namespace Content.Client.Vehicles; + +public sealed class VehicleSystem : SharedVehicleSystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly IEyeManager _eye = default!; + [Dependency] private readonly SpriteSystem _sprites = default!; + + private const float FreezeRotationSpeed = 3f; + private readonly Dictionary _lastRotation = new(); + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAppearanceChange); + SubscribeLocalEvent(OnMove); + SubscribeLocalEvent(OnShutdown); + } + + private void OnAppearanceChange(EntityUid uid, VehicleComponent comp, ref AppearanceChangeEvent args) + { + if (args.Sprite == null) + return; + + if (!_appearance.TryGetData(uid, VehicleState.Animated, out var animated)) + return; + + if (!TryComp(uid, out var spriteComp)) + return; + + SpritePos(uid, comp); + spriteComp.LayerSetAutoAnimated(0, animated); + } + + private void OnMove(EntityUid uid, VehicleComponent component, ref MoveEvent args) + { + SpritePos(uid, component); + + if (!TryComp(uid, out var physics)) + return; + + if (!TryComp(uid, out var xform)) + return; + + var speed = physics.LinearVelocity.Length(); + + if (!_lastRotation.ContainsKey(uid)) + _lastRotation[uid] = xform.LocalRotation; + + if (speed >= FreezeRotationSpeed) + { + xform.LocalRotation = _lastRotation[uid]; + } + else + { + _lastRotation[uid] = xform.LocalRotation; + } + } + + private void OnShutdown(EntityUid uid, VehicleComponent comp, ComponentShutdown args) + { + _lastRotation.Remove(uid); + } + + private void SpritePos(EntityUid uid, VehicleComponent comp) + { + if (!TryComp(uid, out var spriteComp)) + return; + + if (!_appearance.TryGetData(uid, VehicleState.DrawOver, out var depth)) + return; + + spriteComp.DrawDepth = (int)Content.Shared.DrawDepth.DrawDepth.Objects; + + if (comp.RenderOver == VehicleRenderOver.None) + return; + + var eye = _eye.CurrentEye; + var vehicleDir = (Transform(uid).LocalRotation + eye.Rotation).GetCardinalDir(); + var renderOver = (VehicleRenderOver)(1 << (int)vehicleDir); + + if ((comp.RenderOver & renderOver) == renderOver) + { + spriteComp.DrawDepth = (int)Content.Shared.DrawDepth.DrawDepth.OverMobs; + } + else if (depth) + { + spriteComp.DrawDepth = (int)Content.Shared.DrawDepth.DrawDepth.OverMobs; + } + else + { + spriteComp.DrawDepth = (int)Content.Shared.DrawDepth.DrawDepth.Objects; + } + } +} diff --git a/Content.Server/Mech/Systems/MechSystem.cs b/Content.Server/Mech/Systems/MechSystem.cs index b7bbc4ad473..0bd1fff6fe5 100644 --- a/Content.Server/Mech/Systems/MechSystem.cs +++ b/Content.Server/Mech/Systems/MechSystem.cs @@ -23,10 +23,18 @@ using Robust.Shared.Containers; using Robust.Shared.Player; using Content.Shared.Whitelist; - +// Forge-Change-start +using Content.Shared.Actions; +using Robust.Shared.Audio.Systems; +using Content.Shared.Implants.Components; // for IgnitionKey? Might need a new component +using Content.Shared.Vehicles; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; +using Content.Shared.Atmos; +using Content.Shared.Hands.EntitySystems; +// Forge-Change-end namespace Content.Server.Mech.Systems; -/// public sealed partial class MechSystem : SharedMechSystem { [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; @@ -39,6 +47,12 @@ public sealed partial class MechSystem : SharedMechSystem [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly SharedToolSystem _toolSystem = default!; + // Forge-Change-start + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly SharedMoverController _mover = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; + // Forge-Change-end /// public override void Initialize() @@ -46,19 +60,23 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnInteractUsing); - SubscribeLocalEvent(OnInsertBattery); + SubscribeLocalEvent(OnContainerInserted); // Forge-Change + SubscribeLocalEvent(OnRemoveIgnition); // Forge-Change SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent>(OnAlternativeVerb); SubscribeLocalEvent(OnOpenUi); SubscribeLocalEvent(OnRemoveBattery); + SubscribeLocalEvent(OnRemoveIgnitionKey); // Forge-Change SubscribeLocalEvent(OnMechEntry); SubscribeLocalEvent(OnMechExit); - + SubscribeLocalEvent(OnMechPassengerEntry); // Forge-Change SubscribeLocalEvent(OnDamageChanged); SubscribeLocalEvent(OnRemoveEquipmentMessage); - SubscribeLocalEvent(OnMechCanMoveEvent); - + SubscribeLocalEvent(OnActivate); // Forge-Change + SubscribeLocalEvent(OnEjectPassenger1); // Forge-Change + SubscribeLocalEvent(OnEjectPassenger2); // Forge-Change + SubscribeLocalEvent(OnEjectPassenger3); // Forge-Change SubscribeLocalEvent(OnToolUseAttempt); SubscribeLocalEvent(OnInhale); @@ -72,18 +90,43 @@ public override void Initialize() SubscribeLocalEvent(ReceiveEquipmentUiMesssages); #endregion } + // Forge-Change-start + #region Movement & Engine private void OnMechCanMoveEvent(EntityUid uid, MechComponent component, UpdateCanMoveEvent args) { - if (component.Broken || component.Integrity <= 0 || component.Energy <= 0) + if (component.Broken || component.Integrity <= 0 || component.Energy <= 0 || !component.EngineRunning) args.Cancel(); } + private void UpdateEngineRunning(EntityUid uid, MechComponent component) + { + if (component.PilotSlot.ContainedEntity != null) + { + if (component.EngineRunning) + _mover.SetRelay(component.PilotSlot.ContainedEntity.Value, uid); + else + RemComp(component.PilotSlot.ContainedEntity.Value); + } + _actionBlocker.UpdateCanMove(uid); + } + + #endregion + + #region Interaction (Using items) private void OnInteractUsing(EntityUid uid, MechComponent component, InteractUsingEvent args) { - if (TryComp(uid, out var panel) && !panel.Open) + bool isKeyInteraction = HasComp(args.Used); + + if (!isKeyInteraction && TryComp(uid, out var panel) && !panel.Open) return; + if (isKeyInteraction && component.IgnitionSlot.ContainedEntity == null) + { + InsertIgnitionKey(uid, args.Used, component); + _actionBlocker.UpdateCanMove(uid); + return; + } if (component.BatterySlot.ContainedEntity == null && TryComp(args.Used, out var battery)) { InsertBattery(uid, args.Used, component, battery); @@ -93,26 +136,104 @@ private void OnInteractUsing(EntityUid uid, MechComponent component, InteractUsi if (_toolSystem.HasQuality(args.Used, "Prying") && component.BatterySlot.ContainedEntity != null) { + if (TryComp(uid, out var panelCheck) && !panelCheck.Open) + return; + var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.BatteryRemovalDelay, new RemoveBatteryEvent(), uid, target: uid, used: args.Target) { BreakOnMove = true }; - _doAfter.TryStartDoAfter(doAfterEventArgs); + return; + } + } + #endregion + + #region Container handling + + private void OnContainerInserted(EntityUid uid, MechComponent component, EntInsertedIntoContainerMessage args) + { + if (args.Container == component.BatterySlot && TryComp(args.Entity, out var battery)) + { + component.Energy = battery.CurrentCharge; + component.MaxEnergy = battery.MaxCharge; + Dirty(uid, component); + _actionBlocker.UpdateCanMove(uid); + UpdateUserInterface(uid, component); + return; } + if (args.Container == component.IgnitionSlot && HasComp(args.Entity)) + { + component.EngineRunning = true; + Dirty(uid, component); + UpdateEngineRunning(uid, component); + return; + } + } + private void OnRemoveIgnition(EntityUid uid, MechComponent component, EntRemovedFromContainerMessage args) + { + if (args.Container != component.IgnitionSlot) + return; + + component.EngineRunning = false; + Dirty(uid, component); + UpdateEngineRunning(uid, component); + } + #endregion + + #region Ignition key methods + private void InsertIgnitionKey(EntityUid uid, EntityUid toInsert, MechComponent component) + { + if (component.IgnitionSlot.ContainedEntity != null) + return; + _container.Insert(toInsert, component.IgnitionSlot); + } + private void RemoveIgnitionKey(EntityUid uid, MechComponent component) + { + if (component.IgnitionSlot.ContainedEntity == null) + return; + _container.EmptyContainer(component.IgnitionSlot); + } + private void OnRemoveIgnitionKey(EntityUid uid, MechComponent component, RemoveIgnitionKeyEvent args) + { + if (args.Cancelled || args.Handled) + return; + RemoveIgnitionKey(uid, component); + args.Handled = true; } + #endregion - private void OnInsertBattery(EntityUid uid, MechComponent component, EntInsertedIntoContainerMessage args) + #region Battery methods + public void InsertBattery(EntityUid uid, EntityUid toInsert, MechComponent? component = null, BatteryComponent? battery = null) { - if (args.Container != component.BatterySlot || !TryComp(args.Entity, out var battery)) + if (!Resolve(uid, ref component, false)) return; + if (!Resolve(toInsert, ref battery, false)) + return; + + _container.Insert(toInsert, component.BatterySlot); component.Energy = battery.CurrentCharge; component.MaxEnergy = battery.MaxCharge; + _actionBlocker.UpdateCanMove(uid); Dirty(uid, component); + UpdateUserInterface(uid, component); + } + public void RemoveBattery(EntityUid uid, MechComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + _container.EmptyContainer(component.BatterySlot); + component.Energy = 0; + component.MaxEnergy = 0; + _actionBlocker.UpdateCanMove(uid); + + Dirty(uid, component); + UpdateUserInterface(uid, component); } private void OnRemoveBattery(EntityUid uid, MechComponent component, RemoveBatteryEvent args) @@ -125,25 +246,40 @@ private void OnRemoveBattery(EntityUid uid, MechComponent component, RemoveBatte args.Handled = true; } + #endregion + + #region MapInit, Equipment, Verbs, UI private void OnMapInit(EntityUid uid, MechComponent component, MapInitEvent args) { var xform = Transform(uid); - // TODO: this should use containerfill? foreach (var equipment in component.StartingEquipment) { var ent = Spawn(equipment, xform.Coordinates); InsertEquipment(uid, ent, component); } - // TODO: this should just be damage and battery component.Integrity = component.MaxIntegrity; component.Energy = component.MaxEnergy; + if (component.Airtight && !HasComp(uid)) + { + var airComp = AddComp(uid); + // Создаём стандартную атмосферу Земли (21% O2, 79% N2, 101.325 кПа, 293.15 K) + var volume = airComp.Air.Volume; // = 70 литров (из компонента) + var temp = Atmospherics.T20C; // 293.15 K + var pressure = Atmospherics.OneAtmosphere; // 101.325 кПа + var totalMoles = (pressure * volume) / (Atmospherics.R * temp); // уравнение Менделеева-Клапейрона + + airComp.Air.AdjustMoles(Gas.Oxygen, totalMoles * 0.21f); + airComp.Air.AdjustMoles(Gas.Nitrogen, totalMoles * 0.79f); + airComp.Air.Temperature = temp; + } + _actionBlocker.UpdateCanMove(uid); Dirty(uid, component); } - + // Forge-Change-end private void OnRemoveEquipmentMessage(EntityUid uid, MechComponent component, MechEquipmentRemoveMessage args) { var equip = GetEntity(args.Equipment); @@ -185,41 +321,77 @@ private void OnAlternativeVerb(EntityUid uid, MechComponent component, GetVerbsE { BreakOnMove = true, }; - _doAfter.TryStartDoAfter(doAfterEventArgs); } }; - var openUiVerb = new AlternativeVerb //can't hijack someone else's mech + // Forge-Change-start + args.Verbs.Add(enterVerb); + } + else if (!IsEmpty(component) && CanInsertPassenger(uid, args.User, component)) + { + var passengerVerb = new AlternativeVerb { - Act = () => ToggleMechUi(uid, component, args.User), - Text = Loc.GetString("mech-ui-open-verb") + Text = Loc.GetString("mech-verb-enter-passenger"), + Act = () => + { + var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.EntryDelay, new MechPassengerEntryEvent(), uid, target: uid) + { + BreakOnMove = true, + }; + _doAfter.TryStartDoAfter(doAfterEventArgs); + } }; - args.Verbs.Add(enterVerb); - args.Verbs.Add(openUiVerb); + args.Verbs.Add(passengerVerb); } - else if (!IsEmpty(component)) + + var openUiVerb = new AlternativeVerb + { + Act = () => ToggleMechUi(uid, component, args.User), + Text = Loc.GetString("mech-ui-open-verb") + }; + args.Verbs.Add(openUiVerb); + + if (!IsEmpty(component) || !IsPassengerEmpty(component)) { var ejectVerb = new AlternativeVerb { Text = Loc.GetString("mech-verb-exit"), - Priority = 1, // Promote to top to make ejecting the ALT-click action + Priority = 1, Act = () => { - if (args.User == uid || args.User == component.PilotSlot.ContainedEntity) + if (component.PilotSlot.ContainedEntity == args.User) { TryEject(uid, component); return; } + if (IsPassenger(args.User, component)) + { + TryEjectPassenger(uid, args.User, component); + return; + } + if (args.User == uid) + return; var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.ExitDelay, new MechExitEvent(), uid, target: uid); - _doAfter.TryStartDoAfter(doAfterEventArgs); } }; args.Verbs.Add(ejectVerb); } } + private bool IsPassengerEmpty(MechComponent component) + { + return component.PassengerSlot1.ContainedEntity == null && + component.PassengerSlot2.ContainedEntity == null && + component.PassengerSlot3.ContainedEntity == null; + } + private new bool IsPassenger(EntityUid uid, MechComponent component) + { + return component.PassengerSlot1.ContainedEntity == uid || + component.PassengerSlot2.ContainedEntity == uid || + component.PassengerSlot3.ContainedEntity == uid; + } private void OnMechEntry(EntityUid uid, MechComponent component, MechEntryEvent args) { @@ -232,20 +404,62 @@ private void OnMechEntry(EntityUid uid, MechComponent component, MechEntryEvent return; } - TryInsert(uid, args.Args.User, component); + if (!TryInsert(uid, args.User, component)) + { + _popup.PopupEntity("Cannot enter mech!", args.User); + return; + } + _actionBlocker.UpdateCanMove(uid); args.Handled = true; } + private void OnMechPassengerEntry(EntityUid uid, MechComponent component, MechPassengerEntryEvent args) + { + if (args.Cancelled || args.Handled) + return; + + if (!TryInsertPassenger(uid, args.User, component)) + { + _popup.PopupEntity("Cannot enter as passenger!", args.User); + return; + } + + _popup.PopupEntity("You enter as passenger.", args.User); + args.Handled = true; + } private void OnMechExit(EntityUid uid, MechComponent component, MechExitEvent args) { if (args.Cancelled || args.Handled) return; - TryEject(uid, component); + if (component.PilotSlot.ContainedEntity == args.User) + { + TryEject(uid, component); + } + else if (IsPassenger(args.User, component)) + { + TryEjectPassenger(uid, args.User, component); + } + else + { + foreach (var slot in GetPassengerSlots(component)) + { + if (slot.ContainedEntity != null) + { + TryEjectPassenger(uid, slot.ContainedEntity.Value, component); + args.Handled = true; + return; + } + } + if (component.PilotSlot.ContainedEntity != null) + { + TryEject(uid, component); + } + } args.Handled = true; } - + // Forge-Change-end private void OnDamageChanged(EntityUid uid, MechComponent component, DamageChangedEvent args) { var integrity = component.MaxIntegrity - args.Damageable.TotalDamage; @@ -310,8 +524,14 @@ public override void UpdateUserInterface(EntityUid uid, MechComponent? component public override void BreakMech(EntityUid uid, MechComponent? component = null) { + if (!Resolve(uid, ref component)) + return; + // Forge-Change base.BreakMech(uid, component); + if (component.IgnitionSlot.ContainedEntity != null) + RemoveIgnitionKey(uid, component); +// Forge-Change _ui.CloseUi(uid, MechUiKey.Key); _actionBlocker.UpdateCanMove(uid); } @@ -332,7 +552,7 @@ public override bool TryChangeEnergy(EntityUid uid, FixedPoint2 delta, MechCompo return false; _battery.SetCharge(battery!.Value, batteryComp.CurrentCharge + delta.Float(), batteryComp); - if (batteryComp.CurrentCharge != component.Energy) //if there's a discrepency, we have to resync them + if (batteryComp.CurrentCharge != component.Energy) // Forge-Change { Log.Debug($"Battery charge was not equal to mech charge. Battery {batteryComp.CurrentCharge}. Mech {component.Energy}"); component.Energy = batteryComp.CurrentCharge; @@ -342,38 +562,7 @@ public override bool TryChangeEnergy(EntityUid uid, FixedPoint2 delta, MechCompo return true; } - public void InsertBattery(EntityUid uid, EntityUid toInsert, MechComponent? component = null, BatteryComponent? battery = null) - { - if (!Resolve(uid, ref component, false)) - return; - - if (!Resolve(toInsert, ref battery, false)) - return; - - _container.Insert(toInsert, component.BatterySlot); - component.Energy = battery.CurrentCharge; - component.MaxEnergy = battery.MaxCharge; - - _actionBlocker.UpdateCanMove(uid); - - Dirty(uid, component); - UpdateUserInterface(uid, component); - } - - public void RemoveBattery(EntityUid uid, MechComponent? component = null) - { - if (!Resolve(uid, ref component)) - return; - - _container.EmptyContainer(component.BatterySlot); - component.Energy = 0; - component.MaxEnergy = 0; - - _actionBlocker.UpdateCanMove(uid); - - Dirty(uid, component); - UpdateUserInterface(uid, component); - } + #endregion #region Atmos Handling private void OnInhale(EntityUid uid, MechPilotComponent component, InhaleLocationEvent args) @@ -415,7 +604,7 @@ private void OnExpose(EntityUid uid, MechPilotComponent component, ref AtmosExpo return; } - args.Gas = _atmosphere.GetContainingMixture(component.Mech, excite: args.Excite); + args.Gas = _atmosphere.GetContainingMixture(component.Mech, excite: args.Excite); // Forge-Change args.Handled = true; } @@ -424,11 +613,112 @@ private void OnGetFilterAir(EntityUid uid, MechAirComponent comp, ref GetFilterA if (args.Air != null) return; - // only airtight mechs get internal air if (!TryComp(uid, out var mech) || !mech.Airtight) return; args.Air = comp.Air; } #endregion + // Forge-Change-start + #region Horn & Siren (actions from Vehicle) + protected override void OnHornAction(EntityUid uid, MechComponent component, HornActionEvent args) + { + base.OnHornAction(uid, component, args); + if (args.Handled) + return; + if (component.PilotSlot.ContainedEntity != args.Performer) + return; + if (component.HornSound == null) + return; + _audio.PlayPvs(component.HornSound, uid); + args.Handled = true; + } + protected override void OnSirenAction(EntityUid uid, MechComponent component, SirenActionEvent args) + { + base.OnSirenAction(uid, component, args); + if (args.Handled) + return; + if (component.PilotSlot.ContainedEntity != args.Performer) + return; + if (component.SirenSound == null) + return; + if (component.SirenEnabled) + { + component.SirenStream = _audio.Stop(component.SirenStream); + } + else + { + component.SirenStream = _audio.PlayPvs(component.SirenSound, uid)?.Entity; + } + component.SirenEnabled = !component.SirenEnabled; + args.Handled = true; + } + #endregion + private void OnActivate(EntityUid uid, MechComponent component, ActivateInWorldEvent args) + { + if (args.Handled) + return; + + if (HasComp(args.User) || HasComp(args.User)) + return; + + if (component.IgnitionSlot.ContainedEntity is not { } key) + return; + + if (_hands.TryPickupAnyHand(args.User, key)) + { + _popup.PopupEntity(Loc.GetString("mech-key-removed"), uid, args.User); + } + else + { + Transform(key).Coordinates = Transform(uid).Coordinates; + _popup.PopupEntity(Loc.GetString("mech-key-dropped"), uid, args.User); + } + + _container.Remove(key, component.IgnitionSlot); + args.Handled = true; + } + private void OnEjectPassenger1(EntityUid uid, MechComponent component, MechEjectPassenger1Event args) + { + if (args.Handled) + return; + args.Handled = true; + + if (component.PilotSlot.ContainedEntity != args.Performer) + return; + + if (component.PassengerSlot1.ContainedEntity is { } passenger) + TryEjectPassenger(uid, passenger, component); + else + _popup.PopupEntity(Loc.GetString("mech-no-passenger-in-slot", ("slot", 1)), uid, args.Performer); + } + private void OnEjectPassenger2(EntityUid uid, MechComponent component, MechEjectPassenger2Event args) + { + if (args.Handled) + return; + args.Handled = true; + + if (component.PilotSlot.ContainedEntity != args.Performer) + return; + + if (component.PassengerSlot2.ContainedEntity is { } passenger) + TryEjectPassenger(uid, passenger, component); + else + _popup.PopupEntity(Loc.GetString("mech-no-passenger-in-slot", ("slot", 2)), uid, args.Performer); + } + private void OnEjectPassenger3(EntityUid uid, MechComponent component, MechEjectPassenger3Event args) + { + if (args.Handled) + return; + args.Handled = true; + + if (component.PilotSlot.ContainedEntity != args.Performer) + return; + + if (component.PassengerSlot3.ContainedEntity is { } passenger) + TryEjectPassenger(uid, passenger, component); + else + _popup.PopupEntity(Loc.GetString("mech-no-passenger-in-slot", ("slot", 3)), uid, args.Performer); + } + // Forge-Change-end } diff --git a/Content.Server/_Goobstation/VehicleSystem.cs b/Content.Server/_Goobstation/VehicleSystem.cs new file mode 100644 index 00000000000..7eaab46432a --- /dev/null +++ b/Content.Server/_Goobstation/VehicleSystem.cs @@ -0,0 +1,7 @@ +using Content.Shared.Vehicles; + +namespace Content.Server.Vehicles; + +public sealed class VehicleSystem : SharedVehicleSystem +{ +} diff --git a/Content.Server/_N14/WhitelistClothing/WhitelistClothingSystems.cs b/Content.Server/_N14/WhitelistClothing/WhitelistClothingSystems.cs new file mode 100644 index 00000000000..3e05033100c --- /dev/null +++ b/Content.Server/_N14/WhitelistClothing/WhitelistClothingSystems.cs @@ -0,0 +1,25 @@ +using Content.Shared.WhitelistClothing.Components; +using Content.Shared.Tag; +using Content.Shared.Inventory.Events; +using Content.Shared.Inventory; + +namespace Content.Server.WhitelistClothing.Systems; + +public sealed class WhitelistClothingSystems : EntitySystem +{ + [Dependency] private readonly InventorySystem _inventorySystem = default!; + [Dependency] private readonly TagSystem _tagSystem = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnEquipAttempt); + } + private void OnEquipAttempt(DidEquipEvent args) + { + if (TryComp(args.Equipee, out var component) && component.WhitelistState == "humanoid" && !_tagSystem.HasTag(args.Equipment, component.Whitelist) && args.Slot.Equals("outerclothing", StringComparison.CurrentCultureIgnoreCase)) + _inventorySystem.TryUnequip(args.Equipee, args.Slot); + else if (TryComp(args.Equipment, out var componentEquipment) && componentEquipment.WhitelistState == "clothing" && !HasComp(args.Equipee)) + _inventorySystem.TryUnequip(args.Equipee, args.Slot); + } +} diff --git a/Content.Shared/Mech/Components/MechComponent.cs b/Content.Shared/Mech/Components/MechComponent.cs index 6ebfde5f999..927a6ca148c 100644 --- a/Content.Shared/Mech/Components/MechComponent.cs +++ b/Content.Shared/Mech/Components/MechComponent.cs @@ -1,158 +1,74 @@ using Content.Shared.FixedPoint; using Content.Shared.Whitelist; +using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; namespace Content.Shared.Mech.Components; -/// -/// A large, pilotable machine that has equipment that is -/// powered via an internal battery. -/// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class MechComponent : Component { - /// - /// Goobstation: Whether or not an emag disables it. - /// [DataField("breakOnEmag")] [AutoNetworkedField] public bool BreakOnEmag = true; - - /// - /// How much "health" the mech has left. - /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public FixedPoint2 Integrity; - - /// - /// The maximum amount of damage the mech can take. - /// [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public FixedPoint2 MaxIntegrity = 250; - - /// - /// How much energy the mech has. - /// Derived from the currently inserted battery. - /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public FixedPoint2 Energy = 0; - - /// - /// The maximum amount of energy the mech can have. - /// Derived from the currently inserted battery. - /// [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public FixedPoint2 MaxEnergy = 0; - - /// - /// The slot the battery is stored in. - /// [ViewVariables] public ContainerSlot BatterySlot = default!; - [ViewVariables] public readonly string BatterySlotId = "mech-battery-slot"; - - /// - /// A multiplier used to calculate how much of the damage done to a mech - /// is transfered to the pilot - /// [DataField, ViewVariables(VVAccess.ReadWrite)] public float MechToPilotDamageMultiplier; - - /// - /// Whether the mech has been destroyed and is no longer pilotable. - /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public bool Broken = false; - - /// - /// The slot the pilot is stored in. - /// [ViewVariables(VVAccess.ReadWrite)] public ContainerSlot PilotSlot = default!; - [ViewVariables] public readonly string PilotSlotId = "mech-pilot-slot"; - - /// - /// The current selected equipment of the mech. - /// If null, the mech is using just its fists. - /// [ViewVariables, AutoNetworkedField] public EntityUid? CurrentSelectedEquipment; - - /// - /// The maximum amount of equipment items that can be installed in the mech - /// [DataField("maxEquipmentAmount"), ViewVariables(VVAccess.ReadWrite)] public int MaxEquipmentAmount = 3; - - /// - /// A whitelist for inserting equipment items. - /// [DataField] public EntityWhitelist? EquipmentWhitelist; [DataField] public EntityWhitelist? PilotWhitelist; - - /// - /// A container for storing the equipment entities. - /// [ViewVariables(VVAccess.ReadWrite)] public Container EquipmentContainer = default!; - [ViewVariables] public readonly string EquipmentContainerId = "mech-equipment-container"; - - /// - /// How long it takes to enter the mech. - /// [DataField, ViewVariables(VVAccess.ReadWrite)] public float EntryDelay = 3; - - /// - /// How long it takes to pull *another person* - /// outside of the mech. You can exit instantly yourself. - /// [DataField, ViewVariables(VVAccess.ReadWrite)] public float ExitDelay = 3; - - /// - /// How long it takes to pull out the battery. - /// [DataField, ViewVariables(VVAccess.ReadWrite)] public float BatteryRemovalDelay = 2; - - /// - /// Whether or not the mech is airtight. - /// - /// - /// This needs to be redone - /// when mech internals are added - /// [DataField, ViewVariables(VVAccess.ReadWrite)] public bool Airtight; - - /// - /// The equipment that the mech initially has when it spawns. - /// Good for things like nukie mechs that start with guns. - /// [DataField] public List StartingEquipment = new(); - #region Action Prototypes [DataField] public EntProtoId MechCycleAction = "ActionMechCycleEquipment"; [DataField] - public EntProtoId ToggleAction = "ActionToggleLight"; //Goobstation Mech Lights toggle action + public EntProtoId ToggleAction = "ActionToggleLight"; [DataField] public EntProtoId MechUiAction = "ActionMechOpenUI"; [DataField] public EntProtoId MechEjectAction = "ActionMechEject"; + [DataField] + public EntProtoId MechHornAction = "ActionMechHorn"; // Forge-Change + [DataField] + public EntProtoId MechSirenAction = "ActionMechSiren"; // Forge-Change #endregion #region Visualizer States @@ -163,9 +79,51 @@ public sealed partial class MechComponent : Component [DataField] public string? BrokenState; #endregion - [DataField] public EntityUid? MechCycleActionEntity; [DataField] public EntityUid? MechUiActionEntity; [DataField] public EntityUid? MechEjectActionEntity; - [DataField, AutoNetworkedField] public EntityUid? ToggleActionEntity; //Goobstation Mech Lights toggle action + // Forge-Change-start + [DataField, AutoNetworkedField] public EntityUid? ToggleActionEntity; + [DataField, AutoNetworkedField] public EntityUid? MechHornActionEntity; + [DataField, AutoNetworkedField] public EntityUid? MechSirenActionEntity; + [DataField] + public SoundSpecifier? HornSound; + [DataField] + public SoundSpecifier? SirenSound; + [DataField] + public string? EngineOnState; + [DataField, AutoNetworkedField] public bool SirenEnabled; + [DataField, AutoNetworkedField] public EntityUid? SirenStream; + [ViewVariables] + public ContainerSlot IgnitionSlot = default!; + [ViewVariables] + public readonly string IgnitionSlotId = "mech-ignition-slot"; + [DataField, AutoNetworkedField] public bool EngineRunning; // true when key is inserted + [ViewVariables] + public ContainerSlot PassengerSlot1 = default!; + [ViewVariables] + public readonly string PassengerSlot1Id = "mech-passenger-1"; + [ViewVariables] + public ContainerSlot PassengerSlot2 = default!; + [ViewVariables] + public readonly string PassengerSlot2Id = "mech-passenger-2"; + [ViewVariables] + public ContainerSlot PassengerSlot3 = default!; + [ViewVariables] + public readonly string PassengerSlot3Id = "mech-passenger-3"; + #region Action Prototypes + [DataField] + public EntProtoId MechEjectPassenger1Action = "ActionMechEjectPassenger1"; + [DataField] + public EntProtoId MechEjectPassenger2Action = "ActionMechEjectPassenger2"; + [DataField] + public EntProtoId MechEjectPassenger3Action = "ActionMechEjectPassenger3"; + #endregion + + #region Action Entities + [DataField, AutoNetworkedField] public EntityUid? MechEjectPassenger1ActionEntity; + [DataField, AutoNetworkedField] public EntityUid? MechEjectPassenger2ActionEntity; + [DataField, AutoNetworkedField] public EntityUid? MechEjectPassenger3ActionEntity; + #endregion + // Forge-Change-end } diff --git a/Content.Shared/Mech/Components/MechImplantsComponents.cs b/Content.Shared/Mech/Components/MechImplantsComponents.cs new file mode 100644 index 00000000000..15b3e184a5f --- /dev/null +++ b/Content.Shared/Mech/Components/MechImplantsComponents.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Implants.Components; // или Content.Shared.Mech.Components + +[RegisterComponent, NetworkedComponent] +public sealed partial class IgnitionKeyComponent : Component +{ + // Можно добавить дополнительные поля, если нужно (например, уровень доступа) +} + // Forge-Change diff --git a/Content.Shared/Mech/Components/MechPassengerComponent.cs b/Content.Shared/Mech/Components/MechPassengerComponent.cs new file mode 100644 index 00000000000..7456a5f57cc --- /dev/null +++ b/Content.Shared/Mech/Components/MechPassengerComponent.cs @@ -0,0 +1,15 @@ +using Robust.Shared.Containers; +using Robust.Shared.GameStates; + +namespace Content.Shared.Mech.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class MechPassengerComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public EntityUid Mech; + + [ViewVariables] + public ContainerSlot? Slot; +} + // Forge-Change diff --git a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs index f977a2eeb4e..fc645a59d12 100644 --- a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs +++ b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs @@ -21,7 +21,7 @@ using Robust.Shared.Serialization; using Robust.Shared.Timing; -// Goobstation Change +// Goobstation additions using Content.Shared.CCVar; using Content.Shared._Goobstation.CCVar; using Content.Shared.Emag.Systems; @@ -30,7 +30,7 @@ using Content.Shared.Hands.EntitySystems; using Content.Shared.Inventory.VirtualItem; using Robust.Shared.Configuration; -using Content.Shared.Implants.Components; +using Content.Shared.Vehicles; // for HornActionEvent, SirenActionEvent // Forge-Change namespace Content.Shared.Mech.EntitySystems; @@ -56,7 +56,7 @@ public abstract class SharedMechSystem : EntitySystem // Goobstation: Local variable for checking if mech guns can be used out of them. private bool _canUseMechGunOutside; - + /// public override void Initialize() { @@ -70,11 +70,16 @@ public override void Initialize() SubscribeLocalEvent(OnCanDragDrop); SubscribeLocalEvent(OnEmagged); + SubscribeLocalEvent(OnHornAction); // Forge-Change + SubscribeLocalEvent(OnSirenAction); // Forge-Change SubscribeLocalEvent(OnGetMeleeWeapon); SubscribeLocalEvent(OnCanAttackFromContainer); SubscribeLocalEvent(OnAttackAttempt); SubscribeLocalEvent(OnEntGotRemovedFromContainer); SubscribeLocalEvent(OnShotAttempted); // Goobstation + + SubscribeLocalEvent(OnPassengerRemoved); // Forge-Change + Subs.CVar(_config, GoobCVars.MechGunOutsideMech, value => _canUseMechGunOutside = value, true); // Goobstation } @@ -83,6 +88,12 @@ private void OnEntGotRemovedFromContainer(EntityUid uid, MechPilotComponent comp { TryEject(component.Mech, pilot: uid); } + private void OnPassengerRemoved(EntityUid uid, MechPassengerComponent component, EntGotRemovedFromContainerMessage args) + { + if (component.Mech == default) + return; + TryEjectPassenger(component.Mech, uid); // Forge-Change + } private void OnToggleEquipmentAction(EntityUid uid, MechComponent component, MechToggleEquipmentEvent args) { @@ -97,16 +108,68 @@ private void OnEjectPilotEvent(EntityUid uid, MechComponent component, MechEject if (args.Handled) return; args.Handled = true; - TryEject(uid, component); + // Forge-Change-start + + if (TryComp(args.Performer, out var pilot) && pilot.Mech == uid) + { + TryEject(uid, component); + } + else if (TryComp(args.Performer, out var passenger) && passenger.Mech == uid) + { + TryEjectPassenger(uid, args.Performer); + } + } + protected virtual void OnHornAction(EntityUid uid, MechComponent component, HornActionEvent args) + { + } + protected virtual void OnSirenAction(EntityUid uid, MechComponent component, SirenActionEvent args) + { + } + protected virtual void OnEjectPassenger1(EntityUid uid, MechComponent component, MechEjectPassenger1Event args) + { + if (args.Handled) + return; + args.Handled = true; + if (component.PilotSlot.ContainedEntity != args.Performer) + return; + if (component.PassengerSlot1.ContainedEntity is { } passenger) + TryEjectPassenger(uid, passenger, component); + else + _popup.PopupEntity(Loc.GetString("mech-no-passenger-in-slot", ("slot", 1)), uid, args.Performer); } + protected virtual void OnEjectPassenger2(EntityUid uid, MechComponent component, MechEjectPassenger2Event args) + { + if (args.Handled) + return; + args.Handled = true; + if (component.PilotSlot.ContainedEntity != args.Performer) + return; + if (component.PassengerSlot2.ContainedEntity is { } passenger) + TryEjectPassenger(uid, passenger, component); + else + _popup.PopupEntity(Loc.GetString("mech-no-passenger-in-slot", ("slot", 2)), uid, args.Performer); + } + + protected virtual void OnEjectPassenger3(EntityUid uid, MechComponent component, MechEjectPassenger3Event args) + { + if (args.Handled) + return; + args.Handled = true; + if (component.PilotSlot.ContainedEntity != args.Performer) + return; + if (component.PassengerSlot3.ContainedEntity is { } passenger) + TryEjectPassenger(uid, passenger, component); + else + _popup.PopupEntity(Loc.GetString("mech-no-passenger-in-slot", ("slot", 3)), uid, args.Performer); + } + // Forge-Change-end private void RelayInteractionEvent(EntityUid uid, MechComponent component, UserActivateInWorldEvent args) { var pilot = component.PilotSlot.ContainedEntity; if (pilot == null) return; - // TODO why is this being blocked? if (!_timing.IsFirstTimePredicted) return; @@ -121,6 +184,10 @@ private void OnStartup(EntityUid uid, MechComponent component, ComponentStartup component.PilotSlot = _container.EnsureContainer(uid, component.PilotSlotId); component.EquipmentContainer = _container.EnsureContainer(uid, component.EquipmentContainerId); component.BatterySlot = _container.EnsureContainer(uid, component.BatterySlotId); + component.IgnitionSlot = _container.EnsureContainer(uid, component.IgnitionSlotId); // Forge-Change + component.PassengerSlot1 = _container.EnsureContainer(uid, component.PassengerSlot1Id); // Forge-Change + component.PassengerSlot2 = _container.EnsureContainer(uid, component.PassengerSlot2Id); // Forge-Change + component.PassengerSlot3 = _container.EnsureContainer(uid, component.PassengerSlot3Id); // Forge-Change UpdateAppearance(uid, component); } @@ -145,10 +212,10 @@ private void SetupUser(EntityUid mech, EntityUid pilot, MechComponent? component var rider = EnsureComp(pilot); - // Warning: this bypasses most normal interaction blocking components on the user, like drone laws and the like. var irelay = EnsureComp(pilot); - _mover.SetRelay(pilot, mech); + if (component.EngineRunning) // Forge-Change + _mover.SetRelay(pilot, mech); _interaction.SetRelay(pilot, mech, irelay); rider.Mech = mech; Dirty(pilot, rider); @@ -159,7 +226,12 @@ private void SetupUser(EntityUid mech, EntityUid pilot, MechComponent? component _actions.AddAction(pilot, ref component.MechCycleActionEntity, component.MechCycleAction, mech); _actions.AddAction(pilot, ref component.MechUiActionEntity, component.MechUiAction, mech); _actions.AddAction(pilot, ref component.MechEjectActionEntity, component.MechEjectAction, mech); - _actions.AddAction(pilot, ref component.ToggleActionEntity, component.ToggleAction, mech); //Goobstation Mech Lights toggle action + _actions.AddAction(pilot, ref component.ToggleActionEntity, component.ToggleAction, mech); + _actions.AddAction(pilot, ref component.MechHornActionEntity, component.MechHornAction, mech); // Forge-Change + _actions.AddAction(pilot, ref component.MechSirenActionEntity, component.MechSirenAction, mech); // Forge-Change + _actions.AddAction(pilot, ref component.MechEjectPassenger1ActionEntity, component.MechEjectPassenger1Action, mech); // Forge-Change + _actions.AddAction(pilot, ref component.MechEjectPassenger2ActionEntity, component.MechEjectPassenger2Action, mech); // Forge-Change + _actions.AddAction(pilot, ref component.MechEjectPassenger3ActionEntity, component.MechEjectPassenger3Action, mech); // Forge-Change } private void RemoveUser(EntityUid mech, EntityUid pilot) @@ -175,14 +247,17 @@ private void RemoveUser(EntityUid mech, EntityUid pilot) /// /// Destroys the mech, removing the user and ejecting all installed equipment. /// - /// - /// public virtual void BreakMech(EntityUid uid, MechComponent? component = null) { if (!Resolve(uid, ref component)) return; TryEject(uid, component); + foreach (var slot in GetPassengerSlots(component)) + { + if (slot.ContainedEntity != null) + TryEjectPassenger(uid, slot.ContainedEntity.Value); + } // Forge-Change var equipment = new List(component.EquipmentContainer.ContainedEntities); foreach (var ent in equipment) { @@ -196,8 +271,6 @@ public virtual void BreakMech(EntityUid uid, MechComponent? component = null) /// /// Cycles through the currently selected equipment. /// - /// - /// public void CycleEquipment(EntityUid uid, MechComponent? component = null) { if (!Resolve(uid, ref component)) @@ -230,10 +303,6 @@ public void CycleEquipment(EntityUid uid, MechComponent? component = null) /// /// Inserts an equipment item into the mech. /// - /// - /// - /// - /// public void InsertEquipment(EntityUid uid, EntityUid toInsert, MechComponent? component = null, MechEquipmentComponent? equipmentComponent = null) { @@ -259,11 +328,6 @@ public void InsertEquipment(EntityUid uid, EntityUid toInsert, MechComponent? co /// /// Removes an equipment item from a mech. /// - /// - /// - /// - /// - /// Whether or not the removal can be cancelled public void RemoveEquipment(EntityUid uid, EntityUid toRemove, MechComponent? component = null, MechEquipmentComponent? equipmentComponent = null, bool forced = false) { @@ -295,10 +359,6 @@ public void RemoveEquipment(EntityUid uid, EntityUid toRemove, MechComponent? co /// /// Attempts to change the amount of energy in the mech. /// - /// The mech itself - /// The change in energy - /// - /// If the energy was successfully changed. public virtual bool TryChangeEnergy(EntityUid uid, FixedPoint2 delta, MechComponent? component = null) { if (!Resolve(uid, ref component)) @@ -316,9 +376,6 @@ public virtual bool TryChangeEnergy(EntityUid uid, FixedPoint2 delta, MechCompon /// /// Sets the integrity of the mech. /// - /// The mech itself - /// The value the integrity will be set at - /// public void SetIntegrity(EntityUid uid, FixedPoint2 value, MechComponent? component = null) { if (!Resolve(uid, ref component)) @@ -343,20 +400,11 @@ public void SetIntegrity(EntityUid uid, FixedPoint2 value, MechComponent? compon /// /// Checks if the pilot is present /// - /// - /// Whether or not the pilot is present public bool IsEmpty(MechComponent component) { return component.PilotSlot.ContainedEntity == null; } - /// - /// Checks if an entity can be inserted into the mech. - /// - /// - /// - /// - /// public bool CanInsert(EntityUid uid, EntityUid toInsert, MechComponent? component = null) { if (!Resolve(uid, ref component)) @@ -368,9 +416,6 @@ public bool CanInsert(EntityUid uid, EntityUid toInsert, MechComponent? componen /// /// Updates the user interface /// - /// - /// This is defined here so that UI updates can be accessed from shared. - /// public virtual void UpdateUserInterface(EntityUid uid, MechComponent? component = null) { } @@ -378,10 +423,6 @@ public virtual void UpdateUserInterface(EntityUid uid, MechComponent? component /// /// Attempts to insert a pilot into the mech. /// - /// - /// - /// - /// Whether or not the entity was inserted public bool TryInsert(EntityUid uid, EntityUid? toInsert, MechComponent? component = null) { if (!Resolve(uid, ref component)) @@ -403,10 +444,6 @@ public bool TryInsert(EntityUid uid, EntityUid? toInsert, MechComponent? compone /// /// Attempts to eject the current pilot from the mech /// - /// - /// - /// The pilot to eject - /// Whether or not the pilot was ejected. public bool TryEject(EntityUid uid, MechComponent? component = null, EntityUid? pilot = null) { if (!Resolve(uid, ref component)) @@ -424,7 +461,67 @@ public bool TryEject(EntityUid uid, MechComponent? component = null, EntityUid? UpdateHands(pilot.Value, uid, false); // Goobstation return true; } + // Forge-Change-start + public bool CanInsertPassenger(EntityUid uid, EntityUid toInsert, MechComponent component) + { + if (HasComp(toInsert) || IsPassenger(toInsert, component)) + return false; + if (GetFreePassengerSlot(component) == null) + return false; + return _actionBlocker.CanInteract(toInsert, uid); + } + public bool TryInsertPassenger(EntityUid uid, EntityUid toInsert, MechComponent component) + { + if (!CanInsertPassenger(uid, toInsert, component)) + return false; + + var slot = GetFreePassengerSlot(component)!; + _container.Insert(toInsert, slot); + + var passenger = EnsureComp(toInsert); + passenger.Mech = uid; + passenger.Slot = slot; + Dirty(toInsert, passenger); + + return true; + } + public bool TryEjectPassenger(EntityUid uid, EntityUid passenger, MechComponent? component = null) + { + if (!Resolve(uid, ref component)) + return false; + foreach (var slot in GetPassengerSlots(component)) + { + if (slot.ContainedEntity == passenger) + { + _container.RemoveEntity(uid, passenger); + RemComp(passenger); + return true; + } + } + return false; + } + protected ContainerSlot? GetFreePassengerSlot(MechComponent component) + { + if (component.PassengerSlot1.ContainedEntity == null) + return component.PassengerSlot1; + if (component.PassengerSlot2.ContainedEntity == null) + return component.PassengerSlot2; + if (component.PassengerSlot3.ContainedEntity == null) + return component.PassengerSlot3; + return null; + } + protected IEnumerable GetPassengerSlots(MechComponent component) + { + yield return component.PassengerSlot1; + yield return component.PassengerSlot2; + yield return component.PassengerSlot3; + } + protected bool IsPassenger(EntityUid uid, MechComponent component) + { + return GetPassengerSlots(component).Any(slot => slot.ContainedEntity == uid); + } + // Forge-Change-end // Goobstation Change Start private void UpdateHands(EntityUid uid, EntityUid mech, bool active) { @@ -468,7 +565,6 @@ private void FreeHands(EntityUid uid, EntityUid mech) { _virtualItem.DeleteInHandsMatching(uid, mech); } - // Goobstation Change End private void OnGetMeleeWeapon(EntityUid uid, MechPilotComponent component, GetMeleeWeaponEvent args) { @@ -517,6 +613,7 @@ private void UpdateAppearance(EntityUid uid, MechComponent? component = null, _appearance.SetData(uid, MechVisuals.Open, IsEmpty(component), appearance); _appearance.SetData(uid, MechVisuals.Broken, component.Broken, appearance); + _appearance.SetData(uid, MechVisuals.EngineOn, component.EngineRunning, appearance); // Forge-Change } private void OnDragDrop(EntityUid uid, MechComponent component, ref DragDropTargetEvent args) @@ -526,19 +623,28 @@ private void OnDragDrop(EntityUid uid, MechComponent component, ref DragDropTarg args.Handled = true; - var doAfterEventArgs = new DoAfterArgs(EntityManager, args.Dragged, component.EntryDelay, new MechEntryEvent(), uid, target: uid) + if (CanInsert(uid, args.Dragged, component)) + { // Forge-Change + var doAfterEventArgs = new DoAfterArgs(EntityManager, args.Dragged, component.EntryDelay, new MechEntryEvent(), uid, target: uid) + { + BreakOnMove = true, + }; + _doAfter.TryStartDoAfter(doAfterEventArgs); + } + else if (CanInsertPassenger(uid, args.Dragged, component)) { - BreakOnMove = true, - }; - - _doAfter.TryStartDoAfter(doAfterEventArgs); + var doAfterEventArgs = new DoAfterArgs(EntityManager, args.Dragged, component.EntryDelay, new MechPassengerEntryEvent(), uid, target: uid) + { + BreakOnMove = true, + }; + _doAfter.TryStartDoAfter(doAfterEventArgs); + } // Forge-Change } private void OnCanDragDrop(EntityUid uid, MechComponent component, ref CanDropTargetEvent args) { args.Handled = true; - - args.CanDrop |= !component.Broken && CanInsert(uid, args.Dragged, component); + args.CanDrop |= !component.Broken && (CanInsert(uid, args.Dragged, component) || CanInsertPassenger(uid, args.Dragged, component)); } private void OnEmagged(EntityUid uid, MechComponent component, ref GotEmaggedEvent args) // Goobstation @@ -551,36 +657,30 @@ private void OnEmagged(EntityUid uid, MechComponent component, ref GotEmaggedEve } } -/// -/// Event raised when the battery is successfully removed from the mech, -/// on both success and failure -/// +public sealed partial class MechEjectPassenger1Event : InstantActionEvent; // Forge-Change +public sealed partial class MechEjectPassenger2Event : InstantActionEvent; // Forge-Change +public sealed partial class MechEjectPassenger3Event : InstantActionEvent; // Forge-Change + [Serializable, NetSerializable] public sealed partial class RemoveBatteryEvent : SimpleDoAfterEvent { } - -/// -/// Event raised when a person removes someone from a mech, -/// on both success and failure -/// [Serializable, NetSerializable] public sealed partial class MechExitEvent : SimpleDoAfterEvent { } - -/// -/// Event raised when a person enters a mech, on both success and failure -/// [Serializable, NetSerializable] public sealed partial class MechEntryEvent : SimpleDoAfterEvent { } - -/// -/// Event raised when an user attempts to fire a mech weapon to check if its battery is drained -/// - +[Serializable, NetSerializable] +public sealed partial class MechPassengerEntryEvent : SimpleDoAfterEvent // Forge-Change +{ +} +[Serializable, NetSerializable] +public sealed partial class RemoveIgnitionKeyEvent : SimpleDoAfterEvent // Forge-Change +{ +} [Serializable, NetSerializable] public sealed partial class HandleMechEquipmentBatteryEvent : EntityEventArgs { diff --git a/Content.Shared/Mech/SharedMech.cs b/Content.Shared/Mech/SharedMech.cs index 94af4453d48..2dd46d5192c 100644 --- a/Content.Shared/Mech/SharedMech.cs +++ b/Content.Shared/Mech/SharedMech.cs @@ -6,8 +6,9 @@ namespace Content.Shared.Mech; [Serializable, NetSerializable] public enum MechVisuals : byte { - Open, //whether or not it's open and has a rider - Broken //if it broke and no longer works. + Open, + Broken, + EngineOn // Forge-Change } [Serializable, NetSerializable] diff --git a/Content.Shared/_Goobstation/SharedVehicleComponent.cs b/Content.Shared/_Goobstation/SharedVehicleComponent.cs new file mode 100644 index 00000000000..7503656c766 --- /dev/null +++ b/Content.Shared/_Goobstation/SharedVehicleComponent.cs @@ -0,0 +1,81 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared.Vehicles; + +[RegisterComponent, NetworkedComponent] +public sealed partial class VehicleComponent : Component +{ + [ViewVariables] + public EntityUid? Driver; + + [ViewVariables] + public EntityUid? HornAction; + + [ViewVariables] + public EntityUid? SirenAction; + + public bool SirenEnabled = false; + + public EntityUid? SirenStream; + + /// + /// If non-zero how many virtual items to spawn on the driver + /// unbuckles them if they dont have enough + /// + [DataField] + public int RequiredHands = 1; + + /// + /// Will the vehicle move when a driver buckles + /// + [DataField] + public bool EngineRunning = false; + + /// + /// What sound to play when the driver presses the horn action (plays once) + /// + [DataField] + public SoundSpecifier? HornSound; + + /// + /// What sound to play when the driver presses the siren action (loops) + /// + [DataField] + public SoundSpecifier? SirenSound; + + /// + /// If they should be rendered ontop of the vehicle if true or behind + /// + [DataField] + public VehicleRenderOver RenderOver = VehicleRenderOver.None; +} +[Serializable, NetSerializable] +public enum VehicleState : byte +{ + Animated, + DrawOver +} + +[Serializable, NetSerializable, Flags] +public enum VehicleRenderOver +{ + None = 0, + North = 1, + NorthEast = 2, + East = 4, + SouthEast = 8, + South = 16, + SouthWest = 32, + West = 64, + NorthWest = 128, +} + +[Serializable, NetSerializable] +public enum VehicleVisualLayers : byte +{ + Base, + AutoAnimate, + Cover, +} diff --git a/Content.Shared/_Goobstation/SharedVehicleSystem.cs b/Content.Shared/_Goobstation/SharedVehicleSystem.cs new file mode 100644 index 00000000000..5a3b2bb920a --- /dev/null +++ b/Content.Shared/_Goobstation/SharedVehicleSystem.cs @@ -0,0 +1,254 @@ +using Content.Shared.Access.Components; +using Content.Shared.Access.Systems; +using Content.Shared.Actions; +using Content.Shared.Audio; +using Content.Shared.Buckle; +using Content.Shared.Buckle.Components; +using Content.Shared.Hands; +using Content.Shared.Inventory.VirtualItem; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Vehicles; + +public abstract partial class SharedVehicleSystem : EntitySystem +{ + [Dependency] private readonly AccessReaderSystem _access = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly SharedAmbientSoundSystem _ambientSound = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedBuckleSystem _buckle = default!; + [Dependency] private readonly SharedMoverController _mover = default!; + [Dependency] private readonly SharedVirtualItemSystem _virtualItem = default!; + + public static readonly EntProtoId HornActionId = "ActionHorn"; + public static readonly EntProtoId SirenActionId = "ActionSiren"; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnRemove); + SubscribeLocalEvent(OnStrapAttempt); + SubscribeLocalEvent(OnStrapped); + SubscribeLocalEvent(OnUnstrapped); + SubscribeLocalEvent(OnDropped); + + SubscribeLocalEvent(OnInsert); + SubscribeLocalEvent(OnEject); + + SubscribeLocalEvent(OnHorn); + SubscribeLocalEvent(OnSiren); + } + + private void OnInit(EntityUid uid, VehicleComponent component, ComponentInit args) + { + _appearance.SetData(uid, VehicleState.Animated, component.EngineRunning); + _appearance.SetData(uid, VehicleState.DrawOver, false); + } + + private void OnRemove(EntityUid uid, VehicleComponent component, ComponentRemove args) + { + if (component.Driver == null) + return; + + _buckle.TryUnbuckle(component.Driver.Value, component.Driver.Value); + Dismount(component.Driver.Value, uid); + _appearance.SetData(uid, VehicleState.DrawOver, false); + } + + private void OnInsert(EntityUid uid, VehicleComponent component, ref EntInsertedIntoContainerMessage args) + { + if (HasComp(args.Entity)) + return; + + component.EngineRunning = true; + _appearance.SetData(component.Owner, VehicleState.Animated, true); + + _ambientSound.SetAmbience(component.Owner, true); + + if (component.Driver == null) + return; + + Mount(component.Driver.Value, component.Owner); + } + + private void OnEject(EntityUid uid, VehicleComponent component, ref EntRemovedFromContainerMessage args) + { + component.EngineRunning = false; + _appearance.SetData(component.Owner, VehicleState.Animated, false); + + _ambientSound.SetAmbience(component.Owner, false); + + if (component.Driver == null) + return; + + Dismount(component.Driver.Value, component.Owner); + } + + private void OnHorn(EntityUid uid, VehicleComponent component, InstantActionEvent args) + { + if (args.Handled == true) + return; + + if (component.Driver != args.Performer) + return; + + if (component.HornSound == null) + return; + + _audio.PlayPvs(component.HornSound, component.Owner); + args.Handled = true; + } + + private void OnSiren(EntityUid uid, VehicleComponent component, InstantActionEvent args) + { + if (args.Handled == true) + return; + + if (component.Driver != args.Performer) + return; + + if (component.SirenSound == null) + return; + + if (component.SirenEnabled) + { + component.SirenStream = _audio.Stop(component.SirenStream); + } + else + { + component.SirenStream = _audio.PlayPvs(component.SirenSound, uid)?.Entity; + } + + component.SirenEnabled = !component.SirenEnabled; + args.Handled = true; + } + + + private void OnStrapAttempt(Entity ent, ref StrapAttemptEvent args) + { + var driver = args.Buckle.Owner; // i dont want to re write this shit 100 fucking times + + if (ent.Comp.Driver != null) + { + args.Cancelled = true; + return; + } + + if (ent.Comp.RequiredHands != 0) + { + for (int hands = 0; hands < ent.Comp.RequiredHands; hands++) + { + if (!_virtualItem.TrySpawnVirtualItemInHand(ent.Owner, driver, false)) + { + args.Cancelled = true; + _virtualItem.DeleteInHandsMatching(driver, ent.Owner); + return; + } + } + } + + AddHorns(driver, ent); + } + + private void OnStrapped(Entity ent, ref StrappedEvent args) + { + var driver = args.Buckle.Owner; + + if (!TryComp(driver, out MobMoverComponent? mover)) + return; + + if (ent.Comp.Driver != null) + return; + + ent.Comp.Driver = driver; + _appearance.SetData(ent.Owner, VehicleState.DrawOver, true); + + if (!ent.Comp.EngineRunning) + return; + + Mount(driver, ent.Owner); + } + + private void OnUnstrapped(Entity ent, ref UnstrappedEvent args) + { + if (ent.Comp.Driver != args.Buckle.Owner) + return; + + Dismount(args.Buckle.Owner, ent); + _appearance.SetData(ent.Owner, VehicleState.DrawOver, false); + } + + private void OnDropped(EntityUid uid, VehicleComponent comp, VirtualItemDeletedEvent args) + { + if (comp.Driver != args.User) + return; + + _buckle.TryUnbuckle(args.User, args.User); + + Dismount(args.User, comp.Owner); + _appearance.SetData(comp.Owner, VehicleState.DrawOver, false); + } + + private void AddHorns(EntityUid driver, EntityUid vehicle) + { + if (!TryComp(vehicle, out var vehicleComp)) + return; + + if (vehicleComp.HornSound != null) + _actions.AddAction(driver, ref vehicleComp.HornAction, HornActionId, vehicle); + + if (vehicleComp.SirenSound != null) + _actions.AddAction(driver, ref vehicleComp.SirenAction, SirenActionId, vehicle); + } + + private void Mount(EntityUid driver, EntityUid vehicle) + { + if (TryComp(vehicle, out var accessComp)) + { + var accessSources = _access.FindPotentialAccessItems(driver); + var access = _access.FindAccessTags(driver, accessSources); + + foreach (var tag in access) + { + accessComp.Tags.Add(tag); + } + } + + _mover.SetRelay(driver, vehicle); + } + + private void Dismount(EntityUid driver, EntityUid vehicle) + { + if (!TryComp(vehicle, out var vehicleComp)) + return; + + if (vehicleComp.Driver != driver) + return; + + RemComp(driver); + + vehicleComp.Driver = null; + + if (vehicleComp.HornAction != null) + _actions.RemoveAction(driver, vehicleComp.HornAction); + + if (vehicleComp.SirenAction != null) + _actions.RemoveAction(driver, vehicleComp.SirenAction); + + _virtualItem.DeleteInHandsMatching(driver, vehicle); + + if (TryComp(vehicle, out var accessComp)) + accessComp.Tags.Clear(); + } +} + +public sealed partial class HornActionEvent : InstantActionEvent; + +public sealed partial class SirenActionEvent : InstantActionEvent; diff --git a/Content.Shared/_N14/WhitelistClothing/WhitelistClothingComponents.cs b/Content.Shared/_N14/WhitelistClothing/WhitelistClothingComponents.cs new file mode 100644 index 00000000000..138f9cc5f91 --- /dev/null +++ b/Content.Shared/_N14/WhitelistClothing/WhitelistClothingComponents.cs @@ -0,0 +1,12 @@ +namespace Content.Shared.WhitelistClothing.Components; + +[RegisterComponent] +public sealed partial class WhitelistClothingComponent : Component +{ + [DataField, ViewVariables(VVAccess.ReadWrite)] + public string Whitelist = "SupermutantArmor"; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public string Slot = "outerclothing"; + [DataField(required: true), ViewVariables(VVAccess.ReadWrite)] + public string WhitelistState = "humanoid"; +} diff --git a/Resources/Audio/Mecha/cardrive.ogg b/Resources/Audio/Mecha/cardrive.ogg new file mode 100644 index 00000000000..5ed3156e685 Binary files /dev/null and b/Resources/Audio/Mecha/cardrive.ogg differ diff --git a/Resources/Locale/en-US/_Nuclear14/species.ftl b/Resources/Locale/en-US/_Nuclear14/species.ftl index 4714ab0b4d4..2fe9bc009a6 100644 --- a/Resources/Locale/en-US/_Nuclear14/species.ftl +++ b/Resources/Locale/en-US/_Nuclear14/species.ftl @@ -3,4 +3,5 @@ species-name-ghoul = Ghoul species-name-ghoul-glowing = Glowing Ghoul species-name-ratfolk = Rat Folk -species-name-ratmonarch = Rat Monarch \ No newline at end of file +species-name-ratmonarch = Rat Monarch +species-name-Supermutant = Супермутант diff --git a/Resources/Locale/en-US/metabolism/metabolizer-types.ftl b/Resources/Locale/en-US/metabolism/metabolizer-types.ftl index 97d5c068c41..47cb3e9ac16 100644 --- a/Resources/Locale/en-US/metabolism/metabolizer-types.ftl +++ b/Resources/Locale/en-US/metabolism/metabolizer-types.ftl @@ -13,3 +13,4 @@ metabolizer-type-vampiric = Vampiric metabolizer-type-liquorlifeline = Liquor Lifeline metabolizer-type-shadowkin = Shadowkin metabolizer-type-plasmaman = Plasmaman +metabolizer-type-supermutant = Supermutant diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/_nuclear14/entities/objects/vehicles/vehicle.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/_nuclear14/entities/objects/vehicles/vehicle.ftl new file mode 100644 index 00000000000..add65ca8906 --- /dev/null +++ b/Resources/Locale/en-US/ss14-ru/prototypes/_nuclear14/entities/objects/vehicles/vehicle.ftl @@ -0,0 +1 @@ +vehicle-slot-component-slot-name-keys = Ключи diff --git a/Resources/Locale/ru-RU/mech/mech.ftl b/Resources/Locale/ru-RU/mech/mech.ftl index 52cd95e0dea..0ba23353b0b 100644 --- a/Resources/Locale/ru-RU/mech/mech.ftl +++ b/Resources/Locale/ru-RU/mech/mech.ftl @@ -11,3 +11,15 @@ mech-energy-display = Энергия: { $amount }% mech-energy-missing = Энергия: ОТСУТСТВУЕТ mech-slot-display = Доступно слотов: { $amount } mech-no-enter = Вы не можете пилотировать это. +# Forge-Change-start +mech-key-removed = Вы взяли ключ. +mech-key-dropped = Ключ упал на пол. +mech-verb-enter-passenger = Войти пассажиром +mech-no-passenger-in-slot = В пассажирском кресле {$slot} никого нет. +action-name-mech-eject-passenger1 = Высадить пассажира 1 +action-description-mech-eject-passenger1 = Высаживает первого пассажира из меха +action-name-mech-eject-passenger2 = Высадить пассажира 2 +action-description-mech-eject-passenger2 = Высаживает второго пассажира +action-name-mech-eject-passenger3 = Высадить пассажира 3 +action-description-mech-eject-passenger3 = Высаживает третьего пассажира +# Forge-Change-end diff --git a/Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl b/Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl index 7a17abf3656..b5aa0018ee5 100644 --- a/Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl +++ b/Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl @@ -9,3 +9,4 @@ metabolizer-type-plant = Растение metabolizer-type-dwarf = Дварф metabolizer-type-moth = Ниан metabolizer-type-arachnid = Арахнид +metabolizer-type-supermutant = Супермутант diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nuclear14/entities/mobs/species/supermutant.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nuclear14/entities/mobs/species/supermutant.ftl new file mode 100644 index 00000000000..8f3fa121fed --- /dev/null +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nuclear14/entities/mobs/species/supermutant.ftl @@ -0,0 +1,4 @@ +ent-N14BaseMobSupermutant = супермутант + .desc = { ent-BaseMobHuman.desc } +ent-N14MobSupermutantDummy = { ent-MobHumanDummy } + .desc = { ent-MobHumanDummy.desc } diff --git a/Resources/Prototypes/Corvax/Roles/Jobs/BrotherhoodMidwest/Serf.yml b/Resources/Prototypes/Corvax/Roles/Jobs/BrotherhoodMidwest/Serf.yml index f2b01af411b..f9003ff9fdf 100644 --- a/Resources/Prototypes/Corvax/Roles/Jobs/BrotherhoodMidwest/Serf.yml +++ b/Resources/Prototypes/Corvax/Roles/Jobs/BrotherhoodMidwest/Serf.yml @@ -36,9 +36,5 @@ gloves: N14ClothingHandsGlovesCloth bandage: NCClothingCollarBoSSerf - - type: playTimeTracker id: BoSMidSerf - - - diff --git a/Resources/Prototypes/Corvax/Roles/Jobs/Townfolk/Townshopkeeperhelper.yml b/Resources/Prototypes/Corvax/Roles/Jobs/Townfolk/Townshopkeeperhelper.yml index 1ceb820f81f..1d0c795aff4 100644 --- a/Resources/Prototypes/Corvax/Roles/Jobs/Townfolk/Townshopkeeperhelper.yml +++ b/Resources/Prototypes/Corvax/Roles/Jobs/Townfolk/Townshopkeeperhelper.yml @@ -15,11 +15,12 @@ department: Townsfolk min: 7200 # 2 hours startingGear: TownShopkeeperHelperGear - icon: "JobIconTownShopKeeper" + icon: "JobIconTownShopKeeper" supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - TownieShopkeeper - - TownsPerson + - TownsPerson special: - !type:AddComponentSpecial components: @@ -33,16 +34,16 @@ id: TownShopkeeperHelperGear equipment: jumpsuit: N14ClothingUniformJumpsuitMerchant - back: N14ClothingBackpackHiking + back: N14ClothingBackpackHiking shoes: N14ClothingShoesBlack id: N14IDShopkeeperHelperTown belt: N14WalletCash innerClothingSkirt: N14ClothingUniformJumpskirtFalloutBlack satchel: N14ClothingBackpackSatchelWastelanderFilled duffelbag: N14ClothingBackpackDuffelFilled # N14TODO: Trader bag - storage: + storage: back: - N14BoxPlasticFilledWastelander - type: playTimeTracker - id: TownShopkeeperHelper \ No newline at end of file + id: TownShopkeeperHelper diff --git a/Resources/Prototypes/Corvax/Roles/Jobs/Townfolk/town_entity.yml b/Resources/Prototypes/Corvax/Roles/Jobs/Townfolk/town_entity.yml index ae0bfa2e8e7..dba701b2434 100644 --- a/Resources/Prototypes/Corvax/Roles/Jobs/Townfolk/town_entity.yml +++ b/Resources/Prototypes/Corvax/Roles/Jobs/Townfolk/town_entity.yml @@ -12,4 +12,4 @@ - type: NpcFactionMember factions: - Wastelander - - Townsfolk \ No newline at end of file + - Townsfolk diff --git a/Resources/Prototypes/InventoryTemplates/human_inventory_template.yml b/Resources/Prototypes/InventoryTemplates/human_inventory_template.yml index 2aea21ced71..c6eec673f85 100644 --- a/Resources/Prototypes/InventoryTemplates/human_inventory_template.yml +++ b/Resources/Prototypes/InventoryTemplates/human_inventory_template.yml @@ -22,6 +22,9 @@ uiWindowPos: 1,1 strippingWindowPos: 1,2 displayName: Suit + blacklist: + tags: + - SupermutantArmor # Forge-Change - name: gloves slotTexture: gloves slotFlags: GLOVES diff --git a/Resources/Prototypes/InventoryTemplates/supermutant_inventory_template.yml b/Resources/Prototypes/InventoryTemplates/supermutant_inventory_template.yml new file mode 100644 index 00000000000..b179cc92473 --- /dev/null +++ b/Resources/Prototypes/InventoryTemplates/supermutant_inventory_template.yml @@ -0,0 +1,133 @@ +# Forge-Change +- type: inventoryTemplate + id: supermutant + slots: + - name: shoes + slotTexture: shoes + slotFlags: FEET + stripTime: 3 + uiWindowPos: 1,0 + strippingWindowPos: 1,3 + displayName: Shoes + - name: jumpsuit + slotTexture: uniform + slotFlags: INNERCLOTHING + stripTime: 6 + uiWindowPos: 0,1 + strippingWindowPos: 0,2 + displayName: Jumpsuit + - name: outerClothing + slotTexture: suit + slotFlags: OUTERCLOTHING + stripTime: 9 + uiWindowPos: 1,1 + strippingWindowPos: 1,2 + displayName: Suit + whitelist: + tags: + - SupermutantArmor + - name: gloves + slotTexture: gloves + slotFlags: GLOVES + uiWindowPos: 2,1 + strippingWindowPos: 2,2 + displayName: Gloves + - name: neck + slotTexture: neck + slotFlags: NECK + uiWindowPos: 0,2 + strippingWindowPos: 0,1 + displayName: Neck + - name: mask + slotTexture: mask + slotFlags: MASK + uiWindowPos: 1,2 + strippingWindowPos: 1,1 + displayName: Mask + - name: eyes + slotTexture: glasses + slotFlags: EYES + stripTime: 3 + uiWindowPos: 0,3 + strippingWindowPos: 0,0 + displayName: Eyes + - name: ears + slotTexture: ears + slotFlags: EARS + stripTime: 3 + uiWindowPos: 2,2 + strippingWindowPos: 2,1 + displayName: Ears + - name: head + slotTexture: head + slotFlags: HEAD + uiWindowPos: 1,3 + strippingWindowPos: 1,0 + displayName: Head + - name: bandage + slotTexture: bandage + slotFlags: BANDAGE + uiWindowPos: 2,3 + strippingWindowPos: 2,0 + displayName: Bandage + - name: pocket1 + slotTexture: pocket + fullTextureName: template_small + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 0,3 + strippingWindowPos: 0,4 + dependsOn: jumpsuit + displayName: Pocket 1 + stripHidden: true + - name: pocket2 + slotTexture: pocket + fullTextureName: template_small + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 2,3 + strippingWindowPos: 1,4 + dependsOn: jumpsuit + displayName: Pocket 2 + stripHidden: true + - name: suitstorage + slotTexture: suit_storage + slotFlags: SUITSTORAGE + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 2,0 + strippingWindowPos: 2,5 + dependsOn: outerClothing + dependsOnComponents: + - type: AllowSuitStorage + displayName: Suit Storage + - name: id + slotTexture: id + fullTextureName: template_small + slotFlags: IDCARD + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 2,1 + strippingWindowPos: 2,4 + dependsOn: jumpsuit + displayName: ID + - name: belt + slotTexture: belt + fullTextureName: template_small + slotFlags: BELT + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 3,1 + strippingWindowPos: 1,5 + displayName: Belt + - name: back + slotTexture: back + fullTextureName: template_small + slotFlags: BACK + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 3,0 + strippingWindowPos: 0,5 + displayName: Back diff --git a/Resources/Prototypes/Species/species_weights.yml b/Resources/Prototypes/Species/species_weights.yml index 5f165134952..a169559dcb4 100644 --- a/Resources/Prototypes/Species/species_weights.yml +++ b/Resources/Prototypes/Species/species_weights.yml @@ -3,4 +3,5 @@ id: SpeciesWeights weights: Human: 5 - Ghoul: 4 \ No newline at end of file + Ghoul: 4 + Supermutant: 10 # Forge-Change diff --git a/Resources/Prototypes/_Goobstation/Actions/types.yml b/Resources/Prototypes/_Goobstation/Actions/types.yml new file mode 100644 index 00000000000..93c14246540 --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Actions/types.yml @@ -0,0 +1,19 @@ +- type: entity + id: ActionHorn + name: Honk! + description: Beep the horn at whoever you will run over. + components: + - type: InstantAction + useDelay: 1 + icon: { sprite: Objects/Fun/bikehorn.rsi, state: icon } + event: !type:HornActionEvent + +- type: entity + id: ActionSiren + name: Siren + description: Alert your victim to your presence. + components: + - type: InstantAction + useDelay: 1 + icon: { sprite: Objects/Fun/bikehorn.rsi, state: icon } + event: !type:SirenActionEvent diff --git a/Resources/Prototypes/_Goobstation/Entities/Markers/Spawners/vehicles.yml b/Resources/Prototypes/_Goobstation/Entities/Markers/Spawners/vehicles.yml new file mode 100644 index 00000000000..f5f7ca49221 --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Entities/Markers/Spawners/vehicles.yml @@ -0,0 +1,55 @@ +- type: entity + name: Secway Spawner + id: SpawnVehicleSecway + parent: MarkerBase + components: + - type: Sprite + layers: + - state: green + - sprite: Objects/Vehicles/secway.rsi + state: keys + - type: ConditionalSpawner + prototypes: + - VehicleSecway + +- type: entity + name: ATV Spawner + id: SpawnVehicleATV + parent: MarkerBase + components: + - type: Sprite + layers: + - state: green + - sprite: Objects/Vehicles/atv.rsi + state: keys + - type: ConditionalSpawner + prototypes: + - VehicleATV + +- type: entity + name: Janicart Spawner + id: SpawnVehicleJanicart + parent: MarkerBase + components: + - type: Sprite + layers: + - state: green + - sprite: Objects/Vehicles/janicart.rsi + state: keys + - type: ConditionalSpawner + prototypes: + - VehicleJanicart + +- type: entity + name: Motorbike Spawner + id: SpawnVehicleMotorbike + parent: MarkerBase + components: + - type: Sprite + layers: + - state: green + - sprite: Objects/Vehicles/motorbike.rsi + state: keys + - type: ConditionalSpawner + prototypes: + - N14VehicleMotorbike diff --git a/Resources/Prototypes/_Goobstation/Entities/Unique/keys.yml b/Resources/Prototypes/_Goobstation/Entities/Unique/keys.yml new file mode 100644 index 00000000000..9af4a6c062d --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Entities/Unique/keys.yml @@ -0,0 +1,67 @@ +- type: entity + parent: BaseItem + id: BaseKey + abstract: true + categories: [ HideSpawnMenu ] + components: + - type: Item + size: Tiny + - type: Tag + tags: + - VehicleKey + +- type: entity + parent: BaseKey + id: VehicleKeySecway + name: secway keys + description: The keys to the future. + components: + - type: Sprite + sprite: Objects/Vehicles/secway.rsi + state: keys + - type: Tag + tags: + - VehicleKey + - SecwayKeys + +- type: entity + parent: BaseKey + id: VehicleKeySyndicateSegway + name: syndicate segway keys + description: Patterned after the iconic EMAG design. + components: + - type: Sprite + sprite: Objects/Vehicles/syndicatesegway.rsi + state: keys + - type: Tag + tags: + - VehicleKey + - SyndicateSegwayKeys + +- type: entity + parent: BaseKey + id: VehicleKeyATV + name: ATV keys + description: Think this looks like just one key? ATV keys means "actually two vehicle keys." + components: + - type: Sprite + sprite: Objects/Vehicles/atv.rsi + state: keys + - type: Tag + tags: + - VehicleKey + - ATVKeys + +- type: entity + parent: BaseKey + id: VehicleKeyJanicart + name: janicart keys + description: Interesting design. + components: + - type: Sprite + sprite: Objects/Vehicles/janicart.rsi + state: keys + - type: Tag + tags: + - VehicleKey + - JanicartKeys diff --git a/Resources/Prototypes/_Goobstation/Entities/Unique/motorbike_keys.yml b/Resources/Prototypes/_Goobstation/Entities/Unique/motorbike_keys.yml new file mode 100644 index 00000000000..04743a738ab --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Entities/Unique/motorbike_keys.yml @@ -0,0 +1,13 @@ +- type: entity + parent: BaseKey + id: VehicleKeyMotorbike + name: motorbike keys + description: Essential for starting a motorbike. + components: + - type: Sprite + sprite: Objects/Vehicles/motorbike.rsi + state: keys + - type: Tag + tags: + - VehicleKey + - MotorbikeKeys diff --git a/Resources/Prototypes/_Goobstation/Entities/Unique/siren.yml b/Resources/Prototypes/_Goobstation/Entities/Unique/siren.yml new file mode 100644 index 00000000000..60a7b03247c --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Entities/Unique/siren.yml @@ -0,0 +1,4 @@ +- type: soundCollection + id: PoliceSiren + files: + - /Audio/Effects/Vehicle/policesiren.ogg diff --git a/Resources/Prototypes/_Goobstation/Entities/Unique/vehicles.yml b/Resources/Prototypes/_Goobstation/Entities/Unique/vehicles.yml new file mode 100644 index 00000000000..feb6dae2d32 --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Entities/Unique/vehicles.yml @@ -0,0 +1,203 @@ +- type: entity + id: BaseVehicle + abstract: true + save: false + categories: [ HideSpawnMenu ] + components: + - type: Vehicle + renderOver: East, SouthEast, South, SouthWest, West + - type: Appearance + - type: AmbientSound + sound: "/Audio/Effects/Vehicle/vehicleengineidle.ogg" + range: 10 + volume: -10 + enabled: false + - type: InputMover + - type: Clickable + - type: InteractionOutline + - type: Access + - type: Physics + bodyType: Dynamic + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.45 + density: 100 + mask: + - MobMask + layer: + - MobLayer + hard: true + - type: Pullable + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - type: MovementSpeedModifier + acceleration: 8 + friction: 5 # wheels dont stop instantly + baseSprintSpeed: 7 + baseWalkSpeed: 4.5 # default walking speed + - type: ItemSlots + slots: + key_slot: + name: vehicle-slot-component-slot-name-keys + whitelist: + requireAll: true + tags: + - VehicleKey + insertSound: + path: /Audio/Effects/Vehicle/vehiclestartup.ogg + params: + volume: -3 + - type: StaticPrice + price: 2500 + - type: Tag + tags: + - DoorBumpOpener + +- type: entity + id: VehicleSecway + parent: BaseVehicle + name: secway + description: The future of transportation. Popularized by St. James, the patron saint of security officers and internet forum moderators. + components: + - type: Sprite + sprite: Objects/Vehicles/secway.rsi + state: vehicle + noRot: true + - type: Vehicle + hornSound: + collection: DeskBell + params: + variation: 0.125 + sirenSound: + collection: PoliceSiren + params: + variation: 0.125 + - type: Strap + position: Stand + - type: ItemSlots + slots: + key_slot: + name: vehicle-slot-component-slot-name-keys + whitelist: + requireAll: true + tags: + - VehicleKey + - SecwayKeys + insertSound: + path: /Audio/Effects/Vehicle/vehiclestartup.ogg + params: + volume: -3 + +- type: entity + id: VehicleSyndicateSegway + parent: VehicleSecway + name: syndicate segway + description: Be an enemy of the corporation, in style. + components: + - type: Sprite + sprite: Objects/Vehicles/syndicatesegway.rsi + state: vehicle + noRot: true + - type: Strap + position: Stand + - type: ItemSlots + slots: + key_slot: + name: vehicle-slot-component-slot-name-keys + insertSound: + path: /Audio/Effects/Vehicle/vehiclestartup.ogg + params: + volume: -3 + whitelist: + requireAll: true + tags: + - VehicleKey + - SyndicateSegwayKeys + +- type: entity + id: VehicleATV + parent: BaseVehicle + name: ATV + description: All-Tile Vehicle. + components: + - type: Sprite + sprite: Objects/Vehicles/atv.rsi + state: vehicle + noRot: true + - type: Vehicle + hornSound: + collection: BikeHorn + params: + variation: 0.125 + - type: Strap + position: Stand + - type: ItemSlots + slots: + key_slot: + name: vehicle-slot-component-slot-name-keys + whitelist: + requireAll: true + tags: + - VehicleKey + - ATVKeys + insertSound: + path: /Audio/Effects/Vehicle/vehiclestartup.ogg + params: + volume: -3 + +- type: entity + id: VehicleJanicart + parent: BaseVehicle + name: janicart + description: The janitor's trusty steed. + components: + - type: Sprite + sprite: Objects/Vehicles/janicart.rsi + state: vehicle + noRot: true + - type: Vehicle + - type: Strap + position: Stand + - type: ItemSlots + slots: + key_slot: + name: vehicle-slot-component-slot-name-keys + whitelist: + requireAll: true + tags: + - VehicleKey + - JanicartKeys + insertSound: + path: /Audio/Effects/Vehicle/vehiclestartup.ogg + params: + volume: -3 + - type: UnpoweredFlashlight + - type: PointLight + enabled: false + mask: /Textures/Effects/LightMasks/cone.png + autoRot: true + radius: 3.5 + softness: 2 + netsync: false + diff --git a/Resources/Prototypes/_Nuclear14/Body/Parts/Supermutant_parts.yml b/Resources/Prototypes/_Nuclear14/Body/Parts/Supermutant_parts.yml new file mode 100644 index 00000000000..f862f5c17ae --- /dev/null +++ b/Resources/Prototypes/_Nuclear14/Body/Parts/Supermutant_parts.yml @@ -0,0 +1,151 @@ +# Forge-Change +- type: entity + id: PartSupermutant + parent: [BaseItem, BasePart] + name: "Supermutant body part" + abstract: true + components: + - type: Damageable + damageContainer: OrganicPart # Shitmed Change + damageModifierSet: SupermutantPartDamage + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 800 + behaviors: + - !type:GibPartBehavior {} + - trigger: + !type:DamageTypeTrigger + damageType: Piercing + damage: 800 + behaviors: + - !type:GibPartBehavior {} + - trigger: + !type:DamageTypeTrigger + damageType: Slash + damage: 1600 + behaviors: + - !type:GibPartBehavior {} + - trigger: + !type:DamageTypeTrigger + damageType: Heat + damage: 800 + behaviors: + - !type:SpawnEntitiesBehavior + spawnInContainer: true + spawn: + Ash: + min: 2 + max: 5 + - !type:BurnBodyBehavior {} + - !type:PlaySoundBehavior + sound: + collection: MeatLaserImpact + sound: + collection: MeatLaserImpact + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Fat + Quantity: 5 + - ReagentId: Blood + Quantity: 10 + +- type: entity + id: TorsoSupermutant + name: "Supermutant torso" + parent: [PartSupermutant, BaseTorso] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "torso_m" + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Fat + Quantity: 10 + - ReagentId: Blood + Quantity: 40 + +- type: entity + id: HeadSupermutant + name: "Supermutant head" + parent: [PartSupermutant, BaseHead] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "head_m" + +- type: entity + id: LeftArmSupermutant + name: "left Supermutant arm" + parent: [PartSupermutant, BaseLeftArm] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "l_arm" + +- type: entity + id: RightArmSupermutant + name: "right Supermutant arm" + parent: [PartSupermutant, BaseRightArm] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "r_arm" + +- type: entity + id: LeftHandSupermutant + name: "left Supermutant hand" + parent: [PartSupermutant, BaseLeftHand] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "l_hand" + +- type: entity + id: RightHandSupermutant + name: "right Supermutant hand" + parent: [PartSupermutant, BaseRightHand] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "r_hand" + +- type: entity + id: LeftLegSupermutant + name: "left Supermutant leg" + parent: [PartSupermutant, BaseLeftLeg] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "l_leg" + +- type: entity + id: RightLegSupermutant + name: "right Supermutant leg" + parent: [PartSupermutant, BaseRightLeg] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "r_leg" + +- type: entity + id: LeftFootSupermutant + name: "left Supermutant foot" + parent: [PartSupermutant, BaseLeftFoot] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "l_foot" + +- type: entity + id: RightFootSupermutant + name: "right Supermutant foot" + parent: [PartSupermutant, BaseRightFoot] + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: "r_foot" diff --git a/Resources/Prototypes/_Nuclear14/Entities/Clothing/OuterClothing/supermutant_armor.yml b/Resources/Prototypes/_Nuclear14/Entities/Clothing/OuterClothing/supermutant_armor.yml new file mode 100644 index 00000000000..dd360c30efd --- /dev/null +++ b/Resources/Prototypes/_Nuclear14/Entities/Clothing/OuterClothing/supermutant_armor.yml @@ -0,0 +1,94 @@ +# Forge-Change +#MARK: Base Entity +- type: entity + abstract: true + parent: [Clothing] + id: N14FalloutMutantArmorBase + components: + - type: Clothing + slots: + - outerClothing + - type: Sprite + state: icon + - type: Craftable + +#MARK: Armor +- type: entity + parent: [N14FalloutMutantArmorBase, N14ClothingOuterBase] + id: N14ClothingMutantwild + name: броня супермутанта + description: Наспех сделан из грубой кожи и метлолома. + components: + - type: Sprite + sprite: _Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi + - type: Clothing + sprite: _Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi + - type: Armor + modifiers: + coefficients: + Blunt: 0.9 + Slash: 0.9 + Piercing: 0.95 + Heat: 0.9 + priceMultiplier: 0.2 + - type: ExplosionResistance + damageCoefficient: 0.95 + - type: Tag + tags: + - SupermutantArmor + # - type: ClothingSpecialModifier + # luckModifier: 1 + +#MARK: Armor +- type: entity + parent: [N14FalloutMutantArmorBase, N14ClothingOuterBase] + id: N14ClothingMutantmetal + name: металлическая броня супермутанта. + description: Массивная броня, сварен из нескольких полированных стальных пластин. + components: + - type: Sprite + sprite: _Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi + - type: Clothing + sprite: _Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi + - type: Armor + modifiers: + coefficients: + Blunt: 0.8 + Slash: 0.8 + Piercing: 0.85 + Heat: 0.8 + priceMultiplier: 0.4 + - type: ExplosionResistance + damageCoefficient: 0.85 + - type: Tag + tags: + - SupermutantArmor + # - type: ClothingSpecialModifier + # luckModifier: 1 + +#MARK: Armor +- type: entity + parent: [N14FalloutMutantArmorBase, N14ClothingOuterBase] + id: N14ClothingOuterMutantmaster + name: броня мутанта мастера. + description: Куча газовых труб и пластин, мастерски свареных и нанизанных на кожаное основание. + components: + - type: Sprite + sprite: _Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi + - type: Clothing + sprite: _Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi + - type: Armor + modifiers: + coefficients: + Blunt: 0.75 + Slash: 0.75 + Piercing: 0.8 + Heat: 0.85 + priceMultiplier: 0.5 + - type: ExplosionResistance + damageCoefficient: 0.85 + - type: Tag + tags: + - SupermutantArmor + # - type: ClothingSpecialModifier + # luckModifier: 1 diff --git a/Resources/Prototypes/_Nuclear14/Entities/Objects/Vehicles/cars.yml b/Resources/Prototypes/_Nuclear14/Entities/Objects/Vehicles/cars.yml new file mode 100644 index 00000000000..9e88e23813d --- /dev/null +++ b/Resources/Prototypes/_Nuclear14/Entities/Objects/Vehicles/cars.yml @@ -0,0 +1,197 @@ +# Forge-Change +- type: entity + id: BaseCars + parent: BaseMech + save: false + abstract: true + components: + - type: Repairable + fuelCost: 20 + doAfterDelay: 10 + - type: UserInterface + interfaces: + enum.MechUiKey.Key: + type: MechBoundUserInterface + enum.StorageUiKey.Key: + type: StorageBoundUserInterface + - type: DamageOtherOnHit + soundHit: + collection: MetalThud + - type: Puller + needsHands: false + - type: MovementSpeedModifier + acceleration: 8 + friction: 5 # wheels dont stop instantly + baseSprintSpeed: 7 + baseWalkSpeed: 4.5 # default walking speed + - type: AmbientSound + sound: "/Audio/Effects/Vehicle/vehicleengineidle.ogg" + range: 10 + volume: -10 + enabled: false + - type: Tag + tags: + - DoorBumpOpener + - FootstepSound + - type: Physics + bodyType: Dynamic + - type: Clickable + - type: InputMover + - type: InteractionOutline + - type: Access + - type: WiresPanel + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.9,0.5,0.9" + density: 21390 + mask: + - MachineMask + layer: + - MidImpassable + - LowImpassable + - BulletImpassable + - type: Appearance + - type: ContainerContainer + containers: + mech-pilot-slot: !type:ContainerSlot + mech-equipment-container: !type:Container + mech-battery-slot: !type:ContainerSlot + storagebase: !type:Container + - type: ContainerFill + containers: + mech-battery-slot: + - N14PowerCellFusion + - type: Damageable + damageContainer: Inorganic + damageModifierSet: LightArmor # Goobstation + - type: FootstepModifier + footstepSoundCollection: + path: /Audio/Mecha/cardrive.ogg + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 1000 # Goobstation + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: start + - !type:DoActsBehavior + acts: ["Destruction"] + # Goobstation Change Start + - type: StaticPrice + price: 2000 + # Goobstation Change End +# - type: Storage +# grid: +# - 0,0,9,5 +# maxItemSize: Ginormous + +- type: entity + parent: [ BaseCars, SpecialMech ] + id: N14Highwayman + name: Хайвеймен + description: Ничто не остановит „Хайвеймен“! + components: + - type: Sprite + drawdepth: Mobs + noRot: true + sprite: _Nuclear14/Objects/Vehicles/highwayman.rsi + layers: + - map: [ "enum.MechVisualLayers.Base" ] + state: highwayman2 + - type: Mech + baseState: highwayman2 + openState: highwayman1 + brokenState: highwayman_open + engineOnState: highwayman_open + mechToPilotDamageMultiplier: 0.5 + airtight: false + pilotWhitelist: + components: + - HumanoidAppearance + hornSound: + path: /Audio/Items/airhorn.ogg + mechHornAction: ActionMechHorn + +- type: entity + id: ActionMechHorn + name: action-name-mech-horn + description: action-description-mech-horn + components: + - type: InstantAction + icon: + sprite: Objects/Fun/bikehorn.rsi + state: icon + event: !type:HornActionEvent + useDelay: 2.0 + +- type: entity + id: ActionMechSiren + name: action-name-mech-siren + description: action-description-mech-siren + components: + - type: InstantAction + icon: + sprite: Objects/Fun/bikehorn.rsi + state: icon + event: !type:SirenActionEvent + useDelay: 0.5 + +- type: entity + parent: BaseKey + id: MechKey + name: Ключи от машины + description: Нужны для запуска двигателя. Не потеряй их! + components: + - type: Sprite + sprite: Objects/Vehicles/motorbike.rsi + state: keys + - type: IgnitionKey + - type: Tag + tags: + - MechKey + +- type: entity + id: ActionMechEjectPassenger1 + name: Eject passenger 1 + description: Ejects the first passenger from the mech + categories: [ HideSpawnMenu ] + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Interface/Actions/actions_mecha.rsi + state: mech_eject + event: !type:MechEjectPassenger1Event + +- type: entity + id: ActionMechEjectPassenger2 + name: Eject passenger 2 + description: Ejects the second passenger from the mech + categories: [ HideSpawnMenu ] + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Interface/Actions/actions_mecha.rsi + state: mech_eject + event: !type:MechEjectPassenger2Event + +- type: entity + id: ActionMechEjectPassenger3 + name: Eject passenger 3 + description: Ejects the third passenger from the mech + categories: [ HideSpawnMenu ] + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Interface/Actions/actions_mecha.rsi + state: mech_eject + event: !type:MechEjectPassenger3Event diff --git a/Resources/Prototypes/_Nuclear14/Entities/Objects/Vehicles/landvehicles.yml b/Resources/Prototypes/_Nuclear14/Entities/Objects/Vehicles/landvehicles.yml index a4029a93466..abd930f5e57 100644 --- a/Resources/Prototypes/_Nuclear14/Entities/Objects/Vehicles/landvehicles.yml +++ b/Resources/Prototypes/_Nuclear14/Entities/Objects/Vehicles/landvehicles.yml @@ -1,121 +1,198 @@ -# - type: entity - # parent: BaseVehicle - # id: N14VehicleBikeGreen - # name: green motorbike - # description: A clean green motorbike. - # components: - # - type: Vehicle - # northOverride: -0.1 - # southOverride: 0.1 - # - type: Sprite - # sprite: N14/Objects/Vehicles/bikesbuggy.rsi - # layers: - # - state: bike2 - # map: ["enum.VehicleVisualLayers.AutoAnimate"] - # netsync: false - # noRot: true -# # - type: RandomMetadata -# # descriptionSegments: [ATVDescriptions] - # - type: MovementSpeedModifier - # acceleration: 1 - # friction: 1 - # baseWalkSpeed: 4.5 - # baseSprintSpeed: 7 - # - type: Strap - # buckleOffset: "0.1, -0.05" - # - type: UnpoweredFlashlight - # toggleAction: - # name: action-name-toggle-light - # description: action-description-toggle-light - # icon: { sprite: Objects/Tools/flashlight.rsi, state: flashlight } - # iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png - # event: !type:ToggleActionEvent - # - type: PointLight - # enabled: false - # radius: 3.5 - # softness: 2 - # mask: /Textures/Effects/LightMasks/cone.png - # autoRot: true - # - type: ItemSlots - # slots: - # key_slot: - # name: Keys - # whitelist: - # requireAll: true - # tags: - # - VehicleKey - # - ATVKeys # TODO: Change this - # insertSound: - # path: /Audio/Effects/Vehicle/vehiclestartup.ogg - # params: - # volume: -3 +- type: entity + parent: BaseVehicle + id: N14VehicleBikeGreen + name: green motorbike + description: A clean green motorbike. + components: + - type: Sprite + sprite: _Nuclear14/Objects/Vehicles/bikesbuggy.rsi + layers: + - state: bike_green + map: ["enum.VehicleVisualLayers.AutoAnimate"] + netsync: false + noRot: true + - type: MovementSpeedModifier + acceleration: 1 + friction: 0.5 + baseWalkSpeed: 4.5 + baseSprintSpeed: 8 -# - type: entity - # parent: N14VehicleBikeGreen - # id: N14VehicleBikeFlamey - # name: flamey motorbike - # description: A motorbike with a flame decal. - # components: - # - type: Vehicle - # northOverride: -0.1 - # southOverride: 0.1 - # - type: Sprite - # layers: - # - state: bike_flamey2 - # map: ["enum.VehicleVisualLayers.AutoAnimate"] + - type: ItemSlots + slots: + key_slot: + name: Keys + whitelist: + requireAll: true + tags: + - VehicleKey + - MotorbikeKeys + insertSound: + path: /Audio/Effects/Vehicle/vehiclestartup.ogg + params: + volume: -3 -# - type: entity - # parent: N14VehicleBikeGreen - # id: N14VehicleBikeGreen2 - # name: flamey motorbike - # description: A green motorbike. - # components: - # - type: Vehicle - # northOverride: -0.1 - # southOverride: 0.1 - # - type: Sprite - # layers: - # - state: bike_green - # map: ["enum.VehicleVisualLayers.AutoAnimate"] +- type: entity + parent: N14VehicleBikeGreen + id: N14VehicleBikeFlamy + name: flamy motorbike + description: A motorbike with a flame decal. + components: + - type: Sprite + layers: + - state: bike_flamy2 + map: ["enum.VehicleVisualLayers.AutoAnimate"] + - type: Strap + position: Stand -# - type: entity - # parent: N14VehicleBikeGreen - # id: N14VehicleBikeRustLight - # name: rusty motorbike - # description: A rusty motorbike. - # components: - # - type: Vehicle - # northOverride: -0.1 - # southOverride: 0.1 - # - type: Sprite - # layers: - # - state: bike_rust_light - # map: ["enum.VehicleVisualLayers.AutoAnimate"] +- type: entity + parent: N14VehicleBikeGreen + id: N14VehicleBikeRustLight + name: rusty motorbike + description: A rusty motorbike. + components: + - type: Sprite + layers: + - state: bike_rust_light + map: ["enum.VehicleVisualLayers.AutoAnimate"] + - type: Strap + position: Stand -# - type: entity - # parent: N14VehicleBikeGreen - # id: N14VehicleBikeRustMedium - # name: rusty motorbike - # description: A really rusty motorbike. - # components: - # - type: Vehicle - # northOverride: -0.1 - # southOverride: 0.1 - # - type: Sprite - # layers: - # - state: bike_rust_med - # map: ["enum.VehicleVisualLayers.AutoAnimate"] +- type: entity + parent: N14VehicleBikeGreen + id: N14VehicleBikeScrambler + name: scrambler motorbike + description: A scrambler type motorbike. + components: + - type: Sprite + layers: + - state: bike_scrambler2 + map: ["enum.VehicleVisualLayers.AutoAnimate"] + - type: Strap + position: Stand -# - type: entity - # parent: N14VehicleBikeGreen - # id: N14VehicleBikeScrambler - # name: scrambler motorbike - # description: A scrambler type motorbike. - # components: - # - type: Vehicle - # northOverride: -0.1 - # southOverride: 0.1 - # - type: Sprite - # layers: - # - state: bike_scrambler2 - # map: ["enum.VehicleVisualLayers.AutoAnimate"] \ No newline at end of file +- type: entity + parent: N14VehicleBikeGreen + id: N14VehicleBikeClassic + name: classic motorbike + description: A reliable two-wheeler. + components: + - type: Sprite + layers: + - state: bike2 + map: ["enum.VehicleVisualLayers.AutoAnimate"] + - type: Strap + position: Stand + +- type: entity + parent: BaseVehicle + id: N14VehicleBuggyDune + name: dune buggy + description: A rugged offroad buggy. + components: + - type: Vehicle + renderOver: North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest + - type: Sprite + sprite: _Nuclear14/Objects/Vehicles/bikesbuggy.rsi + layers: + - state: buggy_dune + map: ["enum.VehicleVisualLayers.AutoAnimate"] + - state: buggy_dune_cover + map: ["enum.VehicleVisualLayers.Cover"] + netsync: false + noRot: true + - type: MovementSpeedModifier + acceleration: 1 + friction: 0.5 + baseWalkSpeed: 4.5 + baseSprintSpeed: 8 + - type: ItemSlots + slots: + key_slot: + name: Keys + whitelist: + requireAll: true + tags: + - VehicleKey + insertSound: + path: /Audio/Effects/Vehicle/vehiclestartup.ogg + params: + volume: -3 + - type: Strap + position: Stand + +- type: entity + parent: N14VehicleBuggyDune + id: N14VehicleBuggyOlive + name: olive buggy + description: A green offroad buggy. + components: + - type: Sprite + layers: + - state: buggy_olive + map: ["enum.VehicleVisualLayers.AutoAnimate"] + - state: buggy_olive_cover + map: ["enum.VehicleVisualLayers.Cover"] + - type: Strap + position: Stand + +- type: entity + parent: N14VehicleBuggyDune + id: N14VehicleBuggyRed + name: red buggy + description: A bright red buggy ready to roll. + components: + - type: Sprite + layers: + - state: buggy_red + map: ["enum.VehicleVisualLayers.AutoAnimate"] + - state: buggy_red_cover + map: ["enum.VehicleVisualLayers.Cover"] + - type: Strap + position: Stand + +- type: entity + parent: N14VehicleBuggyDune + id: N14VehicleBuggyHot + name: hot buggy + description: A flashy buggy with flame decals. + components: + - type: Sprite + layers: + - state: buggy_hot + map: ["enum.VehicleVisualLayers.AutoAnimate"] + - state: buggy_hot_cover + map: ["enum.VehicleVisualLayers.Cover"] + - type: Strap + position: Stand + +- type: entity + parent: BaseVehicle + id: N14VehicleMotorbike + name: motorbike + description: A rugged two-wheeler ready to ride. + components: + - type: Vehicle + - type: Sprite + sprite: Objects/Vehicles/motorbike.rsi + state: vehicle + noRot: true + - type: MovementSpeedModifier + acceleration: 1 + friction: 0.5 + baseWalkSpeed: 4.5 + baseSprintSpeed: 8 + - type: ItemSlots + slots: + key_slot: + name: Keys + whitelist: + requireAll: true + tags: + - VehicleKey + - MotorbikeKeys + insertSound: + path: /Audio/Effects/Vehicle/vehiclestartup.ogg + params: + volume: -3 + - type: Strap + position: Stand diff --git a/Resources/Prototypes/_Nuclear14/Entities/Structures/Doors/access.yml b/Resources/Prototypes/_Nuclear14/Entities/Structures/Doors/access.yml index 9e1fb465414..9d59f673642 100644 --- a/Resources/Prototypes/_Nuclear14/Entities/Structures/Doors/access.yml +++ b/Resources/Prototypes/_Nuclear14/Entities/Structures/Doors/access.yml @@ -403,6 +403,28 @@ - type: Wires layoutId: AirlockService +# Forge-Change-Start +- type: entity + parent: N14DoorMakeshift + id: N14DoorMakeshiftSecureLockedTownsPerson + suffix: Townie, Locked + components: + - type: AccessReader + access: [ [ "TownsPerson" ] ] + - type: Wires + layoutId: AirlockService + +- type: entity + parent: N14DoorWoodSecure + id: N14DoorWoodSecureLockedTownsPerson + suffix: Townie, Locked + components: + - type: AccessReader + access: [ [ "TownsPerson" ] ] + - type: Wires + layoutId: AirlockService +# Forge-Change-End + # Wastelander - type: entity diff --git a/Resources/Prototypes/_Nuclear14/Entities/Structures/Doors/access_slanted.yml b/Resources/Prototypes/_Nuclear14/Entities/Structures/Doors/access_slanted.yml index 679456e0e56..64a2910a07a 100644 --- a/Resources/Prototypes/_Nuclear14/Entities/Structures/Doors/access_slanted.yml +++ b/Resources/Prototypes/_Nuclear14/Entities/Structures/Doors/access_slanted.yml @@ -211,6 +211,38 @@ - type: Wires layoutId: AirlockService +# Forge-Change-Start +- type: entity + parent: N14DoorWoodRedSlanted + id: N14DoorWoodSlantedLockedTownsPerson + suffix: Townie, Locked + components: + - type: AccessReader + access: [["TownsPerson"]] + - type: Wires + layoutId: AirlockService + +- type: entity + parent: N14DoorMetalBarSlanted + id: N14DoorCellSlantedLockedTownsPerson + suffix: Townie, Locked + components: + - type: AccessReader + access: [["TownsPerson"]] + - type: Wires + layoutId: AirlockService + +- type: entity + parent: N14DoorMetalBlueSlanted + id: N14DoorMetalSlantedLockedIronTownsPerson + suffix: Townie, Locked + components: + - type: AccessReader + access: [["TownsPerson"]] + - type: Wires + layoutId: AirlockService +# Forge-Change-End + #MARK: Vault - type: entity parent: N14DoorAirlockSlanted @@ -402,4 +434,4 @@ - type: AccessReader access: [["SilverKey"]] - type: Wires - layoutId: AirlockCargo \ No newline at end of file + layoutId: AirlockCargo diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/BrotherhoodMidwest/squire.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/BrotherhoodMidwest/squire.yml index 904c712e98a..6473ef5de71 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/BrotherhoodMidwest/squire.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/BrotherhoodMidwest/squire.yml @@ -13,6 +13,7 @@ species: - Human - Ghoul + - Supermutant # Forge-Change - !type:CharacterOverallTimeRequirement min: 3600 startingGear: BoSMidSquireGear diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Fun/followers.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Fun/followers.yml index 6f0b17d61ed..df3ce9f8201 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Fun/followers.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Fun/followers.yml @@ -10,6 +10,7 @@ min: 18000 # 5 hour icon: "JobIconPassenger" supervisors: job-supervisors-followers + alwaysUseSpawner: true # # Forge-Change accessGroups: - FollowersApocalypse # Forge-Change-Start diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Towndoctor.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Towndoctor.yml index 62ee125d2fc..ce891478aa2 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Towndoctor.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Towndoctor.yml @@ -17,9 +17,10 @@ startingGear: TownDoctorGear icon: "JobIconTownMedic" # Corvax-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - TownieDoctor - - TownsPerson # Corvax-Change + - TownsPerson # Forge-Change special: - !type:AddComponentSpecial components: @@ -33,7 +34,7 @@ id: TownDoctorGear equipment: jumpsuit: N14ClothingUniformJumpsuitWastelandDoc - back: N14ClothingBackpackExplorer # Corvax-Change + back: N14ClothingBackpackExplorer # Forge-Change shoes: N14ClothingShoesBlack gloves: N14ClothingHandsGlovesNitrile id: N14IDDoctorTown @@ -41,7 +42,7 @@ innerClothingSkirt: N14ClothingUniformJumpskirtFalloutBlack satchel: N14ClothingBackpackSatchelWastelanderFilled duffelbag: N14ClothingBackpackDuffelFilled # N14TODO: Doctors Bag - storage: # Corvax-Change + storage: # Forge-Change back: - N14BoxPlasticFilledWastelander diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townmechanic.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townmechanic.yml index 5830a941bd9..9a143f68cbd 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townmechanic.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townmechanic.yml @@ -17,6 +17,7 @@ startingGear: TownMechanicGear icon: "JobIconTownMechanic" # Forge-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - TownieMechanic - TownsPerson # Forge-Change diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townshopkeeper.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townshopkeeper.yml index 2bda46b6688..418120f591b 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townshopkeeper.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townshopkeeper.yml @@ -20,9 +20,10 @@ startingGear: TownShopkeeperGear icon: "JobIconTownShopKeeper" # Corvax-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - TownieShopkeeper - - TownsPerson # Corvax-Change + - TownsPerson # Forge-Change special: - !type:AddComponentSpecial components: @@ -36,14 +37,14 @@ id: TownShopkeeperGear equipment: jumpsuit: N14ClothingUniformJumpsuitMerchant - back: N14ClothingBackpackHiking # Corvax-Change + back: N14ClothingBackpackHiking # Forge-Change shoes: N14ClothingShoesBlack id: N14IDShopkeeperTown belt: N14WalletCash innerClothingSkirt: N14ClothingUniformJumpskirtFalloutBlack satchel: N14ClothingBackpackSatchelWastelanderFilled duffelbag: N14ClothingBackpackDuffelFilled # N14TODO: Trader bag - storage: # Corvax-Change + storage: # Forge-Change back: - N14BoxPlasticFilledWastelander diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townsperson.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townsperson.yml index 13cc6110763..c67d937d57d 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townsperson.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/Townsperson.yml @@ -14,10 +14,11 @@ - !type:CharacterOverallTimeRequirement min: 3600 # 1 hour startingGear: TownspersonGear - icon: "JobIconTownPerson" # Corvax-Change + icon: "JobIconTownPerson" # Forge-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - - TownsPerson # Corvax-Change + - TownsPerson # Forge-Change special: - !type:AddComponentSpecial components: @@ -30,13 +31,13 @@ id: TownspersonGear equipment: jumpsuit: N14ClothingUniformJumpsuitSettlerRags - back: N14ClothingBackpackExplorer # Corvax-Change + back: N14ClothingBackpackExplorer # Forge-Change shoes: N14ClothingShoesBlack id: N14IDPassportTownsfolk innerClothingSkirt: N14ClothingUniformJumpskirtFalloutBlack satchel: N14ClothingBackpackSatchelWastelanderFilled duffelbag: N14ClothingBackpackDuffelFilled - storage: # Corvax-Change + storage: # Forge-Change back: - N14BoxPlasticFilledWastelander diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/bartender.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/bartender.yml index 36d24690b63..187f755c95d 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/bartender.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/bartender.yml @@ -17,9 +17,10 @@ startingGear: WastelandBartenderGear icon: "JobIconBartender" supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - WastelandBartender - - TownsPerson # Corvax-Change + - TownsPerson # Forge-Change - InnRoomOne - InnRoomTwo - InnRoomThree @@ -38,13 +39,13 @@ head: ClothingHeadHatTophat jumpsuit: N14ClothingUniformJumpsuitBartenderAlt outerClothing: N14ClothingOuterLeatherArmor - back: N14ClothingBackpackExplorer # Corvax-Change + back: N14ClothingBackpackExplorer # Forge-Change shoes: N14ClothingBootsLeather id: N14IDBartenderTown innerClothingSkirt: N14ClothingUniformJumpsuitBartenderAlt #placeholder satchel: N14ClothingBackpackSatchelWastelanderFilled duffelbag: N14ClothingBackpackDuffelFilled - storage: # Corvax-Change + storage: # Forge-Change back: - N14BoxPlasticFilledWastelander diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/reporter.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/reporter.yml index c6c6531ed10..7050c9d8471 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/reporter.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/reporter.yml @@ -15,11 +15,12 @@ department: Townsfolk min: 7200 # 2 hours startingGear: WastelandReporterGear - icon: "JobIconTownReporter" # Corvax-Change + icon: "JobIconTownReporter" # Forge-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - WastelandReporter - - TownsPerson # Corvax-Change + - TownsPerson # Forge-Change special: - !type:AddComponentSpecial components: @@ -32,13 +33,13 @@ id: WastelandReporterGear equipment: jumpsuit: N14ClothingUniformJumpsuitDetectiveAlt - back: N14ClothingBackpackExplorer # Corvax-Change + back: N14ClothingBackpackExplorer # Forge-Change shoes: N14ClothingShoesBlack id: N14IDReporterTown innerClothingSkirt: N14ClothingUniformJumpsuitDetectiveAlt satchel: N14ClothingBackpackSatchelWastelanderFilled duffelbag: N14ClothingBackpackDuffelFilled - storage: # Corvax-Change + storage: # Forge-Change back: - N14BoxPlasticFilledWastelander diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/towndeputy.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/towndeputy.yml index 6cd7d0a2850..cec4cdb94b2 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/towndeputy.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/towndeputy.yml @@ -17,6 +17,7 @@ startingGear: TownDeputyGear icon: "JobIconTownDeputy" # Forge-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - TownieLaw - TownieMechanic diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/townmayor.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/townmayor.yml index 52781bb018b..196b278c189 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/townmayor.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/townmayor.yml @@ -17,6 +17,7 @@ startingGear: TownMayorGear icon: "JobIconTownMayor" # Corvax-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change accessGroups: - Townie special: @@ -31,7 +32,7 @@ id: TownMayorGear equipment: jumpsuit: N14ClothingUniformJumpsuitCheckered - back: N14ClothingBackpackExplorer # Corvax-Change + back: N14ClothingBackpackExplorer # Forge-Change shoes: N14ClothingShoesBrown id: N14IDBadgeTownMayor pocket1: RadioHandheld @@ -39,7 +40,7 @@ innerClothingSkirt: N14ClothingUniformJumpskirtFalloutBlack satchel: N14ClothingBackpackSatchelMayorFilled duffelbag: N14ClothingBackpackDuffelMayorFilled - storage: # Corvax-Change + storage: # Forge-Change back: - N14BoxPlasticFilledWastelander diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/townsheriff.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/townsheriff.yml index bbf73b69f87..2b1416fbd90 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/townsheriff.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Townsfolk/townsheriff.yml @@ -18,14 +18,15 @@ tracker: TownDeputy min: 14400 # 4 hours startingGear: TownSheriffGear - icon: "JobIconTownSheriff" # Corvax-Change + icon: "JobIconTownSheriff" # Forge-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - TownieLaw - TownieMechanic - TownieDoctor - WastelandReporter - - TownsPerson # Corvax-Change + - TownsPerson # Forge-Change special: - !type:AddComponentSpecial components: diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Wastelanders/chaplain.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Wastelanders/chaplain.yml index bb9324eae45..32d7e278f8d 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Wastelanders/chaplain.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Wastelanders/chaplain.yml @@ -17,6 +17,7 @@ startingGear: WastelandChaplainGear icon: "JobIconWastelandChaplain" # Forge-Change supervisors: job-supervisors-townsfolk + alwaysUseSpawner: true # Forge-Change access: - WastelandChaplain - TownsPerson # Forge-Change diff --git a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Wastelanders/farmer.yml b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Wastelanders/farmer.yml index 6be80a500a4..0428d177323 100644 --- a/Resources/Prototypes/_Nuclear14/Roles/Jobs/Wastelanders/farmer.yml +++ b/Resources/Prototypes/_Nuclear14/Roles/Jobs/Wastelanders/farmer.yml @@ -7,17 +7,18 @@ description: job-description-farmer playTimeTracker: Farmer startingGear: FarmerGear - icon: "JobIconWastelandFarmer" # Corvax-Change + icon: "JobIconWastelandFarmer" # Forge-Change supervisors: job-supervisors-wastelander + alwaysUseSpawner: true # Forge-Change access: - WastelandFarmer - - TownsPerson # Corvax-Change + - TownsPerson # Forge-Change - type: startingGear id: FarmerGear equipment: jumpsuit: N14ClothingUniformJumpsuitBrahminFarmer - back: N14ClothingBackpackExplorer # Corvax-Change + back: N14ClothingBackpackExplorer # Forge-Change shoes: N14ClothingBootsLeather outerClothing: ClothingOuterApronBotanist belt: ClothingBeltFarmerFilled @@ -25,7 +26,7 @@ innerClothingSkirt: N14ClothingUniformJumpsuitBrahminFarmer #placeholder satchel: N14ClothingBackpackSatchelWastelanderFilled duffelbag: N14ClothingBackpackDuffelFilled - storage: # Corvax-Change + storage: # Forge-Change back: - N14BoxPlasticFilledWastelander diff --git a/Resources/Prototypes/_Nuclear14/Species/Supermutant.yml b/Resources/Prototypes/_Nuclear14/Species/Supermutant.yml new file mode 100644 index 00000000000..87d09d519fc --- /dev/null +++ b/Resources/Prototypes/_Nuclear14/Species/Supermutant.yml @@ -0,0 +1,549 @@ +# Forge-Change +- type: entity + id: OrganSupermutantHeart + parent: OrganHumanHeart + name: Supermutant heart + components: + - type: Metabolizer + metabolizerTypes: [ Human ] + +- type: entity + id: OrganSupermutantLiver + parent: OrganHumanLiver + name: Supermutant liver + components: + - type: Metabolizer + metabolizerTypes: [ Human ] + +- type: entity + id: OrganSupermutantStomach + parent: OrganHumanStomach + name: Supermutant stomach + components: + - type: Sprite + state: stomach + - type: Organ + - type: SolutionContainerManager + solutions: + stomach: + maxVol: 100 + food: + maxVol: 5 + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 5 + - type: Stomach + - type: Metabolizer + # mm very yummy + maxReagents: 5 + metabolizerTypes: [ Human ] + +- type: body + id: Supermutant + name: "Supermutant" + root: torso + slots: + head: + part: HeadSupermutant + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganHumanEyes + torso: + part: TorsoSupermutant + connections: + - right arm + - left arm + - right leg + - left leg + organs: + heart: OrganSupermutantHeart + lungs: OrganHumanLungs + stomach: OrganHumanStomach + liver: OrganSupermutantLiver + kidneys: OrganHumanKidneys + right arm: + part: RightArmSupermutant + connections: + - right hand + left arm: + part: LeftArmSupermutant + connections: + - left hand + right hand: + part: RightHandSupermutant + left hand: + part: LeftHandSupermutant + right leg: + part: RightLegSupermutant + connections: + - right foot + left leg: + part: LeftLegSupermutant + connections: + - left foot + right foot: + part: RightFootSupermutant + left foot: + part: LeftFootSupermutant + +- type: metabolizerType + id: supermutant + name: metabolizer-type-supermutant + +- type: entity + save: false + name: Urist McHands The Supermutant + parent: BaseMobSpeciesOrganic + id: BaseMobSupermutant + abstract: true + components: + - type: Sprite + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + netsync: false + noRot: true + drawdepth: Mobs + layers: + - map: [ "enum.HumanoidVisualLayers.Chest" ] + - map: [ "enum.HumanoidVisualLayers.Head" ] + - map: [ "enum.HumanoidVisualLayers.Snout" ] + - map: [ "enum.HumanoidVisualLayers.Eyes" ] + - map: [ "enum.HumanoidVisualLayers.RArm" ] + - map: [ "enum.HumanoidVisualLayers.LArm" ] + - map: [ "enum.HumanoidVisualLayers.RLeg" ] + - map: [ "enum.HumanoidVisualLayers.LLeg" ] + - shader: StencilClear + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: l_leg + - shader: StencilMask + map: [ "enum.HumanoidVisualLayers.StencilMask" ] + sprite: Mobs/Customization/masking_helpers.rsi + state: female_full + visible: false + - map: [ "jumpsuit" ] + - map: [ "enum.HumanoidVisualLayers.LHand" ] + - map: [ "enum.HumanoidVisualLayers.RHand" ] + - map: [ "enum.HumanoidVisualLayers.LFoot" ] + - map: [ "enum.HumanoidVisualLayers.RFoot" ] + - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] + color: "#ffffff" + sprite: Objects/Misc/handcuffs.rsi + state: body-overlay-2 + visible: false + - map: [ "id" ] + - map: [ "gloves" ] + - map: [ "shoes" ] + - map: [ "ears" ] + - map: [ "outerClothing" ] + - map: [ "eyes" ] + - map: [ "belt" ] + - map: [ "neck" ] + - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.FacialHair" ] + - map: [ "enum.HumanoidVisualLayers.Hair" ] + - map: [ "enum.HumanoidVisualLayers.HeadSide" ] + - map: [ "enum.HumanoidVisualLayers.HeadTop" ] + - map: [ "enum.HumanoidVisualLayers.Tail" ] + - map: [ "mask" ] + - map: [ "head" ] + - map: [ "pocket1" ] + - map: [ "pocket2" ] + - type: Perishable + rotAfter: 3600 # An entire in-game day. + - type: Hunger + thresholds: + Overfed: 400 + Okay: 300 + Peckish: 200 + Starving: 100 + Dead: 0 + baseDecayRate: 0.09 + starvationDamage: + types: + Cold: 0.15 + starvingSlowdownModifier: 0.5 + - type: Thirst + thresholds: + OverHydrated: 400 + Okay: 300 + Thirsty: 200 + Parched: 100 + Dead: 0 + baseDecayRate: 0.15 + - type: Icon + sprite: Mobs/Species/Slime/parts.rsi # It was like this beforehand, no idea why. + state: full + - type: Respirator + damage: + types: + Asphyxiation: 1 + Bloodloss: 0.5 + damageRecovery: + types: + Asphyxiation: -1 + - type: Body + prototype: Supermutant + requiredLegs: 2 + - type: Butcherable + butcheringType: Spike + spawned: + - id: FoodMeatHuman + amount: 4 + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.4 + # they r smaller + density: 150 + restitution: 0.0 + mask: + - MobMask + layer: + - MobLayer + - type: Vocal + sounds: + Male: MaleSupermutant + Female: FemaleSupermutant + Unsexed: MaleSupermutant + - type: Speech + speechSounds: Alto + - type: HumanoidAppearance + species: Supermutant + - type: MobThresholds + thresholds: + 0: Alive + 200: Critical + 400: Dead + - type: MovementSpeedModifier + baseWalkSpeed: 3.4 + baseSprintSpeed: 3.4 + - type: SlowOnDamage + speedModifierThresholds: + 100: 1 + 120: 0.9 + 150: 0.8 + 175: 0.7 + 190: 0.5 + - type: MeleeWeapon + altDisarm: true + attackRate: 1.5 + angle: 60 + damage: + types: + Blunt: 15 + - type: Inventory + templateId: supermutant + - type: Tag + tags: + - CanPilot + - FootstepSound + - DoorBumpOpener + - SupermutantArmor + - type: Damageable + damageModifierSet: Supermutant + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 2500 + behaviors: + - !type:GibPartBehavior {} + - trigger: + !type:DamageTypeTrigger + damageType: Heat + damage: 2500 + behaviors: + - !type:SpawnEntitiesBehavior + spawnInContainer: true + spawn: + Ash: + min: 2 + max: 5 + - !type:BurnBodyBehavior {} + - !type:PlaySoundBehavior + sound: + collection: MeatLaserImpact + - type: WhitelistClothing + whitelist: SupermutantArmor + whitelistState: humanoid + - type: Stamina + critThreshold: 200 + + + + - type: Bloodstream + bloodlossDamage: + types: + Bloodloss: 0.5 + bloodlossHealDamage: + types: + Bloodloss: -1.5 + bloodRegenerationHunger: 1.5 + bloodRegenerationThirst: 2 + bloodMaxVolume: 200 + bloodReagent: WastelandBlood + + - type: DamageVisuals + damageOverlayGroups: + Brute: + sprite: Mobs/Effects/brute_damage.rsi + color: "#88221f" + + - type: Barotrauma + damage: + types: + Blunt: 0.30 #per second, scales with pressure and other constants. + Heat: 0.05 + - type: PassiveDamage # Slight passive regen. Assuming one damage type, comes out to about 4 damage a minute. + allowedStates: + - Alive + - Critical + damageCap: 300 + damage: + types: + Heat: -0.5 + Poison: -0.5 + Radiation: -0.1 + groups: + Brute: -0.5 + Genetic: -10 + +- type: damageModifierSet + id: Supermutant + coefficients: + Blunt: 1.0 + Slash: 1.0 + Piercing: 1.0 + Heat: 1.0 + Poison: 0.1 + Cold: 0.5 + Shock: 1.0 + Radiation: 0.1 + Cellular: 0.0 + +- type: entity + save: false + name: Urist McSupermutant + parent: MobHumanDummy + id: MobSupermutantDummy + categories: [ HideSpawnMenu ] + components: + - type: HumanoidAppearance + species: Supermutant + +- type: species + id: Supermutant + name: Супермутант + roundStart: false + prototype: MobSupermutant + sprites: MobSupermutantSprites + markingLimits: MobSupermutantMarkingLimits + dollPrototype: MobSupermutantDummy + skinColoration: Hues + minHeight: 1.45 # Corvax-Change + maxHeight: 1.71 # Corvax-Change + minWidth: 1.45 # Corvax-Change + maxWidth: 1.77 # Corvax-Change + minAge: 50 # Corvax-Change + oldAge: 150 # Corvax-Change + maxAge: 200 # Corvax-Change + +- type: markingPoints + id: MobSupermutantMarkingLimits + points: + Hair: + points: 1 + required: false + FacialHair: + points: 0 + required: false + +- type: speciesBaseSprites + id: MobSupermutantSprites + sprites: + Head: MobSupermutantHead + Hair: MobHumanoidAnyMarking + FacialHair: MobHumanoidAnyMarking + Snout: MobHumanoidAnyMarking + Chest: MobSupermutantTorso + Eyes: MobHumanoidEyes + LArm: MobSupermutantLArm + RArm: MobSupermutantRArm + LHand: MobSupermutantLHand + RHand: MobSupermutantRHand + LLeg: MobSupermutantLLeg + RLeg: MobSupermutantRLeg + LFoot: MobSupermutantLFoot + RFoot: MobSupermutantRFoot + +- type: humanoidBaseSprite + id: MobSupermutantHead + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobSupermutantHeadMale + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobSupermutantHeadFemale + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobSupermutantTorso + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobSupermutantTorsoMale + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobSupermutantTorsoFemale + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobSupermutantLLeg + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobSupermutantLArm + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobSupermutantLHand + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobSupermutantLFoot + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobSupermutantRLeg + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobSupermutantRArm + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobSupermutantRHand + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobSupermutantRFoot + baseSprite: + sprite: _Nuclear14/Mobs/Species/Supermutant/parts.rsi + state: r_foot + +- type: entity + save: false + name: Urist Supermutant + parent: BaseMobSupermutant + id: MobSupermutant + components: + - type: NpcFactionMember + factions: + - Wastelander + +- type: emoteSounds + id: MaleSupermutant + params: + variation: 0.125 + pitch: 0.55 + sounds: + Scream: + collection: MaleScreams + Laugh: + collection: MaleLaugh + Sneeze: + collection: MaleSneezes + Cough: + collection: MaleCoughs + CatMeow: + collection: CatMeows + CatHisses: + collection: CatHisses + MonkeyScreeches: + collection: MonkeyScreeches + RobotBeep: + collection: RobotBeeps + Yawn: + collection: MaleYawn + Snore: + collection: Snores + Honk: + collection: BikeHorn + Sigh: + collection: MaleSigh + Crying: + collection: MaleCry + Whistle: + collection: Whistles + Weh: + collection: Weh + +- type: emoteSounds + id: FemaleSupermutant + params: + variation: 0.125 + pitch: 0.50 + sounds: + Scream: + collection: FemaleScreams + Laugh: + collection: FemaleLaugh + Sneeze: + collection: FemaleSneezes + Cough: + collection: FemaleCoughs + CatMeow: + collection: CatMeows + CatHisses: + collection: CatHisses + MonkeyScreeches: + collection: MonkeyScreeches + RobotBeep: + collection: RobotBeeps + Yawn: + collection: FemaleYawn + Snore: + collection: Snores + Honk: + collection: CluwneHorn + Sigh: + collection: FemaleSigh + Crying: + collection: FemaleCry + Whistle: + collection: Whistles + Weh: + collection: Weh diff --git a/Resources/Prototypes/_Nuclear14/tags.yml b/Resources/Prototypes/_Nuclear14/tags.yml index 2014b5bdde6..0227d7a3003 100644 --- a/Resources/Prototypes/_Nuclear14/tags.yml +++ b/Resources/Prototypes/_Nuclear14/tags.yml @@ -82,6 +82,9 @@ - type: Tag id: Scrap +- type: Tag + id: SupermutantArmor + - type: Tag id: Phial @@ -303,11 +306,6 @@ - type: Tag id: N14LMGMagazine556Rifle -# Forge-Add-Start -- type: Tag - id: Magazine556Rifle30 -# Forge-Add-End - - type: Tag id: N14Magazine762Rifle @@ -326,9 +324,6 @@ - type: Tag id: N14Magazine308Rifle -- type: Tag # forge-add - id: N14Magazine308RifleSnipers - - type: Tag id: N14Magazine308RifleLong @@ -426,3 +421,22 @@ - type: Tag id: NightstalkerPelt + +- type: Tag + id: MotorbikeKeys + +- type: Tag + id: VehicleKey + +- type: Tag + id: JanicartKeys +# Forge-Change-start +- type: Tag + id: MechKey + +- type: Tag + id: Magazine556Rifle30 + +- type: Tag + id: N14Magazine308RifleSnipers +# Forge-Change-end diff --git a/Resources/Prototypes/_Shitmed/Damage/modifier_sets.yml b/Resources/Prototypes/_Shitmed/Damage/modifier_sets.yml index 5992081ac13..4367f602844 100644 --- a/Resources/Prototypes/_Shitmed/Damage/modifier_sets.yml +++ b/Resources/Prototypes/_Shitmed/Damage/modifier_sets.yml @@ -13,3 +13,10 @@ coefficients: Decay: 1.0 Trauma: 1.0 +# Forge-Change-start +- type: damageModifierSet + id: SupermutantPartDamage + coefficients: + Slash: 0.5 + Cold: 0.5 +# Forge-Change-end diff --git a/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/equipped-INNERCLOTHING.png new file mode 100644 index 00000000000..878ef3d9470 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/equipped-INNERCLOTHING.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/icon.png b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/icon.png new file mode 100644 index 00000000000..2b9142c1445 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/icon.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/inhand-left.png b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/inhand-left.png new file mode 100644 index 00000000000..14811c8b82d Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/inhand-left.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/inhand-right.png b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/inhand-right.png new file mode 100644 index 00000000000..0be4a135eeb Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/inhand-right.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/meta.json b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/meta.json new file mode 100644 index 00000000000..654e27cf242 --- /dev/null +++ b/Resources/Textures/_Nuclear14/Clothing/InnerClothingm/alkotop.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "RavenReaper", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-INNERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/equipped-OUTERCLOTHING.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/equipped-OUTERCLOTHING.png new file mode 100644 index 00000000000..a90ef55e63a Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/equipped-OUTERCLOTHING.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/icon.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/icon.png new file mode 100644 index 00000000000..d07dcd09cf2 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/icon.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/inhand-left.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/inhand-left.png new file mode 100644 index 00000000000..c5a659d146d Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/inhand-left.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/inhand-right.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/inhand-right.png new file mode 100644 index 00000000000..03cc2e1abb2 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/inhand-right.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/meta.json b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/meta.json new file mode 100644 index 00000000000..835c6208ecf --- /dev/null +++ b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/master.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Made by RavenReaper", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-OUTERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/equipped-OUTERCLOTHING.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/equipped-OUTERCLOTHING.png new file mode 100644 index 00000000000..48b59f16b90 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/equipped-OUTERCLOTHING.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/icon.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/icon.png new file mode 100644 index 00000000000..d8399684ed1 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/icon.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/inhand-left.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/inhand-left.png new file mode 100644 index 00000000000..e41f6c1ebd6 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/inhand-left.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/inhand-right.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/inhand-right.png new file mode 100644 index 00000000000..8cb1f49df56 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/inhand-right.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/meta.json b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/meta.json new file mode 100644 index 00000000000..835c6208ecf --- /dev/null +++ b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/metal.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Made by RavenReaper", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-OUTERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/equipped-OUTERCLOTHING.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/equipped-OUTERCLOTHING.png new file mode 100644 index 00000000000..dab83e7867c Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/equipped-OUTERCLOTHING.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/icon.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/icon.png new file mode 100644 index 00000000000..6859eb83fae Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/icon.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/inhand-left.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/inhand-left.png new file mode 100644 index 00000000000..e41f6c1ebd6 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/inhand-left.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/inhand-right.png b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/inhand-right.png new file mode 100644 index 00000000000..8cb1f49df56 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/inhand-right.png differ diff --git a/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/meta.json b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/meta.json new file mode 100644 index 00000000000..835c6208ecf --- /dev/null +++ b/Resources/Textures/_Nuclear14/Clothing/OuterClothing/MutantArmor/wild.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Made by RavenReaper", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-OUTERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/appendix-inflamed.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/appendix-inflamed.png new file mode 100644 index 00000000000..3e8f7a6ee95 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/appendix-inflamed.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/appendix.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/appendix.png new file mode 100644 index 00000000000..f52d5b0cdc9 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/appendix.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain-inhand-left.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain-inhand-left.png new file mode 100644 index 00000000000..cf6e4684e9c Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain-inhand-left.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain-inhand-right.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain-inhand-right.png new file mode 100644 index 00000000000..978d4f3c5f1 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain-inhand-right.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain.png new file mode 100644 index 00000000000..04d04890f6b Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/brain.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/ears.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/ears.png new file mode 100644 index 00000000000..ae9ab068ebc Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/ears.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/eyeball-l.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/eyeball-l.png new file mode 100644 index 00000000000..14e728707a9 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/eyeball-l.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/eyeball-r.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/eyeball-r.png new file mode 100644 index 00000000000..d18f4d45725 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/eyeball-r.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/heart-off.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/heart-off.png new file mode 100644 index 00000000000..b2c6562c8ff Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/heart-off.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/heart-on.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/heart-on.png new file mode 100644 index 00000000000..ab786576fe6 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/heart-on.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/kidney-l.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/kidney-l.png new file mode 100644 index 00000000000..9bcb14ea9d3 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/kidney-l.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/kidney-r.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/kidney-r.png new file mode 100644 index 00000000000..442c81338c1 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/kidney-r.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/liver.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/liver.png new file mode 100644 index 00000000000..159339e36c9 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/liver.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/lung-l.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/lung-l.png new file mode 100644 index 00000000000..32aca484b9f Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/lung-l.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/lung-r.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/lung-r.png new file mode 100644 index 00000000000..7e29649ccd8 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/lung-r.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/meta.json b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/meta.json new file mode 100644 index 00000000000..354132ea110 --- /dev/null +++ b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/meta.json @@ -0,0 +1,80 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation and cev-eris at https://github.com/tgstation/tgstation/commit/c4b7f3c41b6742aca260fe60cc358a778ba9b8c8 and https://github.com/discordia-space/CEV-Eris/commit/476e374cea95ff5e8b1603c48342bf700e2cd7af", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "appendix" + }, + { + "name": "appendix-inflamed" + }, + { + "name": "brain" + }, + { + "name": "brain-inhand-left", + "directions": 4 + }, + { + "name": "brain-inhand-right", + "directions": 4 + }, + { + "name": "ears" + }, + { + "name": "eyeball-l" + }, + { + "name": "eyeball-r" + }, + { + "name": "heart-off" + }, + { + "name": "heart-on", + "delays": [ + [ + 0.6, + 0.1, + 0.1 + ] + ] + }, + { + "name": "kidney-l" + }, + { + "name": "kidney-r" + }, + { + "name": "liver" + }, + { + "name": "lung-l" + }, + { + "name": "lung-r" + }, + { + "name": "stomach" + }, + { + "name": "tongue" + }, + { + "name": "muscle" + }, + { + "name": "nerve" + }, + { + "name": "vessel" + } + ] +} diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/muscle.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/muscle.png new file mode 100644 index 00000000000..38da7e76072 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/muscle.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/nerve.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/nerve.png new file mode 100644 index 00000000000..494b5b0290b Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/nerve.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/stomach.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/stomach.png new file mode 100644 index 00000000000..ebf1d5f5141 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/stomach.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/tongue.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/tongue.png new file mode 100644 index 00000000000..5cffd4e0e35 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/tongue.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/vessel.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/vessel.png new file mode 100644 index 00000000000..cfca0298383 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/organs.rsi/vessel.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/full.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/full.png new file mode 100644 index 00000000000..f97eeb8f4a2 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/full.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/head_f.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/head_f.png new file mode 100644 index 00000000000..dcc2584a97d Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/head_f.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/head_m.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/head_m.png new file mode 100644 index 00000000000..dcc2584a97d Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/head_m.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_arm.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_arm.png new file mode 100644 index 00000000000..69177d35d9e Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_arm.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_foot.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_foot.png new file mode 100644 index 00000000000..dc8764e1ba9 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_foot.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_hand.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_hand.png new file mode 100644 index 00000000000..33cc74db0ae Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_hand.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_leg.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_leg.png new file mode 100644 index 00000000000..1a907ae16ce Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/l_leg.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/meta.json b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/meta.json new file mode 100644 index 00000000000..b495662fb08 --- /dev/null +++ b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/meta.json @@ -0,0 +1,62 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by RavenReaper", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full" + }, + { + "name": "head_f", + "directions": 4 + }, + { + "name": "head_m", + "directions": 4 + }, + { + "name": "l_arm", + "directions": 4 + }, + { + "name": "l_foot", + "directions": 4 + }, + { + "name": "l_hand", + "directions": 4 + }, + { + "name": "l_leg", + "directions": 4 + }, + { + "name": "r_arm", + "directions": 4 + }, + { + "name": "r_foot", + "directions": 4 + }, + { + "name": "r_hand", + "directions": 4 + }, + { + "name": "r_leg", + "directions": 4 + }, + { + "name": "torso_f", + "directions": 4 + }, + { + "name": "torso_m", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_arm.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_arm.png new file mode 100644 index 00000000000..198ab59d7ea Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_arm.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_foot.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_foot.png new file mode 100644 index 00000000000..8843bf85c81 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_foot.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_hand.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_hand.png new file mode 100644 index 00000000000..0662ee4ff1a Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_hand.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_leg.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_leg.png new file mode 100644 index 00000000000..d454fbd4fe1 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/r_leg.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/torso_f.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/torso_f.png new file mode 100644 index 00000000000..7a3cb519cd5 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/torso_f.png differ diff --git a/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/torso_m.png b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/torso_m.png new file mode 100644 index 00000000000..bc3b8edf96b Binary files /dev/null and b/Resources/Textures/_Nuclear14/Mobs/Species/Supermutant/parts.rsi/torso_m.png differ diff --git a/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman1.png b/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman1.png new file mode 100644 index 00000000000..c52e384c3e9 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman1.png differ diff --git a/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman2.png b/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman2.png new file mode 100644 index 00000000000..aaf4a442634 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman2.png differ diff --git a/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman_open.png b/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman_open.png new file mode 100644 index 00000000000..98b60cc7df0 Binary files /dev/null and b/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/highwayman_open.png differ diff --git a/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/meta.json b/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/meta.json new file mode 100644 index 00000000000..a758824b383 --- /dev/null +++ b/Resources/Textures/_Nuclear14/Objects/Vehicles/highwayman.rsi/meta.json @@ -0,0 +1,45 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "made by RavenReaper", + "size": { + "x": 96, + "y": 96 + }, + "states": [ + { + "name": "highwayman_open", + "directions": 4 + }, + { + "name": "highwayman1", + "directions": 4 + }, + { + "name": "highwayman2", + "directions": 4, + "delays": [ + [ + 0.030000001, + 0.030000001, + 0.030000001 + ], + [ + 0.030000001, + 0.030000001, + 0.030000001 + ], + [ + 0.030000001, + 0.030000001, + 0.030000001 + ], + [ + 0.030000001, + 0.030000001, + 0.030000001 + ] + ] + } + ] +}