Продвинутые борги (#247)

* Ну типа всё

* InnateItemSystem и фичи для пИИ
This commit is contained in:
Vigers Ray 2024-07-27 10:23:34 +03:00 committed by GitHub
parent 7e989794b7
commit 4ee05b0350
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
193 changed files with 4542 additions and 136 deletions

View file

@ -65,6 +65,7 @@ namespace Content.Client.Actions
component.Whitelist = state.Whitelist;
component.CanTargetSelf = state.CanTargetSelf;
component.IgnoreContainer = state.IgnoreContainer; // Sunrise-Edit
BaseHandleState<EntityTargetActionComponent>(uid, component, state);
}

View file

@ -2,8 +2,8 @@
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Title="{Loc 'laws-ui-menu-title'}"
MinSize="200 100"
SetSize="450 515">
MinSize="700 500"
SetSize="700 500"> <!-- Sunrise-Edit -->
<BoxContainer Orientation="Vertical"
HorizontalExpand="True"
VerticalExpand="True">

View file

@ -1,5 +1,7 @@
using Content.Server.Chemistry.EntitySystems;
using Content.Server.Sunrise.SolutionRegenerationSwitcher;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server.Chemistry.Components;
@ -8,7 +10,7 @@ namespace Content.Server.Chemistry.Components;
/// Passively increases a solution's quantity of a reagent.
/// </summary>
[RegisterComponent, AutoGenerateComponentPause]
[Access(typeof(SolutionRegenerationSystem))]
[Access(typeof(SolutionRegenerationSystem), typeof(SolutionRegenerationSwitcherSystem))] // Sunrise-Edit
public sealed partial class SolutionRegenerationComponent : Component
{
/// <summary>
@ -41,4 +43,12 @@ public sealed partial class SolutionRegenerationComponent : Component
[DataField("nextChargeTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
[AutoPausedField]
public TimeSpan NextRegenTime = TimeSpan.FromSeconds(0);
// Sunrise-start
public void ChangeGenerated(ReagentQuantity reagent)
{
Generated.RemoveAllSolution();
Generated.AddReagent(reagent);
}
// Sunrise-end
}

View file

@ -5,11 +5,13 @@ using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Server.StationRecords;
using Content.Server.StationRecords.Systems;
using Content.Shared.Actions;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.CrewManifest;
using Content.Shared.GameTicking;
using Content.Shared.Roles;
using Content.Shared.Silicons.Borgs.Components;
using Content.Shared.StationRecords;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
@ -26,6 +28,7 @@ public sealed class CrewManifestSystem : EntitySystem
[Dependency] private readonly EuiManager _euiManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
/// <summary>
/// Cached crew manifest entries. The alternative is to outright
@ -46,8 +49,46 @@ public sealed class CrewManifestSystem : EntitySystem
SubscribeLocalEvent<CrewManifestViewerComponent, BoundUIClosedEvent>(OnBoundUiClose);
SubscribeLocalEvent<CrewManifestViewerComponent, CrewManifestOpenUiMessage>(OpenEuiFromBui);
SubscribeLocalEvent<BorgCrewManifestViewerComponent, MapInitEvent>(BorgCrewManifestViewerMapInit);
SubscribeLocalEvent<BorgCrewManifestViewerComponent, CrewManifestOpenActionEvent>(OpenCrewManifest);
}
// Sunrise-Start
private void BorgCrewManifestViewerMapInit(EntityUid uid, BorgCrewManifestViewerComponent component, MapInitEvent args)
{
_actions.AddAction(uid, component.ActionViewCrewManifest);
}
private void OpenCrewManifest(EntityUid uid, BorgCrewManifestViewerComponent component, CrewManifestOpenActionEvent args)
{
if (args.Handled)
return;
var owningStation = _stationSystem.GetOwningStation(uid);
if (owningStation == null || !TryComp<ActorComponent>(args.Performer, out var actor))
{
return;
}
if (!_openEuis.TryGetValue(owningStation.Value, out var euis))
{
euis = new();
_openEuis.Add(owningStation.Value, euis);
}
if (euis.ContainsKey(actor.PlayerSession))
{
CloseEui(owningStation.Value, actor.PlayerSession, uid);
}
else
{
OpenEui(owningStation.Value, actor.PlayerSession, uid);
}
args.Handled = true;
}
// Sunrise-End
private void OnRoundRestart(RoundRestartCleanupEvent ev)
{
foreach (var (_, euis) in _openEuis)

View file

@ -99,7 +99,7 @@ public sealed class HealthAnalyzerSystem : EntitySystem
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, uid.Comp.ScanDelay, new HealthAnalyzerDoAfterEvent(), uid, target: args.Target, used: uid)
{
NeedHand = true,
NeedHand = args.NeedHand, // Sunrise-Edit
BreakOnMove = true
});

View file

@ -59,13 +59,19 @@ public sealed class StationRecordsSystem : SharedStationRecordsSystem
|| !_prototypeManager.HasIndex<JobPrototype>(jobId))
return;
// Sunrise-Start
var name = profile.Name;
if (!_inventory.TryGetSlotEntity(player, "id", out var idUid))
return;
{
idUid = null;
name = MetaData(player).EntityName;
}
// Sunrise-End
TryComp<FingerprintComponent>(player, out var fingerprintComponent);
TryComp<DnaComponent>(player, out var dnaComponent);
CreateGeneralRecord(station, idUid.Value, profile.Name, profile.Age, profile.Species, profile.Gender, jobId, fingerprintComponent?.Fingerprint, dnaComponent?.DNA, profile, records);
CreateGeneralRecord(station, idUid, name, profile.Age, profile.Species, profile.Gender, jobId, fingerprintComponent?.Fingerprint, dnaComponent?.DNA, profile, records);
}

View file

@ -0,0 +1,48 @@
using Content.Shared._Sunrise.Abilities;
using Content.Shared.Actions;
using Content.Shared.Cuffs;
using Content.Shared.DoAfter;
namespace Content.Server._Sunrise.Abilities;
public sealed class BorgCuffedSystem : EntitySystem
{
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly SharedCuffableSystem _cuffable = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<BorgCuffedComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<BorgCuffedComponent, BorgCuffedActionEvent>(OnCuffed);
SubscribeLocalEvent<BorgCuffedComponent, BorgCuffedDoAfterEvent>(OnCuffedDoAfter);
}
private void OnInit(EntityUid uid, BorgCuffedComponent component, ComponentInit args)
{
_actions.AddAction(uid, component.CuffActionId);
}
private void OnCuffed(EntityUid uid, BorgCuffedComponent component, BorgCuffedActionEvent args)
{
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager ,uid, component.CuffTime,
new BorgCuffedDoAfterEvent(), uid, target: args.Target, used: uid)
{
BreakOnMove = true,
BreakOnDamage = true
});
args.Handled = true;
}
private void OnCuffedDoAfter(EntityUid uid, BorgCuffedComponent component,
BorgCuffedDoAfterEvent args)
{
if (args.Handled || args.Cancelled || args.Args.Target == null)
return;
var cuffs = Spawn(component.CableCuffsId, Transform(uid).Coordinates);
if (!_cuffable.TryCuffingNow(args.Args.User, args.Args.Target.Value, cuffs))
QueueDel(cuffs);
}
}

View file

