Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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);
}
78 changes: 78 additions & 0 deletions Content.Server/_ES/StationEvents/VentSwarm/ESVentSwarmRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
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) ||
!TryGetEntity(ventOption.Entity, out var vent))
{
ForceEndSelf(ent);
return;
}

ent.Comp.Vent = vent.Value;

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