Merge branch 'master' into ed-25-08-2025-upstream-sync
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client._CP14.IdentityRecognition;
|
||||
using Content.Client.Administration.Managers;
|
||||
using Content.Client.Chat;
|
||||
using Content.Client.Chat.Managers;
|
||||
@@ -820,6 +821,21 @@ public sealed partial class ChatUIController : UIController
|
||||
|
||||
public void ProcessChatMessage(ChatMessage msg, bool speechBubble = true)
|
||||
{
|
||||
//CP14 transform message on clientside
|
||||
if (_player.LocalEntity is not null && msg.SenderEntity.IsValid())
|
||||
{
|
||||
var ev = new CP14ClientTransformNameEvent(msg.SenderEntity);
|
||||
_ent.EventBus.RaiseLocalEvent(_player.LocalEntity.Value, ev);
|
||||
|
||||
if (ev.Handled)
|
||||
{
|
||||
var oldName = SharedChatSystem.GetStringInsideTag(msg, "Name");
|
||||
var newName = ev.Name;
|
||||
msg.WrappedMessage = msg.WrappedMessage.Replace($"[Name]{oldName}[/Name]", $"[Name]{newName}[/Name]");
|
||||
}
|
||||
}
|
||||
//CP14 end
|
||||
|
||||
// color the name unless it's something like "the old man"
|
||||
if ((msg.Channel == ChatChannel.Local || msg.Channel == ChatChannel.Whisper) && _chatNameColorsEnabled)
|
||||
{
|
||||
|
||||
7
Content.Client/_CP14/Actions/CP14ClientActionSystem.cs
Normal file
7
Content.Client/_CP14/Actions/CP14ClientActionSystem.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using Content.Shared._CP14.Actions;
|
||||
|
||||
namespace Content.Client._CP14.Actions;
|
||||
|
||||
public sealed partial class CP14ClientActionSystem : CP14SharedActionSystem
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Content.Shared._CP14.IdentityRecognition;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
|
||||
namespace Content.Client._CP14.IdentityRecognition;
|
||||
|
||||
public sealed partial class CP14ClientIdentityRecognitionSystem : CP14SharedIdentityRecognitionSystem
|
||||
{
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<MindContainerComponent, CP14ClientTransformNameEvent>(OnTransformSpeakerName);
|
||||
}
|
||||
|
||||
private void OnTransformSpeakerName(Entity<MindContainerComponent> ent, ref CP14ClientTransformNameEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
var mindEntity = ent.Comp.Mind;
|
||||
if (mindEntity is null)
|
||||
return;
|
||||
|
||||
TryComp<CP14RememberedNamesComponent>(mindEntity.Value, out var knownNames);
|
||||
|
||||
var speaker = GetEntity(args.Speaker);
|
||||
|
||||
if (speaker == ent.Owner)
|
||||
return;
|
||||
|
||||
if (knownNames is not null && knownNames.Names.TryGetValue(args.Speaker.Id, out var name))
|
||||
{
|
||||
args.Name = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Name = Identity.Name(speaker, EntityManager, ent);
|
||||
}
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CP14ClientTransformNameEvent(NetEntity speaker) : EntityEventArgs
|
||||
{
|
||||
public NetEntity Speaker = speaker;
|
||||
|
||||
public string Name = string.Empty;
|
||||
|
||||
public bool Handled { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using Content.Shared._CP14.IdentityRecognition;
|
||||
using Content.Shared.Labels.Components;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._CP14.IdentityRecognition;
|
||||
|
||||
public sealed class CP14IdentityRecognitionBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
[ViewVariables]
|
||||
private CP14RememberNameWindow? _window;
|
||||
|
||||
private NetEntity? _rememberedTarget;
|
||||
|
||||
public CP14IdentityRecognitionBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<CP14RememberNameWindow>();
|
||||
|
||||
if (_entManager.TryGetComponent(Owner, out HandLabelerComponent? labeler))
|
||||
{
|
||||
_window.SetMaxLabelLength(labeler!.MaxLabelChars);
|
||||
}
|
||||
|
||||
_window.OnRememberedNameChanged += OnLabelChanged;
|
||||
Reload();
|
||||
}
|
||||
|
||||
private void OnLabelChanged(string newLabel)
|
||||
{
|
||||
if (_rememberedTarget is null)
|
||||
return;
|
||||
|
||||
// Focus moment
|
||||
var currentName = CurrentName();
|
||||
|
||||
if (currentName is not null && currentName.Equals(newLabel))
|
||||
return;
|
||||
|
||||
SendPredictedMessage(new CP14RememberedNameChangedMessage(newLabel, _rememberedTarget.Value));
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
var currentName = CurrentName();
|
||||
|
||||
if (currentName is null)
|
||||
return;
|
||||
|
||||
_window.SetCurrentLabel(currentName);
|
||||
}
|
||||
|
||||
private string? CurrentName()
|
||||
{
|
||||
if (_rememberedTarget is null)
|
||||
return null;
|
||||
if (!_entManager.TryGetComponent<MindContainerComponent>(_player.LocalEntity, out var mindContainer))
|
||||
return null;
|
||||
if (!_entManager.TryGetComponent<CP14RememberedNamesComponent>(mindContainer.Mind, out var knownNames))
|
||||
return null;
|
||||
|
||||
var netId = _rememberedTarget.Value.Id;
|
||||
return knownNames.Names.GetValueOrDefault(netId);
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case CP14RememberNameUiState rememberNameUiState:
|
||||
_rememberedTarget = rememberNameUiState.Target;
|
||||
|
||||
var currentName = CurrentName();
|
||||
if (currentName is not null)
|
||||
_window.SetCurrentLabel(currentName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="{Loc 'cp14-remember-name-verb'}">
|
||||
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="180">
|
||||
<Label Name="CurrentTextLabel" Text="{Loc 'cp14-remember-name-name'}" />
|
||||
<LineEdit Name="LabelLineEdit" />
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
@@ -0,0 +1,61 @@
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._CP14.IdentityRecognition;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14RememberNameWindow : DefaultWindow
|
||||
{
|
||||
public event Action<string>? OnRememberedNameChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Is the user currently entering text into the control?
|
||||
/// </summary>
|
||||
private bool _focused;
|
||||
// TODO LineEdit Make this a bool on the LineEdit control
|
||||
|
||||
private string _label = string.Empty;
|
||||
|
||||
public CP14RememberNameWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
LabelLineEdit.OnTextChanged += e =>
|
||||
{
|
||||
_label = e.Text;
|
||||
OnRememberedNameChanged?.Invoke(_label);
|
||||
};
|
||||
|
||||
LabelLineEdit.OnFocusEnter += _ => _focused = true;
|
||||
LabelLineEdit.OnFocusExit += _ =>
|
||||
{
|
||||
_focused = false;
|
||||
LabelLineEdit.Text = _label;
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Opened()
|
||||
{
|
||||
base.Opened();
|
||||
|
||||
// Give the editor keyboard focus, since that's the only
|
||||
// thing the user will want to be doing with this UI
|
||||
LabelLineEdit.GrabKeyboardFocus();
|
||||
}
|
||||
|
||||
public void SetCurrentLabel(string label)
|
||||
{
|
||||
if (label == _label)
|
||||
return;
|
||||
|
||||
_label = label;
|
||||
if (!_focused)
|
||||
LabelLineEdit.Text = label;
|
||||
}
|
||||
|
||||
public void SetMaxLabelLength(int maxLength)
|
||||
{
|
||||
LabelLineEdit.IsValid = s => s.Length <= maxLength;
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,4 @@ using Content.Shared._CP14.MagicEnergy;
|
||||
|
||||
namespace Content.Client._CP14.MagicEnergy;
|
||||
|
||||
public sealed class CP14MagicEnergySystem : SharedCP14MagicEnergySystem;
|
||||
public sealed class CP14MagicEnergySystem : CP14SharedMagicEnergySystem;
|
||||
|
||||
@@ -284,7 +284,7 @@ namespace Content.Server.GameTicking
|
||||
var jobName = _jobs.MindTryGetJobName(newMind);
|
||||
_admin.UpdatePlayerList(player);
|
||||
|
||||
if (lateJoin && !silent)
|
||||
if (lateJoin && !silent && false) //CP14 disable arrival snnouncement
|
||||
{
|
||||
if (jobPrototype.JoinNotifyCrew)
|
||||
{
|
||||
@@ -301,7 +301,7 @@ namespace Content.Server.GameTicking
|
||||
else
|
||||
{
|
||||
_chatSystem.DispatchStationAnnouncement(station,
|
||||
Loc.GetString("cp14-latejoin-arrival-announcement",//CrystallEdge
|
||||
Loc.GetString("latejoin-arrival-announcement",
|
||||
("character", MetaData(mob).EntityName),
|
||||
("gender", character.Gender), // CrystallEdge-LastnameGender
|
||||
("entity", mob),
|
||||
|
||||
@@ -90,6 +90,16 @@ public sealed class IdentitySystem : SharedIdentitySystem
|
||||
var representation = GetIdentityRepresentation(uid);
|
||||
var name = GetIdentityName(uid, representation);
|
||||
|
||||
//CP14 override character name
|
||||
if (TryComp<HumanoidAppearanceComponent>(uid, out var humanoid))
|
||||
{
|
||||
var species = _humanoid.GetSpeciesRepresentation(humanoid.Species).ToLower();
|
||||
var age = _humanoid.GetAgeRepresentation(humanoid.Species, humanoid.Age);
|
||||
|
||||
name = age + " " + species;
|
||||
}
|
||||
//CP14 end
|
||||
|
||||
// Clone the old entity's grammar to the identity entity, for loc purposes.
|
||||
if (TryComp<GrammarComponent>(uid, out var grammar))
|
||||
{
|
||||
|
||||
43
Content.Server/_CP14/Actions/CP14ActionSystem.cs
Normal file
43
Content.Server/_CP14/Actions/CP14ActionSystem.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Content.Server.Instruments;
|
||||
using Content.Shared._CP14.Actions;
|
||||
using Content.Shared._CP14.Actions.Components;
|
||||
using Content.Shared.Actions.Events;
|
||||
using Content.Shared.Instruments;
|
||||
|
||||
namespace Content.Server._CP14.Actions;
|
||||
|
||||
public sealed partial class CP14ActionSystem : CP14SharedActionSystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14ActionRequiredMusicToolComponent, ActionAttemptEvent>(OnActionMusicAttempt);
|
||||
}
|
||||
|
||||
private void OnActionMusicAttempt(Entity<CP14ActionRequiredMusicToolComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
var passed = false;
|
||||
var query = EntityQueryEnumerator<ActiveInstrumentComponent, InstrumentComponent>();
|
||||
while (query.MoveNext(out var uid, out var active, out var instrument))
|
||||
{
|
||||
if (!instrument.Playing)
|
||||
continue;
|
||||
|
||||
if (Transform(uid).ParentUid != args.User)
|
||||
continue;
|
||||
|
||||
passed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (passed)
|
||||
return;
|
||||
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-music-aspect"), args.User, args.User);
|
||||
args.Cancelled = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
using Content.Shared._CP14.IdentityRecognition;
|
||||
|
||||
namespace Content.Server._CP14.IdentityRecognition;
|
||||
|
||||
public sealed class CP14IdentityRecognitionSystem : CP14SharedIdentityRecognitionSystem
|
||||
{
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._CP14.MagicEnergy;
|
||||
|
||||
public sealed partial class CP14MagicEnergySystem : SharedCP14MagicEnergySystem
|
||||
public sealed partial class CP14MagicEnergySystem : CP14SharedMagicEnergySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly CP14MagicEnergyCrystalSlotSystem _magicSlot = default!;
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Server._CP14.MagicEnergy;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Instruments;
|
||||
using Content.Shared._CP14.Actions.Components;
|
||||
using Content.Shared._CP14.MagicEnergy.Components;
|
||||
using Content.Shared._CP14.MagicSpell;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
@@ -40,12 +41,10 @@ public sealed class CP14MagicSystem : CP14SharedMagicSystem
|
||||
SubscribeLocalEvent<CP14SpellEffectOnHitComponent, ThrowDoHitEvent>(OnProjectileHit);
|
||||
SubscribeLocalEvent<CP14SpellEffectOnCollideComponent, StartCollideEvent>(OnStartCollide);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectVerbalAspectComponent, CP14SpellSpeechEvent>(OnSpellSpoken);
|
||||
SubscribeLocalEvent<CP14ActionSpeakingComponent, CP14ActionSpeechEvent>(OnSpellSpoken);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectCastingVisualComponent, CP14StartCastMagicEffectEvent>(OnSpawnMagicVisualEffect);
|
||||
SubscribeLocalEvent<CP14MagicEffectCastingVisualComponent, CP14EndCastMagicEffectEvent>(OnDespawnMagicVisualEffect);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectRequiredMusicToolComponent, CP14CastMagicEffectAttemptEvent>(OnMusicCheck);
|
||||
}
|
||||
|
||||
private void OnStartCollide(Entity<CP14SpellEffectOnCollideComponent> ent, ref StartCollideEvent args)
|
||||
@@ -121,7 +120,7 @@ public sealed class CP14MagicSystem : CP14SharedMagicSystem
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSpellSpoken(Entity<CP14MagicEffectVerbalAspectComponent> ent, ref CP14SpellSpeechEvent args)
|
||||
private void OnSpellSpoken(Entity<CP14ActionSpeakingComponent> ent, ref CP14ActionSpeechEvent args)
|
||||
{
|
||||
if (args.Performer is not null && args.Speech is not null)
|
||||
_chat.TrySendInGameICMessage(args.Performer.Value, args.Speech, args.Emote ? InGameICChatType.Emote : InGameICChatType.Speak, true);
|
||||
@@ -139,27 +138,4 @@ public sealed class CP14MagicSystem : CP14SharedMagicSystem
|
||||
QueueDel(ent.Comp.SpawnedEntity);
|
||||
ent.Comp.SpawnedEntity = null;
|
||||
}
|
||||
|
||||
private void OnMusicCheck(Entity<CP14MagicEffectRequiredMusicToolComponent> ent, ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
var passed = false;
|
||||
var query = EntityQueryEnumerator<ActiveInstrumentComponent, InstrumentComponent>();
|
||||
while (query.MoveNext(out var uid, out var active, out var instrument))
|
||||
{
|
||||
if (!instrument.Playing)
|
||||
continue;
|
||||
|
||||
if (Transform(uid).ParentUid != args.Performer)
|
||||
continue;
|
||||
|
||||
passed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (passed)
|
||||
return;
|
||||
|
||||
args.PushReason(Loc.GetString("cp14-magic-music-aspect"));
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,6 @@ namespace Content.Server._CP14.ModularCraft.Modifiers;
|
||||
|
||||
public sealed partial class EditManacostModify : CP14ModularCraftModifier
|
||||
{
|
||||
[DataField]
|
||||
public Dictionary<ProtoId<CP14MagicTypePrototype>, FixedPoint2> Modifiers = new();
|
||||
|
||||
[DataField]
|
||||
public FixedPoint2 GlobalModifier = 1f;
|
||||
|
||||
@@ -20,21 +17,6 @@ public sealed partial class EditManacostModify : CP14ModularCraftModifier
|
||||
if (!entManager.TryGetComponent<CP14MagicManacostModifyComponent>(start, out var manacostModifyComp))
|
||||
return;
|
||||
|
||||
foreach (var (magicType, modifier) in Modifiers)
|
||||
{
|
||||
if (manacostModifyComp.Modifiers.ContainsKey(magicType))
|
||||
{
|
||||
if (modifier >= 1f)
|
||||
manacostModifyComp.Modifiers[magicType] += modifier - 1f;
|
||||
else
|
||||
manacostModifyComp.Modifiers[magicType] -= 1f - modifier;
|
||||
}
|
||||
else
|
||||
{
|
||||
manacostModifyComp.Modifiers[magicType] = modifier;
|
||||
}
|
||||
}
|
||||
|
||||
manacostModifyComp.GlobalModifier += GlobalModifier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Server;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
@@ -10,7 +9,6 @@ public sealed partial class CP14RoundEndSystem
|
||||
{
|
||||
[Dependency] private readonly IConsoleHost _consoleHost = default!;
|
||||
[Dependency] private readonly GameTicker _ticker = default!;
|
||||
[Dependency] private readonly IBaseServer _baseServer = default!;
|
||||
|
||||
private TimeSpan _nextUpdateTime = TimeSpan.Zero;
|
||||
private readonly TimeSpan _updateFrequency = TimeSpan.FromSeconds(60f);
|
||||
@@ -114,7 +112,7 @@ public sealed partial class CP14RoundEndSystem
|
||||
{
|
||||
var ruDays = now.DayOfWeek is DayOfWeek.Tuesday || now.DayOfWeek is DayOfWeek.Thursday || now.DayOfWeek is DayOfWeek.Saturday;
|
||||
|
||||
var timeMap = new (int Hour, int Minute, Action Action)[]
|
||||
var timeMap = new (int Hour, int Minute, System.Action Action)[]
|
||||
{
|
||||
(21, 45, () =>
|
||||
{
|
||||
|
||||
@@ -135,19 +135,16 @@ public sealed class CP14RoundLeaveSystem : EntitySystem
|
||||
_stationRecords.RemoveRecord(key, stationRecords);
|
||||
}
|
||||
|
||||
_chatSystem.DispatchStationAnnouncement(station.Value,
|
||||
Loc.GetString(
|
||||
_mobState.IsAlive(uid) ? "cp14-earlyleave-ship-announcement" : "cp14-earlyleave-ship-announcement-dead",
|
||||
("character", name),
|
||||
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(jobName))
|
||||
),
|
||||
Loc.GetString("cp14-ship-sender"),
|
||||
playDefaultSound: false
|
||||
);
|
||||
//_chatSystem.DispatchStationAnnouncement(station.Value,
|
||||
// Loc.GetString(
|
||||
// _mobState.IsAlive(uid) ? "cp14-earlyleave-ship-announcement" : "cp14-earlyleave-ship-announcement-dead",
|
||||
// ("character", name),
|
||||
// ("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(jobName))
|
||||
// ),
|
||||
// Loc.GetString("cp14-ship-sender"),
|
||||
// playDefaultSound: false
|
||||
//);
|
||||
|
||||
QueueDel(uid);
|
||||
|
||||
//if (mind is not null && mind.Value.Comp.Session is not null)
|
||||
// _gameTicker.Respawn(mind.Value.Comp.Session);
|
||||
}
|
||||
}
|
||||
|
||||
280
Content.Shared/_CP14/Actions/CP14ActionSystem.Attempt.cs
Normal file
280
Content.Shared/_CP14/Actions/CP14ActionSystem.Attempt.cs
Normal file
@@ -0,0 +1,280 @@
|
||||
using System.Linq;
|
||||
using Content.Shared._CP14.Actions.Components;
|
||||
using Content.Shared._CP14.MagicEnergy;
|
||||
using Content.Shared._CP14.MagicEnergy.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared.Actions.Events;
|
||||
using Content.Shared.CombatMode.Pacification;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Speech.Muting;
|
||||
using Content.Shared.SSDIndicator;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared._CP14.Actions;
|
||||
|
||||
public abstract partial class CP14SharedActionSystem
|
||||
{
|
||||
[Dependency] private readonly SharedHandsSystem _hand = default!;
|
||||
[Dependency] private readonly CP14SharedMagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly CP14SharedReligionGodSystem _god = default!;
|
||||
private void InitializeAttempts()
|
||||
{
|
||||
SubscribeLocalEvent<CP14ActionFreeHandsRequiredComponent, ActionAttemptEvent>(OnSomaticActionAttempt);
|
||||
SubscribeLocalEvent<CP14ActionSpeakingComponent, ActionAttemptEvent>(OnVerbalActionAttempt);
|
||||
SubscribeLocalEvent<CP14ActionMaterialCostComponent, ActionAttemptEvent>(OnMaterialActionAttempt);
|
||||
SubscribeLocalEvent<CP14ActionManaCostComponent, ActionAttemptEvent>(OnManacostActionAttempt);
|
||||
SubscribeLocalEvent<CP14ActionStaminaCostComponent, ActionAttemptEvent>(OnStaminaCostActionAttempt);
|
||||
SubscribeLocalEvent<CP14ActionDangerousComponent, ActionAttemptEvent>(OnDangerousActionAttempt);
|
||||
SubscribeLocalEvent<CP14ActionSkillPointCostComponent, ActionAttemptEvent>(OnSkillPointActionAttempt);
|
||||
|
||||
SubscribeLocalEvent<CP14ActionSSDBlockComponent, ActionValidateEvent>(OnActionSSDAttempt);
|
||||
SubscribeLocalEvent<CP14ActionTargetMobStatusRequiredComponent, ActionValidateEvent>(OnTargetMobStatusRequiredValidate);
|
||||
SubscribeLocalEvent<CP14ActionReligionRestrictedComponent, ActionValidateEvent>(OnReligionActionValidate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Before using a spell, a mana check is made for the amount of mana to show warnings.
|
||||
/// </summary>
|
||||
private void OnManacostActionAttempt(Entity<CP14ActionManaCostComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
TryComp<CP14MagicEffectComponent>(ent, out var magicEffect);
|
||||
|
||||
//Total man required
|
||||
var requiredMana = ent.Comp.ManaCost;
|
||||
|
||||
if (ent.Comp.CanModifyManacost)
|
||||
{
|
||||
var manaEv = new CP14CalculateManacostEvent(args.User, ent.Comp.ManaCost);
|
||||
|
||||
RaiseLocalEvent(args.User, manaEv);
|
||||
|
||||
if (magicEffect?.SpellStorage is not null)
|
||||
RaiseLocalEvent(magicEffect.SpellStorage.Value, manaEv);
|
||||
|
||||
requiredMana = manaEv.GetManacost();
|
||||
}
|
||||
|
||||
//First - trying get mana from item
|
||||
if (magicEffect is not null && magicEffect.SpellStorage is not null &&
|
||||
TryComp<CP14MagicEnergyContainerComponent>(magicEffect.SpellStorage, out var magicContainer))
|
||||
requiredMana = MathF.Max(0, (float)(requiredMana - magicContainer.Energy));
|
||||
|
||||
if (requiredMana <= 0)
|
||||
return;
|
||||
|
||||
//Second - trying get mana from performer
|
||||
if (!TryComp<CP14MagicEnergyContainerComponent>(args.User, out var playerMana))
|
||||
{
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-no-mana-component"), args.User, args.User);
|
||||
args.Cancelled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_magicEnergy.HasEnergy(args.User, requiredMana, playerMana, true) && _timing.IsFirstTimePredicted)
|
||||
Popup.PopupClient(Loc.GetString($"cp14-magic-spell-not-enough-mana-cast-warning-{_random.Next(5)}"),
|
||||
args.User,
|
||||
args.User,
|
||||
PopupType.SmallCaution);
|
||||
}
|
||||
|
||||
private void OnStaminaCostActionAttempt(Entity<CP14ActionStaminaCostComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (!TryComp<StaminaComponent>(args.User, out var staminaComp))
|
||||
return;
|
||||
|
||||
if (!staminaComp.Critical)
|
||||
return;
|
||||
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-stamina-not-enough"), args.User, args.User);
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnSomaticActionAttempt(Entity<CP14ActionFreeHandsRequiredComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
if (TryComp<HandsComponent>(args.User, out var hands))
|
||||
{
|
||||
if (_hand.CountFreeHands((args.User, hands)) >= ent.Comp.FreeHandRequired)
|
||||
return;
|
||||
}
|
||||
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-need-somatic-component"), args.User, args.User);
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnVerbalActionAttempt(Entity<CP14ActionSpeakingComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (!HasComp<MutedComponent>(args.User))
|
||||
return;
|
||||
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-need-verbal-component"), args.User, args.User);
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnMaterialActionAttempt(Entity<CP14ActionMaterialCostComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
if (ent.Comp.Requirement is null)
|
||||
return;
|
||||
|
||||
HashSet<EntityUid> heldedItems = new();
|
||||
|
||||
foreach (var hand in _hand.EnumerateHands(args.User))
|
||||
{
|
||||
var helded = _hand.GetHeldItem(args.User, hand);
|
||||
if (helded is not null)
|
||||
heldedItems.Add(helded.Value);
|
||||
}
|
||||
|
||||
if (!ent.Comp.Requirement.CheckRequirement(EntityManager, _proto, heldedItems))
|
||||
{
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-need-material-component"), args.User, args.User);
|
||||
args.Cancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDangerousActionAttempt(Entity<CP14ActionDangerousComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
if (HasComp<PacifiedComponent>(args.User))
|
||||
{
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-pacified"), args.User, args.User);
|
||||
args.Cancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSkillPointActionAttempt(Entity<CP14ActionSkillPointCostComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (!_proto.TryIndex(ent.Comp.SkillPoint, out var indexedSkillPoint) || ent.Comp.SkillPoint is null)
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14SkillStorageComponent>(args.User, out var skillStorage))
|
||||
{
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-skillpoint-not-enough",
|
||||
("name", Loc.GetString(indexedSkillPoint.Name)),
|
||||
("count", ent.Comp.Count)),
|
||||
args.User,
|
||||
args.User);
|
||||
args.Cancelled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var points = skillStorage.SkillPoints;
|
||||
if (points.TryGetValue(ent.Comp.SkillPoint.Value, out var currentPoints))
|
||||
{
|
||||
var freePoints = currentPoints.Max - currentPoints.Sum;
|
||||
|
||||
if (freePoints < ent.Comp.Count)
|
||||
{
|
||||
var d = ent.Comp.Count - freePoints;
|
||||
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-skillpoint-not-enough",
|
||||
("name", Loc.GetString(indexedSkillPoint.Name)),
|
||||
("count", d)),
|
||||
args.User,
|
||||
args.User);
|
||||
args.Cancelled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTargetMobStatusRequiredValidate(Entity<CP14ActionTargetMobStatusRequiredComponent> ent,
|
||||
ref ActionValidateEvent args)
|
||||
{
|
||||
if (args.Invalid)
|
||||
return;
|
||||
|
||||
var target = GetEntity(args.Input.EntityTarget);
|
||||
|
||||
if (!TryComp<MobStateComponent>(target, out var mobStateComp))
|
||||
{
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-target-not-mob"), args.User, args.User);
|
||||
args.Invalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ent.Comp.AllowedStates.Contains(mobStateComp.CurrentState))
|
||||
{
|
||||
var states = string.Join(", ",
|
||||
ent.Comp.AllowedStates.Select(state => state switch
|
||||
{
|
||||
MobState.Alive => Loc.GetString("cp14-magic-spell-target-mob-state-live"),
|
||||
MobState.Dead => Loc.GetString("cp14-magic-spell-target-mob-state-dead"),
|
||||
MobState.Critical => Loc.GetString("cp14-magic-spell-target-mob-state-critical")
|
||||
}));
|
||||
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-target-mob-state", ("state", states)),
|
||||
args.User,
|
||||
args.User);
|
||||
args.Invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnActionSSDAttempt(Entity<CP14ActionSSDBlockComponent> ent, ref ActionValidateEvent args)
|
||||
{
|
||||
if (args.Invalid)
|
||||
return;
|
||||
|
||||
if (!TryComp<SSDIndicatorComponent>(GetEntity(args.Input.EntityTarget), out var ssdIndication))
|
||||
return;
|
||||
|
||||
if (ssdIndication.IsSSD)
|
||||
{
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-ssd"), args.User, args.User);
|
||||
args.Invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReligionActionValidate(Entity<CP14ActionReligionRestrictedComponent> ent, ref ActionValidateEvent args)
|
||||
{
|
||||
if (args.Invalid)
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14ReligionEntityComponent>(args.User, out var religionComp))
|
||||
return;
|
||||
|
||||
var position = GetCoordinates(args.Input.EntityCoordinatesTarget);
|
||||
var target = GetEntity(args.Input.EntityTarget);
|
||||
|
||||
if (target is not null)
|
||||
position ??= Transform(target.Value).Coordinates;
|
||||
|
||||
if (ent.Comp.OnlyInReligionZone)
|
||||
{
|
||||
if (position is null || !_god.InVision(position.Value, (args.User, religionComp)))
|
||||
{
|
||||
args.Invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ent.Comp.OnlyOnFollowers)
|
||||
{
|
||||
if (target is null || !TryComp<CP14ReligionFollowerComponent>(target, out var follower) || follower.Religion != religionComp.Religion)
|
||||
{
|
||||
Popup.PopupClient(Loc.GetString("cp14-magic-spell-target-god-follower"), args.User, args.User);
|
||||
args.Invalid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Content.Shared/_CP14/Actions/CP14ActionSystem.Examine.cs
Normal file
74
Content.Shared/_CP14/Actions/CP14ActionSystem.Examine.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System.Linq;
|
||||
using Content.Shared._CP14.Actions.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Mobs;
|
||||
|
||||
namespace Content.Shared._CP14.Actions;
|
||||
|
||||
public abstract partial class CP14SharedActionSystem
|
||||
{
|
||||
private void InitializeExamine()
|
||||
{
|
||||
SubscribeLocalEvent<CP14ActionManaCostComponent, ExaminedEvent>(OnManacostExamined);
|
||||
SubscribeLocalEvent<CP14ActionStaminaCostComponent, ExaminedEvent>(OnStaminaCostExamined);
|
||||
SubscribeLocalEvent<CP14ActionSkillPointCostComponent, ExaminedEvent>(OnSkillPointCostExamined);
|
||||
|
||||
SubscribeLocalEvent<CP14ActionSpeakingComponent, ExaminedEvent>(OnVerbalExamined);
|
||||
SubscribeLocalEvent<CP14ActionFreeHandsRequiredComponent, ExaminedEvent>(OnSomaticExamined);
|
||||
SubscribeLocalEvent<CP14ActionMaterialCostComponent, ExaminedEvent>(OnMaterialExamined);
|
||||
SubscribeLocalEvent<CP14ActionRequiredMusicToolComponent, ExaminedEvent>(OnMusicExamined);
|
||||
SubscribeLocalEvent<CP14ActionTargetMobStatusRequiredComponent, ExaminedEvent>(OnMobStateExamined);
|
||||
}
|
||||
|
||||
private void OnManacostExamined(Entity<CP14ActionManaCostComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup($"{Loc.GetString("cp14-magic-manacost")}: [color=#5da9e8]{ent.Comp.ManaCost}[/color]", priority: 9);
|
||||
}
|
||||
|
||||
private void OnStaminaCostExamined(Entity<CP14ActionStaminaCostComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup($"{Loc.GetString("cp14-magic-staminacost")}: [color=#3fba54]{ent.Comp.Stamina}[/color]", priority: 9);
|
||||
}
|
||||
|
||||
private void OnSkillPointCostExamined(Entity<CP14ActionSkillPointCostComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
if (!_proto.TryIndex(ent.Comp.SkillPoint, out var indexedSkillPoint))
|
||||
return;
|
||||
|
||||
args.PushMarkup($"{Loc.GetString("cp14-magic-skillpointcost", ("name", Loc.GetString(indexedSkillPoint.Name)), ("count", ent.Comp.Count))}", priority: 9);
|
||||
}
|
||||
|
||||
private void OnVerbalExamined(Entity<CP14ActionSpeakingComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-verbal-aspect"), 8);
|
||||
}
|
||||
|
||||
private void OnSomaticExamined(Entity<CP14ActionFreeHandsRequiredComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-somatic-aspect") + " " + ent.Comp.FreeHandRequired, 8);
|
||||
}
|
||||
|
||||
private void OnMaterialExamined(Entity<CP14ActionMaterialCostComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
if (ent.Comp.Requirement is not null)
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-material-aspect") + " " + ent.Comp.Requirement.GetRequirementTitle(_proto));
|
||||
}
|
||||
private void OnMusicExamined(Entity<CP14ActionRequiredMusicToolComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-music-aspect"));
|
||||
}
|
||||
|
||||
private void OnMobStateExamined(Entity<CP14ActionTargetMobStatusRequiredComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
var states = string.Join(", ",
|
||||
ent.Comp.AllowedStates.Select(state => state switch
|
||||
{
|
||||
MobState.Alive => Loc.GetString("cp14-magic-spell-target-mob-state-live"),
|
||||
MobState.Dead => Loc.GetString("cp14-magic-spell-target-mob-state-dead"),
|
||||
MobState.Critical => Loc.GetString("cp14-magic-spell-target-mob-state-critical")
|
||||
}));
|
||||
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-spell-target-mob-state", ("state", states)));
|
||||
}
|
||||
}
|
||||
17
Content.Shared/_CP14/Actions/CP14SharedActionSystem.cs
Normal file
17
Content.Shared/_CP14/Actions/CP14SharedActionSystem.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Actions;
|
||||
|
||||
public abstract partial class CP14SharedActionSystem : EntitySystem
|
||||
{
|
||||
[Dependency] protected readonly SharedPopupSystem Popup = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeAttempts();
|
||||
InitializeExamine();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Content.Shared._CP14.MagicSpell;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Blocks the target from using magic if they are pacified.
|
||||
/// Also block using spell on SSD player
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class CP14ActionDangerousComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -4,7 +4,7 @@ namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
/// Requires the user to have at least one free hand to use this spell
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectSomaticAspectComponent : Component
|
||||
public sealed partial class CP14ActionFreeHandsRequiredComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public int FreeHandRequired = 1;
|
||||
@@ -1,12 +1,12 @@
|
||||
using Content.Shared.FixedPoint;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Restricts the use of this action, by spending mana or user requirements.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectManaCostComponent : Component
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14ActionManaCostComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public FixedPoint2 ManaCost = 0f;
|
||||
@@ -1,12 +1,12 @@
|
||||
using Content.Shared._CP14.Workbench;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the caster to hold a specific resource in their hand, which will be spent to use the spell.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectMaterialAspectComponent : Component
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14ActionMaterialCostComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public CP14WorkbenchCraftRequirement? Requirement;
|
||||
@@ -1,10 +1,11 @@
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// If the user belongs to a religion, this spell can only be used within the area of influence of that religion
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectReligionRestrictedComponent : Component
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14ActionReligionRestrictedComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// does not allow the spell to be used outside the god's area of influence
|
||||
@@ -0,0 +1,11 @@
|
||||
using Content.Shared._CP14.MagicSpell;
|
||||
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the user to play music to use this spell
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14ActionRequiredMusicToolComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using Content.Shared._CP14.MagicSpell;
|
||||
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Blocks the user from using action against target target in SSD.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14ActionSSDBlockComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
using Content.Shared._CP14.Skill.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Restricts the use of this action, by spending user skillpoints
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectSkillPointCostComponent : Component
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class CP14ActionSkillPointCostComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ProtoId<CP14SkillPointPrototype>? SkillPoint;
|
||||
@@ -1,10 +1,10 @@
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the user to be able to speak in order to use this spell. Also forces the user to use certain phrases at the beginning and end of a spell cast
|
||||
/// Requires the user to be able to speak in order to use this action. Also forces the user to use certain phrases at the beginning and end of a action use
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectVerbalAspectComponent : Component
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14ActionSpeakingComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public string StartSpeech = string.Empty; //Not LocId!
|
||||
@@ -17,7 +17,7 @@ public sealed partial class CP14MagicEffectVerbalAspectComponent : Component
|
||||
/// patch to send an event to the server for saying a phrase out loud
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public sealed class CP14SpellSpeechEvent : EntityEventArgs
|
||||
public sealed class CP14ActionSpeechEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid? Performer { get; init; }
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared._CP14.MagicSpell;
|
||||
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Restricts the use of this action, by spending stamina.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectStaminaCostComponent : Component
|
||||
public sealed partial class CP14ActionStaminaCostComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float Stamina = 0f;
|
||||
@@ -1,13 +1,13 @@
|
||||
using Content.Shared.Mobs;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
namespace Content.Shared._CP14.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to limit the use of a spell based on the target's alive/dead status
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class CP14MagicEffectTargetMobStatusRequiredComponent : Component
|
||||
public sealed partial class CP14ActionTargetMobStatusRequiredComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public HashSet<MobState> AllowedStates = new() { MobState.Alive };
|
||||
@@ -35,7 +35,7 @@ public sealed partial class CP14ManaChange : EntityEffect
|
||||
if (args is EntityEffectReagentArgs reagentArgs)
|
||||
scale = ScaleByQuantity ? reagentArgs.Quantity * reagentArgs.Scale : reagentArgs.Scale;
|
||||
|
||||
var magicSystem = entityManager.System<SharedCP14MagicEnergySystem>();
|
||||
var magicSystem = entityManager.System<CP14SharedMagicEnergySystem>();
|
||||
magicSystem.ChangeEnergy(args.TargetEntity, ManaDelta * scale, out var changed, out var overload, safe: Safe);
|
||||
|
||||
scale -= FixedPoint2.Abs(changed + overload);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._CP14.IdentityRecognition;
|
||||
|
||||
/// <summary>
|
||||
/// Stores all the names of other characters that the player has memorized.
|
||||
/// These players will be visible to the player under that name, rather than as nameless characters.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class CP14RememberedNamesComponent : Component
|
||||
{
|
||||
//Pair of NetEntity Id and names
|
||||
[DataField, AutoNetworkedField]
|
||||
public Dictionary<int, string> Names = [];
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.IdentityManagement.Components;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.IdentityRecognition;
|
||||
|
||||
public abstract class CP14SharedIdentityRecognitionSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
[Dependency] private readonly SharedIdentitySystem _identity = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14UnknownIdentityComponent, GetVerbsEvent<Verb>>(OnUnknownIdentityVerb);
|
||||
SubscribeLocalEvent<CP14UnknownIdentityComponent, ExaminedEvent>(OnExaminedEvent);
|
||||
|
||||
SubscribeLocalEvent<MindContainerComponent, CP14RememberedNameChangedMessage>(OnRememberedNameChanged);
|
||||
|
||||
SubscribeLocalEvent<CP14RememberedNamesComponent, MapInitEvent>(OnMapInit);
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<CP14RememberedNamesComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
if (!TryComp<MindComponent>(ent, out var mind))
|
||||
return;
|
||||
|
||||
if (mind.OwnedEntity is null)
|
||||
return;
|
||||
|
||||
if (mind.CharacterName is null)
|
||||
return;
|
||||
|
||||
RememberCharacter(ent, GetNetEntity(mind.OwnedEntity.Value), mind.CharacterName);
|
||||
}
|
||||
|
||||
private void OnUnknownIdentityVerb(Entity<CP14UnknownIdentityComponent> ent, ref GetVerbsEvent<Verb> args)
|
||||
{
|
||||
if (HasComp<GhostComponent>(args.User))
|
||||
return;
|
||||
|
||||
if(!_mind.TryGetMind(args.User, out var mindId, out var mind))
|
||||
return;
|
||||
|
||||
if (!TryComp<ActorComponent>(args.User, out var actor))
|
||||
return;
|
||||
|
||||
if (args.User == ent.Owner)
|
||||
return;
|
||||
|
||||
EnsureComp<CP14RememberedNamesComponent>(mindId);
|
||||
|
||||
var seeAttemptEv = new SeeIdentityAttemptEvent();
|
||||
RaiseLocalEvent(ent.Owner, seeAttemptEv);
|
||||
|
||||
var _args = args;
|
||||
var verb = new Verb
|
||||
{
|
||||
Priority = 2,
|
||||
Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/sentient.svg.192dpi.png")),
|
||||
Text = Loc.GetString("cp14-remember-name-verb"),
|
||||
Disabled = seeAttemptEv.Cancelled,
|
||||
Act = () =>
|
||||
{
|
||||
_uiSystem.SetUiState(_args.User, CP14RememberNameUiKey.Key, new CP14RememberNameUiState(GetNetEntity(ent)));
|
||||
_uiSystem.TryToggleUi(_args.User, CP14RememberNameUiKey.Key, actor.PlayerSession);
|
||||
},
|
||||
};
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
private void OnExaminedEvent(Entity<CP14UnknownIdentityComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
var ev = new SeeIdentityAttemptEvent();
|
||||
RaiseLocalEvent(ent.Owner, ev);
|
||||
|
||||
if (ev.Cancelled)
|
||||
return;
|
||||
|
||||
if (!_mind.TryGetMind(args.Examiner, out var mindId, out var mind))
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14RememberedNamesComponent>(mindId, out var knownNames))
|
||||
return;
|
||||
|
||||
if (knownNames.Names.TryGetValue(GetNetEntity(ent).Id, out var name))
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("cp14-remember-name-examine", ("name", name)), priority: -1);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRememberedNameChanged(Entity<MindContainerComponent> ent, ref CP14RememberedNameChangedMessage args)
|
||||
{
|
||||
var mindEntity = ent.Comp.Mind;
|
||||
|
||||
if (mindEntity is null)
|
||||
return;
|
||||
|
||||
RememberCharacter(mindEntity.Value, args.Target, args.Name);
|
||||
}
|
||||
|
||||
private void RememberCharacter(EntityUid mindEntity, NetEntity targetId, string name)
|
||||
{
|
||||
var knownNames = EnsureComp<CP14RememberedNamesComponent>(mindEntity);
|
||||
|
||||
knownNames.Names[targetId.Id] = name;
|
||||
Dirty(mindEntity, knownNames);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14RememberedNameChangedMessage(string name, NetEntity target) : BoundUserInterfaceMessage
|
||||
{
|
||||
public string Name { get; } = name;
|
||||
public NetEntity Target { get; } = target;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CP14RememberNameUiKey
|
||||
{
|
||||
Key,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14RememberNameUiState(NetEntity target) : BoundUserInterfaceState
|
||||
{
|
||||
public NetEntity Target = target;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._CP14.IdentityRecognition;
|
||||
|
||||
/// <summary>
|
||||
/// defines this character's name as unknown.
|
||||
/// The name can be memorized via KnownNamesComponent,
|
||||
/// and is hidden when IdentityBlocker is enabled.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class CP14UnknownIdentityComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -9,7 +9,7 @@ using Content.Shared.Rounding;
|
||||
|
||||
namespace Content.Shared._CP14.MagicEnergy;
|
||||
|
||||
public abstract class SharedCP14MagicEnergySystem : EntitySystem
|
||||
public abstract class CP14SharedMagicEnergySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly SharedAmbientSoundSystem _ambient = default!;
|
||||
@@ -9,7 +9,7 @@ namespace Content.Shared._CP14.MagicEnergy.Components;
|
||||
/// Allows an item to store magical energy within itself.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
[Access(typeof(SharedCP14MagicEnergySystem))]
|
||||
[Access(typeof(CP14SharedMagicEnergySystem))]
|
||||
public sealed partial class CP14MagicEnergyContainerComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
|
||||
@@ -6,5 +6,5 @@ namespace Content.Shared._CP14.MagicEnergy.Components;
|
||||
/// Allows you to examine how much energy is in that object.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[Access(typeof(SharedCP14MagicEnergySystem))]
|
||||
[Access(typeof(CP14SharedMagicEnergySystem))]
|
||||
public sealed partial class CP14MagicEnergyExaminableComponent : Component;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Content.Shared._CP14.MagicEnergy.Components;
|
||||
/// <summary>
|
||||
/// Restores or expends magical energy when taking damage of certain types.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(SharedCP14MagicEnergySystem))]
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicEnergySystem))]
|
||||
public sealed partial class CP14MagicEnergyFromDamageComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Content.Shared._CP14.MagicEnergy.Components;
|
||||
/// <summary>
|
||||
/// Restores mana if the entity is in the sun, and wastes it if not
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(SharedCP14MagicEnergySystem))]
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicEnergySystem))]
|
||||
public sealed partial class CP14MagicEnergyPhotosynthesisComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
|
||||
@@ -12,7 +12,7 @@ public abstract class SharedCP14MagicEnergyCrystalSlotSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
|
||||
[Dependency] private readonly SharedCP14MagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly CP14SharedMagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Content.Shared._CP14.MagicEssence;
|
||||
/// <summary>
|
||||
/// Allows you to see how much magic essence is stored in objects
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(SharedCP14MagicEnergySystem))]
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicEnergySystem))]
|
||||
public sealed partial class CP14MagicEssenceScannerComponent : Component
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public partial class CP14MagicEssenceSystem : EntitySystem
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly INetManager _net = default!;
|
||||
[Dependency] private readonly SharedCP14MagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly CP14SharedMagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
|
||||
|
||||
@@ -10,9 +10,6 @@ namespace Content.Shared._CP14.MagicManacostModify;
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14MagicManacostModifyComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public Dictionary<ProtoId<CP14MagicTypePrototype>, FixedPoint2> Modifiers = new();
|
||||
|
||||
[DataField]
|
||||
public FixedPoint2 GlobalModifier = 1f;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public sealed partial class CP14MagicManacostModifySystem : EntitySystem
|
||||
if (!args.CanInteract || !args.CanAccess || !ent.Comp.Examinable)
|
||||
return;
|
||||
|
||||
var markup = GetManacostModifyMessage(ent.Comp.GlobalModifier, ent.Comp.Modifiers);
|
||||
var markup = GetManacostModifyMessage(ent.Comp.GlobalModifier);
|
||||
_examine.AddDetailedExamineVerb(
|
||||
args,
|
||||
ent.Comp,
|
||||
@@ -38,7 +38,7 @@ public sealed partial class CP14MagicManacostModifySystem : EntitySystem
|
||||
Loc.GetString("cp14-magic-examinable-verb-message"));
|
||||
}
|
||||
|
||||
public FormattedMessage GetManacostModifyMessage(FixedPoint2 global, Dictionary<ProtoId<CP14MagicTypePrototype>, FixedPoint2> modifiers)
|
||||
public FormattedMessage GetManacostModifyMessage(FixedPoint2 global)
|
||||
{
|
||||
var msg = new FormattedMessage();
|
||||
msg.AddMarkupOrThrow(Loc.GetString("cp14-clothing-magic-examine"));
|
||||
@@ -52,18 +52,6 @@ public sealed partial class CP14MagicManacostModifySystem : EntitySystem
|
||||
$"{Loc.GetString("cp14-clothing-magic-global")}: {plus}{MathF.Round((float)(global - 1) * 100, MidpointRounding.AwayFromZero)}%");
|
||||
}
|
||||
|
||||
foreach (var modifier in modifiers)
|
||||
{
|
||||
if (modifier.Value == 1)
|
||||
continue;
|
||||
|
||||
msg.PushNewline();
|
||||
|
||||
var plus = modifier.Value > 1 ? "+" : "";
|
||||
var indexedType = _proto.Index(modifier.Key);
|
||||
msg.AddMarkupOrThrow($"- [color={indexedType.Color.ToHex()}]{Loc.GetString(indexedType.Name)}[/color]: {plus}{(modifier.Value - 1)*100}%");
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -75,10 +63,5 @@ public sealed partial class CP14MagicManacostModifySystem : EntitySystem
|
||||
private void OnCalculateManacost(Entity<CP14MagicManacostModifyComponent> ent, ref CP14CalculateManacostEvent args)
|
||||
{
|
||||
args.Multiplier *= (float)ent.Comp.GlobalModifier;
|
||||
|
||||
if (args.MagicType is not null && ent.Comp.Modifiers.TryGetValue(args.MagicType.Value, out var modifier))
|
||||
{
|
||||
args.Multiplier *= (float)modifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
using System.Linq;
|
||||
using Content.Shared._CP14.Actions.Components;
|
||||
using Content.Shared._CP14.MagicEnergy.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Content.Shared._CP14.Religion.Components;
|
||||
using Content.Shared._CP14.Religion.Systems;
|
||||
using Content.Shared._CP14.Skill;
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared.CombatMode.Pacification;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Speech.Muting;
|
||||
using Content.Shared.SSDIndicator;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell;
|
||||
|
||||
@@ -27,237 +17,24 @@ public abstract partial class CP14SharedMagicSystem
|
||||
|
||||
private void InitializeChecks()
|
||||
{
|
||||
SubscribeLocalEvent<CP14MagicEffectSomaticAspectComponent, CP14CastMagicEffectAttemptEvent>(OnSomaticCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectVerbalAspectComponent, CP14CastMagicEffectAttemptEvent>(OnVerbalCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectMaterialAspectComponent, CP14CastMagicEffectAttemptEvent>(OnMaterialCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectManaCostComponent, CP14CastMagicEffectAttemptEvent>(OnManaCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectStaminaCostComponent, CP14CastMagicEffectAttemptEvent>(OnStaminaCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectSkillPointCostComponent, CP14CastMagicEffectAttemptEvent>(OnSkillPointCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectPacifiedBlockComponent, CP14CastMagicEffectAttemptEvent>(OnPacifiedCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectSSDBlockComponent, CP14CastMagicEffectAttemptEvent>(OnSSDCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectTargetMobStatusRequiredComponent, CP14CastMagicEffectAttemptEvent>(OnMobStateCheck);
|
||||
SubscribeLocalEvent<CP14MagicEffectReligionRestrictedComponent, CP14CastMagicEffectAttemptEvent>(OnReligionRestrictedCheck);
|
||||
|
||||
//Verbal speaking
|
||||
SubscribeLocalEvent<CP14MagicEffectVerbalAspectComponent, CP14StartCastMagicEffectEvent>(OnVerbalAspectStartCast);
|
||||
SubscribeLocalEvent<CP14MagicEffectVerbalAspectComponent, CP14MagicEffectConsumeResourceEvent>(OnVerbalAspectAfterCast);
|
||||
SubscribeLocalEvent<CP14ActionSpeakingComponent, CP14StartCastMagicEffectEvent>(OnVerbalAspectStartCast);
|
||||
SubscribeLocalEvent<CP14ActionSpeakingComponent, CP14MagicEffectConsumeResourceEvent>(OnVerbalAspectAfterCast);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectEmotingComponent, CP14StartCastMagicEffectEvent>(OnEmoteStartCast);
|
||||
SubscribeLocalEvent<CP14MagicEffectEmotingComponent, CP14MagicEffectConsumeResourceEvent>(OnEmoteEndCast);
|
||||
|
||||
//Consuming resources
|
||||
SubscribeLocalEvent<CP14MagicEffectMaterialAspectComponent, CP14MagicEffectConsumeResourceEvent>(OnMaterialAspectEndCast);
|
||||
SubscribeLocalEvent<CP14MagicEffectStaminaCostComponent, CP14MagicEffectConsumeResourceEvent>(OnStaminaConsume);
|
||||
SubscribeLocalEvent<CP14MagicEffectManaCostComponent, CP14MagicEffectConsumeResourceEvent>(OnManaConsume);
|
||||
SubscribeLocalEvent<CP14MagicEffectSkillPointCostComponent, CP14MagicEffectConsumeResourceEvent>(OnSkillPointConsume);
|
||||
SubscribeLocalEvent<CP14ActionMaterialCostComponent, CP14MagicEffectConsumeResourceEvent>(OnMaterialAspectEndCast);
|
||||
SubscribeLocalEvent<CP14ActionStaminaCostComponent, CP14MagicEffectConsumeResourceEvent>(OnStaminaConsume);
|
||||
SubscribeLocalEvent<CP14ActionManaCostComponent, CP14MagicEffectConsumeResourceEvent>(OnManaConsume);
|
||||
SubscribeLocalEvent<CP14ActionSkillPointCostComponent, CP14MagicEffectConsumeResourceEvent>(OnSkillPointConsume);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Before using a spell, a mana check is made for the amount of mana to show warnings.
|
||||
/// </summary>
|
||||
private void OnManaCheck(Entity<CP14MagicEffectManaCostComponent> ent, ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
//Total man required
|
||||
var requiredMana = CalculateManacost(ent, args.Performer);
|
||||
|
||||
//First - trying get mana from item
|
||||
if (_magicEffectQuery.TryComp(ent, out var magicEffect))
|
||||
{
|
||||
if (magicEffect.SpellStorage is not null &&
|
||||
_magicContainerQuery.TryComp(magicEffect.SpellStorage, out var magicContainer))
|
||||
requiredMana = MathF.Max(0, (float)(requiredMana - magicContainer.Energy));
|
||||
}
|
||||
|
||||
if (requiredMana <= 0)
|
||||
return;
|
||||
|
||||
//Second - trying get mana from performer
|
||||
if (!_magicContainerQuery.TryComp(args.Performer, out var playerMana))
|
||||
{
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-no-mana-component"));
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_magicEnergy.HasEnergy(args.Performer, requiredMana, playerMana, true))
|
||||
_popup.PopupEntity(Loc.GetString($"cp14-magic-spell-not-enough-mana-cast-warning-{_random.Next(5)}"),
|
||||
args.Performer,
|
||||
args.Performer,
|
||||
PopupType.SmallCaution);
|
||||
}
|
||||
|
||||
private void OnStaminaCheck(Entity<CP14MagicEffectStaminaCostComponent> ent,
|
||||
ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (!TryComp<StaminaComponent>(args.Performer, out var staminaComp))
|
||||
return;
|
||||
|
||||
if (!staminaComp.Critical)
|
||||
return;
|
||||
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-stamina-not-enough"));
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnSkillPointCheck(Entity<CP14MagicEffectSkillPointCostComponent> ent, ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (!_proto.TryIndex(ent.Comp.SkillPoint, out var indexedSkillPoint) || ent.Comp.SkillPoint is null)
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14SkillStorageComponent>(args.Performer, out var skillStorage))
|
||||
{
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-skillpoint-not-enough", ("name", Loc.GetString(indexedSkillPoint.Name)), ("count", ent.Comp.Count)));
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
var points = skillStorage.SkillPoints;
|
||||
if (points.TryGetValue(ent.Comp.SkillPoint.Value, out var currentPoints))
|
||||
{
|
||||
var freePoints = currentPoints.Max - currentPoints.Sum;
|
||||
|
||||
if (freePoints < ent.Comp.Count)
|
||||
{
|
||||
var d = ent.Comp.Count - freePoints;
|
||||
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-skillpoint-not-enough",
|
||||
("name", Loc.GetString(indexedSkillPoint.Name)),
|
||||
("count", d)));
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSomaticCheck(Entity<CP14MagicEffectSomaticAspectComponent> ent,
|
||||
ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (TryComp<HandsComponent>(args.Performer, out var hands) || hands is not null)
|
||||
{
|
||||
if (_hand.CountFreeableHands((args.Performer, hands)) >= ent.Comp.FreeHandRequired)
|
||||
return;
|
||||
}
|
||||
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-need-somatic-component"));
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnVerbalCheck(Entity<CP14MagicEffectVerbalAspectComponent> ent,
|
||||
ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (!HasComp<MutedComponent>(args.Performer))
|
||||
return;
|
||||
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-need-verbal-component"));
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnMaterialCheck(Entity<CP14MagicEffectMaterialAspectComponent> ent, ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (ent.Comp.Requirement is null)
|
||||
return;
|
||||
|
||||
HashSet<EntityUid> heldedItems = new();
|
||||
|
||||
foreach (var hand in _hand.EnumerateHands(args.Performer))
|
||||
{
|
||||
var helded = _hand.GetHeldItem(args.Performer, hand);
|
||||
if (helded is not null)
|
||||
heldedItems.Add(helded.Value);
|
||||
}
|
||||
|
||||
if (!ent.Comp.Requirement.CheckRequirement(EntityManager, _proto, heldedItems))
|
||||
{
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-need-material-component"));
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPacifiedCheck(Entity<CP14MagicEffectPacifiedBlockComponent> ent,
|
||||
ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (!HasComp<PacifiedComponent>(args.Performer))
|
||||
return;
|
||||
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-pacified"));
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnSSDCheck(Entity<CP14MagicEffectSSDBlockComponent> ent, ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (args.Target is null)
|
||||
return;
|
||||
|
||||
if (!TryComp<SSDIndicatorComponent>(args.Target.Value, out var ssdIndication))
|
||||
return;
|
||||
|
||||
if (ssdIndication.IsSSD)
|
||||
{
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-ssd"));
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMobStateCheck(Entity<CP14MagicEffectTargetMobStatusRequiredComponent> ent,
|
||||
ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (args.Target is not { } target)
|
||||
return;
|
||||
|
||||
if (!TryComp<MobStateComponent>(target, out var mobStateComp))
|
||||
{
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-target-not-mob"));
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ent.Comp.AllowedStates.Contains(mobStateComp.CurrentState))
|
||||
{
|
||||
var states = string.Join(", ",
|
||||
ent.Comp.AllowedStates.Select(state => state switch
|
||||
{
|
||||
MobState.Alive => Loc.GetString("cp14-magic-spell-target-mob-state-live"),
|
||||
MobState.Dead => Loc.GetString("cp14-magic-spell-target-mob-state-dead"),
|
||||
MobState.Critical => Loc.GetString("cp14-magic-spell-target-mob-state-critical")
|
||||
}));
|
||||
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-target-mob-state", ("state", states)));
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReligionRestrictedCheck(Entity<CP14MagicEffectReligionRestrictedComponent> ent,
|
||||
ref CP14CastMagicEffectAttemptEvent args)
|
||||
{
|
||||
if (!TryComp<CP14ReligionEntityComponent>(args.Performer, out var religionComp))
|
||||
return;
|
||||
|
||||
var position = args.Position;
|
||||
|
||||
if (args.Target is not null)
|
||||
position ??= Transform(args.Target.Value).Coordinates;
|
||||
|
||||
if (ent.Comp.OnlyInReligionZone)
|
||||
{
|
||||
if (position is null || !_god.InVision(position.Value, (args.Performer, religionComp)))
|
||||
{
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
if (ent.Comp.OnlyOnFollowers)
|
||||
{
|
||||
if (args.Target is null || !TryComp<CP14ReligionFollowerComponent>(args.Target, out var follower) || follower.Religion != religionComp.Religion)
|
||||
{
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-target-god-follower"));
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnVerbalAspectStartCast(Entity<CP14MagicEffectVerbalAspectComponent> ent,
|
||||
private void OnVerbalAspectStartCast(Entity<CP14ActionSpeakingComponent> ent,
|
||||
ref CP14StartCastMagicEffectEvent args)
|
||||
{
|
||||
var ev = new CP14SpellSpeechEvent
|
||||
var ev = new CP14ActionSpeechEvent
|
||||
{
|
||||
Performer = args.Performer,
|
||||
Speech = Loc.GetString(ent.Comp.StartSpeech),
|
||||
@@ -266,10 +43,10 @@ public abstract partial class CP14SharedMagicSystem
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
}
|
||||
|
||||
private void OnVerbalAspectAfterCast(Entity<CP14MagicEffectVerbalAspectComponent> ent,
|
||||
private void OnVerbalAspectAfterCast(Entity<CP14ActionSpeakingComponent> ent,
|
||||
ref CP14MagicEffectConsumeResourceEvent args)
|
||||
{
|
||||
var ev = new CP14SpellSpeechEvent
|
||||
var ev = new CP14ActionSpeechEvent
|
||||
{
|
||||
Performer = args.Performer,
|
||||
Speech = Loc.GetString(ent.Comp.EndSpeech),
|
||||
@@ -280,7 +57,7 @@ public abstract partial class CP14SharedMagicSystem
|
||||
|
||||
private void OnEmoteStartCast(Entity<CP14MagicEffectEmotingComponent> ent, ref CP14StartCastMagicEffectEvent args)
|
||||
{
|
||||
var ev = new CP14SpellSpeechEvent
|
||||
var ev = new CP14ActionSpeechEvent
|
||||
{
|
||||
Performer = args.Performer,
|
||||
Speech = Loc.GetString(ent.Comp.StartEmote),
|
||||
@@ -292,7 +69,7 @@ public abstract partial class CP14SharedMagicSystem
|
||||
|
||||
private void OnEmoteEndCast(Entity<CP14MagicEffectEmotingComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
{
|
||||
var ev = new CP14SpellSpeechEvent
|
||||
var ev = new CP14ActionSpeechEvent
|
||||
{
|
||||
Performer = args.Performer,
|
||||
Speech = Loc.GetString(ent.Comp.EndEmote),
|
||||
@@ -301,7 +78,7 @@ public abstract partial class CP14SharedMagicSystem
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
}
|
||||
|
||||
private void OnMaterialAspectEndCast(Entity<CP14MagicEffectMaterialAspectComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
private void OnMaterialAspectEndCast(Entity<CP14ActionMaterialCostComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
{
|
||||
if (ent.Comp.Requirement is null || args.Performer is null)
|
||||
return;
|
||||
@@ -318,7 +95,7 @@ public abstract partial class CP14SharedMagicSystem
|
||||
ent.Comp.Requirement.PostCraft(EntityManager, _proto, heldedItems);
|
||||
}
|
||||
|
||||
private void OnStaminaConsume(Entity<CP14MagicEffectStaminaCostComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
private void OnStaminaConsume(Entity<CP14ActionStaminaCostComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
{
|
||||
if (args.Performer is null)
|
||||
return;
|
||||
@@ -326,7 +103,7 @@ public abstract partial class CP14SharedMagicSystem
|
||||
_stamina.TakeStaminaDamage(args.Performer.Value, ent.Comp.Stamina, visual: false);
|
||||
}
|
||||
|
||||
private void OnManaConsume(Entity<CP14MagicEffectManaCostComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
private void OnManaConsume(Entity<CP14ActionManaCostComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
{
|
||||
if (!TryComp<CP14MagicEffectComponent>(ent, out var magicEffect))
|
||||
return;
|
||||
@@ -349,9 +126,9 @@ public abstract partial class CP14SharedMagicSystem
|
||||
_magicEnergy.ChangeEnergy((args.Performer.Value, playerMana), -requiredMana, out _, out _, safe: false);
|
||||
}
|
||||
|
||||
private void OnSkillPointConsume(Entity<CP14MagicEffectSkillPointCostComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
private void OnSkillPointConsume(Entity<CP14ActionSkillPointCostComponent> ent, ref CP14MagicEffectConsumeResourceEvent args)
|
||||
{
|
||||
if (!_proto.TryIndex(ent.Comp.SkillPoint, out var indexedSkillPoint) || ent.Comp.SkillPoint is null || args.Performer is null)
|
||||
if (ent.Comp.SkillPoint is null || args.Performer is null)
|
||||
return;
|
||||
|
||||
_skill.RemoveSkillPoints(args.Performer.Value, ent.Comp.SkillPoint.Value, ent.Comp.Count);
|
||||
|
||||
@@ -64,10 +64,6 @@ public abstract partial class CP14SharedMagicSystem
|
||||
if (currentTarget is not null && currentTarget == EntityUid.Invalid)
|
||||
currentTarget = null;
|
||||
|
||||
var spellArgs = new CP14SpellEffectBaseArgs(performer, action.Comp.SpellStorage, currentTarget, worldTarget);
|
||||
if (!CanCastSpell(action, spellArgs))
|
||||
return false;
|
||||
|
||||
if (_doAfter.IsRunning(action.Comp.ActiveDoAfter))
|
||||
{
|
||||
_doAfter.Cancel(action.Comp.ActiveDoAfter);
|
||||
@@ -79,6 +75,8 @@ public abstract partial class CP14SharedMagicSystem
|
||||
|
||||
var evStart = new CP14StartCastMagicEffectEvent(performer);
|
||||
RaiseLocalEvent(action, ref evStart);
|
||||
|
||||
var spellArgs = new CP14SpellEffectBaseArgs(performer, action.Comp.SpellStorage, currentTarget, worldTarget);
|
||||
CastTelegraphy(action, spellArgs);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
using System.Linq;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Mobs;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell;
|
||||
|
||||
public abstract partial class CP14SharedMagicSystem
|
||||
{
|
||||
private void InitializeExamine()
|
||||
{
|
||||
SubscribeLocalEvent<CP14MagicEffectComponent, ExaminedEvent>(OnManaEffectExamined);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectManaCostComponent, ExaminedEvent>(OnManacostExamined);
|
||||
SubscribeLocalEvent<CP14MagicEffectStaminaCostComponent, ExaminedEvent>(OnStaminaCostExamined);
|
||||
SubscribeLocalEvent<CP14MagicEffectSkillPointCostComponent, ExaminedEvent>(OnSkillPointCostExamined);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectVerbalAspectComponent, ExaminedEvent>(OnVerbalExamined);
|
||||
SubscribeLocalEvent<CP14MagicEffectSomaticAspectComponent, ExaminedEvent>(OnSomaticExamined);
|
||||
SubscribeLocalEvent<CP14MagicEffectMaterialAspectComponent, ExaminedEvent>(OnMaterialExamined);
|
||||
SubscribeLocalEvent<CP14MagicEffectRequiredMusicToolComponent, ExaminedEvent>(OnMusicExamined);
|
||||
SubscribeLocalEvent<CP14MagicEffectTargetMobStatusRequiredComponent, ExaminedEvent>(OnMobStateExamined);
|
||||
}
|
||||
|
||||
private void OnManaEffectExamined(Entity<CP14MagicEffectComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
if (_proto.TryIndex(ent.Comp.MagicType, out var indexedMagic))
|
||||
{
|
||||
args.PushMarkup($"{Loc.GetString("cp14-magic-type")}: [color={indexedMagic.Color.ToHex()}]{Loc.GetString(indexedMagic.Name)}[/color]", 10);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnManacostExamined(Entity<CP14MagicEffectManaCostComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup($"{Loc.GetString("cp14-magic-manacost")}: [color=#5da9e8]{ent.Comp.ManaCost}[/color]", priority: 9);
|
||||
}
|
||||
|
||||
private void OnStaminaCostExamined(Entity<CP14MagicEffectStaminaCostComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup($"{Loc.GetString("cp14-magic-staminacost")}: [color=#3fba54]{ent.Comp.Stamina}[/color]", priority: 9);
|
||||
}
|
||||
|
||||
private void OnSkillPointCostExamined(Entity<CP14MagicEffectSkillPointCostComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
if (!_proto.TryIndex(ent.Comp.SkillPoint, out var indexedSkillPoint))
|
||||
return;
|
||||
|
||||
args.PushMarkup($"{Loc.GetString("cp14-magic-skillpointcost", ("name", Loc.GetString(indexedSkillPoint.Name)), ("count", ent.Comp.Count))}", priority: 9);
|
||||
}
|
||||
|
||||
private void OnVerbalExamined(Entity<CP14MagicEffectVerbalAspectComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-verbal-aspect"), 8);
|
||||
}
|
||||
|
||||
private void OnSomaticExamined(Entity<CP14MagicEffectSomaticAspectComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-somatic-aspect") + " " + ent.Comp.FreeHandRequired, 8);
|
||||
}
|
||||
|
||||
private void OnMaterialExamined(Entity<CP14MagicEffectMaterialAspectComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
if (ent.Comp.Requirement is not null)
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-material-aspect") + " " + ent.Comp.Requirement.GetRequirementTitle(_proto));
|
||||
}
|
||||
private void OnMusicExamined(Entity<CP14MagicEffectRequiredMusicToolComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-music-aspect"));
|
||||
}
|
||||
|
||||
private void OnMobStateExamined(Entity<CP14MagicEffectTargetMobStatusRequiredComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
var states = string.Join(", ",
|
||||
ent.Comp.AllowedStates.Select(state => state switch
|
||||
{
|
||||
MobState.Alive => Loc.GetString("cp14-magic-spell-target-mob-state-live"),
|
||||
MobState.Dead => Loc.GetString("cp14-magic-spell-target-mob-state-dead"),
|
||||
MobState.Critical => Loc.GetString("cp14-magic-spell-target-mob-state-critical")
|
||||
}));
|
||||
|
||||
args.PushMarkup(Loc.GetString("cp14-magic-spell-target-mob-state", ("state", states)));
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,8 @@ public abstract partial class CP14SharedMagicSystem
|
||||
return;
|
||||
|
||||
var spellArgs = new CP14SpellEffectBaseArgs(args.Performer, magicEffect.SpellStorage, args.Performer, Transform(args.Performer).Coordinates);
|
||||
|
||||
if (!CanCastSpell((args.Action, magicEffect), spellArgs))
|
||||
return;
|
||||
|
||||
CastSpell((args.Action, magicEffect), spellArgs);
|
||||
|
||||
_action.SetCooldown(args.Action.Owner, args.Cooldown);
|
||||
}
|
||||
|
||||
@@ -39,11 +36,8 @@ public abstract partial class CP14SharedMagicSystem
|
||||
return;
|
||||
|
||||
var spellArgs = new CP14SpellEffectBaseArgs(args.Performer, magicEffect.SpellStorage, null, args.Target);
|
||||
|
||||
if (!CanCastSpell((args.Action, magicEffect), spellArgs))
|
||||
return;
|
||||
|
||||
CastSpell((args.Action, magicEffect), spellArgs);
|
||||
|
||||
_action.SetCooldown(args.Action.Owner, args.Cooldown);
|
||||
}
|
||||
|
||||
@@ -56,11 +50,8 @@ public abstract partial class CP14SharedMagicSystem
|
||||
return;
|
||||
|
||||
var spellArgs = new CP14SpellEffectBaseArgs(args.Performer, magicEffect.SpellStorage, args.Target, Transform(args.Target).Coordinates);
|
||||
|
||||
if (!CanCastSpell((args.Action, magicEffect), spellArgs))
|
||||
return;
|
||||
|
||||
CastSpell((args.Action, magicEffect), spellArgs);
|
||||
|
||||
_action.SetCooldown(args.Action.Owner, args.Cooldown);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ public abstract partial class CP14SharedMagicSystem
|
||||
var spellArgs =
|
||||
new CP14SpellEffectBaseArgs(toggled.Performer, effect.SpellStorage, toggled.EntityTarget, toggled.WorldTarget);
|
||||
|
||||
if (!CanCastSpell((uid, effect), spellArgs))
|
||||
{
|
||||
if (_doAfter.IsRunning(toggled.DoAfterId))
|
||||
_doAfter.Cancel(toggled.DoAfterId);
|
||||
continue;
|
||||
}
|
||||
//if (!CanCastSpell((uid, effect), spellArgs))
|
||||
//{
|
||||
// if (_doAfter.IsRunning(toggled.DoAfterId))
|
||||
// _doAfter.Cancel(toggled.DoAfterId);
|
||||
// continue;
|
||||
//}
|
||||
|
||||
CastSpell((uid, effect), spellArgs);
|
||||
}
|
||||
@@ -127,10 +127,6 @@ public abstract partial class CP14SharedMagicSystem
|
||||
|
||||
private void ToggleToggleableAction(ICP14ToggleableMagicEffect toggleable, DoAfterEvent doAfter, Entity<CP14MagicEffectComponent> action, EntityUid performer, EntityUid? entityTarget = null, EntityCoordinates? worldTarget = null)
|
||||
{
|
||||
var spellArgs = new CP14SpellEffectBaseArgs(performer, entityTarget, entityTarget, worldTarget);
|
||||
if (!CanCastSpell(action, spellArgs))
|
||||
return;
|
||||
|
||||
if (_doAfter.IsRunning(action.Comp.ActiveDoAfter))
|
||||
_doAfter.Cancel(action.Comp.ActiveDoAfter);
|
||||
else
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Text;
|
||||
using Content.Shared._CP14.Actions.Components;
|
||||
using Content.Shared._CP14.MagicEnergy;
|
||||
using Content.Shared._CP14.MagicEnergy.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Content.Shared._CP14.MagicSpell.Spells;
|
||||
using Content.Shared._CP14.MagicVision;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Damage.Systems;
|
||||
@@ -26,7 +26,7 @@ namespace Content.Shared._CP14.MagicSpell;
|
||||
public abstract partial class CP14SharedMagicSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly SharedCP14MagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly CP14SharedMagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
@@ -49,7 +49,6 @@ public abstract partial class CP14SharedMagicSystem : EntitySystem
|
||||
InitializeInstantActions();
|
||||
InitializeChecks();
|
||||
InitializeSlowdown();
|
||||
InitializeExamine();
|
||||
|
||||
_magicContainerQuery = GetEntityQuery<CP14MagicEnergyContainerComponent>();
|
||||
_magicEffectQuery = GetEntityQuery<CP14MagicEffectComponent>();
|
||||
@@ -106,23 +105,6 @@ public abstract partial class CP14SharedMagicSystem : EntitySystem
|
||||
_doAfter.Cancel(ent.Comp.ActiveDoAfter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checking to see if the spell can be used at all
|
||||
/// </summary>
|
||||
private bool CanCastSpell(Entity<CP14MagicEffectComponent> ent, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (args.User is not { } performer)
|
||||
return true;
|
||||
|
||||
var ev = new CP14CastMagicEffectAttemptEvent(performer, args.Used, args.Target, args.Position);
|
||||
RaiseLocalEvent(ent, ev);
|
||||
|
||||
if (ev.Reason != string.Empty)
|
||||
_popup.PopupPredicted(ev.Reason, performer, performer);
|
||||
|
||||
return !ev.Cancelled;
|
||||
}
|
||||
|
||||
private void CastTelegraphy(Entity<CP14MagicEffectComponent> ent, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (!_timing.IsFirstTimePredicted)
|
||||
@@ -149,7 +131,7 @@ public abstract partial class CP14SharedMagicSystem : EntitySystem
|
||||
|
||||
if (args.User is not null
|
||||
&& TryComp<ActionComponent>(ent, out var actionComp)
|
||||
&& TryComp<CP14MagicEffectManaCostComponent>(ent, out var manaCost))
|
||||
&& TryComp<CP14ActionManaCostComponent>(ent, out var manaCost))
|
||||
{
|
||||
_magicVision.SpawnMagicTrace(
|
||||
Transform(args.User.Value).Coordinates,
|
||||
@@ -161,13 +143,13 @@ public abstract partial class CP14SharedMagicSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
protected FixedPoint2 CalculateManacost(Entity<CP14MagicEffectManaCostComponent> ent, EntityUid? caster)
|
||||
public FixedPoint2 CalculateManacost(Entity<CP14ActionManaCostComponent> ent, EntityUid? caster)
|
||||
{
|
||||
var manaCost = ent.Comp.ManaCost;
|
||||
|
||||
if (ent.Comp.CanModifyManacost && _magicEffectQuery.TryComp(ent, out var magicEffect))
|
||||
{
|
||||
var manaEv = new CP14CalculateManacostEvent(caster, ent.Comp.ManaCost, magicEffect.MagicType);
|
||||
var manaEv = new CP14CalculateManacostEvent(caster, ent.Comp.ManaCost);
|
||||
|
||||
if (caster is not null)
|
||||
RaiseLocalEvent(caster.Value, manaEv);
|
||||
|
||||
@@ -18,9 +18,6 @@ public sealed partial class CP14MagicEffectComponent : Component
|
||||
[DataField]
|
||||
public EntityUid? SpellStorage;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<CP14MagicTypePrototype>? MagicType = null;
|
||||
|
||||
/// <summary>
|
||||
/// Effects that will trigger at the beginning of the cast, before mana is spent. Should have no gameplay importance, just special effects, popups and sounds.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Blocks the target from using magic if they are pacified.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectPacifiedBlockComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the user to play music to use this spell
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectRequiredMusicToolComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Blocks the target from using magic if they are pacified.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14MagicEffectSSDBlockComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -8,35 +8,6 @@ using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Called first to verify that all conditions are met and the spell can be performed.
|
||||
/// </summary>
|
||||
public sealed class CP14CastMagicEffectAttemptEvent : CancellableEntityEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The Performer of the event, to check if they meet the requirements.
|
||||
/// </summary>
|
||||
public readonly EntityUid Performer;
|
||||
public readonly EntityUid? Used;
|
||||
public readonly EntityUid? Target;
|
||||
public readonly EntityCoordinates? Position;
|
||||
|
||||
public string Reason = string.Empty;
|
||||
|
||||
public CP14CastMagicEffectAttemptEvent(EntityUid performer, EntityUid? used, EntityUid? target, EntityCoordinates? position)
|
||||
{
|
||||
Performer = performer;
|
||||
Used = used;
|
||||
Target = target;
|
||||
Position = position;
|
||||
}
|
||||
|
||||
public void PushReason(string reason)
|
||||
{
|
||||
Reason += $"{reason}\n";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event that checks all sorts of conditions, and calculates the total cost of casting a spell. Called before the spell is cast.
|
||||
/// </summary>
|
||||
@@ -47,13 +18,11 @@ public sealed class CP14CalculateManacostEvent : EntityEventArgs, IInventoryRela
|
||||
|
||||
public float Multiplier = 1f;
|
||||
public EntityUid? Performer;
|
||||
public ProtoId<CP14MagicTypePrototype>? MagicType;
|
||||
|
||||
public CP14CalculateManacostEvent(EntityUid? performer, FixedPoint2 initialManacost, ProtoId<CP14MagicTypePrototype>? magicType)
|
||||
public CP14CalculateManacostEvent(EntityUid? performer, FixedPoint2 initialManacost)
|
||||
{
|
||||
Performer = performer;
|
||||
Manacost = initialManacost;
|
||||
MagicType = magicType;
|
||||
}
|
||||
|
||||
public float GetManacost()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared._CP14.Actions.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared.Electrocution;
|
||||
|
||||
@@ -22,7 +23,7 @@ public sealed partial class CP14SpellInterruptSpell : CP14SpellEffect
|
||||
var interrupt = false;
|
||||
foreach (var spell in caster.CastedSpells)
|
||||
{
|
||||
if (entManager.HasComponent<CP14MagicEffectManaCostComponent>(spell))
|
||||
if (entManager.HasComponent<CP14ActionManaCostComponent>(spell))
|
||||
{
|
||||
interrupt = true;
|
||||
break;
|
||||
|
||||
@@ -22,7 +22,7 @@ public sealed partial class CP14SpellConsumeManaEffect : CP14SpellEffect
|
||||
if (!entManager.HasComponent<CP14MagicEnergyContainerComponent>(targetEntity))
|
||||
return;
|
||||
|
||||
var magicEnergy = entManager.System<SharedCP14MagicEnergySystem>();
|
||||
var magicEnergy = entManager.System<CP14SharedMagicEnergySystem>();
|
||||
|
||||
//First - used object
|
||||
if (args.Used is not null)
|
||||
|
||||
@@ -25,7 +25,7 @@ public sealed partial class CP14SpellTransferManaToGod : CP14SpellEffect
|
||||
return;
|
||||
|
||||
var religionSys = entManager.System<CP14SharedReligionGodSystem>();
|
||||
var magicEnergySys = entManager.System<SharedCP14MagicEnergySystem>();
|
||||
var magicEnergySys = entManager.System<CP14SharedMagicEnergySystem>();
|
||||
|
||||
var gods = religionSys.GetGods(follower.Religion.Value);
|
||||
var manaAmount = Amount / gods.Count;
|
||||
|
||||
@@ -11,13 +11,13 @@ public sealed partial class AddManaMax : CP14SkillEffect
|
||||
public FixedPoint2 AdditionalMana = 0;
|
||||
public override void AddSkill(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
var magicSystem = entManager.System<SharedCP14MagicEnergySystem>();
|
||||
var magicSystem = entManager.System<CP14SharedMagicEnergySystem>();
|
||||
magicSystem.ChangeMaximumEnergy(target, AdditionalMana);
|
||||
}
|
||||
|
||||
public override void RemoveSkill(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
var magicSystem = entManager.System<SharedCP14MagicEnergySystem>();
|
||||
var magicSystem = entManager.System<CP14SharedMagicEnergySystem>();
|
||||
magicSystem.ChangeMaximumEnergy(target, -AdditionalMana);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,20 +12,10 @@ public sealed partial class ModifyManacost : CP14SkillEffect
|
||||
[DataField]
|
||||
public FixedPoint2 Global = 0f;
|
||||
|
||||
[DataField]
|
||||
public Dictionary<ProtoId<CP14MagicTypePrototype>, FixedPoint2> Modifiers = new();
|
||||
|
||||
public override void AddSkill(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
entManager.EnsureComponent<CP14MagicManacostModifyComponent>(target, out var magicEffectManaCost);
|
||||
|
||||
foreach (var (magicType, modifier) in Modifiers)
|
||||
{
|
||||
if (!magicEffectManaCost.Modifiers.ContainsKey(magicType))
|
||||
magicEffectManaCost.Modifiers.Add(magicType, 1 + modifier);
|
||||
else
|
||||
magicEffectManaCost.Modifiers[magicType] += modifier;
|
||||
}
|
||||
magicEffectManaCost.GlobalModifier += Global;
|
||||
}
|
||||
|
||||
@@ -33,15 +23,6 @@ public sealed partial class ModifyManacost : CP14SkillEffect
|
||||
{
|
||||
entManager.EnsureComponent<CP14MagicManacostModifyComponent>(target, out var magicEffectManaCost);
|
||||
|
||||
foreach (var (magicType, modifier) in Modifiers)
|
||||
{
|
||||
if (!magicEffectManaCost.Modifiers.ContainsKey(magicType))
|
||||
continue;
|
||||
|
||||
magicEffectManaCost.Modifiers[magicType] -= modifier;
|
||||
if (magicEffectManaCost.Modifiers[magicType] <= 0)
|
||||
magicEffectManaCost.Modifiers.Remove(magicType);
|
||||
}
|
||||
magicEffectManaCost.GlobalModifier -= Global;
|
||||
}
|
||||
|
||||
@@ -63,16 +44,6 @@ public sealed partial class ModifyManacost : CP14SkillEffect
|
||||
$"{Loc.GetString("cp14-clothing-magic-global")}: {plus}{MathF.Round((float)Global * 100, MidpointRounding.AwayFromZero)}%\n");
|
||||
}
|
||||
|
||||
foreach (var modifier in Modifiers)
|
||||
{
|
||||
if (modifier.Value == 0)
|
||||
continue;
|
||||
|
||||
var plus = modifier.Value > 1 ? "+" : "";
|
||||
var indexedType = protoManager.Index(modifier.Key);
|
||||
sb.Append($"- [color={indexedType.Color.ToHex()}]{Loc.GetString(indexedType.Name)}[/color]: {plus}{modifier.Value*100}%");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Content.Shared._CP14.Vampire.Components;
|
||||
using Content.Shared.Actions.Events;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.SSDIndicator;
|
||||
@@ -12,22 +13,25 @@ public abstract partial class CP14SharedVampireSystem
|
||||
|
||||
private void InitializeSpell()
|
||||
{
|
||||
SubscribeLocalEvent<CP14MagicEffectVampireComponent, CP14CastMagicEffectAttemptEvent>(OnVampireCastAttempt);
|
||||
SubscribeLocalEvent<CP14MagicEffectVampireComponent, ActionAttemptEvent>(OnVampireCastAttempt);
|
||||
SubscribeLocalEvent<CP14MagicEffectVampireComponent, ExaminedEvent>(OnVampireCastExamine);
|
||||
}
|
||||
|
||||
private void OnVampireCastAttempt(Entity<CP14MagicEffectVampireComponent> ent, ref CP14CastMagicEffectAttemptEvent args)
|
||||
private void OnVampireCastAttempt(Entity<CP14MagicEffectVampireComponent> ent, ref ActionAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
//If we are not vampires in principle, we certainly should not have this ability,
|
||||
//but then we will not limit its use to a valid vampire form that is unavailable to us.
|
||||
|
||||
if (!HasComp<CP14VampireComponent>(args.Performer))
|
||||
if (!HasComp<CP14VampireComponent>(args.User))
|
||||
return;
|
||||
|
||||
if (!HasComp<CP14VampireVisualsComponent>(args.Performer))
|
||||
if (!HasComp<CP14VampireVisualsComponent>(args.User))
|
||||
{
|
||||
args.PushReason(Loc.GetString("cp14-magic-spell-need-vampire-valid"));
|
||||
args.Cancel();
|
||||
_popup.PopupClient(Loc.GetString("cp14-magic-spell-need-vampire-valid"), args.User, args.User);
|
||||
args.Cancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public sealed partial class MagicInWorkbench : CP14WorkbenchCraftCondition
|
||||
EntityUid workbench,
|
||||
EntityUid user)
|
||||
{
|
||||
var magicSys = entManager.System<SharedCP14MagicEnergySystem>();
|
||||
var magicSys = entManager.System<CP14SharedMagicEnergySystem>();
|
||||
|
||||
magicSys.ChangeEnergy(workbench, -Energy, out _, out _);
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public sealed partial class MagicInWorkbench : CP14WorkbenchCraftCondition
|
||||
EntityUid workbench,
|
||||
EntityUid user)
|
||||
{
|
||||
var magicSys = entManager.System<SharedCP14MagicEnergySystem>();
|
||||
var magicSys = entManager.System<CP14SharedMagicEnergySystem>();
|
||||
magicSys.ChangeEnergy(workbench, -Energy, out _, out _);
|
||||
|
||||
if (entManager.TryGetComponent<TransformComponent>(workbench, out var xform))
|
||||
|
||||
@@ -1859,3 +1859,48 @@
|
||||
id: 8235
|
||||
time: '2025-08-24T23:03:24.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1705
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: Players no longer know each other's names at the start of the round.
|
||||
type: Tweak
|
||||
- message: "The player can \u201CRemember\u201D the name of any other character\
|
||||
\ (by entering any text) via the Verb menu. This \u201CRemembered\u201D name\
|
||||
\ will be visible in chat and when viewing the character."
|
||||
type: Tweak
|
||||
- message: Notifications about players arriving at and leaving the settlement are
|
||||
disabled.
|
||||
type: Remove
|
||||
- message: Vampire masks no longer require blood essence to craft, but do not change
|
||||
the wearer's voice.
|
||||
type: Tweak
|
||||
id: 8236
|
||||
time: '2025-08-27T14:34:11.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1710
|
||||
- author: KittyCat432
|
||||
changes:
|
||||
- message: Added the spineguard a new mob that can be found in underground areas.
|
||||
type: Add
|
||||
- message: Added a new monster toxin depletonide which is used in the spineguards
|
||||
spines it causes you to take increased damage (1.4x).
|
||||
type: Add
|
||||
id: 8237
|
||||
time: '2025-08-30T07:27:04.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1659
|
||||
- author: Nimfar11
|
||||
changes:
|
||||
- message: Small boxes and barrels are once again being carried across the water.
|
||||
type: Fix
|
||||
- message: The T2 skeleton archer now has the ability to fight with a sword, which
|
||||
he is also armed with.
|
||||
type: Fix
|
||||
id: 8238
|
||||
time: '2025-09-01T12:07:27.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1730
|
||||
- author: Nimfar11
|
||||
changes:
|
||||
- message: 'Adds three magic traps: electric, fire, and ice. They can only be created
|
||||
with scrolls or appear in demiplanes.'
|
||||
type: Add
|
||||
id: 8239
|
||||
time: '2025-09-02T08:52:37.0000000+00:00'
|
||||
url: https://github.com/crystallpunk-14/crystall-punk-14/pull/1662
|
||||
|
||||
@@ -16,6 +16,7 @@ cp14-modifier-cackle = cackles
|
||||
cp14-modifier-skeleton = sentient skeletons
|
||||
cp14-modifier-dyno = dynos
|
||||
cp14-modifier-mole = predatory moles
|
||||
cp14-modifier-spineguard = spineguards
|
||||
cp14-modifier-watcher = watchers
|
||||
cp14-modifier-rabbits = rabbits
|
||||
cp14-modifier-boars = wild boars
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
cp14-remember-name-verb = Remember name
|
||||
|
||||
cp14-remember-name-name = Name
|
||||
|
||||
cp14-remember-name-examine = You remember this character as [color=yellow]{$name}[/color]
|
||||
@@ -3,3 +3,6 @@ cp14-reagent-desc-toxin-spider = A venom which slows down its victim while destr
|
||||
|
||||
cp14-reagent-name-toxin-bleed = Hemoroxide
|
||||
cp14-reagent-desc-toxin-bleed = A venom which causes intense bleeding. Commonly used by Cackles.
|
||||
|
||||
cp14-reagent-name-toxin-vuln = Depletonide
|
||||
cp14-reagent-desc-toxin-vuln = A venom which causes the body to be more susceptible to damage and become fatigued. Commonly used by Spineguard's spines.
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
cp14-tips-1 = Keep an eye on the condition of your weapon! You can inspect it to see its condition and sharpness.
|
||||
cp14-tips-2 = If your weapon is dull, you can sharpen it with sharpening stones.
|
||||
cp14-tips-3 = Some light weapons, such as daggers or sickles, are effective for dual wield combat.
|
||||
cp14-tips-4 = Some magic items can only work after being attuned. To customize the binding, press the RMB and select the desired action.
|
||||
cp14-tips-4 = Initially, you don't know the names of the other characters! But you can remember any names and nicknames for them via the context menu.
|
||||
cp14-tips-5 = As an alchemist, if you mix some reagents together, you can no longer separate them! Look for the right alchemical reactions that will allow you to edit your solution.
|
||||
cp14-tips-6 = As an alchemist, remember to keep your cauldron off the stove or fire. Your potion may boil over, releasing a reagent cloud.
|
||||
cp14-tips-7 = You can use shields to parry enemy attacks! Hit the enemy with a shield strike immediately after his attack and you can knock the weapon out of his hands.
|
||||
cp14-tips-7 = As a vampire, if you try to suck out the essence of blood but there is none at the target, it can mean one of two things: Either you are eating another vampire, or your victim has already been eaten by other vampires.
|
||||
cp14-tips-8 = If you run out of magic energy, you can still use spells and spend mana, but it will damage you and potentially render you unconscious!
|
||||
cp14-tips-9 = Don't go on the demiplanes alone, kids! The demiplanes are designed to be difficult for a group of 4 people.
|
||||
cp14-tips-9 = Be careful during thunderstorms! Lightning can strike anyone and anything that is not under cover. It can cause massive fires.
|
||||
cp14-tips-10 = Tall bushes are good for hiding your character! But they slow you down a lot and make a lot of noise if you move in them.
|
||||
cp14-tips-11 = Don't forget to lock your doors if you don't want anyone to get in!
|
||||
cp14-tips-12 = You can examine the demiplane key to see what you can find in it. The information may be incomplete, but you can still navigate by it, and choose where you want to go.
|
||||
cp14-tips-13 = As a farmer, don't forget to water your vegetable garden! Plants die without watering.
|
||||
cp14-tips-12 = You can create your own keys and locks to ensure the privacy of your territory! To do this, use key files and screwdrivers!
|
||||
cp14-tips-13 = Tip number 13 does not exist.
|
||||
cp14-tips-14 = Demiplanes can be very dangerous, don't neglect medical consumables and alchemist potions.
|
||||
cp14-tips-15 = When you use the demiplane key, an unstable rift opens up that will draw in up to 4 nearby players after a while.
|
||||
cp14-tips-16 = When moving between or from the demiplane, you can additionally grab a large item (or the corpse of a dead friend) by pulling it with you during the teleportation time.
|
||||
cp14-tips-17 = If you wish to leave the round, you may board a traveling ship. When it travels to the empire, you will leave the round and free up your role for another player.
|
||||
cp14-tips-15 = You can look inside the giant crystal connecting the demiplanes to see the entire current map of demiplane connections!
|
||||
cp14-tips-16 = The main source of income for adventurers is the extraction of raw resources within pocket dimensions known as demi-planes.
|
||||
cp14-tips-17 = The magic vision spell allows you to see where and when spells were used! Investigators can use this to search for criminals.
|
||||
@@ -16,6 +16,7 @@ cp14-modifier-cackle = кэклзы
|
||||
cp14-modifier-skeleton = разумные скелеты
|
||||
cp14-modifier-dyno = динозавры
|
||||
cp14-modifier-mole = хищные кроты
|
||||
cp14-modifier-spineguard = шипостражи
|
||||
cp14-modifier-watcher = наблюдатели
|
||||
cp14-modifier-rabbits = кролики
|
||||
cp14-modifier-boars = дикие кабаны
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
cp14-remember-name-verb = Запомнить имя
|
||||
|
||||
cp14-remember-name-name = Имя
|
||||
|
||||
cp14-remember-name-examine = Вы помните этого персонажа как [color=yellow]{$name}[/color]
|
||||
@@ -3,3 +3,6 @@ cp14-reagent-desc-toxin-spider = Яд, который замедляет жер
|
||||
|
||||
cp14-reagent-name-toxin-bleed = Гемороксид
|
||||
cp14-reagent-desc-toxin-bleed = Яд, вызывающий сильное кровотечение. Обычно используется Кэклзом.
|
||||
|
||||
cp14-reagent-name-toxin-vuln = Деплетонид
|
||||
cp14-reagent-desc-toxin-vuln = Яд, который делает тело более восприимчивым к повреждениям и утомляет его. Обычно используется шипами Шипостража.
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
cp14-tips-1 = Следите за состоянием вашего оружия! Вы можете осмотреть его, чтобы увидеть его состояние и остроту.
|
||||
cp14-tips-2 = Если ваше оружие затупилось, вы можете заточить его при помощи точильных камней.
|
||||
cp14-tips-3 = Некоторое легкое оружие, такое как кинжалы или серпы, эффективно для боя с двух рук.
|
||||
cp14-tips-4 = Некоторые магические предметы могут работать только после привязки. Чтобы настроить привязку, нажмите ПКМ и выберите нужное действие.
|
||||
cp14-tips-4 = Изначально вы не знаете как зовут других персонажей! Но вы можете запомнить любые имена и клички для них через контекстное меню.
|
||||
cp14-tips-5 = Будучи алхимиком, если вы смешали какие-то реагенты вместе, вы больше не сможете их разделить! Ищите нужные алхимические реакции, которые позволят вам редактировать ваш раствор.
|
||||
cp14-tips-6 = Будучи алхимиком, не забывайте убрать ваш котелок с печки или костра. Ваше зелье может выкипеть, выпустив реагентное облако.
|
||||
cp14-tips-7 = Вы можете использовать щиты, чтобы парировать вражеские атаки! Попадите по противнику ударом щита сразу же после его атаки, и вы сможете выбить оружие из его рук.
|
||||
cp14-tips-7 = Будучи вампиром, если вы пытаетесь высосать эссенции крови, но ее у цели нет, это может значить одно из двух: Или вы кушаете другого вампира, или вашу жертву уже кушали другие вампиры.
|
||||
cp14-tips-8 = Если у вас кончилась магическая энергия, вы все еще можете использовать заклинания и тратить ману, но это будет наносить вам урон, и потенциально может лишить вас сознания!
|
||||
cp14-tips-9 = Не ходите, дети, в демипланы в одиночку! Демипланы рассчитаны по сложности на группу из 4 человек.
|
||||
cp14-tips-9 = Будьте внимательны во время грозы! Молния может ударить в кого угодно и во что угодно, что не находится под крышей. И вызвать массвые пожары.
|
||||
cp14-tips-10 = Высокие кусты неплохо прячут вашего персонажа! Но сильно замедляют передвижение и шумят, если вы двигаетесь в них.
|
||||
cp14-tips-11 = Не забывайте закрывать двери на ключ, если не хотите чтобы туда заходил кто попало!
|
||||
cp14-tips-12 = Вы можете осмотреть ключ демиплана, чтобы узнать, что вы можете в нем найти. Информация может быть неполной, но по ней вы все равно можете ориентироваться, и выбирать куда вы хотите отправиться.
|
||||
cp14-tips-13 = Будучи фермером, не забывайте поливать свой огород! Растения умирают без полива.
|
||||
cp14-tips-12 = Вы можете создавать свои ключи и замки, чтобы обеспечить приватность территории! Для этого пользуйтесь нпильниками для ключей и отвертками!
|
||||
cp14-tips-13 = Совета номер 13 не существует.
|
||||
cp14-tips-14 = Демипланы могут быть очень опасны, не пренебрегайте медицинскими расходными материалами и алхимическими зельями.
|
||||
cp14-tips-15 = Когда вы используете ключ демиплана, открывается нестабильный разлом, который через некоторое время затянет в себя до 4 ближайших игроков.
|
||||
cp14-tips-16 = Перемещаясь между демипланом или из него, вы можете дополнительно захватить с собой большой предмет (или труп погибшего союзника), держа его во время момента телепортации.
|
||||
cp14-tips-17 = Если вы хотите покинуть раунд, вы можете сесть на странствующий корабль. Когда он отправится в империю, вы покинете раунд и освободите свою роль для другого игрока.
|
||||
cp14-tips-15 = Вы можете заглянуть внутрь гигантского кристалла связи с демипланами, чтобы увидеть всю текущую карту демипланов!
|
||||
cp14-tips-16 = Основным заработком авантюристов является добыча сырых ресурсов внутри карманных измерений-демипланов.
|
||||
cp14-tips-17 = Заклинание магического зрения позволяет видеть где и когда были использованы заклинания! Дознаватели стражи могут использовать это для поиска преступников.
|
||||
@@ -22,4 +22,10 @@
|
||||
description: cp14-alerts-confused-aura-desc
|
||||
icons:
|
||||
- sprite: _CP14/Actions/Spells/meta.rsi
|
||||
state: magic_vision_shuffled
|
||||
state: magic_vision_shuffled
|
||||
|
||||
- type: alert
|
||||
id: CP14Vuln
|
||||
icons:
|
||||
- sprite: _CP14/Actions/Spells/misc.rsi
|
||||
state: vulnerability
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
name: Dash
|
||||
description: You make a quick dash to the chosen position to quickly close the distance or dodge danger.
|
||||
components:
|
||||
- type: CP14MagicEffectStaminaCost
|
||||
- type: CP14ActionStaminaCost
|
||||
stamina: 40
|
||||
- type: CP14MagicEffect
|
||||
effects:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
state: kick
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.4
|
||||
- type: CP14MagicEffectStaminaCost
|
||||
- type: CP14ActionStaminaCost
|
||||
stamina: 40
|
||||
- type: CP14MagicEffect
|
||||
effects:
|
||||
@@ -32,7 +32,7 @@
|
||||
- type: CP14MagicEffectEmoting
|
||||
startEmote: cp14-kick-emote-start
|
||||
endEmote: cp14-kick-emote
|
||||
- type: CP14MagicEffectPacifiedBlock
|
||||
- type: CP14ActionDangerous
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/physical.rsi
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
state: sprint
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 1.3
|
||||
- type: CP14MagicEffectStaminaCost
|
||||
- type: CP14ActionStaminaCost
|
||||
stamina: 1.5
|
||||
- type: CP14MagicEffect
|
||||
effects:
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
name: Impenetrable darkness
|
||||
description: You summon a thick fog that obscures vision and disorients mortals.
|
||||
components:
|
||||
- type: CP14MagicEffectReligionRestricted
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionReligionRestricted
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 10
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
name: The Wrath of Lumera
|
||||
description: "You unleash your anger on the creature, stunning it, inflicting damage, and burning its mind, removing 0.5 memory points."
|
||||
components:
|
||||
- type: CP14MagicEffectReligionRestricted
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionReligionRestricted
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 300
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
name: Expansion of consciousness
|
||||
description: "You expand the boundaries of what is possible for the chosen creature, revealing to it the secrets of the universe. The target gains +0.5 memory points, up to a maximum of 6.5"
|
||||
components:
|
||||
- type: CP14MagicEffectReligionRestricted
|
||||
- type: CP14ActionReligionRestricted
|
||||
onlyOnFollowers: true
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 300
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
name: Lunar strike
|
||||
description: You focus the concentrated light of the stars into a single point, blinding and damaging everything that comes within reach of the angry goddess.
|
||||
components:
|
||||
- type: CP14MagicEffectReligionRestricted
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionReligionRestricted
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 30
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
name: Touch of Lumera
|
||||
description: "Multitasking effects on the world: depending on what you click on, the effect may vary. Using it on an empty space will create a glowing sign that attracts the attention of mortals."
|
||||
components:
|
||||
- type: CP14MagicEffectReligionRestricted
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionReligionRestricted
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 5
|
||||
- type: CP14MagicEffect
|
||||
effects:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
components:
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.5
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 30
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
@@ -17,7 +17,7 @@
|
||||
- !type:CP14SpellTeleportToCity
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14ImpactEffectShadowStep
|
||||
- type: CP14MagicEffectSomaticAspect
|
||||
- type: CP14ActionFreeHandsRequired
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/dimension.rsi
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
- type: Sprite
|
||||
sprite: _CP14/Actions/Spells/dimension.rsi
|
||||
state: shadow_grab
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 20
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
@@ -23,7 +23,7 @@
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
- CP14ImpactEffectShadowStep
|
||||
- type: CP14MagicEffectSomaticAspect
|
||||
- type: CP14ActionFreeHandsRequired
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/dimension.rsi
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
state: shadow_step
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.8
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 20
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
@@ -20,7 +20,7 @@
|
||||
- !type:CP14SpellCasterTeleport
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14ImpactEffectShadowStep
|
||||
- type: CP14MagicEffectSomaticAspect
|
||||
- type: CP14ActionFreeHandsRequired
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/dimension.rsi
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
state: shadow_swap
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.8
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 20
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
@@ -23,8 +23,8 @@
|
||||
- !type:CP14SpellCasterSwap
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14ImpactEffectShadowStep
|
||||
- type: CP14MagicEffectSomaticAspect
|
||||
- type: CP14MagicEffectTargetMobStatusRequired
|
||||
- type: CP14ActionFreeHandsRequired
|
||||
- type: CP14ActionTargetMobStatusRequired
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/dimension.rsi
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
components:
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: -1.0
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 5
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
state: earth_wall
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.3
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 15
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
@@ -20,11 +20,11 @@
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
- CP14WallSpawnEarthWall
|
||||
- type: CP14MagicEffectMaterialAspect
|
||||
- type: CP14ActionMaterialCost
|
||||
requirement: !type:StackResource
|
||||
stack: CP14Dirt
|
||||
count: 2
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "Surgite terram..."
|
||||
endSpeech: "de profundis terrae"
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
- type: entity
|
||||
id: CP14ActionSpellElectricTrap
|
||||
parent: CP14ActionSpellBase
|
||||
name: Electric trap
|
||||
description: Creates a electric trap at the selected location. Don't forget to recharge it with mana.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Actions/Spells/electromancy.rsi
|
||||
state: electric_trap
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.9
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 40
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
- CP14ImpactEffectElectricTrap
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
- CP14SpawnMagicElectricTrap
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "Signum electricum..."
|
||||
endSpeech: "hunc locum custodi"
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneElectricTrap
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/electromancy.rsi
|
||||
state: electric_trap
|
||||
- type: TargetAction
|
||||
range: 3
|
||||
- type: WorldTargetAction
|
||||
event: !type:CP14DelayedWorldTargetActionEvent
|
||||
cooldown: 4
|
||||
|
||||
- type: entity
|
||||
id: CP14RuneElectricTrap
|
||||
parent: CP14BaseMagicTrap
|
||||
categories: [ HideSpawnMenu ]
|
||||
save: false
|
||||
components:
|
||||
- type: PointLight
|
||||
color: "#e8ff4c"
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: small_circle
|
||||
color: "#e8ff4c"
|
||||
shader: unshaded
|
||||
- state: rune_fire
|
||||
color: "#e8ff4c"
|
||||
shader: unshaded
|
||||
|
||||
- type: entity
|
||||
id: CP14ImpactEffectElectricTrap
|
||||
parent: CP14BaseMagicImpact
|
||||
categories: [ HideSpawnMenu ]
|
||||
save: false
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: particles_up
|
||||
color: "#e8ff4c"
|
||||
shader: unshaded
|
||||
|
||||
- type: entity
|
||||
id: CP14SpawnMagicElectricTrap
|
||||
parent: CP14BaseMagicTrap
|
||||
name: electric trap
|
||||
description: A rune of electric drawn on the ground using magic — it's best not to step on it.
|
||||
categories: [ ForkFiltered ]
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: small_circle
|
||||
color: "#e8ff4c"
|
||||
shader: unshaded
|
||||
- state: rune_energia
|
||||
color: "#e8ff4c"
|
||||
shader: unshaded
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
trap:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.2,-0.2,0.2,0.2"
|
||||
hard: false
|
||||
mask:
|
||||
- MobMask
|
||||
layer:
|
||||
- SlipLayer
|
||||
- type: CP14MagicEnergyExaminable
|
||||
- type: CP14MagicEnergyContainer
|
||||
maxEnergy: 42
|
||||
energy: 42
|
||||
unsafeSupport: true
|
||||
- type: CP14MagicEnergyDraw
|
||||
energy: -0.5
|
||||
delay: 5
|
||||
- type: CP14MagicUnsafeDamage
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 1
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- type: TriggerOnCollide
|
||||
fixtureID: trap
|
||||
- type: SpawnOnTrigger
|
||||
proto: CP14ActionSpellElectricTrapEffect
|
||||
- type: DeleteOnTrigger
|
||||
|
||||
- type: entity
|
||||
id: CP14ActionSpellElectricTrapEffect
|
||||
name: electric star
|
||||
categories: [ HideSpawnMenu ]
|
||||
save: false
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Effects/Magic/cast_impact.rsi
|
||||
drawdepth: Mobs
|
||||
noRot: true
|
||||
layers:
|
||||
- state: stars
|
||||
color: "#e8ff4c"
|
||||
shader: unshaded
|
||||
- type: TimedDespawn
|
||||
lifetime: 1
|
||||
- type: Tag
|
||||
tags:
|
||||
- HideContextMenu
|
||||
- type: CP14AreaEntityEffect
|
||||
range: 2
|
||||
effects:
|
||||
- !type:CP14SpellApplyEntityEffect
|
||||
effects:
|
||||
- !type:HealthChange
|
||||
ignoreResistances: false
|
||||
damage:
|
||||
types:
|
||||
Shock: 10
|
||||
- !type:MovespeedModifier
|
||||
walkSpeedModifier: 1.3
|
||||
sprintSpeedModifier: 1.3
|
||||
statusLifetime: 4
|
||||
- !type:Jitter
|
||||
- !type:CP14StaminaChange
|
||||
staminaDelta: -100
|
||||
- type: EmitSoundOnTrigger
|
||||
sound:
|
||||
path: /Audio/Effects/PowerSink/electric.ogg
|
||||
params:
|
||||
variation: 0.1
|
||||
volume: -2
|
||||
- type: TriggerOnSpawn
|
||||
|
||||
- type: entity
|
||||
parent: CP14BaseSpellScrollElectric
|
||||
id: CP14SpellScrollElectricTrap
|
||||
name: electric trap spell scroll
|
||||
components:
|
||||
- type: CP14SpellStorage
|
||||
spells:
|
||||
- CP14ActionSpellElectricTrap
|
||||
|
||||
- type: entity
|
||||
parent: CP14SpawnMagicElectricTrap
|
||||
id: CP14SpawnMagicElectricTrapInvisible
|
||||
suffix: Invisible. Permanent
|
||||
components:
|
||||
- type: Visibility
|
||||
layer: 16
|
||||
- type: CP14MagicEnergyDraw
|
||||
energy: 0
|
||||
delay: 0
|
||||
|
||||
- type: entity
|
||||
parent: CP14SpawnMagicElectricTrap
|
||||
id: CP14SpawnMagicElectricTrapPermanent
|
||||
suffix: Permanent
|
||||
components:
|
||||
- type: CP14MagicEnergyDraw
|
||||
energy: 0
|
||||
delay: 0
|
||||
@@ -6,10 +6,9 @@
|
||||
components:
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.5
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 20
|
||||
- type: CP14MagicEffect
|
||||
magicType: Energia
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
@@ -29,12 +28,12 @@
|
||||
- !type:CP14SpellThrowFromUser
|
||||
throwPower: 4
|
||||
distance: 1
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "A fulgur percutiens... "
|
||||
endSpeech: "erit ledo vobis!"
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneLightningStrike
|
||||
- type: CP14MagicEffectPacifiedBlock
|
||||
- type: CP14ActionDangerous
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/electromancy.rsi
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
components:
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.5
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 7
|
||||
- type: CP14MagicEffect
|
||||
magicType: Energia
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
@@ -29,7 +28,7 @@
|
||||
- !type:CP14SpellThrowFromUser
|
||||
throwPower: 2
|
||||
distance: 0.5
|
||||
- type: CP14MagicEffectPacifiedBlock
|
||||
- type: CP14ActionDangerous
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/electromancy.rsi
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
components:
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 1
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 1
|
||||
- type: CP14MagicEffect
|
||||
magicType: Energia
|
||||
effects:
|
||||
- !type:CP14SpellArea
|
||||
affectCaster: true
|
||||
@@ -28,7 +27,7 @@
|
||||
walkSpeedModifier: 1.2
|
||||
sprintSpeedModifier: 1.2
|
||||
statusLifetime: 1.8
|
||||
- type: CP14MagicEffectRequiredMusicTool
|
||||
- type: CP14ActionRequiredMusicTool
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneSpeedBallade
|
||||
- type: Action
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
- type: entity
|
||||
id: CP14ActionSpellFireTrap
|
||||
parent: CP14ActionSpellBase
|
||||
name: Fire trap
|
||||
description: Creates a fire trap at the selected location. Don't forget to recharge it with mana.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Actions/Spells/fire.rsi
|
||||
state: fire_trap
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.9
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 40
|
||||
- type: CP14MagicEffect
|
||||
telegraphyEffects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
- CP14ImpactEffectFireTrap
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
- CP14SpawnMagicFireTrap
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "Signum ignis..."
|
||||
endSpeech: "hunc locum custodi"
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneFireTrap
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/fire.rsi
|
||||
state: fire_trap
|
||||
- type: TargetAction
|
||||
range: 3
|
||||
- type: WorldTargetAction
|
||||
event: !type:CP14DelayedWorldTargetActionEvent
|
||||
cooldown: 4
|
||||
|
||||
- type: entity
|
||||
id: CP14RuneFireTrap
|
||||
parent: CP14BaseMagicTrap
|
||||
categories: [ HideSpawnMenu ]
|
||||
save: false
|
||||
components:
|
||||
- type: PointLight
|
||||
color: "#eea911"
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: small_circle
|
||||
color: "#fdda5d"
|
||||
shader: unshaded
|
||||
- state: rune_fire
|
||||
color: "#eea911"
|
||||
shader: unshaded
|
||||
|
||||
- type: entity
|
||||
id: CP14ImpactEffectFireTrap
|
||||
parent: CP14BaseMagicImpact
|
||||
categories: [ HideSpawnMenu ]
|
||||
save: false
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: particles_up
|
||||
color: "#eea911"
|
||||
shader: unshaded
|
||||
|
||||
- type: entity
|
||||
id: CP14SpawnMagicFireTrap
|
||||
parent: CP14BaseMagicTrap
|
||||
name: fire trap
|
||||
description: A rune of fire drawn on the ground using magic — it's best not to step on it.
|
||||
categories: [ ForkFiltered ]
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: small_circle
|
||||
color: "#fdda5d"
|
||||
shader: unshaded
|
||||
- state: rune_fire
|
||||
color: "#eea911"
|
||||
shader: unshaded
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
trap:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.2,-0.2,0.2,0.2"
|
||||
hard: false
|
||||
mask:
|
||||
- MobMask
|
||||
layer:
|
||||
- SlipLayer
|
||||
- type: CP14MagicEnergyExaminable
|
||||
- type: CP14MagicEnergyContainer
|
||||
maxEnergy: 42
|
||||
energy: 42
|
||||
unsafeSupport: true
|
||||
- type: CP14MagicEnergyDraw
|
||||
energy: -0.5
|
||||
delay: 5
|
||||
- type: CP14MagicUnsafeDamage
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 1
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- type: TriggerOnCollide
|
||||
fixtureID: trap
|
||||
- type: IgnitionSource
|
||||
temperature: 400
|
||||
ignited: true
|
||||
- type: IgniteOnCollide
|
||||
fireStacks: 3
|
||||
- type: ExplodeOnTrigger
|
||||
- type: Explosive
|
||||
explosionType: FireBomb
|
||||
totalIntensity: 10.0
|
||||
intensitySlope: 4
|
||||
maxIntensity: 3
|
||||
- type: DeleteOnTrigger
|
||||
|
||||
- type: entity
|
||||
parent: CP14BaseSpellScrollFire
|
||||
id: CP14SpellScrollFireTrap
|
||||
name: fire trap spell scroll
|
||||
components:
|
||||
- type: CP14SpellStorage
|
||||
spells:
|
||||
- CP14ActionSpellFireTrap
|
||||
|
||||
- type: entity
|
||||
parent: CP14SpawnMagicFireTrap
|
||||
id: CP14SpawnMagicFireTrapInvisible
|
||||
suffix: Invisible. Permanent
|
||||
components:
|
||||
- type: Visibility
|
||||
layer: 16
|
||||
- type: CP14MagicEnergyDraw
|
||||
energy: 0
|
||||
delay: 0
|
||||
|
||||
- type: entity
|
||||
parent: CP14SpawnMagicFireTrap
|
||||
id: CP14SpawnMagicFireTrapPermanent
|
||||
suffix: Permanent
|
||||
components:
|
||||
- type: CP14MagicEnergyDraw
|
||||
energy: 0
|
||||
delay: 0
|
||||
@@ -6,23 +6,22 @@
|
||||
components:
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.3
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 20
|
||||
- type: CP14MagicEffect
|
||||
magicType: Fire
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnUser
|
||||
spawns:
|
||||
- CP14ImpactEffectFireball
|
||||
- !type:CP14SpellProjectile
|
||||
prototype: CP14Fireball
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "Quaeso, quemdam inter vos quaero... "
|
||||
endSpeech: "A pila!"
|
||||
- type: CP14MagicEffectSomaticAspect
|
||||
- type: CP14ActionFreeHandsRequired
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneFireball
|
||||
- type: CP14MagicEffectPacifiedBlock
|
||||
- type: CP14ActionDangerous
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/fire.rsi
|
||||
|
||||
@@ -9,21 +9,20 @@
|
||||
state: firewave
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.75
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 10
|
||||
- type: CP14MagicEffect
|
||||
magicType: Fire
|
||||
effects:
|
||||
- !type:CP14SpellProjectile
|
||||
prototype: CP14Firebolt
|
||||
spread: 2
|
||||
projectileSpeed: 5
|
||||
projectileCount: 8
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
- type: CP14ActionSpeaking
|
||||
endSpeech: "Ignis acus!"
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneFirebolt
|
||||
- type: CP14MagicEffectPacifiedBlock
|
||||
- type: CP14ActionDangerous
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/fire.rsi
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
name: Flame creation
|
||||
description: A artificial flame forms in your hand, illuminating your surroundings. You can throw it to use it as a disposable weapon.
|
||||
components:
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 5
|
||||
- type: CP14MagicEffect
|
||||
magicType: Fire
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
clientside: true
|
||||
@@ -16,10 +15,10 @@
|
||||
- !type:CP14SpellSpawnInHandEntity
|
||||
spawns:
|
||||
- CP14FlameCreationArtificialFlame
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "Et conteret ignis..."
|
||||
endSpeech: "in manu mea"
|
||||
- type: CP14MagicEffectSomaticAspect
|
||||
- type: CP14ActionFreeHandsRequired
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneFlameCreation
|
||||
- type: Action
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
state: heat
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.8
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 7
|
||||
- type: CP14MagicEffect
|
||||
magicType: Fire
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
@@ -24,11 +23,11 @@
|
||||
- !type:AdjustTemperature
|
||||
amount: 20000
|
||||
- !type:ExtinguishReaction
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "Vos adepto calidum..."
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneHeat
|
||||
- type: CP14MagicEffectPacifiedBlock
|
||||
- type: CP14ActionDangerous
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/fire.rsi
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
state: fire_music
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.5
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 8
|
||||
- type: CP14MagicEffect
|
||||
magicType: Fire
|
||||
effects:
|
||||
- !type:CP14SpellArea
|
||||
range: 3
|
||||
@@ -32,10 +31,10 @@
|
||||
- !type:AdjustTemperature
|
||||
amount: 500
|
||||
- !type:Ignite
|
||||
- type: CP14MagicEffectRequiredMusicTool
|
||||
- type: CP14ActionRequiredMusicTool
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneHellBallade
|
||||
- type: CP14MagicEffectPacifiedBlock
|
||||
- type: CP14ActionDangerous
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/fire.rsi
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneTieflingRevenge
|
||||
- type: CP14MagicEffect
|
||||
magicType: Fire
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
components:
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.4
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 5
|
||||
- type: CP14MagicEffect
|
||||
magicType: Life
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
components:
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.5
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 12
|
||||
- type: CP14MagicEffect
|
||||
magicType: Life
|
||||
telegraphyEffects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
clientside: true
|
||||
@@ -29,8 +28,8 @@
|
||||
Heat: -10
|
||||
Shock: -10
|
||||
- !type:Jitter
|
||||
- type: CP14MagicEffectTargetMobStatusRequired
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
- type: CP14ActionTargetMobStatusRequired
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "Pellis dolorem..."
|
||||
endSpeech: "non novit"
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
state: cure_poison
|
||||
- type: CP14MagicEffectCastSlowdown
|
||||
speedMultiplier: 0.5
|
||||
- type: CP14MagicEffectManaCost
|
||||
- type: CP14ActionManaCost
|
||||
manaCost: 12
|
||||
- type: CP14MagicEffect
|
||||
magicType: Life
|
||||
telegraphyEffects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
clientside: true
|
||||
@@ -34,10 +33,10 @@
|
||||
- !type:Jitter
|
||||
- !type:ModifyBloodLevel
|
||||
amount: 25
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
- type: CP14ActionSpeaking
|
||||
startSpeech: "Nella coda..."
|
||||
endSpeech: "sta il veleno"
|
||||
- type: CP14MagicEffectTargetMobStatusRequired
|
||||
- type: CP14ActionTargetMobStatusRequired
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneBloodPurification
|
||||
- type: Action
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user