mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-10-10 08:17:31 +00:00
* Nubody (#42419) * Nubody * fix test fails * gibbing * lung test returns * doc comment * hand organ test * giblet test * yaml formatting * returning * relocate * trimming * re-smite * oops thusd tweak * arachnids have slower metabolism i guess * never mind the old behaviour is bad actually * rider whyyy * style changes and allat * fix collision --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> * C# files done * Visual nubody (humanoid appearance refactor) (#42476) * initial visual nubody * oops overlay * im so pheeming rn * conversion... * tests * comeback of the underwear * oops eyes * blabbl * zeds * yaml linted * search and visible count constraints * reordering * preserve previously selected markings colors * fix test * some ui niceties * ordering * make DB changes backwards-compatible/downgrade-friendly * fix things again * fix migration * vulpkanin markings limit increase * wrapping * code cleanup and more code cleanup and more code cleanup and more code cleanup and * fix slop ports * better sampling API * make filter work + use the method i made for its intended purpose * fix test fails real quick * magic mirror cleanup, remove TODO * don't 0-init the organ profile data * remove deltastates --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> * Let vox eat trash again (#42503) * C# complete port * Getting closer * Harpy Nubody Port * Port Feroxi, Kitsune. Fix some yml typos and remove ipcs stuff * Port Oni * Port Rest, except Motorkind * Port Motorkind * Remove more surgery, restore too much deleted stuff * Fix Typos and change some organ names. Need to split eyes next * Harpy HAve Wings again * Some fixes, More Surgeyr Removal, Copying of eye organs * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Use correct Body imports * Markings Refactoring, Harpy Layering * Motorkind doesn't crash anymore. Some layer remappings. * Allow Organs to have Markings Displacements again. (#43604) * first shtep * readd markings support --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> * Fix STalk eyes and several layerings * Fix sexed organs (#42554) * Fix markings for several species, fit them for sexed organs and rename some files to fit them for it * Additional IPC-related removals * Vulpkanin eyes are now correct again * Fix Subtle Cultist Marks on species * Fix Asakim Sprites (sexed) and make CD imports work * Migration, error fixes, and Height * Fix humanoid profile voice being broken (#42550) Fix humanoid appearance voice being broken * Change Kitsune SexChanged Event to with ref * Fix asakim issue, Respirator fix * Simplify hands UI code (#42534) * Simplify hands UI code * i remembered about SortedHands in the component * minor cleanup --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> * Set size of Analyzer back to 350, Kitsune can't gib themselves no more. Migration * yml linter errors and an rudimentary onAdd Organ Functionality * Fixing it trying to remove nothing * midpoint migration * Why do you put so many organs everywhere * More missing prototypes * Migration of more organs * Forgot lungs * Move character preview handling into a specialized control (#41252) * Move character preview handling into a specialized control Co-authored-by: Quantum-cross <7065792+Quantum-cross@users.noreply.github.com> * Restore job name that I accidentally removed from character picker buttons * Just resolve dependencies the standard way --------- Co-authored-by: Quantum-cross <7065792+Quantum-cross@users.noreply.github.com> Co-authored-by: Janet Blackquill <uhhadd@gmail.com> * Drop ICharacterProfile/ICharacterAppearance interfaces (#42661) * Ensure profile loading only returns valid species (#42842) (Stable merge) (#42865) Co-authored-by: pathetic meowmeow <uhhadd@gmail.com> * Changes to make it work for us. * No more bald Harpy * OperatingTables instead of null * Adding Delta V Comments, commenting out instead of deleting * Fix broken Height Scale. * Remove HumanoidSilicon Mention * Did an error. Readded, uncommented. * Clean up Marking data structure, add tests for Zombie transformation (#42756) * Clean up Marking data structure, add tests for Zombie transformation * empty * AAAAAAAAAAAAAAAA --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> * Fix markings colour setting (#42771) * Fix: Markings Color For Downstream * Comment out A Leg. Remove Todo * Revert to original hidden species code --------- Co-authored-by: pathetic meowmeow <uhhadd@gmail.com> Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Co-authored-by: Absotively <jen@jenpollock.ca> Co-authored-by: Quantum-cross <7065792+Quantum-cross@users.noreply.github.com> Co-authored-by: Myra <vasilis@pikachu.systems>
512 lines
18 KiB
C#
512 lines
18 KiB
C#
// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
|
|
// SPDX-FileCopyrightText: 2025 Solstice <solsticeofthewinter@gmail.com>
|
|
// SPDX-FileCopyrightText: 2025 SolsticeOfTheWinter <solsticeofthewinter@gmail.com>
|
|
// SPDX-FileCopyrightText: 2025 coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
|
// SPDX-FileCopyrightText: 2025 gluesniffler <159397573+gluesniffler@users.noreply.github.com>
|
|
// SPDX-FileCopyrightText: 2025 gluesniffler <linebarrelerenthusiast@gmail.com>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using Content.Shared._Goobstation.Paper;
|
|
using Content.Server._Goobstation.Devil.Objectives.Components;
|
|
using Content.Server._Goobstation.Possession;
|
|
using Content.Shared._Goobstation.Devil;
|
|
using Content.Shared._Goobstation.Devil.Condemned;
|
|
using Content.Shared._Goobstation.Devil.Contract;
|
|
using Content.Server.Explosion.EntitySystems;
|
|
using Content.Server.Hands.Systems;
|
|
using Content.Server.Implants;
|
|
using Content.Server.Mind;
|
|
using Content.Server.Polymorph.Systems;
|
|
using Content.Shared.Damage.Systems;
|
|
using Content.Shared.Examine;
|
|
using Content.Shared.Mindshield.Components;
|
|
using Content.Shared.Nutrition;
|
|
using Content.Shared.Paper;
|
|
using Content.Shared.Popups;
|
|
using Content.Shared.Silicons.Borgs.Components;
|
|
using Content.Shared.Verbs;
|
|
using Robust.Shared.Audio;
|
|
using Robust.Shared.Audio.Systems;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Random;
|
|
using Robust.Shared.Utility;
|
|
using Content.Shared._EE.Silicon.Components;
|
|
using Content.Shared.StatusEffectNew; // DeltaV - Clause status effects
|
|
|
|
namespace Content.Server._Goobstation.Devil.Contract;
|
|
|
|
public sealed partial class DevilContractSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedPopupSystem _popupSystem = null!;
|
|
[Dependency] private readonly DamageableSystem _damageable = null!;
|
|
[Dependency] private readonly HandsSystem _hands = null!;
|
|
[Dependency] private readonly SharedAudioSystem _audio = null!;
|
|
[Dependency] private readonly IPrototypeManager _prototypeManager = null!;
|
|
[Dependency] private readonly IRobustRandom _random = null!;
|
|
[Dependency] private readonly SubdermalImplantSystem _implant = null!;
|
|
[Dependency] private readonly PolymorphSystem _polymorph = null!;
|
|
[Dependency] private readonly ExplosionSystem _explosion = null!;
|
|
[Dependency] private readonly MindSystem _mind = null!;
|
|
[Dependency] private readonly StatusEffectsSystem _statusEffects = null!; // DeltaV - Clause status effects
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
InitializeRegex();
|
|
InitializeSpecialActions();
|
|
|
|
SubscribeLocalEvent<DevilContractComponent, BeingSignedAttemptEvent>(OnContractSignAttempt);
|
|
SubscribeLocalEvent<DevilContractComponent, ExaminedEvent>(OnExamined);
|
|
SubscribeLocalEvent<DevilContractComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerbs);
|
|
SubscribeLocalEvent<DevilContractComponent, SignSuccessfulEvent>(OnSignStep);
|
|
SubscribeLocalEvent<DevilContractComponent, FullyEatenEvent>(OnEaten);
|
|
}
|
|
|
|
private readonly Dictionary<LocId, Func<DevilContractComponent, EntityUid?>> _targetResolvers = new()
|
|
{
|
|
// The contractee is who is making the deal.
|
|
["devil-contract-contractee"] = comp => comp.Signer,
|
|
// The contractor is the entity offering the deal.
|
|
["devil-contract-contractor"] = comp => comp.ContractOwner,
|
|
};
|
|
|
|
private Regex _clauseRegex = null!;
|
|
|
|
private void InitializeRegex()
|
|
{
|
|
var escapedPatterns = _targetResolvers.Keys.Select(locId => Loc.GetString(locId)).ToList(); // malicious linq and regex
|
|
var targetPattern = string.Join("|", escapedPatterns);
|
|
|
|
_clauseRegex = new Regex($@"^\s*(?<target>{targetPattern})\s*:\s*(?<clause>.+?)\s*$",
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline);
|
|
}
|
|
private void OnGetVerbs(Entity<DevilContractComponent> contract, ref GetVerbsEvent<AlternativeVerb> args)
|
|
{
|
|
if (!args.CanInteract
|
|
|| !args.CanAccess
|
|
|| !TryComp<DevilComponent>(args.User, out var devilComp))
|
|
return;
|
|
|
|
var user = args.User;
|
|
|
|
AlternativeVerb burnVerb = new()
|
|
{
|
|
Act = () => TryBurnContract(contract, (user, devilComp)),
|
|
Text = Loc.GetString("burn-contract-prompt"),
|
|
Icon = new SpriteSpecifier.Rsi(new ("/Textures/Effects/fire.rsi"), "fire"),
|
|
};
|
|
|
|
args.Verbs.Add(burnVerb);
|
|
}
|
|
|
|
private void TryBurnContract(Entity<DevilContractComponent> contract, Entity<DevilComponent> devil)
|
|
{
|
|
var coordinates = Transform(contract).Coordinates;
|
|
|
|
if (contract.Comp is not { IsContractFullySigned: true})
|
|
{
|
|
Spawn(devil.Comp.FireEffectProto, coordinates);
|
|
_audio.PlayPvs(devil.Comp.FwooshPath, coordinates, new AudioParams(-2f, 1f, SharedAudioSystem.DefaultSoundRange, 1f, false, 0f));
|
|
QueueDel(contract);
|
|
}
|
|
else
|
|
_popupSystem.PopupCoordinates(Loc.GetString("burn-contract-popup-fail"), coordinates, devil, PopupType.MediumCaution);
|
|
}
|
|
|
|
private void OnExamined(Entity<DevilContractComponent> contract, ref ExaminedEvent args)
|
|
{
|
|
if (!args.IsInDetailsRange)
|
|
return;
|
|
|
|
UpdateContractWeight(contract);
|
|
args.PushMarkup(Loc.GetString("devil-contract-examined", ("weight", contract.Comp.ContractWeight)));
|
|
}
|
|
|
|
private void OnEaten(Entity<DevilContractComponent> contract, ref FullyEatenEvent args)
|
|
{
|
|
_explosion.QueueExplosion(
|
|
args.User,
|
|
typeId: "Default",
|
|
totalIntensity: 1, // contract explosions should not cause any kind of major structural damage. you should at worst need to weld a window or repair a table.
|
|
slope: 1,
|
|
maxTileIntensity: 1,
|
|
maxTileBreak: 0,
|
|
addLog: false); // DeltaV - Use EntitySystem Logger intead of _sawmill
|
|
}
|
|
|
|
#region Signing Steps
|
|
|
|
private void OnContractSignAttempt(Entity<DevilContractComponent> contract, ref BeingSignedAttemptEvent args)
|
|
{
|
|
// Make sure that weight is set properly!
|
|
UpdateContractWeight(contract);
|
|
|
|
// Don't allow mortals to sign contracts for other people.
|
|
if (contract.Comp.IsVictimSigned && args.Signer != contract.Comp.ContractOwner)
|
|
{
|
|
var invalidUserPopup = Loc.GetString("devil-sign-invalid-user");
|
|
_popupSystem.PopupEntity(invalidUserPopup, contract, args.Signer);
|
|
|
|
args.Cancelled = true;
|
|
return;
|
|
}
|
|
|
|
// Only handle unsigned contracts.
|
|
if (contract.Comp.IsVictimSigned || contract.Comp.IsDevilSigned)
|
|
return;
|
|
|
|
if (!IsUserValid(args.Signer, out var failReason))
|
|
{
|
|
_popupSystem.PopupEntity(failReason, contract, args.Signer, PopupType.MediumCaution);
|
|
|
|
args.Cancelled = true;
|
|
return;
|
|
}
|
|
|
|
// Check if the weight is too low
|
|
if (!contract.Comp.IsContractSignable)
|
|
{
|
|
var difference = Math.Abs(contract.Comp.ContractWeight);
|
|
|
|
var unevenOddsPopup = Loc.GetString("contract-uneven-odds", ("number", difference));
|
|
_popupSystem.PopupEntity(unevenOddsPopup, contract, args.Signer, PopupType.MediumCaution);
|
|
|
|
args.Cancelled = true;
|
|
return;
|
|
}
|
|
|
|
// Check if devil is trying to sign first
|
|
if (args.Signer == contract.Comp.ContractOwner)
|
|
{
|
|
var tooEarlyPopup = Loc.GetString("devil-contract-early-sign-failed");
|
|
_popupSystem.PopupEntity(tooEarlyPopup, args.Signer, args.Signer, PopupType.MediumCaution);
|
|
|
|
args.Cancelled = true;
|
|
}
|
|
|
|
}
|
|
|
|
private void OnSignStep(Entity<DevilContractComponent> contract, ref SignSuccessfulEvent args)
|
|
{
|
|
// Determine signing phase
|
|
if (!contract.Comp.IsVictimSigned)
|
|
HandleVictimSign(contract, args.Paper, args.User);
|
|
else if (!contract.Comp.IsDevilSigned)
|
|
HandleDevilSign(contract, args.Paper, args.User);
|
|
|
|
// Final activation check
|
|
if (contract.Comp.IsContractFullySigned)
|
|
HandleBothPartiesSigned(contract);
|
|
}
|
|
|
|
private void HandleVictimSign(Entity<DevilContractComponent> contract, EntityUid signed, EntityUid signer)
|
|
{
|
|
contract.Comp.Signer = signer;
|
|
contract.Comp.IsVictimSigned = true;
|
|
|
|
if (TryComp<PaperComponent>(contract, out var paper))
|
|
paper.EditingDisabled = true;
|
|
|
|
_popupSystem.PopupEntity(Loc.GetString("contract-victim-signed"), signed, signer);
|
|
}
|
|
|
|
private void HandleDevilSign(Entity<DevilContractComponent> contract, EntityUid signed, EntityUid signer)
|
|
{
|
|
contract.Comp.IsDevilSigned = true;
|
|
_popupSystem.PopupEntity(Loc.GetString("contract-devil-signed"), signed, signer);
|
|
|
|
if (_mind.TryGetMind(signer, out var mindId, out var mind) &&
|
|
_mind.TryGetObjectiveComp<MeetContractWeightConditionComponent>(mindId, out var objectiveComp, mind))
|
|
objectiveComp.ContractWeight += contract.Comp.ContractWeight;
|
|
}
|
|
|
|
private void HandleBothPartiesSigned(Entity<DevilContractComponent> contract)
|
|
{
|
|
UpdateContractWeight(contract);
|
|
DoContractEffects(contract);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Helper Events
|
|
|
|
public bool IsUserValid(EntityUid user, out string failReason)
|
|
{
|
|
if (HasComp<CondemnedComponent>(user)
|
|
|| HasComp<SiliconComponent>(user)
|
|
|| HasComp<BorgChassisComponent>(user))
|
|
{
|
|
failReason = Loc.GetString("devil-contract-no-soul-sign-failed");
|
|
return false;
|
|
}
|
|
|
|
if (HasComp<MindShieldComponent>(user)
|
|
&& !HasComp<DevilComponent>(user))
|
|
{
|
|
failReason = Loc.GetString("devil-contract-mind-shielded-failed");
|
|
return false;
|
|
}
|
|
|
|
if (HasComp<PossessedComponent>(user))
|
|
{
|
|
failReason = Loc.GetString("devil-contract-early-sign-failed");
|
|
return false;
|
|
}
|
|
|
|
failReason = string.Empty;
|
|
return true;
|
|
}
|
|
public bool TryTransferSouls(EntityUid devil, EntityUid contractee, int added)
|
|
{
|
|
// Can't sell what doesn't exist.
|
|
if (HasComp<CondemnedComponent>(contractee)
|
|
|| devil == contractee)
|
|
return false;
|
|
|
|
var ev = new SoulAmountChangedEvent(devil, contractee, added);
|
|
RaiseLocalEvent(devil, ref ev);
|
|
|
|
var condemned = EnsureComp<CondemnedComponent>(contractee);
|
|
condemned.SoulOwner = devil;
|
|
condemned.CondemnOnDeath = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
private void UpdateContractWeight(Entity<DevilContractComponent> contract, PaperComponent? paper = null)
|
|
{
|
|
if (!Resolve(contract, ref paper))
|
|
return;
|
|
|
|
contract.Comp.CurrentClauses.Clear();
|
|
var newWeight = 0;
|
|
|
|
var matches = _clauseRegex.Matches(paper.Content);
|
|
foreach (Match match in matches)
|
|
{
|
|
if (!match.Success)
|
|
continue;
|
|
|
|
var clauseKey = match.Groups["clause"].Value.Trim().ToLowerInvariant().Replace(" ", "");
|
|
|
|
if (!_prototypeManager.TryIndex(clauseKey, out DevilClausePrototype? clauseProto)
|
|
|| !contract.Comp.CurrentClauses.Add(clauseProto))
|
|
continue;
|
|
|
|
newWeight += clauseProto.ClauseWeight;
|
|
}
|
|
|
|
contract.Comp.ContractWeight = newWeight;
|
|
}
|
|
|
|
private void DoContractEffects(Entity<DevilContractComponent> contract, PaperComponent? paper = null)
|
|
{
|
|
if (!Resolve(contract, ref paper))
|
|
return;
|
|
|
|
UpdateContractWeight(contract);
|
|
|
|
var matches = _clauseRegex.Matches(paper.Content);
|
|
var processedClauses = new HashSet<string>();
|
|
|
|
foreach (Match match in matches)
|
|
{
|
|
if (!match.Success)
|
|
continue;
|
|
|
|
var targetKey = match.Groups["target"].Value.Trim().ToLowerInvariant().Replace(" ", "");
|
|
var clauseKey = match.Groups["clause"].Value.Trim().ToLowerInvariant().Replace(" ", "");
|
|
|
|
var locId = _targetResolvers.Keys.FirstOrDefault(id => Loc.GetString(id).Equals(targetKey, StringComparison.OrdinalIgnoreCase));
|
|
var resolver = _targetResolvers[locId];
|
|
|
|
if (resolver(contract.Comp) == null)
|
|
{
|
|
Log.Warning($"Unknown resolver: {resolver(contract.Comp)}"); // DeltaV - Use EntitySystem Logger intead of _sawmill
|
|
continue;
|
|
}
|
|
|
|
if (!_prototypeManager.TryIndex(clauseKey, out DevilClausePrototype? clause))
|
|
{
|
|
Log.Warning($"Unknown contract clause: {clauseKey}"); // DeltaV - Use EntitySystem Logger intead of _sawmill
|
|
continue;
|
|
}
|
|
|
|
// no duplicates
|
|
if (!processedClauses.Add(clauseKey))
|
|
{
|
|
Log.Warning($"Attempted to apply duplicate clause: {clauseKey} on contract {ToPrettyString(contract)}"); // DeltaV - Use EntitySystem Logger intead of _sawmill
|
|
continue;
|
|
}
|
|
|
|
|
|
var targetEntity = resolver(contract.Comp);
|
|
|
|
if (targetEntity is not null)
|
|
ApplyEffectToTarget(targetEntity.Value, clause, contract);
|
|
else
|
|
Log.Warning($"Invalid target entity from resolver for clause {clauseKey} in contract {ToPrettyString(contract)}"); // DeltaV - Use EntitySystem Logger intead of _sawmill
|
|
}
|
|
}
|
|
|
|
private void ApplyEffectToTarget(EntityUid target, DevilClausePrototype clause, Entity<DevilContractComponent>? contract)
|
|
{
|
|
|
|
DoPolymorphs(target, clause);
|
|
|
|
RemoveComponents(target, clause);
|
|
|
|
AddComponents(target, clause);
|
|
|
|
OverrideComponents(target, clause); // DeltaV - Fix component modifications
|
|
|
|
ApplyStatusEffect(target, clause); // DeltaV - Clause status effects
|
|
|
|
ChangeDamageModifier(target, clause);
|
|
|
|
AddImplants(target, clause);
|
|
|
|
SpawnItems(target, clause);
|
|
|
|
DoSpecialActions(target, contract, clause);
|
|
}
|
|
|
|
private void ChangeDamageModifier(EntityUid target, DevilClausePrototype clause)
|
|
{
|
|
if (clause.DamageModifierSet == null)
|
|
return;
|
|
|
|
_damageable.SetDamageModifierSetId(target, clause.DamageModifierSet);
|
|
}
|
|
|
|
private void RemoveComponents(EntityUid target, DevilClausePrototype clause)
|
|
{
|
|
if (clause.RemovedComponents == null)
|
|
return;
|
|
|
|
EntityManager.RemoveComponents(target, clause.RemovedComponents);
|
|
}
|
|
|
|
private void AddImplants(EntityUid target, DevilClausePrototype clause)
|
|
{
|
|
if (clause.Implants == null)
|
|
return;
|
|
|
|
_implant.AddImplants(target, clause.Implants);
|
|
}
|
|
|
|
private void AddComponents(EntityUid target, DevilClausePrototype clause)
|
|
{
|
|
if (clause.AddedComponents == null)
|
|
return;
|
|
|
|
EntityManager.AddComponents(target, clause.AddedComponents, false);
|
|
}
|
|
|
|
// Begin DeltaV Addition - Fix component modifications
|
|
private void OverrideComponents(EntityUid target, DevilClausePrototype clause)
|
|
{
|
|
if (clause.OverriddenComponents == null)
|
|
return;
|
|
|
|
EntityManager.AddComponents(target, clause.OverriddenComponents, true);
|
|
}
|
|
// End DeltaV Addition
|
|
|
|
// Begin DeltaV Addition - Devil clause status effects
|
|
private void ApplyStatusEffect(EntityUid target, DevilClausePrototype clause)
|
|
{
|
|
foreach (var effect in clause.StatusEffects)
|
|
{
|
|
_statusEffects.TrySetStatusEffectDuration(target, effect);
|
|
}
|
|
}
|
|
// End DeltaV Addition - Devil clause status effects
|
|
|
|
private void SpawnItems(EntityUid target, DevilClausePrototype clause)
|
|
{
|
|
if (clause.SpawnedItems == null)
|
|
return;
|
|
|
|
foreach (var item in clause.SpawnedItems)
|
|
{
|
|
if (!_prototypeManager.TryIndex(item, out _))
|
|
continue;
|
|
|
|
var spawnedItem = SpawnNextToOrDrop(item, target);
|
|
_hands.TryPickupAnyHand(target, spawnedItem, false, false, false);
|
|
}
|
|
}
|
|
|
|
private void DoPolymorphs(EntityUid target, DevilClausePrototype clause)
|
|
{
|
|
if (clause.Polymorph == null)
|
|
return;
|
|
|
|
_polymorph.PolymorphEntity(target, clause.Polymorph.Value);
|
|
}
|
|
|
|
private void DoSpecialActions(EntityUid target, Entity<DevilContractComponent>? contract, DevilClausePrototype clause)
|
|
{
|
|
if (clause.Event == null)
|
|
return;
|
|
|
|
var ev = clause.Event;
|
|
ev.Target = target;
|
|
|
|
if (contract is not null)
|
|
ev.Contract = contract;
|
|
|
|
// you gotta cast this shit to object, don't ask me vro idk either
|
|
RaiseLocalEvent(target, (object)ev, true);
|
|
}
|
|
|
|
public void AddRandomNegativeClause(EntityUid target)
|
|
{
|
|
var negativeClauses = _prototypeManager.EnumeratePrototypes<DevilClausePrototype>()
|
|
.Where(c => c.ClauseWeight >= 0)
|
|
.ToList();
|
|
|
|
if (negativeClauses.Count == 0)
|
|
return;
|
|
|
|
var selectedClause = _random.Pick(negativeClauses);
|
|
ApplyEffectToTarget(target, selectedClause, null);
|
|
|
|
Log.Debug($"Selected {selectedClause.ID} effect for {ToPrettyString(target)}"); // DeltaV - Use EntitySystem Logger intead of _sawmill
|
|
}
|
|
|
|
public void AddRandomPositiveClause(EntityUid target)
|
|
{
|
|
var positiveClauses = _prototypeManager.EnumeratePrototypes<DevilClausePrototype>()
|
|
.Where(c => c.ClauseWeight <= 0)
|
|
.ToList();
|
|
|
|
if (positiveClauses.Count == 0)
|
|
return;
|
|
|
|
var selectedClause = _random.Pick(positiveClauses);
|
|
ApplyEffectToTarget(target, selectedClause, null);
|
|
|
|
Log.Debug($"Selected {selectedClause.ID} effect for {ToPrettyString(target)}"); // DeltaV - Use EntitySystem Logger intead of _sawmill
|
|
}
|
|
|
|
public void AddRandomClause(EntityUid target)
|
|
{
|
|
var clauses = _prototypeManager.EnumeratePrototypes<DevilClausePrototype>().ToList();
|
|
|
|
if (clauses.Count == 0)
|
|
return;
|
|
|
|
var selectedClause = _random.Pick(clauses);
|
|
ApplyEffectToTarget(target, selectedClause, null);
|
|
|
|
Log.Debug($"Selected {selectedClause.ID} effect for {ToPrettyString(target)}"); // DeltaV - Use EntitySystem Logger intead of _sawmill
|
|
}
|
|
|
|
#endregion
|
|
}
|