Good artifact effects (#13223)

This commit is contained in:
Nemanja 2023-01-01 00:59:38 -05:00 committed by GitHub
parent 2287f9df11
commit 01ef7a2d1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 253 additions and 103 deletions

View File

@ -0,0 +1,14 @@
namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
/// <summary>
/// This is used for recharging all nearby batteries when activated
/// </summary>
[RegisterComponent]
public sealed class ChargeBatteryArtifactComponent : Component
{
/// <summary>
/// The radius of entities that will be affected
/// </summary>
[DataField("radius")]
public float Radius = 15f;
}

View File

@ -1,6 +1,4 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Content.Shared.Storage;
namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
@ -11,18 +9,8 @@ namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
[RegisterComponent]
public sealed class SpawnArtifactComponent : Component
{
/// <summary>
/// The list of possible prototypes to spawn that it picks from.
/// </summary>
[DataField("possiblePrototypes", customTypeSerializer:typeof(PrototypeIdListSerializer<EntityPrototype>))]
public List<string> PossiblePrototypes = new();
/// <summary>
/// The prototype it selected to spawn.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("prototype", customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? Prototype;
[DataField("spawns")]
public List<EntitySpawnEntry>? Spawns;
/// <summary>
/// The range around the artifact that it will spawn the entity
@ -34,12 +22,5 @@ public sealed class SpawnArtifactComponent : Component
/// The maximum number of times the spawn will occur
/// </summary>
[DataField("maxSpawns")]
public int MaxSpawns = 20;
/// <summary>
/// Whether or not the artifact spawns the same entity every time
/// or picks through the list each time.
/// </summary>
[DataField("consistentSpawn")]
public bool ConsistentSpawn = true;
public int MaxSpawns = 10;
}

View File

@ -0,0 +1,26 @@
using Content.Server.Power.Components;
using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
/// <summary>
/// This handles <see cref="ChargeBatteryArtifactComponent"/>
/// </summary>
public sealed class ChargeBatteryArtifactSystem : EntitySystem
{
[Dependency] private readonly EntityLookupSystem _lookup = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<ChargeBatteryArtifactComponent, ArtifactActivatedEvent>(OnActivated);
}
private void OnActivated(EntityUid uid, ChargeBatteryArtifactComponent component, ArtifactActivatedEvent args)
{
foreach (var battery in _lookup.GetComponentsInRange<BatteryComponent>(Transform(uid).MapPosition, component.Radius))
{
battery.CurrentCharge = battery.MaxCharge;
}
}
}

View File

@ -17,9 +17,7 @@ public sealed class RandomInstrumentArtifactSystem : EntitySystem
private void OnStartup(EntityUid uid, RandomInstrumentArtifactComponent component, ComponentStartup args)
{
if (!TryComp<SharedInstrumentComponent>(uid, out var instrument))
return;
var instrument = EnsureComp<InstrumentComponent>(uid);
_instrument.SetInstrumentProgram(instrument, (byte) _random.Next(0, 127), 0);
}
}

View File

@ -1,6 +1,6 @@
using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Storage;
using Robust.Shared.Random;
namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
@ -8,7 +8,6 @@ namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
public sealed class SpawnArtifactSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly ArtifactSystem _artifact = default!;
public const string NodeDataSpawnAmount = "nodeDataSpawnAmount";
@ -16,45 +15,28 @@ public sealed class SpawnArtifactSystem : EntitySystem
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SpawnArtifactComponent, ArtifactNodeEnteredEvent>(OnNodeEntered);
SubscribeLocalEvent<SpawnArtifactComponent, ArtifactActivatedEvent>(OnActivate);
}
private void OnNodeEntered(EntityUid uid, SpawnArtifactComponent component, ArtifactNodeEnteredEvent args)
{
if (component.PossiblePrototypes.Count == 0)
return;
var proto = component.PossiblePrototypes[args.RandomSeed % component.PossiblePrototypes.Count];
component.Prototype = proto;
}
private void OnActivate(EntityUid uid, SpawnArtifactComponent component, ArtifactActivatedEvent args)
{
if (component.Prototype == null)
return;
if (!_artifact.TryGetNodeData(uid, NodeDataSpawnAmount, out int amount))
amount = 0;
if (amount >= component.MaxSpawns)
return;
var toSpawn = component.Prototype;
if (!component.ConsistentSpawn)
toSpawn = _random.Pick(component.PossiblePrototypes);
if (component.Spawns is not {} spawns)
return;
// select spawn position near artifact
var artifactCord = Transform(uid).MapPosition;
var dx = _random.NextFloat(-component.Range, component.Range);
var dy = _random.NextFloat(-component.Range, component.Range);
var spawnCord = artifactCord.Offset(new Vector2(dx, dy));
// spawn entity
var spawned = EntityManager.SpawnEntity(toSpawn, spawnCord);
_artifact.SetNodeData(uid, NodeDataSpawnAmount, amount+1);
// if there is an user - try to put spawned item in their hands
// doesn't work for spawners
_handsSystem.PickupOrDrop(args.Activator, spawned);
foreach (var spawn in EntitySpawnCollection.GetSpawns(spawns, _random))
{
var dx = _random.NextFloat(-component.Range, component.Range);
var dy = _random.NextFloat(-component.Range, component.Range);
var spawnCord = artifactCord.Offset(new Vector2(dx, dy));
EntityManager.SpawnEntity(spawn, spawnCord);
}
_artifact.SetNodeData(uid, NodeDataSpawnAmount, amount + 1);
}
}

