Skip to content

Commit

Permalink
Продвинутое энергетическое оружие (#59)
Browse files Browse the repository at this point in the history
* added advanced energy gun (AEG)

* added traitor objective targeting HoS' new gun

* fixed formatting

* added research tech unlocking energy weaponry

* me stupid
  • Loading branch information
pxc1984 authored Jun 12, 2024
1 parent ce27d25 commit 4fd33aa
Show file tree
Hide file tree
Showing 98 changed files with 1,001 additions and 2 deletions.
57 changes: 57 additions & 0 deletions Content.Server/_Sunrise/Weapons/EnergyGunComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Content.Server.Weapons.Ranged.Systems;

namespace Content.Server.Weapons.Ranged.Components;

/// <summary>
/// Allows for energy gun to switch between three modes. This also changes the sprite accordingly.
/// </summary>
/// <remarks>This is BatteryWeaponFireModesSystem with additional changes to allow for different sprites.</remarks>
[RegisterComponent]
[Access(typeof(EnergyGunSystem))]
[AutoGenerateComponentState]
public sealed partial class EnergyGunComponent : Component
{
/// <summary>
/// A list of the different firing modes the energy gun can switch between
/// </summary>
[DataField("fireModes", required: true)]
[AutoNetworkedField]
public List<EnergyWeaponFireMode> FireModes = new();

/// <summary>
/// The currently selected firing mode
/// </summary>
[DataField("currentFireMode")]
[AutoNetworkedField]
public EnergyWeaponFireMode? CurrentFireMode = default!;
}

[DataDefinition]
public sealed partial class EnergyWeaponFireMode
{
/// <summary>
/// The projectile prototype associated with this firing mode
/// </summary>
[DataField("proto", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string Prototype = default!;

/// <summary>
/// The battery cost to fire the projectile associated with this firing mode
/// </summary>
[DataField("fireCost")]
public float FireCost = 100;

/// <summary>
/// The name of the selected firemode
/// </summary>
[DataField("name")]
public string Name = string.Empty;

/// <summary>
/// What RsiState we use for that firemode if it needs to change.
/// </summary>
[DataField("state")]
public string State = string.Empty;
}
159 changes: 159 additions & 0 deletions Content.Server/_Sunrise/Weapons/EnergyGunSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
using Content.Server.Popups;
using Content.Server.Weapons.Ranged.Components;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Verbs;
using Content.Shared.Item;
using Content.Shared._Sunrise.Weapons.Ranged;
using Content.Shared.Weapons.Ranged.Components;
using Robust.Shared.Prototypes;
using System.Linq;
using System;

namespace Content.Server.Weapons.Ranged.Systems;
public sealed class EnergyGunSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedItemSystem _item = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<EnergyGunComponent, ActivateInWorldEvent>(OnInteractHandEvent);
SubscribeLocalEvent<EnergyGunComponent, GetVerbsEvent<Verb>>(OnGetVerb);
SubscribeLocalEvent<EnergyGunComponent, ExaminedEvent>(OnExamined);
}

private void OnExamined(EntityUid uid, EnergyGunComponent component, ExaminedEvent args)
{
if (component.FireModes == null || component.FireModes.Count < 2)
return;

if (component.CurrentFireMode == null)
{
SetFireMode(uid, component, component.FireModes.First());
}

if (component.CurrentFireMode?.Prototype == null)
return;

if (!_prototypeManager.TryIndex<EntityPrototype>(component.CurrentFireMode.Prototype, out var proto))
return;

args.PushMarkup(Loc.GetString("energygun-examine-fire-mode", ("mode", Loc.GetString(component.CurrentFireMode.Name))));
}

private void OnGetVerb(EntityUid uid, EnergyGunComponent component, GetVerbsEvent<Verb> args)
{
if (!args.CanAccess || !args.CanInteract || args.Hands == null)
return;

if (component.FireModes == null || component.FireModes.Count < 2)
return;

if (component.CurrentFireMode == null)
{
SetFireMode(uid, component, component.FireModes.First());
}

foreach (var fireMode in component.FireModes)
{
var entProto = _prototypeManager.Index<EntityPrototype>(fireMode.Prototype);

var v = new Verb
{
Priority = 1,
Category = VerbCategory.SelectType,
Text = entProto.Name,
Disabled = fireMode == component.CurrentFireMode,
Impact = LogImpact.Low,
DoContactInteraction = true,
Act = () =>
{
SetFireMode(uid, component, fireMode, args.User);
}
};

args.Verbs.Add(v);
}
}

private void OnInteractHandEvent(EntityUid uid, EnergyGunComponent component, ActivateInWorldEvent args)
{
if (component.FireModes == null || component.FireModes.Count < 2)
return;

CycleFireMode(uid, component, args.User);
}

private void CycleFireMode(EntityUid uid, EnergyGunComponent component, EntityUid user)
{
int index = (component.CurrentFireMode != null) ?
Math.Max(component.FireModes.IndexOf(component.CurrentFireMode), 0) + 1 : 1;

EnergyWeaponFireMode? fireMode;

if (index >= component.FireModes.Count)
{
fireMode = component.FireModes.FirstOrDefault();
}

else
{
fireMode = component.FireModes[index];
}

SetFireMode(uid, component, fireMode, user);
}

private void SetFireMode(EntityUid uid, EnergyGunComponent component, EnergyWeaponFireMode? fireMode, EntityUid? user = null)
{
if (fireMode?.Prototype == null)
return;

component.CurrentFireMode = fireMode;

if (TryComp(uid, out ProjectileBatteryAmmoProviderComponent? projectileBatteryAmmoProvider))
{
if (!_prototypeManager.TryIndex<EntityPrototype>(fireMode.Prototype, out var prototype))
return;

projectileBatteryAmmoProvider.Prototype = fireMode.Prototype;
projectileBatteryAmmoProvider.FireCost = fireMode.FireCost;

if (user != null)
{
_popupSystem.PopupEntity(Loc.GetString("gun-set-fire-mode", ("mode", Loc.GetString(component.CurrentFireMode.Name))), uid, user.Value);
}

if (component.CurrentFireMode.State == string.Empty)
return;

if (TryComp<AppearanceComponent>(uid, out var _) && TryComp<ItemComponent>(uid, out var item))
{
_item.SetHeldPrefix(uid, component.CurrentFireMode.State, false, item);
switch (component.CurrentFireMode.State)
{
case "disabler":
UpdateAppearance(uid, EnergyGunFireModeState.Disabler);
break;
case "lethal":
UpdateAppearance(uid, EnergyGunFireModeState.Lethal);
break;
case "special":
UpdateAppearance(uid, EnergyGunFireModeState.Special);
break;
}
}
}
}

private void UpdateAppearance(EntityUid uid, EnergyGunFireModeState state)
{
_appearance.SetData(uid, EnergyGunFireModeVisuals.State, state);
}
}
17 changes: 17 additions & 0 deletions Content.Shared/_Sunrise/Weapons/EnergyGunFireModeVisuals.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Robust.Shared.Serialization;

namespace Content.Shared._Sunrise.Weapons.Ranged;

[Serializable, NetSerializable]
public enum EnergyGunFireModeVisuals : byte
{
State
}

[Serializable, NetSerializable]
public enum EnergyGunFireModeState : byte
{
Disabler,
Lethal,
Special
}
1 change: 1 addition & 0 deletions Resources/Locale/en-US/_sunrise/ranged/energygun.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
energygun-examine-fire-mode = The firemode is set to {$mode}
3 changes: 3 additions & 0 deletions Resources/Locale/en-US/research/technologies.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ research-technology-portable-microfusion-weaponry = Portable Microfusion Weaponr
research-technology-experimental-battery-ammo = Experimental Battery Ammo
research-technology-basic-shuttle-armament = Shuttle basic armament
research-technology-advanced-shuttle-weapon = Advanced shuttle weapons
research-technology-energy-gun = Energy weaponry
research-technology-energy-gun-advance = Advanced energy weaponry
research-technology-advance-laser = Military-grade energy weaponry
research-technology-basic-robotics = Basic Robotics
research-technology-basic-anomalous-research = Basic Anomalous Research
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ ent-HandTeleporterStealObjective = { ent-BaseRDStealObjective }
.desc = { ent-BaseRDStealObjective.desc }
ent-SecretDocumentsStealObjective = { ent-BaseTraitorStealObjective }
.desc = { ent-BaseTraitorStealObjective.desc }
ent-MultiphaseEnergygunStealObjective = { ent-BaseTraitorStealObjective }
.desc = { ent-BaseTraitorStealObjective.desc }
ent-MagbootsStealObjective = { ent-BaseTraitorStealObjective }
.desc = { ent-BaseTraitorStealObjective.desc }
ent-ClipboardStealObjective = { ent-BaseTraitorStealObjective }
Expand Down
19 changes: 19 additions & 0 deletions Resources/Locale/ru-RU/_sunrise/ranged/energygun.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
energygun-examine-fire-mode = Режим огня установлен на {$mode}
ent-WeaponEnergyGun = Энергетическая пушка
.desc = Базовая гибридная энергетическая с двумя режимами работы: обезоруживание и летал.
ent-WeaponEnergyGunMultiphase = X-01 Мультифазный энергетический карабин
.desc = Это дорогая современная реконструкция старинного лазерного пистолета. Пистолет имеет несколько уникальных режимов стрельбы, но лишен возможности перезаряжаться со временем.
ent-WeaponEnergyGunMini = миниатюрная энергетическая пушка
.desc = Облегченная версия энергетического пистолета с меньшей емкостью.
ent-WeaponEnergyGunPistol = Энергетический пистолет PDW-9
.desc = Военное оружие, используемое многими ополченцами в местном секторе.
ent-WeaponGunLaserCarbineAutomatic = Лазерный карабин ИК-60
.desc = Лазерный полуавтоматический карабин на 20 патронов.
energy-gun-lethal = летал
energy-gun-disable = обезоруживание
3 changes: 3 additions & 0 deletions Resources/Locale/ru-RU/research/technologies.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ research-technology-honk-mech = Мех Х.О.Н.К.
research-technology-advanced-spray = Продвинутые спреи
research-technology-quantum-fiber-weaving = Плетение квантового волокна
research-technology-bluespace-cargo-transport = Блюспейс-транспортировка грузов
research-technology-energy-gun = Энергетическое вооружение
research-technology-energy-gun-advance = Продвинутое энергетическое вооружение
research-technology-advance-laser = Военное энергетическое вооружение
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ ent-HandTeleporterStealObjective = { ent-BaseRDStealObjective }
.desc = { ent-BaseRDStealObjective.desc }
ent-SecretDocumentsStealObjective = { ent-BaseTraitorStealObjective }
.desc = { ent-BaseTraitorStealObjective.desc }
ent-MultiphaseEnergygunStealObjective = { ent-BaseTraitorStealObjective }
.desc = { ent-BaseTraitorStealObjective.desc }
ent-MagbootsStealObjective = { ent-BaseTraitorStealObjective }
.desc = { ent-BaseTraitorStealObjective.desc }
ent-ClipboardStealObjective = { ent-BaseTraitorStealObjective }
Expand Down
4 changes: 2 additions & 2 deletions Resources/Prototypes/Catalog/Fills/Lockers/heads.yml
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,7 @@
- id: ClothingMaskGasSwat
# - id: ClothingShoeSlippersDuck: Need more space for style
# prob: 0.2
- id: DrinkVacuumFlask
prob: 0.8
- id: WeaponEnergyGunMultiphase # Sunrise-AEG
- id: ClothingBeltSecurityFilled
- id: ClothingHeadsetAltSecurity
- id: ClothingEyesGlassesSecurity
Expand Down Expand Up @@ -316,6 +315,7 @@
- id: BoxEncryptionKeySecurity
- id: HoloprojectorSecurity
- id: BookSecretDocuments
- id: WeaponEnergyGunMultiphase # Sunrise-AEG

- type: entity
id: LockerFreezerVaultFilled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1108,3 +1108,44 @@
soundHit:
collection: WeakHit
soundForce: true

# Sunrise-AEG
- type: entity
name: energy bolt
id: BulletEnergyGunLaser
parent: BaseBullet
noSpawn: true
components:
- type: Reflective
reflective:
- Energy
- type: FlyBySound
sound:
collection: EnergyMiss
params:
volume: 5
- type: Sprite
sprite: Objects/Weapons/Guns/Projectiles/projectiles_tg.rsi
layers:
- state: omnilaser_greyscale
shader: unshaded
color: red
- type: Ammo
- type: Physics
- type: Fixtures
fixtures:
projectile:
shape:
!type:PhysShapeAabb
bounds: "-0.2,-0.2,0.2,0.2"
hard: false
mask:
- Opaque
fly-by: *flybyfixture
- type: Projectile
impactEffect: BulletImpactEffectRedDisabler
damage:
types:
Heat: 20 # Slightly more damage than the 17heat from the Captain's Hitscan lasgun
soundHit:
collection: WeakHit
4 changes: 4 additions & 0 deletions Resources/Prototypes/Entities/Structures/Machines/lathe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@
- RiotShield
- SpeedLoaderMagnum
- SpeedLoaderMagnumEmpty
- WeaponEnergyGun # Sunrise - Energy Gun
- WeaponEnergyGunMini # Sunrise - Miniature Energy Gun
- WeaponEnergyGunPistol # Sunrise - PDW-9 Energy Pistol
- WeaponGunLaserCarbineAutomatic # Sunrise - IK-60 Laser Carbine

- type: entity
id: AutolatheHyperConvection
Expand Down
7 changes: 7 additions & 0 deletions Resources/Prototypes/Objectives/stealTargetGroups.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
sprite: Objects/Misc/bureaucracy.rsi
state: folder-sec-doc

- type: stealTargetGroup # Sunrise-AEG
id: WeaponEnergyGunMultiphase
name: x-01 multiphase energy gun
sprite:
sprite: _Sunrise/Objects/Weapons/Guns/Battery/multiphase_energygun.rsi
state: base

- type: stealTargetGroup
id: ClothingShoesBootsMagAdv
name: advanced magboots
Expand Down
Loading

0 comments on commit 4fd33aa

Please sign in to comment.