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:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user