Files
OldThink/Content.Server/Revenant/EntitySystems/RevenantSystem.cs
Remuchi 0b2238b57a Merge remote-tracking branch 'upstream/master' into upstream
# Conflicts:
#	Content.Client/Clothing/ClientClothingSystem.cs
#	Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
#	Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs
#	Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml
#	Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs
#	Content.Server/Administration/Commands/AdminWhoCommand.cs
#	Content.Server/Bed/Sleep/SleepingSystem.cs
#	Content.Server/Body/Components/BloodstreamComponent.cs
#	Content.Server/Body/Components/RespiratorComponent.cs
#	Content.Server/Body/Systems/InternalsSystem.cs
#	Content.Server/Body/Systems/RespiratorSystem.cs
#	Content.Server/Chat/Managers/IChatManager.cs
#	Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs
#	Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs
#	Content.Server/Electrocution/ElectrocutionSystem.cs
#	Content.Server/Holosign/HolosignProjectorComponent.cs
#	Content.Server/Holosign/HolosignSystem.cs
#	Content.Server/Remotes/DoorRemoteSystem.cs
#	Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs
#	Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs
#	Content.Server/Store/Systems/StoreSystem.Ui.cs
#	Content.Server/VendingMachines/VendingMachineSystem.cs
#	Content.Server/VoiceMask/VoiceMaskSystem.Equip.cs
#	Content.Server/VoiceMask/VoiceMaskSystem.cs
#	Content.Server/VoiceMask/VoiceMaskerComponent.cs
#	Content.Server/Zombies/ZombieSystem.cs
#	Content.Shared/Bed/Sleep/SleepEmitSoundComponent.cs
#	Content.Shared/Cuffs/SharedCuffableSystem.cs
#	Content.Shared/VoiceMask/SharedVoiceMaskSystem.cs
#	Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
#	Resources/Maps/bagel.yml
#	Resources/Maps/box.yml
#	Resources/Maps/centcomm.yml
#	Resources/Maps/cluster.yml
#	Resources/Maps/europa.yml
#	Resources/Maps/marathon.yml
#	Resources/Maps/meta.yml
#	Resources/Maps/omega.yml
#	Resources/Maps/origin.yml
#	Resources/Maps/packed.yml
#	Resources/Maps/reach.yml
#	Resources/Prototypes/Catalog/Fills/Boxes/syndicate.yml
#	Resources/Prototypes/Catalog/Fills/Lockers/security.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/medidrobe.yml
#	Resources/Prototypes/Entities/Clothing/Hands/colored.yml
#	Resources/Prototypes/Entities/Clothing/Neck/mantles.yml
#	Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml
#	Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Cigarettes/packs.yml
#	Resources/Prototypes/Entities/Objects/Misc/land_mine.yml
#	Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml
#	Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml
#	Resources/Prototypes/Entities/Structures/Decoration/curtains.yml
#	Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml
#	Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml
#	Resources/Prototypes/Entities/Structures/Holographic/projections.yml
#	Resources/Prototypes/Entities/Structures/Machines/lathe.yml
#	Resources/Prototypes/Maps/marathon.yml
#	Resources/Prototypes/Maps/packed.yml
#	Resources/Prototypes/Recipes/Lathes/security.yml
#	Resources/Prototypes/Roles/Jobs/Engineering/atmospheric_technician.yml
#	Resources/Prototypes/Roles/Jobs/Security/detective.yml
#	Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml
#	Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml
#	Resources/Prototypes/Roles/Jobs/Security/security_officer.yml
#	Resources/Prototypes/Roles/Jobs/Security/warden.yml
#	Resources/Textures/Clothing/OuterClothing/Armor/lingarmor.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/equipped-OUTERCLOTHING.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/icon-open.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/icon.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/inhand-left.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/inhand-right.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/open-equipped-OUTERCLOTHING.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/open-inhand-left.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/open-inhand-right.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/equipped-OUTERCLOTHING.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/icon-open.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/icon.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/inhand-left.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/inhand-right.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/open-equipped-OUTERCLOTHING.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/open-inhand-left.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/open-inhand-right.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_cmo.rsi/equipped-OUTERCLOTHING.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_cmo.rsi/icon-open.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_cmo.rsi/icon.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_cmo.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_cmo.rsi/open-equipped-OUTERCLOTHING.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_sci.rsi/equipped-OUTERCLOTHING-body-slim.png
#	Resources/Textures/Clothing/OuterClothing/Coats/labcoat_sci.rsi/open-equipped-OUTERCLOTHING-body-slim.png
#	Resources/Textures/Clothing/OuterClothing/Hardsuits/cybersun.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Hardsuits/lingspacesuit.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Hardsuits/paramed.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Hardsuits/spatio.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiecommander.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Hardsuits/syndieelite.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Misc/nunrobe.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Misc/plaguedoctorsuit.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/Suits/atmos_firesuit.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coat.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatatmos.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatbar.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatcap.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatcargo.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatce.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatcentcom.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatchem.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatclown.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatcmo.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatengi.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatgen.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coathop.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coathos.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coathydro.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatjani.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatmed.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatmime.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatminer.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatnomi.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatparamed.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatqm.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatrd.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatrobo.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatsci.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatsec.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatviro.rsi/meta.json
#	Resources/Textures/Clothing/OuterClothing/WinterCoats/coatwarden.rsi/meta.json
#	Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/meta.json
#	Resources/Textures/Clothing/Shoes/Specific/bling.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpskirt/atmosf.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpskirt/centcomformaldress.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpskirt/hosformaldress.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpskirt/operative_s.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpsuit/atmos.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpsuit/centcomformal.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpsuit/hosformal.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpsuit/operative.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/meta.json
#	Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/meta.json
#	Resources/Textures/Interface/Alerts/essence_counter.rsi/essence0.png
#	Resources/Textures/Interface/Alerts/essence_counter.rsi/essence16.png
#	Resources/Textures/Objects/Storage/boxes.rsi/meta.json
#	Resources/Textures/Structures/Doors/Airlocks/Glass/atmospherics.rsi/meta.json
#	Resources/Textures/Structures/Doors/Airlocks/Standard/atmospherics.rsi/meta.json
#	Resources/Textures/Structures/Doors/Airlocks/highsec/highsec.rsi/meta.json
2024-03-30 10:36:17 +07:00

