Мозговой Червь (#17)

* - add: Added Cortic Borer.

* - fix: Removed unnecessary imports, unused fields, variables, methods.

* - fix: Изменён принцип вселения: теперь не создаётся новый энтити с переходом разума, вместо этого хост хранит в себе контейнер для червя, в который последний и погружается

* - fix: Убрано использование устаревших методов и полей, исправлена ошибка, из-за которой при вселении в носителя уровень сахара не проверялся

* - fix: Изменено тестировочное значение добавления очков химикатов

* - fix: Borer can't speak now

* - fix: Some bug and shitcode fixes

* - fix: Some bug and shitcode fixes

* - fix: Added cooldown after releasing the humanoid's body

* - fix: fix

* - add: Added russian localization

* - add: Убрал использование метода _chatManager.ChatMessageToOne в некоторых местах, т.к. popup включает в себя вывод сообщения в чат.

* - fix: fix

* - fix: fix
This commit is contained in:
Ogunefu
2024-02-03 20:31:56 +03:00
committed by GitHub
parent 1594dff648
commit ff26505b11
39 changed files with 1630 additions and 3 deletions

View File

@@ -0,0 +1,23 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Borer;
/// <summary>
/// This is used for...
/// </summary>
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState]
public sealed partial class BorerComponent : Component
{
public string ActionInfest = "ActionInfest";
public EntityUid? ActionInfestEntity;
public string ActionStun = "ActionBorerStunVictim";
public EntityUid? ActionStunEntity;
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadOnly)]
public int Points = 0;
}

View File

@@ -0,0 +1,14 @@
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
namespace Content.Shared.Borer;
/// <summary>
/// This is used for...
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class BorerHostComponent : Component
{
//public EntityUid Borer;
public Container BorerContainer;
}

View File

@@ -0,0 +1,79 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Borer;
/// <summary>
/// This is used for...
/// </summary>
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState]
public sealed partial class InfestedBorerComponent : Component
{
[DataField("reproduceCost")]
public int ReproduceCost = 100;
[DataField("assumeControlCost")]
public int AssumeControlCost = 250;
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadOnly)]
public bool ControllingBrain = false;
public TimeSpan PointUpdateNext = TimeSpan.Zero;
public TimeSpan PointUpdateRate = TimeSpan.FromSeconds(2);
public readonly int PointUpdateValue = 1;
public string ActionBorerOut = "ActionBorerOut";
public EntityUid? ActionBorerOutEntity;
public string ActionBorerBrainSpeech = "ActionBorerBrainSpeech";
public EntityUid? ActionBorerBrainSpeechEntity;
public string ActionBorerInjectWindowOpen = "ActionBorerInjectWindowOpen";
public EntityUid? ActionBorerInjectWindowOpenEntity;
public string ActionBorerScan = "ActionBorerScan";
public EntityUid? ActionBorerScanEntity;
public string ActionBorerBrainTake = "ActionBorerBrainTake";
public EntityUid? ActionBorerBrainTakeEntity;
public string ActionBorerBrainRelease = "ActionBorerBrainRelease";
public EntityUid? ActionBorerBrainReleaseEntity;
public string ActionBorerBrainResist = "ActionBorerBrainResist";
public EntityUid? ActionBorerBrainResistEntity;
public string ActionBorerReproduce = "ActionBorerReproduce";
public EntityUid? ActionBorerReproduceEntity;
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadOnly)]
public EntityUid? Host;
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadOnly)]
public int Points = 0;
[ViewVariables(VVAccess.ReadOnly)]
public readonly Dictionary<string, int> AvailableReagents = new()
{
{ "Epinephrine", 30 },
{ "Bicaridine", 30 },
{ "Kelotane", 30 },
{ "Dylovene", 30 },
{ "Dexalin", 30 },
{ "SpaceDrugs", 75 },
{ "Leporazine", 75 }
};
}

View File

