Ling update (#183)

* - add: Augmented Eyesight.

* - add: Dissonant Shriek.

* - tweak: Nuke use delays.

* - tweak: Tweak chemical regeneration and chemical costs.

* - add: Add chitinous helmet.

* - fix: Fix chem regeneration while dead.

* - tweak: Faster fleshmend.

* - add: Void Adaptation.

* - tweak: No lesser form delay.

* - tweak: Lesser form tweaks.

* - tweak: Stasis doafter is hidden now.

* - add: Refund after absorbing.

* - tweak: Some tweaks.
This commit is contained in:
Aviu00
2024-03-14 01:19:30 +09:00
committed by GitHub
parent 83c3df1593
commit c05a1d09c2
33 changed files with 529 additions and 130 deletions

View File

@@ -6,6 +6,8 @@ using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Cuffs;
using Content.Server.DoAfter;
using Content.Server.Emp;
using Content.Server.Flash.Components;
using Content.Server.Forensics;
using Content.Server.GameTicking.Rules;
using Content.Server.Humanoid;
@@ -19,6 +21,7 @@ using Content.Server.Store.Components;
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared._White.Chaplain;
using Content.Shared._White.Overlays;
using Content.Shared.Actions;
using Content.Shared.Changeling;
using Content.Shared.Chemistry.EntitySystems;
@@ -42,6 +45,7 @@ using Content.Shared.Pulling.Components;
using Content.Shared.Standing;
using Content.Shared.StatusEffect;
using Content.Shared.Tag;
using Robust.Server.Containers;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects.Components.Localization;
using Robust.Shared.Player;
@@ -78,6 +82,9 @@ public sealed partial class ChangelingSystem
[Dependency] private readonly CultRuleSystem _cult = default!;
[Dependency] private readonly NpcFactionSystem _faction = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly EmpSystem _empSystem = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly ContainerSystem _container = default!;
private void InitializeAbilities()
{
@@ -97,6 +104,8 @@ public sealed partial class ChangelingSystem
SubscribeLocalEvent<ChangelingComponent, AdrenalineSacsActionEvent>(OnAdrenalineSacs);
SubscribeLocalEvent<ChangelingComponent, FleshmendActionEvent>(OnFleshMend);
SubscribeLocalEvent<ChangelingComponent, BiodegradeActionEvent>(OnBiodegrade);
SubscribeLocalEvent<ChangelingComponent, AugmentedEyesightActionEvent>(OnEyesight);
SubscribeLocalEvent<ChangelingComponent, DissonantShriekActionEvent>(OnDissonantShriek);
SubscribeLocalEvent<ChangelingComponent, ArmbladeActionEvent>(OnArmBlade);
SubscribeLocalEvent<ChangelingComponent, OrganicShieldActionEvent>(OnShield);
@@ -109,6 +118,9 @@ public sealed partial class ChangelingSystem
SubscribeLocalEvent<ChangelingComponent, LesserFormDoAfterEvent>(OnLesserFormDoAfter);
SubscribeLocalEvent<ChangelingComponent, ListViewItemSelectedMessage>(OnTransformUiMessage);
SubscribeLocalEvent<ChangelingComponent, AugmentedEyesightPurchasedEvent>(OnEyesightPurchased);
SubscribeLocalEvent<ChangelingComponent, VoidAdaptationPurchasedEvent>(OnVoidAdaptationPurchased);
}
#region Data
@@ -259,7 +271,8 @@ public sealed partial class ChangelingSystem
new RegenerateDoAfterEvent(), args.Performer,
args.Performer, args.Performer)
{
RequireCanInteract = false
RequireCanInteract = false,
Hidden = true
});
component.IsRegenerating = true;
@@ -267,7 +280,7 @@ public sealed partial class ChangelingSystem
private void OnLesserForm(EntityUid uid, ChangelingComponent component, LesserFormActionEvent args)
{
if (_mobStateSystem.IsDead(uid) || component.IsRegenerating)
if (!_mobStateSystem.IsAlive(uid))
{
_popup.PopupEntity(Loc.GetString("changeling-popup-cant-perform"), uid, uid);
return;
@@ -282,7 +295,8 @@ public sealed partial class ChangelingSystem
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.Performer, component.LesserFormDelay,
new LesserFormDoAfterEvent(), args.Performer, args.Performer)
{
BreakOnUserMove = true
BreakOnUserMove = true,
RequireCanInteract = false
});
}
@@ -490,7 +504,7 @@ public sealed partial class ChangelingSystem
if (!TakeChemicals(uid, component, 20))
return;
_solutionContainer.TryAddReagent(injectable.Value, "Omnizine", 25);
_solutionContainer.TryAddReagent(injectable.Value, "Ichor", 10);
if (TryComp(uid, out BloodstreamComponent? bloodstream))
{
_blood.TryModifyBleedAmount(uid, -bloodstream.BleedAmount, bloodstream);
@@ -501,7 +515,7 @@ public sealed partial class ChangelingSystem
private void OnBiodegrade(EntityUid uid, ChangelingComponent component, BiodegradeActionEvent args)
{
if (_mobStateSystem.IsDead(uid))
if (!_mobStateSystem.IsAlive(uid))
return;
if (!TryComp(uid, out CuffableComponent? cuffs) || cuffs.Container.ContainedEntities.Count < 1)
@@ -512,7 +526,7 @@ public sealed partial class ChangelingSystem
var lastAddedCuffs = cuffs.LastAddedCuffs;
_cuffable.Uncuff(uid, lastAddedCuffs, lastAddedCuffs);
_cuffable.Uncuff(uid, null, lastAddedCuffs);
Del(lastAddedCuffs);
@@ -523,14 +537,14 @@ public sealed partial class ChangelingSystem
private void OnArmBlade(EntityUid uid, ChangelingComponent component, ArmbladeActionEvent args)
{
SpawnOrDeleteItem(uid, "ArmBlade");
SpawnOrDeleteItem(uid, component, "ArmBlade", 20);
args.Handled = true;
}
private void OnShield(EntityUid uid, ChangelingComponent component, OrganicShieldActionEvent args)
{
SpawnOrDeleteItem(uid, "OrganicShield");
SpawnOrDeleteItem(uid, component, "OrganicShield", 20);
args.Handled = true;
}
@@ -538,43 +552,83 @@ public sealed partial class ChangelingSystem
private void OnArmor(EntityUid uid, ChangelingComponent component, ChitinousArmorActionEvent args)
{
const string outerName = "outerClothing";
const string protoName = "ClothingOuterChangeling";
const string headName = "head";
const string armorName = "ClothingOuterChangeling";
const string helmetName = "ClothingHeadHelmetLing";
if (!_inventorySystem.TryGetSlotEntity(uid, outerName, out var outerEnt))
_inventorySystem.TryUnequip(uid, outerName, out var outer, true, true);
_inventorySystem.TryUnequip(uid, headName, out var helmet, true, true);
if (TryComp(outer, out MetaDataComponent? metaData) && metaData.EntityPrototype is {ID: armorName})
{
_inventorySystem.SpawnItemInSlot(uid, outerName, protoName, silent: true);
args.Handled = true;
return;
}
if (!TryComp<MetaDataComponent>(outerEnt, out var meta))
if (!TakeChemicals(uid, component, 20))
{
_inventorySystem.SpawnItemInSlot(uid, outerName, protoName, silent: true);
if (outer != null)
_inventorySystem.TryEquip(uid, outer.Value, outerName, true, true);
if (helmet != null)
_inventorySystem.TryEquip(uid, helmet.Value, headName, true, true);
return;
}
if (meta.EntityPrototype == null)
{
_inventorySystem.SpawnItemInSlot(uid, outerName, protoName, silent: true);
return;
}
if (meta.EntityPrototype.ID == protoName)
{
_inventorySystem.TryUnequip(uid, outerName, out var removedItem, force: true);
QueueDel(removedItem);
return;
}
_inventorySystem.TryUnequip(uid, outerName, out _);
_inventorySystem.SpawnItemInSlot(uid, outerName, protoName, silent: true);
_inventorySystem.SpawnItemInSlot(uid, outerName, armorName, true, true);
_inventorySystem.SpawnItemInSlot(uid, headName, helmetName, true, true);
args.Handled = true;
}
private void OnTentacleArm(EntityUid uid, ChangelingComponent component, TentacleArmActionEvent args)
{
SpawnOrDeleteItem(uid, "TentacleArmGun");
SpawnOrDeleteItem(uid, component, "TentacleArmGun", 10);
args.Handled = true;
}
private void OnEyesightPurchased(Entity<ChangelingComponent> ent, ref AugmentedEyesightPurchasedEvent args)
{
EnsureComp<FlashImmunityComponent>(ent);
EnsureComp<EyeProtectionComponent>(ent);
}
private void OnVoidAdaptationPurchased(Entity<ChangelingComponent> ent, ref VoidAdaptationPurchasedEvent args)
{
EnsureComp<VoidAdaptationComponent>(ent);
}
private void OnEyesight(Entity<ChangelingComponent> ent, ref AugmentedEyesightActionEvent args)
{
if (!_mobStateSystem.IsAlive(ent))
return;
args.Handled = true;
if (HasComp<TemporaryNightVisionComponent>(ent))
{
RemComp<TemporaryNightVisionComponent>(ent);
EnsureComp<FlashImmunityComponent>(ent);
EnsureComp<EyeProtectionComponent>(ent);
return;
}
EnsureComp<TemporaryNightVisionComponent>(ent);
RemComp<FlashImmunityComponent>(ent);
RemComp<EyeProtectionComponent>(ent);
}
private void OnDissonantShriek(Entity<ChangelingComponent> ent, ref DissonantShriekActionEvent args)
{
if (!_mobStateSystem.IsAlive(ent))
return;
if (!TakeChemicals(ent, ent.Comp, 20))
return;
_empSystem.EmpPulse(_transform.GetMapCoordinates(ent), 5, 100000, 10f);
args.Handled = true;
}
@@ -612,6 +666,20 @@ public sealed partial class ChangelingSystem
component.AbsorbedCount++;
_chemicalsSystem.AddChemicals(uid, component, 50);
if (_container.TryGetContainer(uid, ImplanterComponent.ImplantSlotId, out var implantContainer))
{
foreach (var implant in implantContainer.ContainedEntities)
{
if (!TryComp<StoreComponent>(implant, out var store) || store.Preset != "StorePresetChangeling")
continue;
store.Refunds = true;
store.RefundAllowed = true;
}
}
if (TryComp(uid, out SharedPullerComponent? puller) && puller.Pulling is { } pulled &&
TryComp(pulled, out SharedPullableComponent? pullable))
{
@@ -653,6 +721,7 @@ public sealed partial class ChangelingSystem
{
if (args.Handled || args.Cancelled || args.Target == null)
{
component.IsRegenerating = false;
return;
}
@@ -664,7 +733,10 @@ public sealed partial class ChangelingSystem
}
if (!TakeChemicals(uid, component, 15))
{
component.IsRegenerating = false;
return;
}
_rejuvenate.PerformRejuvenate(args.Target.Value);
@@ -682,14 +754,14 @@ public sealed partial class ChangelingSystem
if (args.Handled || args.Cancelled)
return;
if (!TakeChemicals(uid, component, 5))
return;
var polymorphEntity = _polymorph.PolymorphEntity(args.User, "MonkeyChangeling");
if (polymorphEntity == null)
return;
if (!TakeChemicals(uid, component, 5))
return;
var toAdd = new ChangelingComponent
{
HiveName = component.HiveName,
@@ -701,6 +773,8 @@ public sealed partial class ChangelingSystem
EntityManager.AddComponent(polymorphEntity.Value, toAdd);
TransferComponents(uid, polymorphEntity.Value);
_implantSystem.TransferImplants(uid, polymorphEntity.Value);
_actionContainerSystem.TransferAllActionsFiltered(uid, polymorphEntity.Value, polymorphEntity.Value);
_action.GrantContainedActions(polymorphEntity.Value, polymorphEntity.Value);
@@ -830,12 +904,6 @@ public sealed partial class ChangelingSystem
_identity.QueueIdentityUpdate(polymorphEntity.Value);
if (HasComp<BibleUserComponent>(target))
EnsureComp<BibleUserComponent>(polymorphEntity.Value);
if (HasComp<HolyComponent>(target))
EnsureComp<HolyComponent>(polymorphEntity.Value);
if (TryComp(target, out ChangelingComponent? lingComp))
{
var toAdd = new ChangelingComponent
@@ -850,18 +918,7 @@ public sealed partial class ChangelingSystem
_chemicalsSystem.UpdateAlert(polymorphEntity.Value, toAdd);
}
if (TryComp(target, out NpcFactionMemberComponent? factionMember))
{
_faction.ClearFactions(polymorphEntity.Value);
foreach (var faction in factionMember.Factions)
{
_faction.AddFaction(polymorphEntity.Value, faction);
}
}
_nukeOps.TransferRole(target, polymorphEntity.Value);
_cult.TransferRole(target, polymorphEntity.Value);
TransferComponents(target, polymorphEntity.Value);
_implantSystem.TransferImplants(target, polymorphEntity.Value);
_actionContainerSystem.TransferAllActionsFiltered(target, polymorphEntity.Value, polymorphEntity.Value);
@@ -870,6 +927,50 @@ public sealed partial class ChangelingSystem
return polymorphEntity;
}
private void TransferComponents(EntityUid from, EntityUid to)
{
if (HasComp<BibleUserComponent>(from))
EnsureComp<BibleUserComponent>(to);
if (HasComp<HolyComponent>(from))
EnsureComp<HolyComponent>(to);
if (HasComp<FlashImmunityComponent>(from))
EnsureComp<FlashImmunityComponent>(to);
if (HasComp<EyeProtectionComponent>(from))
EnsureComp<EyeProtectionComponent>(to);
if (HasComp<VoidAdaptationComponent>(from))
EnsureComp<VoidAdaptationComponent>(to);
if (TryComp(from, out TemporaryNightVisionComponent? nvComp))
{
var toAdd = new TemporaryNightVisionComponent
{
Color = nvComp.Color,
Tint = nvComp.Tint,
Strength = nvComp.Strength,
Noise = nvComp.Noise
};
EntityManager.AddComponent(to, toAdd);
}
if (TryComp(from, out NpcFactionMemberComponent? factionMember))
{
_faction.ClearFactions(to);
foreach (var faction in factionMember.Factions)
{
_faction.AddFaction(to, faction);
}
}
_nukeOps.TransferRole(from, to);
_cult.TransferRole(from, to);
}
private void TransferDna(EntityUid target, string dna)
{
if (!TryComp<DnaComponent>(target, out var dnaComponent))
@@ -932,7 +1033,7 @@ public sealed partial class ChangelingSystem
Dirty(target, targetHumanoid);
}
private void SpawnOrDeleteItem(EntityUid target, string prototypeName)
private void SpawnOrDeleteItem(EntityUid target, ChangelingComponent component, string prototypeName, int chemicals)
{
foreach (var eHand in _handsSystem.EnumerateHands(target))
{
@@ -952,6 +1053,9 @@ public sealed partial class ChangelingSystem
return;
}
if (!TakeChemicals(target, component, chemicals))
return;
var item = Spawn(prototypeName, Transform(target).Coordinates);
if (!_handsSystem.TryPickup(target, item, hand, animate: false))