241 lines
8.8 KiB
C#

using System.Numerics;
using Content.Server.Actions;
using Content.Server.GameTicking;
using Content.Server.Store.Components;
using Content.Server.Store.Systems;
using Content.Shared._White.Chaplain;
using Content.Shared.Alert;
using Content.Shared.Damage;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Eye;
using Content.Shared.FixedPoint;
using Content.Shared.Interaction;
using Content.Shared.Maps;
using Content.Shared.Mobs.Systems;
using Content.Shared.Physics;
using Content.Shared.Popups;
using Content.Shared.Revenant;
using Content.Shared.Revenant.Components;
using Content.Shared.StatusEffect;
using Content.Shared.Stunnable;
using Content.Shared.Tag;
using Content.Shared.Weapons.Melee;
using Content.Shared.Weapons.Melee.Events;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Revenant.EntitySystems;
public sealed partial class RevenantSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ActionsSystem _action = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly DamageableSystem _damage = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly GameTicker _ticker = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly PhysicsSystem _physics = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedEyeSystem _eye = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
[Dependency] private readonly SharedInteractionSystem _interact = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedStunSystem _stun = default!;
[Dependency] private readonly StoreSystem _store = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly VisibilitySystem _visibility = default!;
[ValidatePrototypeId<EntityPrototype>]
private const string RevenantShopId = "ActionRevenantShop";
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RevenantComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<RevenantComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<RevenantComponent, RevenantShopActionEvent>(OnShop);
SubscribeLocalEvent<RevenantComponent, DamageChangedEvent>(OnDamage);
SubscribeLocalEvent<RevenantComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<RevenantComponent, StatusEffectAddedEvent>(OnStatusAdded);
SubscribeLocalEvent<RevenantComponent, StatusEffectEndedEvent>(OnStatusEnded);
SubscribeLocalEvent<RoundEndTextAppendEvent>(_ => MakeVisible(true));
SubscribeLocalEvent<RevenantComponent, AttackedEvent>(OnAttacked); // WD EDIT
InitializeAbilities();
}
// WD START
private void OnAttacked(Entity<RevenantComponent> ent, ref AttackedEvent args)
{
if (!HasComp<HolyWeaponComponent>(args.Used) || !TryComp(args.Used, out MeleeWeaponComponent? weapon))
return;
args.BonusDamage = weapon.Damage;
}
// WD END
private void OnStartup(EntityUid uid, RevenantComponent component, ComponentStartup args)
{
//update the icon
ChangeEssenceAmount(uid, 0, component);
//default the visuals
_appearance.SetData(uid, RevenantVisuals.Corporeal, false);
_appearance.SetData(uid, RevenantVisuals.Harvesting, false);
_appearance.SetData(uid, RevenantVisuals.Stunned, false);
if (_ticker.RunLevel == GameRunLevel.PostRound && TryComp<VisibilityComponent>(uid, out var visibility))
{
_visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Ghost, false);
_visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false);
_visibility.RefreshVisibility(uid, visibility);
}
//ghost vision
if (TryComp(uid, out EyeComponent? eye))
{
_eye.SetVisibilityMask(uid, eye.VisibilityMask | (int) (VisibilityFlags.Ghost), eye);
}
}
private void OnMapInit(EntityUid uid, RevenantComponent component, MapInitEvent args)
{
_action.AddAction(uid, ref component.Action, RevenantShopId);
}
private void OnStatusAdded(EntityUid uid, RevenantComponent component, StatusEffectAddedEvent args)
{
if (args.Key == "Stun")
_appearance.SetData(uid, RevenantVisuals.Stunned, true);
}
private void OnStatusEnded(EntityUid uid, RevenantComponent component, StatusEffectEndedEvent args)
{
if (args.Key == "Stun")
_appearance.SetData(uid, RevenantVisuals.Stunned, false);
}
private void OnExamine(EntityUid uid, RevenantComponent component, ExaminedEvent args)
{
if (args.Examiner == args.Examined)
{
args.PushMarkup(Loc.GetString("revenant-essence-amount",
("current", component.Essence.Int()), ("max", component.EssenceRegenCap.Int())));
}
}
private void OnDamage(EntityUid uid, RevenantComponent component, DamageChangedEvent args)
{
if (!HasComp<CorporealComponent>(uid) || args.DamageDelta == null)
return;
var essenceDamage = args.DamageDelta.GetTotal().Float() * component.DamageToEssenceCoefficient * -1;
ChangeEssenceAmount(uid, essenceDamage, component);
}
public bool ChangeEssenceAmount(EntityUid uid, FixedPoint2 amount, RevenantComponent? component = null, bool allowDeath = true, bool regenCap = false)
{
if (!Resolve(uid, ref component))
return false;
if (!allowDeath && component.Essence + amount <= 0)
return false;
component.Essence += amount;
Dirty(uid, component);
if (regenCap)
FixedPoint2.Min(component.Essence, component.EssenceRegenCap);
if (TryComp<StoreComponent>(uid, out var store))
_store.UpdateUserInterface(uid, uid, store);
_alerts.ShowAlert(uid, AlertType.Essence);
if (component.Essence <= 0)
{
Spawn(component.SpawnOnDeathPrototype, Transform(uid).Coordinates);
QueueDel(uid);
}
return true;
}
private bool TryUseAbility(EntityUid uid, RevenantComponent component, FixedPoint2 abilityCost, Vector2 debuffs)
{
if (component.Essence <= abilityCost)
{
_popup.PopupEntity(Loc.GetString("revenant-not-enough-essence"), uid, uid);
return false;
}
var tileref = Transform(uid).Coordinates.GetTileRef();
if (tileref != null)
{
if(_physics.GetEntitiesIntersectingBody(uid, (int) CollisionGroup.Impassable).Count > 0)
{
_popup.PopupEntity(Loc.GetString("revenant-in-solid"), uid, uid);
return false;
}
}
ChangeEssenceAmount(uid, abilityCost, component, false);
_statusEffects.TryAddStatusEffect<CorporealComponent>(uid, "Corporeal", TimeSpan.FromSeconds(debuffs.Y), false);
_stun.TryStun(uid, TimeSpan.FromSeconds(debuffs.X), false);
return true;
}
private void OnShop(EntityUid uid, RevenantComponent component, RevenantShopActionEvent args)
{
if (!TryComp<StoreComponent>(uid, out var store))
return;
_store.ToggleUi(uid, uid, store);
}
public void MakeVisible(bool visible)
{
var query = EntityQueryEnumerator<RevenantComponent, VisibilityComponent>();
while (query.MoveNext(out var uid, out _, out var vis))
{
if (visible)
{
_visibility.AddLayer(uid, vis, (int) VisibilityFlags.Normal, false);
_visibility.RemoveLayer(uid, vis, (int) VisibilityFlags.Ghost, false);
}
else
{
_visibility.AddLayer(uid, vis, (int) VisibilityFlags.Ghost, false);
_visibility.RemoveLayer(uid, vis, (int) VisibilityFlags.Normal, false);
}
_visibility.RefreshVisibility(uid, vis);
}
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<RevenantComponent>();
while (query.MoveNext(out var uid, out var rev))
{
rev.Accumulator += frameTime;
if (rev.Accumulator <= 1)
continue;
rev.Accumulator -= 1;
if (rev.Essence < rev.EssenceRegenCap)
{
ChangeEssenceAmount(uid, rev.EssencePerSecond, rev, regenCap: true);
}
}
}
}