Merge branch 'master' into RefactorMouseFilterMode

This commit is contained in:
ShadowCommander
2020-03-10 19:42:21 -07:00
75 changed files with 779 additions and 4295 deletions

View File

@@ -55,9 +55,6 @@ namespace Content.Server.Administration
return;
}
if(mind.IsVisitingEntity)
mind.UnVisit();
mindComponent.Mind?.TransferTo(null);
mind.TransferTo(target);

View File

@@ -31,9 +31,10 @@ namespace Content.Server.GameObjects.Components.Construction
SpriteComponent Sprite;
ITransformComponent Transform;
#pragma warning disable 649
#pragma warning disable 649
[Dependency] private IRobustRandom _random;
#pragma warning restore 649
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
#pragma warning restore 649
public override void Initialize()
{
@@ -46,6 +47,13 @@ namespace Content.Server.GameObjects.Components.Construction
public bool AttackBy(AttackByEventArgs eventArgs)
{
var playerEntity = eventArgs.User;
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
if (!interactionSystem.InRangeUnobstructed(playerEntity.Transform.MapPosition, Owner.Transform.WorldPosition, ignoredEnt: Owner, insideBlockerValid: true))
{
return false;
}
var stage = Prototype.Stages[Stage];
if (TryProcessStep(stage.Forward, eventArgs.AttackWith))

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Construction;
@@ -29,7 +29,6 @@ namespace Content.Server.GameObjects.Components.Construction
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
{
base.HandleMessage(message, netChannel, component);
switch (message)
{
case TryStartStructureConstructionMessage tryStart:
@@ -43,7 +42,9 @@ namespace Content.Server.GameObjects.Components.Construction
var prototype = _prototypeManager.Index<ConstructionPrototype>(prototypeName);
var transform = Owner.Transform;
if (!loc.InRange(_mapManager, transform.GridPosition, InteractionSystem.InteractionRange))
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
if (!interactionSystem.InRangeUnobstructed(loc.ToMap(_mapManager), Owner.Transform.WorldPosition, ignoredEnt: Owner, insideBlockerValid: true))
{
return;
}

View File

@@ -78,11 +78,16 @@ namespace Content.Server.GameObjects
public bool CanPickup(IEntity user)
{
var coords = Owner.Transform.GridPosition;
if (!ActionBlockerSystem.CanPickup(user)) return false;
if (user.Transform.MapID != Owner.Transform.MapID)
return false;
var userPos = user.Transform.MapPosition;
var itemPos = Owner.Transform.WorldPosition;
return _entitySystemManager.GetEntitySystem<InteractionSystem>()
.InRangeUnobstructed(coords, user.Transform.GridPosition, ignoredEnt:Owner);
.InRangeUnobstructed(userPos, itemPos, ignoredEnt: Owner, insideBlockerValid:true);
}
public bool AttackHand(AttackHandEventArgs eventArgs)

View File

@@ -9,6 +9,7 @@ using Robust.Server.GameObjects.Components.UserInterface;
using Robust.Server.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
namespace Content.Server.GameObjects.Components.Medical
@@ -20,6 +21,7 @@ namespace Content.Server.GameObjects.Components.Medical
private AppearanceComponent _appearance;
private BoundUserInterface _userInterface;
private ContainerSlot _bodyContainer;
private readonly Vector2 _ejectOffset = new Vector2(-0.5f, 0f);
public bool IsOccupied => _bodyContainer.ContainedEntity != null;
public override void Initialize()
@@ -61,7 +63,7 @@ namespace Content.Server.GameObjects.Components.Medical
var dmgDict = new Dictionary<string, int>();
foreach (var dmgType in (DamageType[])Enum.GetValues(typeof(DamageType)))
foreach (var dmgType in (DamageType[]) Enum.GetValues(typeof(DamageType)))
{
if (damageable.CurrentDamage.TryGetValue(dmgType, out var amount))
{
@@ -70,7 +72,7 @@ namespace Content.Server.GameObjects.Components.Medical
}
return new MedicalScannerBoundUserInterfaceState(
deathThresholdValue-currentHealth,
deathThresholdValue - currentHealth,
deathThresholdValue,
dmgDict);
}
@@ -160,7 +162,9 @@ namespace Content.Server.GameObjects.Components.Medical
public void EjectBody()
{
_bodyContainer.Remove(_bodyContainer.ContainedEntity);
var containedEntity = _bodyContainer.ContainedEntity;
_bodyContainer.Remove(containedEntity);
containedEntity.Transform.WorldPosition += _ejectOffset;
UpdateUserInterface();
UpdateAppearance();
}

View File

@@ -72,6 +72,11 @@ namespace Content.Server.GameObjects
{
return true;
}
bool IActionBlocker.CanAttack()
{
return true;
}
}
/// <summary>
@@ -128,6 +133,11 @@ namespace Content.Server.GameObjects
{
return false;
}
bool IActionBlocker.CanAttack()
{
return false;
}
}
/// <summary>
@@ -204,5 +214,10 @@ namespace Content.Server.GameObjects
{
return false;
}
bool IActionBlocker.CanAttack()
{
return false;
}
}
}

View File

