diff --git a/Content.Server/SimpleStation14/SpawnEntitiesOnTrigger/SpawnEntitiesOnTriggerComponent.cs b/Content.Server/SimpleStation14/SpawnEntitiesOnTrigger/SpawnEntitiesOnTriggerComponent.cs new file mode 100644 index 0000000000..8d5d24f45a --- /dev/null +++ b/Content.Server/SimpleStation14/SpawnEntitiesOnTrigger/SpawnEntitiesOnTriggerComponent.cs @@ -0,0 +1,57 @@ +namespace Content.Server.SimpleStation14.Grenades; + +[RegisterComponent] + +/// +/// Spawns entities when triggered. +/// This is used for grenades and other things that spawn entities on trigger. +/// +public sealed class SpawnEntitiesOnTriggerComponent : Component +{ + /// + /// The prototype of the entity to spawn. + /// + [DataField("prototype")] + public string? Prototype = null; + + /// + /// The amount of entities to spawn. + /// + [DataField("count")] + public int Count = 1; + + /// + /// The minimum amount of entities to spawn. + /// If this is null, will always spawn full amount. + /// + [DataField("minCount")] + public int? MinCount = null; + + /// + /// The velocity to either shoot or throw the spawned entities with. + /// If this is null, entities won't be thrown or shot. + /// + [DataField("velocity")] + public float? Velocity = null; + + /// + /// The time in seconds before the spawned entities despawn. + /// If this is null, entities won't despawn. + /// + [DataField("despawnTime")] + public float? DespawnTime = null; + + /// + /// Whether or to shoot the spawned entities. + /// If this is false, entities with velocity will be thrown. + /// + [DataField("shoot")] + public bool Shoot = false; + + /// + /// The offset multiplier for the spawned entities in max tiles. + /// If this is 0, entities will spawn on top of the trigger. + /// + [DataField("offset")] + public float Offset = 0f; +} diff --git a/Content.Server/SimpleStation14/SpawnEntitiesOnTrigger/SpawnEntitiesOnTriggerSystem.cs b/Content.Server/SimpleStation14/SpawnEntitiesOnTrigger/SpawnEntitiesOnTriggerSystem.cs new file mode 100644 index 0000000000..d27b7e0d7d --- /dev/null +++ b/Content.Server/SimpleStation14/SpawnEntitiesOnTrigger/SpawnEntitiesOnTriggerSystem.cs @@ -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(OnTrigger); + } + + /// + /// 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. + /// + private void OnTrigger(EntityUid uid, SpawnEntitiesOnTriggerComponent component, TriggerEvent args) + { + if (component.Prototype == null) return; + + var prototype = _prototypes.Index(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(uid).Coordinates + + new EntityCoordinates(EntityManager.GetComponent(uid).ParentUid, _random.NextVector2(-1, 1) * component.Offset)); + + var transfComp = EntityManager.GetComponent(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(spawnedEntity); + despawnComp.Lifetime = component.DespawnTime.Value; + } + } + } +} diff --git a/Resources/Audio/SimpleStation14/Effects/Weapons/Grenades/beenade.ogg b/Resources/Audio/SimpleStation14/Effects/Weapons/Grenades/beenade.ogg new file mode 100644 index 0000000000..ca49db47d4 Binary files /dev/null and b/Resources/Audio/SimpleStation14/Effects/Weapons/Grenades/beenade.ogg differ diff --git a/Resources/Prototypes/SimpleStation14/Catalog/uplink_catalog_syndicate.yml b/Resources/Prototypes/SimpleStation14/Catalog/uplink_catalog_syndicate.yml new file mode 100644 index 0000000000..7361b01fa4 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Catalog/uplink_catalog_syndicate.yml @@ -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 diff --git a/Resources/Prototypes/SimpleStation14/Entities/Objects/Weapons/Guns/Projectiles/shrapnel.yml b/Resources/Prototypes/SimpleStation14/Entities/Objects/Weapons/Guns/Projectiles/shrapnel.yml new file mode 100644 index 0000000000..25f01acd7a --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Objects/Weapons/Guns/Projectiles/shrapnel.yml @@ -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 diff --git a/Resources/Prototypes/SimpleStation14/Entities/Objects/Weapons/Guns/Throwable/grenades.yml b/Resources/Prototypes/SimpleStation14/Entities/Objects/Weapons/Guns/Throwable/grenades.yml new file mode 100644 index 0000000000..98e553befa --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Objects/Weapons/Guns/Throwable/grenades.yml @@ -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 diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/equipped-BELT.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/equipped-BELT.png new file mode 100644 index 0000000000..c4f5d06a15 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/equipped-BELT.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/icon.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/icon.png new file mode 100644 index 0000000000..0e3e8facc7 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/icon.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/inhand-left.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/inhand-left.png new file mode 100644 index 0000000000..2036d38b74 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/inhand-left.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/inhand-right.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/inhand-right.png new file mode 100644 index 0000000000..999c50e9ea Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/inhand-right.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/meta.json b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/meta.json new file mode 100644 index 0000000000..1de1effa9f --- /dev/null +++ b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/meta.json @@ -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 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/primed.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/primed.png new file mode 100644 index 0000000000..44849da77e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/beenade.rsi/primed.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/equipped-BELT.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/equipped-BELT.png new file mode 100644 index 0000000000..a5da12489e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/equipped-BELT.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/icon.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/icon.png new file mode 100644 index 0000000000..c552d96eed Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/icon.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/inhand-left.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/inhand-left.png new file mode 100644 index 0000000000..4ab86f4513 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/inhand-left.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/inhand-right.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/inhand-right.png new file mode 100644 index 0000000000..9e77c9a106 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/inhand-right.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/meta.json b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/meta.json new file mode 100644 index 0000000000..29ad3a5726 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/meta.json @@ -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 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/primed.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/primed.png new file mode 100644 index 0000000000..d7fbd7d571 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Grenades/frag_grenade.rsi/primed.png differ diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Guns/Projectiles/projectiles.rsi/meta.json b/Resources/Textures/SimpleStation14/Objects/Weapons/Guns/Projectiles/projectiles.rsi/meta.json index 7f921b6e6b..fd4dc5e016 100644 --- a/Resources/Textures/SimpleStation14/Objects/Weapons/Guns/Projectiles/projectiles.rsi/meta.json +++ b/Resources/Textures/SimpleStation14/Objects/Weapons/Guns/Projectiles/projectiles.rsi/meta.json @@ -54,6 +54,9 @@ 0.11 ] ] + }, + { + "name": "shrapnel" } ] -} \ No newline at end of file +} diff --git a/Resources/Textures/SimpleStation14/Objects/Weapons/Guns/Projectiles/projectiles.rsi/shrapnel.png b/Resources/Textures/SimpleStation14/Objects/Weapons/Guns/Projectiles/projectiles.rsi/shrapnel.png new file mode 100644 index 0000000000..a3ae1339b1 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Objects/Weapons/Guns/Projectiles/projectiles.rsi/shrapnel.png differ