Температурные пушки (#90)

* - add: Temperature guns.

* - tweak: Change cryo sting slowdown.

* - tweak: Tempgun tweaks.

* - add: Hardsuit temperature adjustment system.
This commit is contained in:
Aviu00
2024-02-18 17:28:18 +09:00
committed by GitHub
parent 0b6fd195a7
commit 9caa5a408b
42 changed files with 383 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using Content.Server.Administration.Systems;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
@@ -11,6 +11,7 @@ using Content.Server.Mind;
using Content.Server.Polymorph.Systems;
using Content.Server.Popups;
using Content.Server.Store.Components;
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared.Actions;
using Content.Shared.Changeling;
@@ -431,7 +432,8 @@ public sealed partial class ChangelingSystem
private void OnCryoSting(EntityUid uid, ChangelingComponent component, CryoStingActionEvent args)
{
if (!HasComp<HumanoidAppearanceComponent>(args.Target))
if (!HasComp<HumanoidAppearanceComponent>(args.Target) ||
!TryComp(args.Target, out TemperatureComponent? temperature))
{
_popup.PopupEntity(Loc.GetString("changeling-popup-cant-sting"), uid, uid);
return;
@@ -440,10 +442,8 @@ public sealed partial class ChangelingSystem
if (!TakeChemicals(uid, component, 15))
return;
var statusTimeSpan = TimeSpan.FromSeconds(30);
_statusEffectsSystem.TryAddStatusEffect(args.Target, "SlowedDown", statusTimeSpan, false, "SlowedDown");
_temperatureSystem.ForceChangeTemperature(args.Target, 100);
_temperatureSystem.ForceChangeTemperature(args.Target, MathF.Min(70, temperature.CurrentTemperature),
temperature);
args.Handled = true;
}

View File

@@ -58,6 +58,9 @@ public sealed partial class TemperatureComponent : Component
}
}
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool Slowdown = true;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public DamageSpecifier ColdDamage = new();

View File

@@ -155,6 +155,13 @@ public sealed class TemperatureSystem : EntitySystem
var heat = temperatureDelta * (airHeatCapacity * heatCapacity /
(airHeatCapacity + heatCapacity));
ChangeHeat(uid, heat * temperature.AtmosTemperatureTransferEfficiency, temperature: temperature);
// WD START
var adjEv = new AdjustTemperatureEvent(temperature.CurrentTemperature);
RaiseLocalEvent(uid, adjEv);
if (!MathHelper.CloseTo(adjEv.Temperature, temperature.CurrentTemperature))
ForceChangeTemperature(uid, adjEv.Temperature, temperature);
// WD END
}
public float GetHeatCapacity(EntityUid uid, TemperatureComponent? comp = null, PhysicsComponent? physics = null)

View File

@@ -0,0 +1,11 @@
namespace Content.Server._White.ChangeTemperatureOnCollide;
[RegisterComponent]
public sealed partial class ChangeTemperatureOnCollideComponent : Component
{
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float Temperature;
[DataField]
public string FixtureID = "projectile";
}

View File

@@ -0,0 +1,30 @@
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared.Atmos;
using Robust.Shared.Physics.Events;
namespace Content.Server._White.ChangeTemperatureOnCollide;
public sealed class ChangeTemperatureOnCollideSystem : EntitySystem
{
[Dependency] private readonly TemperatureSystem _temperature = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ChangeTemperatureOnCollideComponent, StartCollideEvent>(OnCollide);
}
private void OnCollide(EntityUid uid, ChangeTemperatureOnCollideComponent component, ref StartCollideEvent args)
{
if (args.OurFixtureId != component.FixtureID)
return;
if (!TryComp(args.OtherEntity, out TemperatureComponent? temperature))
return;
_temperature.ForceChangeTemperature(args.OtherEntity,
MathF.Max(Atmospherics.TCMB, temperature.CurrentTemperature + component.Temperature), temperature);
}
}

View File

@@ -0,0 +1,11 @@
namespace Content.Server._White.ChangeTemperatureOnCollide;
[RegisterComponent]
public sealed partial class ClothingTemperatureAdjustComponent : Component
{
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float Rate = 1f;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float TargetTemperature = 310.15f;
}

View File

@@ -0,0 +1,23 @@
using Content.Shared.Inventory;
using Content.Shared.Temperature;
namespace Content.Server._White.ChangeTemperatureOnCollide;
public sealed class ClothingTemperatureAdjustSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ClothingTemperatureAdjustComponent, InventoryRelayedEvent<AdjustTemperatureEvent>>(
OnAdjustTemperature);
}
private void OnAdjustTemperature(Entity<ClothingTemperatureAdjustComponent> ent,
ref InventoryRelayedEvent<AdjustTemperatureEvent> args)
{
var delta = ent.Comp.TargetTemperature - args.Args.Temperature;
var rate = Math.Min(ent.Comp.Rate, Math.Abs(delta));
args.Args.Temperature += Math.Sign(delta) * rate;
}
}