@@ -117,6 +117,11 @@ namespace Content.Server.GameObjects
return CurrentDamageState.CanEmote();
}
bool IActionBlocker.CanAttack()
{
return CurrentDamageState.CanAttack();
}
List<DamageThreshold> IOnDamageBehavior.GetAllDamageThresholds()
{
var thresholdlist = DamageTemplate.DamageThresholds;

View File

@@ -134,7 +134,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
for (var i = 0; i < increments; i++)
{
var castAngle = new Angle(baseAngle + increment * i);
var res = _physicsManager.IntersectRay(mapId, new CollisionRay(position, castAngle.ToVec(), 23), _range, ignore);
var res = _physicsManager.IntersectRay(mapId, new CollisionRay(position, castAngle.ToVec(), 23), _range, ignore, ignoreNonHardCollidables: true);
if (res.HitEntity != null)
{
resSet.Add(res.HitEntity);

View File

@@ -90,7 +90,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
var angle = new Angle(clickLocation.Position - userPosition);
var ray = new CollisionRay(userPosition, angle.ToVec(), (int)(CollisionGroup.Impassable | CollisionGroup.MobImpassable));
var rayCastResults = IoCManager.Resolve<IPhysicsManager>().IntersectRay(user.Transform.MapID, ray, MaxLength, user);
var rayCastResults = IoCManager.Resolve<IPhysicsManager>().IntersectRay(user.Transform.MapID, ray, MaxLength, user, ignoreNonHardCollidables: true);
Hit(rayCastResults, energyModifier, user);
AfterEffects(user, rayCastResults, angle, energyModifier);

View File

@@ -1,32 +1,106 @@
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
/// <summary>
/// Passes information about the projectiles to be fired by AmmoWeapons
/// </summary>
[RegisterComponent]
public class BallisticBulletComponent : Component
{
public override string Name => "BallisticBullet";
private BallisticCaliber _caliber;
private string _projectileType;
private bool _spent;
/// <summary>
/// Cartridge calibre, restricts what AmmoWeapons this ammo can be fired from.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public BallisticCaliber Caliber { get => _caliber; set => _caliber = value; }
public string ProjectileType => _projectileType;
public BallisticCaliber Caliber => _caliber;
public bool Spent
{
get => _spent;
set => _spent = value;
}
private string _projectileID;
/// <summary>
/// YAML ID of the projectiles to be created when firing this ammo.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public string ProjectileID { get => _projectileID; set => _projectileID = value; }
private int _projectilesFired;
/// <summary>
/// How many copies of the projectile are shot.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public int ProjectilesFired { get => _projectilesFired; set => _projectilesFired = value; }
private float _spreadStdDev_Ammo;
/// <summary>
/// Weapons that fire projectiles from ammo types.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float SpreadStdDev_Ammo { get => _spreadStdDev_Ammo; set => _spreadStdDev_Ammo = value; }
private float _evenSpreadAngle_Ammo;
/// <summary>
/// Arc angle of shotgun pellet spreads, only used if multiple projectiles are being fired.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float EvenSpreadAngle_Ammo { get => _evenSpreadAngle_Ammo; set => _evenSpreadAngle_Ammo = value; }
private float _velocity_Ammo;
/// <summary>
/// Adds additional velocity to the projectile, on top of what it already has.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float Velocity_Ammo { get => _velocity_Ammo; set => _velocity_Ammo = value; }
private bool _spent;
/// <summary>
/// If the ammo cartridge has been shot already.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool Spent { get => _spent; set => _spent = value; }
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _caliber, "caliber", BallisticCaliber.Unspecified);
serializer.DataField(ref _projectileType, "projectile", null);
serializer.DataField(ref _projectileID, "projectile", null);
serializer.DataField(ref _spent, "spent", false);
serializer.DataField(ref _projectilesFired, "projectilesfired", 1);
serializer.DataField(ref _spreadStdDev_Ammo, "ammostddev", 0);
serializer.DataField(ref _evenSpreadAngle_Ammo, "ammospread", 0);
serializer.DataField(ref _velocity_Ammo, "ammovelocity", 0);
}
}
public enum BallisticCaliber
{
Unspecified = 0,
// .32
A32,
// .357
A357,
// .44
A44,
// .45mm
A45mm,
// .50 cal
A50,
// 5.56mm
A556mm,
// 6.5mm
A65mm,
// 7.62mm
A762mm,
// 9mm
A9mm,
// 10mm
A10mm,
// 20mm
A20mm,
// 24mm
A24mm,
// 12g
A12g,
}
}

View File

@@ -74,7 +74,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
}
}
_updateAppearance();
UpdateAppearance();
OnAmmoCountChanged?.Invoke();
_appearance.SetData(BallisticMagazineVisuals.AmmoCapacity, Capacity);
@@ -99,7 +99,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
_bulletContainer.Insert(bullet);
_loadedBullets.Push(bullet);
_updateAppearance();
UpdateAppearance();
OnAmmoCountChanged?.Invoke();
}
@@ -122,7 +122,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
_bulletContainer.Remove(bullet);
}
_updateAppearance();
UpdateAppearance();
OnAmmoCountChanged?.Invoke();
return bullet;
}
@@ -224,7 +224,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
return false;
}
private void _updateAppearance()
private void UpdateAppearance()
{
_appearance.SetData(BallisticMagazineVisuals.AmmoLeft, CountLoaded);
}
@@ -278,5 +278,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
// 24mm
A24mm,
// 12g
A12g,
}
}

View File

