diff --git a/Content.Server/Polymorph/Systems/PolymorphSystem.cs b/Content.Server/Polymorph/Systems/PolymorphSystem.cs
index 63b0de7359..13fdbf5f86 100644
--- a/Content.Server/Polymorph/Systems/PolymorphSystem.cs
+++ b/Content.Server/Polymorph/Systems/PolymorphSystem.cs
@@ -157,12 +157,18 @@ public sealed partial class PolymorphSystem : EntitySystem
if (ent.Comp.Reverted)
return;
+ // Sunrise-start
if (ent.Comp.Configuration.RevertOnDelete)
+ {
Revert(ent.AsNullable());
-
- // Remove our original entity too
+ return;
+ }
+ // Заглушка-решение. Ишуй оффам отправлен
+ // Remove our original entity too.
// Note that Revert will set Parent to null, so reverted entities will not be deleted
- QueueDel(ent.Comp.Parent);
+ if (ent.Comp.Parent is { } parent && !Deleted(parent))
+ QueueDel(parent);
+ // Sunrise-end
}
///
diff --git a/Content.Server/_Sunrise/CryoTeleport/CryoTeleportSystem.cs b/Content.Server/_Sunrise/CryoTeleport/CryoTeleportSystem.cs
index d39003e22e..31204d460e 100644
--- a/Content.Server/_Sunrise/CryoTeleport/CryoTeleportSystem.cs
+++ b/Content.Server/_Sunrise/CryoTeleport/CryoTeleportSystem.cs
@@ -1,5 +1,6 @@
using Content.Server.Bed.Cryostorage;
using Content.Server.Body.Components;
+using Content.Server.Polymorph.Components;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared._Sunrise.SunriseCCVars;
@@ -87,6 +88,9 @@ public sealed class CryoTeleportationSystem : EntitySystem
|| HasComp(uid))
continue;
+ if (HasComp(uid))
+ continue;
+
// Check if the entity has a brain - if no brain, don't teleport to cryo
// This prevents brainless bodies (e.g., during brain transplant surgery) from being auto-teleported
var hasBrain = false;
diff --git a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs
index 6ae4857547..84e88156ad 100644
--- a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs
+++ b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs
@@ -34,6 +34,12 @@ public sealed partial class MeleeWeaponComponent : Component
[AutoPausedField]
public TimeSpan NextAttack;
+ ///
+ /// Starts attack cooldown when equipped if true.
+ ///
+ [DataField, AutoNetworkedField]
+ public bool ResetOnHandSelected = true;
+
/*
* Melee combat works based around 2 types of attacks:
* 1. Click attacks with left-click. This attacks whatever is under your mnouse
diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs
index fe541486e2..d4eeeaa880 100644
--- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs
+++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs
@@ -131,7 +131,6 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
DirtyField(uid, component, nameof(MeleeWeaponComponent.NextAttack));
}
}
-
private void OnMeleeExamineDamage(EntityUid uid, MeleeWeaponComponent component, ref DamageExamineEvent args)
{
if (component.Hidden)
@@ -144,44 +143,27 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
_damageExamine.AddDamageExamine(args.Message, Damageable.ApplyUniversalAllModifiers(damageSpec), Loc.GetString("damage-melee"));
}
- private void OnMeleeSelected(Entity ent, ref HandSelectedEvent args)
+ private void OnMeleeSelected(EntityUid uid, MeleeWeaponComponent component, HandSelectedEvent args)
{
- var uid = ent.Owner;
+ var attackRate = GetAttackRate(uid, args.User, component);
+ if (attackRate.Equals(0f))
+ return;
- var attackRate = GetAttackRate(uid, args.User, ent);
- if (attackRate == 0f)
+ if (!component.ResetOnHandSelected)
return;
if (Paused(uid))
return;
- if (TryComp(uid, out var delayComp))
- {
- var delay = delayComp.EquipDelayTime;
- var curTime = Timing.CurTime;
+ // If someone swaps to this weapon then reset its cd.
+ var curTime = Timing.CurTime;
+ var minimum = curTime + TimeSpan.FromSeconds(1 / attackRate);
- var minimum = curTime + TimeSpan.FromSeconds(delay);
+ if (minimum < component.NextAttack)
+ return;
- if (minimum < ent.Comp.NextAttack)
- return;
-
- ent.Comp.NextAttack = minimum;
-
- DirtyField(uid, ent.Comp, nameof(MeleeWeaponComponent.NextAttack));
- }
- else
- {
- var curTime = Timing.CurTime;
-
- var minimum = curTime + TimeSpan.FromSeconds(0.3);
-
- if (minimum < ent.Comp.NextAttack)
- return;
-
- ent.Comp.NextAttack = minimum;
-
- DirtyField(uid, ent.Comp, nameof(MeleeWeaponComponent.NextAttack));
- }
+ component.NextAttack = minimum;
+ DirtyField(uid, component, nameof(MeleeWeaponComponent.NextAttack));
}
private void OnGetBonusMeleeDamage(EntityUid uid, BonusMeleeDamageComponent component, ref GetMeleeDamageEvent args)
diff --git a/Content.Shared/Weapons/Misc/EquipDelayComponent.cs b/Content.Shared/Weapons/Misc/EquipDelayComponent.cs
deleted file mode 100644
index d198aca5f2..0000000000
--- a/Content.Shared/Weapons/Misc/EquipDelayComponent.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Robust.Shared.GameStates;
-
-namespace Content.Shared.Weapons;
-
-[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
-public sealed partial class EquipDelayComponent : Component
-{
- ///
- /// Delay before the next attack after picking up a weapon, in seconds.
- ///
- [DataField("delay"), AutoNetworkedField]
- public float EquipDelayTime = 0.3f;
-}
\ No newline at end of file
diff --git a/Content.Shared/Weapons/Ranged/Components/GunComponent.cs b/Content.Shared/Weapons/Ranged/Components/GunComponent.cs
index 0fccda7dfc..aa3f496d8a 100644
--- a/Content.Shared/Weapons/Ranged/Components/GunComponent.cs
+++ b/Content.Shared/Weapons/Ranged/Components/GunComponent.cs
@@ -209,6 +209,12 @@ public sealed partial class GunComponent : Component
[AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public float FireRateModified;
+ ///
+ /// Starts fire cooldown when equipped if true.
+ ///
+ [DataField]
+ public bool ResetOnHandSelected = true;
+
///
/// The base value for how fast the projectile moves.
///
@@ -226,7 +232,7 @@ public sealed partial class GunComponent : Component
/// When the gun is next available to be shot.
/// Can be set multiple times in a single tick due to guns firing faster than a single tick time.
///
- [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
+ [DataField(customTypeSerializer:typeof(TimeOffsetSerializer))]
[AutoNetworkedField]
[AutoPausedField]
public TimeSpan NextFire = TimeSpan.Zero;
diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs
index 0f02f83cd7..e79866dd7a 100644
--- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs
+++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs
@@ -66,7 +66,7 @@ public abstract partial class SharedGunSystem
if (component.SelectedMode == fire)
return;
- DebugTools.Assert((component.AvailableModes & fire) != 0x0);
+ DebugTools.Assert((component.AvailableModes & fire) != 0x0);
component.SelectedMode = fire;
if (!Paused(uid))
@@ -110,45 +110,32 @@ public abstract partial class SharedGunSystem
SelectFire(uid, component, args.Mode, args.Performer);
}
- private void OnGunSelected(Entity ent, ref HandSelectedEvent args)
+ private void OnGunSelected(EntityUid uid, GunComponent component, HandSelectedEvent args)
{
- var uid = ent.Owner;
-
if (Timing.ApplyingState)
return;
- if (ent.Comp.FireRateModified <= 0)
+ if (component.FireRateModified <= 0)
+ return;
+
+ var fireDelay = 1f / component.FireRateModified;
+ if (fireDelay.Equals(0f))
+ return;
+
+ if (!component.ResetOnHandSelected)
return;
if (Paused(uid))
return;
- if (TryComp(uid, out var delayComp))
- {
- var delay = delayComp.EquipDelayTime;
- var curTime = Timing.CurTime;
+ // If someone swaps to this weapon then reset its cd.
+ var curTime = Timing.CurTime;
+ var minimum = curTime + TimeSpan.FromSeconds(fireDelay);
- var minimum = curTime + TimeSpan.FromSeconds(delay);
+ if (minimum < component.NextFire)
+ return;
- if (minimum < ent.Comp.NextFire)
- return;
-
- ent.Comp.NextFire = minimum;
-
- DirtyField(uid, ent.Comp, nameof(GunComponent.NextFire));
- }
- else
- {
- var curTime = Timing.CurTime;
-
- var minimum = curTime + TimeSpan.FromSeconds(0.3);
-
- if (minimum < ent.Comp.NextFire)
- return;
-
- ent.Comp.NextFire = minimum;
-
- DirtyField(uid, ent.Comp, nameof(GunComponent.NextFire));
- }
+ component.NextFire = minimum;
+ Dirty(uid, component);
}
}
diff --git a/Resources/Prototypes/Body/Prototypes/vulpkanin.yml b/Resources/Prototypes/Body/Prototypes/vulpkanin.yml
index e939e3ac47..39492523e0 100644
--- a/Resources/Prototypes/Body/Prototypes/vulpkanin.yml
+++ b/Resources/Prototypes/Body/Prototypes/vulpkanin.yml
@@ -10,6 +10,10 @@
organs:
brain: OrganHumanBrain
eyes: OrganHumanEyes
+ # Sunrise-start
+ tongue: OrganHumanTongue
+ eye_implant: null
+ # Sunrise-end
torso:
part: TorsoVulpkanin
connections:
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml
index f335701974..352521cbd5 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml
@@ -75,6 +75,7 @@
- type: ActionGrant
actions:
- ActionRevenantShop
+ - ActionRevenantDrain # Sunrise
- type: Store
categories:
- RevenantAbilities
diff --git a/Resources/Prototypes/Entities/Mobs/Species/vulpkanin.yml b/Resources/Prototypes/Entities/Mobs/Species/vulpkanin.yml
index 58abd7373d..79a0aec36a 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/vulpkanin.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/vulpkanin.yml
@@ -133,6 +133,7 @@
state: hair
# Sunrise-start
- type: Carriable
+ - type: FootprintEmitter
# Sunrise-end
- type: Inventory
# SUNRISE EDIT
diff --git a/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml b/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml
index 3c5fd8039d..66ab826ac2 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/handcuffs.yml
@@ -19,6 +19,7 @@
- Handcuffs
- type: MeleeWeapon
wideAnimationRotation: 90
+ resetOnHandSelected: false
animation: WeaponArcDisarm
damage:
types:
diff --git a/Resources/Prototypes/_Sunrise/Entities/Mobs/Species/humanoid_xeno.yml b/Resources/Prototypes/_Sunrise/Entities/Mobs/Species/humanoid_xeno.yml
index 9393331067..5fb81f6e1c 100644
--- a/Resources/Prototypes/_Sunrise/Entities/Mobs/Species/humanoid_xeno.yml
+++ b/Resources/Prototypes/_Sunrise/Entities/Mobs/Species/humanoid_xeno.yml
@@ -54,18 +54,6 @@
Brute:
sprite: Mobs/Effects/brute_damage.rsi
color: "#44944A"
- - type: Fixtures
- fixtures:
- fix1:
- shape:
- !type:PhysShapeCircle
- radius: 0.40
- density: 250
- restitution: 0.0
- mask:
- - MobMask
- layer:
- - MobLayer
- type: Sprite
layers:
- map: [ "enum.HumanoidVisualLayers.Chest" ]
diff --git a/Resources/Prototypes/borg_types.yml b/Resources/Prototypes/borg_types.yml
index 641904f5ee..3b61988fb3 100644
--- a/Resources/Prototypes/borg_types.yml
+++ b/Resources/Prototypes/borg_types.yml
@@ -142,23 +142,6 @@
acceleration: 1
friction: 0.3
weightlessModifier: 1.3
- moleUsage: 0.00085
- - type: GasTank
- outputPressure: 42.6
- air:
- # 13 minutes of thrust
- volume: 5
- temperature: 293.15
- moles:
- - 1.025689525 # oxygen
- - 1.025689525 # nitrogen
- - type: GasRegeneration
- airRegenerate:
- volume: 5
- temperature: 293.15
- moles:
- - 0.0008 # oxygen
- - 0.0008 # nitrogen
- type: Appearance
- type: GenericVisualizer
visuals: