Skip to content

Commit

Permalink
[X]
Browse files Browse the repository at this point in the history
  • Loading branch information
NameLunar committed Dec 26, 2024
1 parent f8788fd commit 838281b
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 80 deletions.
66 changes: 0 additions & 66 deletions Content.Server/ADT/Abilities/XenoQeen/XenoQeenSystem.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.Abilities.XenoQeen
namespace Content.Server.Abilities.XenoQueen
{
/// <summary>
/// Lets its owner entity use mime powers, like placing invisible walls.
/// </summary>
[RegisterComponent]
public sealed partial class XenoQeenComponent : Component
public sealed partial class XenoQueenComponent : Component
{
/// <summary>
/// Whether this component is active or not.
Expand All @@ -25,5 +25,27 @@ public sealed partial class XenoQeenComponent : Component
public string? XenoTurretAction = "ActionXenoQeenTurret";

[DataField("xenoTurretActionEntity")] public EntityUid? XenoTurretActionEntity;

// Призывы
[DataField]
public EntityUid? ActionSpawnXenoBurrower;

[DataField]
public EntityUid? ActionSpawnXenoDrone;

[DataField]
public EntityUid? ActionSpawnXenoRunner;

[DataField]
public EntityUid? ActionSpawnXenoSpitter;

[DataField]
public EntityUid? ActionSpawnXenoPraetorian;

[DataField]
public EntityUid? ActionSpawnXenoRavager;

[DataField]
public EntityUid? ActionSpawnXenoQueen;
}
}
143 changes: 143 additions & 0 deletions Content.Server/ADT/Abilities/XenoQueen/XenoQueenSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using Content.Server.Popups;
using Content.Shared.Actions;
using Content.Shared.Actions.Events;
using Content.Shared.Maps;
using Content.Shared.Coordinates.Helpers;
using Content.Shared.Magic.Events;
using Content.Shared.Physics;
using Robust.Shared.Containers;
using Robust.Shared.Spawners;
using Robust.Shared.Map;
using Robust.Shared.Random;
using System.Numerics;
using Content.Shared.Storage;
using Robust.Shared.Network;
using Content.Shared.Magic;

namespace Content.Server.Abilities.XenoQueen
{
public sealed class XenoQueenSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly TurfSystem _turf = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly IMapManager _mapMan = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<XenoQueenComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<XenoQueenComponent, InvisibleWallActionEvent>(OnCreateTurret);
SubscribeLocalEvent<SpawnXenoQueenEvent> (OnWorldSpawn);
}

public override void Update(float frameTime)
{
base.Update(frameTime);
}
private void OnComponentInit(EntityUid uid, XenoQueenComponent component, ComponentInit args)
{
_actionsSystem.AddAction(uid, ref component.XenoTurretActionEntity, component.XenoTurretAction, uid);
_actionsSystem.AddAction(uid, ref component.ActionSpawnXenoBurrower, "ActionSpawnMobXenoBurrower");
_actionsSystem.AddAction(uid, ref component.ActionSpawnXenoDrone, "ActionSpawnMobXenoDrone");
_actionsSystem.AddAction(uid, ref component.ActionSpawnXenoRunner, "ActionSpawnMobXenoRunner");
_actionsSystem.AddAction(uid, ref component.ActionSpawnXenoSpitter, "ActionSpawnMobXenoSpitter");
_actionsSystem.AddAction(uid, ref component.ActionSpawnXenoPraetorian, "ActionSpawnMobXenoPraetorian");
_actionsSystem.AddAction(uid, ref component.ActionSpawnXenoRavager, "ActionSpawnMobXenoRavager");
//_actionsSystem.AddAction(uid, ref component.ActionSpawnXenoQueen, "ActionSpawnMobXenoQueen");
}
private void OnCreateTurret(EntityUid uid, XenoQueenComponent component, InvisibleWallActionEvent args)
{
if (!component.Enabled)
return;

if (_container.IsEntityOrParentInContainer(uid))
return;

var xform = Transform(uid);
// Get the tile in front of the Qeen
var offsetValue = xform.LocalRotation.ToWorldVec();
var coords = xform.Coordinates.Offset(offsetValue).SnapToGrid(EntityManager, _mapMan);
var tile = coords.GetTileRef(EntityManager, _mapMan);
if (tile == null)
return;

// Check if the tile is blocked by a wall or mob, and don't create the wall if so
if (_turf.IsTileBlocked(tile.Value, CollisionGroup.Impassable | CollisionGroup.Opaque))
{
_popupSystem.PopupEntity(Loc.GetString("create-turret-failed"), uid, uid);
return;
}

_popupSystem.PopupEntity(Loc.GetString("create-turret"), uid);
// Make sure we set the invisible wall to despawn properly
Spawn(component.XenoTurret, _turf.GetTileCenter(tile.Value));
// Handle args so cooldown works
args.Handled = true;
}
// Spawn Tipo
private void OnWorldSpawn(SpawnXenoQueenEvent args)
{
if (args.Handled || !PassesSpellPrerequisites(args.Action, args.Performer))
return;

var targetMapCoords = args.Target;

WorldSpawnSpellHelper(args.Prototypes, targetMapCoords, args.Performer, args.Lifetime, args.Offset);
Speak(args);
args.Handled = true;
}
// Help
private void WorldSpawnSpellHelper(List<EntitySpawnEntry> entityEntries, EntityCoordinates entityCoords, EntityUid performer, float? lifetime, Vector2 offsetVector2)
{
var getProtos = EntitySpawnCollection.GetSpawns(entityEntries, _random);

var offsetCoords = entityCoords;
foreach (var proto in getProtos)
{
SpawnSpellHelper(proto, offsetCoords, performer, lifetime);
offsetCoords = offsetCoords.Offset(offsetVector2);
}
}
// Help 2
private void SpawnSpellHelper(string? proto, EntityCoordinates position, EntityUid performer, float? lifetime = null, bool preventCollide = false)
{
if (!_net.IsServer)
return;

var ent = Spawn(proto, position.SnapToGrid(EntityManager, _mapManager));

if (lifetime != null)
{
var comp = EnsureComp<TimedDespawnComponent>(ent);
comp.Lifetime = lifetime.Value;
}

if (preventCollide)
{
var comp = EnsureComp<PreventCollideComponent>(ent);
comp.Uid = performer;
}
}
//
private bool PassesSpellPrerequisites(EntityUid spell, EntityUid performer)
{
var ev = new BeforeCastSpellEvent(performer);
RaiseLocalEvent(spell, ref ev);
return !ev.Cancelled;
}
//
private void Speak(BaseActionEvent args)
{
if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech))
return;

