Система лизания пиздец (#429)
* Насрал пиздец * Немного говна * Готово ебана * Фиксы * А теперь * А так * Йес * Показываю * Работает * Дофиксы
This commit is contained in:
180
Content.Server/White/SelfHeal/SelfHealSystem.cs
Normal file
180
Content.Server/White/SelfHeal/SelfHealSystem.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Content.Shared/White/SelfHeal/SelfHealComponent.cs
Normal file
40
Content.Shared/White/SelfHeal/SelfHealComponent.cs
Normal 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
|
||||||
|
{
|
||||||
|
}
|
||||||
9
Content.Shared/White/SelfHeal/SelfHealDoAfterEvent.cs
Normal file
9
Content.Shared/White/SelfHeal/SelfHealDoAfterEvent.cs
Normal 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
|
||||||
|
{
|
||||||
|
}
|
||||||
BIN
Resources/Audio/White/Felinid/lick.ogg
Normal file
BIN
Resources/Audio/White/Felinid/lick.ogg
Normal file
Binary file not shown.
@@ -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
|
||||||
@@ -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 = Зализать раны
|
||||||
@@ -37,3 +37,18 @@
|
|||||||
interactSuccessString: hugging-success-generic
|
interactSuccessString: hugging-success-generic
|
||||||
interactSuccessSound: /Audio/Effects/thudswoosh.ogg
|
interactSuccessSound: /Audio/Effects/thudswoosh.ogg
|
||||||
messagePerceivedByOthers: hugging-success-generic-others
|
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"
|
||||||
|
|
||||||
|
|||||||
@@ -21,3 +21,12 @@
|
|||||||
event: !type:HairballActionEvent
|
event: !type:HairballActionEvent
|
||||||
charges: 1
|
charges: 1
|
||||||
useDelay: 30
|
useDelay: 30
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SelfHealAction
|
||||||
|
name: Lick wounds.
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: EntityTargetAction
|
||||||
|
event: !type:SelfHealEvent
|
||||||
|
icon: White/Icons/tongue.png
|
||||||
|
|||||||
BIN
Resources/Textures/White/Icons/tongue.png
Normal file
BIN
Resources/Textures/White/Icons/tongue.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 375 B |
Reference in New Issue
Block a user