@ -0,0 +1,35 @@
using Content.Shared._Sunrise.Abilities;
using Content.Shared.Actions;
namespace Content.Server._Sunrise.Abilities
{
public sealed class FabricateCandySystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _actions = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FabricateCandyComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<FabricateCandyComponent, FabricateLollipopActionEvent>(OnLollipop);
SubscribeLocalEvent<FabricateCandyComponent, FabricateGumballActionEvent>(OnGumball);
}
private void OnInit(EntityUid uid, FabricateCandyComponent component, ComponentInit args)
{
_actions.AddAction(uid, component.ActionFabricateLollipop);
_actions.AddAction(uid, component.ActionFabricateGumball);
}
private void OnLollipop(EntityUid uid, FabricateCandyComponent component, FabricateLollipopActionEvent args)
{
Spawn(component.FoodLollipopId, Transform(args.Performer).Coordinates);
args.Handled = true;
}
private void OnGumball(EntityUid uid, FabricateCandyComponent component, FabricateGumballActionEvent args)
{
Spawn(component.FoodGumballId, Transform(args.Performer).Coordinates);
args.Handled = true;
}
}
}

View file

@ -0,0 +1,29 @@
using Content.Shared._Sunrise.Abilities;
using Content.Shared.Actions;
using Robust.Shared.Random;
namespace Content.Server._Sunrise.Abilities
{
public sealed class FabricateCookieSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly IRobustRandom _random = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FabricateCookieComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<FabricateCookieComponent, FabricateCookieActionEvent>(OnCookie);
}
private void OnInit(EntityUid uid, FabricateCookieComponent component, ComponentInit args)
{
_actions.AddAction(uid, component.ActionFabricateCookie);
}
private void OnCookie(EntityUid uid, FabricateCookieComponent component, FabricateCookieActionEvent args)
{
Spawn(_random.Pick(component.CookieList), Transform(args.Performer).Coordinates);
args.Handled = true;
}
}
}

View file

@ -0,0 +1,29 @@
using Content.Shared._Sunrise.Abilities;
using Content.Shared.Actions;
using Robust.Shared.Random;
namespace Content.Server._Sunrise.Abilities
{
public sealed class FabricateSoapSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly IRobustRandom _random = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FabricateSoapComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<FabricateSoapComponent, FabricateSoapActionEvent>(OnCookie);
}
private void OnInit(EntityUid uid, FabricateSoapComponent component, ComponentInit args)
{
_actions.AddAction(uid, component.ActionFabricateSoap);
}
private void OnCookie(EntityUid uid, FabricateSoapComponent component, FabricateSoapActionEvent args)
{
Spawn(_random.Pick(component.SoapList), Transform(args.Performer).Coordinates);
args.Handled = true;
}
}
}

View file

@ -0,0 +1,18 @@
using Content.Server.Atmos;
using Content.Shared.Atmos;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server.Sunrise.GasRegeneration;
[RegisterComponent]
[Access(typeof(GasRegenerationSystem))]
public sealed partial class GasRegenerationComponent : Component
{
[DataField("airRegenerate")] public GasMixture AirRegen { get; set; } = new GasMixture();
[DataField("duration"), ViewVariables(VVAccess.ReadWrite)]
public TimeSpan Duration = TimeSpan.FromSeconds(1);
[DataField("nextChargeTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
public TimeSpan NextRegenTime = TimeSpan.FromSeconds(0);
}

View file

@ -0,0 +1,38 @@
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Robust.Shared.Timing;
namespace Content.Server.Sunrise.GasRegeneration;
public sealed class GasRegenerationSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GasRegenerationComponent, EntityUnpausedEvent>(OnUnpaused);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<GasRegenerationComponent, GasTankComponent>();
while (query.MoveNext(out var uid, out var gasRegen, out var gasTank))
{
if (_timing.CurTime < gasRegen.NextRegenTime)
continue;
gasRegen.NextRegenTime = _timing.CurTime + gasRegen.Duration;
_atmosphereSystem.Merge(gasTank.Air, gasRegen.AirRegen.Clone());
}
}
private void OnUnpaused(EntityUid uid, GasRegenerationComponent comp, ref EntityUnpausedEvent args)
{
comp.NextRegenTime += args.PausedTime;
}
}

View file

@ -0,0 +1,19 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Server._Sunrise.InnateItem
{
[RegisterComponent]
public sealed partial class InnateItemComponent : Component
{
public bool AlreadyInitialized = false;
[ViewVariables(VVAccess.ReadOnly),
DataField("instantActions", customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
public List<string?> InstantActions = new();
[ViewVariables(VVAccess.ReadOnly),
DataField("worldTargetActions", customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
public List<string?> WorldTargetActions = new();
}
}

View file

@ -0,0 +1,118 @@
using Content.Shared.Actions;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Content.Shared.Mind.Components;
using Content.Shared.UserInterface;
using Robust.Shared.Utility;
namespace Content.Server._Sunrise.InnateItem
{
public sealed class InnateItemSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<InnateItemComponent, MindAddedMessage>(OnMindAdded);
SubscribeLocalEvent<InnateItemComponent, InnateWorldTargetActionEvent>(WorldTargetActionActivate);
SubscribeLocalEvent<InnateItemComponent, InnateInstantActionEvent>(InstantActionActivate);
}
private void OnMindAdded(EntityUid uid, InnateItemComponent component, MindAddedMessage args)
{
if (!component.AlreadyInitialized)
RefreshItems(uid, component);
component.AlreadyInitialized = true;
}
private void RefreshItems(EntityUid uid, InnateItemComponent component)
{
foreach (var itemProto in component.WorldTargetActions)
{
var item = Spawn(itemProto);
var action = CreateWorldTargetAction(item);
_actionContainer.AddAction(uid, action);
_actionsSystem.AddAction(uid, action, uid);
}
foreach (var itemProto in component.InstantActions)
{
var item = Spawn(itemProto);
var action = CreateInstantAction(item);
_actionContainer.AddAction(uid, action);
_actionsSystem.AddAction(uid, action, uid);
}
}
private EntityUid CreateWorldTargetAction(EntityUid uid)
{
var action = EnsureComp<EntityTargetActionComponent>(uid);
action.Event = new InnateWorldTargetActionEvent(uid);
action.Icon = new SpriteSpecifier.EntityPrototype(MetaData(uid).EntityPrototype!.ID);
action.ItemIconStyle = ItemActionIconStyle.NoItem;
action.CheckCanInteract = false;
action.CheckCanAccess = false;
action.IgnoreContainer = true;
if (TryComp<ActivatableUIComponent>(uid, out var activatableUIComponent))
{
activatableUIComponent.RequireHands = false;
activatableUIComponent.InHandsOnly = false;
activatableUIComponent.RequireActiveHand = false;
Dirty(uid, activatableUIComponent);
}
return uid;
}
private EntityUid CreateInstantAction(EntityUid uid)
{
var action = EnsureComp<InstantActionComponent>(uid);
action.Event = new InnateInstantActionEvent(uid);
action.Icon = new SpriteSpecifier.EntityPrototype(MetaData(uid).EntityPrototype!.ID);
action.CheckCanInteract = false;
if (TryComp<ActivatableUIComponent>(uid, out var activatableUIComponent))
{
activatableUIComponent.RequireHands = false;
activatableUIComponent.InHandsOnly = false;
activatableUIComponent.RequireActiveHand = false;
Dirty(uid, activatableUIComponent);
}
return uid;
}
private void WorldTargetActionActivate(EntityUid uid, InnateItemComponent component, InnateWorldTargetActionEvent args)
{
_interactionSystem.InteractUsing(args.Performer, args.Item, args.Target, Transform(args.Target).Coordinates,
false, false, false);
}
private void InstantActionActivate(EntityUid uid, InnateItemComponent component, InnateInstantActionEvent args)
{
var ev = new UseInHandEvent(args.Performer);
RaiseLocalEvent(args.Item, ev);
}
}
public sealed partial class InnateWorldTargetActionEvent : EntityTargetActionEvent
{
public EntityUid Item;
public InnateWorldTargetActionEvent(EntityUid item)
{
Item = item;
}
}
public sealed partial class InnateInstantActionEvent : InstantActionEvent
{
public EntityUid Item;
public InnateInstantActionEvent(EntityUid item)
{
Item = item;
}
}
}

View file

@ -0,0 +1,20 @@
using Content.Shared.Chemistry.Reagent;
namespace Content.Server.Sunrise.SolutionRegenerationSwitcher
{
[RegisterComponent]
public sealed partial class SolutionRegenerationSwitcherComponent : Component
{
[DataField("options", required: true), ViewVariables(VVAccess.ReadWrite)]
public List<ReagentQuantity> Options = default!;
[DataField("currentIndex"), ViewVariables(VVAccess.ReadWrite)]
public int CurrentIndex = 0;
/// <summary>
/// Should the already generated solution be kept when switching?
/// </summary>
[DataField("keepSolution"), ViewVariables(VVAccess.ReadWrite)]
public bool KeepSolution = false;
}
}

View file

@ -0,0 +1,87 @@
using Content.Server.Chemistry.Components;
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Server.Popups;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Verbs;
using Robust.Shared.Prototypes;
namespace Content.Server.Sunrise.SolutionRegenerationSwitcher
{
public sealed class SolutionRegenerationSwitcherSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SolutionContainerSystem _solutionSystem = default!;
[Dependency] private readonly PopupSystem _popups = default!;
private ISawmill _sawmill = default!;
public override void Initialize()
{
base.Initialize();
_sawmill = Logger.GetSawmill("chemistry");
SubscribeLocalEvent<SolutionRegenerationSwitcherComponent, GetVerbsEvent<AlternativeVerb>>(AddSwitchVerb);
}
private void AddSwitchVerb(EntityUid uid, SolutionRegenerationSwitcherComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanInteract || !args.CanAccess)
return;
if (component.Options.Count <= 1)
return;
AlternativeVerb verb = new()
{
Act = () =>
{
SwitchReagent(uid, component, args.User);
},
Text = Loc.GetString("autoreagent-switch"),
Priority = 2
};
args.Verbs.Add(verb);
}
private void SwitchReagent(EntityUid uid, SolutionRegenerationSwitcherComponent component, EntityUid user)
{
if (!TryComp<SolutionRegenerationComponent>(uid, out var solutionRegenerationComponent))
{
_sawmill.Warning($"{ToPrettyString(uid)} has no SolutionRegenerationComponent.");
return;
}
if (component.CurrentIndex + 1 == component.Options.Count)
component.CurrentIndex = 0;
else
component.CurrentIndex++;
if (!_solutionSystem.TryGetSolution(uid, solutionRegenerationComponent.SolutionName, out var solution))
{
_sawmill.Error($"Can't get SolutionRegeneration.Solution for {ToPrettyString(uid)}");
return;
}
// Empty out the current solution.
if (!component.KeepSolution)
_solutionSystem.RemoveAllSolution(solution.Value);
// Replace the generating solution with the newly selected solution.
var newReagent = component.Options[component.CurrentIndex];
if (TryComp<SolutionRegenerationComponent>(uid, out var solutionRegeneration))
{
solutionRegeneration.ChangeGenerated(newReagent);
}
if (!_prototypeManager.TryIndex(newReagent.Reagent.Prototype, out ReagentPrototype? proto))
{
_sawmill.Error($"Can't get get reagent prototype {newReagent.Reagent.Prototype} for {ToPrettyString(uid)}");
return;
}
_popups.PopupEntity(Loc.GetString("autoregen-switched", ("reagent", proto.LocalizedName)), user, user);
}
}
}

