diff --git a/Content.Server/Store/Systems/StoreSystem.Refund.cs b/Content.Server/Store/Systems/StoreSystem.Refund.cs index 04bd585ffcf75e..8f3b9a62ea1ce6 100644 --- a/Content.Server/Store/Systems/StoreSystem.Refund.cs +++ b/Content.Server/Store/Systems/StoreSystem.Refund.cs @@ -19,7 +19,7 @@ private void OnEntityRemoved(EntityUid uid, StoreRefundComponent component, EntR if (component.StoreEntity == null || _actions.TryGetActionData(uid, out _, false) || !TryComp(component.StoreEntity.Value, out var storeComp)) return; - DisableRefund(component.StoreEntity.Value, storeComp); + DisableRefund(uid, component.StoreEntity.Value, storeComp); } private void OnEntityInserted(EntityUid uid, StoreRefundComponent component, EntInsertedIntoContainerMessage args) @@ -27,7 +27,7 @@ private void OnEntityInserted(EntityUid uid, StoreRefundComponent component, Ent if (component.StoreEntity == null || _actions.TryGetActionData(uid, out _) || !TryComp(component.StoreEntity.Value, out var storeComp)) return; - DisableRefund(component.StoreEntity.Value, storeComp); + DisableRefund(uid, component.StoreEntity.Value, storeComp); } private void OnStoreTerminating(Entity ent, ref EntityTerminatingEvent args) diff --git a/Content.Server/Store/Systems/StoreSystem.Ui.cs b/Content.Server/Store/Systems/StoreSystem.Ui.cs index 6719035d09a9f0..62b80d7578371c 100644 --- a/Content.Server/Store/Systems/StoreSystem.Ui.cs +++ b/Content.Server/Store/Systems/StoreSystem.Ui.cs @@ -385,6 +385,9 @@ private void OnRequestRefund(EntityUid uid, StoreComponent component, StoreReque RefreshAllListings(component); component.BalanceSpent = new(); UpdateUserInterface(buyer, uid, component); + + var ev = new StoreRefundedEvent(); + RaiseLocalEvent(uid, ref ev, true); } private void HandleRefundComp(EntityUid uid, StoreComponent component, EntityUid purchase) @@ -400,15 +403,30 @@ private bool IsOnStartingMap(EntityUid store, StoreComponent component) return component.StartingMap == xform.MapUid; } + /// + /// Enables refunds for this store + /// + public void EnableRefund(EntityUid buyer, EntityUid store, StoreComponent? component = null) + { + if (!Resolve(store, ref component)) + return; + + component.RefundAllowed = true; + + UpdateUserInterface(buyer, store, component); + } + /// /// Disables refunds for this store /// - public void DisableRefund(EntityUid store, StoreComponent? component = null) + public void DisableRefund(EntityUid buyer, EntityUid store, StoreComponent? component = null) { if (!Resolve(store, ref component)) return; component.RefundAllowed = false; + + UpdateUserInterface(buyer, store, component); } } diff --git a/Content.Server/_Goobstation/Changeling/ChangelingSystem.Abilities.cs b/Content.Server/_Goobstation/Changeling/ChangelingSystem.Abilities.cs index a0e8564a17ab93..6fb69138a249f3 100644 --- a/Content.Server/_Goobstation/Changeling/ChangelingSystem.Abilities.cs +++ b/Content.Server/_Goobstation/Changeling/ChangelingSystem.Abilities.cs @@ -163,22 +163,20 @@ private void OnAbsorbDoAfter(EntityUid uid, ChangelingComponent comp, ref Absorb var popupOthers = Loc.GetString("changeling-absorb-end-others", ("user", Identity.Entity(uid, EntityManager)), ("target", Identity.Entity(target, EntityManager))); var bonusChemicals = 0f; - var bonusEvolutionPoints = 0f; + var bonusEvolutionPoints = 0; if (TryComp(target, out var targetComp)) { popupSelf = Loc.GetString("changeling-absorb-end-self-ling", ("target", Identity.Entity(target, EntityManager))); bonusChemicals += targetComp.MaxChemicals / 2; - bonusEvolutionPoints += 10; + bonusEvolutionPoints += 2; comp.MaxBiomass += targetComp.MaxBiomass / 2; } else { bonusChemicals += 10; - if (!reducedBiomass) - bonusEvolutionPoints += 2; - else + if (reducedBiomass) popupSelf = Loc.GetString("changeling-absorb-end-self-reduced-biomass", ("target", Identity.Entity(target, EntityManager))); } @@ -189,11 +187,13 @@ private void OnAbsorbDoAfter(EntityUid uid, ChangelingComponent comp, ref Absorb TryStealDNA(uid, target, comp, true); comp.TotalAbsorbedEntities++; comp.MaxChemicals += bonusChemicals; + comp.MaxEvolutionPoints += bonusEvolutionPoints; if (TryComp(args.User, out var store)) { _store.TryAddCurrency(new Dictionary { { "EvolutionPoint", bonusEvolutionPoints } }, args.User, store); _store.UpdateUserInterface(args.User, args.User, store); + _store.EnableRefund(uid, args.User, store); } if (_mind.TryGetMind(uid, out var mindId, out var mind)) diff --git a/Content.Server/_Goobstation/Changeling/ChangelingSystem.cs b/Content.Server/_Goobstation/Changeling/ChangelingSystem.cs index f6a10daa3e2cc4..a0bba7367b55ae 100644 --- a/Content.Server/_Goobstation/Changeling/ChangelingSystem.cs +++ b/Content.Server/_Goobstation/Changeling/ChangelingSystem.cs @@ -56,6 +56,8 @@ using Content.Shared.Jittering; using Content.Server.Explosion.EntitySystems; using System.Linq; +using Content.Server.Flash.Components; +using Content.Shared.Stealth.Components; namespace Content.Server.Changeling; @@ -122,9 +124,10 @@ public override void Initialize() SubscribeLocalEvent(OnMobStateChange); SubscribeLocalEvent(OnDamageChange); SubscribeLocalEvent(OnComponentRemove); - SubscribeLocalEvent(OnRefreshSpeed); + SubscribeLocalEvent(OnStoreRefunded); + SubscribeAbilities(); } @@ -631,15 +634,31 @@ public bool TryTransform(EntityUid target, ChangelingComponent comp, bool sting public void RemoveAllChangelingEquipment(EntityUid target, ChangelingComponent comp) { - // check if there's no entities or all entities are null - if (comp.Equipment.Values.Count == 0 - || comp.Equipment.Values.All(ent => ent == null ? true : false)) - return; + var playSound = false; + + // check if there's no entities in equipment, or all entities are null + if (comp.Equipment.Values.Count != 0 + || comp.Equipment.Values.All(ent => ent == null ? false : true)) + { + foreach (var equip in comp.Equipment.Values) + QueueDel(equip); + + comp.Equipment.Clear(); + playSound = true; + } + + // check if there's no entities in armor, or all entities are null + if (comp.ActiveArmor != null) + { + foreach (var armor in comp.ActiveArmor) + QueueDel(armor); - foreach (var equip in comp.Equipment.Values) - QueueDel(equip); + comp.ActiveArmor = null; + playSound = true; + } - PlayMeatySound(target, comp); + if (playSound) + PlayMeatySound(target, comp); } #endregion @@ -694,5 +713,25 @@ private void OnComponentRemove(Entity ent, ref ComponentRem RemoveAllChangelingEquipment(ent, ent.Comp); } + private void OnStoreRefunded(Entity ent, ref StoreRefundedEvent args) + { + var comp = EnsureComp(ent); + + RemoveAllChangelingEquipment(ent, comp); + comp.StrainedMusclesActive = false; + RemComp(ent); // augmented vision, yes this sucks. refactor one day i prommy - last online 9740 days ago + RemComp(ent); // chameleon skin. as above + RemComp(ent); // chameleon skin + + if (HasComp(ent)) + { + RemComp(ent); + _popup.PopupEntity(Loc.GetString("changeling-hivemind-end"), ent, ent, PopupType.MediumCaution); + } + + _speed.RefreshMovementSpeedModifiers(ent); + _store.DisableRefund(ent.Owner, ent, ent.Comp); + } + #endregion } diff --git a/Content.Server/_Goobstation/GameTicking/Rules/ChangelingRuleSystem.cs b/Content.Server/_Goobstation/GameTicking/Rules/ChangelingRuleSystem.cs index a1777ad61e6b7a..b34c7d82d47044 100644 --- a/Content.Server/_Goobstation/GameTicking/Rules/ChangelingRuleSystem.cs +++ b/Content.Server/_Goobstation/GameTicking/Rules/ChangelingRuleSystem.cs @@ -70,14 +70,14 @@ public bool MakeChangeling(EntityUid target, ChangelingRuleComponent rule) _npcFaction.AddFaction(target, ChangelingFactionId); // make sure it's initial chems are set to max - EnsureComp(target); + var changelingComp = EnsureComp(target); // add store var store = EnsureComp(target); foreach (var category in rule.StoreCategories) store.Categories.Add(category); store.CurrencyWhitelist.Add(Currency); - store.Balance.Add(Currency, 16); + store.Balance.Add(Currency, changelingComp.MaxEvolutionPoints); rule.ChangelingMinds.Add(mindId); diff --git a/Content.Shared/Store/Components/StoreComponent.cs b/Content.Shared/Store/Components/StoreComponent.cs index 49d5614593edf3..281ba7edac655d 100644 --- a/Content.Shared/Store/Components/StoreComponent.cs +++ b/Content.Shared/Store/Components/StoreComponent.cs @@ -111,6 +111,19 @@ public sealed partial class StoreComponent : Component /// [ByRefEvent] public readonly record struct StoreRemovedEvent; +/// +/// Event that is broadcast when a store is refunded +/// +[ByRefEvent] +public readonly struct StoreRefundedEvent +{ + public EntityUid Uid { get; } + + public StoreRefundedEvent(EntityUid uid) + { + Uid = uid; + } +} /// /// Broadcast when an Entity with the is deleted diff --git a/Content.Shared/_Goobstation/Changeling/ChangelingComponent.cs b/Content.Shared/_Goobstation/Changeling/ChangelingComponent.cs index 087e061da9f395..28c7d9bd22e574 100644 --- a/Content.Shared/_Goobstation/Changeling/ChangelingComponent.cs +++ b/Content.Shared/_Goobstation/Changeling/ChangelingComponent.cs @@ -103,6 +103,9 @@ public sealed partial class ChangelingComponent : Component public float BiomassUpdateTimer = 0f; public float BiomassUpdateCooldown = 60f; + [DataField, AutoNetworkedField] + public int MaxEvolutionPoints = 10; + [ViewVariables(VVAccess.ReadOnly)] public List AbsorbedDNA = new(); /// diff --git a/Resources/Locale/en-US/_Goobstation/changeling/abilities/changeling.ftl b/Resources/Locale/en-US/_Goobstation/changeling/abilities/changeling.ftl index 8c6edd69c6dcd1..87bfc715531d47 100644 --- a/Resources/Locale/en-US/_Goobstation/changeling/abilities/changeling.ftl +++ b/Resources/Locale/en-US/_Goobstation/changeling/abilities/changeling.ftl @@ -70,3 +70,4 @@ changeling-chameleon-start = We adapt our skin to the environment. changeling-chameleon-end = Our skin no longer blends in. changeling-hivemind-start = We attune our brainwaves to match the greater hivemind. +changeling-hivemind-end = Our connection to the greater hivemind is severed. diff --git a/Resources/Prototypes/_Goobstation/Changeling/Catalog/changeling_catalog.yml b/Resources/Prototypes/_Goobstation/Changeling/Catalog/changeling_catalog.yml index bdf109c3f7af16..05273f75bc7ae3 100644 --- a/Resources/Prototypes/_Goobstation/Changeling/Catalog/changeling_catalog.yml +++ b/Resources/Prototypes/_Goobstation/Changeling/Catalog/changeling_catalog.yml @@ -1,4 +1,4 @@ -# combat +# Combat - type: listing id: EvolutionMenuCombatArmblade @@ -7,7 +7,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: armblade } productAction: ActionToggleArmblade cost: - EvolutionPoint: 4 + EvolutionPoint: 2 categories: - ChangelingAbilityCombat conditions: @@ -21,7 +21,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: bone_shard } productAction: ActionCreateBoneShard cost: - EvolutionPoint: 3 + EvolutionPoint: 2 categories: - ChangelingAbilityCombat conditions: @@ -35,7 +35,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: chitinous_armor } productAction: ActionToggleChitinousArmor cost: - EvolutionPoint: 4 + EvolutionPoint: 1 categories: - ChangelingAbilityCombat conditions: @@ -49,7 +49,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: organic_shield } productAction: ActionToggleOrganicShield cost: - EvolutionPoint: 2 + EvolutionPoint: 1 categories: - ChangelingAbilityCombat conditions: @@ -63,7 +63,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: shriek_dissonant } productAction: ActionShriekDissonant cost: - EvolutionPoint: 2 + EvolutionPoint: 1 categories: - ChangelingAbilityCombat conditions: @@ -77,7 +77,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: shriek_resonant } productAction: ActionShriekResonant cost: - EvolutionPoint: 2 + EvolutionPoint: 1 categories: - ChangelingAbilityCombat conditions: @@ -91,7 +91,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: strained_muscles } productAction: ActionToggleStrainedMuscles cost: - EvolutionPoint: 2 + EvolutionPoint: 1 categories: - ChangelingAbilityCombat conditions: @@ -112,7 +112,7 @@ # - !type:ListingLimitedStockCondition # stock: 1 -# sting +# Sting - type: listing id: EvolutionMenuStingBlind @@ -121,7 +121,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: sting_blind } productAction: ActionStingBlind cost: - EvolutionPoint: 4 + EvolutionPoint: 2 categories: - ChangelingAbilitySting conditions: @@ -135,7 +135,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: sting_cryo } productAction: ActionStingCryo cost: - EvolutionPoint: 4 + EvolutionPoint: 2 categories: - ChangelingAbilitySting conditions: @@ -149,7 +149,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: sting_lethargic } productAction: ActionStingLethargic cost: - EvolutionPoint: 4 + EvolutionPoint: 2 categories: - ChangelingAbilitySting conditions: @@ -163,7 +163,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: sting_mute } productAction: ActionStingMute cost: - EvolutionPoint: 4 + EvolutionPoint: 2 categories: - ChangelingAbilitySting conditions: @@ -177,7 +177,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: sting_armblade } productAction: ActionStingFakeArmblade cost: - EvolutionPoint: 5 + EvolutionPoint: 1 categories: - ChangelingAbilitySting conditions: @@ -198,7 +198,7 @@ # - !type:ListingLimitedStockCondition # stock: 1 -# utility +# Utility - type: listing id: EvolutionMenuUtilityPanacea @@ -207,7 +207,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: anatomic_panacea } productAction: ActionAnatomicPanacea cost: - EvolutionPoint: 2 + EvolutionPoint: 1 categories: - ChangelingAbilityUtility conditions: @@ -221,7 +221,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: augmented_eyesight } productAction: ActionAugmentedEyesight cost: - EvolutionPoint: 4 + EvolutionPoint: 2 categories: - ChangelingAbilityUtility conditions: @@ -235,7 +235,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: biodegrade } productAction: ActionBiodegrade cost: - EvolutionPoint: 4 + EvolutionPoint: 2 categories: - ChangelingAbilityUtility conditions: @@ -263,7 +263,8 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: epinephrine_overdose } productAction: ActionEphedrineOverdose cost: - EvolutionPoint: 4 + # i'm a hater and this will get removed down the line anyway. it's strictly superior to strained muscles + EvolutionPoint: 3 categories: - ChangelingAbilityUtility conditions: @@ -277,7 +278,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: fleshmend } productAction: ActionFleshmend cost: - EvolutionPoint: 5 + EvolutionPoint: 2 categories: - ChangelingAbilityUtility conditions: @@ -291,7 +292,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: last_resort } productAction: ActionLastResort cost: - EvolutionPoint: 2 + EvolutionPoint: 1 categories: - ChangelingAbilityUtility conditions: @@ -305,7 +306,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: lesser_form } productAction: ActionToggleLesserForm cost: - EvolutionPoint: 2 + EvolutionPoint: 1 categories: - ChangelingAbilityUtility conditions: @@ -319,7 +320,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: space_adaptation } productAction: ActionToggleSpacesuit cost: - EvolutionPoint: 4 + EvolutionPoint: 2 categories: - ChangelingAbilityUtility conditions: @@ -333,7 +334,7 @@ icon: { sprite: _Goobstation/Changeling/changeling_abilities.rsi, state: hivemind_access } productAction: ActionHivemindAccess cost: - EvolutionPoint: 2 + EvolutionPoint: 1 categories: - ChangelingAbilityUtility conditions: