Re-add improved random sentience event (#29123)
* Re-add improved random sentience event * Make randomly sentient PDA more likely * Make vending machine sentience less likely * Make requested changes * Make randomly sentient captain's gear more likely * Sentient captain sabre has pirate accent * Tweak new random sentient object a bit more * Sentient PDA improvements * Apply recommended fixes * Add requested changes * Fix merge conflict
This commit is contained in:
@@ -1,9 +1,13 @@
|
|||||||
using Content.Server.StationEvents.Events;
|
using Content.Server.StationEvents.Events;
|
||||||
|
|
||||||
namespace Content.Server.StationEvents.Components;
|
namespace Content.Server.StationEvents.Components;
|
||||||
|
|
||||||
[RegisterComponent, Access(typeof(RandomSentienceRule))]
|
[RegisterComponent, Access(typeof(RandomSentienceRule))]
|
||||||
public sealed partial class RandomSentienceRuleComponent : Component
|
public sealed partial class RandomSentienceRuleComponent : Component
|
||||||
{
|
{
|
||||||
|
[DataField]
|
||||||
|
public int MinSentiences = 1;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public int MaxSentiences = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
using Content.Server.StationEvents.Events;
|
using Content.Server.StationEvents.Events;
|
||||||
|
|
||||||
namespace Content.Server.StationEvents.Components;
|
namespace Content.Server.StationEvents.Components;
|
||||||
|
|
||||||
[RegisterComponent, Access(typeof(RandomSentienceRule))]
|
[RegisterComponent, Access(typeof(RandomSentienceRule))]
|
||||||
public sealed partial class SentienceTargetComponent : Component
|
public sealed partial class SentienceTargetComponent : Component
|
||||||
{
|
{
|
||||||
[DataField("flavorKind", required: true)]
|
[DataField(required: true)]
|
||||||
public string FlavorKind = default!;
|
public string FlavorKind = default!;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public float Weight = 1.0f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,56 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameTicking.Rules.Components;
|
using Content.Shared.Dataset;
|
||||||
using Content.Server.Ghost.Roles.Components;
|
using Content.Server.Ghost.Roles.Components;
|
||||||
using Content.Server.StationEvents.Components;
|
using Content.Server.StationEvents.Components;
|
||||||
using Content.Shared.GameTicking.Components;
|
using Content.Shared.GameTicking.Components;
|
||||||
|
using Content.Shared.Random.Helpers;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
namespace Content.Server.StationEvents.Events;
|
namespace Content.Server.StationEvents.Events;
|
||||||
|
|
||||||
public sealed class RandomSentienceRule : StationEventSystem<RandomSentienceRuleComponent>
|
public sealed class RandomSentienceRule : StationEventSystem<RandomSentienceRuleComponent>
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
protected override void Started(EntityUid uid, RandomSentienceRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
|
protected override void Started(EntityUid uid, RandomSentienceRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
|
||||||
{
|
{
|
||||||
HashSet<EntityUid> stationsToNotify = new();
|
if (!TryGetRandomStation(out var station))
|
||||||
|
return;
|
||||||
|
|
||||||
var targetList = new List<Entity<SentienceTargetComponent>>();
|
var targetList = new List<Entity<SentienceTargetComponent>>();
|
||||||
var query = EntityQueryEnumerator<SentienceTargetComponent>();
|
var query = EntityQueryEnumerator<SentienceTargetComponent, TransformComponent>();
|
||||||
while (query.MoveNext(out var targetUid, out var target))
|
while (query.MoveNext(out var targetUid, out var target, out var xform))
|
||||||
{
|
{
|
||||||
|
if (StationSystem.GetOwningStation(targetUid, xform) != station)
|
||||||
|
continue;
|
||||||
|
|
||||||
targetList.Add((targetUid, target));
|
targetList.Add((targetUid, target));
|
||||||
}
|
}
|
||||||
|
|
||||||
RobustRandom.Shuffle(targetList);
|
var toMakeSentient = _random.Next(component.MinSentiences, component.MaxSentiences);
|
||||||
|
|
||||||
var toMakeSentient = RobustRandom.Next(2, 5);
|
|
||||||
var groups = new HashSet<string>();
|
var groups = new HashSet<string>();
|
||||||
|
|
||||||
foreach (var target in targetList)
|
for (var i = 0; i < toMakeSentient && targetList.Count > 0; i++)
|
||||||
{
|
{
|
||||||
if (toMakeSentient-- == 0)
|
// weighted random to pick a sentience target
|
||||||
|
var totalWeight = targetList.Sum(x => x.Comp.Weight);
|
||||||
|
// This initial target should never be picked.
|
||||||
|
// It's just so that target doesn't need to be nullable and as a safety fallback for id floating point errors ever mess up the comparison in the foreach.
|
||||||
|
var target = targetList[0];
|
||||||
|
var chosenWeight = _random.NextFloat(totalWeight);
|
||||||
|
var currentWeight = 0.0;
|
||||||
|
foreach (var potentialTarget in targetList)
|
||||||
|
{
|
||||||
|
currentWeight += potentialTarget.Comp.Weight;
|
||||||
|
if (currentWeight > chosenWeight)
|
||||||
|
{
|
||||||
|
target = potentialTarget;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
targetList.Remove(target);
|
||||||
|
|
||||||
RemComp<SentienceTargetComponent>(target);
|
RemComp<SentienceTargetComponent>(target);
|
||||||
var ghostRole = EnsureComp<GhostRoleComponent>(target);
|
var ghostRole = EnsureComp<GhostRoleComponent>(target);
|
||||||
@@ -45,24 +68,15 @@ public sealed class RandomSentienceRule : StationEventSystem<RandomSentienceRule
|
|||||||
var kind2 = groupList.Count > 1 ? groupList[1] : "???";
|
var kind2 = groupList.Count > 1 ? groupList[1] : "???";
|
||||||
var kind3 = groupList.Count > 2 ? groupList[2] : "???";
|
var kind3 = groupList.Count > 2 ? groupList[2] : "???";
|
||||||
|
|
||||||
foreach (var target in targetList)
|
|
||||||
{
|
|
||||||
var station = StationSystem.GetOwningStation(target);
|
|
||||||
if(station == null)
|
|
||||||
continue;
|
|
||||||
stationsToNotify.Add((EntityUid) station);
|
|
||||||
}
|
|
||||||
foreach (var station in stationsToNotify)
|
|
||||||
{
|
|
||||||
ChatSystem.DispatchStationAnnouncement(
|
ChatSystem.DispatchStationAnnouncement(
|
||||||
station,
|
station.Value,
|
||||||
Loc.GetString("station-event-random-sentience-announcement",
|
Loc.GetString("station-event-random-sentience-announcement",
|
||||||
("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count),
|
("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count),
|
||||||
("data", Loc.GetString($"random-sentience-event-data-{RobustRandom.Next(1, 6)}")),
|
("data", _random.Pick(_prototype.Index<LocalizedDatasetPrototype>("RandomSentienceEventData"))),
|
||||||
("strength", Loc.GetString($"random-sentience-event-strength-{RobustRandom.Next(1, 8)}"))),
|
("strength", _random.Pick(_prototype.Index<LocalizedDatasetPrototype>("RandomSentienceEventStrength")))
|
||||||
|
),
|
||||||
playDefaultSound: false,
|
playDefaultSound: false,
|
||||||
colorOverride: Color.Gold
|
colorOverride: Color.Gold
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
namespace Content.Shared.Interaction.Components;
|
namespace Content.Shared.Interaction.Components;
|
||||||
|
|
||||||
@@ -8,5 +8,6 @@ namespace Content.Shared.Interaction.Components;
|
|||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent]
|
||||||
public sealed partial class BlockMovementComponent : Component
|
public sealed partial class BlockMovementComponent : Component
|
||||||
{
|
{
|
||||||
|
[DataField]
|
||||||
|
public bool BlockInteraction = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public partial class SharedInteractionSystem
|
|||||||
|
|
||||||
private void CancelInteractEvent(Entity<BlockMovementComponent> ent, ref InteractionAttemptEvent args)
|
private void CancelInteractEvent(Entity<BlockMovementComponent> ent, ref InteractionAttemptEvent args)
|
||||||
{
|
{
|
||||||
|
if (ent.Comp.BlockInteraction)
|
||||||
args.Cancelled = true;
|
args.Cancelled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,3 +36,4 @@ station-event-random-sentience-flavor-corgi = corgi
|
|||||||
station-event-random-sentience-flavor-primate = primate
|
station-event-random-sentience-flavor-primate = primate
|
||||||
station-event-random-sentience-flavor-kobold = kobold
|
station-event-random-sentience-flavor-kobold = kobold
|
||||||
station-event-random-sentience-flavor-slime = slime
|
station-event-random-sentience-flavor-slime = slime
|
||||||
|
station-event-random-sentience-flavor-inanimate = inanimate
|
||||||
@@ -869,6 +869,10 @@
|
|||||||
- ClothMade
|
- ClothMade
|
||||||
- WhitelistChameleon
|
- WhitelistChameleon
|
||||||
- HamsterWearable
|
- HamsterWearable
|
||||||
|
- type: SentienceTarget
|
||||||
|
flavorKind: station-event-random-sentience-flavor-inanimate
|
||||||
|
weight: 0.0002 # 5,000 times less likely than 1 regular animal
|
||||||
|
- type: BlockMovement
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingHeadBase
|
parent: ClothingHeadBase
|
||||||
|
|||||||
@@ -376,6 +376,8 @@
|
|||||||
behaviors:
|
behaviors:
|
||||||
- !type:GibBehavior { }
|
- !type:GibBehavior { }
|
||||||
- type: NonSpreaderZombie
|
- type: NonSpreaderZombie
|
||||||
|
- type: SentienceTarget
|
||||||
|
flavorKind: station-event-random-sentience-flavor-organic
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: glockroach
|
name: glockroach
|
||||||
|
|||||||
@@ -286,6 +286,8 @@
|
|||||||
- type: Construction
|
- type: Construction
|
||||||
graph: MediBot
|
graph: MediBot
|
||||||
node: bot
|
node: bot
|
||||||
|
- type: SentienceTarget
|
||||||
|
flavorKind: station-event-random-sentience-flavor-mechanical
|
||||||
- type: Anchorable
|
- type: Anchorable
|
||||||
- type: InteractionPopup
|
- type: InteractionPopup
|
||||||
interactSuccessString: petting-success-medibot
|
interactSuccessString: petting-success-medibot
|
||||||
|
|||||||
@@ -103,6 +103,15 @@
|
|||||||
- DoorBumpOpener
|
- DoorBumpOpener
|
||||||
- type: Input
|
- type: Input
|
||||||
context: "human"
|
context: "human"
|
||||||
|
- type: SentienceTarget # sentient PDA = pAI lite
|
||||||
|
flavorKind: station-event-random-sentience-flavor-mechanical
|
||||||
|
weight: 0.001 # 1,000 PDAs = as likely to be picked as 1 regular animal
|
||||||
|
- type: BlockMovement
|
||||||
|
blockInteraction: false # lets the PDA toggle its own flashlight
|
||||||
|
- type: TypingIndicator
|
||||||
|
proto: robot
|
||||||
|
- type: Speech
|
||||||
|
speechVerb: Robotic
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BasePDA
|
parent: BasePDA
|
||||||
@@ -220,6 +229,8 @@
|
|||||||
borderColor: "#d7d7d0"
|
borderColor: "#d7d7d0"
|
||||||
- type: Icon
|
- type: Icon
|
||||||
state: pda-cook
|
state: pda-cook
|
||||||
|
- type: ReplacementAccent # for random sentience event
|
||||||
|
accent: italian
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BasePDA
|
parent: BasePDA
|
||||||
@@ -299,6 +310,7 @@
|
|||||||
accentHColor: "#333333"
|
accentHColor: "#333333"
|
||||||
- type: Icon
|
- type: Icon
|
||||||
state: pda-mime
|
state: pda-mime
|
||||||
|
- type: Muted # for random sentience event
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: chaplain PDA
|
name: chaplain PDA
|
||||||
|
|||||||
@@ -584,6 +584,10 @@
|
|||||||
price: 750
|
price: 750
|
||||||
- type: StealTarget
|
- type: StealTarget
|
||||||
stealGroup: WeaponAntiqueLaser
|
stealGroup: WeaponAntiqueLaser
|
||||||
|
- type: SentienceTarget # I hope this is only the captain's gun
|
||||||
|
flavorKind: station-event-random-sentience-flavor-inanimate
|
||||||
|
weight: 0.0002 # 5,000 times less likely than 1 regular animal
|
||||||
|
# not putting a BlockMovement component here cause that's funny.
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: advanced laser pistol
|
name: advanced laser pistol
|
||||||
|
|||||||
@@ -40,6 +40,11 @@
|
|||||||
tags:
|
tags:
|
||||||
- CaptainSabre
|
- CaptainSabre
|
||||||
- type: DisarmMalus
|
- type: DisarmMalus
|
||||||
|
- type: SentienceTarget
|
||||||
|
flavorKind: station-event-random-sentience-flavor-inanimate
|
||||||
|
weight: 0.0002 # 5,000 times less likely than 1 regular animal
|
||||||
|
- type: PirateAccent
|
||||||
|
# not putting a BlockMovement component here cause that's funny.
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: katana
|
name: katana
|
||||||
|
|||||||
@@ -96,6 +96,7 @@
|
|||||||
- type: Actions
|
- type: Actions
|
||||||
- type: SentienceTarget
|
- type: SentienceTarget
|
||||||
flavorKind: station-event-random-sentience-flavor-mechanical
|
flavorKind: station-event-random-sentience-flavor-mechanical
|
||||||
|
weight: 0.025 # fuck you in particular (it now needs 40 vending machines to be as likely as 1 interesting animal)
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 100
|
price: 100
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
|
|||||||
25
Resources/Prototypes/GameRules/random_sentience.yml
Normal file
25
Resources/Prototypes/GameRules/random_sentience.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
- type: entity
|
||||||
|
id: RandomSentience
|
||||||
|
parent: BaseGameRule
|
||||||
|
components:
|
||||||
|
- type: StationEvent
|
||||||
|
weight: 6
|
||||||
|
duration: 1
|
||||||
|
maxOccurrences: 1 # this event has diminishing returns on interesting-ness, so we cap it
|
||||||
|
startAudio:
|
||||||
|
path: /Audio/Announcements/attention.ogg
|
||||||
|
- type: RandomSentienceRule
|
||||||
|
minSentiences: 2
|
||||||
|
maxSentiences: 5
|
||||||
|
|
||||||
|
- type: localizedDataset
|
||||||
|
id: RandomSentienceEventData
|
||||||
|
values:
|
||||||
|
prefix: random-sentience-event-data-
|
||||||
|
count: 6
|
||||||
|
|
||||||
|
- type: localizedDataset
|
||||||
|
id: RandomSentienceEventStrength
|
||||||
|
values:
|
||||||
|
prefix: random-sentience-event-strength-
|
||||||
|
count: 8
|
||||||
Reference in New Issue
Block a user