Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the big massive work-in-progress heretic fix slash rebalance #1184

Merged
merged 17 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
using Content.Shared.Damage;
using Content.Shared.Atmos;
using Content.Server.Polymorph.Systems;
using Robust.Server.Audio;
using Robust.Shared.Audio;

namespace Content.Server.Heretic.Abilities;

public sealed partial class HereticAbilitySystem : EntitySystem
{
[Dependency] private readonly AudioSystem _audio = default!;
public SoundSpecifier JauntExitSound = new SoundPathSpecifier("/Audio/Magic/fireball.ogg");
public const float RebirthRange = 3f;

private void SubscribeAsh()
{
SubscribeLocalEvent<HereticComponent, EventHereticAshenShift>(OnJaunt);
Expand Down Expand Up @@ -43,6 +49,15 @@ private bool TryDoJaunt(EntityUid ent)
private void OnJauntEnd(Entity<HereticComponent> ent, ref PolymorphRevertEvent args)
{
Spawn("PolymorphAshJauntEndAnimation", Transform(ent).Coordinates);

if (TryComp<FlammableComponent>(ent, out var flam))
{
if (!flam.OnFire)
{
_flammable.AdjustFireStacks(ent, 1, flam, true);
}
}
_audio.PlayPvs(JauntExitSound, ent, AudioParams.Default.WithVolume(-2f));
}

private void OnVolcano(Entity<HereticComponent> ent, ref EventHereticVolcanoBlast args)
Expand Down Expand Up @@ -74,7 +89,7 @@ private void OnNWRebirth(Entity<HereticComponent> ent, ref EventHereticNightwatc
if (!TryUseAbility(ent, args))
return;

var lookup = _lookup.GetEntitiesInRange(ent, 5f);
var lookup = _lookup.GetEntitiesInRange(ent, RebirthRange);

foreach (var look in lookup)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
using Content.Shared.Body.Part;
using Content.Shared.Damage;
using Content.Shared.DoAfter;
using Content.Shared.Eye.Blinding.Components;
using Content.Shared.Heretic;
using Content.Shared.Popups;
using Content.Shared.Speech.Muting;
using Robust.Shared.Audio;
using Robust.Shared.Player;

Expand Down Expand Up @@ -39,42 +41,33 @@ private void OnFleshSurgery(Entity<HereticComponent> ent, ref EventHereticFleshS
return;
}

// remove a random organ
// temporarily disable a random organ
// the fucking goob coders were literally just deleting organ components. who thought that was okay
// TODO: change this to actually remove/disable organs once newmed comes out next week
if (TryComp<BodyComponent>(args.Target, out var body))
{
_vomit.Vomit(args.Target, -1000, -1000); // You feel hollow!

switch (_random.Next(0, 2))
//i should really make these their own methods. but i dont want to
switch (_random.Next(0, 3))
{
// remove stomach
// case 0: barf
case 0:
foreach (var entity in _body.GetBodyOrganEntityComps<StomachComponent>((args.Target, body)))
QueueDel(entity.Owner);

_popup.PopupEntity(Loc.GetString("admin-smite-stomach-removal-self"), args.Target,
args.Target, PopupType.LargeCaution);
_popup.PopupEntity(Loc.GetString("heretic-fleshsurgery-barf"), args.Target, args.Target, PopupType.LargeCaution);
_vomit.Vomit(args.Target, -1000, -1000); // i frew up
break;

// remove random hand
// case 1: blind (fixable!)
case 1:
var baseXform = Transform(args.Target);
foreach (var part in _body.GetBodyChildrenOfType(args.Target, BodyPartType.Hand, body))
{
_transform.AttachToGridOrMap(part.Id);
break;
}
_popup.PopupEntity(Loc.GetString("admin-smite-remove-hands-self"), args.Target, args.Target, PopupType.LargeCaution);
_popup.PopupCoordinates(Loc.GetString("admin-smite-remove-hands-other", ("name", args.Target)), baseXform.Coordinates,
Filter.PvsExcept(args.Target), true, PopupType.Medium);
if (!TryComp<BlindableComponent>(args.Target, out var blindable) || blindable.IsBlind)
return;

_popup.PopupEntity(Loc.GetString("heretic-fleshsurgery-eyes"), args.Target, args.Target, PopupType.LargeCaution);
_blindable.AdjustEyeDamage((args.Target, blindable), 7); //same as rawdogging a welder 7 times. fixable but definitely a pain
break;

// remove lungs
// case 2: mute for 2.5 minutes
case 2:
foreach (var entity in _body.GetBodyOrganEntityComps<LungComponent>((args.Target, body)))
QueueDel(entity.Owner);

_popup.PopupEntity(Loc.GetString("admin-smite-lung-removal-self"), args.Target,
args.Target, PopupType.LargeCaution);
_popup.PopupEntity(Loc.GetString("heretic-fleshsurgery-mute"), args.Target, args.Target, PopupType.LargeCaution);
_statusEffect.TryAddStatusEffect<MutedComponent>(args.Target, "Muted", TimeSpan.FromSeconds(150), false);
break;

default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
using Robust.Shared.Audio;
using Content.Shared.Mobs.Components;
using Robust.Shared.Prototypes;
using Content.Shared.Eye.Blinding.Systems;

namespace Content.Server.Heretic.Abilities;

Expand All @@ -57,7 +58,9 @@ public sealed partial class HereticAbilitySystem : EntitySystem
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedBodySystem _body = default!;
[Dependency] private readonly BlindableSystem _blindable = default!;
[Dependency] private readonly VomitSystem _vomit = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffect = default!;
[Dependency] private readonly PhysicsSystem _phys = default!;
[Dependency] private readonly SharedStunSystem _stun = default!;
[Dependency] private readonly ThrowingSystem _throw = default!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private void OnTryAttack(Entity<GhoulComponent> ent, ref AttackAttemptEvent args

private void OnExamine(Entity<GhoulComponent> ent, ref ExaminedEvent args)
{
args.PushMarkup(Loc.GetString("examine-system-cant-see-entity"));
args.PushMarkup($"[color=red]{Loc.GetString("heretic-ghoul-examine", ("ent", args.Examined))}[/color]");
}

private void OnMobStateChange(Entity<GhoulComponent> ent, ref MobStateChangedEvent args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
using Content.Shared.DoAfter;
using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Explosion.Components;
using Content.Shared.Eye.Blinding.Systems;
using Content.Shared.Hands;
using Content.Shared.Heretic;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Content.Shared.Mobs.Components;
using Content.Shared.Silicons.Borgs.Components;
using Content.Shared.Speech.Muting;
Expand Down Expand Up @@ -97,6 +99,7 @@ public override void Initialize()

SubscribeLocalEvent<TagComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<HereticComponent, DrawRitualRuneDoAfterEvent>(OnRitualRuneDoAfter);
SubscribeLocalEvent<MansusGraspComponent, UseInHandEvent>(OnUseInHand);
}

private void OnAfterInteract(Entity<MansusGraspComponent> ent, ref AfterInteractEvent args)
Expand Down Expand Up @@ -146,6 +149,21 @@ private void OnAfterInteract(Entity<MansusGraspComponent> ent, ref AfterInteract
QueueDel(ent);
}

private void OnUseInHand(EntityUid uid, MansusGraspComponent component, UseInHandEvent args)
{
if (args.Handled)
return;

if (!TryComp<HereticComponent>(args.User, out var hereticComp))
{
QueueDel(uid);
return;
}

hereticComp.MansusGraspActive = false;
QueueDel(uid);
}

private void OnAfterInteract(Entity<TagComponent> ent, ref AfterInteractEvent args)
{
var tags = ent.Comp.Tags;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,66 @@
using Content.Shared.Fluids.Components;
using Content.Shared.Heretic.Prototypes;
using Robust.Shared.Prototypes;
using System.Linq;

namespace Content.Server.Heretic.Ritual;

public sealed partial class RitualReagentPuddleBehavior : RitualCustomBehavior
{
protected EntityLookupSystem _lookup = default!;

[DataField] public ProtoId<ReagentPrototype>? Reagent;
[DataField] public List<ProtoId<ReagentPrototype>>? Reagents;

private List<EntityUid> uids = new();

public override bool Execute(RitualData args, out string? outstr)
{
outstr = null;
if (Reagents == null)
{
//should only happen if someone fucked up their ritual yaml
outstr = Loc.GetString("heretic-ritual-unknown");
return false;
}
string reagStrings = "";

if (Reagent == null)
return true;
foreach(var Reagent in Reagents)
{
reagStrings += (Reagent.Id + ", ");

_lookup = args.EntityManager.System<EntityLookupSystem>();
outstr = null;
_lookup = args.EntityManager.System<EntityLookupSystem>();

var lookup = _lookup.GetEntitiesInRange(args.Platform, .75f);
var lookup = _lookup.GetEntitiesInRange(args.Platform, .75f);

foreach (var ent in lookup)
{
if (!args.EntityManager.TryGetComponent<PuddleComponent>(ent, out var puddle))
continue;
foreach (var ent in lookup)
{
if (!args.EntityManager.TryGetComponent<PuddleComponent>(ent, out var puddle))
continue;

if (puddle.Solution == null)
continue;
if (puddle.Solution == null)
continue;

var soln = puddle.Solution.Value;

var soln = puddle.Solution.Value;
if (!soln.Comp.Solution.ContainsPrototype(Reagent))
continue;

if (!soln.Comp.Solution.ContainsPrototype(Reagent))
uids.Add(ent);
}

if (uids.Count == 0)
{
continue;
}

uids.Add(ent);
return true;
}

if (uids.Count == 0)
{
outstr = Loc.GetString("heretic-ritual-fail-reagentpuddle", ("reagentname", Reagent!));
return false;
}
//take off the comma + space on the end of the reagStrings
reagStrings = reagStrings.Substring(0, reagStrings.Length - 2);
outstr = Loc.GetString("heretic-ritual-fail-reagentpuddle", ("reagentname", reagStrings));
return false;

return true;
}

public override void Finalize(RitualData args)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
using Content.Server.Heretic.EntitySystems;
using Content.Shared.Heretic;
using Content.Shared.Heretic.Prototypes;
using Content.Shared.Mind;
using Content.Shared.Store;
using System.Linq;
using Robust.Shared.Prototypes;

namespace Content.Server.Store.Conditions;

public sealed partial class HereticPathCondition : ListingCondition
{
[Dependency] private readonly IPrototypeManager _proto = default!;

public int AlternatePathPenalty = 1; //you can only buy alternate paths' abilities if they are this amount under your initial path's top ability level.
[DataField] public HashSet<string>? Whitelist;
[DataField] public HashSet<string>? Blacklist;
[DataField] public int Stage = 0;
Expand All @@ -15,15 +20,22 @@ public override bool Condition(ListingConditionArgs args)
{
var ent = args.EntityManager;
var minds = ent.System<SharedMindSystem>();
var knowledgeSys = ent.System<HereticKnowledgeSystem>();



if (!minds.TryGetMind(args.Buyer, out var mindId, out var mind))
return false;

if (!ent.TryGetComponent<HereticComponent>(args.Buyer, out var hereticComp))
return false;

//Stage is the level of the knowledge we're looking at
//always check for level
if (Stage > hereticComp.PathStage)
{
return false;
}

if (Whitelist != null)
{
Expand All @@ -41,6 +53,30 @@ public override bool Condition(ListingConditionArgs args)
return true;
}


//if you have chosen a path
if ((hereticComp.CurrentPath != null) && (args.Listing.ProductHereticKnowledge != null))
{
ProtoId<HereticKnowledgePrototype> knowledgeProtoId = new ProtoId<HereticKnowledgePrototype>((ProtoId<HereticKnowledgePrototype>)args.Listing.ProductHereticKnowledge);
var knowledge = knowledgeSys.GetKnowledge(knowledgeProtoId);
HashSet<string> myPaths = new HashSet<string>();
myPaths.Add(hereticComp.CurrentPath);
myPaths.Add("Side");

//and the knowledge you're looking at is not from your current path or side knowledge
if (knowledge.Path != null && !(myPaths.Contains(knowledge.Path)))
{
//then, there should be a penalty.
//so, if the level of the knowledge is greater than your current path's level minus the penalty
if (Stage > hereticComp.PathStage - AlternatePathPenalty)
{
//then you can't have it.
return false;
//this took me two days.
}

}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ heretic-magicitem-examine = [color=yellow]Allows you to use advanced spells whil
heretic-blade-examine = [color=yellow]Using it while it's in your hand will break the blade and teleport you away from danger.[/color]
heretic-blade-use = The blade shatters, and you feel the voices pulling you away.

heretic-ghoul-examine = { CAPITALIZE(POSS-ADJ($ent)) } body looks like a decaying corpse.

heretic-rust-mark-itembreak = {$name} shatters into dust!

heretic-manselink-fail-exists = This creature is already connected!
heretic-manselink-fail-nomind = This creature does not have a mind!
heretic-manselink-start = You begin to connect this creature's mind to yours.
heretic-manselink-start-target = You feel your mind being pulled somewhere...

heretic-fleshsurgery-barf = The contents of your stomach come pouring out!
heretic-fleshsurgery-eyes = Your vision becomes dull and cloudy!
heretic-fleshsurgery-mute = Your tongue falls limp!

heretic-livingheart-notargets = No available targets, visit the rune.
heretic-livingheart-offstation = It's {$state}, off station, {$direction}!
heretic-livingheart-onstation = It's {$state}, {$direction}!
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
guide-entry-heretics = Heretics
guide-entry-heretics-paths = Paths
guide-entry-heretics-knowledge = Knowledge Points
guide-entry-heretics-rituals = Rituals & Sacrifices
guide-entry-heretics-spells = Spells & Foci
guide-entry-heretics-ash = Path of Ash
guide-entry-heretics-flesh = Path of Flesh
guide-entry-heretics-void = Path of Void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ heretic-ritual-basic-heart = Relentless Heartbeat

heretic-ritual-fail-sacrifice = There is no corpse to sacrifice.
heretic-ritual-fail-sacrifice-ineligible = The rune refuses to accept this sacrifice.
heretic-ritual-fail-reagentpuddle = There is no {$reagentname} present.
heretic-ritual-fail-reagentpuddle = This ritual needs a puddle of one of these: {$reagentname}.
heretic-ritual-fail-temperature-hot = It is too hot here.
heretic-ritual-fail-temperature-cold = It is not cold enough here.
heretic-ritual-fail-sacrifice-ash = There's either not enough of them dead, or burning.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ knowledge-path-ash-s1-desc =
The City Guard know their watch. If you ask them at night, they may tell you about the ashy lantern.

Opens up the Path of Ash to you.
Allows you to transmute a match and a knife into an Ashen Blade.
Allows you to transmute a welding tool and a knife into an Ashen Blade.

knowledge-path-ash-s2-name = Grasp of Ash
knowledge-path-ash-s2-desc =
Expand Down
Loading
Loading