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

фелиниды #203

Merged
merged 8 commits into from
Aug 8, 2024
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions Content.Server/Abilities/WoundLicking/WoundLickingComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System.Threading;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.Felinid
{
[RegisterComponent]
[Access(typeof(WoundLickingSystem))]
public sealed partial class WoundLickingComponent : Component
{
[DataField("woundLickingAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? WoundLickingAction = "ActionWoundLicking";

[DataField("woundLickingActionEntity")]
public EntityUid? WoundLickingActionEntity;

/// <summary>
/// How frequent wound-licking will cause diseases. Scales with amount of reduced bleeding
/// </summary>
[DataField("diseaseChance")]
[ViewVariables(VVAccess.ReadWrite)]
public float DiseaseChance { get; set; } = 0.25f;

/// <summary>
/// Max possible bleeding reduce. Human max bleeding is 20f, many weapons deals near 15f bleeding
/// </summary>
[DataField("maxHeal")]
[ViewVariables(VVAccess.ReadWrite)]
public float MaxHeal { get; set; } = 15f;

/// <summary>
/// How long it requires to lick wounds
/// </summary>
[DataField("delay")]
[ViewVariables(VVAccess.ReadWrite)]
public float Delay { get; set; } = 3f;

/// <summary>
/// If true, then wound-licking can be applied only on yourself
/// </summary>
[DataField("canApplyOnSelf")]
[ViewVariables(VVAccess.ReadWrite)]
public bool CanApplyOnSelf { get; set; } = true;

/// <summary>
/// If true, then wound-licking can be applied only on other entities
/// </summary>
[DataField("canApplyOnOther")]
[ViewVariables(VVAccess.ReadWrite)]
public bool CanApplyOnOther { get; set; } = false;



/// <summary>
/// Which diseases can be caused because of wound-licking
/// </summary>
[DataField("possibleDiseases")]
public List<String> PossibleDiseases { get; set; } = new()
{
"Plague",
"BirdFlew",
"SpaceFlu",
"SpaceCold",
"VentCough"
};

/// <summary>
/// If Target's bloodstream don't use one of these reagents, then ability can't be performed on it.
/// </summary>
[DataField("reagentWhitelist")]
public List<String> ReagentWhitelist { get; set; } = new()
{
"Blood",
"Slime"
};

/// <summary>
/// Token for interrupting a do-after action. If not null, implies component is
/// currently "in use".
/// </summary>
public CancellationTokenSource? CancelToken;
}
}
206 changes: 206 additions & 0 deletions Content.Server/Abilities/WoundLicking/WoundLickingSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
//using Content.Server.Disease.Components;
//using Content.Server.Disease;

using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Popups;
using Content.Shared.DoAfter;
using Content.Shared.Felinid;
using Content.Shared.IdentityManagement;
using Content.Shared.Actions;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs;
using Robust.Shared.Player;
using Robust.Shared.Random;
using System.Linq;
/// taken from https://github.com/Workbench-Team/space-station-14/tree/arumoon-server
namespace Content.Server.Felinid
{
/// <summary>
/// "Lick your or other felinid wounds. Reduce bleeding, but unsanitary and can cause diseases."
/// </summary>
public sealed partial class WoundLickingSystem : EntitySystem
{
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
// [Dependency] private readonly DiseaseSystem _disease = default!;
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WoundLickingComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<WoundLickingComponent, ComponentRemove>(OnRemove);
SubscribeLocalEvent<WoundLickingComponent, WoundLickingDoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<WoundLickingActionEvent>(OnActionPerform);
}

private void OnInit(EntityUid uid, WoundLickingComponent comp, ComponentInit args)
{
_actionsSystem.AddAction(uid, ref comp.WoundLickingActionEntity, comp.WoundLickingAction);
}

private void OnRemove(EntityUid uid, WoundLickingComponent comp, ComponentRemove args)
{
_actionsSystem.RemoveAction(uid, comp.WoundLickingActionEntity);
}

protected void OnActionPerform(WoundLickingActionEvent args)
{
if (args.Handled)
return;

args.Handled = true;
var performer = args.Performer;
var target = args.Target;

// Ensure components
if (
!TryComp<WoundLickingComponent>(performer, out var woundLicking) ||
!TryComp<BloodstreamComponent>(target, out var bloodstream) ||
!TryComp<MobStateComponent>(target, out var mobState)
)
return;

// Check target
if (mobState.CurrentState == MobState.Dead)
return;

// Check "CanApplyOnSelf" field
if (performer == target & !woundLicking.CanApplyOnSelf)
{
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-yourself-impossible"),
performer, Filter.Entities(performer), true);
return;
}

// Check "CanApplyOnOther" field
if (performer != target & !woundLicking.CanApplyOnOther)
{
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-other-impossible"),
performer, Filter.Entities(performer), true);
return;
}

if (woundLicking.ReagentWhitelist.Any() &&
!woundLicking.ReagentWhitelist.Contains(bloodstream.BloodReagent)
) return;

// Check bloodstream
if (bloodstream.BleedAmount == 0)
{
if (performer == target)
{
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-yourself-no-wounds"),
performer, performer);
return;
}
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-performer-no-wounds", ("target", target)),
performer, performer);
return;
}