View File

@ -15,6 +15,7 @@ artifact-effect-hint-multitool = Utility conglomerate
artifact-effect-hint-storage = Internal chamber
artifact-effect-hint-drill = Serrated rotator
artifact-effect-hint-soap = Lubricated surface
artifact-effect-hint-communication = Long-distance communication
# the triggers should be more obvious than the effects
# gives people an idea of what to do: don't be too specific (i.e. no "welders")

View File

@ -1,4 +1,5 @@
blink-artifact-popup = The artifact disappeared in an instant!
foam-artifact-popup = Strange foam pours out of the artifact!
shuffle-artifact-popup = You feel yourself teleport instantly!
shuffle-artifact-popup = You feel yourself teleport instantly!
charge-artifact-popup = You feel the air buzz with electricity.

View File

@ -46,6 +46,8 @@
type: StorageBoundUserInterface
- key: enum.TransferAmountUiKey.Key
type: TransferAmountBoundUserInterface
- key: enum.InstrumentUiKey.Key
type: InstrumentBoundUserInterface
- type: Appearance
- type: StaticPrice
price: 500

View File

@ -19,6 +19,14 @@
bodyType: Dynamic
- type: Transform
noRot: true
- type: UserInterface #needs to be here for certain effects
interfaces:
- key: enum.StorageUiKey.Key
type: StorageBoundUserInterface
- key: enum.TransferAmountUiKey.Key
type: TransferAmountBoundUserInterface
- key: enum.InstrumentUiKey.Key
type: InstrumentBoundUserInterface
- type: Fixtures
fixtures:
- shape:

View File