View File

@@ -0,0 +1,52 @@
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
namespace Content.Server._White.ChangeTemperatureOnCollide;
public sealed class LowTemperatureSlowdownSystem : EntitySystem
{
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MovementSpeedModifierComponent, OnTemperatureChangeEvent>(OnTemperatureChange);
SubscribeLocalEvent<TemperatureComponent, RefreshMovementSpeedModifiersEvent>(OnMoveSpeedRefresh);
}
private void OnMoveSpeedRefresh(EntityUid uid, TemperatureComponent component,
RefreshMovementSpeedModifiersEvent args)
{
var modifier = !component.Slowdown ? 1f : GetSpeedModifier(component.CurrentTemperature);
args.ModifySpeed(modifier, modifier);
}
private void OnTemperatureChange(EntityUid uid, MovementSpeedModifierComponent component,
OnTemperatureChangeEvent args)
{
// ReSharper disable once CompareOfFloatsByEqualityOperator
if(GetSpeedModifier(args.LastTemperature) == GetSpeedModifier(args.CurrentTemperature))
return;
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(uid, component);
}
private static float GetSpeedModifier(float temperature)
{
return temperature switch
{
> 290f => 1f,
> 280f => 0.9f,
> 260f => 0.8f,
> 230f => 0.7f,
> 200f => 0.6f,
> 160f => 0.5f,
> 110f => 0.4f,
> 50f => 0.3f,
_ => 0.2f
};
}
}

View File

@@ -26,6 +26,7 @@ public partial class InventorySystem
SubscribeLocalEvent<InventoryComponent, BeforeStripEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, SeeIdentityAttemptEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, ModifyChangedTemperatureEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, AdjustTemperatureEvent>(RelayInventoryEvent); // WD
SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
// by-ref events

View File

@@ -13,3 +13,17 @@ public sealed class ModifyChangedTemperatureEvent : EntityEventArgs, IInventoryR
TemperatureDelta = temperature;
}
}
// WD START
public sealed class AdjustTemperatureEvent : EntityEventArgs, IInventoryRelayEvent
{
public SlotFlags TargetSlots => ~SlotFlags.POCKET;
public float Temperature;
public AdjustTemperatureEvent(float temperature)
{
Temperature = temperature;
}
}
// WD END

View File

@@ -40,6 +40,12 @@ public sealed partial class TwoModeEnergyAmmoProviderComponent : BatteryAmmoProv
public SoundSpecifier? ToggleSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Misc/egun_toggle.ogg");
[ViewVariables(VVAccess.ReadOnly)] public bool InStun = true;
[DataField("modeNames")] public Dictionary<EnergyModes, string> ModeNames = new()
{
{EnergyModes.Stun, "Stun"},
{EnergyModes.Laser, "Laser"}
};
}
public enum EnergyModes

View File

@@ -25,13 +25,13 @@ public abstract partial class SharedGunSystem
return;
args.PushMarkup(Loc.GetString("gun-twomode-mode-examine", ("color", TwoModeExamineColor),
("mode", GetLocMode(comp.CurrentMode))));
("mode", GetLocMode(comp))));
}
}
private object GetLocMode(EnergyModes mode)
private object GetLocMode(TwoModeEnergyAmmoProviderComponent comp)
{
return Loc.GetString($"gun-twomode-{mode.ToString()}");
return Loc.GetString($"gun-twomode-{comp.ModeNames[comp.CurrentMode]}");
}
private string GetLocSelector(SelectiveFire mode)

View File

@@ -54,3 +54,5 @@ gun-speedloader-empty = Спидлоадер пуст
gun-twomode-mode-examine = Выбран тип огня [color={ $color }]{ $mode }[/color].
gun-twomode-Stun = шокер
gun-twomode-Laser = лазер
gun-twomode-Cool = охлаждение
gun-twomode-Heat = нагрев

View File

@@ -0,0 +1,4 @@
ent-WeaponTempGun = температурная пушка
.desc = Пушка, изменяющая температуру.
research-technology-temperature-weaponry = Температурное вооружение

View File

@@ -71,6 +71,7 @@
- id: WeaponDisabler
- id: HoloprojectorSecurity
prob: 0.6
- id: WeaponTempGun
- type: entity
id: LockerBrigmedicFilled
@@ -235,3 +236,13 @@
contents:
- id: WeaponLaserCarbine
amount: 3
- type: entity
parent: GunSafe
id: GunSafeTempGun
name: temperature gun safe
components:
- type: StorageFill
contents:
- id: WeaponTempGun
amount: 3

View File

@@ -114,6 +114,7 @@
tags:
- Hardsuit
- WhitelistChameleon
- type: ClothingTemperatureAdjust
- type: entity
abstract: true

View File