@@ -21,6 +21,9 @@ using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
/// <summary>
/// Guns that have a magazine.
/// </summary>
[RegisterComponent]
public class BallisticMagazineWeaponComponent : BallisticWeaponComponent, IUse, IAttackBy, IMapInit
{
@@ -46,7 +49,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
[ViewVariables] private bool _autoEjectMagazine;
[ViewVariables] private AppearanceComponent _appearance;
private static readonly Direction[] _randomBulletDirs =
private static readonly Direction[] RandomBulletDirs =
{
Direction.North,
Direction.East,
@@ -54,12 +57,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
Direction.West
};
protected override int ChamberCount => 1;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _magazineTypes, "magazines",
new List<BallisticMagazineType> {BallisticMagazineType.Unspecified});
serializer.DataField(ref _defaultMagazine, "default_magazine", null);
@@ -72,7 +72,6 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
public override void Initialize()
{
base.Initialize();
_appearance = Owner.GetComponent<AppearanceComponent>();
}
@@ -80,57 +79,44 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
protected override void Startup()
{
base.Startup();
_magazineSlot = ContainerManagerComponent.Ensure<ContainerSlot>("ballistic_gun_magazine", Owner);
if (Magazine != null)
{
// Already got magazine from loading a container.
Magazine.GetComponent<BallisticMagazineComponent>().OnAmmoCountChanged += _magazineAmmoCountChanged;
Magazine.GetComponent<BallisticMagazineComponent>().OnAmmoCountChanged += MagazineAmmoCountChanged;
}
_updateAppearance();
UpdateAppearance();
}
public bool InsertMagazine(IEntity magazine, bool playSound = true)
{
if (!magazine.TryGetComponent(out BallisticMagazineComponent component))
if (!magazine.TryGetComponent(out BallisticMagazineComponent magazinetype))
{
throw new ArgumentException("Not a magazine", nameof(magazine));
}
if (!MagazineTypes.Contains(component.MagazineType))
if (!MagazineTypes.Contains(magazinetype.MagazineType))
{
throw new ArgumentException("Wrong magazine type", nameof(magazine));
}
if (component.Caliber != Caliber)
{
throw new ArgumentException("Wrong caliber", nameof(magazine));
}
if (!_magazineSlot.Insert(magazine))
{
return false;
}
if (_magInSound != null)
{
Owner.GetComponent<SoundComponent>().Play(_magInSound);
}
component.OnAmmoCountChanged += _magazineAmmoCountChanged;
magazinetype.OnAmmoCountChanged += MagazineAmmoCountChanged;
if (GetChambered(0) == null)
{
// No bullet in chamber, load one from magazine.
var bullet = component.TakeBullet();
var bullet = magazinetype.TakeBullet();
if (bullet != null)
{
LoadIntoChamber(0, bullet);
}
}
_updateAppearance();
UpdateAppearance();
Dirty();
return true;
}
@@ -142,7 +128,6 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
return false;
}
if (_magazineSlot.Remove(entity))
{
entity.Transform.GridPosition = Owner.Transform.GridPosition;
@@ -150,14 +135,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
Owner.GetComponent<SoundComponent>().Play(_magOutSound, AudioParams.Default.WithVolume(20));
}
_updateAppearance();
UpdateAppearance();
Dirty();
entity.GetComponent<BallisticMagazineComponent>().OnAmmoCountChanged -= _magazineAmmoCountChanged;
entity.GetComponent<BallisticMagazineComponent>().OnAmmoCountChanged -= MagazineAmmoCountChanged;
return true;
}
_updateAppearance();
UpdateAppearance();
Dirty();
return false;
}
@@ -168,9 +151,13 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
// Eject chambered bullet.
var entity = RemoveFromChamber(chamber);
if (entity == null)
{
return;
}
var offsetPos = (CalcBulletOffset(), CalcBulletOffset());
entity.Transform.GridPosition = Owner.Transform.GridPosition.Offset(offsetPos);
entity.Transform.LocalRotation = _bulletDropRandom.Pick(_randomBulletDirs).ToAngle();
entity.Transform.LocalRotation = _bulletDropRandom.Pick(RandomBulletDirs).ToAngle();
var effect = $"/Audio/Guns/Casings/casingfall{_bulletDropRandom.Next(1, 4)}.ogg";
Owner.GetComponent<SoundComponent>().Play(effect, AudioParams.Default.WithVolume(-3));
@@ -188,9 +175,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
DoAutoEject();
}
}
Dirty();
_updateAppearance();
UpdateAppearance();
}
private float CalcBulletOffset()
@@ -206,7 +192,6 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
Owner.GetComponent<SoundComponent>().Play(_autoEjectSound, AudioParams.Default.WithVolume(-5));
}
Dirty();
}
@@ -221,7 +206,6 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
Owner.PopupMessage(eventArgs.User, "No magazine");
}
return true;
}
@@ -231,29 +215,26 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
return false;
}
if (Magazine != null)
{
Owner.PopupMessage(eventArgs.User, "Already got a magazine.");
return false;
}
if (!MagazineTypes.Contains(component.MagazineType) || component.Caliber != Caliber)
if (!MagazineTypes.Contains(component.MagazineType))
{
Owner.PopupMessage(eventArgs.User, "Magazine doesn't fit.");
return false;
}
return InsertMagazine(eventArgs.AttackWith);
}
private void _magazineAmmoCountChanged()
private void MagazineAmmoCountChanged()
{
Dirty();
_updateAppearance();
UpdateAppearance();
}
private void _updateAppearance()
private void UpdateAppearance()
{
if (Magazine != null)
{
@@ -273,15 +254,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
public override ComponentState GetComponentState()
{
var chambered = GetChambered(0) != null;
(int, int)? count = null;
if (Magazine != null)
{
var magComponent = Magazine.GetComponent<BallisticMagazineComponent>();
count = (magComponent.CountLoaded, magComponent.Capacity);
}
return new BallisticMagazineWeaponComponentState(chambered, count);
}

View File

@@ -0,0 +1,149 @@
using Content.Server.GameObjects.Components.Sound;
using Robust.Server.GameObjects.Components.Container;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using System;
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
/// <summary>
/// Handles firing projectiles from a contained <see cref="BallisticBulletComponent" />.
/// </summary>
public abstract class BallisticWeaponComponent : BaseProjectileWeaponComponent
{
private Chamber[] _chambers;
/// <summary>
/// Number of chambers created during initialization.
/// </summary>
private int _chamberCount;
[ViewVariables]
private BallisticCaliber _caliber ;
/// <summary>
/// What type of ammo this gun can fire.
/// </summary>
private string _soundGunEmpty;
/// <summary>
/// Sound played when trying to shoot if there is no ammo available.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public string SoundGunEmpty { get => _soundGunEmpty; set => _soundGunEmpty = value; }
private float _spreadStdDevGun;
/// <summary>
/// Increases the standard deviation of the ammo being fired.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float SpreadStdDevGun { get => _spreadStdDevGun; set => _spreadStdDevGun = value; }
private float _evenSpreadAngleGun;
/// <summary>
/// Increases the evenspread of the ammo being fired.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float EvenSpreadAngleGun { get => _evenSpreadAngleGun; set => _evenSpreadAngleGun = value; }
private float _velocityGun;
/// <summary>
/// Increases the velocity of the ammo being fired.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float VelocityGun { get => _velocityGun; set => _velocityGun = value; }
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _soundGunEmpty, "sound_empty", "/Audio/Guns/Empty/empty.ogg");
serializer.DataField(ref _spreadStdDevGun, "spreadstddev", 0);
serializer.DataField(ref _evenSpreadAngleGun, "evenspread", 0);
serializer.DataField(ref _velocityGun, "gunvelocity", 0);
serializer.DataField(ref _caliber, "caliber", BallisticCaliber.Unspecified);
serializer.DataField(ref _chamberCount, "chambers", 1);
}
public override void Initialize()
{
base.Initialize();
Owner.GetComponent<RangedWeaponComponent>().FireHandler = TryShoot;
_chambers = new Chamber[_chamberCount];
for (var i = 0; i < _chambers.Length; i++)
{
var container = ContainerManagerComponent.Ensure<ContainerSlot>($"ballistics_chamber_{i}", Owner);
_chambers[i] = new Chamber(container);
}
}
/// <summary>
/// Fires projectiles based on loaded ammo from entity to a coordinate.
/// </summary>
protected void TryShoot(IEntity user, GridCoordinates clickLocation)
{
var ammo = GetChambered(FirstChamber)?.GetComponent<BallisticBulletComponent>();
CycleChamberedBullet(FirstChamber);
if (ammo == null || ammo?.Spent == true || ammo?.Caliber != _caliber)
{
PlayEmptySound();
return;
}
ammo.Spent = true;
var total_stdev = _spreadStdDevGun + ammo.SpreadStdDev_Ammo;
var final_evenspread = _evenSpreadAngleGun + ammo.EvenSpreadAngle_Ammo;
var final_velocity = _velocityGun + ammo.Velocity_Ammo;
FireAtCoord(user, clickLocation, ammo.ProjectileID, total_stdev, ammo.ProjectilesFired, final_evenspread, final_velocity);
}
protected IEntity GetChambered(int chamber) => _chambers[chamber].Slot.ContainedEntity;
/// <summary>
/// Loads the next ammo casing into the chamber.
/// </summary>
protected virtual void CycleChamberedBullet(int chamber) { }
public IEntity RemoveFromChamber(int chamber)
{
var c = _chambers[chamber];
var loaded = c.Slot.ContainedEntity;
if (loaded != null)
{
c.Slot.Remove(loaded);
}
return loaded;
}
protected bool LoadIntoChamber(int chamber, IEntity bullet)
{
if (!bullet.TryGetComponent(out BallisticBulletComponent component))
{
throw new ArgumentException("entity isn't a bullet.", nameof(bullet));
}
if (component.Caliber != _caliber)
{
throw new ArgumentException("entity is of the wrong caliber.", nameof(bullet));
}
if (GetChambered(chamber) != null)
{
return false;
}
_chambers[chamber].Slot.Insert(bullet);
return true;
}
private void PlayEmptySound() => Owner.GetComponent<SoundComponent>().Play(_soundGunEmpty);
protected sealed class Chamber
{
public Chamber(ContainerSlot slot)
{
Slot = slot;
}
public ContainerSlot Slot { get; }
}
private const int FirstChamber = 0;
}
}

