Снова абдукторы (#2705)
This commit is contained in:
parent
d85c749552
commit
dd73908949
17 changed files with 272 additions and 93 deletions
|
|
@ -16,6 +16,7 @@ using Content.Shared.Hands.EntitySystems;
|
|||
using Robust.Server.GameObjects;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
|
||||
namespace Content.Server._Sunrise.Antags.Abductor;
|
||||
|
||||
|
|
@ -35,6 +36,8 @@ public sealed partial class AbductorSystem : SharedAbductorSystem
|
|||
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||
[Dependency] private readonly SharedVirtualItemSystem _virtualItem = default!;
|
||||
|
||||
private EntityUid? _opener;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<AbductorHumanObservationConsoleComponent, BeforeActivatableUIOpenEvent>(OnBeforeActivatableUIOpen);
|
||||
|
|
@ -43,6 +46,7 @@ public sealed partial class AbductorSystem : SharedAbductorSystem
|
|||
SubscribeLocalEvent<AbductorComponent, GetVisMaskEvent>(OnAbductorGetVis);
|
||||
|
||||
Subs.BuiEvents<AbductorHumanObservationConsoleComponent>(AbductorCameraConsoleUIKey.Key, subs => subs.Event<AbductorBeaconChosenBuiMsg>(OnAbductorBeaconChosenBuiMsg));
|
||||
|
||||
InitializeActions();
|
||||
InitializeGizmo();
|
||||
InitializeConsole();
|
||||
|
|
@ -60,110 +64,78 @@ public sealed partial class AbductorSystem : SharedAbductorSystem
|
|||
private void OnAbductorBeaconChosenBuiMsg(Entity<AbductorHumanObservationConsoleComponent> ent, ref AbductorBeaconChosenBuiMsg args)
|
||||
{
|
||||
OnCameraExit(args.Actor);
|
||||
if (ent.Comp.RemoteEntityProto != null)
|
||||
|
||||
EntityUid eye;
|
||||
|
||||
_opener = args.Actor;
|
||||
var beacon = _entityManager.GetEntity(args.Beacon.NetEnt);
|
||||
var beaconCoords = Transform(beacon).Coordinates;
|
||||
|
||||
if (ent.Comp.RemoteEntity != null && TryGetEntity(ent.Comp.RemoteEntity, out var existingEye))
|
||||
{
|
||||
var beacon = _entityManager.GetEntity(args.Beacon.NetEnt);
|
||||
var eye = SpawnAtPosition(ent.Comp.RemoteEntityProto, Transform(beacon).Coordinates);
|
||||
ent.Comp.RemoteEntity = GetNetEntity(eye);
|
||||
|
||||
if (TryComp<HandsComponent>(args.Actor, out var handsComponent))
|
||||
{
|
||||
foreach (var hand in _hands.EnumerateHands(args.Actor, handsComponent))
|
||||
{
|
||||
if (hand.HeldEntity == null)
|
||||
continue;
|
||||
|
||||
if (HasComp<UnremoveableComponent>(hand.HeldEntity))
|
||||
continue;
|
||||
|
||||
_hands.DoDrop(args.Actor, hand, true, handsComponent);
|
||||
}
|
||||
|
||||
if (_virtualItem.TrySpawnVirtualItemInHand(ent.Owner, args.Actor, out var virtItem1))
|
||||
{
|
||||
EnsureComp<UnremoveableComponent>(virtItem1.Value);
|
||||
}
|
||||
|
||||
if (_virtualItem.TrySpawnVirtualItemInHand(ent.Owner, args.Actor, out var virtItem2))
|
||||
{
|
||||
EnsureComp<UnremoveableComponent>(virtItem2.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var visibility = EnsureComp<VisibilityComponent>(eye);
|
||||
|
||||
Dirty(ent);
|
||||
|
||||
if (TryComp(args.Actor, out EyeComponent? eyeComp))
|
||||
{
|
||||
_eye.RefreshVisibilityMask(args.Actor);
|
||||
_eye.SetTarget(args.Actor, eye, eyeComp);
|
||||
_eye.SetDrawFov(args.Actor, false);
|
||||
|
||||
if (!TryComp(eye, out RemoteEyeSourceContainerComponent? remoteEyeSourceContainerComponent))
|
||||
{
|
||||
remoteEyeSourceContainerComponent = new RemoteEyeSourceContainerComponent { Actor = args.Actor };
|
||||
AddComp(eye, remoteEyeSourceContainerComponent);
|
||||
}
|
||||
else
|
||||
remoteEyeSourceContainerComponent.Actor = args.Actor;
|
||||
Dirty(eye, remoteEyeSourceContainerComponent);
|
||||
}
|
||||
|
||||
AddActions(args);
|
||||
|
||||
_mover.SetRelay(args.Actor, eye);
|
||||
eye = existingEye.Value;
|
||||
_xformSys.SetCoordinates(eye, beaconCoords);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCameraExit(EntityUid actor)
|
||||
{
|
||||
AbductorScientistComponent? scientistComp = null;
|
||||
AbductorAgentComponent? agentComp = null;
|
||||
|
||||
if (TryComp<RelayInputMoverComponent>(actor, out var comp) && TryComp<AbductorScientistComponent>(actor, out scientistComp) || TryComp<AbductorAgentComponent>(actor, out agentComp))
|
||||
else
|
||||
{
|
||||
EntityUid? console = null;
|
||||
|
||||
if (scientistComp != null && scientistComp.Console.HasValue)
|
||||
console = scientistComp.Console.Value;
|
||||
else if (agentComp != null && agentComp.Console.HasValue)
|
||||
console = agentComp.Console.Value;
|
||||
|
||||
if (console == null || comp == null)
|
||||
if (ent.Comp.RemoteEntityProto == null)
|
||||
return;
|
||||
|
||||
var relay = comp.RelayEntity;
|
||||
RemComp(actor, comp);
|
||||
eye = SpawnAtPosition(ent.Comp.RemoteEntityProto, Transform(beacon).Coordinates);
|
||||
ent.Comp.RemoteEntity = GetNetEntity(eye);
|
||||
|
||||
_virtualItem.DeleteInHandsMatching(actor, console.Value);
|
||||
EnsureComp<VisibilityComponent>(eye);
|
||||
|
||||
if (TryComp(actor, out EyeComponent? eyeComp))
|
||||
{
|
||||
_eye.SetVisibilityMask(actor, eyeComp.VisibilityMask ^ (int)VisibilityFlags.Abductor, eyeComp);
|
||||
_eye.SetDrawFov(actor, true);
|
||||
}
|
||||
RemoveActions(actor);
|
||||
QueueDel(relay);
|
||||
var remoteEyeSource = EnsureComp<RemoteEyeSourceContainerComponent>(eye);
|
||||
remoteEyeSource.Actor = args.Actor;
|
||||
|
||||
Dirty(eye, remoteEyeSource);
|
||||
}
|
||||
|
||||
AddVirtualItems(args.Actor, ent);
|
||||
SetEye(args.Actor, eye, args);
|
||||
Dirty(ent);
|
||||
}
|
||||
private void OnCameraExit(EntityUid actor)
|
||||
{
|
||||
if (!HasComp<RelayInputMoverComponent>(actor))
|
||||
return;
|
||||
|
||||
EntityUid? console = null;
|
||||
|
||||
if (TryComp<AbductorScientistComponent>(actor, out var scientistComp) && scientistComp.Console is { } scientistConsole)
|
||||
console = scientistConsole;
|
||||
|
||||
if (TryComp<AbductorAgentComponent>(actor, out var agentComp) && agentComp.Console is { } agentConsole)
|
||||
console = agentConsole;
|
||||
|
||||
if (console == null)
|
||||
return;
|
||||
|
||||
RemoveEye(actor);
|
||||
_virtualItem.DeleteInHandsMatching(actor, console.Value);
|
||||
|
||||
_opener = null;
|
||||
}
|
||||
|
||||
private void OnActivatableUIOpenAttemptEvent(Entity<AbductorHumanObservationConsoleComponent> ent, ref ActivatableUIOpenAttemptEvent args)
|
||||
{
|
||||
if (!HasComp<AbductorScientistComponent>(args.User) && !HasComp<AbductorAgentComponent>(args.User))
|
||||
args.Cancel();
|
||||
|
||||
if (_opener != null && _opener != args.User)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("console-occupied"), args.User, args.User);
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBeforeActivatableUIOpen(Entity<AbductorHumanObservationConsoleComponent> ent, ref BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
AbductorAgentComponent? agentComp = null;
|
||||
|
||||
if (!TryComp<AbductorScientistComponent>(args.User, out var scientistComp) && !TryComp<AbductorAgentComponent>(args.User, out agentComp))
|
||||
return;
|
||||
|
||||
if (scientistComp != null)
|
||||
if (TryComp<AbductorScientistComponent>(args.User, out var scientistComp))
|
||||
scientistComp.Console = ent.Owner;
|
||||
else if (agentComp != null)
|
||||
|
||||
if (TryComp<AbductorAgentComponent>(args.User, out var agentComp))
|
||||
agentComp.Console = ent.Owner;
|
||||
|
||||
var stations = _stationSystem.GetStations();
|
||||
|
|
@ -175,8 +147,6 @@ public sealed partial class AbductorSystem : SharedAbductorSystem
|
|||
|| !TryComp(station, out MetaDataComponent? stationMetaData))
|
||||
return;
|
||||
|
||||
var mapId = Transform(grid).MapID;
|
||||
|
||||
if (!_entityManager.TryGetComponent<NavMapComponent>(grid, out var navMap))
|
||||
return;
|
||||
|
||||
|
|
@ -190,4 +160,54 @@ public sealed partial class AbductorSystem : SharedAbductorSystem
|
|||
|
||||
_uiSystem.SetUiState(ent.Owner, AbductorCameraConsoleUIKey.Key, new AbductorCameraConsoleBuiState() { Stations = result });
|
||||
}
|
||||
|
||||
private void SetEye(EntityUid uid, EntityUid eye, AbductorBeaconChosenBuiMsg args)
|
||||
{
|
||||
if (!TryComp(uid, out EyeComponent? eyeComp))
|
||||
return;
|
||||
|
||||
AddComp(uid, new StationAiOverlayComponent { AllowCrossGrid = true });
|
||||
|
||||
_eye.RefreshVisibilityMask(uid);
|
||||
_eye.SetTarget(uid, eye, eyeComp);
|
||||
_eye.SetDrawFov(uid, false);
|
||||
|
||||
AddActions(args);
|
||||
_mover.SetRelay(uid, eye);
|
||||
}
|
||||
|
||||
private void RemoveEye(EntityUid uid)
|
||||
{
|
||||
if (!TryComp(uid, out EyeComponent? eyeComp))
|
||||
return;
|
||||
|
||||
RemComp<RelayInputMoverComponent>(uid);
|
||||
RemComp<StationAiOverlayComponent>(uid);
|
||||
|
||||
_eye.SetTarget(uid, null);
|
||||
_eye.SetVisibilityMask(uid, eyeComp.VisibilityMask ^ (int)VisibilityFlags.Abductor, eyeComp);
|
||||
_eye.SetDrawFov(uid, true);
|
||||
|
||||
RemoveActions(uid);
|
||||
}
|
||||
|
||||
private void AddVirtualItems(EntityUid uid, EntityUid console)
|
||||
{
|
||||
if (!TryComp<HandsComponent>(uid, out var hands))
|
||||
return;
|
||||
|
||||
foreach (var hand in _hands.EnumerateHands(uid, hands))
|
||||
{
|
||||
if (hand.HeldEntity == null || HasComp<UnremoveableComponent>(hand.HeldEntity))
|
||||
continue;
|
||||
|
||||
_hands.DoDrop(uid, hand, true, hands);
|
||||
}
|
||||
|
||||
if (_virtualItem.TrySpawnVirtualItemInHand(console, uid, out var virtItem1))
|
||||
EnsureComp<UnremoveableComponent>(virtItem1.Value);
|
||||
|
||||
if (_virtualItem.TrySpawnVirtualItemInHand(console, uid, out var virtItem2))
|
||||
EnsureComp<UnremoveableComponent>(virtItem2.Value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,28 @@ public abstract partial class SharedMoverController
|
|||
Dirty(relayEntity, targetComp);
|
||||
_blocker.UpdateCanMove(uid);
|
||||
}
|
||||
// Sunrise-start
|
||||
public void RemoveRelay(EntityUid uid)
|
||||
{
|
||||
if (!TryComp<RelayInputMoverComponent>(uid, out var moverComp))
|
||||
return;
|
||||
|
||||
var relay = moverComp.RelayEntity;
|
||||
|
||||
if (TryComp(relay, out MovementRelayTargetComponent? targetComp))
|
||||
{
|
||||
targetComp.Source = EntityUid.Invalid;
|
||||
Dirty(relay, targetComp);
|
||||
RemCompDeferred<MovementRelayTargetComponent>(relay);
|
||||
PhysicsSystem.UpdateIsPredicted(relay);
|
||||
}
|
||||
|
||||
Dirty(uid, moverComp);
|
||||
RemCompDeferred<RelayInputMoverComponent>(uid);
|
||||
PhysicsSystem.UpdateIsPredicted(uid);
|
||||
_blocker.UpdateCanMove(uid);
|
||||
}
|
||||
// Sunrise-end
|
||||
|
||||
private void OnRelayShutdown(Entity<RelayInputMoverComponent> entity, ref ComponentShutdown args)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ public sealed partial class TeleportLocationsComponent : Component
|
|||
/// </summary>
|
||||
[DataField]
|
||||
public LocId? Speech;
|
||||
|
||||
// Sunrise-start
|
||||
[DataField]
|
||||
public bool DeleteAfterUse;
|
||||
// Sunrise-end
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,10 @@ public abstract partial class SharedTeleportLocationsSystem : EntitySystem
|
|||
|
||||
// Teleport's done, now tell the BUI to close if needed.
|
||||
_ui.CloseUi(ent.Owner, TeleportLocationUiKey.Key);
|
||||
|
||||
// Sunrise-start
|
||||
if (comp.DeleteAfterUse)
|
||||
QueueDel(ent);
|
||||
// Sunrise-end
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@
|
|||
source: "https://github.com/ss14Starlight/space-station-14"
|
||||
|
||||
- files: ["holopaper_open"]
|
||||
license: "Custom"
|
||||
copyright: 'ZAPSPLAT'
|
||||
source: "https://www.zapsplat.com/sound-effect-category/rollover/"
|
||||
|
|
|
|||
|
|
@ -29,5 +29,6 @@ abductors-ui-shop-WeaponAlien = Инопланетный пистолет
|
|||
abductors-ui-shop-ClothingHeadHelmetAbductor = Шлем
|
||||
abductors-ui-shop-AbductorGizmo = Гизмо
|
||||
abductors-ui-shop-AbductorExtractor = Экстрактор сердца
|
||||
abductors-ui-shop-MedkitCombat = Боевая аптечка
|
||||
abductors-ui-shop-MedkitUniversal = Универсальная аптечка
|
||||
abductors-ui-shop-Teleporter = Одноразовый телепорт
|
||||
abductors-ui-shop-VendingMachineRestockAbductorDispenser = Пополнение диспенсера
|
||||
|
|
|
|||
|
|
@ -20,3 +20,5 @@ gizmo-is-successfully-filled = Гизмо успешно заполнен
|
|||
gizmo-is-not-in-pockets = В карманах нету гизмо!
|
||||
owo-organ-transformation = ВЫ КОШКОФИЦИРОВАЛИСЬ!!
|
||||
need-stop-carry = Нельзя переместиться пока кто-то на руках!
|
||||
console-occupied = Консоль уже занята кем-то!
|
||||
teleportation-device-window-title = Устройство телепортации
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
- type: entity
|
||||
id: MedkitUniversalFilled
|
||||
name: universal medkit
|
||||
desc: Contains all types of medicine that you need.
|
||||
suffix: Filled
|
||||
parent: MedkitCombat
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: MedicatedSuture
|
||||
amount: 2
|
||||
- id: RegenerativeMesh
|
||||
amount: 2
|
||||
- id: PillCanisterHyronalin
|
||||
- id: BurnAutoInjector
|
||||
amount: 2
|
||||
- id: BruteAutoInjector
|
||||
amount: 2
|
||||
- id: SyringeSaline
|
||||
amount: 2
|
||||
- id: PillCanisterDylovene
|
||||
- type: Storage
|
||||
grid:
|
||||
- 0,0,3,3
|
||||
- type: Item
|
||||
size: Huge
|
||||
|
|
@ -61,6 +61,7 @@
|
|||
gloves: ClothingHandsGlovesCombat
|
||||
shoes: ClothingShoesBootsCombat
|
||||
pocket1: AbductorGizmo
|
||||
id: AbductorIDCard
|
||||
|
||||
- type: startingGear
|
||||
id: AbductorAgentGear
|
||||
|
|
@ -74,6 +75,7 @@
|
|||
pocket2: WeaponAlien
|
||||
belt: ClothingAbductorBeltFilled
|
||||
outerClothing: ClothingOuterArmorAbductor
|
||||
id: AbductorIDCard
|
||||
inhand:
|
||||
- Wonderprod
|
||||
|
||||
|
|
|
|||
|
|
@ -374,3 +374,26 @@
|
|||
- state: idstationminer
|
||||
- type: PresetIdCard
|
||||
job: MiningSpecialist
|
||||
|
||||
- type: entity
|
||||
parent: [ IDCardStandard ]
|
||||
id: AbductorIDCard
|
||||
name: abductor ID card
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _Sunrise/Objects/Misc/id_cards.rsi
|
||||
layers:
|
||||
- state: abductor
|
||||
- type: Access # get your access from your victims.
|
||||
- type: AgentIDCard
|
||||
- type: IdCard
|
||||
bypassLogging: true
|
||||
canMicrowave: false
|
||||
jobTitle: job-name-unknown
|
||||
- type: ActivatableUI
|
||||
key: enum.AgentIDCardUiKey.Key
|
||||
inHandsOnly: true
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
enum.AgentIDCardUiKey.Key:
|
||||
type: AgentIDCardBoundUserInterface
|
||||
|
|
|
|||
|
|
@ -30,5 +30,5 @@
|
|||
- type: InjectOnHit
|
||||
limit: 20
|
||||
reagents:
|
||||
- ReagentId: MuteToxin
|
||||
- ReagentId: MuteToxinAbductor
|
||||
Quantity: 5
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@
|
|||
- type: InjectOnHit
|
||||
limit: 20
|
||||
reagents:
|
||||
- ReagentId: Nocturine
|
||||
- ReagentId: NocturineAbductor
|
||||
Quantity: 2.5
|
||||
|
||||
damage: !type:ItemSwitchState
|
||||
|
|
|
|||
|
|
@ -13,3 +13,24 @@
|
|||
- state: green_bit
|
||||
shader: unshaded
|
||||
- state: refill_medical
|
||||
|
||||
- type: entity
|
||||
id: AbductorTeleport
|
||||
name: teleport device
|
||||
parent: [ BaseItem, BaseMagicalContraband ]
|
||||
components:
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
enum.TeleportLocationUiKey.Key:
|
||||
type: TeleportLocationsBoundUserInterface
|
||||
- type: ActivatableUI
|
||||
key: enum.TeleportLocationUiKey.Key
|
||||
- type: Sprite
|
||||
sprite: Objects/Devices/hand_teleporter.rsi
|
||||
state: icon
|
||||
- type: TeleportLocations
|
||||
name: teleportation-device-window-title
|
||||
teleportEffect: RadiationPulse
|
||||
closeAfterTeleport: true
|
||||
deleteAfterUse: true
|
||||
|
||||
|
|
|
|||
|
|
@ -144,3 +144,45 @@
|
|||
damage:
|
||||
types:
|
||||
Poison: 5
|
||||
|
||||
- type: reagent
|
||||
id: MuteToxinAbductor
|
||||
name: reagent-name-mute-toxin
|
||||
group: Narcotics
|
||||
desc: reagent-desc-mute-toxin
|
||||
physicalDesc: reagent-physical-desc-syrupy
|
||||
color: "#000000"
|
||||
boilingPoint: 255.0
|
||||
meltingPoint: 36.0
|
||||
metabolisms:
|
||||
Narcotic:
|
||||
effects:
|
||||
- !type:GenericStatusEffect
|
||||
key: Muted
|
||||
component: Muted
|
||||
type: Add
|
||||
time: 80
|
||||
refresh: true
|
||||
|
||||
- type: reagent
|
||||
id: NocturineAbductor
|
||||
name: reagent-name-nocturine
|
||||
group: Narcotics
|
||||
desc: reagent-desc-nocturine
|
||||
physicalDesc: reagent-physical-desc-powdery
|
||||
color: "#128e80"
|
||||
boilingPoint: 444.0
|
||||
meltingPoint: 128.0
|
||||
metabolisms:
|
||||
Narcotic:
|
||||
effects:
|
||||
- !type:GenericStatusEffect
|
||||
conditions:
|
||||
- !type:ReagentThreshold
|
||||
reagent: NocturineAbductor
|
||||
min: 8
|
||||
key: ForcedSleep
|
||||
component: ForcedSleeping
|
||||
refresh: true
|
||||
type: Add
|
||||
time: 120
|
||||
|
|
|
|||
|
|
@ -17,10 +17,16 @@
|
|||
productEntity: AbductorGizmo
|
||||
|
||||
- type: abductorListing
|
||||
id: MedkitCombat
|
||||
name: abductors-ui-shop-MedkitCombat
|
||||
id: MedkitUniversal
|
||||
name: abductors-ui-shop-MedkitUniversal
|
||||
cost: 2
|
||||
productEntity: MedkitUniversalFilled
|
||||
|
||||
- type: abductorListing
|
||||
id: AbductorTeleport
|
||||
name: abductors-ui-shop-Teleporter
|
||||
cost: 1
|
||||
productEntity: MedkitCombatFilled
|
||||
productEntity: AbductorTeleport
|
||||
|
||||
- type: abductorListing
|
||||
id: WeaponAlien
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 466 B |
|
|
@ -141,6 +141,9 @@
|
|||
},
|
||||
{
|
||||
"name": "idintern-tech"
|
||||
},
|
||||
{
|
||||
"name": "abductor"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue