diff --git a/Content.Server/Spider/SpiderSystem.cs b/Content.Server/Spider/SpiderSystem.cs new file mode 100644 index 0000000000..449e43984c --- /dev/null +++ b/Content.Server/Spider/SpiderSystem.cs @@ -0,0 +1,77 @@ +using System.Linq; +using Content.Server.Popups; +using Content.Shared.Spider; +using Content.Shared.Maps; +using Robust.Server.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.Spider; + +public sealed class SpiderSystem : SharedSpiderSystem +{ + [Dependency] private readonly PopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnSpawnNet); + } + + private void OnSpawnNet(EntityUid uid, SpiderComponent component, SpiderWebActionEvent args) + { + if (args.Handled) + return; + + var transform = Transform(uid); + + if (transform.GridUid == null) + { + _popup.PopupEntity(Loc.GetString("spider-web-action-nogrid"), args.Performer, args.Performer); + return; + } + + var coords = transform.Coordinates; + + // TODO generic way to get certain coordinates + + var result = false; + // Spawn web in center + if (!IsTileBlockedByWeb(coords)) + { + Spawn(component.WebPrototype, coords); + result = true; + } + + // Spawn web in other directions + for (var i = 0; i < 4; i++) + { + var direction = (DirectionFlag) (1 << i); + coords = transform.Coordinates.Offset(direction.AsDir().ToVec()); + + if (!IsTileBlockedByWeb(coords)) + { + Spawn(component.WebPrototype, coords); + result = true; + } + } + + if (result) + { + _popup.PopupEntity(Loc.GetString("spider-web-action-success"), args.Performer, args.Performer); + args.Handled = true; + } + else + _popup.PopupEntity(Loc.GetString("spider-web-action-fail"), args.Performer, args.Performer); + } + + private bool IsTileBlockedByWeb(EntityCoordinates coords) + { + foreach (var entity in coords.GetEntitiesInTile()) + { + if (HasComp(entity)) + return true; + } + return false; + } +} + diff --git a/Content.Server/StationEvents/Events/SpiderSpawn.cs b/Content.Server/StationEvents/Events/SpiderSpawn.cs new file mode 100644 index 0000000000..cb58e438ee --- /dev/null +++ b/Content.Server/StationEvents/Events/SpiderSpawn.cs @@ -0,0 +1,32 @@ +using Content.Server.StationEvents.Components; +using Content.Shared.Actions; +using Robust.Shared.Random; +using System.Linq; + +namespace Content.Server.StationEvents.Events; + +public sealed class SpiderSpawn : StationEventSystem +{ + public override string Prototype => "SpiderSpawn"; + + public override void Started() + { + base.Started(); + var spawnLocations = EntityManager.EntityQuery().ToList(); + RobustRandom.Shuffle(spawnLocations); + + var mod = Math.Sqrt(GetSeverityModifier()); + + var spawnAmount = (int) (RobustRandom.Next(4, 8) * mod); + Sawmill.Info($"Spawning {spawnAmount} of spiders"); + foreach (var location in spawnLocations) + { + if (spawnAmount-- == 0) + break; + + var coords = EntityManager.GetComponent(location.Owner); + + EntityManager.SpawnEntity("MobGiantSpiderAngry", coords.Coordinates); + } + } +} diff --git a/Content.Server/StationEvents/Events/VentCritters.cs b/Content.Server/StationEvents/Events/VentCritters.cs index d1569b07f1..5d61e10c71 100644 --- a/Content.Server/StationEvents/Events/VentCritters.cs +++ b/Content.Server/StationEvents/Events/VentCritters.cs @@ -1,4 +1,5 @@ using Content.Server.StationEvents.Components; +using Content.Shared.Actions; using Robust.Shared.Random; using System.Linq; @@ -7,7 +8,7 @@ namespace Content.Server.StationEvents.Events; public sealed class VentCritters : StationEventSystem { public static List SpawnedPrototypeChoices = new List() - {"MobGiantSpiderAngry", "MobMouse", "MobMouse1", "MobMouse2"}; + {"MobMouse", "MobMouse1", "MobMouse2"}; public override string Prototype => "VentCritters"; @@ -18,9 +19,7 @@ public sealed class VentCritters : StationEventSystem var spawnLocations = EntityManager.EntityQuery().ToList(); RobustRandom.Shuffle(spawnLocations); - var mod = Math.Sqrt(GetSeverityModifier()); - - var spawnAmount = (int) (RobustRandom.Next(4, 12) * mod); // A small colony of critters. + var spawnAmount = (int) (RobustRandom.Next(4, 12)); // A small colony of critters. Sawmill.Info($"Spawning {spawnAmount} of {spawnChoice}"); foreach (var location in spawnLocations) { diff --git a/Content.Shared/Spider/IgnoreSpiderWebComponent.cs b/Content.Shared/Spider/IgnoreSpiderWebComponent.cs new file mode 100644 index 0000000000..8b412df690 --- /dev/null +++ b/Content.Shared/Spider/IgnoreSpiderWebComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Spider; + +[RegisterComponent] +public sealed class IgnoreSpiderWebComponent : Component +{ + +} diff --git a/Content.Shared/Spider/SharedSpiderSystem.cs b/Content.Shared/Spider/SharedSpiderSystem.cs new file mode 100644 index 0000000000..b64f980c34 --- /dev/null +++ b/Content.Shared/Spider/SharedSpiderSystem.cs @@ -0,0 +1,35 @@ +using System.Linq; +using Content.Shared.Spider; +using Content.Shared.Actions; +using Content.Shared.Actions.ActionTypes; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Shared.Spider; + +public abstract class SharedSpiderSystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _action = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly IRobustRandom _robustRandom = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnWebStartup); + SubscribeLocalEvent(OnSpiderStartup); + } + + private void OnSpiderStartup(EntityUid uid, SpiderComponent component, ComponentStartup args) + { + var netAction = new InstantAction(_proto.Index(component.WebActionName)); + _action.AddAction(uid, netAction, null); + } + + private void OnWebStartup(EntityUid uid, SpiderWebObjectComponent component, ComponentStartup args) + { + _appearance.SetData(uid, SpiderWebVisuals.Variant, _robustRandom.Next(1, 3)); + } +} diff --git a/Content.Shared/Spider/SpiderComponent.cs b/Content.Shared/Spider/SpiderComponent.cs new file mode 100644 index 0000000000..a5b5731711 --- /dev/null +++ b/Content.Shared/Spider/SpiderComponent.cs @@ -0,0 +1,22 @@ +using Content.Shared.Actions; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.Spider; + +[RegisterComponent, NetworkedComponent] +[Access(typeof(SharedSpiderSystem))] +public sealed class SpiderComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite)] + [DataField("webPrototype", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string WebPrototype = "SpiderWeb"; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("webActionName")] + public string WebActionName = "SpiderWebAction"; +} + +public sealed class SpiderWebActionEvent : InstantActionEvent { } diff --git a/Content.Shared/Spider/SpiderWebObjectComponent.cs b/Content.Shared/Spider/SpiderWebObjectComponent.cs new file mode 100644 index 0000000000..ad9f5b9f39 --- /dev/null +++ b/Content.Shared/Spider/SpiderWebObjectComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Spider; + +[RegisterComponent, NetworkedComponent] +[Access(typeof(SharedSpiderSystem))] +public sealed class SpiderWebObjectComponent : Component +{ +} diff --git a/Content.Shared/Spider/SpiderWebVisualsComponent.cs b/Content.Shared/Spider/SpiderWebVisualsComponent.cs new file mode 100644 index 0000000000..2d6fb58815 --- /dev/null +++ b/Content.Shared/Spider/SpiderWebVisualsComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Spider; + +[Serializable, NetSerializable] +public enum SpiderWebVisuals +{ + Variant +} diff --git a/Resources/Locale/en-US/actions/actions/spider.ftl b/Resources/Locale/en-US/actions/actions/spider.ftl new file mode 100644 index 0000000000..3fc482ce3e --- /dev/null +++ b/Resources/Locale/en-US/actions/actions/spider.ftl @@ -0,0 +1,5 @@ +spider-web-action-name = Spider Web +spider-web-action-description = Spawns a web that slows your prey down. +spider-web-action-nogrid = There is no floor under you! +spider-web-action-success = You place webs around you. +spider-web-action-fail = You can't place webs here! All cardinal directions already have webs! \ No newline at end of file diff --git a/Resources/Prototypes/Actions/spider.yml b/Resources/Prototypes/Actions/spider.yml new file mode 100644 index 0000000000..8a5ee0e52d --- /dev/null +++ b/Resources/Prototypes/Actions/spider.yml @@ -0,0 +1,7 @@ +- type: instantAction + id: SpiderWebAction + icon: Interface/Actions/web.png + name: spider-web-action-name + description: spider-web-action-description + serverEvent: !type:SpiderWebActionEvent + useDelay: 25 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 8d18229c23..23a0130615 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -1316,6 +1316,21 @@ enabled: false autoPopulate: false name: action-name-disarm + - type: MobThresholds + thresholds: + 0: Alive + 90: Critical + 150: Dead + - type: MeleeWeapon + hidden: true + angle: 0 + animation: WeaponArcBite + soundHit: + path: /Audio/Effects/bite.ogg + damage: + types: + Piercing: 12 + Poison: 4 - type: ReplacementAccent accent: xeno - type: InteractionPopup @@ -1323,6 +1338,10 @@ interactSuccessString: petting-success-tarantula interactFailureString: petting-failure-generic - type: Puller + needsHands: false + - type: NoSlip + - type: Spider + - type: IgnoreSpiderWeb - type: entity name: tarantula @@ -1341,7 +1360,7 @@ makeSentient: true name: ghost-role-information-giant-spider-name description: ghost-role-information-giant-spider-description - + - type: entity name: possum parent: SimpleMobBase diff --git a/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml b/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml new file mode 100644 index 0000000000..63d89fc479 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml @@ -0,0 +1,75 @@ +- type: entity + id: SpiderWeb + name: spider web + description: It's stringy and sticky. + placement: + mode: SnapgridCenter + snap: + - Wall + components: + - type: MeleeSound + soundGroups: + Brute: + path: + "/Audio/Weapons/slash.ogg" + - type: Sprite + sprite: Objects/Misc/spiderweb.rsi + layers: + - state: spider_web_1 + map: ["spiderWebLayer"] + drawdepth: WallMountedItems + netsync: false + - type: Appearance + - type: GenericVisualizer + visuals: + enum.SpiderWebVisuals.Variant: + spiderWebLayer: + 1: {state: spider_web_1} + 2: {state: spider_web_2} + - type: Clickable + - type: Transform + anchored: true + - type: Physics + - type: Fixtures + fixtures: + - hard: false + density: 7 + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + layer: + - MidImpassable + - type: Damageable + damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 10 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Temperature + heatDamage: + types: + Heat: 5 + coldDamage: {} + ColdDamageThreshold: 0 + - type: Flammable + fireSpread: true + cold: + types: {} + damage: + types: + Heat: 1 + - type: Reactive + groups: + Flammable: [Touch] + Extinguish: [Touch] + - type: SpiderWebObject + - type: SlowContacts + walkSpeedModifier: 0.5 + sprintSpeedModifier: 0.5 + ignoreWhitelist: + components: + - IgnoreSpiderWeb diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index dae169bdd3..2597006dfa 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -186,6 +186,16 @@ weight: 5 endAfter: 60 +- type: gameRule + id: SpiderSpawn + config: + !type:StationEventRuleConfiguration + id: SpiderSpawn + earliestStart: 20 + minimumPlayers: 15 + weight: 5 + endAfter: 60 + - type: gameRule id: ZombieOutbreak config: diff --git a/Resources/Textures/Interface/Actions/meta.json b/Resources/Textures/Interface/Actions/meta.json index 5fb7046353..a26a136365 100644 --- a/Resources/Textures/Interface/Actions/meta.json +++ b/Resources/Textures/Interface/Actions/meta.json @@ -5,7 +5,7 @@ "y": 32 }, "license": "CC-BY-SA-3.0", - "copyright": "Taken from https://github.com/tgstation/tgstation/commit/3d049e69fe71a0be2133005e65ea469135d648c8. Harm and disarm heavily modified.", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/3d049e69fe71a0be2133005e65ea469135d648c8. Harm and disarm heavily modified. Web made by jackfrost (github) for SS14", "states": [ { "name": "internal0" @@ -54,6 +54,9 @@ }, { "name": "malfunction" + }, + { + "name": "web" } ] } diff --git a/Resources/Textures/Interface/Actions/web.png b/Resources/Textures/Interface/Actions/web.png new file mode 100644 index 0000000000..e459a74bb0 Binary files /dev/null and b/Resources/Textures/Interface/Actions/web.png differ diff --git a/Resources/Textures/Objects/Misc/spiderweb.rsi/meta.json b/Resources/Textures/Objects/Misc/spiderweb.rsi/meta.json new file mode 100644 index 0000000000..fbb29bcf3b --- /dev/null +++ b/Resources/Textures/Objects/Misc/spiderweb.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/788b2576cd9511ced86e74222b6395fd3ef9affe", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "spider_web_1" + }, + { + "name": "spider_web_2" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Misc/spiderweb.rsi/spider_web_1.png b/Resources/Textures/Objects/Misc/spiderweb.rsi/spider_web_1.png new file mode 100644 index 0000000000..e86c5ad4a1 Binary files /dev/null and b/Resources/Textures/Objects/Misc/spiderweb.rsi/spider_web_1.png differ diff --git a/Resources/Textures/Objects/Misc/spiderweb.rsi/spider_web_2.png b/Resources/Textures/Objects/Misc/spiderweb.rsi/spider_web_2.png new file mode 100644 index 0000000000..949dc46083 Binary files /dev/null and b/Resources/Textures/Objects/Misc/spiderweb.rsi/spider_web_2.png differ