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

Frags #103

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
namespace Content.Server.SimpleStation14.Grenades;

[RegisterComponent]

/// <summary>
/// Spawns entities when triggered.
/// This is used for grenades and other things that spawn entities on trigger.
/// </summary>
public sealed class SpawnEntitiesOnTriggerComponent : Component
{
/// <summary>
/// The prototype of the entity to spawn.
/// </summary>
[DataField("prototype")]
public string? Prototype = null;

/// <summary>
/// The amount of entities to spawn.
/// </summary>
[DataField("count")]
public int Count = 1;

/// <summary>
/// The minimum amount of entities to spawn.
/// If this is null, will always spawn full amount.
/// </summary>
[DataField("minCount")]
public int? MinCount = null;

/// <summary>
/// The velocity to either shoot or throw the spawned entities with.
/// If this is null, entities won't be thrown or shot.
/// </summary>
[DataField("velocity")]
public float? Velocity = null;

/// <summary>
/// The time in seconds before the spawned entities despawn.
/// If this is null, entities won't despawn.
/// </summary>
[DataField("despawnTime")]
public float? DespawnTime = null;

/// <summary>
/// Whether or to shoot the spawned entities.
/// If this is false, entities with velocity will be thrown.
/// </summary>
[DataField("shoot")]
public bool Shoot = false;

/// <summary>
/// The offset multiplier for the spawned entities in max tiles.
/// If this is 0, entities will spawn on top of the trigger.
/// </summary>
[DataField("offset")]
public float Offset = 0f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using Content.Shared.Spawners.Components;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Content.Server.Explosion.EntitySystems;
using Robust.Shared.Random;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Content.Server.Weapons.Ranged.Systems;
using Content.Shared.Throwing;
using Robust.Server.GameObjects;

namespace Content.Server.SimpleStation14.Grenades;

public class SpawnEntitiesOnTriggerSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypes = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly GunSystem _guns = default!;
[Dependency] private readonly ThrowingSystem _throw = default!;
[Dependency] private readonly TransformSystem _transform = default!;

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

SubscribeLocalEvent<SpawnEntitiesOnTriggerComponent, TriggerEvent>(OnTrigger);
}