@@ -0,0 +1,10 @@
using Content.Shared.DoAfter;
using Robust.Shared.Serialization;
namespace Content.Shared.Borer;
[Serializable, NetSerializable]
public sealed partial class BorerBrainResistAfterEvent : SimpleDoAfterEvent
{
}

View File

@@ -0,0 +1,10 @@
using Content.Shared.DoAfter;
using Robust.Shared.Serialization;
namespace Content.Shared.Borer;
[Serializable, NetSerializable]
public sealed partial class BorerBrainTakeAfterEvent : SimpleDoAfterEvent
{
}

View File

@@ -0,0 +1,10 @@
using Content.Shared.DoAfter;
using Robust.Shared.Serialization;
namespace Content.Shared.Borer;
[Serializable, NetSerializable]
public sealed partial class BorerInfestDoAfterEvent : SimpleDoAfterEvent
{
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Borer;
[Serializable, NetSerializable]
public sealed partial class BorerOverlayResponceEvent : EntityEventArgs
{
}

View File

@@ -0,0 +1,10 @@
using Content.Shared.DoAfter;
using Robust.Shared.Serialization;
namespace Content.Shared.Borer;
[Serializable, NetSerializable]
public sealed partial class BorerReproduceAfterEvent : SimpleDoAfterEvent
{
}

View File

@@ -0,0 +1,16 @@
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
using Robust.Shared.Serialization;
namespace Content.Shared.Borer;
[Serializable, NetSerializable]
public sealed partial class BorerScanDoAfterEvent : EntityEventArgs
{
public Dictionary<string, FixedPoint2> Solution;
public BorerScanDoAfterEvent(Dictionary<string, FixedPoint2> solution)
{
Solution = solution;
}
}

View File

@@ -0,0 +1,176 @@
using Content.Shared.Actions;
using Content.Shared.Alert;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Mind;
using Robust.Shared.Serialization;
namespace Content.Shared.Borer;
/// <summary>
/// This handles...
/// </summary>
public sealed class SharedBorerSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _action = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<BorerComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<BorerComponent, ComponentRemove>(OnRemove);
SubscribeLocalEvent<InfestedBorerComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<InfestedBorerComponent, ComponentRemove>(OnRemove);
SubscribeLocalEvent<InfestedBorerComponent, ExamineAttemptEvent>(OnExamineAttempt);
SubscribeLocalEvent<BorerComponent, ExamineAttemptEvent>(OnExamineAttempt);
SubscribeLocalEvent<InfestedBorerComponent, BorerBrainResistEvent>(OnResistControl);
}
private void OnRemove(EntityUid uid, InfestedBorerComponent component, ComponentRemove args)
{
if (!TryComp(uid, out ActionsComponent? borerActComponent))
return;
_action.RemoveAction(uid, component.ActionBorerOutEntity, borerActComponent);
_action.RemoveAction(uid, component.ActionBorerScanEntity, borerActComponent);
_action.RemoveAction(uid, component.ActionBorerBrainTakeEntity, borerActComponent);
_action.RemoveAction(uid, component.ActionBorerBrainSpeechEntity, borerActComponent);
_action.RemoveAction(uid, component.ActionBorerInjectWindowOpenEntity, borerActComponent);
}
private void OnRemove(EntityUid uid, BorerComponent component, ComponentRemove args)
{
if (!TryComp(uid, out ActionsComponent? borerActComponent))
return;
_action.RemoveAction(uid, component.ActionInfestEntity, borerActComponent);
_action.RemoveAction(uid, component.ActionStunEntity, borerActComponent);
}
private void OnResistControl(EntityUid uid, InfestedBorerComponent component, BorerBrainResistEvent args)
{
args.Handled = true;
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager,
uid,
TimeSpan.FromSeconds(30),
new BorerBrainResistAfterEvent(), uid)
{
Hidden = true
});
}
private void OnStartup(EntityUid uid, BorerComponent component, ComponentStartup args)
{
if (!TryComp(uid, out ActionsComponent? comp))
return;
_action.AddAction(uid, ref component.ActionInfestEntity, component.ActionInfest, component: comp);
_action.AddAction(uid, ref component.ActionStunEntity, component.ActionStun, component: comp);
_metaData.SetEntityName(uid, Loc.GetString("borer-entity-name"));
_metaData.SetEntityDescription(uid, Loc.GetString("borer-entity-description"));
RaiseNetworkEvent(new BorerOverlayResponceEvent());
}
private void OnStartup(EntityUid uid, InfestedBorerComponent component, ComponentStartup args)
{
AddInfestedAbilities(uid, component);
}
private void OnExamineAttempt(EntityUid uid, InfestedBorerComponent component, ExamineAttemptEvent args)
{
args.Cancel();
}
private void OnExamineAttempt(EntityUid uid, BorerComponent component, ExamineAttemptEvent args)
{
args.Cancel();
}
public void RaiseInjectEvent(string protoId, int cost)
{
RaiseNetworkEvent(new BorerInjectActionEvent(protoId, cost));
}
public Dictionary<string, int> GetReagents(EntityUid borerUid)
{
if (TryComp(borerUid, out InfestedBorerComponent? infestedComp))
return infestedComp.AvailableReagents;
else
return new();
}
public bool AddInfestedAbilities(EntityUid uid, InfestedBorerComponent component)
{
if (!TryComp(uid, out ActionsComponent? comp))
return false;
_action.AddAction(uid, ref component.ActionBorerOutEntity, component.ActionBorerOut, component: comp);
_action.AddAction(uid, ref component.ActionBorerBrainSpeechEntity, component.ActionBorerBrainSpeech, component: comp);
_action.AddAction(uid, ref component.ActionBorerInjectWindowOpenEntity, component.ActionBorerInjectWindowOpen, component: comp);
_action.AddAction(uid, ref component.ActionBorerScanEntity, component.ActionBorerScan, component: comp);
_action.AddAction(uid, ref component.ActionBorerBrainTakeEntity, component.ActionBorerBrainTake, component: comp);
if (component.ActionBorerBrainTakeEntity.HasValue)
{
_metaData.SetEntityName(component.ActionBorerBrainTakeEntity.Value,
$"{Loc.GetString("borer-abilities-control-name")} ([color=red]{component.AssumeControlCost}c[/color])");
}
return true;
}
public int GetPoints(EntityUid borerUid)
{
if (TryComp(borerUid, out InfestedBorerComponent? infestedComp))
return infestedComp.Points;
else return 0;
}
public EntityUid? GetHost(EntityUid borerUid)
{
if (TryComp(borerUid, out InfestedBorerComponent? infestedComp))
return infestedComp.Host;
else
return null;
}
}
public sealed partial class BorerInfestActionEvent : EntityTargetActionEvent {}
public sealed partial class BorerOutActionEvent : InstantActionEvent {}
public sealed partial class BorerBrainSpeechActionEvent : InstantActionEvent {}
public sealed partial class BorerInjectWindowOpenEvent : InstantActionEvent{}
public sealed partial class BorerBrainTakeEvent : InstantActionEvent{}
public sealed partial class BorerBrainReleaseEvent : InstantActionEvent{}
public sealed partial class BorerBrainResistEvent : InstantActionEvent{}
public sealed partial class BorerStunActionEvent : EntityTargetActionEvent{}
public sealed partial class BorerReproduceEvent : InstantActionEvent { }
[Serializable, NetSerializable]
public sealed partial class BorerPointsUpdateEvent : EntityEventArgs{}
[Serializable, NetSerializable]
public sealed partial class BorerInjectActionEvent : EntityEventArgs
{
public string ProtoId;
public int Cost;
public BorerInjectActionEvent(string protoId, int cost)
{
ProtoId = protoId;
Cost = cost;
}
}
public sealed partial class BorerScanInstantActionEvent : InstantActionEvent
{
}