Compare commits

...

28 Commits

Author SHA1 Message Date
Redrover1760 da767f3e0f fix 2026-04-04 16:14:22 -04:00
Redrover1760 5eeaf3a4e3 testfail fix? 2026-04-04 16:13:41 -04:00
Redrover1760 c5f5cbc8ee code improvements 2026-04-04 15:03:20 -04:00
Redrover1760 50d4130f75 ree 2026-04-04 15:01:17 -04:00
Redrover1760 74cd863daf comments 2026-04-04 14:53:50 -04:00
Redrover1760 424dd518e0 adjusts things to work 2026-04-04 14:53:41 -04:00
Redrover1760 03d32fc523 hell 2026-04-04 03:20:34 -04:00
Redrover1760 d325a536b1 lessons learned 2026-04-04 02:48:45 -04:00
Redrover1760 44da153488 delete 2026-04-04 02:37:36 -04:00
Redrover1760 df87fc784a begone 2026-04-04 02:35:14 -04:00
Redrover1760 7a73c806de delete 2026-04-04 02:34:29 -04:00
Redrover1760 2bbfb35ecc mobbers 2026-04-04 02:33:55 -04:00
Redrover1760 ed4e303bf3 death 2026-04-04 02:32:57 -04:00
Redrover1760 c6cd221511 final implementation 2026-04-04 02:29:39 -04:00
Redrover1760 906f32b00b not sure where to go from here 2026-04-03 22:58:55 -04:00
Redrover1760 099b943c30 struggles 2026-04-03 22:47:16 -04:00
Redrover1760 1c961e5300 help 2026-04-02 23:31:31 -04:00
Redrover1760 e74ffc3178 renames 2026-04-02 18:09:07 -04:00
Redrover1760 c6c036a27f Merge branch 'main' of https://github.com/Monolith-Station/Monolith into size-density-adjustment 2026-04-02 18:07:05 -04:00
Redrover1760 7c5ab0b1cd eeee 2026-04-02 10:31:12 -04:00
Redrover1760 eb5e54d485 a 2026-04-01 18:13:51 -04:00
Redrover1760 59f1950bce a 2026-04-01 18:12:47 -04:00
Redrover1760 617eca8397 1 2026-04-01 18:12:01 -04:00
Redrover1760 aa354fd8d7 hell 2026-03-31 19:22:46 -04:00
Redrover1760 274b9d0a68 real 2026-03-30 22:29:28 -04:00
Redrover1760 2c2edc8460 ree 2026-03-30 22:29:11 -04:00
Redrover1760 d98c2dd0a7 Merge branch 'main' of https://github.com/Monolith-Station/Monolith into size-density-adjustment 2026-03-30 22:02:40 -04:00
Redrover1760 a65d7b6a5d ree 2026-03-30 22:02:25 -04:00
11 changed files with 238 additions and 125 deletions
@@ -0,0 +1,25 @@
using Content.Shared._Mono.Humanoid;
using Content.Shared._Mono.Traits.Physical;
namespace Content.Server._Mono.Traits.Physical;
/// <summary>
/// Applies the Will To Live trait effects by modifying the death health threshold.
/// </summary>
public sealed class MobThresholdOffsetSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MobThresholdOffsetComponent, QueryMobThresholdsEvent>(OnQueryMobThresholds);
}
private void OnQueryMobThresholds(Entity<MobThresholdOffsetComponent> ent, ref QueryMobThresholdsEvent ev)
{
ev.DeathOffset += ent.Comp.DeadOffset;
ev.CritOffset += ent.Comp.CritOffset;
}
}
@@ -1,44 +0,0 @@
using Content.Shared._Mono.Traits.Physical;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
namespace Content.Server._Mono.Traits.Physical;
/// <summary>
/// Applies the Will To Die trait effects by decreasing the death health threshold.
/// </summary>
public sealed class WillToDieSystem : EntitySystem
{
[Dependency] private readonly MobThresholdSystem _mobThresholds = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WillToDieComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<WillToDieComponent, ComponentShutdown>(OnShutdown);
}
private void OnStartup(Entity<WillToDieComponent> ent, ref ComponentStartup args)
{
AdjustDeathThreshold(ent.Owner, -ent.Comp.DeadDecrease);
}
private void OnShutdown(Entity<WillToDieComponent> ent, ref ComponentShutdown args)
{
AdjustDeathThreshold(ent.Owner, ent.Comp.DeadDecrease);
}
private void AdjustDeathThreshold(EntityUid uid, int deltaPoints, MobThresholdsComponent? thresholdsComp = null)
{
if (!_mobThresholds.TryGetThresholdForState(uid, MobState.Dead, out var current, thresholdsComp))
return;
var newValue = FixedPoint2.Max(0, current.Value + deltaPoints);
_mobThresholds.SetMobStateThreshold(uid, newValue, MobState.Dead, thresholdsComp);
}
}
@@ -1,45 +0,0 @@
using Content.Shared._Mono.Traits.Physical;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
namespace Content.Server._Mono.Traits.Physical;
/// <summary>
/// Applies the Will To Live trait effects by increasing the death health threshold.
/// </summary>
public sealed class WillToLiveSystem : EntitySystem
{
[Dependency] private readonly MobThresholdSystem _mobThresholds = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WillToLiveComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<WillToLiveComponent, ComponentShutdown>(OnShutdown);
}
private void OnStartup(Entity<WillToLiveComponent> ent, ref ComponentStartup args)
{
AdjustDeathThreshold(ent.Owner, ent.Comp.DeadIncrease);
}
private void OnShutdown(Entity<WillToLiveComponent> ent, ref ComponentShutdown args)
{
AdjustDeathThreshold(ent.Owner, -ent.Comp.DeadIncrease);
}
private void AdjustDeathThreshold(EntityUid uid, int deltaPoints, MobThresholdsComponent? thresholdsComp = null)
{
if (!_mobThresholds.TryGetThresholdForState(uid, MobState.Dead, out var current, thresholdsComp))
return;
var newValue = FixedPoint2.Max(0, current.Value + deltaPoints);
_mobThresholds.SetMobStateThreshold(uid, newValue, MobState.Dead, thresholdsComp);
}
}
@@ -77,6 +77,10 @@ public sealed partial class HumanoidAppearanceComponent : Component
[DataField, AutoNetworkedField]
public float Width = 1.0f;
[DataField, AutoNetworkedField] // Mono - Prescaled radial fixture sizes.
public Dictionary<string, float> DefaultFixtures = [];
/// <summary>
/// Hair color of this humanoid. Used to avoid looping through all markings
/// </summary>
@@ -1,6 +1,7 @@
using System.IO;
using System.Linq;
using System.Numerics;
using Content.Shared._Mono.Humanoid; // Mono Fixture Adjustment
using Content.Shared.Examine;
using Content.Shared.Humanoid.Markings;
using Content.Shared._Shitmed.Humanoid.Events; // Shitmed Change
@@ -38,6 +39,7 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
[Dependency] private readonly ISerializationManager _serManager = default!;
[Dependency] private readonly MarkingManager _markingManager = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly HumanoidPhysicsScalingSystem _scaling = default!;
[ValidatePrototypeId<SpeciesPrototype>]
public const string DefaultSpecies = "Human";
@@ -444,6 +446,9 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
_appearance.SetData(uid, ScaleVisuals.Scale, new Vector2(profile.Appearance.Width, profile.Appearance.Height), appearance);
}
// Update physics hitbox to match the new height and width - Mono
_scaling.UpdatePhysicsHitbox(uid, humanoid);
RaiseLocalEvent(uid, new ProfileLoadFinishedEvent()); // Shitmed Change
Dirty(uid, humanoid);
}
@@ -1,10 +1,12 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared._Mono.Humanoid;
using Content.Shared.Alert;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Events;
using Content.Shared.Sprite;
using Robust.Shared.GameStates;
namespace Content.Shared.Mobs.Systems;
@@ -335,9 +337,27 @@ public sealed class MobThresholdSystem : EntitySystem
private void CheckThresholds(EntityUid target, MobStateComponent mobStateComponent,
MobThresholdsComponent thresholdsComponent, DamageableComponent damageableComponent, EntityUid? origin = null)
{
var ev = new QueryMobThresholdsEvent();
RaiseLocalEvent(target, ref ev);
Log.Debug($"ThresholdEvent for {ToPrettyString(target)}: Scale={ev.Scale:F2}, Crit={ev.CritOffset:F2}, Death={ev.DeathOffset:F2}");
foreach (var (threshold, mobState) in thresholdsComponent.Thresholds.Reverse())
{
if (damageableComponent.TotalDamage < threshold)
// Mono Begin
float scale = 1;
if (ev.Scale != 0) // To scale from being zeroed out from no response i.e. comp not initialized yet.
scale = ev.Scale;
float offset = 0;
if (mobState == MobState.Dead)
offset += ev.DeathOffset;
if (mobState == MobState.Critical)
offset += ev.CritOffset;
// Mono End
if (damageableComponent.TotalDamage < (threshold + (FixedPoint2)offset) * scale) // Mono - Add threshold scale and offset.
continue;
TriggerThreshold(target, mobState, mobStateComponent, thresholdsComponent, origin);
@@ -474,9 +494,11 @@ public sealed class MobThresholdSystem : EntitySystem
UpdateAllEffects((ent, ent, null, null), args.NewMobState);
}
#endregion
}
/// <summary>
/// Event that triggers when an entity with a mob threshold is checked
/// </summary>
@@ -0,0 +1,151 @@
using System.Linq;
using Content.Shared._Mono.Traits.Physical;
using Content.Shared._Shitmed.Humanoid.Events;
using Content.Shared.FixedPoint;
using Content.Shared.Ghost;
using Content.Shared.Humanoid;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Sprite;
using Robust.Shared.Network;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Systems;
namespace Content.Shared._Mono.Humanoid;
/// <summary>
/// System that adjusts physics hitboxes of humanoid entities based on their height and weight (width).
/// </summary>
public sealed class HumanoidPhysicsScalingSystem : EntitySystem
{
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
public override void Initialize()
{
base.Initialize();
// Listen for when a humanoid appearance is loaded (character creation/spawning)
SubscribeLocalEvent<HumanoidAppearanceComponent, ComponentStartup>(OnComponentStartup);
// Listen for when humanoid appearance changes (admin commands, mutations, etc.)
SubscribeLocalEvent<HumanoidAppearanceComponent, ComponentRemove>(OnHumanoidShutdown);
SubscribeLocalEvent<HumanoidAppearanceComponent, QueryMobThresholdsEvent>(OnQueryMobThresholds);
}
private void OnComponentStartup(EntityUid uid, HumanoidAppearanceComponent component, ComponentStartup args)
{
AssignDefaultHitboxes(uid, component);
UpdatePhysicsHitbox(uid, component);
}
private void OnHumanoidShutdown(EntityUid uid, HumanoidAppearanceComponent component, ComponentRemove args)
{
// Reset hitbox to default when component is removed
if (TryComp<FixturesComponent>(uid, out var fixtures))
{
ResetToDefaultHitbox(uid, component, fixtures);
}
}
/// <summary>
/// Public method to manually update a humanoid's hitbox
/// </summary>
/// <param name="uid">The entity to update</param>
public void UpdateHitbox(EntityUid uid)
{
if (TryComp<HumanoidAppearanceComponent>(uid, out var humanoid))
{
UpdatePhysicsHitbox(uid, humanoid);
}
}
/// <summary>
/// Public method to set specific height and width then update hitbox.
/// </summary>
/// <param name="uid">The entity to update</param>
/// <param name="height">Height multiplier (1.0 = default)</param>
/// <param name="width">Width multiplier (1.0 = default)</param>
public void UpdateHitbox(EntityUid uid, float height, float width)
{
if (TryComp<HumanoidAppearanceComponent>(uid, out var humanoid))
{
humanoid.Height = height;
humanoid.Width = width;
UpdatePhysicsHitbox(uid, humanoid);
}
}
public void AssignDefaultHitboxes(EntityUid uid, HumanoidAppearanceComponent humanoid)
{
if (!TryComp<FixturesComponent>(uid, out var fixtures))
return;
foreach (var (fixtureId, fixture) in fixtures.Fixtures)
{
if (fixture.Shape is PhysShapeCircle)
{
var oldRadius = fixture.Shape.Radius;
humanoid.DefaultFixtures[fixtureId] = oldRadius;
}
}
}
/// <summary>
/// Updates the physics hitbox based on the humanoid's height and width.
/// </summary>
/// <param name="uid">The entity to update</param>
/// <param name="humanoid">The humanoid appearance component</param>
public void UpdatePhysicsHitbox(EntityUid uid, HumanoidAppearanceComponent humanoid)
{
if (!TryComp<FixturesComponent>(uid, out var fixtures))
return;
// Calculate the new radius based on height and width
// We take the average of height and width for a circular hitbox
var scale = CalculateScale(humanoid);
// Update all circular fixtures (most humanoids should have just one main fixture)
foreach (var (fixtureId, fixture) in fixtures.Fixtures)
{
if (fixture.Shape is PhysShapeCircle circle && humanoid.DefaultFixtures.TryGetValue(fixtureId, out var oldRadius))
{
var newRadius = oldRadius * scale;
_physics.SetRadius(uid, fixtureId, fixture, circle, newRadius, fixtures);
// Log the change for debugging
Log.Debug($"Updated physics hitbox for {ToPrettyString(uid)}: Fixture={fixtureId:F2} Height={humanoid.Height:F2}, Width={humanoid.Width:F2}, Radius={newRadius:F2}");
}
}
}
private void OnQueryMobThresholds(Entity<HumanoidAppearanceComponent> ent, ref QueryMobThresholdsEvent args)
{
args.Scale = CalculateScale(ent.Comp);
Log.Debug($"Updated damage scale for {ToPrettyString(ent)}: Scale={args.Scale:F2} Height={ent.Comp.Height:F2}, Width={ent.Comp.Width:F2}");
}
public float CalculateScale(HumanoidAppearanceComponent humanoid)
{
return MathF.Sqrt(MathF.Pow(humanoid.Height, 2) + MathF.Pow(humanoid.Width, 2)) / MathF.Sqrt(2.0f);
}
/// <summary>
/// Resets a humanoid's hitbox to the default size.
/// </summary>
/// <param name="uid">The entity to reset</param>
/// <param name="fixtures">The fixtures component</param>
private void ResetToDefaultHitbox(EntityUid uid, HumanoidAppearanceComponent humanoid, FixturesComponent fixtures)
{
foreach (var (fixtureId, fixture) in fixtures.Fixtures)
{
if (fixture.Shape is PhysShapeCircle circle && humanoid.DefaultFixtures.TryGetValue(fixtureId, out var oldRadius))
{
_physics.SetRadius(uid, fixtureId, fixture, circle, oldRadius, fixtures);
}
}
}
}
[ByRefEvent]
public record struct QueryMobThresholdsEvent(float Scale = 1.0f, float DeathOffset = 0, float CritOffset = 0);
@@ -0,0 +1,20 @@
namespace Content.Shared._Mono.Traits.Physical;
/// <summary>
/// Offsets the threshold required to reach mob thresholds.
/// </summary>
[RegisterComponent]
public sealed partial class MobThresholdOffsetComponent : Component
{
/// <summary>
/// How much to increase the Dead damage threshold by.
/// </summary>
[DataField]
public int DeadOffset = 0;
/// <summary>
/// How much to increase the Crit damage threshold by.
/// </summary>
[DataField]
public int CritOffset = 0;
}
@@ -1,16 +0,0 @@
namespace Content.Shared._Mono.Traits.Physical;
/// <summary>
/// Decreases the damage threshold required to enter the Dead state.
/// </summary>
[RegisterComponent]
public sealed partial class WillToDieComponent : Component
{
/// <summary>
/// How much to decrease the Dead damage threshold by.
/// </summary>
[DataField]
public int DeadDecrease = 15;
}
@@ -1,14 +0,0 @@
namespace Content.Shared._Mono.Traits.Physical;
/// <summary>
/// Increases the damage threshold required to enter the Dead state.
/// </summary>
[RegisterComponent]
public sealed partial class WillToLiveComponent : Component
{
/// <summary>
/// How much to increase the Dead damage threshold by.
/// </summary>
[DataField]
public int DeadIncrease = 10;
}
+10 -5
View File
@@ -80,7 +80,8 @@
components:
- BorgChassis
components:
- type: WillToLive
- type: MobThresholdOffset
deadOffset: 15
- type: trait
id: WillToDie
@@ -90,13 +91,16 @@
cost: -1
mutuallyExclusiveTraits:
- WillToLive
- Redshirt
speciesBlacklist:
- IPC
blacklist:
components:
- BorgChassis
components:
- type: WillToDie
- type: MobThresholdOffset
deadOffset: -15
- type: trait
id: Thieving
@@ -250,14 +254,15 @@
cost: -8
mutuallyExclusiveTraits:
- WillToLive
- WillToDie
speciesBlacklist:
- IPC
blacklist:
components:
- BorgChassis
components:
- type: WillToDie
deadDecrease: 100
- type: MobThresholdOffset
deadOffset: -100
- type: trait
id: StrikingCalluses
@@ -308,7 +313,7 @@
Blunt: 3.5
Slash: 3.5
Piercing: 3.5
- type: trait
id: HardenedLymphocytes
name: trait-hardened-lymphocytes-name