Система лизания пиздец (#429)

* Насрал пиздец

* Немного говна

* Готово ебана

* Фиксы

* А теперь

* А так

* Йес

* Показываю

* Работает

* Дофиксы
This commit is contained in:
ThereDrD0
2023-09-24 18:46:51 +03:00
committed by Aviu00
parent 7120f4d85d
commit 855f5eada2
9 changed files with 270 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
using Content.Server.Administration.Logs;
using Content.Server.Nutrition.Components;
using Content.Server.Popups;
using Content.Shared.Actions;
using Content.Shared.Damage;
using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.Humanoid;
using Content.Shared.Interaction;
using Content.Shared.Inventory;
using Content.Shared.White.SelfHeal;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
namespace Content.Server.White.SelfHeal;
public sealed class SelfHealSystem: EntitySystem
{
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SelfHealComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<SelfHealComponent, SelfHealEvent>(OnHealingAfterInteract);
SubscribeLocalEvent<DamageableComponent, SelfHealDoAfterEvent>(OnDoAfter);
}
private void OnInit(EntityUid uid, SelfHealComponent component, ComponentInit args)
{
_actionsSystem.AddAction(uid, ref component.ActionEntity, component.Action);
}
private void OnHealingAfterInteract(EntityUid uid, SelfHealComponent component, SelfHealEvent args)
{
if (args.Handled)
return;
TryHeal(args.Performer, args.Target, component);
args.Handled = true;
}
private void OnDoAfter(EntityUid uid, DamageableComponent component, SelfHealDoAfterEvent args)
{
var dontRepeat = false;
if (!TryComp(args.User, out SelfHealComponent? healing) || args.Target == null)
return;
if (args.Handled || args.Cancelled)
return;
if (healing.DamageContainers is not null &&
component.DamageContainerID is not null &&
!healing.DamageContainers.Contains(component.DamageContainerID))
{
return;
}
if (!CanHeal(args.User, args.Target.Value, healing))
return;
Heal(args.Target.Value, healing, args);
// Logic to determine the whether or not to repeat the healing action
args.Repeat = (HasDamage(component, healing) && !dontRepeat);
if (!args.Repeat && !dontRepeat)
_popupSystem.PopupEntity(Loc.GetString("self-heal-finished-using", ("verb", Loc.GetString("self-heal-lick")), ("name", uid)), uid, args.User);
args.Handled = true;
}
private void Heal(EntityUid uid, SelfHealComponent component, SelfHealDoAfterEvent args)
{
var healed = _damageable.TryChangeDamage(uid, component.Damage, true, origin: args.Args.User);
if (healed == null)
return;
var total = healed.GetTotal();
var userString = EntityManager.ToPrettyString(args.User);
var targetString = EntityManager.ToPrettyString(uid);
var healMessage = uid != args.User
? $"{userString:user} healed {targetString:target} for {total:damage} with {Loc.GetString("self-heal-lick")}"
: $"{userString:user} healed themselves for {total:damage} with {Loc.GetString("self-heal-lick")}";
_adminLogger.Add(LogType.Healed, $"{healMessage}");
if (TryComp<SelfHealComponent>(args.User, out var selfHealComponent))
{
var audio = selfHealComponent.HealingSound;
var audioParams = new AudioParams().WithVariation(2f).WithVolume(-5f);
_audio.PlayPvs(audio, args.User, audioParams);
_popupSystem.PopupEntity(Loc.GetString("self-heal-using-other", ("name", uid), ("verb", Loc.GetString("self-heal-lick"))), uid);
}
}
private bool CanHeal(EntityUid user, EntityUid target, SelfHealComponent component)
{
if (!TryComp<DamageableComponent>(target, out var targetDamage) || !HasComp<HumanoidAppearanceComponent>(target))
return false;
if (user != target && !_interactionSystem.InRangeUnobstructed(user, target, popup: true))
return false;
if (!HasDamage(targetDamage, component))
{
var popup = Loc.GetString("self-heal-cant-use", ("verb", Loc.GetString("self-heal-lick")),
("name", target));
_popupSystem.PopupEntity(popup, user, user);
return false;
}
if (component.DisallowedClothingUser != null)
{
foreach (var clothing in component.DisallowedClothingUser)
{
if (_inventorySystem.TryGetSlotEntity(user, clothing, out var blockedClothing) &&
EntityManager.TryGetComponent<IngestionBlockerComponent>(blockedClothing, out var blocker) &&
blocker.Enabled)
{
var popup = Loc.GetString("self-heal-cant-use-clothing", ("verb", Loc.GetString("self-heal-lick")), ("clothing", blockedClothing));
_popupSystem.PopupEntity(popup, user, user);
return false;
}
}
}
if (component.DisallowedClothingTarget != null)
{
foreach (var clothing in component.DisallowedClothingTarget)
{
if (_inventorySystem.TryGetSlotEntity(target, clothing, out var blockedClothing))
{
var popup = Loc.GetString("self-heal-cant-use-clothing-other", ("verb", Loc.GetString("self-heal-lick")), ("name", target), ("clothing", blockedClothing));
_popupSystem.PopupEntity(popup, user, user);
return false;
}
}
}
return true;
}
private void TryHeal(EntityUid user, EntityUid target, SelfHealComponent component)
{
if (!CanHeal(user, target, component))
return;
var doAfterEventArgs =
new DoAfterArgs(EntityManager, user, component.Delay, new SelfHealDoAfterEvent(), target, target)
{
BreakOnUserMove = true,
BreakOnTargetMove = true,
};
_doAfter.TryStartDoAfter(doAfterEventArgs);
}
private bool HasDamage(DamageableComponent component, SelfHealComponent healing)
{
var damageableDict = component.Damage.DamageDict;
var healingDict = healing.Damage.DamageDict;
foreach (var type in healingDict)
{
if (damageableDict[type.Key].Value > 0)
return true;
}
return false;
}
}

