Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Race: IPCs #1480

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
da48783
Complete IPC overhaul (#31)
Day-OS Jun 28, 2024
4a7c1c4
Missing dependencies
Timemaster99 Jul 10, 2024
fe305f6
Updated old methods and conventions
Timemaster99 Jul 10, 2024
d7bfcef
Fixed IPC guidebook locale
Timemaster99 Jul 10, 2024
5f0fff2
Fixed color for markings and IPC
Timemaster99 Jul 10, 2024
0244121
Merge branch 'master' into ipc-port
Timemaster99 Jul 10, 2024
dbcbfe8
IPCs can no longer eject their own battery, in congruence with borgs
Timemaster99 Jul 10, 2024
1981561
Merge branch 'master' into ipc-port
Timemaster99 Jul 13, 2024
28bc046
Merge branch 'master' into ipc-port
Timemaster99 Jul 15, 2024
dc9bcd3
Merge branch 'master' into ipc-port
Timemaster99 Jul 15, 2024
d8ea098
IPCs no longer lose charge when SSD or ghosted
Timemaster99 Jul 16, 2024
8d16f5c
Merge branch 'ipc-port' of https://github.com/Timemaster99/Delta-v in…
Timemaster99 Jul 16, 2024
dcaaf59
Merge branch 'master' into ipc-port
Timemaster99 Jul 16, 2024
ee7685f
Merge branch 'master' into ipc-port
Timemaster99 Jul 25, 2024
4a70062
Fixed old using reference
Timemaster99 Jul 25, 2024
d2f99c0
Fixed TryWaking call
Timemaster99 Jul 25, 2024
20183b5
Merge branch 'master' into ipc-port
Timemaster99 Jul 25, 2024
46f8045
Refactored IPC alerts to use borg health and battery instead
Timemaster99 Jul 27, 2024
1865d65
Fixes invalid alert category
Timemaster99 Jul 27, 2024
4f363f3
Merge branch 'master' into ipc-port
Timemaster99 Jul 30, 2024
a0eecea
Fix alert proto test fail
Timemaster99 Aug 2, 2024
843232e
Merge branch 'master' into ipc-port
Timemaster99 Aug 3, 2024
712979d
Updated markings
Timemaster99 Aug 7, 2024
58aadc4
Merge branch 'master' into ipc-port
Timemaster99 Aug 7, 2024
68eeb10
Marked, moved, and commented changes to base files
Timemaster99 Aug 7, 2024
af0b295
Merge branch 'ipc-port' of https://github.com/Timemaster99/Delta-v in…
Timemaster99 Aug 7, 2024
b6f0543
IPCs are now alerted when another person tries to toggle their lock
Timemaster99 Aug 7, 2024
d91246c
Added missing comment in BatterySlotRequiresLockSystem
Timemaster99 Aug 7, 2024
98bcb3e
Readded markings locale
Timemaster99 Aug 7, 2024
3d922d0
Merge branch 'master' into ipc-port
Timemaster99 Aug 11, 2024
0b74862
Updated starting gear to use interface
Timemaster99 Aug 12, 2024
51d15e3
Merge branch 'master' into ipc-port
Timemaster99 Aug 12, 2024
ce661cb
Merge branch 'master' into ipc-port
Timemaster99 Aug 15, 2024
34cf141
Removed ChargeBuffer so IPCs can be recharged instantly. Fixed indefi…
Timemaster99 Aug 15, 2024
2ada76f
Merge branch 'master' into ipc-port
Timemaster99 Aug 16, 2024
ed5f1c1
Merge branch 'master' into ipc-port
Timemaster99 Aug 20, 2024
932d389
Added missing if statement to charge update system
Timemaster99 Aug 21, 2024
5cb93ee
Fixed alert reference
Timemaster99 Aug 21, 2024
80902f5
Apply suggestions from code review
Timemaster99 Aug 21, 2024
70c3c36
Update Content.Server/Power/Components/SiliconEmitSoundOnDrainedCompo…
VMSolidus Aug 21, 2024
1140035
Update Content.Server/Power/Components/SiliconEmitSoundOnDrainedCompo…
VMSolidus Aug 21, 2024
4671d56
Added extra info on npc silicon state
Timemaster99 Aug 21, 2024
666ff29
Apply suggestions from code review
Timemaster99 Aug 21, 2024
50284ab
Merge branch 'ipc-port' of https://github.com/Timemaster99/Delta-v in…
Timemaster99 Aug 21, 2024
c268b95
Merge branch 'master' into ipc-port
Sep 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Robust.Shared.Console;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Content.Server.SimpleStation14.Silicon.IPC; // Parkstation - IPCs

namespace Content.Server.Administration.Commands
{
Expand Down Expand Up @@ -127,7 +128,7 @@ public static bool SetOutfit(EntityUid target, string gear, IEntityManager entit
handsSystem.TryPickup(target, inhandEntity, checkActionBlocker: false, handsComp: handsComponent);
}
}

InternalEncryptionKeySpawner.TryInsertEncryptionKey(target, startingGear, entityManager, profile); // Parkstation - IPC
return true;
}
}
Expand Down
4 changes: 3 additions & 1 deletion Content.Server/Bed/BedSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Content.Shared.Mobs.Systems;
using Content.Shared.Power;
using Robust.Shared.Timing;
using Content.Shared.SimpleStation14.Silicon.Components; // Parkstation-IPCs // I shouldn't have to modify this.
using Robust.Shared.Utility;