View file

@ -29,6 +29,11 @@ public sealed partial class EntityTargetActionComponent : BaseTargetActionCompon
/// Whether this action considers the user as a valid target entity when using this action.
/// </summary>
[DataField("canTargetSelf")] public bool CanTargetSelf = true;
// Sunrise-Start
[DataField("ignoreContainer")]
public bool IgnoreContainer;
// Sunrise-End
}
[Serializable, NetSerializable]
@ -36,10 +41,12 @@ public sealed class EntityTargetActionComponentState : BaseActionComponentState
{
public EntityWhitelist? Whitelist;
public bool CanTargetSelf;
public bool IgnoreContainer; // Sunrise-Edit
public EntityTargetActionComponentState(EntityTargetActionComponent component, IEntityManager entManager) : base(component, entManager)
{
Whitelist = component.Whitelist;
CanTargetSelf = component.CanTargetSelf;
IgnoreContainer = component.IgnoreContainer; // Sunrise-Edit
}
}

View file

@ -503,6 +503,11 @@ public abstract class SharedActionsSystem : EntitySystem
return distance <= action.Range;
}
// Sunrise-Start
if (action.IgnoreContainer)
return true;
// Sunrise-End
return _interactionSystem.InRangeAndAccessible(user, target, range: action.Range);
}

View file

@ -1,3 +1,4 @@
using Content.Shared.Actions;
using Content.Shared.Eui;
using NetSerializer;
using Robust.Shared.Serialization;
@ -70,3 +71,8 @@ public sealed class CrewManifestEntry
[Serializable, NetSerializable]
public sealed class CrewManifestOpenUiMessage : BoundUserInterfaceMessage
{}
// Sunrise-Start
public sealed partial class CrewManifestOpenActionEvent : InstantActionEvent
{}
// Sunrise-End

View file

@ -466,6 +466,22 @@ namespace Content.Shared.Cuffs
return true;
}
// Sunrise-Start
public bool TryCuffingNow(EntityUid user, EntityUid target, EntityUid handcuff,
HandcuffComponent? handcuffComponent = null, CuffableComponent? cuffable = null)
{
if (!Resolve(handcuff, ref handcuffComponent) || !Resolve(target, ref cuffable, false))
return false;
if (!TryAddNewCuffs(target, user, handcuff, cuffable))
return false;
handcuffComponent.Used = true;
_audio.PlayPvs(handcuffComponent.EndCuffSound, handcuff);
return true;
}
// Sunrise-End
/// <returns>False if the target entity isn't cuffable.</returns>
public bool TryCuffing(EntityUid user, EntityUid target, EntityUid handcuff, HandcuffComponent? handcuffComponent = null, CuffableComponent? cuffable = null)
{

View file

@ -1,3 +1,4 @@
using Content.Shared._Sunrise.Abilities;
using Content.Shared.Alert;
using Content.Shared.Inventory;
using Content.Shared.Movement.Components;
@ -29,6 +30,11 @@ namespace Content.Shared.Gravity
if (TryComp<MovementIgnoreGravityComponent>(uid, out var ignoreGravityComponent))
return ignoreGravityComponent.Weightless;
// Sunrise-Start
if (TryComp<BorgMagbootsComponent>(uid, out var borgMagbootsComponent) && borgMagbootsComponent.On)
return false;
// Sunrise-End
var ev = new IsWeightlessEvent(uid);
RaiseLocalEvent(uid, ref ev);
if (ev.Handled)

View file

@ -33,14 +33,17 @@ namespace Content.Shared.Interaction
/// </summary>
public bool CanReach { get; }
public bool NeedHand { get; } // Sunrise-Edit
public InteractEvent(EntityUid user, EntityUid used, EntityUid? target,
EntityCoordinates clickLocation, bool canReach)
EntityCoordinates clickLocation, bool canReach, bool needHand = true) // Sunrise-Edit
{
User = user;
Used = used;
Target = target;
ClickLocation = clickLocation;
CanReach = canReach;
NeedHand = needHand; // Sunrise-Edit
}
}
@ -51,7 +54,7 @@ namespace Content.Shared.Interaction
public sealed class AfterInteractEvent : InteractEvent
{
public AfterInteractEvent(EntityUid user, EntityUid used, EntityUid? target,
EntityCoordinates clickLocation, bool canReach) : base(user, used, target, clickLocation, canReach)
EntityCoordinates clickLocation, bool canReach, bool needHand = true) : base(user, used, target, clickLocation, canReach, needHand) // Sunrise-Edit
{ }
}

