Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Content.Server/NPC/HTN/HTNSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,18 @@ private void Update(HTNComponent component, float frameTime)
break;
case HTNOperatorStatus.Failed:
ShutdownTask(currentOperator, blackboard, status);
ShutdownPlan(component);
// ES START
if (component.Plan != null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:smoke:

lovely video gae

ShutdownPlan(component);
// ES END
break;
// Operator completed so go to the next one.
case HTNOperatorStatus.Finished:
ShutdownTask(currentOperator, blackboard, status);
// ES START
if (component.Plan == null)
break;
// ES END
component.Plan.Index++;

// Plan finished!
Expand Down
29 changes: 28 additions & 1 deletion Content.Server/NPC/Systems/NPCUtilitySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@
using Robust.Shared.Utility;
using Content.Shared.Atmos.Components;
using System.Linq;
using Content.Server._ES.NPCs.Queries.Considerations;
using Content.Shared.Damage.Components;
using Content.Shared.Temperature.Components;
using Content.Shared._Offbrand.Wounds; // Offbrand
using Content.Shared._Offbrand.Wounds;
using Content.Shared.ActionBlocker;
using Content.Shared.Interaction; // Offbrand

namespace Content.Server.NPC.Systems;

Expand All @@ -39,6 +42,9 @@ namespace Content.Server.NPC.Systems;
/// </summary>
public sealed class NPCUtilitySystem : EntitySystem
{
// ES START
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
// ES END
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
Expand Down Expand Up @@ -170,6 +176,27 @@ private float GetScore(NPCBlackboard blackboard, EntityUid targetUid, UtilityCon
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
switch (consideration)
{
// ES START
case ESTargetBesideCon:
{
if (!TryComp(targetUid, out TransformComponent? targetXform) ||
!TryComp(owner, out TransformComponent? xform))
{
return 0f;
}

if (!targetXform.Coordinates.TryDistance(EntityManager, _transform, xform.Coordinates, out var distance))
{
return 0f;
}

return Math.Clamp(distance / 0.5f, 0f, 1f);
}
case ESCanInteractCon:
{
return _actionBlocker.CanInteract(owner, targetUid) ? 1 : 0;
}
// ES END
case FoodValueCon:
{
// do we have a mouth available? Is the food item opened?
Expand Down
42 changes: 42 additions & 0 deletions Content.Server/_ES/NPCs/Operators/ESSnipCableOperator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Content.Server.Electrocution;
using Content.Server.NPC;
using Content.Server.NPC.HTN;
using Content.Server.NPC.HTN.PrimitiveTasks;
using Content.Server.Power.Components;

namespace Content.Server._ES.NPCs.Operators;

public sealed partial class ESSnipCableOperator : HTNOperator
{
[Dependency] private readonly IEntityManager _entityManager = default!;
private ElectrocutionSystem _electrocution;

/// <summary>
/// Key that contains the target entity.
/// </summary>
[DataField]
public string TargetKey = "Target";

public override void Initialize(IEntitySystemManager sysManager)
{
base.Initialize(sysManager);
_electrocution = sysManager.GetEntitySystem<ElectrocutionSystem>();
}

public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime)
{
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);

if (!blackboard.TryGetValue<EntityUid>(TargetKey, out var target, _entityManager))
return HTNOperatorStatus.Failed;

if (!_entityManager.TryGetComponent<CableComponent>(target, out var cableComponent))
return HTNOperatorStatus.Failed;

_electrocution.TryDoElectrifiedAct(target, owner);
_entityManager.SpawnNextToOrDrop(cableComponent.CableDroppedOnCutPrototype, target);
_entityManager.QueueDeleteEntity(target);

return HTNOperatorStatus.Finished;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Content.Server.NPC.Queries.Considerations;

namespace Content.Server._ES.NPCs.Queries.Considerations;

public sealed partial class ESCanInteractCon : UtilityConsideration;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Content.Server.NPC.Queries.Considerations;

namespace Content.Server._ES.NPCs.Queries.Considerations;

public sealed partial class ESTargetBesideCon : UtilityConsideration;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Content.Shared.EntityTable.EntitySelectors;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;

namespace Content.Server._ES.StationEvents.VentSwarm.Components;

[RegisterComponent, AutoGenerateComponentPause]
[Access(typeof(ESVentSwarmRule))]
public sealed partial class ESVentSwarmRuleComponent : Component
{
[DataField]
public EntityUid? Vent;

[DataField]
public EntityTableSelector SpawnTable;

[DataField]
public int MinSwarmCount = 6;

[DataField]
public int MaxSwarmCount = 12;

[DataField]
public int SwarmCount;

[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan NextSwarmTime;

[DataField]
public TimeSpan MinSwarmDelay = TimeSpan.FromSeconds(1);

[DataField]
public TimeSpan MaxSwarmDelay = TimeSpan.FromSeconds(3);
}
77 changes: 77 additions & 0 deletions Content.Server/_ES/StationEvents/VentSwarm/ESVentSwarmRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Content.Server._ES.StationEvents.VentSwarm.Components;
using Content.Server.Pinpointer;
using Content.Server.Popups;
using Content.Server.StationEvents.Components;
using Content.Server.StationEvents.Events;
using Content.Shared._ES.Voting.Components;
using Content.Shared._ES.Voting.Results;
using Content.Shared.EntityTable;
using Content.Shared.GameTicking.Components;
using Robust.Shared.Utility;

namespace Content.Server._ES.StationEvents.VentSwarm;

public sealed class ESVentSwarmRule : StationEventSystem<ESVentSwarmRuleComponent>
{
[Dependency] private readonly EntityTableSystem _entityTable = default!;
[Dependency] private readonly NavMapSystem _navMap = default!;
[Dependency] private readonly PopupSystem _popup = default!;

/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ESVentSwarmRuleComponent, ESSynchronizedVotesCompletedEvent>(OnVotesCompleted);
}

private void OnVotesCompleted(Entity<ESVentSwarmRuleComponent> ent, ref ESSynchronizedVotesCompletedEvent args)
{
if (!args.TryGetResult<ESEntityVoteOption>(0, out var ventOption))
{
ForceEndSelf(ent);
return;
}

ent.Comp.Vent = GetEntity(ventOption.Entity);

if (TryComp<StationEventComponent>(ent, out var station))
{
station.StartAnnouncement = Loc.GetString("es-station-event-vent-swarm-start-announcement",
("location", FormattedMessage.RemoveMarkupPermissive(_navMap.GetNearestBeaconString(ent.Comp.Vent.Value))));
}
}

protected override void Started(EntityUid uid, ESVentSwarmRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);

component.NextSwarmTime = Timing.CurTime;
component.SwarmCount = RobustRandom.Next(component.MinSwarmCount, component.MaxSwarmCount + 1);
}

protected override void ActiveTick(EntityUid uid, ESVentSwarmRuleComponent component, GameRuleComponent gameRule, float frameTime)
{
base.ActiveTick(uid, component, gameRule, frameTime);

if (!component.Vent.HasValue || TerminatingOrDeleted(component.Vent))
{
ForceEndSelf(uid, gameRule);
return;
}

if (Timing.CurTime < component.NextSwarmTime)
return;
component.NextSwarmTime += RobustRandom.Next(component.MinSwarmDelay, component.MaxSwarmDelay);

foreach (var spawn in _entityTable.GetSpawns(component.SpawnTable))
{
var ent = SpawnNextToOrDrop(spawn, component.Vent.Value);
_popup.PopupEntity(Loc.GetString("es-vent-swarm-popup", ("spawn", ent)), ent);
}

component.SwarmCount--;
if (component.SwarmCount <= 0)
ForceEndSelf(uid, gameRule);
}
}
2 changes: 1 addition & 1 deletion Resources/Audio/_ES/Announcements/attributions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
copyright: "Taken from tgstation, modified by pigeonbeans"
source: "https://github.com/tgstation/tgstation/blob/40d89d11ea4a5cb81d61dc1018b46f4e7d32c62a/sound/ai/default/shuttlerecalled.ogg"

- files: ["attention_low.ogg", "attention_medium.ogg", "attention_high.ogg", "breaker_flip.ogg", "electrical_fire.ogg", "gas_leak.ogg", "greytide.ogg", "meteors.ogg", "power_off.ogg", "power_on.ogg", "solar_flare.ogg", "space_dust.ogg", "vent_foam.ogg", "radstorm_start.ogg", "radstorm_5mins.ogg", "radstorm_15mins.ogg", "radstorm_30mins.ogg"]
- files: ["attention_low.ogg", "attention_medium.ogg", "attention_high.ogg", "breaker_flip.ogg", "critterswarm.ogg", "electrical_fire.ogg", "gas_leak.ogg", "greytide.ogg", "meteors.ogg", "power_off.ogg", "power_on.ogg", "solar_flare.ogg", "space_dust.ogg", "vent_foam.ogg", "radstorm_start.ogg", "radstorm_5mins.ogg", "radstorm_15mins.ogg", "radstorm_30mins.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Made by pigeonbeans using sounds from tgstation"
source: "https://github.com/tgstation/tgstation/tree/master/sound/announcer/vox_fem"
Binary file not shown.
3 changes: 3 additions & 0 deletions Resources/Locale/en-US/_ES/station-events/vent-swarm.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
es-station-event-vent-swarm-start-announcement = An influx of unknown life forms have been detected on the station. Sensors indicate they've entered through ventilation {$location}.
es-vent-swarm-popup = {CAPITALIZE(THE($spawn))} crawls out of the vent!
es-voter-query-string-vent-swarm-location = The swarm will enter:
7 changes: 4 additions & 3 deletions Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,9 @@
- type: HTN
constantlyReplan: false
rootTask:
task: MouseCompound
# ES START
task: RuminantCompound
# ES END
- type: Physics
- type: Fixtures
fixtures:
Expand Down Expand Up @@ -1815,8 +1817,7 @@
- type: MobThresholds
thresholds:
0: Alive
10: Critical
20: Dead
5: Dead
- type: MovementSpeedModifier
baseWalkSpeed : 2.5
baseSprintSpeed : 5
Expand Down
4 changes: 3 additions & 1 deletion Resources/Prototypes/Entities/Mobs/NPCs/space.yml
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,9 @@
- type: HTN
constantlyReplan: false
rootTask:
task: MouseCompound
# ES START
task: RuminantCompound
# ES END
- type: Physics
- type: Fixtures
fixtures:
Expand Down
7 changes: 6 additions & 1 deletion Resources/Prototypes/NPCs/mob.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@
- type: htnCompound
id: MouseCompound
branches:
# ES START
- tasks:
- !type:HTNCompoundTask
task: ESCutCablesCompound
# ES END
- tasks:
- !type:HTNCompoundTask
task: FoodCompound
- tasks:
- !type:HTNCompoundTask
task: IdleCompound

- type: htnCompound
id: MoproachCompound
branches:
Expand Down
20 changes: 20 additions & 0 deletions Resources/Prototypes/_ES/GameRules/degradation_events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
table:
all:
- id: ESDegradationEventAirlocks
- id: ESDegradationEventMouse
- id: ESDegradationEventCommunicationsConsole
- id: ESDegradationEventCriminalRecords
- id: ESDegradationEventTelecoms
Expand All @@ -33,6 +34,25 @@
- type: StationEvent
weight: 50

- type: entity
parent: ESBaseDegradationEvent
id: ESDegradationEventMouse
name: Mouse Swarm
description: Sends mice into maintenance to nibble wires.
components:
- type: ESSpawnRandomRule
spawnRegion: ESMaintenance
table:
group:
- id: MobMouse
- id: MobMouse1
- id: MobMouse2
rolls: 5, 8
- type: ESTimedDespawn
lifetime: 1.0
- type: StationEvent
weight: 40

- type: entity
parent: ESBaseDegradationEvent
id: ESDegradationEventCommunicationsConsole
Expand Down
34 changes: 34 additions & 0 deletions Resources/Prototypes/_ES/GameRules/station_events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
- id: ESStationEventVentClog
- id: ESStationEventMeteorSwarm
- id: ESStationEventElectricalFire
- id: ESStationEventVentSwarm

# Event Prototypes

Expand Down Expand Up @@ -214,6 +215,39 @@
startAnnouncement: station-event-vent-clog-start-announcement
- type: VentClogRule

## Vent Swarm
- type: entity
parent: ESBaseStationEvent
id: ESStationEventVentSwarm
name: Critter Swarm
description: Causes a swarm of critters to enter through a vent
components:
- type: StationEvent
startAudio:
path: /Audio/_ES/Announcements/critterswarm.ogg
params:
volume: -4
duration: 120
- type: ESVentSwarmRule
spawnTable:
group:
- id: MobMouse
- id: MobMouse1
- id: MobMouse2
- type: ESSynchronizedVoteManager
votes:
- ESVoteVentSwarmLocation

- type: entity
id: ESVoteVentSwarmLocation
name: Where should the swarm enter?
components:
- type: ESVote
queryString: es-voter-query-string-vent-swarm-location
duration: 30
- type: ESGasVentVote
count: 4

## Meteor Swarm
- type: entity
parent: ESBaseStationEventDelayed
Expand Down
Loading
Loading