Magic staves + wands (#9070)
@@ -0,0 +1,20 @@
|
|||||||
|
using Content.Shared.Weapons.Ranged.Components;
|
||||||
|
|
||||||
|
namespace Content.Client.Weapons.Ranged.Systems;
|
||||||
|
|
||||||
|
public partial class GunSystem
|
||||||
|
{
|
||||||
|
protected override void InitializeBasicEntity()
|
||||||
|
{
|
||||||
|
base.InitializeBasicEntity();
|
||||||
|
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, UpdateAmmoCounterEvent>(OnBasicEntityAmmoCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBasicEntityAmmoCount(EntityUid uid, BasicEntityAmmoProviderComponent component, UpdateAmmoCounterEvent args)
|
||||||
|
{
|
||||||
|
if (args.Control is DefaultStatusControl control && component.Count != null && component.Capacity != null)
|
||||||
|
{
|
||||||
|
control.Update(component.Count.Value, component.Capacity.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using Content.Shared.Polymorph;
|
||||||
|
using Content.Shared.Sound;
|
||||||
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
|
namespace Content.Server.Polymorph.Components;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class PolymorphOnCollideComponent : Component
|
||||||
|
{
|
||||||
|
[DataField("polymorph", required: true, customTypeSerializer:typeof(PrototypeIdSerializer<PolymorphPrototype>))]
|
||||||
|
public string Polymorph = default!;
|
||||||
|
|
||||||
|
[DataField("whitelist", required: true)]
|
||||||
|
public EntityWhitelist Whitelist = default!;
|
||||||
|
|
||||||
|
[DataField("blacklist")]
|
||||||
|
public EntityWhitelist? Blacklist;
|
||||||
|
|
||||||
|
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Magic/forcewall.ogg");
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using Content.Server.Polymorph.Components;
|
||||||
|
using Content.Shared.Projectiles;
|
||||||
|
using Content.Shared.Sound;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Physics.Dynamics;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
|
namespace Content.Server.Polymorph.Systems;
|
||||||
|
|
||||||
|
public partial class PolymorphableSystem
|
||||||
|
{
|
||||||
|
// Need to do this so we don't get a collection enumeration error in physics by polymorphing
|
||||||
|
// an entity we're colliding with
|
||||||
|
private Queue<PolymorphQueuedData> _queuedPolymorphUpdates = new();
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
while (_queuedPolymorphUpdates.TryDequeue(out var data))
|
||||||
|
{
|
||||||
|
if (Deleted(data.Ent))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var ent = PolymorphEntity(data.Ent, data.Polymorph);
|
||||||
|
if (ent != null)
|
||||||
|
{
|
||||||
|
SoundSystem.Play(data.Sound.GetSound(), Filter.Pvs(ent.Value, entityManager: EntityManager),
|
||||||
|
ent.Value, data.Sound.Params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeCollide()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<PolymorphOnCollideComponent, StartCollideEvent>(OnPolymorphCollide);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPolymorphCollide(EntityUid uid, PolymorphOnCollideComponent component, StartCollideEvent args)
|
||||||
|
{
|
||||||
|
if (args.OurFixture.ID != SharedProjectileSystem.ProjectileFixture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var other = args.OtherFixture.Body.Owner;
|
||||||
|
if (!component.Whitelist.IsValid(other)
|
||||||
|
|| component.Blacklist != null && component.Blacklist.IsValid(other))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_queuedPolymorphUpdates.Enqueue(new (other, component.Sound, component.Polymorph));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PolymorphQueuedData
|
||||||
|
{
|
||||||
|
public EntityUid Ent;
|
||||||
|
public SoundSpecifier Sound;
|
||||||
|
public string Polymorph;
|
||||||
|
|
||||||
|
public PolymorphQueuedData(EntityUid ent, SoundSpecifier sound, string polymorph)
|
||||||
|
{
|
||||||
|
Ent = ent;
|
||||||
|
Sound = sound;
|
||||||
|
Polymorph = polymorph;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.Actions;
|
using Content.Server.Actions;
|
||||||
|
using Content.Server.Body.Components;
|
||||||
using Content.Server.Buckle.Components;
|
using Content.Server.Buckle.Components;
|
||||||
using Content.Server.Inventory;
|
using Content.Server.Inventory;
|
||||||
using Content.Server.Mind.Commands;
|
using Content.Server.Mind.Commands;
|
||||||
@@ -12,8 +13,11 @@ using Content.Shared.Damage;
|
|||||||
using Content.Shared.Hands.EntitySystems;
|
using Content.Shared.Hands.EntitySystems;
|
||||||
using Content.Shared.Polymorph;
|
using Content.Shared.Polymorph;
|
||||||
using Robust.Server.Containers;
|
using Robust.Server.Containers;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Physics.Dynamics;
|
||||||
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
@@ -39,6 +43,7 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
SubscribeLocalEvent<PolymorphableComponent, ComponentStartup>(OnStartup);
|
SubscribeLocalEvent<PolymorphableComponent, ComponentStartup>(OnStartup);
|
||||||
SubscribeLocalEvent<PolymorphableComponent, PolymorphActionEvent>(OnPolymorphActionEvent);
|
SubscribeLocalEvent<PolymorphableComponent, PolymorphActionEvent>(OnPolymorphActionEvent);
|
||||||
|
|
||||||
|
InitializeCollide();
|
||||||
InitializeMap();
|
InitializeMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ namespace Content.Server.Projectiles.Components
|
|||||||
[DataField("deleteOnCollide")]
|
[DataField("deleteOnCollide")]
|
||||||
public bool DeleteOnCollide { get; } = true;
|
public bool DeleteOnCollide { get; } = true;
|
||||||
|
|
||||||
|
[DataField("ignoreResistances")]
|
||||||
|
public bool IgnoreResistances { get; } = false;
|
||||||
|
|
||||||
// Get that juicy FPS hit sound
|
// Get that juicy FPS hit sound
|
||||||
[DataField("soundHit")] public SoundSpecifier? SoundHit;
|
[DataField("soundHit")] public SoundSpecifier? SoundHit;
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace Content.Server.Projectiles
|
|||||||
|
|
||||||
var otherEntity = args.OtherFixture.Body.Owner;
|
var otherEntity = args.OtherFixture.Body.Owner;
|
||||||
|
|
||||||
var modifiedDamage = _damageableSystem.TryChangeDamage(otherEntity, component.Damage);
|
var modifiedDamage = _damageableSystem.TryChangeDamage(otherEntity, component.Damage, component.IgnoreResistances);
|
||||||
component.DamagedEntity = true;
|
component.DamagedEntity = true;
|
||||||
|
|
||||||
if (modifiedDamage is not null && EntityManager.EntityExists(component.Shooter))
|
if (modifiedDamage is not null && EntityManager.EntityExists(component.Shooter))
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using Content.Shared.Sound;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
|
||||||
|
namespace Content.Server.Weapon.Ranged.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Responsible for handling recharging a basic entity ammo provider over time.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class RechargeBasicEntityAmmoComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("minRechargeCooldown")]
|
||||||
|
public float MinRechargeCooldown = 30f;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("maxRechargeCooldown")]
|
||||||
|
public float MaxRechargeCooldown = 45f;
|
||||||
|
|
||||||
|
[DataField("rechargeSound")]
|
||||||
|
public SoundSpecifier RechargeSound = new SoundPathSpecifier("/Audio/Magic/forcewall.ogg")
|
||||||
|
{
|
||||||
|
Params = AudioParams.Default.WithVolume(-5f)
|
||||||
|
};
|
||||||
|
|
||||||
|
[DataField("accumulatedFrametime")]
|
||||||
|
public float AccumulatedFrameTime;
|
||||||
|
/// <summary>
|
||||||
|
/// Number of seconds until the next recharge.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float NextRechargeTime = 0f;
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
using Content.Server.Weapon.Ranged.Components;
|
||||||
|
using Content.Shared.Examine;
|
||||||
|
using Content.Shared.Weapons.Ranged.Components;
|
||||||
|
using Content.Shared.Weapons.Ranged.Systems;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Server.Weapon.Ranged.Systems;
|
||||||
|
|
||||||
|
public sealed class RechargeBasicEntityAmmoSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly SharedGunSystem _gun = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<RechargeBasicEntityAmmoComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<RechargeBasicEntityAmmoComponent, ExaminedEvent>(OnExamined);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
foreach (var (recharge, ammo) in
|
||||||
|
EntityQuery<RechargeBasicEntityAmmoComponent, BasicEntityAmmoProviderComponent>())
|
||||||
|
{
|
||||||
|
if (ammo.Count is null || ammo.Count == ammo.Capacity)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
recharge.AccumulatedFrameTime += frameTime;
|
||||||
|
|
||||||
|
if (recharge.AccumulatedFrameTime < recharge.NextRechargeTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
recharge.AccumulatedFrameTime -= recharge.NextRechargeTime;
|
||||||
|
UpdateCooldown(recharge);
|
||||||
|
|
||||||
|
|
||||||
|
if (_gun.UpdateBasicEntityAmmoCount(ammo.Owner, ammo.Count.Value + 1, ammo))
|
||||||
|
{
|
||||||
|
SoundSystem.Play(recharge.RechargeSound.GetSound(), Filter.Pvs(recharge.Owner), recharge.Owner,
|
||||||
|
recharge.RechargeSound.Params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInit(EntityUid uid, RechargeBasicEntityAmmoComponent component, ComponentInit args)
|
||||||
|
{
|
||||||
|
UpdateCooldown(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnExamined(EntityUid uid, RechargeBasicEntityAmmoComponent component, ExaminedEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<BasicEntityAmmoProviderComponent>(uid, out var ammo)
|
||||||
|
|| ammo.Count == ammo.Capacity)
|
||||||
|
{
|
||||||
|
args.PushMarkup(Loc.GetString("recharge-basic-entity-ammo-full"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeLeft = component.NextRechargeTime - component.AccumulatedFrameTime;
|
||||||
|
args.PushMarkup(Loc.GetString("recharge-basic-entity-ammo-can-recharge", ("seconds", Math.Round(timeLeft, 1))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCooldown(RechargeBasicEntityAmmoComponent component)
|
||||||
|
{
|
||||||
|
component.NextRechargeTime = _random.NextFloat(component.MinRechargeCooldown, component.MaxRechargeCooldown);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
|
namespace Content.Shared.Weapons.Ranged.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Simply provides a certain capacity of entities that cannot be reloaded through normal means and have
|
||||||
|
/// no special behavior like cycling, magazine
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class BasicEntityAmmoProviderComponent : AmmoProviderComponent
|
||||||
|
{
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("proto", required: true, customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||||
|
public string Proto = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Max capacity.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("capacity")]
|
||||||
|
public int? Capacity = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Actual ammo left. Initialized to capacity unless they are non-null and differ.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("count")]
|
||||||
|
public int? Count = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class BasicEntityAmmoProviderComponentState : ComponentState
|
||||||
|
{
|
||||||
|
public int? Capacity;
|
||||||
|
public int? Count;
|
||||||
|
|
||||||
|
public BasicEntityAmmoProviderComponentState(int? capacity, int? count)
|
||||||
|
{
|
||||||
|
Capacity = capacity;
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
using Content.Shared.Weapons.Ranged.Components;
|
||||||
|
using Content.Shared.Weapons.Ranged.Events;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Weapons.Ranged.Systems;
|
||||||
|
|
||||||
|
public abstract partial class SharedGunSystem
|
||||||
|
{
|
||||||
|
protected virtual void InitializeBasicEntity()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, ComponentInit>(OnBasicEntityInit);
|
||||||
|
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, TakeAmmoEvent>(OnBasicEntityTakeAmmo);
|
||||||
|
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, GetAmmoCountEvent>(OnBasicEntityAmmoCount);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, ComponentGetState>(OnBasicEntityGetState);
|
||||||
|
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, ComponentHandleState>(OnBasicEntityHandleState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBasicEntityGetState(EntityUid uid, BasicEntityAmmoProviderComponent component, ref ComponentGetState args)
|
||||||
|
{
|
||||||
|
args.State = new BasicEntityAmmoProviderComponentState(component.Capacity, component.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBasicEntityHandleState(EntityUid uid, BasicEntityAmmoProviderComponent component, ref ComponentHandleState args)
|
||||||
|
{
|
||||||
|
if (args.Current is BasicEntityAmmoProviderComponentState state)
|
||||||
|
{
|
||||||
|
component.Capacity = state.Capacity;
|
||||||
|
component.Count = state.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBasicEntityInit(EntityUid uid, BasicEntityAmmoProviderComponent component, ComponentInit args)
|
||||||
|
{
|
||||||
|
if (component.Count is null)
|
||||||
|
{
|
||||||
|
component.Count = component.Capacity;
|
||||||
|
Dirty(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateBasicEntityAppearance(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBasicEntityTakeAmmo(EntityUid uid, BasicEntityAmmoProviderComponent component, TakeAmmoEvent args)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < args.Shots; i++)
|
||||||
|
{
|
||||||
|
if (component.Count <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (component.Count != null)
|
||||||
|
{
|
||||||
|
component.Count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ent = Spawn(component.Proto, args.Coordinates);
|
||||||
|
args.Ammo.Add(EnsureComp<AmmoComponent>(ent));
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateBasicEntityAppearance(component);
|
||||||
|
Dirty(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBasicEntityAmmoCount(EntityUid uid, BasicEntityAmmoProviderComponent component, ref GetAmmoCountEvent args)
|
||||||
|
{
|
||||||
|
args.Capacity = component.Capacity ?? int.MaxValue;
|
||||||
|
args.Count = component.Count ?? int.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateBasicEntityAppearance(BasicEntityAmmoProviderComponent component)
|
||||||
|
{
|
||||||
|
if (!Timing.IsFirstTimePredicted || !TryComp<AppearanceComponent>(component.Owner, out var appearance)) return;
|
||||||
|
appearance.SetData(AmmoVisuals.HasAmmo, component.Count != 0);
|
||||||
|
appearance.SetData(AmmoVisuals.AmmoCount, component.Count ?? int.MaxValue);
|
||||||
|
appearance.SetData(AmmoVisuals.AmmoMax, component.Capacity ?? int.MaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Public API
|
||||||
|
|
||||||
|
public bool UpdateBasicEntityAmmoCount(EntityUid uid, int count, BasicEntityAmmoProviderComponent? component = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref component))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (count > component.Capacity)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
component.Count = count;
|
||||||
|
Dirty(component);
|
||||||
|
UpdateBasicEntityAppearance(component);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -83,6 +83,7 @@ public abstract partial class SharedGunSystem
|
|||||||
protected void UpdateBatteryAppearance(EntityUid uid, BatteryAmmoProviderComponent component)
|
protected void UpdateBatteryAppearance(EntityUid uid, BatteryAmmoProviderComponent component)
|
||||||
{
|
{
|
||||||
if (!TryComp<AppearanceComponent>(uid, out var appearance)) return;
|
if (!TryComp<AppearanceComponent>(uid, out var appearance)) return;
|
||||||
|
appearance.SetData(AmmoVisuals.HasAmmo, component.Shots != 0);
|
||||||
appearance.SetData(AmmoVisuals.AmmoCount, component.Shots);
|
appearance.SetData(AmmoVisuals.AmmoCount, component.Shots);
|
||||||
appearance.SetData(AmmoVisuals.AmmoMax, component.Capacity);
|
appearance.SetData(AmmoVisuals.AmmoMax, component.Capacity);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ public abstract partial class SharedGunSystem
|
|||||||
{
|
{
|
||||||
// Copy the magazine's appearance data
|
// Copy the magazine's appearance data
|
||||||
appearance?.SetData(AmmoVisuals.MagLoaded, magLoaded);
|
appearance?.SetData(AmmoVisuals.MagLoaded, magLoaded);
|
||||||
|
appearance?.SetData(AmmoVisuals.HasAmmo, count != 0);
|
||||||
appearance?.SetData(AmmoVisuals.AmmoCount, count);
|
appearance?.SetData(AmmoVisuals.AmmoCount, count);
|
||||||
appearance?.SetData(AmmoVisuals.AmmoMax, capacity);
|
appearance?.SetData(AmmoVisuals.AmmoMax, capacity);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,9 @@ public partial class SharedGunSystem
|
|||||||
private void UpdateRevolverAppearance(RevolverAmmoProviderComponent component)
|
private void UpdateRevolverAppearance(RevolverAmmoProviderComponent component)
|
||||||
{
|
{
|
||||||
if (!TryComp<AppearanceComponent>(component.Owner, out var appearance)) return;
|
if (!TryComp<AppearanceComponent>(component.Owner, out var appearance)) return;
|
||||||
appearance.SetData(AmmoVisuals.AmmoCount, GetRevolverCount(component));
|
var count = GetRevolverCount(component);
|
||||||
|
appearance.SetData(AmmoVisuals.HasAmmo, count != 0);
|
||||||
|
appearance.SetData(AmmoVisuals.AmmoCount, count);
|
||||||
appearance.SetData(AmmoVisuals.AmmoMax, component.Capacity);
|
appearance.SetData(AmmoVisuals.AmmoMax, component.Capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ public abstract partial class SharedGunSystem : EntitySystem
|
|||||||
InitializeChamberMagazine();
|
InitializeChamberMagazine();
|
||||||
InitializeMagazine();
|
InitializeMagazine();
|
||||||
InitializeRevolver();
|
InitializeRevolver();
|
||||||
|
InitializeBasicEntity();
|
||||||
|
|
||||||
// Interactions
|
// Interactions
|
||||||
SubscribeLocalEvent<GunComponent, GetVerbsEvent<AlternativeVerb>>(OnAltVerb);
|
SubscribeLocalEvent<GunComponent, GetVerbsEvent<AlternativeVerb>>(OnAltVerb);
|
||||||
@@ -389,5 +390,6 @@ public enum AmmoVisuals : byte
|
|||||||
Spent,
|
Spent,
|
||||||
AmmoCount,
|
AmmoCount,
|
||||||
AmmoMax,
|
AmmoMax,
|
||||||
|
HasAmmo, // used for generic visualizers. c# stuff can just check ammocount != 0
|
||||||
MagLoaded,
|
MagLoaded,
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Resources/Audio/Magic/staff_animation.ogg
Normal file
BIN
Resources/Audio/Magic/staff_change.ogg
Normal file
BIN
Resources/Audio/Magic/staff_chaos.ogg
Normal file
BIN
Resources/Audio/Magic/staff_door.ogg
Normal file
BIN
Resources/Audio/Magic/staff_healing.ogg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# BEHOLD:
|
||||||
|
# FIRST EVER USAGE OF ROBUST GENERIC ATTRIBUTION STANDARD IN SPACE STATION 14
|
||||||
|
|
||||||
|
- files: [ "staff_animation.ogg", "staff_change.ogg", "staff_chaos.ogg", "staff_door.ogg", "staff_healing.ogg" ]
|
||||||
|
license: "CC-BY-SA-3.0"
|
||||||
|
copyright: "https://github.com/tgstation/tgstation/commit/906fb0682bab6a0975b45036001c54f021f58ae7"
|
||||||
BIN
Resources/Audio/Weapons/Guns/Gunshots/Magic/staff_animation.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Gunshots/Magic/staff_change.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Gunshots/Magic/staff_chaos.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Gunshots/Magic/staff_door.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Gunshots/Magic/staff_healing.ogg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
recharge-basic-entity-ammo-can-recharge = It will recharge its ammo in [color=yellow]{$seconds}[/color] seconds.
|
||||||
|
recharge-basic-entity-ammo-full = It doesn't need to recharge its ammo yet.
|
||||||
@@ -100,3 +100,14 @@
|
|||||||
amount: 1
|
amount: 1
|
||||||
- id: MedkitCombatFilled
|
- id: MedkitCombatFilled
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: ClothingBeltWand
|
||||||
|
id: ClothingBeltWandFilled
|
||||||
|
suffix: Filled
|
||||||
|
components:
|
||||||
|
- type: StorageFill
|
||||||
|
contents:
|
||||||
|
- id: WeaponWandPolymorphCarp
|
||||||
|
- id: WeaponWandFireball
|
||||||
|
- id: WeaponWandDeath
|
||||||
|
- id: WeaponWandPolymorphDoor
|
||||||
|
|||||||
@@ -503,3 +503,19 @@
|
|||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Belt/suspenders.rsi
|
sprite: Clothing/Belt/suspenders.rsi
|
||||||
quickEquip: true
|
quickEquip: true
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: ClothingBeltStorageBase
|
||||||
|
id: ClothingBeltWand
|
||||||
|
name: wand belt
|
||||||
|
description: A belt designed to hold various rods of power. A veritable fanny pack of exotic magic.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Clothing/Belt/wand.rsi
|
||||||
|
- type: Clothing
|
||||||
|
sprite: Clothing/Belt/wand.rsi
|
||||||
|
- type: Storage
|
||||||
|
capacity: 120
|
||||||
|
whitelist:
|
||||||
|
tags:
|
||||||
|
- WizardWand
|
||||||
|
|||||||
@@ -69,6 +69,9 @@
|
|||||||
- type: TypingIndicator
|
- type: TypingIndicator
|
||||||
proto: alien
|
proto: alien
|
||||||
- type: NoSlip
|
- type: NoSlip
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- Carp
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: magicarp
|
name: magicarp
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
- type: entity
|
||||||
|
id: WeaponStaffBase
|
||||||
|
abstract: true
|
||||||
|
parent: BaseItem
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Magic/staves.rsi
|
||||||
|
- type: Item
|
||||||
|
sprite: Objects/Weapons/Guns/Magic/staves.rsi
|
||||||
|
HeldPrefix: staff
|
||||||
|
size: 60
|
||||||
|
- type: Gun
|
||||||
|
fireRate: 1
|
||||||
|
selectedMode: SemiAuto
|
||||||
|
availableModes:
|
||||||
|
- SemiAuto
|
||||||
|
- type: AmmoCounter
|
||||||
|
# All staves recharge. Wands are not.
|
||||||
|
- type: RechargeBasicEntityAmmo
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- WizardStaff
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
- type: entity
|
||||||
|
id: WeaponWandBase
|
||||||
|
abstract: true
|
||||||
|
parent: BaseItem
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Magic/wands.rsi
|
||||||
|
- type: Item
|
||||||
|
sprite: Objects/Weapons/Guns/Magic/wands.rsi
|
||||||
|
HeldPrefix: wand
|
||||||
|
size: 30
|
||||||
|
- type: Gun
|
||||||
|
fireRate: 0.5
|
||||||
|
selectedMode: SemiAuto
|
||||||
|
availableModes:
|
||||||
|
- SemiAuto
|
||||||
|
- type: AmmoCounter
|
||||||
|
# These will only do anything if the effect layer is actually set.
|
||||||
|
- type: Appearance
|
||||||
|
- type: GenericVisualizer
|
||||||
|
visuals:
|
||||||
|
enum.AmmoVisuals.HasAmmo:
|
||||||
|
effect:
|
||||||
|
True: { visible: True }
|
||||||
|
False: { visible: False }
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- WizardWand
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# To be implemented: see #9072
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: staff of healing
|
||||||
|
parent: WeaponStaffBase
|
||||||
|
id: WeaponStaffHealing
|
||||||
|
description: You don't foresee having to use this in your quest for carnage too often.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: healing
|
||||||
|
- type: Item
|
||||||
|
HeldPrefix: healing
|
||||||
|
- type: Gun
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Weapons/Guns/Gunshots/Magic/staff_healing.ogg
|
||||||
|
- type: BasicEntityAmmoProvider
|
||||||
|
proto: ProjectileHealingBolt
|
||||||
|
capacity: 10
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: staff of entrance
|
||||||
|
parent: WeaponStaffBase
|
||||||
|
id: WeaponStaffPolymorphDoor
|
||||||
|
description: For when you need a get-away route.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: door
|
||||||
|
- type: Item
|
||||||
|
HeldPrefix: door
|
||||||
|
- type: Gun
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Weapons/Guns/Gunshots/Magic/staff_door.ogg
|
||||||
|
- type: BasicEntityAmmoProvider
|
||||||
|
proto: ProjectilePolyboltDoor
|
||||||
|
capacity: 10
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
- type: entity
|
||||||
|
name: wand of carp polymorph
|
||||||
|
parent: WeaponWandBase
|
||||||
|
id: WeaponWandPolymorphCarp
|
||||||
|
description: For when you need a carp filet quick and the clown is looking juicy.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: poly
|
||||||
|
- state: poly-effect
|
||||||
|
map: ["effect"]
|
||||||
|
- type: Gun
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Weapons/Guns/Gunshots/Magic/staff_animation.ogg
|
||||||
|
- type: BasicEntityAmmoProvider
|
||||||
|
proto: ProjectilePolyboltCarp
|
||||||
|
capacity: 5
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: wand of fireball
|
||||||
|
parent: WeaponWandBase
|
||||||
|
id: WeaponWandFireball
|
||||||
|
description: Great big balls of fire!
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: fire
|
||||||
|
- state: fire-effect
|
||||||
|
map: ["effect"]
|
||||||
|
- type: Gun
|
||||||
|
fireRate: 0.25
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Magic/fireball.ogg
|
||||||
|
- type: BasicEntityAmmoProvider
|
||||||
|
proto: ProjectileFireball
|
||||||
|
capacity: 5
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: magical wand of instant death
|
||||||
|
parent: WeaponWandBase
|
||||||
|
id: WeaponWandDeath
|
||||||
|
description: Only the best and brightest of the Space Wizards R&D team worked together to create this beauty.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: death
|
||||||
|
- state: death-effect
|
||||||
|
map: ["effect"]
|
||||||
|
- type: Gun
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Weapons/Guns/Gunshots/mateba.ogg # PUNCH
|
||||||
|
- type: BasicEntityAmmoProvider
|
||||||
|
proto: BulletInstakillMagic
|
||||||
|
capacity: 3
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: wand of entrance
|
||||||
|
parent: WeaponWandBase
|
||||||
|
id: WeaponWandPolymorphDoor
|
||||||
|
description: For when you need a get-away route.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: door
|
||||||
|
- state: door-effect
|
||||||
|
map: ["effect"]
|
||||||
|
- type: Gun
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Weapons/Guns/Gunshots/Magic/staff_door.ogg
|
||||||
|
- type: BasicEntityAmmoProvider
|
||||||
|
proto: ProjectilePolyboltDoor
|
||||||
|
capacity: 10
|
||||||
@@ -15,3 +15,87 @@
|
|||||||
intensitySlope: 6
|
intensitySlope: 6
|
||||||
totalIntensity: 200
|
totalIntensity: 200
|
||||||
maxTileBreak: 0
|
maxTileBreak: 0
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: ProjectilePolyboltCarp
|
||||||
|
name: carp polybolt
|
||||||
|
description: Nooo, I don't wanna be fish!
|
||||||
|
parent: BaseBullet
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Projectiles/magic.rsi
|
||||||
|
layers:
|
||||||
|
- state: spell
|
||||||
|
color: '#00FF00'
|
||||||
|
- type: PolymorphOnCollide
|
||||||
|
polymorph: WizardForcedCarp
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Body
|
||||||
|
blacklist:
|
||||||
|
tags:
|
||||||
|
- Carp # can't re-polymorph
|
||||||
|
- type: Projectile
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Poison: 5
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: ProjectilePolyboltDoor
|
||||||
|
name: door polybolt
|
||||||
|
description: Nooo, I don't wanna be door!
|
||||||
|
parent: BaseBullet
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Projectiles/magic.rsi
|
||||||
|
layers:
|
||||||
|
- state: spell
|
||||||
|
color: brown
|
||||||
|
- type: PolymorphOnCollide
|
||||||
|
polymorph: WizardWallDoor
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Airlock
|
||||||
|
- Firelock
|
||||||
|
tags:
|
||||||
|
- Wall
|
||||||
|
- type: Projectile
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Poison: 5
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: ProjectileHealingBolt
|
||||||
|
name: healing bolt
|
||||||
|
description: I COMMAND YOU TO LIVE!
|
||||||
|
parent: BaseBullet
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Projectiles/magic.rsi
|
||||||
|
layers:
|
||||||
|
- state: spell
|
||||||
|
color: white
|
||||||
|
- type: Projectile
|
||||||
|
damage:
|
||||||
|
groups: # good enough. Maybe make it call the rejuvenate command later.
|
||||||
|
Brute: -900
|
||||||
|
Burn: -900
|
||||||
|
Airloss: -600
|
||||||
|
Toxin: -600
|
||||||
|
ignoreResistances: true
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BulletInstakillMagic
|
||||||
|
name: magical lead cylinder
|
||||||
|
parent: BaseBulletHighVelocity
|
||||||
|
noSpawn: true
|
||||||
|
description: This looks familiar.
|
||||||
|
components:
|
||||||
|
- type: Projectile
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Piercing: 300
|
||||||
|
ignoreResistances: true
|
||||||
|
|||||||
@@ -18,6 +18,26 @@
|
|||||||
revertOnCrit: true
|
revertOnCrit: true
|
||||||
revertOnDeath: true
|
revertOnDeath: true
|
||||||
|
|
||||||
|
- type: polymorph
|
||||||
|
id: WizardForcedCarp
|
||||||
|
entity: MobCarpMagic
|
||||||
|
forced: true
|
||||||
|
inventory: None
|
||||||
|
transferName: true
|
||||||
|
transferDamage: true
|
||||||
|
revertOnCrit: false
|
||||||
|
revertOnDeath: true
|
||||||
|
|
||||||
|
- type: polymorph
|
||||||
|
id: WizardWallDoor
|
||||||
|
entity: WoodDoor
|
||||||
|
forced: true
|
||||||
|
inventory: None
|
||||||
|
transferName: false
|
||||||
|
transferDamage: false
|
||||||
|
revertOnCrit: false
|
||||||
|
revertOnDeath: false
|
||||||
|
|
||||||
# this is a test for transferring some visual appearance stuff
|
# this is a test for transferring some visual appearance stuff
|
||||||
- type: polymorph
|
- type: polymorph
|
||||||
id: TestHumanMorph
|
id: TestHumanMorph
|
||||||
|
|||||||
@@ -51,6 +51,9 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
id: CaptainSabre
|
id: CaptainSabre
|
||||||
|
|
||||||
|
- type: Tag
|
||||||
|
id: Carp
|
||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: Cartridge
|
id: Cartridge
|
||||||
|
|
||||||
@@ -426,6 +429,12 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
id: Window
|
id: Window
|
||||||
|
|
||||||
|
- type: Tag
|
||||||
|
id: WizardWand # that evil vvizard vvand
|
||||||
|
|
||||||
|
- type: Tag
|
||||||
|
id: WizardStaff
|
||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: Wirecutter
|
id: Wirecutter
|
||||||
|
|
||||||
|
|||||||
BIN
Resources/Textures/Clothing/Belt/wand.rsi/equipped-BELT.png
Normal file
|
After Width: | Height: | Size: 501 B |
BIN
Resources/Textures/Clothing/Belt/wand.rsi/icon.png
Normal file
|
After Width: | Height: | Size: 514 B |
BIN
Resources/Textures/Clothing/Belt/wand.rsi/inhand-left.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
Resources/Textures/Clothing/Belt/wand.rsi/inhand-right.png
Normal file
|
After Width: | Height: | Size: 483 B |
26
Resources/Textures/Clothing/Belt/wand.rsi/meta.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "tgstation at https://github.com/tgstation/tgstation/commit/270acce4f551253d8ac75de19236b8b4be598f7f",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-BELT",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-left",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-right",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 782 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 949 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1010 B |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,522 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "/tg/station at https://github.com/tgstation/tgstation/commit/270acce4f551253d8ac75de19236b8b4be598f7f. edited by mirrorcult to allow layering",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "animation",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "healing",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "door",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "staff-inhand-left",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "animation-inhand-left",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "healing-inhand-left",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "door-inhand-left",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "staff-inhand-right",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "animation-inhand-right",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "healing-inhand-right",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "door-inhand-right",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "change",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nothing",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "chaos",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "change-inhand-left",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "chaos-inhand-left",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "change-inhand-right",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4,
|
||||||
|
0.4
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "chaos-inhand-right",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 534 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 278 B |
|
After Width: | Height: | Size: 340 B |
|
After Width: | Height: | Size: 182 B |
BIN
Resources/Textures/Objects/Weapons/Guns/Magic/wands.rsi/door.png
Normal file
|
After Width: | Height: | Size: 379 B |
|
After Width: | Height: | Size: 442 B |
BIN
Resources/Textures/Objects/Weapons/Guns/Magic/wands.rsi/fire.png
Normal file
|
After Width: | Height: | Size: 284 B |
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "/tg/station at https://github.com/tgstation/tgstation/commit/270acce4f551253d8ac75de19236b8b4be598f7f. edited by mirrorcult to allow layering",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "death-effect",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "poly-effect",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fire-effect",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "death"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "poly"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fire"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "door-effect"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "door"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nothing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wand-inhand-left",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wand-inhand-right",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 342 B |
|
After Width: | Height: | Size: 510 B |
BIN
Resources/Textures/Objects/Weapons/Guns/Magic/wands.rsi/poly.png
Normal file
|
After Width: | Height: | Size: 299 B |
|
After Width: | Height: | Size: 316 B |
|
After Width: | Height: | Size: 322 B |
|
Before Width: | Height: | Size: 356 B After Width: | Height: | Size: 396 B |
|
Before Width: | Height: | Size: 906 B After Width: | Height: | Size: 555 B |
|
Before Width: | Height: | Size: 320 B After Width: | Height: | Size: 263 B |
|
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 218 B |
|
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 384 B |
|
Before Width: | Height: | Size: 395 B |
|
Before Width: | Height: | Size: 417 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 468 B After Width: | Height: | Size: 398 B |
@@ -7,16 +7,6 @@
|
|||||||
"y": 32
|
"y": 32
|
||||||
},
|
},
|
||||||
"states": [
|
"states": [
|
||||||
{
|
|
||||||
"name": "energy",
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
0.1,
|
|
||||||
0.1,
|
|
||||||
0.1
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "magicm",
|
"name": "magicm",
|
||||||
"delays": [
|
"delays": [
|
||||||
@@ -59,26 +49,6 @@
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "energy2",
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
0.1,
|
|
||||||
0.1,
|
|
||||||
0.1
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "energy3",
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
0.1,
|
|
||||||
0.1,
|
|
||||||
0.1
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "chronobolt"
|
"name": "chronobolt"
|
||||||
},
|
},
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 314 B |