// Popup


if (target == performer)
{
// Applied on yourself
var performerIdentity = Identity.Entity(performer, EntityManager);
var otherFilter = Filter.Pvs(performer, entityManager: EntityManager)
.RemoveWhereAttachedEntity(e => e == performer);

_popupSystem.PopupEntity(Loc.GetString("lick-wounds-yourself-begin"),
performer, performer);
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-yourself-other-begin", ("performer", performerIdentity)),
performer, otherFilter, true);
}
else
{
// Applied on someone else
var targetIdentity = Identity.Entity(target, EntityManager);
var performerIdentity = Identity.Entity(performer, EntityManager);
var otherFilter = Filter.Pvs(performer, entityManager: EntityManager)
.RemoveWhereAttachedEntity(e => e == performer || e == target);

_popupSystem.PopupEntity(Loc.GetString("lick-wounds-performer-begin", ("target", targetIdentity)),
performer, performer);
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-target-begin", ("performer", performerIdentity)),
target, target);
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-other-begin", ("performer", performerIdentity), ("target", targetIdentity)),
performer, otherFilter, true);
}

// DoAfter
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, performer, woundLicking.Delay, new WoundLickingDoAfterEvent(), performer, target: target)
{
BreakOnMove = true,
BreakOnDamage = true
});
}

private void OnDoAfter(EntityUid uid, WoundLickingComponent comp, WoundLickingDoAfterEvent args)
{
if (args.Cancelled || args.Handled)
{
return;
}
if (TryComp<BloodstreamComponent>(args.Args.Target, out var bloodstream))
LickWound(uid, args.Args.Target.Value, bloodstream, comp);
}

private void LickWound(EntityUid performer, EntityUid target, BloodstreamComponent bloodstream, WoundLickingComponent comp)
{
// The more you heal, the more is disease chance
// For 15 maxHeal and 50% diseaseChance
// Heal 15 > chance 50%
// Heal 7.5 > chance 25%
// Heal 0 > chance 0%

var healed = bloodstream.BleedAmount;
if (comp.MaxHeal - bloodstream.BleedAmount < 0) healed = comp.MaxHeal;
/* var chance = comp.DiseaseChance * (1 / comp.MaxHeal * healed);

if (comp.DiseaseChance > 0f & comp.PossibleDiseases.Any())
{
if (TryComp<DiseaseCarrierComponent>(target, out var disCarrier))
{
var diseaseName = comp.PossibleDiseases[_random.Next(0, comp.PossibleDiseases.Count)];
_disease.TryInfect(disCarrier, diseaseName, chance);
}
}
*/
_bloodstreamSystem.TryModifyBleedAmount(target, -healed, bloodstream);

if (performer == target)
{
// Applied on yourself
var performerIdentity = Identity.Entity(performer, EntityManager);
var otherFilter = Filter.Pvs(performer, entityManager: EntityManager)
.RemoveWhereAttachedEntity(e => e == performer);

_popupSystem.PopupEntity(Loc.GetString("lick-wounds-yourself-success"),
performer, performer);
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-yourself-other-success", ("performer", performerIdentity)),
performer, otherFilter, true);
}
else
{
// Applied on someone else
var targetIdentity = Identity.Entity(target, EntityManager);
var performerIdentity = Identity.Entity(performer, EntityManager);
var otherFilter = Filter.Pvs(performer, entityManager: EntityManager)
.RemoveWhereAttachedEntity(e => e == performer || e == target);

_popupSystem.PopupEntity(Loc.GetString("lick-wounds-performer-success", ("target", targetIdentity)),
performer, performer);
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-target-success", ("performer", performerIdentity)),
target, target);
_popupSystem.PopupEntity(Loc.GetString("lick-wounds-other-success", ("performer", performerIdentity), ("target", targetIdentity)),
performer, otherFilter, true);
}
}
}
}
8 changes: 8 additions & 0 deletions Content.Server/Speech/Components/NyaAccentComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// taken from pr: Workbench-Team/space-station-14#1
namespace Content.Server.Speech.Components
{
[RegisterComponent]
public sealed partial class NyaAccentComponent : Component
{
}
}
Loading
Loading