View File

@@ -0,0 +1,40 @@
using Content.Shared.Actions;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.White.SelfHeal;
[RegisterComponent]
public sealed partial class SelfHealComponent: Component
{
[ViewVariables(VVAccess.ReadWrite), DataField("delay")]
public float Delay = 3f;
[ViewVariables(VVAccess.ReadWrite), DataField("healingSound")]
public SoundSpecifier? HealingSound;
[ViewVariables(VVAccess.ReadWrite), DataField("damage", required: true)]
public DamageSpecifier Damage = default!;
[ViewVariables(VVAccess.ReadWrite), DataField("damageContainers", customTypeSerializer: typeof(PrototypeIdListSerializer<DamageContainerPrototype>))]
public List<string>? DamageContainers;
[ViewVariables(VVAccess.ReadWrite),DataField("disallowedClothingUser")]
public List<string>? DisallowedClothingUser;
[ViewVariables(VVAccess.ReadWrite), DataField("disallowedClothingTarget")]
public List<string>? DisallowedClothingTarget;
[DataField]
public EntProtoId Action = "SelfHealAction";
[DataField]
public EntityUid? ActionEntity;
}
public sealed partial class SelfHealEvent : EntityTargetActionEvent
{
}

View File

@@ -0,0 +1,9 @@
using Content.Shared.DoAfter;
using Robust.Shared.Serialization;
namespace Content.Shared.White.SelfHeal;
[Serializable, NetSerializable]
public sealed partial class SelfHealDoAfterEvent : SimpleDoAfterEvent
{
}

Binary file not shown.

View File

@@ -0,0 +1,8 @@
self-heal-finished-using = You have finished {$verb}ing all {$name}`s wounds
self-heal-cant-use = There is no damage you can heal by {$verb}ing {$name}
self-heal-stop-bleeding = They have stopped bleeding
self-heal-lick = lick
self-heal-cant-use-clothing = You cant {$verb}ing yourself while wearing a {$clothing}
self-heal-cant-use-clothing-other = You cant {$verb}ing {$name} while {$name} is wearing a {$clothing}
self-heal-action = Lick the wounds
self-heal-using-other = {$name} have {$verb}ed some of {$name} wounds

View File

@@ -0,0 +1,9 @@
self-heal-finished-using = Вы закончили {$verb} все раны {$name}!
self-heal-cant-use = {$name} не имеет ран, которые вы могли бы {$verb}
self-heal-stop-bleeding = Оно перестало кровоточить
self-heal-lick = вылизывать
self-heal-cant-use-clothing = Вы не можете {$verb}, пока на вас {$clothing}
self-heal-cant-use-clothing-other = Вы не можете {$verb} {$name}, пока {$name} носит {$clothing}
self-heal-action = Зализать раны
self-heal-using-other = {$name} закончил {$verb} часть {$name} ран
ent-SelfHealAction = Зализать раны

View File

@@ -37,3 +37,18 @@
interactSuccessString: hugging-success-generic
interactSuccessSound: /Audio/Effects/thudswoosh.ogg
messagePerceivedByOthers: hugging-success-generic-others
- type: SelfHeal
damageContainers:
- Biological
damage:
types:
Slash: -0.4
Piercing: -0.4
disallowedClothingUser:
- mask
disallowedClothingTarget:
- jumpsuit
- outerClothing
healingSound:
path: "/Audio/White/Felinid/lick.ogg"

View File

@@ -21,3 +21,12 @@
event: !type:HairballActionEvent
charges: 1
useDelay: 30
- type: entity
id: SelfHealAction
name: Lick wounds.
noSpawn: true
components:
- type: EntityTargetAction
event: !type:SelfHealEvent
icon: White/Icons/tongue.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B