View File

@@ -1,121 +0,0 @@
using System;
using Content.Server.GameObjects.Components.Sound;
using Robust.Server.GameObjects.Components.Container;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
public abstract class BallisticWeaponComponent : ProjectileWeaponComponent
{
private BallisticCaliber _caliber;
private Chamber[] _chambers;
public BallisticCaliber Caliber => _caliber;
protected abstract int ChamberCount { get; }
private string _soundGunEmpty;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _caliber, "caliber", BallisticCaliber.Unspecified);
serializer.DataField(ref _soundGunEmpty, "sound_empty", null);
}
public override void Initialize()
{
base.Initialize();
_chambers = new Chamber[ChamberCount];
for (var i = 0; i < _chambers.Length; i++)
{
var container = ContainerManagerComponent.Ensure<ContainerSlot>($"ballistics_chamber_{i}", Owner);
_chambers[i] = new Chamber(container);
}
}
public IEntity GetChambered(int chamber) => _chambers[chamber].Slot.ContainedEntity;
public bool LoadIntoChamber(int chamber, IEntity bullet)
{
if (!bullet.TryGetComponent(out BallisticBulletComponent component))
{
throw new ArgumentException("entity isn't a bullet.", nameof(bullet));
}
if (component.Caliber != Caliber)
{
throw new ArgumentException("entity is of the wrong caliber.", nameof(bullet));
}
if (GetChambered(chamber) != null)
{
return false;
}
_chambers[chamber].Slot.Insert(bullet);
return true;
}
protected sealed override IEntity GetFiredProjectile()
{
void PlayEmpty()
{
if (_soundGunEmpty != null)
{
Owner.GetComponent<SoundComponent>().Play(_soundGunEmpty);
}
}
var chambered = GetChambered(0);
if (chambered != null)
{
var bullet = chambered.GetComponent<BallisticBulletComponent>();
if (bullet.Spent)
{
PlayEmpty();
return null;
}
var projectile = Owner.EntityManager.SpawnEntity(bullet.ProjectileType, Owner.Transform.GridPosition);
bullet.Spent = true;
CycleChamberedBullet(0);
// Load a new bullet into the chamber from magazine.
return projectile;
}
PlayEmpty();
return null;
}
protected virtual void CycleChamberedBullet(int chamber)
{
}
public IEntity RemoveFromChamber(int chamber)
{
var c = _chambers[chamber];
var loaded = c.Slot.ContainedEntity;
if (loaded != null)
{
c.Slot.Remove(loaded);
}
return loaded;
}
private sealed class Chamber
{
public Chamber(ContainerSlot slot)
{
Slot = slot;
}
public ContainerSlot Slot { get; }
}
}
}

View File

@@ -0,0 +1,95 @@
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Projectiles;
using Content.Server.GameObjects.Components.Sound;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using System.Collections.Generic;
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
/// <summary>
/// Methods to shoot projectiles.
/// </summary>
public abstract class BaseProjectileWeaponComponent : Component
{
private string _soundGunshot;
[ViewVariables(VVAccess.ReadWrite)]
public string SoundGunshot
{ get => _soundGunshot; set => _soundGunshot = value; }
#pragma warning disable 649
[Dependency] private IRobustRandom _spreadRandom;
#pragma warning restore 649
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _soundGunshot, "sound_gunshot", "/Audio/Guns/Gunshots/smg.ogg");
}
/// <summary>
/// Fires projectile from an entity at a coordinate.
/// </summary>
protected void FireAtCoord(IEntity source, GridCoordinates coord, string projectileType, double spreadStdDev, int projectilesFired = 1, double evenSpreadAngle = 0, float velocity = 0)
{
var angle = GetAngleFromClickLocation(source, coord);
FireAtAngle(source, angle, projectileType, spreadStdDev, projectilesFired, evenSpreadAngle, velocity);
}
/// <summary>
/// Fires projectile in the direction of an angle.
/// </summary>
protected void FireAtAngle(IEntity source, Angle angle, string projectileType = null, double spreadStdDev = 0, int projectilesFired = 1, double evenSpreadAngle = 0, float velocity = 0)
{
List<Angle> sprayanglechange = null;
if (evenSpreadAngle != 0 & projectilesFired > 1)
{
sprayanglechange = Linspace(-evenSpreadAngle/2, evenSpreadAngle/2, projectilesFired);
}
for (var i = 1; i <= projectilesFired; i++)
{
Angle finalangle = angle + Angle.FromDegrees(_spreadRandom.NextGaussian(0, spreadStdDev)) + (sprayanglechange != null ? sprayanglechange[i - 1] : 0);
var projectile = Owner.EntityManager.SpawnEntity(projectileType, Owner.Transform.GridPosition);
projectile.Transform.GridPosition = source.Transform.GridPosition; //move projectile to entity it is being fired from
projectile.GetComponent<ProjectileComponent>().IgnoreEntity(source);//make sure it doesn't hit the source entity
var finalvelocity = projectile.GetComponent<ProjectileComponent>().Velocity + velocity;//add velocity
projectile.GetComponent<PhysicsComponent>().LinearVelocity = finalangle.ToVec() * finalvelocity;//Rotate the bullets sprite to the correct direction
projectile.Transform.LocalRotation = finalangle.Theta;
}
PlayFireSound();
if (source.TryGetComponent(out CameraRecoilComponent recoil))
{
var recoilVec = angle.ToVec() * -0.15f;
recoil.Kick(recoilVec);
}
}
private void PlayFireSound() => Owner.GetComponent<SoundComponent>().Play(_soundGunshot);
/// <summary>
/// Gets the angle from an entity to a coordinate.
/// </summary>
protected Angle GetAngleFromClickLocation(IEntity source, GridCoordinates clickLocation) => new Angle(clickLocation.Position - source.Transform.GridPosition.Position);
/// <summary>
/// Returns a list of numbers that form a set of equal intervals between the start and end value. Used to calculate shotgun spread angles.
/// </summary>
protected List<Angle> Linspace(double start, double end, int intervals)
{
var linspace = new List<Angle> { };
for (var i = 0; i <= intervals - 1; i++)
{
linspace.Add(Angle.FromDegrees(start + (end - start) * i / (intervals - 1)));
}
return linspace;
}
}
}

