Merge remote-tracking branch 'upstream/master' into ups

This commit is contained in:
Jabak
2024-07-29 12:58:16 +03:00
167 changed files with 2923 additions and 468 deletions

View File

@@ -212,6 +212,7 @@ public sealed partial class BlockingSystem : EntitySystem
hard: true,
collisionLayer: (int) CollisionGroup.WallLayer,
body: physicsComponent);
_physics.SetBodyType(user, BodyType.Static, body: physicsComponent);
}
component.IsBlocking = true;

View File

@@ -838,7 +838,7 @@ namespace Content.Shared.CCVar
/// de-admin them.
/// </summary>
public static readonly CVarDef<bool> AdminDeadminOnJoin =
CVarDef.Create("admin.deadmin_on_join", false, CVar.SERVERONLY);
CVarDef.Create("admin.deadmin_on_join", true, CVar.SERVERONLY);
/// <summary>
/// Overrides the name the client sees in ahelps. Set empty to disable.
@@ -851,7 +851,7 @@ namespace Content.Shared.CCVar
/// If 0, appearing as a new player is disabled.
/// </summary>
public static readonly CVarDef<int> NewPlayerThreshold =
CVarDef.Create("admin.new_player_threshold", 0, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
CVarDef.Create("admin.new_player_threshold", 4320, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
/// <summary>
/// How long an admin client can go without any input before being considered AFK.
@@ -1346,7 +1346,7 @@ namespace Content.Shared.CCVar
/// <summary>
/// Config for when the restart vote should be allowed to be called based on percentage of ghosts.
///
/// </summary>
public static readonly CVarDef<int> VoteRestartGhostPercentage =
CVarDef.Create("vote.restart_ghost_percentage", 75, CVar.SERVERONLY);
@@ -1441,7 +1441,7 @@ namespace Content.Shared.CCVar
/// Whether the arrivals terminal should be on a planet map.
/// </summary>
public static readonly CVarDef<bool> ArrivalsPlanet =
CVarDef.Create("shuttle.arrivals_planet", true, CVar.SERVERONLY);
CVarDef.Create("shuttle.arrivals_planet", false, CVar.SERVERONLY);
/// <summary>
/// Whether the arrivals shuttle is enabled.
@@ -1459,7 +1459,7 @@ namespace Content.Shared.CCVar
/// Cooldown between arrivals departures. This should be longer than the FTL time or it will double cycle.
/// </summary>
public static readonly CVarDef<float> ArrivalsCooldown =
CVarDef.Create("shuttle.arrivals_cooldown", 50f, CVar.SERVERONLY);
CVarDef.Create("shuttle.arrivals_cooldown", 10f, CVar.SERVERONLY);
/// <summary>
/// Are players allowed to return on the arrivals shuttle.

View File

@@ -38,7 +38,6 @@ public sealed partial class StaminaSystem : EntitySystem
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!; // WD EDIT
/// <summary>
/// How much of a buffer is there between the stun duration and when stuns can be re-applied.
@@ -365,7 +364,7 @@ public sealed partial class StaminaSystem : EntitySystem
continue;
// We were in crit so come out of it and continue.
if (!_statusEffectsSystem.HasStatusEffect(uid, "Stun") && comp.Critical) // WD EIT
if (comp.Critical)
{
ExitStamCrit(uid, comp);
continue;

View File

@@ -101,7 +101,7 @@ public abstract partial class SharedHandsSystem : EntitySystem
if (TryComp(session?.AttachedEntity, out HandsComponent? hands) && hands.ActiveHand != null)
// WD EDIT START
{
if (HasComp<BoltBarrageComponent>(hands.ActiveHandEntity))
if (HasComp<DeleteOnDropAttemptComponent>(hands.ActiveHandEntity))
{
if (_net.IsServer)
QueueDel(hands.ActiveHandEntity.Value);

View File

@@ -114,7 +114,7 @@ public sealed class HungerSystem : EntitySystem
return;
//WD start
if (_net.IsServer)
if (_net.IsServer && component.CurrentThreshold != HungerThreshold.Overfed)
{
var ev = new MoodEffectEvent("Hunger" + component.CurrentThreshold);
RaiseLocalEvent(uid, ev);

View File

@@ -112,10 +112,13 @@ public sealed class ThirstSystem : EntitySystem
_alerts.ClearAlertCategory(uid, AlertCategory.Thirst);
}
//WD start
var ev = new MoodEffectEvent("Thirst" + component.CurrentThirstThreshold);
RaiseLocalEvent(uid, ev);
//WD end
// WD start
if (component.CurrentThirstThreshold != ThirstThreshold.OverHydrated)
{
var ev = new MoodEffectEvent("Thirst" + component.CurrentThirstThreshold);
RaiseLocalEvent(uid, ev);
}
// WD end
switch (component.CurrentThirstThreshold)
{

View File

@@ -116,6 +116,9 @@ public abstract partial class SharedProjectileSystem : EntitySystem
return;
// WD START
if (args.Handled)
return;
if (component is {Penetrate: true, PenetratedUid: null} &&
TryComp(args.Target, out PenetratedComponent? penetrated) &&
penetrated is {ProjectileUid: null, IsPinned: false} &&

View File

@@ -13,4 +13,8 @@ public sealed partial class RCDAmmoComponent : Component
/// </summary>
[DataField("charges"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public int Charges = 30;
[DataField] public bool CanBeExamined = true; // WD
[DataField] public float ChargeCountModifier = 1; // WD
}

View File

@@ -1,3 +1,4 @@
using Content.Shared._White.RCD;
using Content.Shared.RCD.Systems;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
@@ -33,6 +34,12 @@ public sealed partial class RCDComponent : Component
[DataField, AutoNetworkedField]
public ProtoId<RCDPrototype> ProtoId { get; set; } = "Invalid";
/// <summary>
/// The ProtoId of the currently selected RCD prototype
/// </summary>
[DataField(required: true), AutoNetworkedField]
public HashSet<ProtoId<RCDCategoryPrototype>> CategoryPrototypes = default!;
/// <summary>
/// A cached copy of currently selected RCD prototype
/// </summary>

View File

@@ -1,3 +1,4 @@
using Content.Shared._White.RCD;
using Content.Shared.Physics;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Prototypes;
@@ -23,14 +24,14 @@ public sealed class RCDPrototype : IPrototype
/// <summary>
/// The name associated with the prototype
/// </summary>
[DataField("name"), ViewVariables(VVAccess.ReadOnly)]
public string SetName { get; private set; } = "Unknown";
[DataField, ViewVariables(VVAccess.ReadOnly)]
public string Name { get; private set; } = "Unknown";
/// <summary>
/// The name of the radial container that this prototype will be listed under on the RCD menu
/// </summary>
[DataField, ViewVariables(VVAccess.ReadOnly)]
public string Category { get; private set; } = "Undefined";
public ProtoId<RCDCategoryPrototype> Category { get; private set; } = "WallsAndFlooring"; // WD
/// <summary>
/// Texture path for this prototypes menu icon
@@ -42,7 +43,7 @@ public sealed class RCDPrototype : IPrototype
/// The entity prototype that will be constructed (mode dependent)
/// </summary>
[DataField, ViewVariables(VVAccess.ReadOnly)]
public string? Prototype { get; private set; } = string.Empty;
public ProtoId<EntityPrototype>? Prototype { get; private set; } = null;
/// <summary>
/// Number of charges consumed when the operation is completed
@@ -51,7 +52,7 @@ public sealed class RCDPrototype : IPrototype
public int Cost { get; private set; } = 1;
/// <summary>
/// The length of the operation
/// The length of the operation
/// </summary>
[DataField, ViewVariables(VVAccess.ReadOnly)]
public float Delay { get; private set; } = 1f;
@@ -75,7 +76,7 @@ public sealed class RCDPrototype : IPrototype
public CollisionGroup CollisionMask { get; private set; } = CollisionGroup.None;
/// <summary>
/// Specifies a set of custom collision bounds for determining whether the entity prototype will fit into a target tile
/// Specifies a set of custom collision bounds for determining whether the entity prototype will fit into a target tile
/// </summary>
/// <remarks>
/// Should be set assuming that the entity faces south.
@@ -106,7 +107,7 @@ public sealed class RCDPrototype : IPrototype
private Box2? _collisionBounds = null;
/// <summary>
/// The polygon shape associated with the prototype CollisionBounds (if set)
/// The polygon shape associated with the prototype CollisionBounds (if set)
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
public PolygonShape? CollisionPolygon { get; private set; } = null;

View File

@@ -4,6 +4,7 @@ using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.RCD.Components;
using Content.Shared.Stacks;
using Robust.Shared.Timing;
namespace Content.Shared.RCD.Systems;
@@ -13,20 +14,37 @@ public sealed class RCDAmmoSystem : EntitySystem
[Dependency] private readonly SharedChargesSystem _charges = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedStackSystem _stack = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RCDAmmoComponent, ComponentInit>(OnInit); // WD edit
SubscribeLocalEvent<RCDAmmoComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<RCDAmmoComponent, AfterInteractEvent>(OnAfterInteract);
}
// WD edit start
private void OnInit(EntityUid uid, RCDAmmoComponent rcdAmmoComponent, ComponentInit _)
{
if (TryComp<StackComponent>(uid, out var stackComponent))
rcdAmmoComponent.Charges = (int) (stackComponent.Count * rcdAmmoComponent.ChargeCountModifier);
else
rcdAmmoComponent.Charges = (int) (rcdAmmoComponent.Charges * rcdAmmoComponent.ChargeCountModifier);
}
// WD edit end
private void OnExamine(EntityUid uid, RCDAmmoComponent comp, ExaminedEvent args)
{
if (!args.IsInDetailsRange)
return;
if (!comp.CanBeExamined) // WD edit
return;
var examineMessage = Loc.GetString("rcd-ammo-component-on-examine", ("charges", comp.Charges));
args.PushText(examineMessage);
}
@@ -51,6 +69,15 @@ public sealed class RCDAmmoSystem : EntitySystem
}
_popup.PopupClient(Loc.GetString("rcd-ammo-component-after-interact-refilled"), target, user);
// WD edit start
if (TryComp<StackComponent>(uid, out var stackComponent))
{
var spent = (int) (count / comp.ChargeCountModifier) == 0 ? 1 : (int) (count / comp.ChargeCountModifier);
_stack.SetCount(uid, stackComponent.Count - spent);
}
// WD edit end
_charges.AddCharges(target, count, charges);
comp.Charges -= count;
Dirty(uid, comp);

View File

@@ -25,6 +25,7 @@ using Robust.Shared.Serialization;
using Robust.Shared.Timing;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared._White.ClothingGrant.Systems;
namespace Content.Shared.RCD.Systems;
@@ -75,7 +76,7 @@ public class RCDSystem : EntitySystem
if (component.AvailablePrototypes.Any())
{
component.ProtoId = component.AvailablePrototypes.First();
UpdateCachedPrototype(uid, component);
UpdateCachedPrototype(component);
Dirty(uid, component);
return;
@@ -96,7 +97,7 @@ public class RCDSystem : EntitySystem
// Set the current RCD prototype to the one supplied
component.ProtoId = args.ProtoId;
UpdateCachedPrototype(uid, component);
UpdateCachedPrototype(component);
Dirty(uid, component);
}
@@ -106,13 +107,14 @@ public class RCDSystem : EntitySystem
return;
// Update cached prototype if required
UpdateCachedPrototype(uid, component);
UpdateCachedPrototype(component);
var msg = Loc.GetString("rcd-component-examine-mode-details", ("mode", Loc.GetString(component.CachedPrototype.SetName)));
var msg = Loc.GetString("rcd-component-examine-mode-details", ("mode", Loc.GetString(component.CachedPrototype.Name)));
if (component.CachedPrototype.Mode == RcdMode.ConstructTile || component.CachedPrototype.Mode == RcdMode.ConstructObject)
var mode = component.CachedPrototype.Mode;
if (mode == RcdMode.ConstructTile || mode == RcdMode.ConstructObject)
{
var name = Loc.GetString(component.CachedPrototype.SetName);
var name = Loc.GetString(component.CachedPrototype.Name);
if (component.CachedPrototype.Prototype != null &&
_protoManager.TryIndex(component.CachedPrototype.Prototype, out var proto))
@@ -225,7 +227,7 @@ public class RCDSystem : EntitySystem
private void OnDoAfterAttempt(EntityUid uid, RCDComponent component, DoAfterAttemptEvent<RCDDoAfterEvent> args)
{
if (args.Event?.DoAfter?.Args == null)
if (args.Event?.DoAfter?.Args == null) // wtf if this
return;
// Exit if the RCD prototype has changed
@@ -302,7 +304,7 @@ public class RCDSystem : EntitySystem
public bool IsRCDOperationStillValid(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid? target, EntityUid user, bool popMsgs = true)
{
// Update cached prototype if required
UpdateCachedPrototype(uid, component);
UpdateCachedPrototype(component);
// Check that the RCD has enough ammo to get the job done
TryComp<LimitedChargesComponent>(uid, out var charges);
@@ -589,7 +591,7 @@ public class RCDSystem : EntitySystem
return boundingPolygon.ComputeAABB(boundingTransform, 0).Intersects(fixture.Shape.ComputeAABB(entXform, 0));
}
public void UpdateCachedPrototype(EntityUid uid, RCDComponent component)
public void UpdateCachedPrototype(RCDComponent component)
{
if (component.ProtoId.Id != component.CachedPrototype?.Prototype)
component.CachedPrototype = _protoManager.Index(component.ProtoId);

View File

@@ -1,5 +1,6 @@
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Whitelist;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
@@ -62,19 +63,31 @@ public sealed partial class MeleeWeaponComponent : Component
public bool Attacking = false;
// WD START
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool CanHeavyAttack = true;
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool CanAttackSelf = true;
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool CanMiss = true;
[DataField]
public EntityWhitelist? AttackWhitelist;
[DataField]
public EntityWhitelist? AttackBlacklist;
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool IgnoreResistances;
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float HeavyAttackStaminaCost = 8;
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public EntProtoId MissAnimation = "WeaponArcPunch";
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public EntProtoId DisarmAnimation = "WeaponArcDisarm";
// WD END

View File

@@ -365,6 +365,30 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
if (weaponUid == lightTarget)
return false;
// WD START
if (user == lightTarget && !weapon.CanAttackSelf)
return false;
if (lightTarget == null)
{
if (weapon.CanMiss)
break;
return false;
}
if (weapon.AttackWhitelist != null)
{
if (!weapon.AttackWhitelist.IsValid(lightTarget.Value, EntityManager))
return false;
}
if (weapon.AttackBlacklist != null)
{
if (weapon.AttackBlacklist.IsValid(lightTarget.Value, EntityManager))
return false;
}
// WD END
break;
case DisarmAttackEvent disarm:
var disarmTarget = GetEntity(disarm.Target);

View File

@@ -3,6 +3,7 @@ using Content.Shared.Inventory.Events;
using Robust.Shared.Serialization.Manager;
using Content.Shared.Tag;
using Content.Shared._White.ClothingGrant.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Shared._White.ClothingGrant.Systems;
@@ -40,24 +41,29 @@ public sealed class ClothingGrantingSystem : EntitySystem
return;
}
foreach (var (name, data) in component.Components)
{
var newComp = (Component) _componentFactory.GetComponent(name);
if (HasComp(args.Equipee, newComp.GetType()))
continue;
newComp.Owner = args.Equipee;
var temp = (object) newComp;
_serializationManager.CopyTo(data.Component, ref temp);
EntityManager.AddComponent(args.Equipee, (Component)temp!);
}
AddComponents(args.Equipee, component.Components);
component.IsActive = true;
Dirty(uid, component);
}
public void AddComponents(EntityUid uid, ComponentRegistry components)
{
foreach (var (name, data) in components)
{
var newComp = (Component) _componentFactory.GetComponent(name);
if (HasComp(uid, newComp.GetType()))
continue;
newComp.Owner = uid;
var temp = (object) newComp;
_serializationManager.CopyTo(data.Component, ref temp);
EntityManager.AddComponent(uid, (Component)temp!);
}
}
private void OnCompUnequip(EntityUid uid, ClothingGrantComponentComponent component, GotUnequippedEvent args)
{
if (!component.IsActive) return;

View File

@@ -1,29 +1,40 @@
using Content.Shared.Actions;
using Content.Shared.Magic;
namespace Content.Shared._White.Cult.Actions;
public sealed partial class CultTwistedConstructionActionEvent : EntityTargetActionEvent
public sealed partial class CultTwistedConstructionActionEvent : EntityTargetActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultSummonDaggerActionEvent : InstantActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultStunActionEvent : InstantActionEvent
{
}
public sealed partial class CultSummonDaggerActionEvent : InstantActionEvent
public sealed partial class CultTeleportTargetActionEvent : EntityTargetActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultStunTargetActionEvent : EntityTargetActionEvent
public sealed partial class CultElectromagneticPulseInstantActionEvent : InstantActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultTeleportTargetActionEvent : EntityTargetActionEvent
{
}
public sealed partial class CultElectromagneticPulseInstantActionEvent : InstantActionEvent
{
}
public sealed partial class CultShadowShacklesTargetActionEvent : EntityTargetActionEvent
public sealed partial class CultShadowShacklesTargetActionEvent : EntityTargetActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultSummonCombatEquipmentTargetActionEvent : EntityTargetActionEvent
@@ -31,8 +42,10 @@ public sealed partial class CultSummonCombatEquipmentTargetActionEvent : EntityT
}
[Virtual]
public partial class CultConcealPresenceInstantActionEvent : InstantActionEvent
public partial class CultConcealPresenceInstantActionEvent : InstantActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultConcealInstantActionEvent : CultConcealPresenceInstantActionEvent
@@ -43,8 +56,10 @@ public sealed partial class CultRevealInstantActionEvent : CultConcealPresenceIn
{
}
public sealed partial class CultBloodRitesInstantActionEvent : InstantActionEvent
public sealed partial class CultBloodRitesInstantActionEvent : InstantActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultBloodSpearRecallInstantActionEvent : InstantActionEvent

View File

@@ -11,7 +11,7 @@ namespace Content.Shared._White.Cult.Components;
/// This is used for tagging a mob as a cultist.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class CultistComponent : ShowCultHudComponent
public sealed partial class CultistComponent : Component
{
[DataField("greetSound", customTypeSerializer: typeof(SoundSpecifierTypeSerializer))]
public SoundSpecifier? CultistGreetSound = new SoundPathSpecifier("/Audio/CultSounds/fart.ogg");
@@ -41,7 +41,7 @@ public sealed partial class CultistComponent : ShowCultHudComponent
public static string CultSummonCombatEquipmentAction = "ActionCultSummonCombatEquipment";
public static string CultStunAction = "ActionCultStun";
public static string CultStunAction = "InstantActionCultStun";
public static string CultShadowShacklesAction = "ActionCultShadowShackles";

View File

@@ -0,0 +1,8 @@
namespace Content.Shared._White.Cult.Components;
[RegisterComponent]
public sealed partial class DeleteOnDropAttemptComponent : Component
{
[DataField]
public string Message = string.Empty;
}

View File

@@ -1,5 +1,6 @@
using Content.Shared.Damage;
using Content.Shared.Damage;
using Robust.Shared.Audio;
using Robust.Shared.Map;
using Robust.Shared.Serialization;
namespace Content.Shared._White.Cult.Pylon;
@@ -64,6 +65,25 @@ public sealed partial class SharedPylonComponent : Component
[DataField("wallConvertEffect")]
public string WallConvertEffect = "CultWallGlow";
public static bool CheckForStructure(EntityCoordinates coordinates, IEntityManager entMan, float range, EntityUid? pylon = null)
{
var lookupSystem = entMan.System<EntityLookupSystem>();
var entities = lookupSystem.GetEntitiesInRange(coordinates, range);
foreach (var ent in entities)
{
if (ent == pylon)
continue;
if (!entMan.TryGetComponent<MetaDataComponent>(ent, out var metadata))
continue;
if (metadata.EntityPrototype?.ID is "CultPylon")
return true;
}
return false;
}
}
[Serializable, NetSerializable]

View File

@@ -1,7 +1,9 @@
using Content.Shared._White.Chaplain;
using Content.Shared._White.Cult.Components;
using Content.Shared.Actions;
using Content.Shared.Examine;
using Content.Shared.Hands;
using Content.Shared.Projectiles;
using Content.Shared.StatusEffect;
using Content.Shared.Stunnable;
using Content.Shared.Throwing;
@@ -15,6 +17,7 @@ public sealed class BloodSpearSystem : EntitySystem
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly HolyWeaponSystem _holy = default!;
[Dependency] private readonly INetManager _net = default!;
public override void Initialize()
@@ -23,7 +26,8 @@ public sealed class BloodSpearSystem : EntitySystem
SubscribeLocalEvent<BloodSpearComponent, ComponentRemove>(OnRemove);
SubscribeLocalEvent<BloodSpearComponent, GotEquippedHandEvent>(OnEquip);
SubscribeLocalEvent<BloodSpearComponent, ThrowDoHitEvent>(OnThrowDoHit);
SubscribeLocalEvent<BloodSpearComponent, ThrowDoHitEvent>(OnThrowDoHit,
before: new[] {typeof(SharedProjectileSystem)});
SubscribeLocalEvent<BloodSpearComponent, ExaminedEvent>(OnExamine);
}
@@ -34,11 +38,20 @@ public sealed class BloodSpearSystem : EntitySystem
private void OnThrowDoHit(Entity<BloodSpearComponent> ent, ref ThrowDoHitEvent args)
{
if (HasComp<CultistComponent>(args.Target) || HasComp<ConstructComponent>(args.Target))
{
args.Handled = true;
return;
}
if (!TryComp(args.Target, out StatusEffectsComponent? status))
return;
if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(6), true, status))
return;
if (!_holy.IsHoldingHolyWeapon(args.Target))
{
if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(4), true, status))
return;
}
if (_net.IsClient)
return;

View File

@@ -1,3 +1,5 @@
using Content.Shared._White.Cult.Components;
namespace Content.Shared._White.Cult.Systems;
/// <summary>
@@ -9,16 +11,18 @@ public sealed class CultistSystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<Components.CultistComponent, ComponentStartup>(OnInit);
SubscribeLocalEvent<Components.CultistComponent, ComponentShutdown>(OnRemove);
SubscribeLocalEvent<ConstructComponent, ComponentStartup>(OnInit);
SubscribeLocalEvent<ConstructComponent, ComponentShutdown>(OnRemove);
SubscribeLocalEvent<CultistComponent, ComponentStartup>(OnInit);
SubscribeLocalEvent<CultistComponent, ComponentShutdown>(OnRemove);
}
private void OnInit(EntityUid uid, Components.CultistComponent component, ComponentStartup args)
private void OnInit<T>(EntityUid uid, T component, ComponentStartup args)
{
RaiseLocalEvent(new EventCultistComponentState(true));
}
private void OnRemove(EntityUid uid, Components.CultistComponent component, ComponentShutdown args)
private void OnRemove<T>(EntityUid uid, T component, ComponentShutdown args)
{
RaiseLocalEvent(new EventCultistComponentState(false));
}

View File

@@ -0,0 +1,19 @@
using Content.Shared._White.Cult.Components;
using Content.Shared.Examine;
namespace Content.Shared._White.Cult.Systems;
public sealed class DeleteOnDropAttemptSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DeleteOnDropAttemptComponent, ExaminedEvent>(OnExamine);
}
private void OnExamine(Entity<DeleteOnDropAttemptComponent> ent, ref ExaminedEvent args)
{
args.PushMarkup(Loc.GetString(ent.Comp.Message));
}
}

