Timestop spell (#370)

* - tweak: Tweak mindswap.

* - fix: Mindswap and cult fixes.

* - add: Timestop v1.

* - add: Timestop spell.

* - remove: What?

* - fix: Fixes.
This commit is contained in:
Aviu00
2024-06-20 16:24:10 +00:00
committed by GitHub
parent fd06a8b1d3
commit 6a7ad10d72
23 changed files with 446 additions and 71 deletions

View File

@@ -29,6 +29,7 @@ using Content.Shared._White.Mood;
using Content.Shared.Cloning;
using Content.Shared.Mind;
using Content.Shared.NPC.Systems;
using Robust.Server.Containers;
using Robust.Server.Player;
namespace Content.Server._White.Cult.GameRule;
@@ -50,6 +51,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly GulagSystem _gulag = default!;
[Dependency] private readonly BloodSpearSystem _bloodSpear = default!;
[Dependency] private readonly ContainerSystem _container = default!;
private const int PlayerPerCultist = 10;
private int _minStartingCultists;
@@ -160,22 +162,18 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
private void OnCultistComponentInit(EntityUid uid, CultistComponent component, ComponentInit args)
{
RaiseLocalEvent(uid, new MoodEffectEvent("CultFocused"));
var query = QueryActiveRules();
while (query.MoveNext(out _, out var cult, out _))
{
if (!TryComp<MindContainerComponent>(uid, out var mindComponent))
return;
if (!mindComponent.HasMind)
return;
cult.CurrentCultists.Add(component);
var name = Name(uid);
if (TryComp<ActorComponent>(uid, out var actor) && !cult.CultistsCache.ContainsKey(name))
if (TryComp<ActorComponent>(uid, out var actor))
{
cult.CultistsCache.Add(name, actor.PlayerSession.Name);
cult.CultistsCache.TryAdd(name, actor.PlayerSession.Name);
}
UpdateCultistsAppearance(cult);
@@ -203,17 +201,23 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
while (query.MoveNext(out _, out var cult, out _))
{
cult.CurrentCultists.Remove(component);
_bloodSpear.DetachSpearFromUser((uid, component));
foreach (var empower in component.SelectedEmpowers)
{
_actions.RemoveAction(uid, GetEntity(empower));
}
RemoveCultistAppearance(uid);
CheckRoundShouldEnd();
}
if (!TerminatingOrDeleted(uid))
{
RemoveAllCultistItems(uid);
RemoveCultistAppearance(uid);
RaiseLocalEvent(uid, new MoodRemoveEffectEvent("CultFocused"));
}
_bloodSpear.DetachSpearFromUser((uid, component));
foreach (var empower in component.SelectedEmpowers)
{
_actions.RemoveAction(uid, GetEntity(empower));
}
CheckRoundShouldEnd();
}
private void OnCultistsStateChanged(EntityUid uid, CultistComponent component, MobStateChangedEvent ev)
@@ -422,8 +426,6 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
_factionSystem.RemoveFaction(cultist, "NanoTrasen", false);
_factionSystem.AddFaction(cultist, "Cultist");
RaiseLocalEvent(cultist, new MoodEffectEvent("CultFocused"));
if (_inventorySystem.TryGetSlotEntity(cultist, "back", out var backPack))
{
foreach (var itemPrototype in rule.StartingItems)
@@ -442,6 +444,20 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
return true;
}
private void RemoveAllCultistItems(EntityUid uid)
{
if (!_inventorySystem.TryGetContainerSlotEnumerator(uid, out var enumerator))
return;
while (enumerator.MoveNext(out var container))
{
if (container.ContainedEntity != null && HasComp<CultItemComponent>(container.ContainedEntity.Value))
{
_container.Remove(container.ContainedEntity.Value, container, true, true);
}
}
}
public void TransferRole(EntityUid transferFrom, EntityUid transferTo)
{
if (HasComp<PentagramComponent>(transferFrom))

View File

@@ -1,18 +1,11 @@
using System.Threading;
using Content.Server._White.Cult.GameRule;
using Content.Server.Objectives.Components;
using Content.Server.Popups;
using Content.Server.Roles;
using Content.Server.Stunnable;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory;
using Content.Shared._White.Cult.Components;
using Content.Shared._White.Mood;
using Content.Shared.Jittering;
using Content.Shared.Mind;
using JetBrains.Annotations;
using Robust.Server.Containers;
using Robust.Shared.Prototypes;
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
using Timer = Robust.Shared.Timing.Timer;
@@ -60,26 +53,10 @@ public sealed partial class DeconvertCultist : ReagentEffect
cultist.HolyConvertToken = null;
var inventory = entityManager.System<InventorySystem>();
var containerSystem = entityManager.System<ContainerSystem>();
if (!inventory.TryGetContainerSlotEnumerator(uid, out var enumerator))
return;
while (enumerator.MoveNext(out var container))
{
if (container.ContainedEntity != null &&
entityManager.HasComponent<CultItemComponent>(container.ContainedEntity.Value))
{
containerSystem.Remove(container.ContainedEntity.Value, container, true, true);
}
}
entityManager.RemoveComponent<CultistComponent>(uid);
entityManager.RemoveComponent<PentagramComponent>(uid);
var cultRuleSystem = entityManager.System<CultRuleSystem>();
cultRuleSystem.RemoveObjectiveAndRole(uid);
entityManager.EventBus.RaiseLocalEvent(uid, new MoodRemoveEffectEvent("CultFocused"));
}
}

View File

@@ -10,4 +10,7 @@ public sealed partial class CultRobeModifierComponent : Component
public string DamageModifierSetId = "CultRobe";
public string? StoredDamageSetId { get; set; }
[ViewVariables]
public bool Active;
}