View File

@@ -1,130 +0,0 @@
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Projectiles;
using Content.Server.GameObjects.Components.Sound;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{
public abstract class ProjectileWeaponComponent : Component
{
private float _spreadStdDev = 3;
private bool _spread = true;
private string _soundGunshot;
#pragma warning disable 649
[Dependency] private IRobustRandom _spreadRandom;
#pragma warning restore 649
[ViewVariables(VVAccess.ReadWrite)]
public bool Spread
{
get => _spread;
set => _spread = value;
}
[ViewVariables(VVAccess.ReadWrite)]
public float SpreadStdDev
{
get => _spreadStdDev;
set => _spreadStdDev = value;
}
public override void Initialize()
{
base.Initialize();
var rangedWeapon = Owner.GetComponent<RangedWeaponComponent>();
rangedWeapon.FireHandler = Fire;
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _spread, "spread", true);
serializer.DataField(ref _spreadStdDev, "spreadstddev", 3);
serializer.DataField(ref _soundGunshot, "sound_gunshot", "/Audio/Guns/Gunshots/smg.ogg");
}
private void Fire(IEntity user, GridCoordinates clickLocation)
{
var projectile = GetFiredProjectile();
if (projectile == null)
{
return;
}
var userPosition = user.Transform.GridPosition; //Remember world positions are ephemeral and can only be used instantaneously
var angle = new Angle(clickLocation.Position - userPosition.Position);
if (user.TryGetComponent(out CameraRecoilComponent recoil))
{
var recoilVec = angle.ToVec() * -0.15f;
recoil.Kick(recoilVec);
}
if (Spread)
{
angle += Angle.FromDegrees(_spreadRandom.NextGaussian(0, SpreadStdDev));
}
projectile.Transform.GridPosition = userPosition;
//Give it the velocity we fire from this weapon, and make sure it doesn't shoot our character
projectile.GetComponent<ProjectileComponent>().IgnoreEntity(user);
var velocity = projectile.GetComponent<ProjectileComponent>().Velocity;
//Give it the velocity this weapon gives to things it fires from itself
projectile.GetComponent<PhysicsComponent>().LinearVelocity = angle.ToVec() * velocity;
//Rotate the bullets sprite to the correct direction, from north facing I guess
projectile.Transform.LocalRotation = angle.Theta;
// Sound!
Owner.GetComponent<SoundComponent>().Play(_soundGunshot);
}
/// <summary>
/// Try to get a projectile for firing. If null, nothing will be fired.
/// </summary>
protected abstract IEntity GetFiredProjectile();
}
public enum BallisticCaliber
{
Unspecified = 0,
// .32
A32,
// .357
A357,
// .44
A44,
// .45mm
A45mm,
// .50 cal
A50,
// 5.56mm
A556mm,
// 6.5mm
A65mm,
// 7.62mm
A762mm,
// 9mm
A9mm,
// 10mm
A10mm,
// 20mm
A20mm,
// 24mm
A24mm,
}
}

View File

@@ -1,5 +1,6 @@
using System;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components.Weapons.Ranged;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
@@ -30,7 +31,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged
private bool UserCanFire(IEntity user)
{
return UserCanFireHandler == null || UserCanFireHandler(user);
return (UserCanFireHandler == null || UserCanFireHandler(user)) && ActionBlockerSystem.CanAttack(user);
}
private void Fire(IEntity user, GridCoordinates clickLocation)

View File

@@ -20,6 +20,8 @@ namespace Content.Server.GameObjects.EntitySystems
bool CanPickup();
bool CanEmote();
bool CanAttack();
}
public class ActionBlockerSystem : EntitySystem
@@ -105,5 +107,17 @@ namespace Content.Server.GameObjects.EntitySystems
return canemote;
}
public static bool CanAttack(IEntity entity)
{
bool canattack = true;
foreach (var actionblockercomponents in entity.GetAllComponents<IActionBlocker>())
{
canattack &= actionblockercomponents.CanAttack();
}
return canattack;
}
}
}

View File

@@ -273,26 +273,31 @@ namespace Content.Server.GameObjects.EntitySystems
/// If the <paramref name="range"/> is zero or negative,
/// this method will only check if nothing obstructs the two sets of coordinates..
/// </summary>
/// <param name="mapManager">Map manager containing the two GridIds.</param>
/// <param name="coords">Set of coordinates to use.</param>
/// <param name="otherCoords">Other set of coordinates to use.</param>
/// <param name="range">maximum distance between the two sets of coordinates.</param>
/// <param name="collisionMask">the mask to check for collisions</param>
/// <param name="ignoredEnt">the entity to be ignored when checking for collisions.</param>
/// <param name="mapManager">Map manager containing the two GridIds.</param>
/// <param name="insideBlockerValid">if coordinates inside obstructions count as obstructed or not</param>
/// <returns>True if the two points are within a given range without being obstructed.</returns>
public bool InRangeUnobstructed(GridCoordinates coords, GridCoordinates otherCoords, float range = InteractionRange, int collisionMask = (int)CollisionGroup.Impassable, IEntity ignoredEnt = null)
public bool InRangeUnobstructed(MapCoordinates coords, Vector2 otherCoords, float range = InteractionRange,
int collisionMask = (int) CollisionGroup.Impassable, IEntity ignoredEnt = null, bool insideBlockerValid = false)
{
if (range > 0f && !coords.InRange(_mapManager, otherCoords, range))
{
var dir = otherCoords - coords.Position;
if (dir.LengthSquared.Equals(0f))
return true;
if (range > 0f && !(dir.LengthSquared <= range*range))
return false;
}
var dir = (otherCoords.Position - coords.Position);
if (!(dir.Length > 0f)) return true;
var ray = new CollisionRay(coords.Position, dir.Normalized, collisionMask);
var rayResults = _physicsManager.IntersectRay(_mapManager.GetGrid(coords.GridID).ParentMapId, ray, dir.Length, ignoredEnt);
var rayResults = _physicsManager.IntersectRay(coords.MapId, ray, dir.Length, ignoredEnt, true);
return !rayResults.DidHitObject;
return !rayResults.DidHitObject || (insideBlockerValid && rayResults.DidHitObject && rayResults.Distance < 1f);
}
private bool HandleActivateItemInWorld(ICommonSession session, GridCoordinates coords, EntityUid uid)
@@ -848,7 +853,7 @@ namespace Content.Server.GameObjects.EntitySystems
var item = hands.GetActiveHand?.Owner;
// TODO: If item is null we need some kinda unarmed combat.
if (!ActionBlockerSystem.CanInteract(player) || item == null)
if (!ActionBlockerSystem.CanAttack(player) || item == null)
{
return;
}