namespace Content.Server.Bed
Expand Down Expand Up @@ -70,7 +71,8 @@ public override void Update(float frameTime)

foreach (var healedEntity in strapComponent.BuckledEntities)
{
if (_mobStateSystem.IsDead(healedEntity))
if (_mobStateSystem.IsDead(healedEntity)
|| HasComp<SiliconComponent>(healedEntity)) // Parkstation-IPCs // I shouldn't have to modify this.
continue;

var damage = bedComponent.Damage;
Expand Down
12 changes: 7 additions & 5 deletions Content.Server/Electrocution/ElectrocutionSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
[ValidatePrototypeId<DamageTypePrototype>]
private const string DamageType = "Shock";

// Multiply and shift the log scale for shock damage.
// Yes, this is absurdly small for a reason.
public const float ElectrifiedDamagePerWatt = 0.0015f; // Parkstation-IPC // This information is allowed to be public, and was needed in BatteryElectrocuteChargeSystem.cs

private const float RecursiveDamageMultiplier = 0.75f;
private const float RecursiveTimeMultiplier = 0.8f;

Expand Down Expand Up @@ -300,9 +302,9 @@ public override bool TryDoElectrocution(
|| !DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects))
return false;

RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient), true);
return true;
}
RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient, shockDamage), true); // Parkstation-IPC
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undo these indents

}

private bool TryDoElectrocutionPowered(
EntityUid uid,
Expand Down Expand Up @@ -350,7 +352,7 @@ private bool TryDoElectrocutionPowered(
electrocutionComponent.Electrocuting = uid;
electrocutionComponent.Source = sourceUid;

RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient), true);
RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient, shockDamage), true); // Parkstation-IPC

return true;
}
Expand Down
10 changes: 8 additions & 2 deletions Content.Server/Mobs/DeathgaspComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Content.Shared.Chat.Prototypes;
using Content.Shared.Chat.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.Mobs;
Expand All @@ -13,6 +13,12 @@ public sealed partial class DeathgaspComponent : Component
/// <summary>
/// The emote prototype to use.
/// </summary>
[DataField("prototype", customTypeSerializer:typeof(PrototypeIdSerializer<EmotePrototype>))]
[DataField(customTypeSerializer:typeof(PrototypeIdSerializer<EmotePrototype>))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reason to change this, it can be done upstream and use ProtoId too

public string Prototype = "DefaultDeathgasp";

/// <summary>
/// Makes sure that the deathgasp is only displayed if the entity went critical before dying - Estacao Pirata
/// </summary>
[DataField]
public bool NeedsCritical = true;
}
8 changes: 5 additions & 3 deletions Content.Server/Mobs/DeathgaspSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Content.Server.Chat.Systems;
using Content.Server.Chat.Systems;
using Content.Server.Speech.Muting;
using Content.Shared.Mobs;
using Content.Shared.Speech.Muting;
Expand All @@ -20,9 +20,11 @@ public override void Initialize()

