Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f544d53
ebal
Armorkillerd Jan 30, 2026
2f1b756
Merge branch 'master' into 105
Armorkillerd Jan 30, 2026
6115d30
1
Armorkillerd Jan 30, 2026
d2e1432
2
Armorkillerd Jan 30, 2026
ed69127
3
Armorkillerd Jan 30, 2026
d62c55c
4
Armorkillerd Jan 30, 2026
a736875
sda
Armorkillerd Jan 30, 2026
5a2252c
6
Armorkillerd Jan 30, 2026
4023495
sfa
Armorkillerd Jan 30, 2026
aa3d33e
7
Armorkillerd Jan 31, 2026
9ccdcb4
8
Armorkillerd Jan 31, 2026
a1260e0
9
Armorkillerd Jan 31, 2026
b5f3836
11
Armorkillerd Jan 31, 2026
07a91cd
12
Armorkillerd Jan 31, 2026
9db9a86
13
Armorkillerd Jan 31, 2026
5f8f989
14
Armorkillerd Jan 31, 2026
3bcfd35
15
Armorkillerd Jan 31, 2026
fb286a3
desd
Armorkillerd Jan 31, 2026
ba2ab40
16
Armorkillerd Jan 31, 2026
1831fb6
sa
Armorkillerd Jan 31, 2026
ce6bd66
Merge branch 'master' into 105
Armorkillerd Feb 1, 2026
b4a4021
fdu
Armorkillerd Feb 1, 2026
5da928f
17
Armorkillerd Feb 1, 2026
57435d3
sad
Armorkillerd Feb 1, 2026
54ba0ad
18
Armorkillerd Feb 1, 2026
29cb687
19
Armorkillerd Feb 1, 2026
e41abe5
20
Armorkillerd Feb 1, 2026
5389f79
Sad
Armorkillerd Feb 1, 2026
1f2d4a2
20
Armorkillerd Feb 1, 2026
7d38acc
as
Armorkillerd Feb 1, 2026
2dbd00a
sad
Armorkillerd Feb 1, 2026
bfdf2c7
damn
Armorkillerd Feb 8, 2026
80c76eb
lol
Armorkillerd Feb 8, 2026
eee0717
77
Armorkillerd Feb 9, 2026
c7abbf9
ded
Armorkillerd Feb 9, 2026
698cf30
Merge branch 'master' into 105
Armorkillerd Feb 10, 2026
23fcf18
Merge branch 'master' into 105
Armorkillerd Feb 22, 2026
5b02223
11
Armorkillerd Feb 23, 2026
feca82f
Merge branch 'master' into 105
Armorkillerd Feb 23, 2026
4342099
12
Armorkillerd Feb 23, 2026
1b48f3f
21
Armorkillerd Feb 23, 2026
8f843d1
1
Armorkillerd Feb 23, 2026
4339fa2
13
Armorkillerd Feb 23, 2026
0f25e15
Merge branch 'master' into 105
Armorkillerd Mar 16, 2026
491a78e
Merge branch 'master' into 105
Armorkillerd Mar 19, 2026
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
  •  
  •  
  •  
24 changes: 24 additions & 0 deletions Content.Client/ADT/Weapon/WeaponDismantleOnShootSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Content.Shared.ADT.Weapon.Systems;
using System.Numerics;
using Content.Shared.ADT.Weapon.Components;
using Content.Shared.Inventory;
using Content.Shared.Popups;
using Content.Shared.Tag;
using Content.Shared.Throwing;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Physics.Systems;

//linq
using System.Linq;
using Content.Shared.Weapons.Ranged.Events;
using Robust.Shared.Random;
using Content.Shared.Damage;
using Content.Shared.Wieldable;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Player;
using Robust.Shared.Audio;

namespace Content.Client.ADT.Weapon.Systems;
public sealed partial class WeaponDismantleOnShootSystem : SharedWeaponDismantleOnShootSystem
{
}
103 changes: 103 additions & 0 deletions Content.Server/ADT/Weapon/WeaponDismantleOnShootSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using Content.Shared.ADT.Weapon.Systems;
using System.Numerics;
using Content.Shared.ADT.Weapon.Components;
using Content.Shared.Inventory;
using Content.Shared.Popups;
using Content.Shared.Tag;
using Content.Shared.Throwing;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Physics.Systems;

//linq
using System.Linq;
using Content.Shared.Weapons.Ranged.Events;
using Robust.Shared.Random;
using Content.Shared.Damage;
using Content.Shared.Wieldable;
using Content.Shared.Weapons.Ranged.Components;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;

namespace Content.Server.ADT.Weapon.Systems;
public sealed partial class WeaponDismantleOnShootSystem : SharedWeaponDismantleOnShootSystem
{
[Dependency] private readonly TagSystem _tagSystem = default!;
[Dependency] private readonly SharedGunSystem _gunSystem = default!;
[Dependency] private readonly ILogManager _log = default!;
[Dependency] protected readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly ThrowingSystem _throwing = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] protected readonly DamageableSystem Damageable = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WeaponDismantleOnShootComponent, AmmoShotEvent>(OnGunShot);
}

