Система лизания пиздец (#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
|
||||
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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
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