This repository has been archived by the owner on Dec 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Species] InterPersonal Conflict (#97)
# Description Adds IPCs! Everyone's favourite Positronic species finally available to be played in Space Station 14! # TODO - [x] Make the basis of the SiliconCharge system - [x] Make a working IPC species - [x] Improve upon Borg - [x] Add chargers and charging systems - [x] Localize all strings - [ ] ~~Make a hud/shader effect for power drain~~ - [ ] ~~Make sure IPCs can be refilled (blood transfusions)~~ Seperate pr #172 - [x] Make sure IPCs can't become zombies/suffer from many other biological issues (will likely need testing) - [x] Make chargers take machine parts for upgrading - [ ] ~~Make Silicon batteries upgradable(?)~~ Gonna probably just wait on bodysystem. - [x] Ensure death, crit, and revival work as intended - [x] Fix skin color being weird - [x] Make sure BatteryDrinker is clean Ready to merge? # Changelog :cl: - add: Added IPC to the game as a new species! Your favourite robot people are finally around to suffer like the rest of us. Be sure to stop by Engineering for a charge! --------- Co-authored-by: DEATHB4DEFEAT <[email protected]>
- Loading branch information
1 parent
3d86d8f
commit 81ba344
Showing
164 changed files
with
6,937 additions
and
295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
namespace Content.Server.Borgs | ||
{ | ||
[Obsolete("CyborgComponent is unused on Parkstation, see SiliconComponent")] // Parkstation-IPCs | ||
[RegisterComponent] | ||
public sealed class CyborgComponent : Component | ||
{} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
Content.Server/SimpleStation14/Power/Components/BatteryDrinkerComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
namespace Content.Server.SimpleStation14.Power; | ||
|
||
[RegisterComponent] | ||
public sealed class BatteryDrinkerComponent : Component | ||
{ | ||
/// <summary> | ||
/// Is this drinker allowed to drink batteries not tagged as <see cref="BatteryDrinkSource"/>? | ||
/// </summary> | ||
[DataField("drinkAll"), ViewVariables(VVAccess.ReadWrite)] | ||
public bool DrinkAll = false; | ||
|
||
/// <summary> | ||
/// How long it takes to drink from a battery, in seconds. | ||
/// Is multiplied by the source. | ||
/// </summary> | ||
[DataField("drinkSpeed"), ViewVariables(VVAccess.ReadWrite)] | ||
public float DrinkSpeed = 1.5f; | ||
|
||
/// <summary> | ||
/// The multiplier for the amount of power to attempt to drink. | ||
/// Default amount is 1000 | ||
/// </summary> | ||
[DataField("drinkMultiplier"), ViewVariables(VVAccess.ReadWrite)] | ||
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("drinkAllMultiplier"), ViewVariables(VVAccess.ReadWrite)] | ||
public float DrinkAllMultiplier = 2.5f; | ||
} |
26 changes: 26 additions & 0 deletions
26
Content.Server/SimpleStation14/Power/Components/RandomBatteryChargeComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 class RandomBatteryChargeComponent : Component | ||
{ | ||
/// <summary> | ||
/// The minimum and maximum max charge the battery can have. | ||
/// </summary> | ||
[DataField("batteryMaxMinMax")] | ||
public Vector2 BatteryMaxMinMax = new(0.85f, 1.15f); | ||
|
||
/// <summary> | ||
/// The minimum and maximum current charge the battery can have. | ||
/// </summary> | ||
[DataField("batteryChargeMinMax")] | ||
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("basedOnMaxCharge")] | ||
public bool BasedOnMaxCharge = true; | ||
} |
24 changes: 24 additions & 0 deletions
24
Content.Server/SimpleStation14/Power/Components/SiliconEmitSoundOnDrainedComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using Robust.Shared.Audio; | ||
using Content.Server.Sound.Components; | ||
|
||
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 class SiliconEmitSoundOnDrainedComponent : Component | ||
{ | ||
[DataField("sound"), Required] | ||
public SoundSpecifier Sound = default!; | ||
|
||
[DataField("interval")] | ||
public float Interval = 8f; | ||
|
||
[DataField("playChance")] | ||
public float PlayChance = 1f; | ||
|
||
[DataField("popUp")] | ||
public string? PopUp; | ||
} |
146 changes: 146 additions & 0 deletions
146
Content.Server/SimpleStation14/Power/Systems/BatteryDrinkerSystem.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
using System.Diagnostics.CodeAnalysis; | ||
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; | ||
|
||
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!; | ||
|
||
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) || | ||
!TryGetFillableBattery(args.User, out var drinkerBattery, out _)) | ||
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 bool TryGetFillableBattery(EntityUid uid, [NotNullWhen(true)] out BatteryComponent? battery, [NotNullWhen(true)] out EntityUid batteryUid) | ||
{ | ||
if (_silicon.TryGetSiliconBattery(uid, out battery, out batteryUid)) | ||
return true; | ||
|
||
if (TryComp(uid, out battery)) | ||
return true; | ||
|
||
if (TryComp<PowerCellSlotComponent>(uid, out var powerCellSlot) && | ||
_slots.TryGetSlot(uid, powerCellSlot.CellSlotId, out var slot) && | ||
slot.Item != null && | ||
TryComp(slot.Item.Value, out battery)) | ||
{ | ||
batteryUid = slot.Item.Value; | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
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(user, doAfterTime, new BatteryDrinkerDoAfterEvent(), user, target) // TODO: Make this doafter loop, once we merge Upstream. | ||
{ | ||
BreakOnDamage = true, | ||
BreakOnTargetMove = 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); | ||
|
||
TryGetFillableBattery(drinker, out var drinkerBattery, out var drinkerBatteryUid); | ||
|
||
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, drinkerBattery.MaxCharge - drinkerBattery.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, sourceBattery)) | ||
_battery.SetCharge(drinkerBatteryUid, drinkerBattery.Charge + amountToDrink, drinkerBattery); | ||
else | ||
{ | ||
_battery.SetCharge(drinker, sourceBattery.Charge + drinkerBattery.Charge, drinkerBattery); | ||
_battery.SetCharge(source, 0, sourceBattery); | ||
} | ||
|
||
if (sourceComp != null && sourceComp.DrinkSound != null) | ||
_audio.PlayPvs(sourceComp.DrinkSound, source); | ||
} | ||
} |
Oops, something went wrong.