View File

@@ -126,7 +126,7 @@ namespace Content.Server.GameObjects.EntitySystems
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
if(interactionSystem.InRangeUnobstructed(coords, ent.Transform.GridPosition, 0f, ignoredEnt:ent))
if(interactionSystem.InRangeUnobstructed(coords.ToMap(_mapManager), ent.Transform.WorldPosition, 0f, ignoredEnt: ent))
if (coords.InRange(_mapManager, ent.Transform.GridPosition, InteractionSystem.InteractionRange))
{
handsComp.Drop(handsComp.ActiveIndex, coords);

View File

@@ -40,9 +40,6 @@ namespace Content.Server.GlobalVerbs
var userMind = user.GetComponent<IActorComponent>().playerSession.ContentData().Mind;
var targetMind = target.GetComponent<MindComponent>();
if(userMind.IsVisitingEntity)
userMind.UnVisit();
targetMind.Mind?.TransferTo(null);
userMind.TransferTo(target);
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -70,7 +70,9 @@
name: "Bike Horn"
id: cargo.bikehorn
description: HONK!
icon: Objects/Fun/bikehorn.rsi
icon:
sprite: Objects/Fun/bikehorn.rsi
state: icon
product: crate_bikehorn
cost: 300
category: Other
@@ -102,7 +104,9 @@
name: "Medical Scanner"
id: cargo.medscanner
description: Scans patients. First we stick this probe...
icon: Buildings/medical_scanner.rsi
icon:
sprite: Buildings/medical_scanner.rsi
state: scanner_open
product: crate_medscanner
cost: 400
category: Medical

View File

@@ -0,0 +1,12 @@
- type: construction
name: Skub
id: skub
category: Items/Misc
keywords: [misc]
description: In the end, there is only Skub.
icon: Objects/Misc/skub.rsi/icon.png
result: Skub
objecttype: Item
steps:
- material: Metal
amount: 1

View File

@@ -25,7 +25,7 @@
name: Table
id: table
category: Structures
icon:
icon:
sprite: Buildings/table_solid.rsi
state: plain_preview
result: table

View File

@@ -2,7 +2,7 @@
id: bullet_10mm
name: 10mm Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_10mmf
name: 10mm Bullet (Flash)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_10mmhv
name: 10mm Bullet (High-Velocity)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_10mml
name: 10mm Bullet (L)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_10mmp
name: 10mm Bullet (Practice)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_10mmr
name: 10mm Bullet (Rubber)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -0,0 +1,54 @@
# Empty mags
- type: entity
id: magazine_12g_empty
name: "12g magazine - empty"
parent: BaseItem
abstract: true
components:
- type: BallisticMagazine
caliber: A12g
magazine: A12g
capacity: 8
- type: Sprite
netsync: false
#Magazines
- type: entity
id: magazine_12g_shotgun
name: "12g Magazine"
parent: magazine_12g_empty
components:
- type: BallisticMagazine
fill: ammo_casing_12g
caliber: A12g
magazine: A12g
capacity: 20
- type: Icon
sprite: Objects/Guns/Ammunition/Magazine/10mm/12mml.rsi
state: 12mml-1
- type: Sprite
sprite: Objects/Guns/Ammunition/Magazine/10mm/12mml.rsi
state: 12mml-1
- type: Appearance
visuals:
- type: BallisticMagazineVisualizer2D
base_state: 12mml
steps: 2
# Casings
- type: entity
id: ammo_casing_12g
name: "12g casing"
parent: BaseItem
components:
- type: BallisticBullet
caliber: A12g
projectile: pellet_12g
projectilesfired : 6
- type: Sprite
sprite: Objects/Guns/Ammunition/ammo_casing.rsi
state: s-casing
drawdepth: FloorObjects
- type: Icon
sprite: Objects/Guns/Ammunition/ammo_casing.rsi
state: s-casing

View File

@@ -0,0 +1,34 @@
# Empty boxes
- type: entity
id: box_12g_empty
name: "12g box - empty"
parent: BaseItem
abstract: true
components:
- type: AmmoBox
caliber: A12g
capacity: 30
- type: Sprite
netsync: false
# Ammo boxes
- type: entity
id: box_12g
name: "12g box"
parent: box_12g_empty
components:
- type: AmmoBox
fill: ammo_casing_12g
caliber: A12g
capacity: 30
- type: Icon
sprite: Objects/Guns/Ammunition/Boxes/10mm/box10mm.rsi
state: box10mm-1
- type: Sprite
sprite: Objects/Guns/Ammunition/Boxes/10mm/box10mm.rsi
state: box10mm-1
- type: Appearance
visuals:
- type: BallisticMagazineVisualizer2D
base_state: box10mm
steps: 2

View File

@@ -0,0 +1,10 @@
- type: entity
id: pellet_12g
name: 12g Pellet
parent: bullet_base
abstract: true
components:
- type: Projectile
velocity: 20
damages:
Brute: 10

View File

@@ -2,9 +2,9 @@
id: bullet_20mm
name: 20mm Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
damages:
Brute: 10
Brute: 10

View File

@@ -2,7 +2,7 @@
id: bullet_24mm
name: 24mm Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_24mmf
name: 24mm Bullet (Flash)
parent: bullet_basef
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_24mmhv
name: 24mm Bullet (High-Velocity)
parent: bullet_basehv
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 27
@@ -35,7 +35,7 @@
id: bullet_24mml
name: 24mm Bullet (L)
parent: bullet_basel
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_24mmp
name: 24mm Bullet (Practice)
parent: bullet_basep
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_24mmr
name: 24mm Bullet (Rubber)
parent: bullet_baser
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_45mm
name: .45mm Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_45mmf
name: .45mm Bullet (Flash)
parent: bullet_basef
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_45mmhv
name: .45mm Bullet (High-Velocity)
parent: bullet_basehv
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_45mml
name: .45mm Bullet (L)
parent: bullet_basel
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_45mmp
name: .45mm Bullet (Practice)
parent: bullet_basep
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_45mmr
name: .45mm Bullet (Rubber)
parent: bullet_baser
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_556mm
name: 5.56mm Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_556mmf
name: 5.56mm Bullet (Flash)
parent: bullet_basef
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_556mmhv
name: 5.56mm Bullet (High-Velocity)
parent: bullet_basehv
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_556mml
name: 5.56mm Bullet (L)
parent: bullet_basel
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_556mmp
name: 5.56mm Bullet (Practice)
parent: bullet_basep
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_556mmr
name: 5.56mm Bullet (Rubber)
parent: bullet_baser
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_65mm
name: 6.5mm Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_65mmf
name: 6.5mm Bullet (Flash)
parent: bullet_basef
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_65mmhv
name: 6.5mm Bullet (High-Velocity)
parent: bullet_basehv
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_65mml
name: 6.5mm Bullet (L)
parent: bullet_basel
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_65mmp
name: 6.5mm Bullet (Practice)
parent: bullet_basep
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_65mmr
name: 6.5mm Bullet (Rubber)
parent: bullet_baser
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_762mm
name: 7.62mm Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_762mmf
name: 7.62mm Bullet (Flash)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_762mmhv
name: 7.62mm Bullet (High-Velocity)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_762mml
name: 7.62mm Bullet (L)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_762mmp
name: 7.62mm Bullet (Practice)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_762mmr
name: 7.62mm Bullet (Rubber)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_9mm
name: 9mm Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_9mmf
name: 9mm Bullet (Flash)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_9mmhv
name: 9mm Bullet (High-Velocity)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_9mml
name: 9mm Bullet (L)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_9mmp
name: 9mm Bullet (Practice)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_9mmr
name: 9mm Bullet (Rubber)
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_32
name: .32 Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_32f
name: .32 Bullet (Flash)
parent: bullet_basef
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_32hv
name: .32 Bullet (High-Velocity)
parent: bullet_basehv
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_32l
name: .32 Bullet (L)
parent: bullet_basel
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_32p
name: .32 Bullet (Practice)
parent: bullet_basep
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_32r
name: .32 Bullet (Rubber)
parent: bullet_baser
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_357
name: .357 Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_357f
name: .357 Bullet (Flash)
parent: bullet_basef
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_357hv
name: .357 Bullet (High-Velocity)
parent: bullet_basehv
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_357l
name: .357 Bullet (L)
parent: bullet_basel
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_357p
name: .357 Bullet (Practice)
parent: bullet_basep
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_357r
name: .357 Bullet (Rubber)
parent: bullet_baser
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_44
name: .44 Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_44f
name: .44 Bullet (Flash)
parent: bullet_basef
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_44hv
name: .44 Bullet (High-Velocity)
parent: bullet_basehv
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_44l
name: .44 Bullet (L)
parent: bullet_basel
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_44p
name: .44 Bullet (Practice)
parent: bullet_basep
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_44r
name: .44 Bullet (Rubber)
parent: bullet_baser
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,7 +2,7 @@
id: bullet_50
name: .50 cal Bullet
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -13,7 +13,7 @@
id: bullet_50f
name: .50 cal Bullet (Flash)
parent: bullet_basef
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -24,7 +24,7 @@
id: bullet_50hv
name: .50 cal Bullet (High-Velocity)
parent: bullet_basehv
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 30
@@ -35,7 +35,7 @@
id: bullet_50l
name: .50 cal Bullet (L)
parent: bullet_basel
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -46,7 +46,7 @@
id: bullet_50p
name: .50 cal Bullet (Practice)
parent: bullet_basep
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20
@@ -57,7 +57,7 @@
id: bullet_50r
name: .50 cal Bullet (Rubber)
parent: bullet_baser
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
velocity: 20

View File

@@ -2,9 +2,10 @@
- type: entity
id: bullet_base
name: bullet_base
description: If you can see this you're dead!
description: If you can see this you're probably dead!
abstract: true
components:
- type: Clickable
- type: Sprite
directional: false
texture: Objects/Projectiles/bullet.png
@@ -34,7 +35,6 @@
id: bullet_basef
name: Base Bullet Flash
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
@@ -46,7 +46,6 @@
id: bullet_basehv
name: Base Bullet High-Velocity
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
@@ -58,7 +57,6 @@
id: bullet_basel
name: Base Bullet L
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
@@ -70,7 +68,6 @@
id: bullet_basep
name: Base Bullet Practice
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile
@@ -82,7 +79,6 @@
id: bullet_baser
name: Base Bullet Rubber
parent: bullet_base
description: If you can see this you're dead!
abstract: true
components:
- type: Projectile

View File

@@ -81,7 +81,7 @@
steps: 1
- type: Item
Size: 24
sprite: Objects/Guns/Rifles/black-AK.rsi
sprite: Objects/Guns/Rifles/black-ak.rsi
- type: entity
name: Carbine

View File

@@ -0,0 +1,47 @@
- type: entity
name: Shotgun
parent: BaseItem
id: BaseShotgun
description: A rooty tooty point and shooty.
abstract: true
components:
- type: Sound
- type: RangedWeapon
automatic: false
firerate: 20
- type: BallisticMagazineWeapon
caliber: A12g
evenspread : 40
magazines:
- A12g
default_magazine: magazine_12g_shotgun
auto_eject_magazine: false
sound_auto_eject: /Audio/Guns/EmptyAlarm/smg_empty_alarm.ogg
sound_magazine_in: /Audio/Guns/MagIn/smg_magin.ogg
sound_magazine_out: /Audio/Guns/MagOut/smg_magout.ogg
sound_empty: /Audio/Guns/Empty/empty.ogg
sound_gunshot: /Audio/Guns/Gunshots/smg.ogg
- type: entity
name: Magazine Fed Shotgun
parent: BaseShotgun
id: MagazineFedShotgun
components:
- type: Sprite
netsync: false
sprite: Objects/Guns/SMGs/c20r.rsi
state: c20r-5
- type: Icon
sprite: Objects/Guns/SMGs/c20r.rsi
state: c20r-5
- type: Appearance
visuals:
- type: BallisticMagazineWeaponVisualizer2D
base_state: c20r
steps: 6
- type: Item
Size: 24
sprite: Objects/Guns/SMGs/c20r.rsi
- type: Item
Size: 24
sprite: Objects/Guns/SMGs/wt550.rsi

View File

@@ -83,8 +83,17 @@
static: true
products:
- cargo.dice
- cargo.flashlight
- cargo.Medkit
- cargo.flashlight
- cargo.lightblub
- cargo.fireextinguisher
- cargo.pen
- cargo.bikehorn
- cargo.cleaver
- cargo.fueltank
- cargo.medscanner
- cargo.glass
- cargo.cable
- type: UserInterface
interfaces:
- key: enum.CargoConsoleUiKey.Key

View File

@@ -21,7 +21,7 @@
- type: Collidable
shapes:
- !type:PhysShapeAabb
bounds: "-0.5,-0.25,0.5,0.25"
bounds: "-0.5,0,0.5,1"
layer: 15
IsScrapingFloor: true
- type: Physics

View File

@@ -124,119 +124,119 @@
name: Flashlight Crate (x5)
parent: crate_generic
components:
- type: StorageFill
contents:
- Flashlight
- Flashlight
- Flashlight
- Flashlight
- Flashlight
- type: StorageFill
contents:
- FlashlightLantern
- FlashlightLantern
- FlashlightLantern
- FlashlightLantern
- FlashlightLantern
- type: entity
id: crate_light_bulb
name: Light Bulb Crate (x10)
parent: crate_generic
components:
- type: StorageFill
contents:
- Light Bulb
- Light Bulb
- Light Bulb
- Light Bulb
- Light Bulb
- Light Bulb
- Light Bulb
- Light Bulb
- Light Bulb
- Light Bulb
- type: StorageFill
contents:
- LightBulb
- LightBulb
- LightBulb
- LightBulb
- LightBulb
- LightBulb
- LightBulb
- LightBulb
- LightBulb
- LightBulb
- type: entity
id: crate_fire_extinguisher
name: Fire Extinguisher Crate (x3)
parent: crate_generic
components:
- type: StorageFill
contents:
- Fire Extinguisher
- Fire Extinguisher
- Fire Extinguisher
- type: StorageFill
contents:
- fire_extinguisher
- fire_extinguisher
- fire_extinguisher
- type: entity
id: crate_pen
name: Pen Crate (x10)
parent: crate_generic
components:
- type: StorageFill
contents:
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- type: StorageFill
contents:
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- Pen
- type: entity
id: crate_bikehorn
name: Bike Horn Crate (x5)
parent: crate_generic
components:
- type: StorageFill
contents:
- Bike Horn
- Bike Horn
- Bike Horn
- Bike Horn
- Bike Horn
- type: StorageFill
contents:
- BikeHorn
- BikeHorn
- BikeHorn
- BikeHorn
- BikeHorn
- type: entity
id: crate_cleaver
name: Cleaver Crate (x5)
parent: crate_generic
components:
- type: StorageFill
contents:
- Cleaver
- Cleaver
- Cleaver
- Cleaver
- Cleaver
- type: StorageFill
contents:
- ButchCleaver
- ButchCleaver
- ButchCleaver
- ButchCleaver
- ButchCleaver
- type: entity
id: crate_fueltank
name: Fuel Tank
parent: crate_generic
components:
- type: StorageFill
contents:
- Fuel Tank
- type: StorageFill
contents:
- weldtank
- type: entity
id: crate_medscanner
name: Medical Scanner
parent: crate_generic
components:
- type: StorageFill
contents:
- Medical Scanner
- type: StorageFill
contents:
- medical_scanner
- type: entity
id: crate_glass
name: Glass Sheet Crate (x50)
parent: crate_generic
components:
- type: StorageFill
contents:
- GlassStack
- type: StorageFill
contents:
- GlassStack
- type: entity
id: crate_cable
name: Cable Coil Crate (x50)
parent: crate_generic
components:
- type: StorageFill
contents:
- CableStack
- type: StorageFill
contents:
- CableStack

View File

@@ -167,32 +167,6 @@
- type: Clothing
sprite: Clothing/Gloves/ce_rig_sealed.rsi
- type: entity
parent: GlovesBase
id: GlovesChalAppara1
name: Chal Appara 1 gloves
description: ''
components:
- type: Sprite
sprite: Clothing/Gloves/chal_appara_1.rsi
- type: Icon
sprite: Clothing/Gloves/chal_appara_1.rsi
- type: Clothing
sprite: Clothing/Gloves/chal_appara_1.rsi
- type: entity
parent: GlovesBase
id: GlovesChalAppara12
name: Chal Appara 12 gloves
description: ''
components:
- type: Sprite
sprite: Clothing/Gloves/chal_appara_12.rsi
- type: Icon
sprite: Clothing/Gloves/chal_appara_12.rsi
- type: Clothing
sprite: Clothing/Gloves/chal_appara_12.rsi
- type: entity
parent: GlovesBase
id: GlovesEngineeringRig

View File

@@ -0,0 +1,24 @@
- type: entity
name: Skub
parent: BaseItem
id: Skub
description: Skub is the fifth Chaos God.
components:
- type: Sprite
sprite: Objects/Misc/skub.rsi
state: icon
- type: Icon
sprite: Objects/Misc/skub.rsi
state: icon
- type: Item
sprite: Objects/Misc/skub.rsi
- type: ItemCooldown
- type: Sound
- type: EmitSoundOnUse
sound: /Audio/items/skub.ogg
- type: UseDelay
delay: 2.0

View File

@@ -1 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/blob/c0293684320e7b70cbcac932b8dddeee35f3a51f/icons/obj/structures/windows.dmi", "states": [{"name": "window0", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window1", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window2", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window3", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window4", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window5", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window6", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window7", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/blob/c0293684320e7b70cbcac932b8dddeee35f3a51f/icons/obj/structures/windows.dmi", "states": [{"name": "window0", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window1", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window2", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window3", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window4", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window5", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window6", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "window7", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 B

View File

@@ -1 +0,0 @@
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "https://github.com/discordia-space/CEV-Eris/raw/cb5bda251807e38fe5eae6b1def12f0c243b4d0a/icons/inventory/hands/mob.dmi", "states": [{"name": "equipped-HAND", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "icon", "directions": 1, "delays": [[1.0]]}, {"name": "inhand-left", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "inhand-right", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

View File

@@ -1 +0,0 @@
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "https://github.com/discordia-space/CEV-Eris/raw/cb5bda251807e38fe5eae6b1def12f0c243b4d0a/icons/inventory/hands/mob.dmi", "states": [{"name": "equipped-HAND", "directions": 1}, {"name": "icon", "directions": 1, "delays": [[1.0]]}, {"name": "inhand-left", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "inhand-right", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 B

View File

@@ -0,0 +1 @@
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/tgstation/tgstation", "states": [{"name": "icon", "directions": 1, "delays": [[1.0]]}, {"name": "inhand-left", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "inhand-right", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}