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

Goob Mechs #1611

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions Content.Client/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Content.Client.Weapons.Ranged.Components;
using Content.Shared.Camera;
using Content.Shared.CombatMode;
using Content.Shared.Mech.Components; // Goobstation
using Content.Shared.Weapons.Ranged;
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Events;
Expand Down Expand Up @@ -156,6 +157,9 @@ public override void Update(float frameTime)

var entity = entityNull.Value;

if (TryComp<MechPilotComponent>(entity, out var mechPilot)) // Goobstation
entity = mechPilot.Mech;

if (!TryGetGun(entity, out var gunUid, out var gun))
{
return;
Expand Down
7 changes: 5 additions & 2 deletions Content.Server/Cloning/CloningSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using Content.Server.Materials;
using Content.Server.Popups;
using Content.Server.Power.EntitySystems;
using Content.Server.Traits.Assorted;
using Content.Shared.Silicon.Components; // Goobstation
using Content.Shared.Atmos;
using Content.Shared.CCVar;
using Content.Shared.Chemistry.Components;
Expand Down Expand Up @@ -204,13 +204,16 @@ public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity<MindComponen
|| !_playerManager.TryGetSessionById(mind.UserId.Value, out var client)
|| !CheckBiomassCost(uid, physics, clonePod, cloningCostMultiplier))
return false;

// Special handling for humanoid data related to metempsychosis. This function is needed for Paradox Anomaly code to play nice with reincarnated people
var pref = humanoid.LastProfileLoaded;
if (pref == null
|| !_prototypeManager.TryIndex(humanoid.Species, out var speciesPrototype))
return false;

if (HasComp<SiliconComponent>(bodyToClone))
return false; // Goobstation: Don't clone IPCs.

// Yes, this can return true without making a body. If it returns true, we're making clone soup instead.
if (CheckGeneticDamage(uid, bodyToClone, clonePod, out var geneticDamage, failChanceModifier))
return true;
Expand Down
2 changes: 0 additions & 2 deletions Content.Server/Mech/Systems/MechSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ private void OnMechEntry(EntityUid uid, MechComponent component, MechEntryEvent

TryInsert(uid, args.Args.User, component);
_actionBlocker.UpdateCanMove(uid);

args.Handled = true;
}