private void OnGunShot(Entity<WeaponDismantleOnShootComponent> ent, ref AmmoShotEvent args)
{
if (DismantleCheck(ent, ref args) == false)
return;

//apply the damage to the shooter
//get the shooters damageable component
Damageable.TryChangeDamage(args.Shooter, ent.Comp.SelfDamage, origin:args.Shooter);

//we need the user past this point
if (!args.Shooter.HasValue)
return;

_audio.PlayPvs(ent.Comp.DismantleSound, args.Shooter.Value);

//get the users transform
var userPosition = Transform(args.Shooter.Value).Coordinates;

if (!TryComp<GunComponent>(ent, out var gunComponent))
return;

var toCoordinates = gunComponent.ShootCoordinates;

if (toCoordinates == null)
return;

//loop through all of the items
var random = IoCManager.Resolve<IRobustRandom>();
foreach (var item in ent.Comp.items)
{
for (var i = 0; i < item.Amount; i++)
{
//roll to see if we destroy the item or not
if (!random.Prob(item.SpawnProbability))
continue;

//get the item entity
var itemEntity = Spawn(item.PrototypeId, userPosition);

Vector2 direction = toCoordinates.Value.Position;
//normalize it
direction = Vector2.Normalize(direction);
//multiply it by the distance
direction *= ent.Comp.DismantleDistance;
//rotate it by the angle
direction = item.LaunchAngle.RotateVec(direction);

//roll for random angle modifier
double randomAngle = random.NextDouble(-item.AngleRandomness.Degrees, item.AngleRandomness.Degrees);
//rotate it by the random angle
direction = Angle.FromDegrees(randomAngle).RotateVec(direction);

var throwDirection = new EntityCoordinates(args.Shooter.Value, direction);

_throwing.TryThrow(itemEntity, throwDirection, ent.Comp.DismantleDistance, compensateFriction: true);
}
}

//now we need to destroy the gun
//get the gun entity
_entityManager.QueueDeleteEntity(ent.Owner);
}
}
1 change: 1 addition & 0 deletions Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid?
RaiseLocalEvent(gunUid, new AmmoShotEvent()
{
FiredProjectiles = shotProjectiles,
Shooter = user, // ADT-Tweak
});

void CreateAndFireProjectiles(EntityUid ammoEnt, AmmoComponent ammoComp)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Content.Shared.Damage;
using Content.Shared.Storage;
using Content.Shared.Tag;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;

namespace Content.Shared.ADT.Weapon.Components;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class WeaponDismantleOnShootComponent : Component
{
[DataField, AutoNetworkedField]
public float DismantleChance = 0.0f;

/// <summary>
/// How far to throw things when dismantling.
/// </summary>
[DataField, AutoNetworkedField]
public float DismantleDistance = 5f;

[DataField]
public SoundCollectionSpecifier? DismantleSound = new SoundCollectionSpecifier("MetalBreak");

[DataField, AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public DamageSpecifier SelfDamage = new();

[DataField, AutoNetworkedField]
public List<DismantleOnShootItem> items = [];
}

[DataDefinition]
[Serializable, NetSerializable]
public sealed partial class DismantleOnShootItem
{
public DismantleOnShootItem() { }
[DataField("id")]
public EntProtoId? PrototypeId = null;

/// <summary>
/// The probability that an item will spawn. Takes decimal form so 0.05 is 5%, 0.50 is 50% etc.
/// </summary>
[DataField("prob")]
public float SpawnProbability = 1;

[DataField]
public int Amount = 1;

[ViewVariables(VVAccess.ReadWrite), DataField]
public Angle LaunchAngle = Angle.FromDegrees(0);

[ViewVariables(VVAccess.ReadWrite), DataField]
public Angle AngleRandomness = Angle.FromDegrees(5);
}
38 changes: 38 additions & 0 deletions Content.Shared/ADT/Weapons/SharedWeaponDismantleOnShootSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Content.Shared.ADT.Weapon.Components;
using Content.Shared.Examine;
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Random;

namespace Content.Shared.ADT.Weapon.Systems;

public abstract partial class SharedWeaponDismantleOnShootSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WeaponDismantleOnShootComponent, ExaminedEvent>(OnExamine);
}

public bool DismantleCheck(Entity<WeaponDismantleOnShootComponent> ent, ref AmmoShotEvent args)
{
//roll to see if we explode or not
var random = IoCManager.Resolve<IRobustRandom>();
//1.0f means always true, 0.0f means always false
if (!random.Prob(ent.Comp.DismantleChance))
return false;

return true;
}

private void OnExamine(Entity<WeaponDismantleOnShootComponent> ent, ref ExaminedEvent args)
{
if (!args.IsInDetailsRange)
return;

if (ent.Comp.DismantleChance <= 0.0f)
return;

args.PushMarkup(Loc.GetString("examine-weapon-dismantle-on-shoot", ("chance", String.Format("{0:0.#}", ent.Comp.DismantleChance * 100))));
}
}
1 change: 1 addition & 0 deletions Content.Shared/Weapons/Ranged/Events/AmmoShotEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ namespace Content.Shared.Weapons.Ranged.Events;
public sealed class AmmoShotEvent : EntityEventArgs
{
public List<EntityUid> FiredProjectiles = default!;
public EntityUid? Shooter = default!; // ADT-Tweak
}
Loading
Loading