Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion Content.Client/PDA/PdaVisualizerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ public enum PdaVisualLayers : byte
Flashlight,
IdLight
}
}
}
6 changes: 2 additions & 4 deletions Content.Inky.Client/Content.Inky.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@
</PropertyGroup>
<Import Project="../MSBuild/Content.props" />
<ItemGroup>
<ProjectReference Include="../Content.Goobstation.Client/Content.Goobstation.Client.csproj" />
<ProjectReference Include="../Content.Inky.Shared/Content.Inky.Shared.csproj" />
<ProjectReference Include="../Content.Trauma.Client/Content.Trauma.Client.csproj" />
<ProjectReference Include="../Content.Lavaland.Client/Content.Lavaland.Client.csproj" />
<ProjectReference Include="../Content.Medical.Client/Content.Medical.Client.csproj" />
<ProjectReference Include="..\Content.Inky.Shared\Content.Inky.Shared.csproj" />
<ProjectReference Include="../Content.Client/Content.Client.csproj" />
</ItemGroup>

<Import Project="../RobustToolbox/Imports/Client.props" />
Expand Down
3 changes: 3 additions & 0 deletions Content.Inky.Common/Events/Werewolf/WerewolfEvents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Content.Inky.Common.Events.Werewolf;

public readonly record struct SelectFirstMartialArtEvent(EntityUid Entity);
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Content.Goobstation.Common.Blob;
using Content.Goobstation.Server.Changeling.GameTicking.Rules;
using Content.Inky.Shared.Werewolf.Components;
using Content.Server.Administration.Managers;
using Content.Server.Administration.Systems;
using Content.Server.Antag;
using Content.Shared.Database;
using Content.Shared.Mind.Components;
using Content.Shared.Verbs;
using Content.Trauma.Common.Silicon;
using Robust.Shared.Player;
using Robust.Shared.Utility;

namespace Content.Inky.Server.Administration.Systems;

public sealed partial class InkyAdminVerbSystem
{
[Dependency] private readonly AntagSelectionSystem _antag = default!;

private void OnGetAntagVerbs(ref GetAntagVerbsEvent args)
{
if (!HasComp<MindContainerComponent>(args.Target) || !TryComp<ActorComponent>(args.Target, out var targetActor))
return;

var targetPlayer = targetActor.PlayerSession;

args.Verbs.Verbs.Add(new()
{
Text = Loc.GetString("admin-verb-text-make-werewolf"),
Category = VerbCategory.Antag,
Icon = new SpriteSpecifier.Rsi(new ResPath("/Textures/_Inky/Actions/Werewolf/werewolf.rsi"), "howl"),
Act = () =>
{
_antag.ForceMakeAntag<WerewolfRuleComponent>(targetPlayer, "Werewolf");
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-werewolf"),
});
}
}
13 changes: 13 additions & 0 deletions Content.Inky.Server/Administration/Systems/InkyAdminVerbSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Content.Server.Administration.Systems;

namespace Content.Inky.Server.Administration.Systems;

public sealed partial class InkyAdminVerbSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<GetAntagVerbsEvent>(OnGetAntagVerbs);
}
}
8 changes: 3 additions & 5 deletions Content.Inky.Server/Content.Inky.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Content.Inky.Shared\Content.Inky.Shared.csproj" />
<ProjectReference Include="../Content.Goobstation.Server/Content.Goobstation.Server.csproj" />
<ProjectReference Include="../Content.Lavaland.Server/Content.Lavaland.Server.csproj" />
<ProjectReference Include="../Content.Medical.Server/Content.Medical.Server.csproj" />
<ProjectReference Include="../Content.Inky.Shared/Content.Inky.Shared.csproj" />
<ProjectReference Include="../Content.Trauma.Server/Content.Trauma.Server.csproj" />
<ProjectReference Include="../Content.Server/Content.Server.csproj" />
</ItemGroup>

<Import Project="../RobustToolbox/Imports/Server.props" />
<Import Project="../RobustToolbox/Imports/Shared.props" />
<Import Project="../RobustToolbox/MSBuild/Robust.Properties.targets" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Content.Inky.Shared.Werewolf;
using Content.Inky.Shared.Werewolf.Components;
using Content.Shared.Chat;
using Robust.Shared.Utility;

namespace Content.Inky.Server.Werewolf.Systems;