private void OnMobStateChanged(EntityUid uid, DeathgaspComponent component, MobStateChangedEvent args)
{
// don't deathgasp if they arent going straight from crit to dead
if (args.NewMobState != MobState.Dead || args.OldMobState != MobState.Critical)
// don't deathgasp if they arent going straight from crit to dead - Estacao Pirata
if (component.NeedsCritical && args.OldMobState != MobState.Critical
|| args.NewMobState != MobState.Dead)
return;
// End of Estacao Pirata code

Deathgasp(uid, component);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace Content.Server.SimpleStation14.Power;

[RegisterComponent]
public sealed partial class BatteryDrinkerComponent : Component
{
/// <summary>
/// Is this drinker allowed to drink batteries not tagged as <see cref="BatteryDrinkSource"/>?
/// </summary>
[DataField]
public bool DrinkAll;

/// <summary>
/// How long it takes to drink from a battery, in seconds.
/// Is multiplied by the source.
/// </summary>
[DataField]
public float DrinkSpeed = 1.5f;

/// <summary>
/// The multiplier for the amount of power to attempt to drink.
/// Default amount is 1000
/// </summary>
[DataField]
public float DrinkMultiplier = 5f;

/// <summary>
/// The multiplier for how long it takes to drink a non-source battery, if <see cref="DrinkAll"/> is true.
/// </summary>
[DataField]
public float DrinkAllMultiplier = 2.5f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Numerics;

namespace Content.Server.SimpleStation14.Power.Components;

[RegisterComponent]
public sealed partial class RandomBatteryChargeComponent : Component
{
/// <summary>
/// The minimum and maximum max charge the battery can have.
/// </summary>
[DataField]
public Vector2 BatteryMaxMinMax = new(0.85f, 1.15f);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use destruction MinMax instead of vector2


/// <summary>
/// The minimum and maximum current charge the battery can have.
/// </summary>
[DataField]
public Vector2 BatteryChargeMinMax = new(1f, 1f);

/// <summary>
/// False if the randomized charge of the battery should be a multiple of the preexisting current charge of the battery.
/// True if the randomized charge of the battery should be a multiple of the max charge of the battery post max charge randomization.
/// </summary>
[DataField]
public bool BasedOnMaxCharge = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.ComponentModel.DataAnnotations;
using Robust.Shared.Audio;
using Content.Server.Sound.Components;
using System;

namespace Content.Server.SimpleStation14.Silicon;

/// <summary>
/// Applies a <see cref="SpamEmitSoundComponent"/> to a Silicon when its battery is drained, and removes it when it's not.
/// </summary>
[RegisterComponent]
public sealed partial class SiliconEmitSoundOnDrainedComponent : Component
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should use a ComponentRegistry instead of being extremely hardcoded to this one thing

{
[DataField]
public SoundSpecifier Sound = default!;

[DataField]
public TimeSpan MinInterval = TimeSpan.FromSeconds(8);

[DataField]
public TimeSpan MaxInterval = TimeSpan.FromSeconds(15);

[DataField]
public float PlayChance = 1f;

[DataField]
public string? PopUp;
}
144 changes: 144 additions & 0 deletions Content.Server/SimpleStation14/Power/Systems/BatteryDrinkerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Power.Components;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.DoAfter;
using Content.Shared.PowerCell.Components;
using Content.Shared.SimpleStation14.Silicon;
using Content.Shared.Verbs;
using Robust.Shared.Utility;
using Content.Server.SimpleStation14.Silicon.Charge;
using Content.Server.Power.EntitySystems;
using Content.Server.Popups;
using Content.Server.PowerCell;
using Content.Shared.Popups;
using Content.Shared.SimpleStation14.Silicon.Components;
using FastAccessors;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;

namespace Content.Server.SimpleStation14.Power;

public sealed class BatteryDrinkerSystem : EntitySystem
{
[Dependency] private readonly ItemSlotsSystem _slots = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly BatterySystem _battery = default!;
[Dependency] private readonly SiliconChargeSystem _silicon = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly PowerCellSystem _powerCell = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<BatteryComponent, GetVerbsEvent<AlternativeVerb>>(AddAltVerb);

SubscribeLocalEvent<BatteryDrinkerComponent, BatteryDrinkerDoAfterEvent>(OnDoAfter);
}

private void AddAltVerb(EntityUid uid, BatteryComponent batteryComponent, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;

if (!TryComp<BatteryDrinkerComponent>(args.User, out var drinkerComp) ||
!TestDrinkableBattery(uid, drinkerComp) ||
!_silicon.TryGetSiliconBattery(args.User, out var drinkerBattery))
return;

AlternativeVerb verb = new()
{
Act = () => DrinkBattery(uid, args.User, drinkerComp),
Text = Loc.GetString("battery-drinker-verb-drink"),
Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/smite.svg.192dpi.png")),
};

args.Verbs.Add(verb);
}

private bool TestDrinkableBattery(EntityUid target, BatteryDrinkerComponent drinkerComp)
{
if (!drinkerComp.DrinkAll && !HasComp<BatteryDrinkerSourceComponent>(target))
return false;

return true;
}

private void DrinkBattery(EntityUid target, EntityUid user, BatteryDrinkerComponent drinkerComp)
{
var doAfterTime = drinkerComp.DrinkSpeed;

if (TryComp<BatteryDrinkerSourceComponent>(target, out var sourceComp))
doAfterTime *= sourceComp.DrinkSpeedMulti;
else
doAfterTime *= drinkerComp.DrinkAllMultiplier;

var args = new DoAfterArgs(EntityManager, user, doAfterTime, new BatteryDrinkerDoAfterEvent(), user, target) // TODO: Make this doafter loop, once we merge Upstream.
{
BreakOnDamage = true,
BreakOnMove = true,
Broadcast = false,
DistanceThreshold = 1.35f,
RequireCanInteract = true,
CancelDuplicate = false
};

_doAfter.TryStartDoAfter(args);
}

private void OnDoAfter(EntityUid uid, BatteryDrinkerComponent drinkerComp, DoAfterEvent args)
{
if (args.Cancelled || args.Target == null)
return;

var source = args.Target.Value;
var drinker = uid;
var sourceBattery = Comp<BatteryComponent>(source);

_silicon.TryGetSiliconBattery(drinker, out var drinkerBatteryComponent);

if (!TryComp(uid, out PowerCellSlotComponent? batterySlot))
return;

var container = _container.GetContainer(uid, batterySlot.CellSlotId);
var drinkerBattery = container.ContainedEntities.First();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

power cell system has a method for this dont reinvent the wheel


TryComp<BatteryDrinkerSourceComponent>(source, out var sourceComp);

DebugTools.AssertNotNull(drinkerBattery);

if (drinkerBattery == null)
return;

var amountToDrink = drinkerComp.DrinkMultiplier * 1000;

amountToDrink = MathF.Min(amountToDrink, sourceBattery.CurrentCharge);
amountToDrink = MathF.Min(amountToDrink, drinkerBatteryComponent!.MaxCharge - drinkerBatteryComponent.CurrentCharge);

if (sourceComp != null && sourceComp.MaxAmount > 0)
amountToDrink = MathF.Min(amountToDrink, (float) sourceComp.MaxAmount);

if (amountToDrink <= 0)
{
_popup.PopupEntity(Loc.GetString("battery-drinker-empty", ("target", source)), drinker, drinker);
return;
}

if (_battery.TryUseCharge(source, amountToDrink))
_battery.SetCharge(drinkerBattery, drinkerBatteryComponent.CurrentCharge + amountToDrink, drinkerBatteryComponent);
else
{
_battery.SetCharge(drinkerBattery, sourceBattery.CurrentCharge + drinkerBatteryComponent.CurrentCharge, drinkerBatteryComponent);
_battery.SetCharge(source, 0);
}

if (sourceComp != null && sourceComp.DrinkSound != null){
_popup.PopupEntity(Loc.GetString("ipc-recharge-tip"), drinker, drinker, PopupType.SmallCaution);
_audio.PlayPvs(sourceComp.DrinkSound, source);
Spawn("EffectSparks", Transform(source).Coordinates);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Content.Server.Electrocution;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Shared.Electrocution;
using Robust.Shared.Random;
using Robust.Shared.Timing;

namespace Content.Server.SimpleStation14.Power.Systems;

public sealed class BatteryElectrocuteChargeSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly BatterySystem _battery = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<BatteryComponent, ElectrocutedEvent>(OnElectrocuted);
}

private void OnElectrocuted(EntityUid uid, BatteryComponent battery, ElectrocutedEvent args)
{
if (args.ShockDamage == null || args.ShockDamage <= 0)
return;

var damagePerWatt = ElectrocutionSystem.ElectrifiedDamagePerWatt * 2;

var damage = args.ShockDamage.Value * args.SiemensCoefficient;
var charge = Math.Min(damage / damagePerWatt, battery.MaxCharge * 0.25f) * _random.NextFloat(0.75f, 1.25f);

_battery.SetCharge(uid, battery.CurrentCharge + charge);

_popup.PopupEntity(Loc.GetString("battery-electrocute-charge"), uid, uid);
}
}
Loading
Loading