View File

@@ -29,18 +29,22 @@ public sealed class CultRobeModifierSystem : EntitySystem
if (args.Slot != "outerClothing")
return;
component.Active = true;
ModifySpeed(args.Equipee, component, true);
ModifyDamage(args.Equipee, component, true);
}
private void OnUnequip(EntityUid uid, CultRobeModifierComponent component, GotUnequippedEvent args)
{
if (!HasComp<CultistComponent>(args.Equipee))
if (!component.Active)
return;
if (args.Slot != "outerClothing")
return;
component.Active = false;
ModifySpeed(args.Equipee, component, false);
ModifyDamage(args.Equipee, component, false);
}

View File

@@ -1,5 +1,6 @@
using System.Linq;
using System.Numerics;
using Content.Server._White.Cult;
using Content.Server._White.IncorporealSystem;
using Content.Server._White.Wizard.Magic.Amaterasu;
using Content.Server._White.Wizard.Magic.Other;
@@ -24,7 +25,6 @@ using Content.Shared._White.Wizard;
using Content.Shared._White.Wizard.Magic;
using Content.Shared.Actions;
using Content.Shared.Borer;
using Content.Shared.Changeling;
using Content.Shared.Cluwne;
using Content.Shared.Coordinates.Helpers;
using Content.Shared.Hands.Components;
@@ -36,6 +36,7 @@ using Content.Shared.Inventory.VirtualItem;
using Content.Shared.Item;
using Content.Shared.Magic;
using Content.Shared.Maps;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Physics;
using Content.Shared.Popups;
@@ -85,6 +86,7 @@ public sealed class WizardSpellsSystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<StopTimeSpellEvent>(OnTimeStop);
SubscribeLocalEvent<MindswapSpellEvent>(OnMindswapSpell);
SubscribeLocalEvent<TeleportSpellEvent>(OnTeleportSpell);
SubscribeLocalEvent<InstantRecallSpellEvent>(OnInstantRecallSpell);
@@ -103,6 +105,25 @@ public sealed class WizardSpellsSystem : EntitySystem
SubscribeLocalEvent<MagicComponent, BeforeCastSpellEvent>(OnBeforeCastSpell);
}
#region Timestop
private void OnTimeStop(StopTimeSpellEvent msg)
{
if (!CanCast(msg))
return;
var ent = Spawn(msg.Prototype, Transform(msg.Performer).Coordinates);
_transformSystem.AttachToGridOrMap(ent);
var comp = EnsureComp<PreventCollideComponent>(ent);
comp.Uid = msg.Performer;
msg.Handled = true;
Speak(msg);
}
#endregion
#region Mindswap
private void OnMindswapSpell(MindswapSpellEvent msg)
@@ -113,17 +134,12 @@ public sealed class WizardSpellsSystem : EntitySystem
var target = msg.Target;
var uid = msg.Performer;
if (HasComp<ChangelingComponent>(target) || HasComp<RevolutionaryComponent>(target) ||
HasComp<CultistComponent>(target))
{
_popupSystem.PopupEntity("Не работает на культистов, генокрадов и революционеров.", uid, uid,
PopupType.MediumCaution);
if (!TryComp(target, out MobStateComponent? mobState) || mobState.CurrentState != MobState.Alive)
return;
}
if (TryComp(target, out InfestedBorerComponent? borer) && borer.ControllingBrain)
{
_popupSystem.PopupEntity("Им уже кто-то управляет.", uid, uid, PopupType.MediumCaution);
_popupSystem.PopupEntity(Loc.GetString("mindswap-borer-failed"), uid, uid, PopupType.MediumCaution);
return;
}
@@ -138,7 +154,7 @@ public sealed class WizardSpellsSystem : EntitySystem
if (targetHasMind)
{
_mindSystem.TransferTo(targetMindId, uid, mind: targetMind);
_popupSystem.PopupEntity(Loc.GetString("Ваш разум подменили!"), uid, uid, PopupType.LargeCaution);
_popupSystem.PopupEntity(Loc.GetString("mindswap-success"), uid, uid, PopupType.LargeCaution);
}
TransferAllMagicActions(uid, target);
@@ -149,23 +165,11 @@ public sealed class WizardSpellsSystem : EntitySystem
msg.Handled = true;
Speak(msg);
var hasWiz = HasComp<WizardComponent>(uid);
var targetHasWiz = HasComp<WizardComponent>(target);
if (hasWiz == targetHasWiz)
return;
if (hasWiz)
{
RemComp<WizardComponent>(uid);
EnsureComp<WizardComponent>(target);
}
if (targetHasWiz)
{
RemComp<WizardComponent>(target);
EnsureComp<WizardComponent>(uid);
}
SwapComponent<WizardComponent>(uid, target);
SwapComponent<RevolutionaryComponent>(uid, target);
SwapComponent<HeadRevolutionaryComponent>(uid, target);
SwapComponent<PentagramComponent>(uid, target);
SwapComponent<CultistComponent>(uid, target);
}
#endregion
@@ -919,5 +923,26 @@ public sealed class WizardSpellsSystem : EntitySystem
}
}
private void SwapComponent<T>(EntityUid uid1, EntityUid uid2) where T : Component, new()
{
var hasComp = HasComp<T>(uid1);
var targetHasComp = HasComp<T>(uid2);
if (hasComp == targetHasComp)
return;
if (hasComp)
{
EnsureComp<T>(uid2);
RemComp<T>(uid1);
}
if (targetHasComp)
{
EnsureComp<T>(uid1);
RemComp<T>(uid2);
}
}
#endregion
}