@ -64,20 +64,37 @@
components:
- type: SpawnArtifact
maxSpawns: 10
consistentSpawns: false
possiblePrototypes:
- FoodPacketSyndiTrash
- FoodPacketSemkiTrash
- FoodPacketBoritosTrash
- FoodPacketCheesieTrash
- FoodPacketChipsTrash
- FoodPacketChocolateTrash
- FoodPacketChowMeinTrash
- FoodPacketEnergyTrash
- FoodPacketPopcornTrash
- FoodPacketRaisinsTrash
- RandomInstruments
- ToySpawner
spawns:
- id: FoodPacketSyndiTrash
prob: 0.1
orGroup: Trash
- id: FoodPacketSemkiTrash
prob: 0.1
orGroup: Trash
- id: FoodPacketBoritosTrash
prob: 0.1
orGroup: Trash
- id: FoodPacketCheesieTrash
prob: 0.1
orGroup: Trash
- id: FoodPacketChipsTrash
prob: 0.1
orGroup: Trash
- id: FoodPacketChocolateTrash
prob: 0.1
orGroup: Trash
- id: FoodPacketEnergyTrash
prob: 0.1
orGroup: Trash
- id: FoodPacketPopcornTrash
prob: 0.1
orGroup: Trash
- id: FoodPacketRaisinsTrash
prob: 0.1
orGroup: Trash
- id: ToySpawner
prob: 0.1
orGroup: Trash
- type: artifactEffect
id: EffectLightFlicker
@ -102,8 +119,8 @@
components:
- type: SpawnArtifact
maxSpawns: 20
possiblePrototypes:
- FoodBanana
spawns:
- id: FoodBanana
- type: artifactEffect
id: EffectCold
@ -145,8 +162,32 @@
components:
- type: SpawnArtifact
maxSpawns: 5
possiblePrototypes:
- RandomInstruments
spawns:
- id: RandomInstruments
- type: artifactEffect
id: EffectMonkeySpawn
targetDepth: 1
effectHint: artifact-effect-hint-creation
components:
- type: SpawnArtifact
spawns:
- id: MobMonkey
orGroup: monkey
prob: 0.95
- id: MobGorilla #harambe
orGroup: monkey
prob: 0.05
- type: artifactEffect
id: EffectChargeBatteries
targetDepth: 1
effectHint: artifact-effect-hint-release
components:
- type: ChargeBatteryArtifact
- type: TelepathicArtifact
messages:
- charge-artifact-popup
- type: artifactEffect
id: EffectAngryCarpSpawn
@ -155,9 +196,30 @@
components:
- type: SpawnArtifact
maxSpawns: 5
possiblePrototypes:
- MobCarpHolo
- MobCarpMagic
spawns:
- id: MobCarpHolo
orGroup: carp
- id: MobCarpMagic
orGroup: carp
- type: artifactEffect
id: EffectCashSpawn
targetDepth: 2
effectHint: artifact-effect-hint-creation
components:
- type: SpawnArtifact
maxSpawns: 10
spawns:
- id: SpaceCash10
maxAmount: 5
prob: 0.75
- id: SpaceCash100
maxAmount: 2
prob: 0.5
- id: SpaceCash500
prob: 0.25
- id: SpaceCash1000
prob: 0.1
- type: artifactEffect
id: EffectRadiate
@ -202,6 +264,39 @@
components:
- type: RandomTeleportArtifact
- type: artifactEffect
id: EffectFoamGood
targetDepth: 2
effectHint: artifact-effect-hint-biochemical
components:
- type: FoamArtifact
spreadDuration: 0.5
duration: 5
reagents:
- Dermaline
- Arithrazine
- Spaceacillin
- Inaprovaline
- Kelotane
- Dexalin
- Omnizine
- type: artifactEffect
id: EffectHealAll
targetDepth: 3
effectHint: artifact-effect-hint-environment
components:
- type: DamageNearbyArtifact
damageChance: 0.75
radius: 5
whitelist:
components:
- MobState
damage:
groups:
Brute: -300
Burn: -300
- type: artifactEffect
id: EffectMaterialSpawn
targetDepth: 3
@ -209,11 +304,13 @@
components:
- type: SpawnArtifact
maxSpawns: 5
consistentSpawn: false
possiblePrototypes:
- SheetGlass
- SheetSteel
- SheetPlastic
spawns:
- id: SheetSteel
orGroup: materials
- id: SheetGlass
orGroup: materials
- id: SheetPlastic
orGroup: materials
- type: artifactEffect
id: EffectShuffle
@ -233,13 +330,22 @@
components:
- type: SpawnArtifact
maxSpawns: 10
consistentSpawn: false
possiblePrototypes:
- SuperCapacitorStockPart
- PhasicScanningModuleStockPart
- PicoManipulatorStockPart
- UltraHighPowerMicroLaserStockPart
- SuperMatterBinStockPart
spawns:
- id: SuperCapacitorStockPart
prob: 0.3
maxAmount: 2
- id: PhasicScanningModuleStockPart
prob: 0.3
maxAmount: 2
- id: PicoManipulatorStockPart
prob: 0.3
maxAmount: 2
- id: UltraHighPowerMicroLaserStockPart
prob: 0.3
maxAmount: 2
- id: SuperMatterBinStockPart
prob: 0.3
maxAmount: 2
- type: artifactEffect
id: EffectDisease
@ -262,13 +368,19 @@
effectHint: artifact-effect-hint-creation
components:
- type: SpawnArtifact
maxSpawns: 15
consistentSpawn: false
possiblePrototypes:
- SilverOre1
- PlasmaOre1
- GoldOre1
- UraniumOre1
spawns:
- id: SilverOre1
prob: 0.3
maxAmount: 3
- id: PlasmaOre1
prob: 0.3
maxAmount: 3
- id: GoldOre1
prob: 0.3
maxAmount: 3
- id: UraniumOre1
prob: 0.3
maxAmount: 3
- type: artifactEffect
id: EffectHeat
@ -306,6 +418,16 @@
components:
- type: IgniteArtifact
- type: artifactEffect
id: EffectMitosis
targetDepth: 4
effectHint: artifact-effect-hint-creation
components:
- type: SpawnArtifact
maxSpawns: 1
spawns:
- id: RandomArtifactSpawner
- type: artifactEffect
id: EffectSingulo
targetDepth: 100
@ -313,5 +435,5 @@
components:
- type: SpawnArtifact
maxSpawns: 1
possiblePrototypes:
- Singularity
spawns:
- id: Singularity

View File

@ -1,5 +1,25 @@
# Utility effects permanently modify the entity in some way when triggered, and they generally make it 'useful' for some purpose,
# like turning the artifact into a tool, or gun, or whatever.
- type: artifactEffect
id: EffectIntercom
targetDepth: 2
effectHint: artifact-effect-hint-communication
permanentComponents:
- type: RadioMicrophone
powerRequired: false
listenRange: 3
supportedChannels:
- Common
- CentCom
- Command
- Engineering
- Medical
- Science
- Security
- Service
- Supply
- Syndicate
- type: artifactEffect
id: EffectRandomInstrument
targetDepth: 2
@ -7,14 +27,9 @@
permanentComponents:
- type: Instrument
- type: ActivatableUI
inHandsOnly: true
singleUser: true
verbText: verb-instrument-openui
key: enum.InstrumentUiKey.Key
- type: UserInterface
interfaces:
- key: enum.InstrumentUiKey.Key
type: InstrumentBoundUserInterface
- type: RandomInstrumentArtifact
- type: artifactEffect