@@ -63,6 +63,8 @@
- type: MobPrice
price: 1000 # Living critters are valuable in space.
- type: Perishable
- type: Temperature
slowdown: false
- type: entity
parent:
@@ -106,3 +108,5 @@
price: 150
- type: FloatingVisuals
- type: Penetrated
- type: Temperature
slowdown: true

View File

@@ -1324,3 +1324,56 @@
- type: Reflective
reflective:
- Energy
- type: entity
name: heat beam
id: BulletHeat
parent: BaseBullet
noSpawn: true
components:
- type: FlyBySound
sound:
collection: EnergyMiss
params:
volume: 5
- type: Sprite
sprite: White/Objects/Projectiles/temperature.rsi
layers:
- state: heat
shader: unshaded
- type: Physics
- type: Fixtures
fixtures:
projectile:
shape:
!type:PhysShapeAabb
bounds: "-0.15,-0.3,0.15,0.3"
hard: false
mask:
- Opaque
fly-by: *flybyfixture
- type: Ammo
muzzleFlash: null
- type: ChangeTemperatureOnCollide
temperature: 20
- type: Projectile
damage:
types:
Heat: 0
soundHit:
collection: WeakHit
soundForce: true
- type: entity
name: cold beam
id: BulletCold
parent: BulletHeat
noSpawn: true
components:
- type: Sprite
sprite: White/Objects/Projectiles/temperature.rsi
layers:
- state: cold
shader: unshaded
- type: ChangeTemperatureOnCollide
temperature: -20

View File

@@ -319,6 +319,7 @@
- ClothingEyesNightVisionGoggles # WD EDIT
- KitchenKnife # WD EDIT
- ButchCleaver # WD EDIT
- WeaponTempGun # WD EDIT
- DeviceQuantumSpinInverter
- type: EmagLatheRecipes
emagDynamicRecipes:
@@ -723,6 +724,7 @@
- WeaponLaserCannon
- WeaponLaserCarbine
- WeaponXrayCannon
- WeaponTempGun # WD EDIT
- PowerCageSmall
- PowerCageMedium
- PowerCageHigh

View File

@@ -0,0 +1,27 @@
- type: entity
name: temperature gun
parent: WeaponEgun
id: WeaponTempGun
description: A gun that changes temperatures.
components:
- type: Sprite
sprite: White/Objects/Weapons/Guns/Battery/tempgun.rsi
- type: Gun
soundGunshot:
path: /Audio/Weapons/Guns/Gunshots/laser.ogg
- type: TwoModeEnergyAmmoProvider
stunPrototype: BulletCold
fireCost: 64
stunFireCost: 64
laserPrototype: BulletHeat
laserFireCost: 64
stunProjectileSpeed: 48
laserProjectileSpeed: 48
projSound: "/Audio/Weapons/Guns/Gunshots/laser.ogg"
hitscanSound: "/Audio/Weapons/Guns/Gunshots/laser.ogg"
modeNames:
Stun: Cool
Laser: Heat
- type: BatterySelfRecharger
autoRecharge: true
autoRechargeRate: 20

View File

@@ -11,6 +11,7 @@
completetime: 5
materials:
Steel: 1500
- type: latheRecipe
id: ClothingEyesNightVisionGoggles
result: ClothingEyesNightVisionGoggles
@@ -21,3 +22,11 @@
Silver: 100
Gold: 100
- type: latheRecipe
id: WeaponTempGun
result: WeaponTempGun
completetime: 8
materials:
Steel: 1500
Glass: 1000
Silver: 200

View File

@@ -0,0 +1,11 @@
- type: technology
id: TemperatureWeaponry
name: research-technology-temperature-weaponry
icon:
sprite: White/Objects/Weapons/Guns/Battery/tempgun.rsi
state: icon
discipline: Arsenal
tier: 2
cost: 7500
recipeUnlocks:
- WeaponTempGun

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

View File

@@ -0,0 +1,17 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "taken from vgstation at https://github.com/vgstation-coders/vgstation13 at 6f3d7af6acf4f100cd88deec74cc750d6e90e4f3",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "cold"
},
{
"name": "heat"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

View File

@@ -0,0 +1,75 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from vgstation and tgstation",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "base"
},
{
"name": "mag-twomode1-0",
"delays": [
[
0.3,
0.3
]
]
},
{
"name": "mag-twomode1-1"
},
{
"name": "mag-twomode1-2"
},
{
"name": "mag-twomode1-3"
},
{
"name": "mag-twomode1-4"
},
{
"name": "mag-twomode2-0",
"delays": [
[
0.3,
0.3
]
]
},
{
"name": "mag-twomode2-1"
},
{
"name": "mag-twomode2-2"
},
{
"name": "mag-twomode2-3"
},
{
"name": "mag-twomode2-4"
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
},
{
"name": "laser-inhand-left",
"directions": 4
},
{
"name": "laser-inhand-right",
"directions": 4
}
]
}