Expand All @@ -244,7 +243,6 @@ private void OnMechExit(EntityUid uid, MechComponent component, MechExitEvent ar
return;

TryEject(uid, component);

args.Handled = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ namespace Content.Server.Objectives.Components;
[RegisterComponent, Access(typeof(KillPersonConditionSystem))]
public sealed partial class PickRandomPersonComponent : Component
{
[DataField]
public bool NeedsOrganic; // Goobstation: Only pick non-silicon players.
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server.Objectives.Components;
using Content.Server.Shuttles.Systems;
using Content.Shared.CCVar;
Expand Down Expand Up @@ -54,7 +55,7 @@ private void OnPersonAssigned(EntityUid uid, PickRandomPersonComponent comp, ref
return;

// no other humans to kill
var allHumans = _mind.GetAliveHumansExcept(args.MindId);
var allHumans = _mind.GetAliveHumans(args.MindId, comp.NeedsOrganic);
if (allHumans.Count == 0)
{
args.Cancelled = true;
Expand All @@ -78,7 +79,7 @@ private void OnHeadAssigned(EntityUid uid, PickRandomHeadComponent comp, ref Obj
return;

// no other humans to kill
var allHumans = _mind.GetAliveHumansExcept(args.MindId);
var allHumans = _mind.GetAliveHumans(args.MindId);
if (allHumans.Count == 0)
{
args.Cancelled = true;
Expand All @@ -94,7 +95,7 @@ private void OnHeadAssigned(EntityUid uid, PickRandomHeadComponent comp, ref Obj
}

if (allHeads.Count == 0)
allHeads = allHumans; // fallback to non-head target
allHeads = allHumans.Select(human => human.Owner).ToList(); // fallback to non-head target

_target.SetTarget(uid, _random.Pick(allHeads), target);
}
Expand Down
4 changes: 2 additions & 2 deletions Content.Server/PowerCell/PowerCellSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ private void OnCellEmpAttempt(EntityUid uid, PowerCellComponent component, EmpAt

private void OnCellSlotExamined(EntityUid uid, PowerCellSlotComponent component, ExaminedEvent args)
{
TryGetBatteryFromSlot(uid, out var battery);
OnBatteryExamined(uid, battery, args);
TryGetBatteryFromSlot(uid, out var batteryEnt, out var battery); // Goobstation
OnBatteryExamined(batteryEnt.GetValueOrDefault(uid), battery, args); // Goobstation
}

private void OnBatteryExamined(EntityUid uid, BatteryComponent? component, ExaminedEvent args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,9 @@ private float SiliconHeatEffects(EntityUid silicon, SiliconComponent siliconComp
if (!_random.Prob(Math.Clamp(temperComp.CurrentTemperature / (upperThresh * 5), 0.001f, 0.9f)))
return hotTempMulti;

_flammable.AdjustFireStacks(silicon, Math.Clamp(siliconComp.FireStackMultiplier, -10, 10), flamComp);
_flammable.Ignite(silicon, silicon, flamComp);
// Goobstation: Replaced by KillOnOverheatSystem
//_flammable.AdjustFireStacks(silicon, Math.Clamp(siliconComp.FireStackMultiplier, -10, 10), flamComp);
//_flammable.Ignite(silicon, silicon, flamComp);
return hotTempMulti;
}

Expand Down
30 changes: 22 additions & 8 deletions Content.Server/Silicon/WeldingHealable/WeldingHealableSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using Content.Shared.Damage;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Tools;
using Content.Shared._Shitmed.Targeting;
using Content.Shared.Body.Systems;
using Content.Shared.Tools.Components;
using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem;

Expand All @@ -17,7 +20,7 @@ public sealed class WeldingHealableSystem : SharedWeldingHealableSystem
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;

[Dependency] private readonly SharedBodySystem _bodySystem = default!;
public override void Initialize()
{
SubscribeLocalEvent<WeldingHealableComponent, InteractUsingEvent>(Repair);
Expand All @@ -31,7 +34,7 @@ private void OnRepairFinished(EntityUid uid, WeldingHealableComponent healableCo
|| !TryComp<WeldingHealingComponent>(args.Used, out var component)
|| damageable.DamageContainerID is null
|| !component.DamageContainers.Contains(damageable.DamageContainerID)
|| !HasDamage(damageable, component)
|| !HasDamage((args.Target.Value, damageable), component, args.User)
|| !TryComp<WelderComponent>(args.Used, out var welder)
|| !TryComp<SolutionContainerManagerComponent>(args.Used, out var solutionContainer))
return;
Expand Down Expand Up @@ -70,7 +73,7 @@ private async void Repair(EntityUid uid, WeldingHealableComponent healableCompon
|| !EntityManager.TryGetComponent(args.Target, out DamageableComponent? damageable)
|| damageable.DamageContainerID is null
|| !component.DamageContainers.Contains(damageable.DamageContainerID)
|| !HasDamage(damageable, component)
|| !HasDamage((args.Target, damageable), component, args.User)
|| !_toolSystem.HasQuality(args.Used, component.QualityNeeded)
|| args.User == args.Target && !component.AllowSelfHeal)
return;
Expand All @@ -79,8 +82,8 @@ private async void Repair(EntityUid uid, WeldingHealableComponent healableCompon
? component.DoAfterDelay * component.SelfHealPenalty
: component.DoAfterDelay;

args.Handled = _toolSystem.UseTool
(args.Used,
args.Handled = _toolSystem.UseTool(
args.Used,
args.User,
args.Target,
delay,
Expand All @@ -91,15 +94,26 @@ private async void Repair(EntityUid uid, WeldingHealableComponent healableCompon
});
}

private bool HasDamage(DamageableComponent component, WeldingHealingComponent healable)
private bool HasDamage(Entity<DamageableComponent> damageable, WeldingHealingComponent healable, EntityUid user)
{
if (healable.Damage.DamageDict is null)
return false;

foreach (var type in healable.Damage.DamageDict)
if (component.Damage.DamageDict[type.Key].Value > 0)
if (damageable.Comp.Damage.DamageDict[type.Key].Value > 0)
return true;

// In case the healer is a humanoid entity with targeting, we run the check on the targeted parts.
if (!TryComp(user, out TargetingComponent? targeting))
return false;

var (targetType, targetSymmetry) = _bodySystem.ConvertTargetBodyPart(targeting.Target);
foreach (var part in _bodySystem.GetBodyChildrenOfType(damageable, targetType, symmetry: targetSymmetry))
if (TryComp<DamageableComponent>(part.Id, out var damageablePart))
foreach (var type in healable.Damage.DamageDict)
if (damageablePart.Damage.DamageDict[type.Key].Value > 0)
return true;

return false;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using Content.Server.Mech.Systems;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Shared.Mech.Components;
using Content.Shared.Mech.EntitySystems;
using Content.Shared.Mech.Equipment.Components;
using Content.Shared.Throwing;
using Content.Shared.Weapons.Ranged.Components;
using Robust.Shared.Random;

namespace Content.Server.Mech.Equipment.EntitySystems;
public sealed class MechGunSystem : EntitySystem
{
[Dependency] private readonly MechSystem _mech = default!;
[Dependency] private readonly BatterySystem _battery = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MechEquipmentComponent, HandleMechEquipmentBatteryEvent>(OnHandleMechEquipmentBattery);
SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, CheckMechWeaponBatteryEvent>(OnCheckBattery);
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, CheckMechWeaponBatteryEvent>(OnCheckBattery);
}

private void OnHandleMechEquipmentBattery(EntityUid uid, MechEquipmentComponent component, HandleMechEquipmentBatteryEvent args)
{
if (!component.EquipmentOwner.HasValue)
return;

if (!TryComp<MechComponent>(component.EquipmentOwner.Value, out var mech))
return;

if (TryComp<BatteryComponent>(uid, out var battery))
{
var ev = new CheckMechWeaponBatteryEvent(battery);
RaiseLocalEvent(uid, ref ev);

if (ev.Cancelled)
return;

ChargeGunBattery(uid, battery);
}
}

private void OnCheckBattery(EntityUid uid, BatteryAmmoProviderComponent component, CheckMechWeaponBatteryEvent args)
{
if (args.Battery.CurrentCharge > component.FireCost)
args.Cancelled = true;
}

private void ChargeGunBattery(EntityUid uid, BatteryComponent component)
{
if (!TryComp<MechEquipmentComponent>(uid, out var mechEquipment) || !mechEquipment.EquipmentOwner.HasValue)
return;

if (!TryComp<MechComponent>(mechEquipment.EquipmentOwner.Value, out var mech))
return;

var maxCharge = component.MaxCharge;
var currentCharge = component.CurrentCharge;

var chargeDelta = maxCharge - currentCharge;

// TODO: The battery charge of the mech would be spent directly when fired.
if (chargeDelta <= 0 || mech.Energy - chargeDelta < 0)
return;

if (!_mech.TryChangeEnergy(mechEquipment.EquipmentOwner.Value, -chargeDelta, mech))
return;

_battery.SetCharge(uid, component.MaxCharge, component);
}
}

[ByRefEvent]
public record struct CheckMechWeaponBatteryEvent(BatteryComponent Battery, bool Cancelled = false);
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Content.Shared.Atmos;

namespace Content.Server._Goobstation.Temperature;

/// <summary>
/// Kills an entity when its temperature goes over a threshold.
/// </summary>
[RegisterComponent, Access(typeof(KillOnOverheatSystem))]
public sealed partial class KillOnOverheatComponent : Component
{
[DataField]
public float OverheatThreshold = Atmospherics.T0C + 110f;

[DataField]
public LocId OverheatPopup = "ipc-overheat-popup";
}
33 changes: 33 additions & 0 deletions Content.Server/_Goobstation/Temperature/KillOnOverheatSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Content.Server.Temperature.Components;
using Content.Shared.IdentityManagement;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Popups;
using Content.Shared.Damage.Components;

namespace Content.Server._Goobstation.Temperature;

public sealed class KillOnOverheatSystem : EntitySystem
{
[Dependency] private readonly MobStateSystem _mob = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityQueryEnumerator<KillOnOverheatComponent, TemperatureComponent, MobStateComponent>();
while (query.MoveNext(out var uid, out var comp, out var temp, out var mob))
{
if (mob.CurrentState == MobState.Dead
|| temp.CurrentTemperature < comp.OverheatThreshold
|| HasComp<GodmodeComponent>(uid))
continue;

var msg = Loc.GetString(comp.OverheatPopup, ("name", Identity.Name(uid, EntityManager)));
_popup.PopupEntity(msg, uid, PopupType.LargeCaution);
_mob.ChangeMobState(uid, MobState.Dead, mob);
}
}
}
7 changes: 7 additions & 0 deletions Content.Shared/Mech/Components/MechComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ namespace Content.Shared.Mech.Components;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class MechComponent : Component
{
/// <summary>
/// Goobstation: Whether or not an emag disables it.
/// </summary>
[DataField("breakOnEmag")]
[AutoNetworkedField]
public bool BreakOnEmag = true;

/// <summary>
/// How much "health" the mech has left.
/// </summary>
Expand Down
Loading
Loading