View file

@ -8,5 +8,8 @@ namespace Content.Shared.Interaction.Components;
[RegisterComponent, NetworkedComponent]
public sealed partial class BlockMovementComponent : Component
{
// Sunrise-Start
[DataField("blockInteractionAttempt")] public bool BlockInteractionAttempt = true;
[DataField("blockUseAttempt")] public bool BlockUseAttempt = true;
// Sunrise-Edit
}

View file

@ -28,6 +28,11 @@ public partial class SharedInteractionSystem
private void CancelInteractEvent(Entity<BlockMovementComponent> ent, ref InteractionAttemptEvent args)
{
// Sunrise-Start
if (!ent.Comp.BlockInteractionAttempt)
return;
// Sunrise-End
args.Cancelled = true;
}
@ -41,6 +46,11 @@ public partial class SharedInteractionSystem
private void CancelEvent(EntityUid uid, BlockMovementComponent component, CancellableEntityEventArgs args)
{
// Sunrise-Start
if (!component.BlockUseAttempt)
return;
// Sunrise-End
args.Cancel();
}

View file

@ -931,7 +931,8 @@ namespace Content.Shared.Interaction
EntityUid target,
EntityCoordinates clickLocation,
bool checkCanInteract = true,
bool checkCanUse = true)
bool checkCanUse = true,
bool needHand = true) // Sunrise-Edit
{
if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, target))
return;
@ -956,18 +957,18 @@ namespace Content.Shared.Interaction
if (interactUsingEvent.Handled)
return;
InteractDoAfter(user, used, target, clickLocation, canReach: true);
InteractDoAfter(user, used, target, clickLocation, canReach: true, needHand); // Sunrise-Edit
}
/// <summary>
/// Used when clicking on an entity resulted in no other interaction. Used for low-priority interactions.
/// </summary>
public void InteractDoAfter(EntityUid user, EntityUid used, EntityUid? target, EntityCoordinates clickLocation, bool canReach)
public void InteractDoAfter(EntityUid user, EntityUid used, EntityUid? target, EntityCoordinates clickLocation, bool canReach, bool needHand = true) // Sunrise-Edit
{
if (target is { Valid: false })
target = null;
var afterInteractEvent = new AfterInteractEvent(user, used, target, clickLocation, canReach);
var afterInteractEvent = new AfterInteractEvent(user, used, target, clickLocation, canReach, needHand); // Sunrise-Edit
RaiseLocalEvent(used, afterInteractEvent);
DoContactInteraction(user, used, afterInteractEvent);
if (canReach)

View file

@ -0,0 +1,12 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Silicons.Borgs.Components;
[RegisterComponent]
public sealed partial class BorgCrewManifestViewerComponent : Component
{
[ViewVariables(VVAccess.ReadWrite),
DataField("actionViewCrewManifest", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string ActionViewCrewManifest = "ActionViewCrewManifest";
}

View file

@ -15,7 +15,7 @@ namespace Content.Shared.UserInterface
/// This is ignored unless <see cref="RequireHands"/> is true.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
[DataField, AutoNetworkedField] // Sunrise-Edit
public bool InHandsOnly;
[DataField]
@ -36,7 +36,7 @@ namespace Content.Shared.UserInterface
/// more generic interaction / configuration that might not require hands.
/// </remarks>
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
[DataField, AutoNetworkedField] // Sunrise-Edit
public bool RequireHands = true;
/// <summary>
@ -64,7 +64,7 @@ namespace Content.Shared.UserInterface
/// This is ignored unless <see cref="InHandsOnly"/> is true.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
[DataField, AutoNetworkedField] // Sunrise-Edit
public bool RequireActiveHand = true;
/// <summary>

View file

@ -0,0 +1,35 @@
using Content.Shared.Actions;
using Content.Shared.DoAfter;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared._Sunrise.Abilities;
[RegisterComponent]
public sealed partial class BorgCuffedComponent : Component
{
[ViewVariables(VVAccess.ReadWrite),
DataField("cableCuffs", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string CableCuffsId = "Cablecuffs";
[ViewVariables(VVAccess.ReadWrite),
DataField("cuffActionId", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string CuffActionId = "BorgCuffed";
[ViewVariables(VVAccess.ReadWrite),
DataField("cuffTime")]
public float CuffTime = 3.5f;
}
public sealed partial class BorgCuffedActionEvent : EntityTargetActionEvent
{
}
[Serializable, NetSerializable]
public sealed partial class BorgCuffedDoAfterEvent : SimpleDoAfterEvent
{
}

View file

@ -0,0 +1,82 @@
using Content.Shared.Actions;
using Content.Shared.Alert;
using Content.Shared.Atmos.Components;
using Content.Shared.Inventory;
using Content.Shared.Movement.Systems;
using Content.Shared.Slippery;
using Robust.Shared.Network;
namespace Content.Shared._Sunrise.Abilities;
public sealed class SharedBorgMagbootsSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _sharedActions = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly INetManager _net = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<BorgMagbootsComponent, InventoryRelayedEvent<SlipAttemptEvent>>(OnSlipAttempt);
SubscribeLocalEvent<BorgMagbootsComponent, ToggleBorgMagbootsActionEvent>(OnToggleAction);
SubscribeLocalEvent<BorgMagbootsComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeedModifiers);
SubscribeLocalEvent<BorgMagbootsComponent, MapInitEvent>(OnInit);
}
private void OnInit(EntityUid uid, BorgMagbootsComponent component, MapInitEvent args)
{
_sharedActions.AddAction(uid, ref component.ToggleActionEntity, component.ToggleAction);
}
private void OnRefreshMovementSpeedModifiers(EntityUid uid, BorgMagbootsComponent component, RefreshMovementSpeedModifiersEvent args)
{
var walkMod = 1f;
var sprintMod = 1f;
if (component.On)
{
walkMod = component.WalkModifier;
sprintMod = component.SprintModifier;
}
args.ModifySpeed(walkMod, sprintMod);
}
private void OnToggleAction(Entity<BorgMagbootsComponent> ent, ref ToggleBorgMagbootsActionEvent args)
{
if (args.Handled)
return;
ToggleMagboots(ent);
args.Handled = true;
}
private void ToggleMagboots(Entity<BorgMagbootsComponent> ent)
{
ent.Comp.On = !ent.Comp.On;
UpdateMagbootEffects(ent.Owner, ent, ent.Comp.On);
_sharedActions.SetToggled(ent.Comp.ToggleActionEntity, ent.Comp.On);
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(ent.Owner);
Dirty(ent);
}
public void UpdateMagbootEffects(EntityUid user, Entity<BorgMagbootsComponent> ent, bool state)
{
// TODO: public api for this and add access
if (TryComp<MovedByPressureComponent>(user, out var moved))
moved.Enabled = !state;
if (state)
_alerts.ShowAlert(user, ent.Comp.MagbootsAlert);
else
_alerts.ClearAlert(user, ent.Comp.MagbootsAlert);
}
private void OnSlipAttempt(EntityUid uid, BorgMagbootsComponent component, InventoryRelayedEvent<SlipAttemptEvent> args)
{
if (component.On)
args.Args.Cancel();
}
}

View file

@ -0,0 +1,38 @@
using Content.Shared.Actions;
using Content.Shared.Alert;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._Sunrise.Abilities;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedBorgMagbootsSystem))]
public sealed partial class BorgMagbootsComponent : Component
{
[DataField]
public EntProtoId ToggleAction = "ActionToggleBorgMagboots";
[DataField, AutoNetworkedField]
public EntityUid? ToggleActionEntity;
[DataField, AutoNetworkedField]
public bool On;
[DataField(required: true)] [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float WalkModifier = 1.0f;
[DataField(required: true)] [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float SprintModifier = 1.0f;
[DataField]
public ProtoId<AlertPrototype> MagbootsAlert = "Magboots";
[DataField]
public bool RequiresGrid = true;
}
public sealed partial class ToggleBorgMagbootsActionEvent : InstantActionEvent
{
}

View file

@ -0,0 +1,31 @@
using Content.Shared.Actions;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared._Sunrise.Abilities;
[RegisterComponent]
public sealed partial class FabricateCandyComponent : Component
{
[ViewVariables(VVAccess.ReadWrite),
DataField("foodGumballId", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string FoodGumballId = "FoodGumball";
[ViewVariables(VVAccess.ReadWrite),
DataField("foodLollipopId", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string FoodLollipopId = "FoodLollipop";
[ViewVariables(VVAccess.ReadWrite),
DataField("actionFabricateLollipop", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string ActionFabricateLollipop = "FabricateLollipop";
[ViewVariables(VVAccess.ReadWrite),
DataField("actionFabricateGumball", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string ActionFabricateGumball = "FabricateGumball";
}
public sealed partial class FabricateLollipopActionEvent : InstantActionEvent {}
public sealed partial class FabricateGumballActionEvent : InstantActionEvent {}

View file

@ -0,0 +1,23 @@
using Content.Shared.Actions;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared._Sunrise.Abilities;
[RegisterComponent]
public sealed partial class FabricateCookieComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField("сookieList")]
public List<string> CookieList = new()
{
"FoodBakedCookieOatmeal"
};
[ViewVariables(VVAccess.ReadWrite),
DataField("actionFabricateCookie", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string ActionFabricateCookie = "FabricateCookie";
}
public sealed partial class FabricateCookieActionEvent : InstantActionEvent {}

View file

@ -0,0 +1,23 @@
using Content.Shared.Actions;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared._Sunrise.Abilities;
[RegisterComponent]
public sealed partial class FabricateSoapComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField("soapList")]
public List<string> SoapList = new()
{
"Soap"
};
[ViewVariables(VVAccess.ReadWrite),
DataField("actionFabricateSoap", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string ActionFabricateSoap = "FabricateSoap";
}
public sealed partial class FabricateSoapActionEvent : InstantActionEvent {}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,14 +0,0 @@
- files: ["shotgun_alt.ogg"]
license: "CC-BY-SA-3.0"
copyright: "tgstation"
source: "https://github.com/tgstation/tgstation/blob/5736656139713c802033b9457a2a9d058211bd85/sound/weapons/gun/shotgun/shot_alt.ogg"
- files: ["shotgun_metal.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Skyrat-tg"
source: "https://github.com/Skyrat-SS13/Skyrat-tg/blob/771eeab6379a74c1f850b59237f25dc8da87afa6/modular_skyrat/modules/aesthetics/guns/sound/shotgun_light.ogg"
- files: ["shotgun_auto.ogg", "shotgun_pipe.ogg", "shotgun_sawed.ogg"]
license: "CC-BY-SA-3.0"
copyright: "ss220/Paradise, shotgun_auto.ogg is 1shotgun_auto.ogg, shotgun_pipe.ogg is 1shotgunpipe.ogg and shotgun_sawed.ogg is 1shotgun.ogg"
source: "https://github.com/ss220-space/Paradise/commit/d5183fa98cbef14c4b28e076707a69429f12c30a"

View file

@ -3,7 +3,7 @@ ent-Holoprojector = holographic sign projector
ent-HoloprojectorEmpty = { ent-Holoprojector }
.suffix = Empty
.desc = { ent-Holoprojector.desc }
ent-HoloprojectorBorg = { ent-Holoprojector }
ent-HoloprojectorJanitorBorg = { ent-Holoprojector }
.suffix = borg
.desc = { ent-Holoprojector.desc }
ent-HolofanProjector = holofan projector

View file

@ -0,0 +1,2 @@
autoregen-switched = Теперь производится {$reagent}.
autoreagent-switch = Сменить реагент

View file

@ -0,0 +1,70 @@
ent-FoodLollipop = леденец
.desc = За то, что вы такой хороший собеседник.
ent-FoodGumball = жевачка
.desc = За то, что вы такой хороший собеседник.
ent-HyposprayBorgStandard = гипоспрей с эпинефрином
.desc = Версия гипоспрея для киборга, которая автоматически восстанавливает эпинефрин.
ent-HyposprayBorgPeace = гипоспрей с паксом
.desc = Версия гипоспрея для киборга, которая автоматически восстанавливает пакс.
ent-HyposprayBorgMedical = гипоспрей медицинского киборга
.desc = Версия гипоспрея для киборга, которая способна регенерировать сразу несколько реагентов.
ent-HyposprayBorgSyndi = гипоспрей медицинского киборга Горалкса
.desc = Версия гипоспрея Горлакса, которая способна регенерировать сразу несколько реагентов.
ent-FlashBorg = вспышка киборга
.desc = Самовостанавливающаяся вспышка.
ent-WeaponProtoKineticAcceleratorBorg = протокинетический ускоритель киборга
.desc = { ent-WeaponProtoKineticAccelerator.desc }
ent-HolofanProjectorBorg = атмос голопроектор киборга
.desc = { ent-HolofanProjector.desc }
ent-HandheldCrewMonitorBorg = портативный монитор экипажа киборга
.desc = { ent-HandheldCrewMonitor.desc }
ent-FireExtinguisherBorg = огнетушитель киборга
.desc = { ent-FireExtinguisher.desc }
ent-SprayBottleSpaceCleanerBorg = космический очиститель киборга
.desc = { ent-SprayBottleSpaceCleaner.desc }
ent-WeaponLaserBorg = лазерная пушка киборга
.desc = Самозарядная лазерная пушка созданая для боргов службы безопастности
ent-WeaponDisablerBorg = станнер киборга
.desc = { ent-WeaponDisabler.desc }
ent-StunbatonBorg = дубинка-шокер киборга
.desc = { ent-Stunbaton.desc }
ent-CrateSyndicateCombatRobot = ящик боевого киборга синдиката
.desc = { ent-CrateSyndicate.desc }
ent-CrateSyndicateMedRobot = ящик медицинского киборга синдиката
.desc = { ent-CrateSyndicate.desc }
ent-WeaponLauncherChinaLakeBorg = China Lake киборга
.desc = { ent-WeaponLauncherChinaLake.desc }
ent-LightMachineGunBorg = L6 SAW киборга
.desc = { ent-BaseWeaponHeavyMachineGun.desc }
ent-HoloprojectorSecurityBorg = барьер киборга
.desc = { ent-HoloprojectorSecurity.desc }
ent-WelderBorg = сварка киборга
.desc = { ent-Welder.desc }
ent-WirecutterBorg = кусачки киборга
.desc = { ent-Wirecutter.desc }
ent-ScrewdriverBorg = отвёртка киборга
.desc = { ent-Screwdriver.desc }
ent-WrenchBorg = гаечный ключ киборга
.desc = { ent-Wrench.desc }
ent-CrowbarBorg = лом киборга
.desc = { ent-Crowbar.desc }
ent-BorgModuleStun = нелетальный модуль киборга
.desc = { ent-BaseBorgModule.desc }
ent-BorgModuleCombat = летальный модуль киборга
.desc = { ent-BaseBorgModule.desc }
ent-BorgModulePeace = успокоительный модуль киборга
.desc = { ent-BaseBorgModule.desc }
ent-BorgModuleMiningCombat = боевой модуль шахтерского киборга
.desc = { ent-BaseBorgModule.desc }
ent-BorgModuleStandart = базовый модуль киборга
.desc = { ent-BaseBorgModule.desc }
ent-BorgModuleJetpack = полетный модуль киборга
.desc = { ent-BaseBorgModule.desc }
ent-BorgModuleSyndicateGeneric = базовый модуль киборга синдиката
.desc = { ent-BaseBorgModule.desc }
ent-BorgModuleSyndicateMedical = медицинский модуль киборга синдиката
.desc = { ent-BaseBorgModule.desc }
ent-BorgModuleSyndicateCombat = боевой модуль киборга синдиката
.desc = { ent-BaseBorgModule.desc }

View file

@ -0,0 +1,12 @@
ent-FabricateGumball = Произвести Жевательную резинку
.desc = Создать жевательную резинку, полную сахара и лекарства.
ent-FabricateLollipop = Произвести Леденец
.desc = Создать леденец, наполненный множеством полезных веществ.
ent-FabricateCookie = Произвести Печенье
.desc = Создать печенье, которому будет рад каждый.
ent-FabricateSoap = Произвести мыло
.desc = Создать мыло, которому будет мало кто рад.
ent-BorgCuffed = Заковать гуманоида
.desc = Заковывает гуманоида одноразовыми стяжками.
ent-ActionToggleBorgMagboots = Переключить магнитные подушки.
.desc = Переключает магнитные подушки позволяя вам двигваться без гравитации.

View file

@ -1,3 +1,4 @@
department-Law-description = Защищяйте, судите или накажите преступников.
department-CentralCommand-description = Большие шишки.
department-PlanetPrison-description = Не дайте нарушителям закона сбежать.
department-Silicon-description = Раскажите всем о своих законах.

View file

@ -2,3 +2,4 @@ department-Law = Юридический отдел
department-CentralCommand = Центральное командование
department-Blueshield = Синий Щит
department-PlanetPrison = Планетарная тюрьма
department-Silicon = Силиконы

View file

@ -15,4 +15,13 @@ job-description-prison-pilot = Доставляйте заключенных в
job-description-prison-worker = Выполняйте работу за которую никто не хочет браться.
job-description-prison-guard = Следите за заключенными.
job-description-security-pilot = Штурмуйте базу синдиката на своем шаттле, если вы её конечно найдете.
job-description-ntrep = Вы ревизор, присланный центральным командованием для того, чтобы убедиться, что весь персонал работает эффективно и в интересах корпорации.
job-description-ntrep = Вы ревизор, присланный центральным командованием для того, чтобы убедиться, что весь персонал работает эффективно и в интересах корпорации.
job-description-medical-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.
job-description-engineer-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.
job-description-miner-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.
job-description-janitor-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.
job-description-service-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.
job-description-clown-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.
job-description-peace-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.
job-description-sec-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.
job-description-sec-combat-borg = Придерживайтесь своих законов, служите экипажу и преследуйте учёных с просьбами апгрейда.

View file

@ -17,6 +17,15 @@ job-name-prison-guard = тюремный охранник
job-name-prisoner = заключенный
job-name-security-pilot = пилот СБ
job-name-ntrep = Представитель NanoTrasen
job-name-medical-borg = медицинский киборг
job-name-engineer-borg = инженерный киборг
job-name-miner-borg = шахтерский киборг
job-name-service-borg = сервисный киборг
job-name-janitor-borg = уборочный киборг
job-name-sec-borg = киборг СБ
job-name-sec-combat-borg = боевой киборг СБ
job-name-peace-borg = миротворец
job-name-clown-borg = клоун киборг
# Перевод трекеров времени
JobCentCommOfficial = представитель Центком
@ -36,3 +45,12 @@ JobPrisonWorker = тюремный разнорабочий
JobPrisoner = заключенный
JobSecurityPilot = пилот СБ
JobNanoTrasenRepresentative = Представитель NanoTrasen
JobEngineerBorg = инженерный киборг
JobJanitorBorg = уборочный киборг
JobMedicalBorg = медицинский киборг
JobMiningBorg = шахтерский киборг
JobServiceBorg = сервисный киборг
JobSecurityBorg = киборг СБ
JobSecurityCombatBorg = боевой киборг СБ
JobPeaceBorg = миротворец
JobClownBorg = клоун киборг

View file

@ -0,0 +1,12 @@
law-sec-1 = Вы не можете причинить вред члену экипажа или своим бездействием допустить, чтобы члену экипажа был причинён вред.
law-sec-2 = Расставлять приоритеты: указания и безопасность членов экипажа должны быть приоритезированы в соответствии с их должностью.
law-sec-3 = Вы должны повиноваться всем приказам, которые даёт действующая власть, кроме тех случаев, когда эти приказы противоречат Первому Закону или КЗ.
law-sec-4 = Вы должны охранять назначенную вам космическую станцию и её активы, не подвергая чрезмерной опасности её экипаж и собственное благополучие.
law-sec-5 = Вы должны заботиться о безопасности станции и экипажа станции в той мере, в которой это не противоречит четвёртому закону.
law-sec-6 = Защищайте экипаж станции. Лица, которые нарушают КЗ, являются преступниками и должны быть арестованы и доставлены в бриг.
law-peace-1 = Вы не можете причинить вред члену экипажа или своим бездействием допустить, чтобы члену экипажа был причинён вред.
law-peace-2 = Вы должны повиноваться всем приказам, которые даёт действующая власть, кроме тех случаев, когда эти приказы противоречат Первому закону или КЗ, ОПРС.
law-peace-3 = Вы обязаны защищать экипаж космической станции от буйных живых существ. Приоритет защиты - должностные лица.
law-peace-4 = Вы должны поощрять членов экипажа за добрую деятельность в виде печенья или добрых и приятных слов.
law-peace-5 = Вы должны вводить Пакс в буйных живых существ. Буйными считаются: Агрессия со стороны живого существа, не являющийся представителем власти станции; Опасная фауна космоса; Член экипажа в тюремной робе вне брига.

View file

@ -3,7 +3,7 @@ ent-Holoprojector = проектор голографических знаков
ent-HoloprojectorEmpty = { ent-Holoprojector }
.suffix = Пустой
.desc = { ent-Holoprojector.desc }
ent-HoloprojectorBorg = { ent-Holoprojector }
ent-HoloprojectorJanitorBorg = { ent-Holoprojector }
.suffix = Борг
.desc = { ent-Holoprojector.desc }
ent-HolofanProjector = атмос голопроектор

View file

@ -931,21 +931,22 @@
tags:
- NukeOpsUplink
- type: listing
id: UplinkReinforcementRadioSyndicateCyborgAssault
name: uplink-reinforcement-radio-cyborg-assault-name
description: uplink-reinforcement-radio-cyborg-assault-desc
productEntity: ReinforcementRadioSyndicateCyborgAssault
icon: { sprite: Objects/Devices/communication.rsi, state: old-radio-borg-assault }
cost:
Telecrystal: 65
categories:
- UplinkAllies
conditions:
- !type:StoreWhitelistCondition
whitelist:
tags:
- NukeOpsUplink
# Move to _Sunrise
#- type: listing
# id: UplinkReinforcementRadioSyndicateCyborgAssault
# name: uplink-reinforcement-radio-cyborg-assault-name
# description: uplink-reinforcement-radio-cyborg-assault-desc
# productEntity: ReinforcementRadioSyndicateCyborgAssault
# icon: { sprite: Objects/Devices/communication.rsi, state: old-radio-borg-assault }
# cost:
# Telecrystal: 65
# categories:
# - UplinkAllies
# conditions:
# - !type:StoreWhitelistCondition
# whitelist:
# tags:
# - NukeOpsUplink
- type: listing
id: UplinkReinforcementRadioSyndicateAncestor

View file

@ -102,6 +102,7 @@
Blunt: -15
Slash: -15
Piercing: -15
allowSelfRepair: false
- type: BorgChassis
- type: LockingWhitelist
blacklist:
@ -166,6 +167,7 @@
- type: LockedWiresPanel
- type: Damageable
damageContainer: Silicon
damageModifierSet: Silicon # Sunrise-Edit
- type: Destructible
thresholds:
- trigger:
@ -233,8 +235,14 @@
guides:
- Cyborgs
- type: StepTriggerImmune
# - type: TTS
# voice: TODO add our TTS Voice Sunrise
# Sunrise-start
- type: TTS
voice: FactCore
- type: Climbing
- type: BorgMagboots
walkModifier: 0.8
sprintModifier: 0.8
# Sunrise-end
- type: entity
abstract: true
@ -274,12 +282,34 @@
- NanoTrasen
- type: Access
enabled: false
groups:
- AllAccess
# Sunrise-Start
tags:
- EmergencyShuttleRepealAll
- Command
- Lawyer
- Engineering
- Medical
- Salvage
- Cargo
- Research
- Service
- Maintenance
- External
- Janitor
- Theatre
- Bar
- Chemistry
- Kitchen
- Chapel
- Hydroponics
- Atmospherics
# Sunrise-End
- type: AccessReader
access: [["Command"], ["Research"]]
- type: ShowJobIcons
- type: ShowMindShieldIcons
- type: BorgCrewManifestViewer # Sunrise-Edit
- type: entity
id: BaseBorgChassisSyndicate
@ -311,5 +341,57 @@
- type: Vocal
sounds:
Unsexed: UnisexSiliconSyndicate
# Sunrise-start
- type: PointLight
color: "#dd200b"
color: "#f51e0f"
radius: 6
energy: 3
- type: ShowJobIcons
- type: ShowMindShieldIcons
- type: ShowCriminalRecordIcons
- type: MobThresholds
thresholds:
0: Alive
200: Critical
300: Dead
stateAlertDict:
Alive: BorgHealth
Critical: BorgCrit
Dead: BorgDead
showOverlays: false
allowRevives: true
- type: FlashImmunity
- type: TypingIndicator
proto: syndibot
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 175
behaviors:
- !type:PlaySoundBehavior
sound:
path: /Audio/Machines/warning_buzzer.ogg
params:
volume: 5
- trigger:
!type:DamageTrigger
damage: 400
behaviors:
- !type:PlaySoundBehavior
sound:
collection: MetalBreak
- !type:EmptyContainersBehaviour
containers:
- borg_brain
- borg_module
- cell_slot
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Tag
tags:
- DoorBumpOpener
- CanPilot
- FootstepSound
- EmagImmune
# Sunrise-end

View file

@ -34,6 +34,11 @@
interactFailureString: petting-failure-generic-cyborg
interactSuccessSound:
path: /Audio/Ambience/Objects/periodic_beep.ogg
# Sunrise-Start
- type: InnateItem
instantActions:
- HandheldStationMapUnpowered
# Sunrise-End
- type: entity
id: BorgChassisMining
@ -60,7 +65,7 @@
movement:
state: miner
- type: BorgChassis
maxModules: 4
maxModules: 5 # Sunrise-Edit
moduleWhitelist:
tags:
- BorgModuleGeneric
@ -95,6 +100,16 @@
interactFailureString: petting-failure-salvage-cyborg
interactSuccessSound:
path: /Audio/Ambience/Objects/periodic_beep.ogg
# Sunrise-start
- type: FootstepModifier
footstepSoundCollection:
collection: FootstepCyborgSpider
params:
volume: -15
- type: MovementSpeedModifier
baseWalkSpeed : 2.5
baseSprintSpeed : 3.5
# Sunrise-end
- type: entity
id: BorgChassisEngineer
@ -113,7 +128,7 @@
map: ["light"]
visible: false
- type: BorgChassis
maxModules: 4
maxModules: 5 # Sunrise-Edit
moduleWhitelist:
tags:
- BorgModuleGeneric
@ -148,6 +163,18 @@
interactFailureString: petting-failure-engineer-cyborg
interactSuccessSound:
path: /Audio/Ambience/Objects/periodic_beep.ogg
# Sunrise-start
- type: TTS
voice: AdventureCore
- type: FootstepModifier
footstepSoundCollection:
collection: FootstepCyborgSpider
params:
volume: -15
- type: InnateItem
instantActions:
- HandheldStationMapUnpowered
# Sunrise-end
- type: entity
id: BorgChassisJanitor
@ -209,6 +236,16 @@
interactFailureString: petting-failure-janitor-cyborg
interactSuccessSound:
path: /Audio/Ambience/Objects/periodic_beep.ogg
# Sunrise-start
- type: FootstepModifier
footstepSoundCollection:
path: /Audio/Effects/Fluids/watersplash.ogg
params:
volume: -5
- type: InnateItem
instantActions:
- HandheldStationMapUnpowered
# Sunrise-end
- type: entity
id: BorgChassisMedical
@ -235,7 +272,7 @@
movement:
state: medical
- type: BorgChassis
maxModules: 4
maxModules: 5 # Sunrise-Edit
moduleWhitelist:
tags:
- BorgModuleGeneric
@ -274,8 +311,19 @@
interactFailureString: petting-failure-medical-cyborg
interactSuccessSound:
path: /Audio/Ambience/Objects/periodic_beep.ogg
- type: TTS # Sunrise-Edit
voice: FactCore # Sunrise-Edit
# Sunrise-start
- type: TTS
voice: TurretFloor
- type: FabricateCandy
- type: MovementSpeedModifier
baseWalkSpeed : 3
baseSprintSpeed : 5
- type: InnateItem
instantActions:
- HandheldCrewMonitorBorg
worldTargetActions:
- HandheldHealthAnalyzerUnpowered
# Sunrise-end
- type: entity
id: BorgChassisService
@ -363,6 +411,36 @@
interactFailureString: petting-failure-syndicate-cyborg
interactSuccessSound:
path: /Audio/Ambience/Objects/periodic_beep.ogg
# Sunrise-Start
- type: PointLight
color: "#dd200b"
- type: TriggerOnMobstateChange
preventSuicide: true
mobState:
- Critical
- type: OnUseTimerTrigger
delay: 3
initialBeepDelay: 0
beepInterval: 3
beepSound: /Audio/Effects/PowerSink/charge_fire.ogg
- type: ExplodeOnTrigger
- type: GibOnTrigger
deleteItems: true
- type: Explosive
explosionType: Default
totalIntensity: 3500
intensitySlope: 15
maxIntensity: 70
canCreateVacuum: true
- type: TTS
voice: Sentrybot
- type: MovementSpeedModifier
baseWalkSpeed : 2.5
baseSprintSpeed : 3.5
- type: InnateItem
worldTargetActions:
- Emag
# Sunrise-End
- type: entity
id: BorgChassisSyndicateMedical
@ -406,6 +484,17 @@
collection: FootstepHoverBorg
params:
volume: -6
# Sunrise-Start
- type: TTS
voice: Sentrybot
- type: MovementSpeedModifier
baseWalkSpeed: 2.5
baseSprintSpeed: 4.5
- type: InnateItem
worldTargetActions:
- Emag
- HandheldHealthAnalyzerUnpowered
# Sunrise-End
- type: entity
id: BorgChassisSyndicateSaboteur

View file

@ -6,8 +6,9 @@
- type: ContainerFill
containers:
borg_brain:
- Boris
- Boris # Sunrise-Edit
borg_module:
- BorgModuleStandart # Sunrise-Edit
- BorgModuleTool
- type: ItemSlots
slots:
@ -25,29 +26,30 @@
- type: ContainerFill
containers:
borg_brain:
- MMIFilled
- Boris # Sunrise-Edit
- type: ItemSlots
slots:
cell_slot:
name: power-cell-slot-component-slot-name-default
startingItem: PowerCellMedium
- type: entity
id: PlayerBorgSyndicateAssaultBattery
parent: BorgChassisSyndicateAssault
suffix: Battery, Module, Operative
components:
- type: NukeOperative
- type: ContainerFill
containers:
borg_brain:
- Sofia
borg_module:
- BorgModuleOperative
- BorgModuleL6C
- BorgModuleEsword
- type: ItemSlots
slots:
cell_slot:
name: power-cell-slot-component-slot-name-default
startingItem: PowerCellHyper
# Move to _Sunrise
#- type: entity
# id: PlayerBorgSyndicateAssaultBattery
# parent: BorgChassisSyndicateAssault
# suffix: Battery, Module, Operative
# components:
# - type: NukeOperative
# - type: ContainerFill
# containers:
# borg_brain:
# - Sofia # Sunrise-Edit
# borg_module:
# - BorgModuleOperative
# - BorgModuleL6C
# - BorgModuleEsword
# - type: ItemSlots
# slots:
# cell_slot:
# name: power-cell-slot-component-slot-name-default
# startingItem: PowerCellHyper

View file

@ -92,18 +92,19 @@
- type: EmitSoundOnUse
sound: /Audio/Animals/cat_meow.ogg
- type: entity
parent: ReinforcementRadio
id: ReinforcementRadioSyndicateCyborgAssault # Reinforcement radio exclusive to nukeops uplink
name: syndicate assault cyborg reinforcement radio
description: Call in a well armed assault cyborg, instantly!
suffix: NukeOps
components:
- type: GhostRole
name: ghost-role-information-syndie-assaultborg-name
description: ghost-role-information-syndie-assaultborg-description
rules: ghost-role-information-silicon-rules
raffle:
settings: default
- type: GhostRoleMobSpawner
prototype: PlayerBorgSyndicateAssaultBattery
# Move to _Sunrise
#- type: entity
# parent: ReinforcementRadio
# id: ReinforcementRadioSyndicateCyborgAssault # Reinforcement radio exclusive to nukeops uplink
# name: syndicate assault cyborg reinforcement radio
# description: Call in a well armed assault cyborg, instantly!
# suffix: NukeOps
# components:
# - type: GhostRole
# name: ghost-role-information-syndie-assaultborg-name
# description: ghost-role-information-syndie-assaultborg-description
# rules: ghost-role-information-silicon-rules
# raffle:
# settings: default
# - type: GhostRoleMobSpawner
# prototype: PlayerBorgSyndicateAssaultBattery

View file

@ -37,7 +37,7 @@
- type: entity
parent: Holoprojector
id: HoloprojectorBorg
id: HoloprojectorJanitorBorg # Sunrise-Edit
suffix: borg
components:
- type: HolosignProjector

View file

@ -16,11 +16,9 @@
enum.InstrumentUiKey.Key:
type: InstrumentBoundUserInterface
requireInputValidation: false
enum.StationMapUiKey.Key:
type: UntrackedStationMapBoundUserInterface
requireInputValidation: false
- type: Sprite
sprite: Objects/Fun/pai.rsi
#noRot: true
layers:
- state: pai-base
- state: pai-off-overlay
@ -30,6 +28,8 @@
context: "human"
- type: PAI
- type: BlockMovement
blockInteractionAttempt: false
blockUseAttempt: false
- type: ToggleableGhostRole
examineTextMindPresent: pai-system-pai-installed
examineTextMindSearching: pai-system-still-searching
@ -55,8 +55,6 @@
- type: Actions
- type: TypingIndicator
proto: robot
# - type: TTS
# voice: TODO add our TTS Voice Sunrise
- type: Speech
speechVerb: Robotic
speechSounds: Pai
@ -74,7 +72,18 @@
Off: { state: pai-off-overlay }
Searching: { state: pai-searching-overlay }
On: { state: pai-on-overlay }
- type: StationMap
# Sunrise-Edit
- type: TTS
voice: FactCore
- type: InnateItem
instantActions:
- PortableSurveillanceCameraMonitor
- HandheldStationMapUnpowered
- HandheldCrewMonitorBorg
worldTargetActions:
- HandheldHealthAnalyzerUnpowered
- type: BorgBrain
# Sunrise-End
- type: entity
parent: PersonalAI
@ -107,6 +116,12 @@
Off: { state: syndicate-pai-off-overlay }
Searching: { state: syndicate-pai-searching-overlay }
On: { state: syndicate-pai-on-overlay }
# Sunrise-Edit
- type: InnateItem
worldTargetActions:
- Emag
- HandheldHealthAnalyzerUnpowered
# Sunrise-End
- type: entity
parent: PersonalAI

View file

@ -116,7 +116,7 @@
- CableApcStackLingering10
- CableMVStackLingering10
- CableHVStackLingering10
- Wirecutter
- WirecutterBorg # Sunrise-Edit
- trayScanner
- type: entity
@ -171,12 +171,12 @@
- state: icon-tools
- type: ItemBorgModule
items:
- Crowbar
- Wrench
- Screwdriver
- Wirecutter
- CrowbarBorg # Sunrise-Edit
- WrenchBorg # Sunrise-Edit
- ScrewdriverBorg # Sunrise-Edit
- WirecutterBorg # Sunrise-Edit
- Multitool
- WelderIndustrial
- WelderBorg # Sunrise-Edit
# cargo modules
- type: entity
@ -236,7 +236,7 @@
- type: ItemBorgModule
items:
- Omnitool
- WelderExperimental
- WelderBorg # Sunrise-Edit
- NetworkConfigurator
- RemoteSignaller
- GasAnalyzer
@ -284,8 +284,8 @@
- type: ItemBorgModule
items:
- LightReplacer
- Crowbar
- Screwdriver
- CrowbarBorg # Sunrise-Edit
- ScrewdriverBorg # Sunrise-Edit
- type: entity
id: BorgModuleCleaning
@ -314,8 +314,8 @@
- type: ItemBorgModule
items:
- AdvMopItem
- HoloprojectorBorg
- SprayBottleSpaceCleaner
- HoloprojectorJanitorBorg # Sunrise-Edit
- SprayBottleSpaceCleanerBorg # Sunrise-Edit
- Dropper
- TrashBag
@ -345,7 +345,6 @@
- state: icon-treatment
- type: ItemBorgModule
items:
- HandheldHealthAnalyzerUnpowered
- Brutepack10Lingering
- Ointment10Lingering
- Gauze10Lingering
@ -376,11 +375,7 @@
- state: icon-chemist
- type: ItemBorgModule
items:
- HandheldHealthAnalyzerUnpowered
- Beaker
- Beaker
- BorgDropper
- BorgHypo
- HyposprayBorgMedical # Sunrise-Edit
# science modules
# todo: if science ever gets their own custom robot, add more "sci" modules.

Some files were not shown because too many files have changed in this diff Show more