View File

@@ -3,29 +3,25 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations;
namespace Content.Shared._White.Mood;
[Prototype("moodEffect")]
[Prototype]
public sealed class MoodEffectPrototype : IPrototype
{
[ViewVariables]
[IdDataField]
public string ID { get; } = default!;
[DataField("desc", required: true)]
[DataField(required: true)]
public string Description = string.Empty;
[DataField("moodChange", customTypeSerializer: typeof(EnumSerializer), required: true)]
[DataField(customTypeSerializer: typeof(EnumSerializer), required: true)]
public Enum MoodChange = default!;
[DataField("positiveEffect", required: true)]
public bool PositiveEffect;
[DataField] public bool Positive;
[DataField("timeout")]
public int Timeout;
[DataField] public int Timeout;
[DataField("hidden")]
public bool Hidden;
[DataField] public bool Hidden;
//If mob already has effect of the same category, the new one will replace the old one.
[DataField("category")]
public string? Category;
// If mob already has effect of the same category, the new one will replace the old one.
[DataField] public string? Category;
}

View File

@@ -0,0 +1,17 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Shared._White.RCD;
[Prototype("rcdCategory")]
public sealed class RCDCategoryPrototype : IPrototype
{
[IdDataField]
public string ID { get; private set; } = default!;
[DataField]
public string TooltipBase = "rcd-category-";
[DataField(required: true)]
public SpriteSpecifier SpritePath = default!;
}