var ev = new SpeakSpellEvent(args.Performer, speak.Speech);
RaiseLocalEvent(ref ev);
}
}
}
37 changes: 37 additions & 0 deletions Content.Server/ADT/Events/SpawnXenoQueenEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Numerics;
using Content.Shared.Actions;
using Content.Shared.Storage;

namespace Content.Shared.Magic.Events;

// TODO: This class needs combining with InstantSpawnSpellEvent

public sealed partial class SpawnXenoQueenEvent : WorldTargetActionEvent, ISpeakSpell
{
/// <summary>
/// The list of prototypes this spell will spawn
/// </summary>
[DataField]
public List<EntitySpawnEntry> Prototypes = new();

// TODO: This offset is liable for deprecation.
// TODO: Target tile via code instead?
/// <summary>
/// The offset the prototypes will spawn in on relative to the one prior.
/// Set to 0,0 to have them spawn on the same tile.
/// </summary>
[DataField]
public Vector2 Offset;

/// <summary>
/// Lifetime to set for the entities to self delete
/// </summary>
[DataField]
public float? Lifetime;

[DataField]
public string? Speech { get; private set; }

[DataField]
public int? Cost { get; private set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ ent-ActionSpawnMobXenoPraetorian = Призвать Преторианеца
ent-ActionSpawnMobXenoDrone = Просто Дрон. Кому он нужен?
.desc = Родите рабочего, Дрон.
ent-ActionSpawnMobXenoRavager = Призвать Разрушителя
.desc = Родите смерть во плоти!
.desc = Родите [color=red]смерть[/color] во плоти!
ent-ActionSpawnMobXenoRunner = Призвать Бегуна
.desc = Родите самую быструю личинку!
ent-ActionSpawnMobXenoBurrower = Призвать рабочего
.desc = Стандартный ксено.
.desc = Стандартный ксено.
ent-ActionSpawnMobXenoQueen = Призвать [color=violet]Королеву[/color].
.desc = [color=red]Новое потомство! Новое поколенеи! Эволюция![/color]
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@
event: !type:InvisibleWallActionEvent
# Я не смог сделать отдельный ивент для спавнта турели. Он не видел прототип ивента.

- type: entity
id: ActionSpawnMobXenoQueen
name: Spawn Queen
description: New offspring!
categories: [ HideSpawnMenu ]
components:
- type: WorldTargetAction
useDelay: 1200
range: 4
itemIconStyle: BigAction
icon:
sprite: Mobs/Aliens/Xenos/queen.rsi
state: crit
event: !type:WorldSpawnSpellEvent
prototypes:
- id: MobXenoQueen
amount: 1
offset: 0, 1
speech: "Ааааааа! Ррррр!"

- type: entity
id: ActionSpawnMobXenoBurrower
name: Spawn Burrower
Expand All @@ -26,12 +46,13 @@
icon:
sprite: Mobs/Aliens/Xenos/burrower.rsi
state: crit
event: !type:WorldSpawnSpellEvent
event: !type:SpawnXenoQueenEvent
prototypes:
- id: MobXeno
amount: 1
offset: 0, 1
speech: "Фаьюп"
cost: 10

- type: entity
id: ActionSpawnMobXenoSpitter
Expand Down
Loading

0 comments on commit 838281b

Please sign in to comment.