public sealed partial class WerewolfAbilitiesSystem
{
/// <inheritdoc/>
public void InitializeBlack()
{
SubscribeLocalEvent<WerewolfAbilitiesComponent, WerewolfBeckonEvent>(OnBeckon);
}

private void OnBeckon(EntityUid uid, WerewolfAbilitiesComponent comp, WerewolfBeckonEvent args)
{
var locationName = FormattedMessage.RemoveMarkupOrThrow(_navMap.GetNearestBeaconString(uid));

var message = Loc.GetString("werewolf-beckon-message",
("name", MetaData(uid).EntityName),
("location", locationName));

_chat.TrySendInGameICMessage(uid, $"+l {message}", InGameICChatType.CollectiveMind, ChatTransmitRange.Normal); // holy goida IF ANYONE CHANGES LUNARMIND KEY LETTER CHANGE IT HERE TOO
args.Handled = true;
}
}
211 changes: 211 additions & 0 deletions Content.Inky.Server/Werewolf/Systems/WerewolfAbilitiesSystem.Side.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
using System.Linq;
using Content.Goobstation.Shared.Changeling.Components;
using Content.Inky.Shared.Werewolf;
using Content.Inky.Shared.Werewolf.Components;
using Content.Medical.Shared.Wounds;
using Content.Shared.Body;
using Content.Shared.Body.Components;
using Content.Shared.Chemistry.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
using Content.Shared.Popups;
using Robust.Shared.Prototypes;

namespace Content.Inky.Server.Werewolf.Systems;