/// <summary>
/// On trigger, works out if the entity has a variable count, decides how many to spawn,
/// then iterates through and spawns each one apply any offset, and any velocity, be it thrown or shot,
/// spinning them in a random direction. Finally, sets the entity to be deleted if a despawn time is set.
/// </summary>
private void OnTrigger(EntityUid uid, SpawnEntitiesOnTriggerComponent component, TriggerEvent args)
{
if (component.Prototype == null) return;

var prototype = _prototypes.Index<EntityPrototype>(component.Prototype);

var spawnCount = component.Count;

if (component.MinCount != null)
{
spawnCount = _random.Next(component.MinCount.Value, component.Count);
}

for (var i = 0; i < spawnCount; i++)
{
var spawnedEntity = EntityManager.SpawnEntity(prototype.ID, EntityManager.GetComponent<TransformComponent>(uid).Coordinates
+ new EntityCoordinates(EntityManager.GetComponent<TransformComponent>(uid).ParentUid, _random.NextVector2(-1, 1) * component.Offset));

var transfComp = EntityManager.GetComponent<TransformComponent>(spawnedEntity);
_transform.AttachToGridOrMap(spawnedEntity);

if (component.Velocity != null)
{
transfComp.LocalRotation = Angle.FromDegrees(_random.Next(0, 360));

if (component.Shoot)
{
_guns.ShootProjectile(spawnedEntity, transfComp.LocalRotation.ToWorldVec(), Vector2.Zero, speed: component.Velocity.Value * _random.NextFloat(0.8f, 1.2f));
}
else
{
_throw.TryThrow(spawnedEntity, transfComp.LocalRotation.ToWorldVec(), 1.0f, null, 5.0f);
}
}

if (component.DespawnTime != null)
{
var despawnComp = EntityManager.EnsureComponent<TimedDespawnComponent>(spawnedEntity);
despawnComp.Lifetime = component.DespawnTime.Value;
}
}
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- type: listing
id: UplinkExplosiveBeenade
name: Beenade
description: "A grenade... Full of bees. Now THIS is truly evil."
productEntity: GrenadeBees
cost:
Telecrystal: 3
categories:
- UplinkExplosives
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
- type: entity
id: BulletGrenadeShrapnel
parent: BaseBullet
name: shrapnel
noSpawn: true
components:
- type: Sprite
sprite: SimpleStation14/Objects/Weapons/Guns/Projectiles/projectiles.rsi
layers:
- state: shrapnel
shader: unshaded
- type: Projectile
damage:
types:
Piercing: 30
- type: Fixtures
fixtures:
- shape:
!type:PhysShapeAabb
bounds: "-0.3,-0.25,0.3,0.25"
hard: false
id: projectile
mask:
- Impassable
- BulletImpassable
# - *flybyfixture

- type: entity
id: BulletGrenadeShrapnelRubber
parent: BaseBulletRubber
name: rubber ball
noSpawn: true
components:
- type: Projectile
damage:
types:
Blunt: 1.5
soundHit:
path: /Audio/Weapons/Guns/Hits/snap.ogg
- type: StaminaDamageOnCollide
damage: 15
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
- type: entity
name: fragmentation grenade
description: A grenade that explodes into a cloud of shrapnel.
parent: GrenadeBase
id: GrenadeFragThrown
components:
- type: Sprite
sprite: SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi
- type: SpawnEntitiesOnTrigger
prototype: BulletGrenadeShrapnel
count: 50
minCount: 30
velocity: 20
despawnTime: 0.4
shoot: true
- type: EmitSoundOnTrigger
sound:
path: /Audio/Effects/metalbreak.ogg
# - type: ExplodeOnTrigger
# - type: Explosive
# explosionType: Default
# totalIntensity: 40
# intensitySlope: 45
# maxIntensity: 20
# canCreateVacuum: false
- type: DeleteOnTrigger
- type: Appearance
visuals:
- type: TimerTriggerVisualizer
countdown_sound:
path: /Audio/Items/pop.ogg
- type: OnUseTimerTrigger
delay: 5

- type: entity
name: rubber ball grenade
description:
parent: GrenadeBase
id: GrenadeRubberBall
components:
- type: Sprite
sprite: Objects/Weapons/Grenades/grenade.rsi
- type: SpawnEntitiesOnTrigger
prototype: BulletGrenadeShrapnelRubber
count: 85
minCount: 70
velocity: 15
despawnTime: 1.5
shoot: true
- type: EmitSoundOnTrigger
sound:
path: /Audio/Effects/metalbreak.ogg
- type: DeleteOnTrigger
# - type: Appearance
# visuals:
# - type: TimerTriggerVisualizer
# countdown_sound:
# path: /Audio/Effects/countdown.ogg
- type: OnUseTimerTrigger
delay: 1.5

- type: entity
name: beenade
description: A grenade that explodes into a cloud of bees... Nightmarish.
parent: GrenadeBase
id: GrenadeBees
components:
- type: Sprite
sprite: SimpleStation14/Objects/Weapons/Grenades/beenade.rsi
- type: SpawnEntitiesOnTrigger
prototype: MobAngryBee
count: 14
minCount: 8
despawnTime: 10
offset: 1
- type: DeleteOnTrigger
- type: Appearance
visuals:
- type: TimerTriggerVisualizer
countdown_sound:
path: /Audio/SimpleStation14/Effects/Weapons/Grenades/beenade.ogg
- type: OnUseTimerTrigger
delay: 3
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Made by Pspritechologist",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "primed",
"delays": [[ 0.2, 0.2, 0.2, 0.2 ]]
},
{
"name": "equipped-BELT",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Made by Pspritechologist",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "primed"
},
{
"name": "equipped-BELT",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
0.11
]
]
},
{
"name": "shrapnel"
}
]
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.