/// <summary>
/// Handles side abilities and helpers for the werewolf
/// </summary>
public sealed partial class WerewolfAbilitiesSystem
{
public void InitializeWerewolfSide()
{
SubscribeLocalEvent<WerewolfAbilitiesComponent, EventWerewolfDevour>(TryDevour);
SubscribeLocalEvent<WerewolfAbilitiesComponent, WerewolfDevourDoAfterEvent>(DoDevour);
SubscribeLocalEvent<WerewolfAbilitiesComponent, EventWerewolfGut>(TryGut);
SubscribeLocalEvent<WerewolfAbilitiesComponent, WerewolfGutDoAfterEvent>(DoGut);
}
# region devour
private void TryDevour(EntityUid uid, WerewolfAbilitiesComponent component, EventWerewolfDevour args)
{
var target = args.Target;

if (HasComp<WerewolfBitComponent>(target))
{
_popup.PopupPredictedCursor(Loc.GetString("werewolf-devour-fail-devoured"), uid);
return;
}
if (!HasComp<AbsorbableComponent>(target)) // i mean... it works? also less wizden files changes
{
_popup.PopupPredicted(Loc.GetString("changeling-absorb-fail-unabsorbable"), uid, uid);
return;
}

if (HasComp<WerewolfAbilitiesComponent>(target))
{
_popup.PopupPredicted(Loc.GetString("werewolf-devour-fail-werewolf"), uid, uid); // no to eating each other
return;
}

var popupOthers = Loc.GetString("werewolf-devour-start", ("user", uid), ("target", target));
_popup.PopupPredicted(popupOthers, uid, uid, PopupType.LargeCaution);

var dargs = new DoAfterArgs(EntityManager, uid, TimeSpan.FromSeconds(4), new WerewolfDevourDoAfterEvent(), uid, target) // todo werewolf unhardcode duration
{
DistanceThreshold = 1.5f,
BreakOnDamage = true,
BreakOnHandChange = false,
BreakOnMove = true,
BreakOnWeightlessMove = true,
AttemptFrequency = AttemptFrequency.StartAndEnd,
MultiplyDelay = false,
};
_doAfter.TryStartDoAfter(dargs);
}

public ProtoId<DamageGroupPrototype> DevourDamage = "Brute"; // bro
private void DoDevour(EntityUid uid, WerewolfAbilitiesComponent comp, WerewolfDevourDoAfterEvent args)
{
if (args.Args.Target == null)
return;

var target = args.Args.Target.Value;

if (args.Cancelled
|| HasComp<WerewolfBitComponent>(target)
|| !TryComp<BodyComponent>(target, out var body))
return;

var dmg = new DamageSpecifier(_proto.Index(DevourDamage), 35); // todo werewolf unhardcode this
_damage.TryChangeDamage(target, dmg, true, true);
RipLimb(target, body);

var targetComp = EnsureComp<WerewolfBitComponent>(target);

if (!_mind.TryGetMind(uid, out var mindId, out _)
|| !TryComp<WerewolfMindComponent>(mindId, out var mindComp))
return;

mindComp.Currency += comp.AmountDevour;
mindComp.BittenPeople.Add(args.Args.Target.Value);
targetComp.BittenBy = mindComp;

_hunger.ModifyHunger(uid, +80); // todo werewolf maybe put as a var inside a comp or sdome shit
_audio.PlayPvs(comp.RipSound, uid);
}

private void TryGut(EntityUid uid, WerewolfAbilitiesComponent comp, EventWerewolfGut args)
{
var target = args.Target;

if (!HasComp<AbsorbableComponent>(target))
{
_popup.PopupEntity(Loc.GetString("changeling-absorb-fail-unabsorbable"), uid, uid);
return;
}

_mind.TryGetMind(target, out var mindId, out var mind);

if (mind == null)
{
// _popup.PopupEntity(Loc.GetString("werewolf-gut-fail-mind"), uid, uid); // todo werewolf locale
// return; // todo werewolf uncomment before release
}

var popupOthers = Loc.GetString("werewolf-gut-start", ("user", uid), ("target", target)); // todo locale
_popup.PopupPredicted(popupOthers, uid, uid, PopupType.LargeCaution);

var dargs = new DoAfterArgs(EntityManager, uid, TimeSpan.FromSeconds(4), new WerewolfGutDoAfterEvent(), uid, target)// todo werewolf unhardcode duration
{
DistanceThreshold = 1.5f,
BreakOnDamage = true,
BreakOnHandChange = false,
BreakOnMove = true,
BreakOnWeightlessMove = true,
AttemptFrequency = AttemptFrequency.StartAndEnd,
MultiplyDelay = false,
};
_doAfter.TryStartDoAfter(dargs);
}

#endregion
#region helpers
private void DoGut(EntityUid uid, WerewolfAbilitiesComponent comp, WerewolfGutDoAfterEvent args)
{
if (args.Args.Target == null)
return;

var target = args.Args.Target.Value;

if (args.Cancelled
|| !TryComp<BodyComponent>(target, out var body))
return;

if (!TryRemoveOrgan(uid, target, out var removedOrgan))
return;

_blood.SpillAllSolutions(target);
if (_mind.TryGetMind(uid, out var mindId, out _) && TryComp<WerewolfMindComponent>(mindId, out var mindComp))
mindComp.Currency += comp.AmountGut;

_hunger.ModifyHunger(uid, +20); // todo werewolf maybe put this inside comp
_audio.PlayPvs(comp.RipSound, uid);
}

private bool TryRemoveOrgan(EntityUid user, EntityUid target, out EntityUid? removedOrgan) // shit was originally taken from devil shitcode but upstream broke a shitton of stuff
{
removedOrgan = null;

if (!TryComp<BodyComponent>(target, out var body))
return false;

var organs = _body.GetInternalOrgans((target, body))
.Where(organ => !HasComp<BrainComponent>(organ.Owner))
.ToList();

if (organs.Count < 1)
{
_popup.PopupEntity(Loc.GetString("werewolf-gut-no-organs-left"), user, user);
return false;
}

var nextOrgan = _gambling.Next(organs.Count); // idk
var picked = organs[nextOrgan];
removedOrgan = picked.Owner;

if (TryComp<OrganComponent>(picked.Owner, out var organComp))
_body.RemoveOrgan((target, body), new Entity<OrganComponent?>(picked.Owner, organComp)); // this is horrible
QueueDel(picked.Owner);

_popup.PopupEntity(Loc.GetString("werewolf-gut-success"), user, user);

return true;
}

private void RipLimb(EntityUid target, BodyComponent body)
{
var allOrgans = _body.GetOrgans((target, body));
var limbs = allOrgans // limbs are considered organs for some reason
.Where(organ =>
{
var category = _body.GetCategory(new Entity<OrganComponent?>(organ.Owner, organ.Comp));
return category == "ArmLeft" || category == "ArmRight"; // TODO WEREWOLF: DESHITCODE
})// i have PTSD from shitmed and inkymed looking at this shit above
.ToList();

if (limbs.Count <= 0)
return;

var nextOrgan = _gambling.Next(limbs.Count); // boo copypaste from TryRemoveOrgan
var picked = limbs[nextOrgan];

if (!TryComp<WoundableComponent>(picked.Owner, out var woundable)
|| !woundable.ParentWoundable.HasValue)
return;

_wound.AmputateWoundableSafely(woundable.ParentWoundable.Value, picked.Owner, woundable);
}
# endregion
}
Loading
Loading