Merge pull request #595 from crystallpunk-14/ed-20-11-2024-upstream-sync
Upstream sync
This commit is contained in:
@@ -25,7 +25,7 @@ public static class BanPanelEuiStateMsg
|
||||
{
|
||||
public string? Player { get; set; }
|
||||
public string? IpAddress { get; set; }
|
||||
public byte[]? Hwid { get; set; }
|
||||
public ImmutableTypedHwid? Hwid { get; set; }
|
||||
public uint Minutes { get; set; }
|
||||
public string Reason { get; set; }
|
||||
public NoteSeverity Severity { get; set; }
|
||||
@@ -34,7 +34,7 @@ public static class BanPanelEuiStateMsg
|
||||
public bool UseLastHwid { get; set; }
|
||||
public bool Erase { get; set; }
|
||||
|
||||
public CreateBanRequest(string? player, (IPAddress, int)? ipAddress, bool useLastIp, byte[]? hwid, bool useLastHwid, uint minutes, string reason, NoteSeverity severity, string[]? roles, bool erase)
|
||||
public CreateBanRequest(string? player, (IPAddress, int)? ipAddress, bool useLastIp, ImmutableTypedHwid? hwid, bool useLastHwid, uint minutes, string reason, NoteSeverity severity, string[]? roles, bool erase)
|
||||
{
|
||||
Player = player;
|
||||
IpAddress = ipAddress == null ? null : $"{ipAddress.Value.Item1}/{ipAddress.Value.Item2}";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Alert;
|
||||
|
||||
@@ -6,12 +7,23 @@ namespace Content.Shared.Alert;
|
||||
/// Handles the icons on the right side of the screen.
|
||||
/// Should only be used for player-controlled entities.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
|
||||
// Component is not AutoNetworked due to supporting clientside-only alerts.
|
||||
// Component state is handled manually to avoid the server overwriting the client list.
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class AlertsComponent : Component
|
||||
{
|
||||
[ViewVariables]
|
||||
[AutoNetworkedField]
|
||||
public Dictionary<AlertKey, AlertState> Alerts = new();
|
||||
|
||||
public override bool SendOnlyToOwner => true;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class AlertComponentState : ComponentState
|
||||
{
|
||||
public Dictionary<AlertKey, AlertState> Alerts { get; }
|
||||
public AlertComponentState(Dictionary<AlertKey, AlertState> alerts)
|
||||
{
|
||||
Alerts = alerts;
|
||||
}
|
||||
}
|
||||
|
||||
41
Content.Shared/CCVar/CCVars.Accessibility.cs
Normal file
41
Content.Shared/CCVar/CCVars.Accessibility.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Chat window opacity slider, controlling the alpha of the chat window background.
|
||||
/// Goes from to 0 (completely transparent) to 1 (completely opaque)
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> ChatWindowOpacity =
|
||||
CVarDef.Create("accessibility.chat_window_transparency", 0.85f, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Toggle for visual effects that may potentially cause motion sickness.
|
||||
/// Where reasonable, effects affected by this CVar should use an alternate effect.
|
||||
/// Please do not use this CVar as a bandaid for effects that could otherwise be made accessible without issue.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ReducedMotion =
|
||||
CVarDef.Create("accessibility.reduced_motion", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<bool> ChatEnableColorName =
|
||||
CVarDef.Create("accessibility.enable_color_name",
|
||||
true,
|
||||
CVar.CLIENTONLY | CVar.ARCHIVE,
|
||||
"Toggles displaying names with individual colors.");
|
||||
|
||||
/// <summary>
|
||||
/// Screen shake intensity slider, controlling the intensity of the CameraRecoilSystem.
|
||||
/// Goes from 0 (no recoil at all) to 1 (regular amounts of recoil)
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> ScreenShakeIntensity =
|
||||
CVarDef.Create("accessibility.screen_shake_intensity", 1f, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// A generic toggle for various visual effects that are color sensitive.
|
||||
/// As of 2/16/24, only applies to progress bar colors.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> AccessibilityColorblindFriendly =
|
||||
CVarDef.Create("accessibility.colorblind_friendly", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
}
|
||||
39
Content.Shared/CCVar/CCVars.Admin.Ahelp.cs
Normal file
39
Content.Shared/CCVar/CCVars.Admin.Ahelp.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Ahelp rate limit values are accounted in periods of this size (seconds).
|
||||
/// After the period has passed, the count resets.
|
||||
/// </summary>
|
||||
/// <seealso cref="AhelpRateLimitCount"/>
|
||||
public static readonly CVarDef<float> AhelpRateLimitPeriod =
|
||||
CVarDef.Create("ahelp.rate_limit_period", 2f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How many ahelp messages are allowed in a single rate limit period.
|
||||
/// </summary>
|
||||
/// <seealso cref="AhelpRateLimitPeriod"/>
|
||||
public static readonly CVarDef<int> AhelpRateLimitCount =
|
||||
CVarDef.Create("ahelp.rate_limit_count", 10, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should the administrator's position be displayed in ahelp.
|
||||
/// If it is is false, only the admin's ckey will be displayed in the ahelp.
|
||||
/// </summary>
|
||||
/// <seealso cref="AdminUseCustomNamesAdminRank"/>
|
||||
/// <seealso cref="AhelpAdminPrefixWebhook"/>
|
||||
public static readonly CVarDef<bool> AhelpAdminPrefix =
|
||||
CVarDef.Create("ahelp.admin_prefix", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should the administrator's position be displayed in the webhook.
|
||||
/// If it is is false, only the admin's ckey will be displayed in webhook.
|
||||
/// </summary>
|
||||
/// <seealso cref="AdminUseCustomNamesAdminRank"/>
|
||||
/// <seealso cref="AhelpAdminPrefix"/>
|
||||
public static readonly CVarDef<bool> AhelpAdminPrefixWebhook =
|
||||
CVarDef.Create("ahelp.admin_prefix_webhook", false, CVar.SERVERONLY);
|
||||
}
|
||||
42
Content.Shared/CCVar/CCVars.Admin.Logs.cs
Normal file
42
Content.Shared/CCVar/CCVars.Admin.Logs.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls if admin logs are enabled. Highly recommended to shut this off for development.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> AdminLogsEnabled =
|
||||
CVarDef.Create("adminlogs.enabled", true, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<float> AdminLogsQueueSendDelay =
|
||||
CVarDef.Create("adminlogs.queue_send_delay_seconds", 5f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// When to skip the waiting time to save in-round admin logs, if no admin logs are currently being saved
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> AdminLogsQueueMax =
|
||||
CVarDef.Create("adminlogs.queue_max", 5000, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// When to skip the waiting time to save pre-round admin logs, if no admin logs are currently being saved
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> AdminLogsPreRoundQueueMax =
|
||||
CVarDef.Create("adminlogs.pre_round_queue_max", 5000, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// When to start dropping logs
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> AdminLogsDropThreshold =
|
||||
CVarDef.Create("adminlogs.drop_threshold", 20000, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How many logs to send to the client at once
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> AdminLogsClientBatchSize =
|
||||
CVarDef.Create("adminlogs.client_batch_size", 1000, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> AdminLogsServerName =
|
||||
CVarDef.Create("adminlogs.server_name", "unknown", CVar.SERVERONLY);
|
||||
}
|
||||
18
Content.Shared/CCVar/CCVars.Admin.Rules.cs
Normal file
18
Content.Shared/CCVar/CCVars.Admin.Rules.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Time that players have to wait before rules can be accepted.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> RulesWaitTime =
|
||||
CVarDef.Create("rules.time", 45f, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Don't show rules to localhost/loopback interface.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> RulesExemptLocal =
|
||||
CVarDef.Create("rules.exempt_local", true, CVar.SERVERONLY);
|
||||
}
|
||||
163
Content.Shared/CCVar/CCVars.Admin.cs
Normal file
163
Content.Shared/CCVar/CCVars.Admin.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool> AdminAnnounceLogin =
|
||||
CVarDef.Create("admin.announce_login", true, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<bool> AdminAnnounceLogout =
|
||||
CVarDef.Create("admin.announce_logout", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The token used to authenticate with the admin API. Leave empty to disable the admin API. This is a secret! Do not share!
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> AdminApiToken =
|
||||
CVarDef.Create("admin.api_token", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// Should users be able to see their own notes? Admins will be able to see and set notes regardless
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> SeeOwnNotes =
|
||||
CVarDef.Create("admin.see_own_notes", false, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Should the server play a quick sound to the active admins whenever a new player joins?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> AdminNewPlayerJoinSound =
|
||||
CVarDef.Create("admin.new_player_join_sound", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The amount of days before the note starts fading. It will slowly lose opacity until it reaches stale. Set to 0 to disable.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<double> NoteFreshDays =
|
||||
CVarDef.Create("admin.note_fresh_days", 91.31055, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// The amount of days before the note completely fades, and can only be seen by admins if they press "see more notes". Set to 0
|
||||
/// if you want the note to immediately disappear without fading.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<double> NoteStaleDays =
|
||||
CVarDef.Create("admin.note_stale_days", 365.2422, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// How much time does the user have to wait in seconds before confirming that they saw an admin message?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> MessageWaitTime =
|
||||
CVarDef.Create("admin.message_wait_time", 3f, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Default severity for role bans
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> RoleBanDefaultSeverity =
|
||||
CVarDef.Create("admin.role_ban_default_severity", "medium", CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Default severity for department bans
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DepartmentBanDefaultSeverity =
|
||||
CVarDef.Create("admin.department_ban_default_severity", "medium", CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Default severity for server bans
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> ServerBanDefaultSeverity =
|
||||
CVarDef.Create("admin.server_ban_default_severity", "High", CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether a server ban will ban the player's ip by default.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ServerBanIpBanDefault =
|
||||
CVarDef.Create("admin.server_ban_ip_ban_default", true, CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether a server ban will ban the player's hardware id by default.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ServerBanHwidBanDefault =
|
||||
CVarDef.Create("admin.server_ban_hwid_ban_default", true, CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use details from last connection for ip/hwid in the BanPanel.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ServerBanUseLastDetails =
|
||||
CVarDef.Create("admin.server_ban_use_last_details", true, CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to erase a player's chat messages and their entity from the game when banned.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ServerBanErasePlayer =
|
||||
CVarDef.Create("admin.server_ban_erase_player", false, CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Minimum players sharing a connection required to create an alert. -1 to disable the alert.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If you set this to 0 or 1 then it will alert on every connection, so probably don't do that.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> AdminAlertMinPlayersSharingConnection =
|
||||
CVarDef.Create("admin.alert.min_players_sharing_connection", -1, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Minimum explosion intensity to create an admin alert message. -1 to disable the alert.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> AdminAlertExplosionMinIntensity =
|
||||
CVarDef.Create("admin.alert.explosion_min_intensity", 60, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Minimum particle accelerator strength to create an admin alert message.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> AdminAlertParticleAcceleratorMinPowerState =
|
||||
CVarDef.Create("admin.alert.particle_accelerator_min_power_state", 5, CVar.SERVERONLY); // strength 4
|
||||
|
||||
/// <summary>
|
||||
/// Should the ban details in admin channel include PII? (IP, HWID, etc)
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> AdminShowPIIOnBan =
|
||||
CVarDef.Create("admin.show_pii_onban", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If an admin joins a round by reading up or using the late join button, automatically
|
||||
/// de-admin them.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> AdminDeadminOnJoin =
|
||||
CVarDef.Create("admin.deadmin_on_join", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the name the client sees in ahelps. Set empty to disable.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> AdminAhelpOverrideClientName =
|
||||
CVarDef.Create("admin.override_adminname_in_client_ahelp", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The threshold of minutes to appear as a "new player" in the ahelp menu
|
||||
/// If 0, appearing as a new player is disabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> NewPlayerThreshold =
|
||||
CVarDef.Create("admin.new_player_threshold", 0, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// How long an admin client can go without any input before being considered AFK.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AdminAfkTime =
|
||||
CVarDef.Create("admin.afk_time", 600f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If true, admins are able to connect even if
|
||||
/// <see cref="SoftMaxPlayers"/> would otherwise block regular players.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> AdminBypassMaxPlayers =
|
||||
CVarDef.Create("admin.bypass_max_players", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if custom rank names are used.
|
||||
/// If it is false, it'd use the actual rank name regardless of the individual's title.
|
||||
/// </summary>
|
||||
/// <seealso cref="AhelpAdminPrefix"/>
|
||||
/// <seealso cref="AhelpAdminPrefixWebhook"/>
|
||||
public static readonly CVarDef<bool> AdminUseCustomNamesAdminRank =
|
||||
CVarDef.Create("admin.use_custom_names_admin_rank", true, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<bool> BanHardwareIds =
|
||||
CVarDef.Create("ban.hardware_ids", true, CVar.SERVERONLY);
|
||||
}
|
||||
153
Content.Shared/CCVar/CCVars.Atmos.cs
Normal file
153
Content.Shared/CCVar/CCVars.Atmos.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether gas differences will move entities.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> SpaceWind =
|
||||
CVarDef.Create("atmos.space_wind", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Divisor from maxForce (pressureDifference * 2.25f) to force applied on objects.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> SpaceWindPressureForceDivisorThrow =
|
||||
CVarDef.Create("atmos.space_wind_pressure_force_divisor_throw", 15f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Divisor from maxForce (pressureDifference * 2.25f) to force applied on objects.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> SpaceWindPressureForceDivisorPush =
|
||||
CVarDef.Create("atmos.space_wind_pressure_force_divisor_push", 2500f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum velocity (not force) that may be applied to an object by atmospheric pressure differences.
|
||||
/// Useful to prevent clipping through objects.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> SpaceWindMaxVelocity =
|
||||
CVarDef.Create("atmos.space_wind_max_velocity", 30f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum force that may be applied to an object by pushing (i.e. not throwing) atmospheric pressure differences.
|
||||
/// A "throwing" atmospheric pressure difference ignores this limit, but not the max. velocity limit.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> SpaceWindMaxPushForce =
|
||||
CVarDef.Create("atmos.space_wind_max_push_force", 20f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether monstermos tile equalization is enabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> MonstermosEqualization =
|
||||
CVarDef.Create("atmos.monstermos_equalization", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether monstermos explosive depressurization is enabled.
|
||||
/// Needs <see cref="MonstermosEqualization"/> to be enabled to work.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> MonstermosDepressurization =
|
||||
CVarDef.Create("atmos.monstermos_depressurization", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether monstermos explosive depressurization will rip tiles..
|
||||
/// Needs <see cref="MonstermosEqualization"/> and <see cref="MonstermosDepressurization"/> to be enabled to work.
|
||||
/// WARNING: This cvar causes MAJOR contrast issues, and usually tends to make any spaced scene look very cluttered.
|
||||
/// This not only usually looks strange, but can also reduce playability for people with impaired vision. Please think twice before enabling this on your server.
|
||||
/// Also looks weird on slow spacing for unrelated reasons. If you do want to enable this, you should probably turn on instaspacing.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> MonstermosRipTiles =
|
||||
CVarDef.Create("atmos.monstermos_rip_tiles", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether explosive depressurization will cause the grid to gain an impulse.
|
||||
/// Needs <see cref="MonstermosEqualization"/> and <see cref="MonstermosDepressurization"/> to be enabled to work.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> AtmosGridImpulse =
|
||||
CVarDef.Create("atmos.grid_impulse", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// What fraction of air from a spaced tile escapes every tick.
|
||||
/// 1.0 for instant spacing, 0.2 means 20% of remaining air lost each time
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AtmosSpacingEscapeRatio =
|
||||
CVarDef.Create("atmos.mmos_spacing_speed", 0.15f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Minimum amount of air allowed on a spaced tile before it is reset to 0 immediately in kPa
|
||||
/// Since the decay due to SpacingEscapeRatio follows a curve, it would never reach 0.0 exactly
|
||||
/// unless we truncate it somewhere.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AtmosSpacingMinGas =
|
||||
CVarDef.Create("atmos.mmos_min_gas", 2.0f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How much wind can go through a single tile before that tile doesn't depressurize itself
|
||||
/// (I.e spacing is limited in large rooms heading into smaller spaces)
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AtmosSpacingMaxWind =
|
||||
CVarDef.Create("atmos.mmos_max_wind", 500f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether atmos superconduction is enabled.
|
||||
/// </summary>
|
||||
/// <remarks> Disabled by default, superconduction is awful. </remarks>
|
||||
public static readonly CVarDef<bool> Superconduction =
|
||||
CVarDef.Create("atmos.superconduction", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Heat loss per tile due to radiation at 20 degC, in W.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> SuperconductionTileLoss =
|
||||
CVarDef.Create("atmos.superconduction_tile_loss", 30f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether excited groups will be processed and created.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ExcitedGroups =
|
||||
CVarDef.Create("atmos.excited_groups", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether all tiles in an excited group will clear themselves once being exposed to space.
|
||||
/// Similar to <see cref="MonstermosDepressurization"/>, without none of the tile ripping or
|
||||
/// things being thrown around very violently.
|
||||
/// Needs <see cref="ExcitedGroups"/> to be enabled to work.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ExcitedGroupsSpaceIsAllConsuming =
|
||||
CVarDef.Create("atmos.excited_groups_space_is_all_consuming", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Maximum time in milliseconds that atmos can take processing.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AtmosMaxProcessTime =
|
||||
CVarDef.Create("atmos.max_process_time", 3f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Atmos tickrate in TPS. Atmos processing will happen every 1/TPS seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AtmosTickRate =
|
||||
CVarDef.Create("atmos.tickrate", 15f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Scale factor for how fast things happen in our atmosphere
|
||||
/// simulation compared to real life. 1x means pumps run at 1x
|
||||
/// speed. Players typically expect things to happen faster
|
||||
/// in-game.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AtmosSpeedup =
|
||||
CVarDef.Create("atmos.speedup", 8f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Like atmos.speedup, but only for gas and reaction heat values. 64x means
|
||||
/// gases heat up and cool down 64x faster than real life.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AtmosHeatScale =
|
||||
CVarDef.Create("atmos.heat_scale", 8f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Maximum explosion radius for explosions caused by bursting a gas tank ("max caps").
|
||||
/// Setting this to zero disables the explosion but still allows the tank to burst and leak.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AtmosTankFragment =
|
||||
CVarDef.Create("atmos.max_explosion_range", 26f, CVar.SERVERONLY);
|
||||
}
|
||||
61
Content.Shared/CCVar/CCVars.Audio.cs
Normal file
61
Content.Shared/CCVar/CCVars.Audio.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// How long we'll wait until re-sampling nearby objects for ambience. Should be pretty fast, but doesn't have to match the tick rate.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AmbientCooldown =
|
||||
CVarDef.Create("ambience.cooldown", 0.1f, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How large of a range to sample for ambience.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AmbientRange =
|
||||
CVarDef.Create("ambience.range", 8f, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Maximum simultaneous ambient sounds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> MaxAmbientSources =
|
||||
CVarDef.Create("ambience.max_sounds", 16, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The minimum value the user can set for ambience.max_sounds
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> MinMaxAmbientSourcesConfigured =
|
||||
CVarDef.Create("ambience.min_max_sounds_configured", 16, CVar.REPLICATED | CVar.SERVER | CVar.CHEAT);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum value the user can set for ambience.max_sounds
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> MaxMaxAmbientSourcesConfigured =
|
||||
CVarDef.Create("ambience.max_max_sounds_configured", 64, CVar.REPLICATED | CVar.SERVER | CVar.CHEAT);
|
||||
|
||||
/// <summary>
|
||||
/// Ambience volume.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AmbienceVolume =
|
||||
CVarDef.Create("ambience.volume", 1.5f, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Ambience music volume.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AmbientMusicVolume =
|
||||
CVarDef.Create("ambience.music_volume", 1.5f, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Lobby / round end music volume.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> LobbyMusicVolume =
|
||||
CVarDef.Create("ambience.lobby_music_volume", 0.50f, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// UI volume.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> InterfaceVolume =
|
||||
CVarDef.Create("audio.interface_volume", 0.50f, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
}
|
||||
26
Content.Shared/CCVar/CCVars.Chat.Looc.cs
Normal file
26
Content.Shared/CCVar/CCVars.Chat.Looc.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool> LoocEnabled =
|
||||
CVarDef.Create("looc.enabled", true, CVar.NOTIFY | CVar.REPLICATED);
|
||||
|
||||
public static readonly CVarDef<bool> AdminLoocEnabled =
|
||||
CVarDef.Create("looc.enabled_admin", true, CVar.NOTIFY);
|
||||
|
||||
/// <summary>
|
||||
/// True: Dead players can use LOOC
|
||||
/// False: Dead player LOOC gets redirected to dead chat
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> DeadLoocEnabled =
|
||||
CVarDef.Create("looc.enabled_dead", false, CVar.NOTIFY | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// True: Crit players can use LOOC
|
||||
/// False: Crit player LOOC gets redirected to dead chat
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> CritLoocEnabled =
|
||||
CVarDef.Create("looc.enabled_crit", false, CVar.NOTIFY | CVar.REPLICATED);
|
||||
}
|
||||
27
Content.Shared/CCVar/CCVars.Chat.Ooc.cs
Normal file
27
Content.Shared/CCVar/CCVars.Chat.Ooc.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool>
|
||||
OocEnabled = CVarDef.Create("ooc.enabled", true, CVar.NOTIFY | CVar.REPLICATED);
|
||||
|
||||
public static readonly CVarDef<bool> AdminOocEnabled =
|
||||
CVarDef.Create("ooc.enabled_admin", true, CVar.NOTIFY);
|
||||
|
||||
/// <summary>
|
||||
/// If true, whenever OOC is disabled the Discord OOC relay will also be disabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> DisablingOOCDisablesRelay =
|
||||
CVarDef.Create("ooc.disabling_ooc_disables_relay", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not OOC chat should be enabled during a round.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> OocEnableDuringRound =
|
||||
CVarDef.Create("ooc.enable_during_round", false, CVar.NOTIFY | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<bool> ShowOocPatronColor =
|
||||
CVarDef.Create("ooc.show_ooc_patron_color", true, CVar.ARCHIVE | CVar.REPLICATED | CVar.CLIENT);
|
||||
}
|
||||
68
Content.Shared/CCVar/CCVars.Chat.cs
Normal file
68
Content.Shared/CCVar/CCVars.Chat.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Chat rate limit values are accounted in periods of this size (seconds).
|
||||
/// After the period has passed, the count resets.
|
||||
/// </summary>
|
||||
/// <seealso cref="ChatRateLimitCount"/>
|
||||
public static readonly CVarDef<float> ChatRateLimitPeriod =
|
||||
CVarDef.Create("chat.rate_limit_period", 2f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How many chat messages are allowed in a single rate limit period.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The total rate limit throughput per second is effectively
|
||||
/// <see cref="ChatRateLimitCount"/> divided by <see cref="ChatRateLimitCount"/>.
|
||||
/// </remarks>
|
||||
/// <seealso cref="ChatRateLimitPeriod"/>
|
||||
public static readonly CVarDef<int> ChatRateLimitCount =
|
||||
CVarDef.Create("chat.rate_limit_count", 10, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Minimum delay (in seconds) between notifying admins about chat message rate limit violations.
|
||||
/// A negative value disables admin announcements.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> ChatRateLimitAnnounceAdminsDelay =
|
||||
CVarDef.Create("chat.rate_limit_announce_admins_delay", 15, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<int> ChatMaxMessageLength =
|
||||
CVarDef.Create("chat.max_message_length", 1000, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
public static readonly CVarDef<int> ChatMaxAnnouncementLength =
|
||||
CVarDef.Create("chat.max_announcement_length", 256, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
public static readonly CVarDef<bool> ChatSanitizerEnabled =
|
||||
CVarDef.Create("chat.chat_sanitizer_enabled", true, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<bool> ChatShowTypingIndicator =
|
||||
CVarDef.Create("chat.show_typing_indicator", true, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<bool> ChatEnableFancyBubbles =
|
||||
CVarDef.Create("chat.enable_fancy_bubbles",
|
||||
true,
|
||||
CVar.CLIENTONLY | CVar.ARCHIVE,
|
||||
"Toggles displaying fancy speech bubbles, which display the speaking character's name.");
|
||||
|
||||
public static readonly CVarDef<bool> ChatFancyNameBackground =
|
||||
CVarDef.Create("chat.fancy_name_background",
|
||||
false,
|
||||
CVar.CLIENTONLY | CVar.ARCHIVE,
|
||||
"Toggles displaying a background under the speaking character's name.");
|
||||
|
||||
/// <summary>
|
||||
/// A message broadcast to each player that joins the lobby.
|
||||
/// May be changed by admins ingame through use of the "set-motd" command.
|
||||
/// In this case the new value, if not empty, is broadcast to all connected players and saved between rounds.
|
||||
/// May be requested by any player through use of the "get-motd" command.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> MOTD =
|
||||
CVarDef.Create("chat.motd",
|
||||
"",
|
||||
CVar.SERVER | CVar.SERVERONLY | CVar.ARCHIVE,
|
||||
"A message broadcast to each player that joins the lobby.");
|
||||
}
|
||||
35
Content.Shared/CCVar/CCVars.Config.cs
Normal file
35
Content.Shared/CCVar/CCVars.Config.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
// These are server-only for now since I don't foresee a client use yet,
|
||||
// and I don't wanna have to start coming up with like .client suffixes and stuff like that.
|
||||
|
||||
/// <summary>
|
||||
/// Configuration presets to load during startup.
|
||||
/// Multiple presets can be separated by comma and are loaded in order.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Loaded presets must be located under the <c>ConfigPresets/</c> resource directory and end with the <c>.toml</c> extension.
|
||||
/// Only the file name (without extension) must be given for this variable.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<string> ConfigPresets =
|
||||
CVarDef.Create("config.presets", "", CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to load the preset development CVars.
|
||||
/// This disables some things like lobby to make development easier.
|
||||
/// Even when true, these are only loaded if the game is compiled with <c>DEVELOPMENT</c> set.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ConfigPresetDevelopment =
|
||||
CVarDef.Create("config.preset_development", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to load the preset debug CVars.
|
||||
/// Even when true, these are only loaded if the game is compiled with <c>DEBUG</c> set.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ConfigPresetDebug =
|
||||
CVarDef.Create("config.preset_debug", true, CVar.SERVERONLY);
|
||||
}
|
||||
15
Content.Shared/CCVar/CCVars.Console.cs
Normal file
15
Content.Shared/CCVar/CCVars.Console.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool> ConsoleLoginLocal =
|
||||
CVarDef.Create("console.loginlocal", true, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Automatically log in the given user as host, equivalent to the <c>promotehost</c> command.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> ConsoleLoginHostUser =
|
||||
CVarDef.Create("console.login_host_user", "", CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
}
|
||||
24
Content.Shared/CCVar/CCVars.Crewmanifest.cs
Normal file
24
Content.Shared/CCVar/CCVars.Crewmanifest.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Setting this allows a crew manifest to be opened from any window
|
||||
/// that has a crew manifest button, and sends the correct message.
|
||||
/// If this is false, only in-game entities will allow you to see
|
||||
/// the crew manifest, if the functionality is coded in.
|
||||
/// Having administrator priveledge ignores this, but will still
|
||||
/// hide the button in UI windows.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> CrewManifestWithoutEntity =
|
||||
CVarDef.Create("crewmanifest.no_entity", true, CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Setting this allows the crew manifest to be viewed from 'unsecure'
|
||||
/// entities, such as the PDA.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> CrewManifestUnsecure =
|
||||
CVarDef.Create("crewmanifest.unsecure", true, CVar.REPLICATED);
|
||||
}
|
||||
77
Content.Shared/CCVar/CCVars.Database.cs
Normal file
77
Content.Shared/CCVar/CCVars.Database.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
#if DEBUG
|
||||
private const int DefaultSqliteDelay = 1;
|
||||
#else
|
||||
private const int DefaultSqliteDelay = 0;
|
||||
#endif
|
||||
|
||||
public static readonly CVarDef<string> DatabaseEngine =
|
||||
CVarDef.Create("database.engine", "sqlite", CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> DatabaseSqliteDbPath =
|
||||
CVarDef.Create("database.sqlite_dbpath", "preferences.db", CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Milliseconds to asynchronously delay all SQLite database acquisitions with.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Defaults to 1 on DEBUG, 0 on RELEASE.
|
||||
/// This is intended to help catch .Result deadlock bugs that only happen on postgres
|
||||
/// (because SQLite is not actually asynchronous normally)
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> DatabaseSqliteDelay =
|
||||
CVarDef.Create("database.sqlite_delay", DefaultSqliteDelay, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Amount of concurrent SQLite database operations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that SQLite is not a properly asynchronous database and also has limited read/write concurrency.
|
||||
/// Increasing this number may allow more concurrent reads, but it probably won't matter much.
|
||||
/// SQLite operations are normally ran on the thread pool, which may cause thread pool starvation if the concurrency is too high.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> DatabaseSqliteConcurrency =
|
||||
CVarDef.Create("database.sqlite_concurrency", 3, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> DatabasePgHost =
|
||||
CVarDef.Create("database.pg_host", "localhost", CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<int> DatabasePgPort =
|
||||
CVarDef.Create("database.pg_port", 5432, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> DatabasePgDatabase =
|
||||
CVarDef.Create("database.pg_database", "ss14", CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> DatabasePgUsername =
|
||||
CVarDef.Create("database.pg_username", "postgres", CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> DatabasePgPassword =
|
||||
CVarDef.Create("database.pg_password", "", CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// Max amount of concurrent Postgres database operations.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> DatabasePgConcurrency =
|
||||
CVarDef.Create("database.pg_concurrency", 8, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Milliseconds to asynchronously delay all PostgreSQL database operations with.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is intended for performance testing. It works different from <see cref="DatabaseSqliteDelay"/>,
|
||||
/// as the lag is applied after acquiring the database lock.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> DatabasePgFakeLag =
|
||||
CVarDef.Create("database.pg_fake_lag", 0, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Basically only exists for integration tests to avoid race conditions.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> DatabaseSynchronous =
|
||||
CVarDef.Create("database.sync", false, CVar.SERVERONLY);
|
||||
}
|
||||
61
Content.Shared/CCVar/CCVars.Discord.cs
Normal file
61
Content.Shared/CCVar/CCVars.Discord.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// The role that will get mentioned if a new SOS ahelp comes in.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordAhelpMention =
|
||||
CVarDef.Create("discord.on_call_ping", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// URL of the discord webhook to relay unanswered ahelp messages.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordOnCallWebhook =
|
||||
CVarDef.Create("discord.on_call_webhook", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// URL of the Discord webhook which will relay all ahelp messages.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordAHelpWebhook =
|
||||
CVarDef.Create("discord.ahelp_webhook", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// The server icon to use in the Discord ahelp embed footer.
|
||||
/// Valid values are specified at https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordAHelpFooterIcon =
|
||||
CVarDef.Create("discord.ahelp_footer_icon", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The avatar to use for the webhook. Should be an URL.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordAHelpAvatar =
|
||||
CVarDef.Create("discord.ahelp_avatar", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// URL of the Discord webhook which will relay all custom votes. If left empty, disables the webhook.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordVoteWebhook =
|
||||
CVarDef.Create("discord.vote_webhook", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// URL of the Discord webhook which will relay all votekick votes. If left empty, disables the webhook.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordVotekickWebhook =
|
||||
CVarDef.Create("discord.votekick_webhook", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// URL of the Discord webhook which will relay round restart messages.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordRoundUpdateWebhook =
|
||||
CVarDef.Create("discord.round_update_webhook", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// Role id for the Discord webhook to ping when the round ends.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordRoundEndRoleWebhook =
|
||||
CVarDef.Create("discord.round_end_role", string.Empty, CVar.SERVERONLY);
|
||||
}
|
||||
12
Content.Shared/CCVar/CCVars.Events.cs
Normal file
12
Content.Shared/CCVar/CCVars.Events.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls if the game should run station events
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
EventsEnabled = CVarDef.Create("events.enabled", true, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
}
|
||||
108
Content.Shared/CCVar/CCVars.Explosion.cs
Normal file
108
Content.Shared/CCVar/CCVars.Explosion.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// How many tiles the explosion system will process per tick
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Setting this too high will put a large load on a single tick. Setting this too low will lead to
|
||||
/// unnaturally "slow" explosions.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> ExplosionTilesPerTick =
|
||||
CVarDef.Create("explosion.tiles_per_tick", 100, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Upper limit on the size of an explosion before physics-throwing is disabled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Large nukes tend to generate a lot of shrapnel that flies through space. This can functionally cripple
|
||||
/// the server TPS for a while after an explosion (or even during, if the explosion is processed
|
||||
/// incrementally.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> ExplosionThrowLimit =
|
||||
CVarDef.Create("explosion.throw_limit", 400, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If this is true, explosion processing will pause the NodeGroupSystem to pause updating.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This only takes effect if an explosion needs more than one tick to process (i.e., covers more than <see
|
||||
/// cref="ExplosionTilesPerTick"/> tiles). If this is not enabled, the node-system will rebuild its graph
|
||||
/// every tick as the explosion shreds the station, causing significant slowdown.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<bool> ExplosionSleepNodeSys =
|
||||
CVarDef.Create("explosion.node_sleep", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Upper limit on the total area that an explosion can affect before the neighbor-finding algorithm just
|
||||
/// stops. Defaults to a 60-rile radius explosion.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Actual area may be larger, as it currently doesn't terminate mid neighbor finding. I.e., area may be that of a ~51 tile radius circle instead.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> ExplosionMaxArea =
|
||||
CVarDef.Create("explosion.max_area", (int)3.14f * 256 * 256, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Upper limit on the number of neighbor finding steps for the explosion system neighbor-finding algorithm.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Effectively places an upper limit on the range that any explosion can have. In the vast majority of
|
||||
/// instances, <see cref="ExplosionMaxArea"/> will likely be hit before this becomes a limiting factor.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> ExplosionMaxIterations =
|
||||
CVarDef.Create("explosion.max_iterations", 500, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Max Time in milliseconds to spend processing explosions every tick.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This time limiting is not perfectly implemented. Firstly, a significant chunk of processing time happens
|
||||
/// due to queued entity deletions, which happen outside of the system update code. Secondly, explosion
|
||||
/// spawning cannot currently be interrupted & resumed, and may lead to exceeding this time limit.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<float> ExplosionMaxProcessingTime =
|
||||
CVarDef.Create("explosion.max_tick_time", 7f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If the explosion is being processed incrementally over several ticks, this variable determines whether
|
||||
/// updating the grid tiles should be done incrementally at the end of every tick, or only once the explosion has finished processing.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The most notable consequence of this change is that explosions will only punch a hole in the station &
|
||||
/// create a vacumm once they have finished exploding. So airlocks will no longer slam shut as the explosion
|
||||
/// expands, just suddenly at the end.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<bool> ExplosionIncrementalTileBreaking =
|
||||
CVarDef.Create("explosion.incremental_tile", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// This determines for how many seconds an explosion should stay visible once it has finished expanding.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> ExplosionPersistence =
|
||||
CVarDef.Create("explosion.persistence", 1.0f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If an explosion covers a larger area than this number, the damaging/processing will always start during
|
||||
/// the next tick, instead of during the same tick that the explosion was generated in.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This value can be used to ensure that for large explosions the area/tile calculation and the explosion
|
||||
/// processing/damaging occurs in separate ticks. This helps reduce the single-tick lag if both <see
|
||||
/// cref="ExplosionMaxProcessingTime"/> and <see cref="ExplosionTilesPerTick"/> are large. I.e., instead of
|
||||
/// a single tick explosion, this cvar allows for a configuration that results in a two-tick explosion,
|
||||
/// though most of the computational cost is still in the second tick.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> ExplosionSingleTickAreaLimit =
|
||||
CVarDef.Create("explosion.single_tick_area_limit", 400, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not explosions are allowed to create tiles that have
|
||||
/// <see cref="ContentTileDefinition.MapAtmosphere"/> set to true.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ExplosionCanCreateVacuum =
|
||||
CVarDef.Create("explosion.can_create_vacuum", true, CVar.SERVERONLY);
|
||||
}
|
||||
60
Content.Shared/CCVar/CCVars.Game.Infolinks.cs
Normal file
60
Content.Shared/CCVar/CCVars.Game.Infolinks.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Link to Discord server to show in the launcher.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksDiscord =
|
||||
CVarDef.Create("infolinks.discord", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Link to website to show in the launcher.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksForum =
|
||||
CVarDef.Create("infolinks.forum", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Link to GitHub page to show in the launcher.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksGithub =
|
||||
CVarDef.Create("infolinks.github", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Link to website to show in the launcher.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksWebsite =
|
||||
CVarDef.Create("infolinks.website", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Link to wiki to show in the launcher.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksWiki =
|
||||
CVarDef.Create("infolinks.wiki", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Link to Patreon. Not shown in the launcher currently.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksPatreon =
|
||||
CVarDef.Create("infolinks.patreon", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Link to the bug report form.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksBugReport =
|
||||
CVarDef.Create("infolinks.bug_report", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Link to site handling ban appeals. Shown in ban disconnect messages.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksAppeal =
|
||||
CVarDef.Create("infolinks.appeal", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Link to Telegram channel to show in the launcher.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> InfoLinksTelegram =
|
||||
CVarDef.Create("infolinks.telegram", "", CVar.SERVER | CVar.REPLICATED);
|
||||
}
|
||||
336
Content.Shared/CCVar/CCVars.Game.cs
Normal file
336
Content.Shared/CCVar/CCVars.Game.cs
Normal file
@@ -0,0 +1,336 @@
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Disables most functionality in the GameTicker.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameDummyTicker = CVarDef.Create("game.dummyticker", false, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Controls if the lobby is enabled. If it is not, and there are no available jobs, you may get stuck on a black screen.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameLobbyEnabled = CVarDef.Create("game.lobbyenabled", true, CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Controls the duration of the lobby timer in seconds. Defaults to 2 minutes and 30 seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
GameLobbyDuration = CVarDef.Create("game.lobbyduration", 150, CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Controls if players can latejoin at all.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameDisallowLateJoins = CVarDef.Create("game.disallowlatejoins", false, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Controls the default game preset.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string>
|
||||
GameLobbyDefaultPreset = CVarDef.Create("game.defaultpreset", "secret", CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Controls if the game can force a different preset if the current preset's criteria are not met.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameLobbyFallbackEnabled = CVarDef.Create("game.fallbackenabled", true, CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// The preset for the game to fall back to if the selected preset could not be used, and fallback is enabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string>
|
||||
GameLobbyFallbackPreset = CVarDef.Create("game.fallbackpreset", "Traitor,Extended", CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Controls if people can win the game in Suspicion or Deathmatch.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameLobbyEnableWin = CVarDef.Create("game.enablewin", true, CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Controls the maximum number of character slots a player is allowed to have.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
GameMaxCharacterSlots = CVarDef.Create("game.maxcharacterslots", 30, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Controls the game map prototype to load. SS14 stores these prototypes in Prototypes/Maps.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string>
|
||||
GameMap = CVarDef.Create("game.map", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether to use world persistence or not.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
UsePersistence = CVarDef.Create("game.usepersistence", false, CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// If world persistence is used, what map prototype should be initially loaded.
|
||||
/// If the save file exists, it replaces MapPath but everything else stays the same (station name and such).
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string>
|
||||
PersistenceMap = CVarDef.Create("game.persistencemap", "Empty", CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Prototype to use for map pool.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string>
|
||||
GameMapPool = CVarDef.Create("game.map_pool", "DefaultMapPool", CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The depth of the queue used to calculate which map is next in rotation.
|
||||
/// This is how long the game "remembers" that some map was put in play. Default is 16 rounds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
GameMapMemoryDepth = CVarDef.Create("game.map_memory_depth", 16, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Is map rotation enabled?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameMapRotation = CVarDef.Create("game.map_rotation", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If roles should be restricted based on time.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameRoleTimers = CVarDef.Create("game.role_timers", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Override default role requirements using a <see cref="JobRequirementOverridePrototype"/>
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string>
|
||||
GameRoleTimerOverride = CVarDef.Create("game.role_timer_override", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// If roles should be restricted based on whether or not they are whitelisted.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameRoleWhitelist = CVarDef.Create("game.role_whitelist", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not disconnecting inside of a cryopod should remove the character or just store them until they reconnect.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
GameCryoSleepRejoining = CVarDef.Create("game.cryo_sleep_rejoining", false, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// When enabled, guests will be assigned permanent UIDs and will have their preferences stored.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GamePersistGuests =
|
||||
CVarDef.Create("game.persistguests", true, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<bool> GameDiagonalMovement =
|
||||
CVarDef.Create("game.diagonalmovement", true, CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<int> SoftMaxPlayers =
|
||||
CVarDef.Create("game.soft_max_players", 30, CVar.SERVERONLY | CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// If a player gets denied connection to the server,
|
||||
/// how long they are forced to wait before attempting to reconnect.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> GameServerFullReconnectDelay =
|
||||
CVarDef.Create("game.server_full_reconnect_delay", 30, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not panic bunker is currently enabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> PanicBunkerEnabled =
|
||||
CVarDef.Create("game.panic_bunker.enabled", false, CVar.NOTIFY | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the panic bunker will disable when an admin comes online.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> PanicBunkerDisableWithAdmins =
|
||||
CVarDef.Create("game.panic_bunker.disable_with_admins", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the panic bunker will enable when no admins are online.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> PanicBunkerEnableWithoutAdmins =
|
||||
CVarDef.Create("game.panic_bunker.enable_without_admins", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the panic bunker will count deadminned admins for
|
||||
/// <see cref="PanicBunkerDisableWithAdmins"/> and
|
||||
/// <see cref="PanicBunkerEnableWithoutAdmins"/>
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> PanicBunkerCountDeadminnedAdmins =
|
||||
CVarDef.Create("game.panic_bunker.count_deadminned_admins", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Show reason of disconnect for user or not.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> PanicBunkerShowReason =
|
||||
CVarDef.Create("game.panic_bunker.show_reason", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Minimum age of the account (from server's PoV, so from first-seen date) in minutes.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> PanicBunkerMinAccountAge =
|
||||
CVarDef.Create("game.panic_bunker.min_account_age", 1440, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Minimal overall played time.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> PanicBunkerMinOverallMinutes =
|
||||
CVarDef.Create("game.panic_bunker.min_overall_minutes", 600, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// A custom message that will be used for connections denied to the panic bunker
|
||||
/// If not empty, then will overwrite <see cref="PanicBunkerShowReason"/>
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> PanicBunkerCustomReason =
|
||||
CVarDef.Create("game.panic_bunker.custom_reason", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Allow bypassing the panic bunker if the user is whitelisted.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> BypassBunkerWhitelist =
|
||||
CVarDef.Create("game.panic_bunker.whitelisted_can_bypass", true, CVar.SERVERONLY);
|
||||
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Whether the baby jail is currently enabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> BabyJailEnabled =
|
||||
CVarDef.Create("game.baby_jail.enabled", false, CVar.NOTIFY | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Show reason of disconnect for user or not.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> BabyJailShowReason =
|
||||
CVarDef.Create("game.baby_jail.show_reason", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Maximum age of the account (from server's PoV, so from first-seen date) in minutes that can access baby
|
||||
/// jailed servers.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> BabyJailMaxAccountAge =
|
||||
CVarDef.Create("game.baby_jail.max_account_age", 1440, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Maximum overall played time allowed to access baby jailed servers.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> BabyJailMaxOverallMinutes =
|
||||
CVarDef.Create("game.baby_jail.max_overall_minutes", 120, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// A custom message that will be used for connections denied due to the baby jail.
|
||||
/// If not empty, then will overwrite <see cref="BabyJailShowReason"/>
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> BabyJailCustomReason =
|
||||
CVarDef.Create("game.baby_jail.custom_reason", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Allow bypassing the baby jail if the user is whitelisted.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> BypassBabyJailWhitelist =
|
||||
CVarDef.Create("game.baby_jail.whitelisted_can_bypass", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Make people bonk when trying to climb certain objects like tables.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GameTableBonk =
|
||||
CVarDef.Create("game.table_bonk", false, CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not status icons are rendered for everyone.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GlobalStatusIconsEnabled =
|
||||
CVarDef.Create("game.global_status_icons_enabled", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not status icons are rendered on this specific client.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> LocalStatusIconsEnabled =
|
||||
CVarDef.Create("game.local_status_icons_enabled", true, CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not coordinates on the Debug overlay should only be available to admins.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> DebugCoordinatesAdminOnly =
|
||||
CVarDef.Create("game.debug_coordinates_admin_only", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
#if EXCEPTION_TOLERANCE
|
||||
/// <summary>
|
||||
/// Amount of times round start must fail before the server is shut down.
|
||||
/// Set to 0 or a negative number to disable.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> RoundStartFailShutdownCount =
|
||||
CVarDef.Create("game.round_start_fail_shutdown_count", 5, CVar.SERVERONLY | CVar.SERVER);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Delay between station alert level changes.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> GameAlertLevelChangeDelay =
|
||||
CVarDef.Create("game.alert_level_change_delay", 30, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The time in seconds that the server should wait before restarting the round.
|
||||
/// Defaults to 2 minutes.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> RoundRestartTime =
|
||||
CVarDef.Create("game.round_restart_time", 120f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The prototype to use for secret weights.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> SecretWeightPrototype =
|
||||
CVarDef.Create("game.secret_weight_prototype", "Secret", CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The id of the sound collection to randomly choose a sound from and play when the round ends.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> RoundEndSoundCollection =
|
||||
CVarDef.Create("game.round_end_sound_collection", "RoundEnd", CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to add every player as a global override to PVS at round end.
|
||||
/// This will allow all players to see their clothing in the round screen player list screen,
|
||||
/// but may cause lag during round end with very high player counts.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> RoundEndPVSOverrides =
|
||||
CVarDef.Create("game.round_end_pvs_overrides", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If true, players can place objects onto tabletop games like chess boards.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This feature is currently highly abusable and can easily be used to crash the server,
|
||||
/// so it's off by default.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<bool> GameTabletopPlace =
|
||||
CVarDef.Create("game.tabletop_place", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If true, contraband severity can be viewed in the examine menu
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ContrabandExamine =
|
||||
CVarDef.Create("game.contraband_examine", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Size of the lookup area for adding entities to the context menu
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> GameEntityMenuLookup =
|
||||
CVarDef.Create("game.entity_menu_lookup", 0.25f, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Should the clients window show the server hostname in the title?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GameHostnameInTitlebar =
|
||||
CVarDef.Create("game.hostname_in_titlebar", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
}
|
||||
24
Content.Shared/CCVar/CCVars.Ghost.cs
Normal file
24
Content.Shared/CCVar/CCVars.Ghost.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// The time you must spend reading the rules, before the "Request" button is enabled
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> GhostRoleTime =
|
||||
CVarDef.Create("ghost.role_time", 3f, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// If ghost role lotteries should be made near-instanteous.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GhostQuickLottery =
|
||||
CVarDef.Create("ghost.quick_lottery", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to kill the player's mob on ghosting, when it is in a critical health state.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GhostKillCrit =
|
||||
CVarDef.Create("ghost.kill_crit", true, CVar.REPLICATED | CVar.SERVER);
|
||||
}
|
||||
24
Content.Shared/CCVar/CCVars.Hud.cs
Normal file
24
Content.Shared/CCVar/CCVars.Hud.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<int> HudTheme =
|
||||
CVarDef.Create("hud.theme", 0, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<bool> HudHeldItemShow =
|
||||
CVarDef.Create("hud.held_item_show", true, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<bool> CombatModeIndicatorsPointShow =
|
||||
CVarDef.Create("hud.combat_mode_indicators_point_show", true, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<bool> LoocAboveHeadShow =
|
||||
CVarDef.Create("hud.show_looc_above_head", true, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<float> HudHeldItemOffset =
|
||||
CVarDef.Create("hud.held_item_offset", 28f, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<bool> HudFpsCounterVisible =
|
||||
CVarDef.Create("hud.fps_counter_visible", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
}
|
||||
48
Content.Shared/CCVar/CCVars.Ic.cs
Normal file
48
Content.Shared/CCVar/CCVars.Ic.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Restricts IC character names to alphanumeric chars.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> RestrictedNames =
|
||||
CVarDef.Create("ic.restricted_names", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Allows flavor text (character descriptions)
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> FlavorText =
|
||||
CVarDef.Create("ic.flavor_text", false, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a period at the end of a sentence if the sentence ends in a letter.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ChatPunctuation =
|
||||
CVarDef.Create("ic.punctuation", false, CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Enables automatically forcing IC name rules. Uppercases the first letter of the first and last words of the name
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ICNameCase =
|
||||
CVarDef.Create("ic.name_case", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not players' characters are randomly generated rather than using their selected characters in the creator.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ICRandomCharacters =
|
||||
CVarDef.Create("ic.random_characters", false, CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// A weighted random prototype used to determine the species selected for random characters.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> ICRandomSpeciesWeights =
|
||||
CVarDef.Create("ic.random_species_weights", "SpeciesWeights", CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Control displaying SSD indicators near players
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ICShowSSDIndicator =
|
||||
CVarDef.Create("ic.show_ssd_indicator", true, CVar.CLIENTONLY);
|
||||
}
|
||||
54
Content.Shared/CCVar/CCVars.Interactions.cs
Normal file
54
Content.Shared/CCVar/CCVars.Interactions.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Deadzone for drag-drop interactions.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> DragDropDeadZone =
|
||||
CVarDef.Create("control.drag_dead_zone", 12f, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Toggles whether the walking key is a toggle or a held key.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ToggleWalk =
|
||||
CVarDef.Create("control.toggle_walk", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
// The rationale behind the default limit is simply that I can easily get to 7 interactions per second by just
|
||||
// trying to spam toggle a light switch or lever (though the UseDelay component limits the actual effect of the
|
||||
// interaction). I don't want to accidentally spam admins with alerts just because somebody is spamming a
|
||||
// key manually, nor do we want to alert them just because the player is having network issues and the server
|
||||
// receives multiple interactions at once. But we also want to try catch people with modified clients that spam
|
||||
// many interactions on the same tick. Hence, a very short period, with a relatively high count.
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of interactions that a player can perform within <see cref="InteractionRateLimitCount"/> seconds
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> InteractionRateLimitCount =
|
||||
CVarDef.Create("interaction.rate_limit_count", 5, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <seealso cref="InteractionRateLimitCount"/>
|
||||
public static readonly CVarDef<float> InteractionRateLimitPeriod =
|
||||
CVarDef.Create("interaction.rate_limit_period", 0.5f, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Minimum delay (in seconds) between notifying admins about interaction rate limit violations. A negative
|
||||
/// value disables admin announcements.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> InteractionRateLimitAnnounceAdminsDelay =
|
||||
CVarDef.Create("interaction.rate_limit_announce_admins_delay", 120, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the storage UI is static and bound to the hotbar, or unbound and allowed to be dragged anywhere.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> StaticStorageUI =
|
||||
CVarDef.Create("control.static_storage_ui", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the storage window uses a transparent or opaque sprite.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> OpaqueStorageWindow =
|
||||
CVarDef.Create("control.opaque_storage_background", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
}
|
||||
24
Content.Shared/CCVar/CCVars.Interface.cs
Normal file
24
Content.Shared/CCVar/CCVars.Interface.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<string> UIClickSound =
|
||||
CVarDef.Create("interface.click_sound", "/Audio/UserInterface/click.ogg", CVar.REPLICATED);
|
||||
|
||||
public static readonly CVarDef<string> UIHoverSound =
|
||||
CVarDef.Create("interface.hover_sound", "/Audio/UserInterface/hover.ogg", CVar.REPLICATED);
|
||||
|
||||
public static readonly CVarDef<string> UILayout =
|
||||
CVarDef.Create("ui.layout", "Default", CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<string> DefaultScreenChatSize =
|
||||
CVarDef.Create("ui.default_chat_size", "", CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<string> SeparatedScreenChatSize =
|
||||
CVarDef.Create("ui.separated_chat_size", "0.6,0", CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<bool> OutlineEnabled =
|
||||
CVarDef.Create("outline.enabled", true, CVar.CLIENTONLY);
|
||||
}
|
||||
24
Content.Shared/CCVar/CCVars.Mapping.cs
Normal file
24
Content.Shared/CCVar/CCVars.Mapping.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Will mapping mode enable autosaves when it's activated?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool>
|
||||
AutosaveEnabled = CVarDef.Create("mapping.autosave", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Autosave interval in seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float>
|
||||
AutosaveInterval = CVarDef.Create("mapping.autosave_interval", 600f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Directory in server user data to save to. Saves will be inside folders in this directory.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string>
|
||||
AutosaveDirectory = CVarDef.Create("mapping.autosave_dir", "Autosaves", CVar.SERVERONLY);
|
||||
}
|
||||
18
Content.Shared/CCVar/CCVars.Midi.cs
Normal file
18
Content.Shared/CCVar/CCVars.Midi.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<int> MaxMidiEventsPerSecond =
|
||||
CVarDef.Create("midi.max_events_per_second", 1000, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<int> MaxMidiEventsPerBatch =
|
||||
CVarDef.Create("midi.max_events_per_batch", 60, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<int> MaxMidiBatchesDropped =
|
||||
CVarDef.Create("midi.max_batches_dropped", 1, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<int> MaxMidiLaggedBatches =
|
||||
CVarDef.Create("midi.max_lagged_batches", 8, CVar.SERVERONLY);
|
||||
}
|
||||
97
Content.Shared/CCVar/CCVars.Misc.cs
Normal file
97
Content.Shared/CCVar/CCVars.Misc.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool> HolidaysEnabled = CVarDef.Create("holidays.enabled", true, CVar.SERVERONLY);
|
||||
public static readonly CVarDef<bool> BrandingSteam = CVarDef.Create("branding.steam", false, CVar.CLIENTONLY);
|
||||
public static readonly CVarDef<int> EntityMenuGroupingType = CVarDef.Create("entity_menu", 0, CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should we pre-load all of the procgen atlasses.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ProcgenPreload =
|
||||
CVarDef.Create("procgen.preload", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Enabled: Cloning has 70% cost and reclaimer will refuse to reclaim corpses with souls. (For LRP).
|
||||
/// Disabled: Cloning has full biomass cost and reclaimer can reclaim corpses with souls. (Playtested and balanced for MRP+).
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> BiomassEasyMode =
|
||||
CVarDef.Create("biomass.easy_mode", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// A scale factor applied to a grid's bounds when trying to find a spot to randomly generate an anomaly.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AnomalyGenerationGridBoundsScale =
|
||||
CVarDef.Create("anomaly.generation_grid_bounds_scale", 0.6f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How long a client can go without any input before being considered AFK.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> AfkTime =
|
||||
CVarDef.Create("afk.time", 60f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Flavor limit. This is to ensure that having a large mass of flavors in
|
||||
/// some food object won't spam a user with flavors.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
FlavorLimit = CVarDef.Create("flavor.limit", 10, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> DestinationFile =
|
||||
CVarDef.Create("autogen.destination_file", "", CVar.SERVER | CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether uploaded files will be stored in the server's database.
|
||||
/// This is useful to keep "logs" on what files admins have uploaded in the past.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ResourceUploadingStoreEnabled =
|
||||
CVarDef.Create("netres.store_enabled", true, CVar.SERVER | CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Numbers of days before stored uploaded files are deleted. Set to zero or negative to disable auto-delete.
|
||||
/// This is useful to free some space automatically. Auto-deletion runs only on server boot.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> ResourceUploadingStoreDeletionDays =
|
||||
CVarDef.Create("netres.store_deletion_days", 30, CVar.SERVER | CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If a server update restart is pending, the delay after the last player leaves before we actually restart. In seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> UpdateRestartDelay =
|
||||
CVarDef.Create("update.restart_delay", 20f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If fire alarms should have all access, or if activating/resetting these
|
||||
/// should be restricted to what is dictated on a player's access card.
|
||||
/// Defaults to true.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> FireAlarmAllAccess =
|
||||
CVarDef.Create("firealarm.allaccess", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Time between play time autosaves, in seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float>
|
||||
PlayTimeSaveInterval = CVarDef.Create("playtime.save_interval", 900f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of time the entity GC can process, in ms.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> GCMaximumTimeMs =
|
||||
CVarDef.Create("entgc.maximum_time_ms", 5, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<bool> GatewayGeneratorEnabled =
|
||||
CVarDef.Create("gateway.generator_enabled", true);
|
||||
|
||||
public static readonly CVarDef<string> TippyEntity =
|
||||
CVarDef.Create("tippy.entity", "Tippy", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// The number of seconds that must pass for a single entity to be able to point at something again.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> PointingCooldownSeconds =
|
||||
CVarDef.Create("pointing.cooldown_seconds", 0.5f, CVar.SERVERONLY);
|
||||
}
|
||||
16
Content.Shared/CCVar/CCVars.NPC.cs
Normal file
16
Content.Shared/CCVar/CCVars.NPC.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<int> NPCMaxUpdates =
|
||||
CVarDef.Create("npc.max_updates", 128);
|
||||
|
||||
public static readonly CVarDef<bool> NPCEnabled = CVarDef.Create("npc.enabled", true);
|
||||
|
||||
/// <summary>
|
||||
/// Should NPCs pathfind when steering. For debug purposes.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> NPCPathfinding = CVarDef.Create("npc.pathfinding", true);
|
||||
}
|
||||
15
Content.Shared/CCVar/CCVars.Net.cs
Normal file
15
Content.Shared/CCVar/CCVars.Net.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<float> NetAtmosDebugOverlayTickRate =
|
||||
CVarDef.Create("net.atmosdbgoverlaytickrate", 3.0f);
|
||||
|
||||
public static readonly CVarDef<float> NetGasOverlayTickRate =
|
||||
CVarDef.Create("net.gasoverlaytickrate", 3.0f);
|
||||
|
||||
public static readonly CVarDef<int> GasOverlayThresholds =
|
||||
CVarDef.Create("net.gasoverlaythresholds", 20);
|
||||
}
|
||||
15
Content.Shared/CCVar/CCVars.Parallax.cs
Normal file
15
Content.Shared/CCVar/CCVars.Parallax.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool> ParallaxEnabled =
|
||||
CVarDef.Create("parallax.enabled", true, CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<bool> ParallaxDebug =
|
||||
CVarDef.Create("parallax.debug", false, CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<bool> ParallaxLowQuality =
|
||||
CVarDef.Create("parallax.low_quality", false, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
}
|
||||
27
Content.Shared/CCVar/CCVars.Physics.cs
Normal file
27
Content.Shared/CCVar/CCVars.Physics.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// When a mob is walking should its X / Y movement be relative to its parent (true) or the map (false).
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> RelativeMovement =
|
||||
CVarDef.Create("physics.relative_movement", true, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<float> TileFrictionModifier =
|
||||
CVarDef.Create("physics.tile_friction", 40.0f, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<float> StopSpeed =
|
||||
CVarDef.Create("physics.stop_speed", 0.1f, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Whether mobs can push objects like lockers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Technically client doesn't need to know about it but this may prevent a bug in the distant future so it stays.
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<bool> MobPushing =
|
||||
CVarDef.Create("physics.mob_pushing", false, CVar.REPLICATED | CVar.SERVER);
|
||||
}
|
||||
32
Content.Shared/CCVar/CCVars.Radiation.cs
Normal file
32
Content.Shared/CCVar/CCVars.Radiation.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// What is the smallest radiation dose in rads that can be received by object.
|
||||
/// Extremely small values may impact performance.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> RadiationMinIntensity =
|
||||
CVarDef.Create("radiation.min_intensity", 0.1f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Rate of radiation system update in seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> RadiationGridcastUpdateRate =
|
||||
CVarDef.Create("radiation.gridcast.update_rate", 1.0f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If both radiation source and receiver are placed on same grid, ignore grids between them.
|
||||
/// May get inaccurate result in some cases, but greatly boost performance in general.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> RadiationGridcastSimplifiedSameGrid =
|
||||
CVarDef.Create("radiation.gridcast.simplified_same_grid", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Max distance that radiation ray can travel in meters.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> RadiationGridcastMaxDistance =
|
||||
CVarDef.Create("radiation.gridcast.max_distance", 50f, CVar.SERVERONLY);
|
||||
}
|
||||
43
Content.Shared/CCVar/CCVars.Replays.cs
Normal file
43
Content.Shared/CCVar/CCVars.Replays.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not to record admin chat. If replays are being publicly distributes, this should probably be
|
||||
/// false.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ReplayRecordAdminChat =
|
||||
CVarDef.Create("replay.record_admin_chat", false, CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Automatically record full rounds as replays.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ReplayAutoRecord =
|
||||
CVarDef.Create("replay.auto_record", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The file name to record automatic replays to. The path is relative to <see cref="CVars.ReplayDirectory"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// If the path includes slashes, directories will be automatically created if necessary.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// A number of substitutions can be used to automatically fill in the file name: <c>{year}</c>, <c>{month}</c>, <c>{day}</c>, <c>{hour}</c>, <c>{minute}</c>, <c>{round}</c>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<string> ReplayAutoRecordName =
|
||||
CVarDef.Create("replay.auto_record_name",
|
||||
"{year}_{month}_{day}-{hour}_{minute}-round_{round}.zip",
|
||||
CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Path that, if provided, automatic replays are initially recorded in.
|
||||
/// When the recording is done, the file is moved into its final destination.
|
||||
/// Unless this path is rooted, it will be relative to <see cref="CVars.ReplayDirectory"/>.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> ReplayAutoRecordTempDir =
|
||||
CVarDef.Create("replay.auto_record_temp_dir", "", CVar.SERVERONLY);
|
||||
}
|
||||
18
Content.Shared/CCVar/CCVars.Salvage.cs
Normal file
18
Content.Shared/CCVar/CCVars.Salvage.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Duration for missions
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float>
|
||||
SalvageExpeditionDuration = CVarDef.Create("salvage.expedition_duration", 660f, CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Cooldown for missions.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float>
|
||||
SalvageExpeditionCooldown = CVarDef.Create("salvage.expedition_cooldown", 780f, CVar.REPLICATED);
|
||||
}
|
||||
43
Content.Shared/CCVar/CCVars.Server.cs
Normal file
43
Content.Shared/CCVar/CCVars.Server.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/*
|
||||
* Server
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Change this to have the changelog and rules "last seen" date stored separately.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> ServerId =
|
||||
CVarDef.Create("server.id", "unknown_server_id", CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Guide Entry Prototype ID to be displayed as the server rules.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> RulesFile =
|
||||
CVarDef.Create("server.rules_file", "DefaultRuleset", CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Guide entry that is displayed by default when a guide is opened.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DefaultGuide =
|
||||
CVarDef.Create("server.default_guide", "NewPlayer", CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// If greater than 0, automatically restart the server after this many minutes of uptime.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is intended to work around various bugs and performance issues caused by long continuous server uptime.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This uses the same non-disruptive logic as update restarts,
|
||||
/// i.e. the game will only restart at round end or when there is nobody connected.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static readonly CVarDef<int> ServerUptimeRestartMinutes =
|
||||
CVarDef.Create("server.uptime_restart_minutes", 0, CVar.SERVERONLY);
|
||||
}
|
||||
176
Content.Shared/CCVar/CCVars.Shuttle.cs
Normal file
176
Content.Shared/CCVar/CCVars.Shuttle.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// If true then the camera will match the grid / map and is unchangeable.
|
||||
/// - When traversing grids it will snap to 0 degrees rotation.
|
||||
/// False means the player has control over the camera rotation.
|
||||
/// - When traversing grids it will snap to the nearest cardinal which will generally be imperceptible.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> CameraRotationLocked =
|
||||
CVarDef.Create("shuttle.camera_rotation_locked", false, CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the arrivals terminal should be on a planet map.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ArrivalsPlanet =
|
||||
CVarDef.Create("shuttle.arrivals_planet", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the arrivals shuttle is enabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ArrivalsShuttles =
|
||||
CVarDef.Create("shuttle.arrivals", false, CVar.SERVERONLY); //CP14 arrivals disabled
|
||||
|
||||
/// <summary>
|
||||
/// The map to use for the arrivals station.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> ArrivalsMap =
|
||||
CVarDef.Create("shuttle.arrivals_map", "/Maps/Misc/terminal.yml", CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Cooldown between arrivals departures. This should be longer than the FTL time or it will double cycle.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> ArrivalsCooldown =
|
||||
CVarDef.Create("shuttle.arrivals_cooldown", 50f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Are players allowed to return on the arrivals shuttle.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ArrivalsReturns =
|
||||
CVarDef.Create("shuttle.arrivals_returns", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should all players who spawn at arrivals have godmode until they leave the map?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GodmodeArrivals =
|
||||
CVarDef.Create("shuttle.godmode_arrivals", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If a grid is split then hide any smaller ones under this mass (kg) from the map.
|
||||
/// This is useful to avoid split grids spamming out labels.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> HideSplitGridsUnder =
|
||||
CVarDef.Create("shuttle.hide_split_grids_under", 30, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to automatically spawn escape shuttles.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GridFill =
|
||||
CVarDef.Create("shuttle.grid_fill", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to automatically preloading grids by GridPreloaderSystem
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> PreloadGrids =
|
||||
CVarDef.Create("shuttle.preload_grids", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How long the warmup time before FTL start should be.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> FTLStartupTime =
|
||||
CVarDef.Create("shuttle.startup_time", 5.5f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How long a shuttle spends in FTL.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> FTLTravelTime =
|
||||
CVarDef.Create("shuttle.travel_time", 20f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How long the final stage of FTL before arrival should be.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> FTLArrivalTime =
|
||||
CVarDef.Create("shuttle.arrival_time", 5f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How much time needs to pass before a shuttle can FTL again.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> FTLCooldown =
|
||||
CVarDef.Create("shuttle.cooldown", 10f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum <see cref="PhysicsComponent.Mass"/> a grid can have before it becomes unable to FTL.
|
||||
/// Any value equal to or less than zero will disable this check.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> FTLMassLimit =
|
||||
CVarDef.Create("shuttle.mass_limit", 300f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How long to knock down entities for if they aren't buckled when FTL starts and stops.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> HyperspaceKnockdownTime =
|
||||
CVarDef.Create("shuttle.hyperspace_knockdown_time", 5f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Is the emergency shuttle allowed to be early launched.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> EmergencyEarlyLaunchAllowed =
|
||||
CVarDef.Create("shuttle.emergency_early_launch_allowed", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How long the emergency shuttle remains docked with the station, in seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> EmergencyShuttleDockTime =
|
||||
CVarDef.Create("shuttle.emergency_dock_time", 180f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If the emergency shuttle can't dock at a priority port, the dock time will be multiplied with this value.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> EmergencyShuttleDockTimeMultiplierOtherDock =
|
||||
CVarDef.Create("shuttle.emergency_dock_time_multiplier_other_dock", 1.6667f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If the emergency shuttle can't dock at all, the dock time will be multiplied with this value.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> EmergencyShuttleDockTimeMultiplierNoDock =
|
||||
CVarDef.Create("shuttle.emergency_dock_time_multiplier_no_dock", 2f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How long after the console is authorized for the shuttle to early launch.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> EmergencyShuttleAuthorizeTime =
|
||||
CVarDef.Create("shuttle.emergency_authorize_time", 10f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The minimum time for the emergency shuttle to arrive at centcomm.
|
||||
/// Actual minimum travel time cannot be less than <see cref="ShuttleSystem.DefaultArrivalTime"/>
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> EmergencyShuttleMinTransitTime =
|
||||
CVarDef.Create("shuttle.emergency_transit_time_min", 60f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum time for the emergency shuttle to arrive at centcomm.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> EmergencyShuttleMaxTransitTime =
|
||||
CVarDef.Create("shuttle.emergency_transit_time_max", 180f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the emergency shuttle is enabled or should the round just end.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> EmergencyShuttleEnabled =
|
||||
CVarDef.Create("shuttle.emergency", false, CVar.SERVERONLY); //CP14 Emergency disabled
|
||||
|
||||
/// <summary>
|
||||
/// The percentage of time passed from the initial call to when the shuttle can no longer be recalled.
|
||||
/// ex. a call time of 10min and turning point of 0.5 means the shuttle cannot be recalled after 5 minutes.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> EmergencyRecallTurningPoint =
|
||||
CVarDef.Create("shuttle.recall_turning_point", 0.5f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Time in minutes after round start to auto-call the shuttle. Set to zero to disable.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> EmergencyShuttleAutoCallTime =
|
||||
CVarDef.Create("shuttle.auto_call_time", 90, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Time in minutes after the round was extended (by recalling the shuttle) to call
|
||||
/// the shuttle again.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> EmergencyShuttleAutoCallExtensionTime =
|
||||
CVarDef.Create("shuttle.auto_call_extension_time", 45, CVar.SERVERONLY);
|
||||
}
|
||||
34
Content.Shared/CCVar/CCVars.Sounds.cs
Normal file
34
Content.Shared/CCVar/CCVars.Sounds.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool> LobbyMusicEnabled =
|
||||
CVarDef.Create("ambience.lobby_music_enabled", true, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<bool> EventMusicEnabled =
|
||||
CVarDef.Create("ambience.event_music_enabled", true, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Round end sound (APC Destroyed)
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> RestartSoundsEnabled =
|
||||
CVarDef.Create("ambience.restart_sounds_enabled", true, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
|
||||
|
||||
public static readonly CVarDef<bool> AdminSoundsEnabled =
|
||||
CVarDef.Create("audio.admin_sounds_enabled", true, CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
|
||||
public static readonly CVarDef<string> AdminChatSoundPath =
|
||||
CVarDef.Create("audio.admin_chat_sound_path",
|
||||
"/Audio/Items/pop.ogg",
|
||||
CVar.ARCHIVE | CVar.CLIENT | CVar.REPLICATED);
|
||||
|
||||
public static readonly CVarDef<float> AdminChatSoundVolume =
|
||||
CVarDef.Create("audio.admin_chat_sound_volume", -5f, CVar.ARCHIVE | CVar.CLIENT | CVar.REPLICATED);
|
||||
|
||||
public static readonly CVarDef<string> AHelpSound =
|
||||
CVarDef.Create("audio.ahelp_sound", "/Audio/Effects/adminhelp.ogg", CVar.ARCHIVE | CVar.CLIENTONLY);
|
||||
}
|
||||
13
Content.Shared/CCVar/CCVars.Status.cs
Normal file
13
Content.Shared/CCVar/CCVars.Status.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<string> StatusMoMMIUrl =
|
||||
CVarDef.Create("status.mommiurl", "", CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> StatusMoMMIPassword =
|
||||
CVarDef.Create("status.mommipassword", "", CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
}
|
||||
40
Content.Shared/CCVar/CCVars.Tips.cs
Normal file
40
Content.Shared/CCVar/CCVars.Tips.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether tips being shown is enabled at all.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> TipsEnabled =
|
||||
CVarDef.Create("tips.enabled", true);
|
||||
|
||||
/// <summary>
|
||||
/// The dataset prototype to use when selecting a random tip.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> TipsDataset =
|
||||
CVarDef.Create("tips.dataset", "CP14Tips");
|
||||
|
||||
/// <summary>
|
||||
/// The number of seconds between each tip being displayed when the round is not actively going
|
||||
/// (i.e. postround or lobby)
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> TipFrequencyOutOfRound =
|
||||
CVarDef.Create("tips.out_of_game_frequency", 60f * 1.5f);
|
||||
|
||||
/// <summary>
|
||||
/// The number of seconds between each tip being displayed when the round is actively going
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> TipFrequencyInRound =
|
||||
CVarDef.Create("tips.in_game_frequency", 60f * 60);
|
||||
|
||||
public static readonly CVarDef<string> LoginTipsDataset =
|
||||
CVarDef.Create("tips.login_dataset", "Tips");
|
||||
|
||||
/// <summary>
|
||||
/// The chance for Tippy to replace a normal tip message.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> TipsTippyChance =
|
||||
CVarDef.Create("tips.tippy_chance", 0.01f);
|
||||
}
|
||||
33
Content.Shared/CCVar/CCVars.Viewport.cs
Normal file
33
Content.Shared/CCVar/CCVars.Viewport.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool> ViewportStretch =
|
||||
CVarDef.Create("viewport.stretch", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<int> ViewportFixedScaleFactor =
|
||||
CVarDef.Create("viewport.fixed_scale_factor", 2, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<int> ViewportSnapToleranceMargin =
|
||||
CVarDef.Create("viewport.snap_tolerance_margin", 64, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<int> ViewportSnapToleranceClip =
|
||||
CVarDef.Create("viewport.snap_tolerance_clip", 32, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<bool> ViewportScaleRender =
|
||||
CVarDef.Create("viewport.scale_render", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<int> ViewportMinimumWidth =
|
||||
CVarDef.Create("viewport.minimum_width", 15, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<int> ViewportMaximumWidth =
|
||||
CVarDef.Create("viewport.maximum_width", 21, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<int> ViewportWidth =
|
||||
CVarDef.Create("viewport.width", 21, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<bool> ViewportVerticalFit =
|
||||
CVarDef.Create("viewport.vertical_fit", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
}
|
||||
180
Content.Shared/CCVar/CCVars.Vote.cs
Normal file
180
Content.Shared/CCVar/CCVars.Vote.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows enabling/disabling player-started votes for ultimate authority
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VoteEnabled =
|
||||
CVarDef.Create("vote.enabled", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// See vote.enabled, but specific to restart votes
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VoteRestartEnabled =
|
||||
CVarDef.Create("vote.restart_enabled", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Config for when the restart vote should be allowed to be called regardless with less than this amount of players.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VoteRestartMaxPlayers =
|
||||
CVarDef.Create("vote.restart_max_players", 20, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Config for when the restart vote should be allowed to be called based on percentage of ghosts.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VoteRestartGhostPercentage =
|
||||
CVarDef.Create("vote.restart_ghost_percentage", 55, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// See vote.enabled, but specific to preset votes
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotePresetEnabled =
|
||||
CVarDef.Create("vote.preset_enabled", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// See vote.enabled, but specific to map votes
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VoteMapEnabled =
|
||||
CVarDef.Create("vote.map_enabled", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The required ratio of the server that must agree for a restart round vote to go through.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> VoteRestartRequiredRatio =
|
||||
CVarDef.Create("vote.restart_required_ratio", 0.85f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to prevent the restart vote from having any effect when there is an online admin
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VoteRestartNotAllowedWhenAdminOnline =
|
||||
CVarDef.Create("vote.restart_not_allowed_when_admin_online", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The delay which two votes of the same type are allowed to be made by separate people, in seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> VoteSameTypeTimeout =
|
||||
CVarDef.Create("vote.same_type_timeout", 240f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the duration of the map vote timer.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
VoteTimerMap = CVarDef.Create("vote.timermap", 90, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the duration of the restart vote timer.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
VoteTimerRestart = CVarDef.Create("vote.timerrestart", 60, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the duration of the gamemode/preset vote timer.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
VoteTimerPreset = CVarDef.Create("vote.timerpreset", 30, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the duration of the map vote timer when ALONE.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
VoteTimerAlone = CVarDef.Create("vote.timeralone", 10, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Allows enabling/disabling player-started votekick for ultimate authority
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickEnabled =
|
||||
CVarDef.Create("votekick.enabled", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Config for when the votekick should be allowed to be called based on number of eligible voters.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VotekickEligibleNumberRequirement =
|
||||
CVarDef.Create("votekick.eligible_number", 5, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether a votekick initiator must be a ghost or not.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickInitiatorGhostRequirement =
|
||||
CVarDef.Create("votekick.initiator_ghost_requirement", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should the initiator be whitelisted to initiate a votekick?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickInitiatorWhitelistedRequirement =
|
||||
CVarDef.Create("votekick.initiator_whitelist_requirement", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should the initiator be able to start a votekick if they are bellow the votekick.voter_playtime requirement?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickInitiatorTimeRequirement =
|
||||
CVarDef.Create("votekick.initiator_time_requirement", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether a votekick voter must be a ghost or not.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickVoterGhostRequirement =
|
||||
CVarDef.Create("votekick.voter_ghost_requirement", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Config for how many hours playtime a player must have to be able to vote on a votekick.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VotekickEligibleVoterPlaytime =
|
||||
CVarDef.Create("votekick.voter_playtime", 100, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Config for how many seconds a player must have been dead to initiate a votekick / be able to vote on a votekick.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VotekickEligibleVoterDeathtime =
|
||||
CVarDef.Create("votekick.voter_deathtime", 30, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// The required ratio of eligible voters that must agree for a votekick to go through.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> VotekickRequiredRatio =
|
||||
CVarDef.Create("votekick.required_ratio", 0.6f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to prevent the votekick from having any effect when there is an online admin.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickNotAllowedWhenAdminOnline =
|
||||
CVarDef.Create("votekick.not_allowed_when_admin_online", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The delay for which two votekicks are allowed to be made by separate people, in seconds.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> VotekickTimeout =
|
||||
CVarDef.Create("votekick.timeout", 120f, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the duration of the votekick vote timer.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int>
|
||||
VotekickTimer = CVarDef.Create("votekick.timer", 60, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Config for how many hours playtime a player must have to get protection from the Raider votekick type when playing as an antag.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VotekickAntagRaiderProtection =
|
||||
CVarDef.Create("votekick.antag_raider_protection", 10, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Default severity for votekick bans
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> VotekickBanDefaultSeverity =
|
||||
CVarDef.Create("votekick.ban_default_severity", "High", CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Duration of a ban caused by a votekick (in minutes).
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VotekickBanDuration =
|
||||
CVarDef.Create("votekick.ban_duration", 180, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the ghost requirement settings for votekicks should be ignored for the lobby.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickIgnoreGhostReqInLobby =
|
||||
CVarDef.Create("votekick.ignore_ghost_req_in_lobby", true, CVar.SERVERONLY);
|
||||
}
|
||||
19
Content.Shared/CCVar/CCVars.Whitelist.cs
Normal file
19
Content.Shared/CCVar/CCVars.Whitelist.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls whether the server will deny any players that are not whitelisted in the DB.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> WhitelistEnabled =
|
||||
CVarDef.Create("whitelist.enabled", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the whitelist prototypes to be used by the server. This should be a comma-separated list of prototypes.
|
||||
/// If a whitelists conditions to be active fail (for example player count), the next whitelist will be used instead. If no whitelist is valid, the player will be allowed to connect.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> WhitelistPrototypeList =
|
||||
CVarDef.Create("whitelist.prototype_list", "basicWhitelist", CVar.SERVERONLY);
|
||||
}
|
||||
18
Content.Shared/CCVar/CCVars.Worldgen.cs
Normal file
18
Content.Shared/CCVar/CCVars.Worldgen.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not world generation is enabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> WorldgenEnabled =
|
||||
CVarDef.Create("worldgen.enabled", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The worldgen config to use.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> WorldgenConfig =
|
||||
CVarDef.Create("worldgen.worldgen_config", "Default", CVar.SERVERONLY);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,4 +17,7 @@ public sealed class CartridgeUiMessage : BoundUserInterfaceMessage
|
||||
public abstract class CartridgeMessageEvent : EntityEventArgs
|
||||
{
|
||||
public NetEntity LoaderUid;
|
||||
|
||||
[NonSerialized]
|
||||
public EntityUid Actor;
|
||||
}
|
||||
|
||||
@@ -11,11 +11,6 @@ public sealed partial class HyposprayComponent : Component
|
||||
[DataField]
|
||||
public string SolutionName = "hypospray";
|
||||
|
||||
// TODO: This should be on clumsycomponent.
|
||||
[DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float ClumsyFailChance = 0.5f;
|
||||
|
||||
[DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public FixedPoint2 TransferAmount = FixedPoint2.New(5);
|
||||
|
||||
@@ -45,6 +45,15 @@ public sealed partial class InjectorComponent : Component
|
||||
[DataField]
|
||||
public bool IgnoreMobs;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the injector is able to draw from or inject into containers that are closed/sealed
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// for example: droppers can not inject into cans, but syringes can
|
||||
/// </remarks>
|
||||
[DataField]
|
||||
public bool IgnoreClosed = true;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum amount of solution that can be transferred at once from this solution.
|
||||
/// </summary>
|
||||
|
||||
38
Content.Shared/Chemistry/Events/HyposprayEvents.cs
Normal file
38
Content.Shared/Chemistry/Events/HyposprayEvents.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
namespace Content.Shared.Chemistry.Hypospray.Events;
|
||||
|
||||
public abstract partial class BeforeHyposprayInjectsTargetEvent : CancellableEntityEventArgs, IInventoryRelayEvent
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||
public EntityUid EntityUsingHypospray;
|
||||
public readonly EntityUid Hypospray;
|
||||
public EntityUid TargetGettingInjected;
|
||||
public string? InjectMessageOverride;
|
||||
|
||||
public BeforeHyposprayInjectsTargetEvent(EntityUid user, EntityUid hypospray, EntityUid target)
|
||||
{
|
||||
EntityUsingHypospray = user;
|
||||
Hypospray = hypospray;
|
||||
TargetGettingInjected = target;
|
||||
InjectMessageOverride = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the user using the hypospray before the hypospray is injected.
|
||||
/// The event is triggered on the user and all their clothing.
|
||||
/// </summary>
|
||||
public sealed class SelfBeforeHyposprayInjectsEvent : BeforeHyposprayInjectsTargetEvent
|
||||
{
|
||||
public SelfBeforeHyposprayInjectsEvent(EntityUid user, EntityUid hypospray, EntityUid target) : base(user, hypospray, target) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the target before the hypospray is injected.
|
||||
/// The event is triggered on the target itself and all its clothing.
|
||||
/// </summary>
|
||||
public sealed class TargetBeforeHyposprayInjectsEvent : BeforeHyposprayInjectsTargetEvent
|
||||
{
|
||||
public TargetBeforeHyposprayInjectsEvent (EntityUid user, EntityUid hypospray, EntityUid target) : base(user, hypospray, target) { }
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Climbing.Components;
|
||||
@@ -8,39 +7,18 @@ namespace Content.Shared.Climbing.Components;
|
||||
/// Makes entity do damage and stun entities with ClumsyComponent
|
||||
/// upon DragDrop or Climb interactions.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(Systems.BonkSystem))]
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class BonkableComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Chance of bonk triggering if the user is clumsy.
|
||||
/// How long to stun players on bonk, in seconds.
|
||||
/// </summary>
|
||||
[DataField("bonkClumsyChance")]
|
||||
public float BonkClumsyChance = 0.5f;
|
||||
[DataField]
|
||||
public TimeSpan BonkTime = TimeSpan.FromSeconds(2);
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when bonking.
|
||||
/// How much damage to apply on bonk.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkSound")]
|
||||
public SoundSpecifier? BonkSound;
|
||||
|
||||
/// <summary>
|
||||
/// How long to stun players on bonk, in seconds.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkTime")]
|
||||
public float BonkTime = 2;
|
||||
|
||||
/// <summary>
|
||||
/// How much damage to apply on bonk.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkDamage")]
|
||||
[DataField]
|
||||
public DamageSpecifier? BonkDamage;
|
||||
|
||||
/// <summary>
|
||||
/// How long it takes to bonk.
|
||||
/// </summary>
|
||||
[DataField("bonkDelay")]
|
||||
public float BonkDelay = 1.5f;
|
||||
}
|
||||
|
||||
36
Content.Shared/Climbing/Events/BeforeClimbEvents.cs
Normal file
36
Content.Shared/Climbing/Events/BeforeClimbEvents.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Climbing.Components;
|
||||
|
||||
namespace Content.Shared.Climbing.Events;
|
||||
|
||||
public abstract partial class BeforeClimbEvent : CancellableEntityEventArgs
|
||||
{
|
||||
public readonly EntityUid GettingPutOnTable;
|
||||
public readonly EntityUid PuttingOnTable;
|
||||
public readonly Entity<ClimbableComponent> BeingClimbedOn;
|
||||
|
||||
public BeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn)
|
||||
{
|
||||
GettingPutOnTable = gettingPutOntable;
|
||||
PuttingOnTable = puttingOnTable;
|
||||
BeingClimbedOn = beingClimbedOn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the the person either getting put on or going on the table.
|
||||
/// The event is also called on their clothing as well.
|
||||
/// </summary>
|
||||
public sealed class SelfBeforeClimbEvent : BeforeClimbEvent, IInventoryRelayEvent
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||
public SelfBeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn) : base(gettingPutOntable, puttingOnTable, beingClimbedOn) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the thing being climbed on.
|
||||
/// </summary>
|
||||
public sealed class TargetBeforeClimbEvent : BeforeClimbEvent
|
||||
{
|
||||
public TargetBeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn) : base(gettingPutOntable, puttingOnTable, beingClimbedOn) { }
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Climbing.Components;
|
||||
using Content.Shared.Climbing.Events;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.DragDrop;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Stunnable;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Climbing.Systems;
|
||||
|
||||
public sealed partial class BonkSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<BonkableComponent, BonkDoAfterEvent>(OnBonkDoAfter);
|
||||
SubscribeLocalEvent<BonkableComponent, AttemptClimbEvent>(OnAttemptClimb);
|
||||
}
|
||||
|
||||
private void OnBonkDoAfter(EntityUid uid, BonkableComponent component, BonkDoAfterEvent args)
|
||||
{
|
||||
if (args.Handled || args.Cancelled || args.Args.Used == null)
|
||||
return;
|
||||
|
||||
TryBonk(args.Args.Used.Value, uid, component, source: args.Args.User);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
|
||||
public bool TryBonk(EntityUid user, EntityUid bonkableUid, BonkableComponent? bonkableComponent = null, EntityUid? source = null)
|
||||
{
|
||||
if (!Resolve(bonkableUid, ref bonkableComponent, false))
|
||||
return false;
|
||||
|
||||
// BONK!
|
||||
var userName = Identity.Entity(user, EntityManager);
|
||||
var bonkableName = Identity.Entity(bonkableUid, EntityManager);
|
||||
|
||||
if (user == source)
|
||||
{
|
||||
// Non-local, non-bonking players
|
||||
var othersMessage = Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName));
|
||||
// Local, bonking player
|
||||
var selfMessage = Loc.GetString("bonkable-success-message-user", ("user", userName), ("bonkable", bonkableName));
|
||||
|
||||
_popupSystem.PopupPredicted(selfMessage, othersMessage, user, user);
|
||||
}
|
||||
else if (source != null)
|
||||
{
|
||||
// Local, non-bonking player (dragger)
|
||||
_popupSystem.PopupClient(Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName)), user, source.Value);
|
||||
// Non-local, non-bonking players
|
||||
_popupSystem.PopupEntity(Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName)), user, Filter.Pvs(user).RemoveWhereAttachedEntity(e => e == user || e == source.Value), true);
|
||||
// Non-local, bonking player
|
||||
_popupSystem.PopupEntity(Loc.GetString("bonkable-success-message-user", ("user", userName), ("bonkable", bonkableName)), user, user);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (source != null)
|
||||
_audioSystem.PlayPredicted(bonkableComponent.BonkSound, bonkableUid, source);
|
||||
else
|
||||
_audioSystem.PlayPvs(bonkableComponent.BonkSound, bonkableUid);
|
||||
|
||||
_stunSystem.TryParalyze(user, TimeSpan.FromSeconds(bonkableComponent.BonkTime), true);
|
||||
|
||||
if (bonkableComponent.BonkDamage is { } bonkDmg)
|
||||
_damageableSystem.TryChangeDamage(user, bonkDmg, true, origin: user);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private bool TryStartBonk(EntityUid uid, EntityUid user, EntityUid climber, BonkableComponent? bonkableComponent = null)
|
||||
{
|
||||
if (!Resolve(uid, ref bonkableComponent, false))
|
||||
return false;
|
||||
|
||||
if (!HasComp<ClumsyComponent>(climber) || !HasComp<HandsComponent>(user))
|
||||
return false;
|
||||
|
||||
if (!_cfg.GetCVar(CCVars.GameTableBonk))
|
||||
{
|
||||
// Not set to always bonk, try clumsy roll.
|
||||
if (!_interactionSystem.TryRollClumsy(climber, bonkableComponent.BonkClumsyChance))
|
||||
return false;
|
||||
}
|
||||
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, bonkableComponent.BonkDelay, new BonkDoAfterEvent(), uid, target: uid, used: climber)
|
||||
{
|
||||
BreakOnMove = true,
|
||||
BreakOnDamage = true,
|
||||
DuplicateCondition = DuplicateConditions.SameTool | DuplicateConditions.SameTarget
|
||||
};
|
||||
|
||||
return _doAfter.TryStartDoAfter(doAfterArgs);
|
||||
}
|
||||
|
||||
private void OnAttemptClimb(EntityUid uid, BonkableComponent component, ref AttemptClimbEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
if (TryStartBonk(uid, args.User, args.Climber, component))
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
private sealed partial class BonkDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -251,6 +251,18 @@ public sealed partial class ClimbSystem : VirtualController
|
||||
if (!Resolve(climbable, ref comp, false))
|
||||
return;
|
||||
|
||||
var selfEvent = new SelfBeforeClimbEvent(uid, user, (climbable, comp));
|
||||
RaiseLocalEvent(uid, selfEvent);
|
||||
|
||||
if (selfEvent.Cancelled)
|
||||
return;
|
||||
|
||||
var targetEvent = new TargetBeforeClimbEvent(uid, user, (climbable, comp));
|
||||
RaiseLocalEvent(climbable, targetEvent);
|
||||
|
||||
if (targetEvent.Cancelled)
|
||||
return;
|
||||
|
||||
if (!ReplaceFixtures(uid, climbing, fixtures))
|
||||
return;
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ public sealed partial class ToggleClothingComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool DisableOnUnequip;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the clothes must equip for adding action.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool MustEquip = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -39,8 +39,12 @@ public sealed class ToggleClothingSystem : EntitySystem
|
||||
|
||||
private void OnGetActions(Entity<ToggleClothingComponent> ent, ref GetItemActionsEvent args)
|
||||
{
|
||||
if (args.InHands && ent.Comp.MustEquip)
|
||||
return;
|
||||
|
||||
var ev = new ToggleClothingCheckEvent(args.User);
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
|
||||
if (!ev.Cancelled)
|
||||
args.AddAction(ent.Comp.ActionEntity);
|
||||
}
|
||||
|
||||
61
Content.Shared/Clumsy/ClumsyComponent.cs
Normal file
61
Content.Shared/Clumsy/ClumsyComponent.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Clumsy;
|
||||
|
||||
/// <summary>
|
||||
/// A simple clumsy tag-component.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ClumsyComponent : Component
|
||||
{
|
||||
|
||||
// Standard options. Try to fit these in if you can!
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when clumsy interactions fail.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier ClumsySound = new SoundPathSpecifier("/Audio/Items/bikehorn.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// Default chance to fail a clumsy interaction.
|
||||
/// If a system needs to use something else, add a new variable in the component, do not modify this percentage.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public float ClumsyDefaultCheck = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Default stun time.
|
||||
/// If a system needs to use something else, add a new variable in the component, do not modify this number.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan ClumsyDefaultStunTime = TimeSpan.FromSeconds(2.5);
|
||||
|
||||
// Specific options
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play after hitting your head on a table. Ouch!
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundCollectionSpecifier TableBonkSound = new SoundCollectionSpecifier("TrayHit");
|
||||
|
||||
/// <summary>
|
||||
/// Stun time after failing to shoot a gun.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan GunShootFailStunTime = TimeSpan.FromSeconds(3);
|
||||
|
||||
/// <summary>
|
||||
/// Stun time after failing to shoot a gun.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public DamageSpecifier? GunShootFailDamage;
|
||||
|
||||
/// <summary>
|
||||
/// Noise to play after failing to shoot a gun. Boom!
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier GunShootFailSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/bang.ogg");
|
||||
}
|
||||
146
Content.Shared/Clumsy/ClumsySystem.cs
Normal file
146
Content.Shared/Clumsy/ClumsySystem.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Chemistry.Hypospray.Events;
|
||||
using Content.Shared.Climbing.Components;
|
||||
using Content.Shared.Climbing.Events;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Medical;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Stunnable;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared.Clumsy;
|
||||
|
||||
public sealed class ClumsySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stun = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<ClumsyComponent, SelfBeforeHyposprayInjectsEvent>(BeforeHyposprayEvent);
|
||||
SubscribeLocalEvent<ClumsyComponent, SelfBeforeDefibrillatorZapsEvent>(BeforeDefibrillatorZapsEvent);
|
||||
SubscribeLocalEvent<ClumsyComponent, SelfBeforeGunShotEvent>(BeforeGunShotEvent);
|
||||
SubscribeLocalEvent<ClumsyComponent, SelfBeforeClimbEvent>(OnBeforeClimbEvent);
|
||||
}
|
||||
|
||||
// If you add more clumsy interactions add them in this section!
|
||||
#region Clumsy interaction events
|
||||
private void BeforeHyposprayEvent(Entity<ClumsyComponent> ent, ref SelfBeforeHyposprayInjectsEvent args)
|
||||
{
|
||||
// Clumsy people sometimes inject themselves! Apparently syringes are clumsy proof...
|
||||
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
|
||||
return;
|
||||
|
||||
args.TargetGettingInjected = args.EntityUsingHypospray;
|
||||
args.InjectMessageOverride = "hypospray-component-inject-self-clumsy-message";
|
||||
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
|
||||
}
|
||||
|
||||
private void BeforeDefibrillatorZapsEvent(Entity<ClumsyComponent> ent, ref SelfBeforeDefibrillatorZapsEvent args)
|
||||
{
|
||||
// Clumsy people sometimes defib themselves!
|
||||
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
|
||||
return;
|
||||
|
||||
args.DefibTarget = args.EntityUsingDefib;
|
||||
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
|
||||
|
||||
}
|
||||
|
||||
private void BeforeGunShotEvent(Entity<ClumsyComponent> ent, ref SelfBeforeGunShotEvent args)
|
||||
{
|
||||
// Clumsy people sometimes can't shoot :(
|
||||
|
||||
if (args.Gun.Comp.ClumsyProof)
|
||||
return;
|
||||
|
||||
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
|
||||
return;
|
||||
|
||||
if (ent.Comp.GunShootFailDamage != null)
|
||||
_damageable.TryChangeDamage(ent, ent.Comp.GunShootFailDamage, origin: ent);
|
||||
|
||||
_stun.TryParalyze(ent, ent.Comp.GunShootFailStunTime, true);
|
||||
|
||||
// Apply salt to the wound ("Honk!") (No idea what this comment means)
|
||||
_audio.PlayPvs(ent.Comp.GunShootFailSound, ent);
|
||||
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("gun-clumsy"), ent, ent);
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnBeforeClimbEvent(Entity<ClumsyComponent> ent, ref SelfBeforeClimbEvent args)
|
||||
{
|
||||
// This event is called in shared, thats why it has all the extra prediction stuff.
|
||||
var rand = new System.Random((int)_timing.CurTick.Value);
|
||||
|
||||
// If someone is putting you on the table, always get past the guard.
|
||||
if (!_cfg.GetCVar(CCVars.GameTableBonk) && args.PuttingOnTable == ent.Owner && !rand.Prob(ent.Comp.ClumsyDefaultCheck))
|
||||
return;
|
||||
|
||||
HitHeadClumsy(ent, args.BeingClimbedOn);
|
||||
|
||||
_audio.PlayPredicted(ent.Comp.ClumsySound, ent, ent);
|
||||
|
||||
_audio.PlayPredicted(ent.Comp.TableBonkSound, ent, ent);
|
||||
|
||||
var gettingPutOnTableName = Identity.Entity(args.GettingPutOnTable, EntityManager);
|
||||
var puttingOnTableName = Identity.Entity(args.PuttingOnTable, EntityManager);
|
||||
|
||||
if (args.PuttingOnTable == ent.Owner)
|
||||
{
|
||||
// You are slamming yourself onto the table.
|
||||
_popup.PopupPredicted(
|
||||
Loc.GetString("bonkable-success-message-user", ("bonkable", args.BeingClimbedOn)),
|
||||
Loc.GetString("bonkable-success-message-others", ("victim", gettingPutOnTableName), ("bonkable", args.BeingClimbedOn)),
|
||||
ent,
|
||||
ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Someone else slamed you onto the table.
|
||||
// This is only run in server so you need to use popup entity.
|
||||
_popup.PopupPredicted(
|
||||
Loc.GetString("forced-bonkable-success-message",
|
||||
("bonker", puttingOnTableName),
|
||||
("victim", gettingPutOnTableName),
|
||||
("bonkable", args.BeingClimbedOn)),
|
||||
ent,
|
||||
null);
|
||||
}
|
||||
|
||||
args.Cancel();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Helper functions
|
||||
/// <summary>
|
||||
/// "Hits" an entites head against the given table.
|
||||
/// </summary>
|
||||
// Oh this fucntion is public le- NO!! This is only public for the one admin command if you use this anywhere else I will cry.
|
||||
public void HitHeadClumsy(Entity<ClumsyComponent> target, EntityUid table)
|
||||
{
|
||||
var stunTime = target.Comp.ClumsyDefaultStunTime;
|
||||
|
||||
if (TryComp<BonkableComponent>(table, out var bonkComp))
|
||||
{
|
||||
stunTime = bonkComp.BonkTime;
|
||||
if (bonkComp.BonkDamage != null)
|
||||
_damageable.TryChangeDamage(target, bonkComp.BonkDamage, true);
|
||||
}
|
||||
|
||||
_stun.TryParalyze(target, stunTime, true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -3,12 +3,23 @@ using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Crayon
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Component holding the state of a crayon-like component
|
||||
/// </summary>
|
||||
[NetworkedComponent, ComponentProtoName("Crayon"), Access(typeof(SharedCrayonSystem))]
|
||||
public abstract partial class SharedCrayonComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of currently selected decal prototype that will be placed when the crayon is used
|
||||
/// </summary>
|
||||
public string SelectedState { get; set; } = string.Empty;
|
||||
|
||||
[DataField("color")] public Color Color;
|
||||
/// <summary>
|
||||
/// Color with which the crayon will draw
|
||||
/// </summary>
|
||||
[DataField("color")]
|
||||
public Color Color;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CrayonUiKey : byte
|
||||
@@ -17,6 +28,9 @@ namespace Content.Shared.Crayon
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by the client to notify the server about the selected decal ID
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CrayonSelectMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
@@ -27,6 +41,9 @@ namespace Content.Shared.Crayon
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the color of the crayon, used by Rainbow Crayon
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CrayonColorMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
@@ -37,13 +54,25 @@ namespace Content.Shared.Crayon
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Server to CLIENT. Notifies the BUI that a decal with given ID has been drawn.
|
||||
/// Allows the client UI to advance forward in the client-only ephemeral queue,
|
||||
/// preventing the crayon from becoming a magic text storage device.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public enum CrayonVisuals
|
||||
public sealed class CrayonUsedMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
State,
|
||||
Color
|
||||
public readonly string DrawnDecal;
|
||||
|
||||
public CrayonUsedMessage(string drawn)
|
||||
{
|
||||
DrawnDecal = drawn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component state, describes how many charges are left in the crayon in the near-hand UI
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CrayonComponentState : ComponentState
|
||||
{
|
||||
@@ -60,10 +89,17 @@ namespace Content.Shared.Crayon
|
||||
Capacity = capacity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The state of the crayon UI as sent by the server
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CrayonBoundUserInterfaceState : BoundUserInterfaceState
|
||||
{
|
||||
public string Selected;
|
||||
/// <summary>
|
||||
/// Whether or not the color can be selected
|
||||
/// </summary>
|
||||
public bool SelectableColor;
|
||||
public Color Color;
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ public sealed class DamageExamineSystem : EntitySystem
|
||||
}
|
||||
else
|
||||
{
|
||||
if (damageSpecifier.GetTotal() == FixedPoint2.Zero && !damageSpecifier.AnyPositive())
|
||||
{
|
||||
msg.AddMarkupOrThrow(Loc.GetString("damage-none"));
|
||||
return msg;
|
||||
}
|
||||
|
||||
msg.AddMarkupOrThrow(Loc.GetString("damage-examine-type", ("type", type)));
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,13 @@ public sealed class EmagSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a popup to emag user (client side only!) and adds <see cref="EmaggedComponent"/> to the entity when handled
|
||||
/// </summary>
|
||||
/// <param name="UserUid">Emag user</param>
|
||||
/// <param name="Handled">Did the emagging succeed? Causes a user-only popup to show on client side</param>
|
||||
/// <param name="Repeatable">Can the entity be emagged more than once? Prevents adding of <see cref="EmaggedComponent"/></param>
|
||||
/// <remarks>Needs to be handled in shared/client, not just the server, to actually show the emagging popup</remarks>
|
||||
[ByRefEvent]
|
||||
public record struct GotEmaggedEvent(EntityUid UserUid, bool Handled = false, bool Repeatable = false);
|
||||
|
||||
|
||||
@@ -66,5 +66,5 @@ public record struct GenerateDnaEvent()
|
||||
/// <summary>
|
||||
/// The generated DNA.
|
||||
/// </summary>
|
||||
public string DNA;
|
||||
public required string DNA;
|
||||
}
|
||||
|
||||
33
Content.Shared/GameTicking/PlayerBeforeSpawnEvent.cs
Normal file
33
Content.Shared/GameTicking/PlayerBeforeSpawnEvent.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Shared.GameTicking;
|
||||
|
||||
/// <summary>
|
||||
/// Event raised broadcast before a player is spawned by the GameTicker.
|
||||
/// You can use this event to spawn a player off-station on late-join but also at round start.
|
||||
/// When this event is handled, the GameTicker will not perform its own player-spawning logic.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public sealed class PlayerBeforeSpawnEvent : HandledEntityEventArgs
|
||||
{
|
||||
public ICommonSession Player { get; }
|
||||
public HumanoidCharacterProfile Profile { get; }
|
||||
public string? JobId { get; }
|
||||
public bool LateJoin { get; }
|
||||
public EntityUid Station { get; }
|
||||
|
||||
public PlayerBeforeSpawnEvent(ICommonSession player,
|
||||
HumanoidCharacterProfile profile,
|
||||
string? jobId,
|
||||
bool lateJoin,
|
||||
EntityUid station)
|
||||
{
|
||||
Player = player;
|
||||
Profile = profile;
|
||||
JobId = jobId;
|
||||
LateJoin = lateJoin;
|
||||
Station = station;
|
||||
}
|
||||
}
|
||||
44
Content.Shared/GameTicking/PlayerSpawnCompleteEvent.cs
Normal file
44
Content.Shared/GameTicking/PlayerSpawnCompleteEvent.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Shared.GameTicking;
|
||||
|
||||
/// <summary>
|
||||
/// Event raised both directed and broadcast when a player has been spawned by the GameTicker.
|
||||
/// You can use this to handle people late-joining, or to handle people being spawned at round start.
|
||||
/// Can be used to give random players a role, modify their equipment, etc.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public sealed class PlayerSpawnCompleteEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid Mob { get; }
|
||||
public ICommonSession Player { get; }
|
||||
public string? JobId { get; }
|
||||
public bool LateJoin { get; }
|
||||
public bool Silent { get; }
|
||||
public EntityUid Station { get; }
|
||||
public HumanoidCharacterProfile Profile { get; }
|
||||
|
||||
// Ex. If this is the 27th person to join, this will be 27.
|
||||
public int JoinOrder { get; }
|
||||
|
||||
public PlayerSpawnCompleteEvent(EntityUid mob,
|
||||
ICommonSession player,
|
||||
string? jobId,
|
||||
bool lateJoin,
|
||||
bool silent,
|
||||
int joinOrder,
|
||||
EntityUid station,
|
||||
HumanoidCharacterProfile profile)
|
||||
{
|
||||
Mob = mob;
|
||||
Player = player;
|
||||
JobId = jobId;
|
||||
LateJoin = lateJoin;
|
||||
Silent = silent;
|
||||
Station = station;
|
||||
Profile = profile;
|
||||
JoinOrder = joinOrder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Intellicard;
|
||||
|
||||
/// <summary>
|
||||
/// Allows this entity to download the station AI onto an AiHolderComponent.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class IntellicardComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The duration it takes to download the AI from an AiHolder.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public int DownloadTime = 15;
|
||||
|
||||
/// <summary>
|
||||
/// The duration it takes to upload the AI to an AiHolder.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public int UploadTime = 3;
|
||||
|
||||
/// <summary>
|
||||
/// The sound that plays for the AI
|
||||
/// when they are being downloaded
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public SoundSpecifier? WarningSound = new SoundPathSpecifier("/Audio/Misc/notice2.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// The delay before allowing the warning to play again in seconds.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan WarningDelay = TimeSpan.FromSeconds(8);
|
||||
|
||||
[ViewVariables]
|
||||
public TimeSpan NextWarningAllowed = TimeSpan.Zero;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Interaction.Components;
|
||||
|
||||
/// <summary>
|
||||
/// A simple clumsy tag-component.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ClumsyComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Damage dealt to a clumsy character when they try to fire a gun.
|
||||
/// </summary>
|
||||
[DataField(required: true), AutoNetworkedField]
|
||||
public DamageSpecifier ClumsyDamage = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when clumsy interactions fail.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier ClumsySound = new SoundPathSpecifier("/Audio/Items/bikehorn.ogg");
|
||||
}
|
||||
@@ -159,4 +159,26 @@ public sealed class InteractionPopupSystem : EntitySystem
|
||||
_audio.PlayEntity(sfx, Filter.Empty().FromEntities(target), target, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="InteractionPopupComponent.InteractSuccessString"/>.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// This field is not networked automatically, so this method must be called on both sides of the network.
|
||||
/// </para>
|
||||
public void SetInteractSuccessString(Entity<InteractionPopupComponent> ent, string str)
|
||||
{
|
||||
ent.Comp.InteractSuccessString = str;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="InteractionPopupComponent.InteractFailureString"/>.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// This field is not networked automatically, so this method must be called on both sides of the network.
|
||||
/// </para>
|
||||
public void SetInteractFailureString(Entity<InteractionPopupComponent> ent, string str)
|
||||
{
|
||||
ent.Comp.InteractFailureString = str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Shared.Interaction
|
||||
{
|
||||
public partial class SharedInteractionSystem
|
||||
{
|
||||
public bool RollClumsy(ClumsyComponent component, float chance)
|
||||
{
|
||||
return component.Running && _random.Prob(chance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls a probability chance for a "bad action" if the target entity is clumsy.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity that the clumsy check is happening for.</param>
|
||||
/// <param name="chance">
|
||||
/// The chance that a "bad action" happens if the user is clumsy, between 0 and 1 inclusive.
|
||||
/// </param>
|
||||
/// <returns>True if a "bad action" happened, false if the normal action should happen.</returns>
|
||||
public bool TryRollClumsy(EntityUid entity, float chance, ClumsyComponent? component = null)
|
||||
{
|
||||
return Resolve(entity, ref component, false) && RollClumsy(component, chance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ using Content.Shared.Physics;
|
||||
using Content.Shared.Players.RateLimiting;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Strip;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Timing;
|
||||
using Content.Shared.UserInterface;
|
||||
@@ -67,6 +68,7 @@ namespace Content.Shared.Interaction
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly TagSystem _tagSystem = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
||||
[Dependency] private readonly SharedStrippableSystem _strippable = default!;
|
||||
[Dependency] private readonly SharedPlayerRateLimitManager _rateLimit = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly ISharedChatManager _chat = default!;
|
||||
@@ -1321,7 +1323,7 @@ namespace Content.Shared.Interaction
|
||||
if (wearer == user)
|
||||
return true;
|
||||
|
||||
if (slotDef.StripHidden)
|
||||
if (_strippable.IsStripHidden(slotDef, user))
|
||||
return false;
|
||||
|
||||
return InRangeUnobstructed(user, wearer) && _containerSystem.IsInSameOrParentContainer(user, wearer);
|
||||
|
||||
@@ -7,10 +7,12 @@ namespace Content.Shared.Inventory;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[Access(typeof(InventorySystem))]
|
||||
[AutoGenerateComponentState(true)]
|
||||
public sealed partial class InventoryComponent : Component
|
||||
{
|
||||
[DataField("templateId", customTypeSerializer: typeof(PrototypeIdSerializer<InventoryTemplatePrototype>))]
|
||||
public string TemplateId { get; private set; } = "human";
|
||||
[AutoNetworkedField]
|
||||
public string TemplateId { get; set; } = "human";
|
||||
|
||||
[DataField("speciesId")] public string? SpeciesId { get; set; }
|
||||
|
||||
@@ -32,3 +34,9 @@ public sealed partial class InventoryComponent : Component
|
||||
[DataField]
|
||||
public Dictionary<string, DisplacementData> MaleDisplacements = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised if the <see cref="InventoryComponent.TemplateId"/> of an inventory changed.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public struct InventoryTemplateUpdated;
|
||||
|
||||
@@ -10,6 +10,7 @@ using Content.Shared.Inventory.Events;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Strip;
|
||||
using Content.Shared.Strip.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
@@ -32,6 +33,7 @@ public abstract partial class InventorySystem
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly SharedStrippableSystem _strippable = default!;
|
||||
|
||||
[ValidatePrototypeId<ItemSizePrototype>]
|
||||
private const string PocketableItemSize = "Small";
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using Content.Shared._CP14.MagicEnergy;
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Hypospray.Events;
|
||||
using Content.Shared.Climbing.Events;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Electrocution;
|
||||
using Content.Shared.Explosion;
|
||||
@@ -17,7 +20,7 @@ using Content.Shared.Slippery;
|
||||
using Content.Shared.Strip.Components;
|
||||
using Content.Shared.Temperature;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
|
||||
namespace Content.Shared.Inventory;
|
||||
|
||||
@@ -41,6 +44,10 @@ public partial class InventorySystem
|
||||
SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshNameModifiersEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, TransformSpeakerNameEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, SelfBeforeHyposprayInjectsEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, TargetBeforeHyposprayInjectsEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, SelfBeforeGunShotEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, SelfBeforeClimbEvent>(RelayInventoryEvent);
|
||||
|
||||
// by-ref events
|
||||
SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent);
|
||||
@@ -115,7 +122,7 @@ public partial class InventorySystem
|
||||
var enumerator = new InventorySlotEnumerator(component);
|
||||
while (enumerator.NextItem(out var item, out var slotDef))
|
||||
{
|
||||
if (!slotDef.StripHidden || args.User == uid)
|
||||
if (!_strippable.IsStripHidden(slotDef, args.User) || args.User == uid)
|
||||
RaiseLocalEvent(item, ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.Inventory.Events;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Shared.Containers;
|
||||
@@ -19,6 +20,8 @@ public partial class InventorySystem : EntitySystem
|
||||
|
||||
_vvm.GetTypeHandler<InventoryComponent>()
|
||||
.AddHandler(HandleViewVariablesSlots, ListViewVariablesSlots);
|
||||
|
||||
SubscribeLocalEvent<InventoryComponent, AfterAutoHandleStateEvent>(AfterAutoState);
|
||||
}
|
||||
|
||||
private void ShutdownSlots()
|
||||
@@ -68,6 +71,27 @@ public partial class InventorySystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void AfterAutoState(Entity<InventoryComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
UpdateInventoryTemplate(ent);
|
||||
}
|
||||
|
||||
protected virtual void UpdateInventoryTemplate(Entity<InventoryComponent> ent)
|
||||
{
|
||||
if (ent.Comp.LifeStage < ComponentLifeStage.Initialized)
|
||||
return;
|
||||
|
||||
if (!_prototypeManager.TryIndex(ent.Comp.TemplateId, out InventoryTemplatePrototype? invTemplate))
|
||||
return;
|
||||
|
||||
DebugTools.Assert(ent.Comp.Slots.Length == invTemplate.Slots.Length);
|
||||
|
||||
ent.Comp.Slots = invTemplate.Slots;
|
||||
|
||||
var ev = new InventoryTemplateUpdated();
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
}
|
||||
|
||||
private void OnOpenSlotStorage(OpenSlotStorageNetworkMessage ev, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession.AttachedEntity is not { Valid: true } uid)
|
||||
@@ -170,6 +194,31 @@ public partial class InventorySystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change the inventory template ID an entity is using. The new template must be compatible.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// For an inventory template to be compatible with another, it must have exactly the same slot names.
|
||||
/// All other changes are rejected.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="ent">The entity to update.</param>
|
||||
/// <param name="newTemplate">The ID of the new inventory template prototype.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if the new template is not compatible with the existing one.
|
||||
/// </exception>
|
||||
public void SetTemplateId(Entity<InventoryComponent> ent, ProtoId<InventoryTemplatePrototype> newTemplate)
|
||||
{
|
||||
var newPrototype = _prototypeManager.Index(newTemplate);
|
||||
|
||||
if (!newPrototype.Slots.Select(x => x.Name).SequenceEqual(ent.Comp.Slots.Select(x => x.Name)))
|
||||
throw new ArgumentException("Incompatible inventory template!");
|
||||
|
||||
ent.Comp.TemplateId = newTemplate;
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerator for iterating over an inventory's slot containers. Also has methods that skip empty containers.
|
||||
/// It should be safe to add or remove items while enumerating.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Strip;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -39,6 +40,10 @@ public sealed partial class SlotDefinition
|
||||
[DataField("displayName", required: true)]
|
||||
public string DisplayName { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this slot will have its item hidden in the strip menu, and block interactions.
|
||||
/// <seealso cref="SharedStrippableSystem.IsStripHidden"/>
|
||||
/// </summary>
|
||||
[DataField("stripHidden")] public bool StripHidden { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -32,6 +32,18 @@ public sealed partial class ItemToggleComponent : Component
|
||||
[DataField]
|
||||
public bool OnUse = true;
|
||||
|
||||
/// <summary>
|
||||
/// The localized text to display in the verb to activate.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string VerbToggleOn = "item-toggle-activate";
|
||||
|
||||
/// <summary>
|
||||
/// The localized text to display in the verb to de-activate.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string VerbToggleOff = "item-toggle-deactivate";
|
||||
|
||||
/// <summary>
|
||||
/// Whether the item's toggle can be predicted by the client.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
using Content.Shared.Item.ItemToggle;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Item.ItemToggle.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a verb for toggling something, requires <see cref="ItemToggleComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(ToggleVerbSystem))]
|
||||
public sealed partial class ToggleVerbComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Text the verb will have.
|
||||
/// Gets passed "entity" as the entity's identity string.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public LocId Text = string.Empty;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public sealed class ItemToggleSystem : EntitySystem
|
||||
|
||||
args.Verbs.Add(new ActivationVerb()
|
||||
{
|
||||
Text = !ent.Comp.Activated ? Loc.GetString("item-toggle-activate") : Loc.GetString("item-toggle-deactivate"),
|
||||
Text = !ent.Comp.Activated ? Loc.GetString(ent.Comp.VerbToggleOn) : Loc.GetString(ent.Comp.VerbToggleOff),
|
||||
Act = () =>
|
||||
{
|
||||
Toggle((ent.Owner, ent.Comp), user, predicted: ent.Comp.Predictable);
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Item.ItemToggle.Components;
|
||||
using Content.Shared.Verbs;
|
||||
|
||||
namespace Content.Shared.Item.ItemToggle;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a verb for toggling something with <see cref="ToggleVerbComponent"/>.
|
||||
/// </summary>
|
||||
public sealed class ToggleVerbSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ItemToggleSystem _toggle = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ToggleVerbComponent, GetVerbsEvent<ActivationVerb>>(OnGetVerbs);
|
||||
}
|
||||
|
||||
private void OnGetVerbs(Entity<ToggleVerbComponent> ent, ref GetVerbsEvent<ActivationVerb> args)
|
||||
{
|
||||
if (!args.CanAccess || !args.CanInteract)
|
||||
return;
|
||||
|
||||
var name = Identity.Entity(ent, EntityManager);
|
||||
var user = args.User;
|
||||
args.Verbs.Add(new ActivationVerb()
|
||||
{
|
||||
Text = Loc.GetString(ent.Comp.Text, ("entity", name)),
|
||||
Act = () => _toggle.Toggle(ent.Owner, user)
|
||||
});
|
||||
}
|
||||
}
|
||||
26
Content.Shared/Jaunt/JauntComponent.cs
Normal file
26
Content.Shared/Jaunt/JauntComponent.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Jaunt;
|
||||
|
||||
/// <summary>
|
||||
/// Used to control various aspects of a Jaunt.
|
||||
/// Can be used in place of giving a jaunt-action directly.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class JauntComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Which Jaunt Action the component should grant.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId JauntAction = "ActionPolymorphJaunt";
|
||||
|
||||
/// <summary>
|
||||
/// The jaunt action itself.
|
||||
/// </summary>
|
||||
public EntityUid? Action;
|
||||
|
||||
// TODO: Enter & Exit Times and Whitelist when Actions are reworked and can support it
|
||||
// TODO: Cooldown pausing when Actions can support it
|
||||
}
|
||||
26
Content.Shared/Jaunt/JauntSystem.cs
Normal file
26
Content.Shared/Jaunt/JauntSystem.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Content.Shared.Actions;
|
||||
|
||||
namespace Content.Shared.Jaunt;
|
||||
public sealed class JauntSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<JauntComponent, MapInitEvent>(OnInit);
|
||||
SubscribeLocalEvent<JauntComponent, ComponentShutdown>(OnShutdown);
|
||||
}
|
||||
|
||||
private void OnInit(Entity<JauntComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
_actions.AddAction(ent.Owner, ref ent.Comp.Action, ent.Comp.JauntAction);
|
||||
}
|
||||
|
||||
private void OnShutdown(Entity<JauntComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_actions.RemoveAction(ent.Owner, ent.Comp.Action);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
23
Content.Shared/Magic/Events/RandomGlobalSpawnSpellEvent.cs
Normal file
23
Content.Shared/Magic/Events/RandomGlobalSpawnSpellEvent.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Shared.Magic.Events;
|
||||
|
||||
public sealed partial class RandomGlobalSpawnSpellEvent : InstantActionEvent, ISpeakSpell
|
||||
{
|
||||
/// <summary>
|
||||
/// The list of prototypes this spell can spawn, will select one randomly
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<EntitySpawnEntry> Spawns = new();
|
||||
|
||||
/// <summary>
|
||||
/// Sound that will play globally when cast
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Magic/staff_animation.ogg");
|
||||
|
||||
[DataField]
|
||||
public string? Speech { get; private set; }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Numerics;
|
||||
using System.Numerics;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Systems;
|
||||
@@ -7,12 +7,17 @@ using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Doors.Systems;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Lock;
|
||||
using Content.Shared.Magic.Components;
|
||||
using Content.Shared.Magic.Events;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Speech.Muting;
|
||||
@@ -20,6 +25,7 @@ using Content.Shared.Storage;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Network;
|
||||
@@ -53,6 +59,9 @@ public abstract class SharedMagicSystem : EntitySystem
|
||||
[Dependency] private readonly LockSystem _lock = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -67,6 +76,7 @@ public abstract class SharedMagicSystem : EntitySystem
|
||||
SubscribeLocalEvent<SmiteSpellEvent>(OnSmiteSpell);
|
||||
SubscribeLocalEvent<KnockSpellEvent>(OnKnockSpell);
|
||||
SubscribeLocalEvent<ChargeSpellEvent>(OnChargeSpell);
|
||||
SubscribeLocalEvent<RandomGlobalSpawnSpellEvent>(OnRandomGlobalSpawnSpell);
|
||||
|
||||
// Spell wishlist
|
||||
// A wishlish of spells that I'd like to implement or planning on implementing in a future PR
|
||||
@@ -501,6 +511,37 @@ public abstract class SharedMagicSystem : EntitySystem
|
||||
_gunSystem.UpdateBasicEntityAmmoCount(wand.Value, basicAmmoComp.Count.Value + ev.Charge, basicAmmoComp);
|
||||
}
|
||||
// End Charge Spells
|
||||
#endregion
|
||||
#region Global Spells
|
||||
|
||||
private void OnRandomGlobalSpawnSpell(RandomGlobalSpawnSpellEvent ev)
|
||||
{
|
||||
if (!_net.IsServer || ev.Handled || !PassesSpellPrerequisites(ev.Action, ev.Performer) || ev.Spawns is not { } spawns)
|
||||
return;
|
||||
|
||||
ev.Handled = true;
|
||||
Speak(ev);
|
||||
|
||||
var allHumans = _mind.GetAliveHumans();
|
||||
|
||||
foreach (var human in allHumans)
|
||||
{
|
||||
if (!human.Comp.OwnedEntity.HasValue)
|
||||
continue;
|
||||
|
||||
var ent = human.Comp.OwnedEntity.Value;
|
||||
|
||||
var mapCoords = _transform.GetMapCoordinates(ent);
|
||||
foreach (var spawn in EntitySpawnCollection.GetSpawns(spawns, _random))
|
||||
{
|
||||
var spawned = Spawn(spawn, mapCoords);
|
||||
_hands.PickupOrDrop(ent, spawned);
|
||||
}
|
||||
}
|
||||
|
||||
_audio.PlayGlobal(ev.Sound, ev.Performer);
|
||||
}
|
||||
|
||||
#endregion
|
||||
// End Spells
|
||||
#endregion
|
||||
|
||||
39
Content.Shared/Medical/DefibrillatorEvents.cs
Normal file
39
Content.Shared/Medical/DefibrillatorEvents.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
namespace Content.Shared.Medical;
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly record struct TargetDefibrillatedEvent(EntityUid User, Entity<DefibrillatorComponent> Defibrillator);
|
||||
|
||||
public abstract class BeforeDefibrillatorZapsEvent : CancellableEntityEventArgs, IInventoryRelayEvent
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||
public EntityUid EntityUsingDefib;
|
||||
public readonly EntityUid Defib;
|
||||
public EntityUid DefibTarget;
|
||||
|
||||
public BeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibTarget)
|
||||
{
|
||||
EntityUsingDefib = entityUsingDefib;
|
||||
Defib = defib;
|
||||
DefibTarget = defibTarget;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the user using the defibrillator before is actually zaps someone.
|
||||
/// The event is triggered on the user and all their clothing.
|
||||
/// </summary>
|
||||
public sealed class SelfBeforeDefibrillatorZapsEvent : BeforeDefibrillatorZapsEvent
|
||||
{
|
||||
public SelfBeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibtarget) : base(entityUsingDefib, defib, defibtarget) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the target before it gets zapped with the defibrillator.
|
||||
/// The event is triggered on the target itself and all its clothing.
|
||||
/// </summary>
|
||||
public sealed class TargetBeforeDefibrillatorZapsEvent : BeforeDefibrillatorZapsEvent
|
||||
{
|
||||
public TargetBeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibtarget) : base(entityUsingDefib, defib, defibtarget) { }
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace Content.Shared.Medical;
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly record struct TargetDefibrillatedEvent(EntityUid User, Entity<DefibrillatorComponent> Defibrillator);
|
||||
@@ -546,22 +546,19 @@ public abstract class SharedMindSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Returns a list of every living humanoid player's minds, except for a single one which is exluded.
|
||||
/// </summary>
|
||||
public List<EntityUid> GetAliveHumansExcept(EntityUid exclude)
|
||||
public HashSet<Entity<MindComponent>> GetAliveHumans(EntityUid? exclude = null)
|
||||
{
|
||||
var mindQuery = EntityQuery<MindComponent>();
|
||||
|
||||
var allHumans = new List<EntityUid>();
|
||||
var allHumans = new HashSet<Entity<MindComponent>>();
|
||||
// HumanoidAppearanceComponent is used to prevent mice, pAIs, etc from being chosen
|
||||
var query = EntityQueryEnumerator<MindContainerComponent, MobStateComponent, HumanoidAppearanceComponent>();
|
||||
while (query.MoveNext(out var uid, out var mc, out var mobState, out _))
|
||||
var query = EntityQueryEnumerator<MobStateComponent, HumanoidAppearanceComponent>();
|
||||
while (query.MoveNext(out var uid, out var mobState, out _))
|
||||
{
|
||||
// the player needs to have a mind and not be the excluded one
|
||||
if (mc.Mind == null || mc.Mind == exclude)
|
||||
// the player needs to have a mind and not be the excluded one +
|
||||
// the player has to be alive
|
||||
if (!TryGetMind(uid, out var mind, out var mindComp) || mind == exclude || !_mobState.IsAlive(uid, mobState))
|
||||
continue;
|
||||
|
||||
// the player has to be alive
|
||||
if (_mobState.IsAlive(uid, mobState))
|
||||
allHumans.Add(mc.Mind.Value);
|
||||
allHumans.Add(new Entity<MindComponent>(mind, mindComp));
|
||||
}
|
||||
|
||||
return allHumans;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Follower.Components;
|
||||
using Content.Shared.Input;
|
||||
@@ -8,6 +9,7 @@ using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -21,6 +23,8 @@ namespace Content.Shared.Movement.Systems
|
||||
{
|
||||
public bool CameraRotationLocked { get; set; }
|
||||
|
||||
public static ProtoId<AlertPrototype> WalkingAlert = "Walking";
|
||||
|
||||
private void InitializeInput()
|
||||
{
|
||||
var moveUpCmdHandler = new MoverDirInputCmdHandler(this, Direction.North);
|
||||
@@ -460,7 +464,7 @@ namespace Content.Shared.Movement.Systems
|
||||
component.LastInputSubTick = 0;
|
||||
}
|
||||
|
||||
public void SetSprinting(Entity<InputMoverComponent> entity, ushort subTick, bool walking)
|
||||
public virtual void SetSprinting(Entity<InputMoverComponent> entity, ushort subTick, bool walking)
|
||||
{
|
||||
// Logger.Info($"[{_gameTiming.CurTick}/{subTick}] Sprint: {enabled}");
|
||||
|
||||
|
||||
@@ -9,12 +9,14 @@ namespace Content.Shared.Overlays;
|
||||
/// This component allows you to see health bars above damageable mobs.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState(true)]
|
||||
public sealed partial class ShowHealthBarsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays health bars of the damage containers.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[AutoNetworkedField]
|
||||
public List<ProtoId<DamageContainerPrototype>> DamageContainers = new()
|
||||
{
|
||||
"Biological"
|
||||
|
||||
@@ -8,12 +8,14 @@ namespace Content.Shared.Overlays;
|
||||
/// This component allows you to see health status icons above damageable mobs.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState(true)]
|
||||
public sealed partial class ShowHealthIconsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays health status icons of the damage containers.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[AutoNetworkedField]
|
||||
public List<ProtoId<DamageContainerPrototype>> DamageContainers = new()
|
||||
{
|
||||
"Biological"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Polymorph.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -7,9 +8,22 @@ namespace Content.Shared.Polymorph.Components;
|
||||
/// Component added to disguise entities.
|
||||
/// Used by client to copy over appearance from the disguise's source entity.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedChameleonProjectorSystem))]
|
||||
[AutoGenerateComponentState(true)]
|
||||
public sealed partial class ChameleonDisguiseComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The user of this disguise.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid User;
|
||||
|
||||
/// <summary>
|
||||
/// The projector that created this disguise.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid Projector;
|
||||
|
||||
/// <summary>
|
||||
/// The disguise source entity for copying the sprite.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using Content.Shared.Polymorph.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Polymorph.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Added to a player when they use a chameleon projector.
|
||||
/// Handles making them invisible and revealing when damaged enough or switching hands.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedChameleonProjectorSystem))]
|
||||
[AutoGenerateComponentState]
|
||||
public sealed partial class ChameleonDisguisedComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The disguise entity parented to the player.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid Disguise;
|
||||
|
||||
/// <summary>
|
||||
/// For client, whether the user's sprite was previously visible or not.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool WasVisible;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Shared.Polymorph;
|
||||
using Content.Shared.Polymorph.Systems;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -25,22 +24,26 @@ public sealed partial class ChameleonProjectorComponent : Component
|
||||
public EntityWhitelist? Blacklist;
|
||||
|
||||
/// <summary>
|
||||
/// Polymorph configuration for the disguise entity.
|
||||
/// Disguise entity to spawn and use.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public PolymorphConfiguration Polymorph = new();
|
||||
public EntProtoId DisguiseProto = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Action for disabling your disguise's rotation.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId NoRotAction = "ActionDisguiseNoRot";
|
||||
[DataField]
|
||||
public EntityUid? NoRotActionEntity;
|
||||
|
||||
/// <summary>
|
||||
/// Action for anchoring your disguise in place.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId AnchorAction = "ActionDisguiseAnchor";
|
||||
[DataField]
|
||||
public EntityUid? AnchorActionEntity;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum health to give the disguise.
|
||||
@@ -55,14 +58,8 @@ public sealed partial class ChameleonProjectorComponent : Component
|
||||
public float MaxHealth = 100f;
|
||||
|
||||
/// <summary>
|
||||
/// Popup shown to the user when they try to disguise as an invalid entity.
|
||||
/// User currently disguised by this projector, if any
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public LocId InvalidPopup = "chameleon-projector-invalid";
|
||||
|
||||
/// <summary>
|
||||
/// Popup shown to the user when they disguise as a valid entity.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public LocId SuccessPopup = "chameleon-projector-success";
|
||||
public EntityUid? Disguised;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
|
||||
|
||||
@@ -115,6 +116,18 @@ public sealed partial record PolymorphConfiguration
|
||||
[DataField(serverOnly: true)]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan Cooldown = TimeSpan.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// If not null, this sound will be played when being polymorphed into something.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier? PolymorphSound;
|
||||
|
||||
/// <summary>
|
||||
/// If not null, this sound will be played when being reverted from a polymorph.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier? ExitPolymorphSound;
|
||||
}
|
||||
|
||||
public enum PolymorphInventoryChange : byte
|
||||
|
||||
@@ -1,67 +1,264 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Coordinates;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Polymorph;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Polymorph.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Prototypes;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Storage.Components;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Content.Shared.Polymorph.Systems;
|
||||
|
||||
/// <summary>
|
||||
/// Handles whitelist/blacklist checking.
|
||||
/// Actual polymorphing and deactivation is done serverside.
|
||||
/// Handles disguise validation, disguising and revealing.
|
||||
/// Most appearance copying is done clientside.
|
||||
/// </summary>
|
||||
public abstract class SharedChameleonProjectorSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
[Dependency] private readonly INetManager _net = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly ISerializationManager _serMan = default!;
|
||||
[Dependency] private readonly MetaDataSystem _meta = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ChameleonDisguiseComponent, InteractHandEvent>(OnDisguiseInteractHand, before: [typeof(SharedItemSystem)]);
|
||||
SubscribeLocalEvent<ChameleonDisguiseComponent, DamageChangedEvent>(OnDisguiseDamaged);
|
||||
SubscribeLocalEvent<ChameleonDisguiseComponent, InsertIntoEntityStorageAttemptEvent>(OnDisguiseInsertAttempt);
|
||||
SubscribeLocalEvent<ChameleonDisguiseComponent, ComponentShutdown>(OnDisguiseShutdown);
|
||||
|
||||
SubscribeLocalEvent<ChameleonProjectorComponent, AfterInteractEvent>(OnInteract);
|
||||
SubscribeLocalEvent<ChameleonProjectorComponent, GetVerbsEvent<UtilityVerb>>(OnGetVerbs);
|
||||
SubscribeLocalEvent<ChameleonProjectorComponent, DisguiseToggleNoRotEvent>(OnToggleNoRot);
|
||||
SubscribeLocalEvent<ChameleonProjectorComponent, DisguiseToggleAnchoredEvent>(OnToggleAnchored);
|
||||
SubscribeLocalEvent<ChameleonProjectorComponent, HandDeselectedEvent>(OnDeselected);
|
||||
SubscribeLocalEvent<ChameleonProjectorComponent, GotUnequippedHandEvent>(OnUnequipped);
|
||||
SubscribeLocalEvent<ChameleonProjectorComponent, ComponentShutdown>(OnProjectorShutdown);
|
||||
}
|
||||
|
||||
#region Disguise entity
|
||||
|
||||
private void OnDisguiseInteractHand(Entity<ChameleonDisguiseComponent> ent, ref InteractHandEvent args)
|
||||
{
|
||||
TryReveal(ent.Comp.User);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnDisguiseDamaged(Entity<ChameleonDisguiseComponent> ent, ref DamageChangedEvent args)
|
||||
{
|
||||
// this mirrors damage 1:1
|
||||
if (args.DamageDelta is {} damage)
|
||||
_damageable.TryChangeDamage(ent.Comp.User, damage);
|
||||
}
|
||||
|
||||
private void OnDisguiseInsertAttempt(Entity<ChameleonDisguiseComponent> ent, ref InsertIntoEntityStorageAttemptEvent args)
|
||||
{
|
||||
// stay parented to the user, not the storage
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnDisguiseShutdown(Entity<ChameleonDisguiseComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_actions.RemoveProvidedActions(ent.Comp.User, ent.Comp.Projector);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Projector
|
||||
|
||||
private void OnInteract(Entity<ChameleonProjectorComponent> ent, ref AfterInteractEvent args)
|
||||
{
|
||||
if (!args.CanReach || args.Target is not {} target)
|
||||
if (args.Handled || !args.CanReach || args.Target is not {} target)
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
TryDisguise(ent, args.User, target);
|
||||
}
|
||||
|
||||
private void OnGetVerbs(Entity<ChameleonProjectorComponent> ent, ref GetVerbsEvent<UtilityVerb> args)
|
||||
{
|
||||
if (!args.CanAccess)
|
||||
return;
|
||||
|
||||
var user = args.User;
|
||||
args.Handled = true;
|
||||
var target = args.Target;
|
||||
args.Verbs.Add(new UtilityVerb()
|
||||
{
|
||||
Act = () =>
|
||||
{
|
||||
TryDisguise(ent, user, target);
|
||||
},
|
||||
Text = Loc.GetString("chameleon-projector-set-disguise")
|
||||
});
|
||||
}
|
||||
|
||||
public bool TryDisguise(Entity<ChameleonProjectorComponent> ent, EntityUid user, EntityUid target)
|
||||
{
|
||||
if (_container.IsEntityInContainer(target))
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString("chameleon-projector-inside-container"), target, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsInvalid(ent.Comp, target))
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString(ent.Comp.InvalidPopup), target, user);
|
||||
return;
|
||||
_popup.PopupClient(Loc.GetString("chameleon-projector-invalid"), target, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
_popup.PopupClient(Loc.GetString(ent.Comp.SuccessPopup), target, user);
|
||||
Disguise(ent.Comp, user, target);
|
||||
_popup.PopupClient(Loc.GetString("chameleon-projector-success"), target, user);
|
||||
Disguise(ent, user, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnToggleNoRot(Entity<ChameleonProjectorComponent> ent, ref DisguiseToggleNoRotEvent args)
|
||||
{
|
||||
if (ent.Comp.Disguised is not {} uid)
|
||||
return;
|
||||
|
||||
var xform = Transform(uid);
|
||||
_xform.SetLocalRotationNoLerp(uid, 0, xform);
|
||||
xform.NoLocalRotation = !xform.NoLocalRotation;
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnToggleAnchored(Entity<ChameleonProjectorComponent> ent, ref DisguiseToggleAnchoredEvent args)
|
||||
{
|
||||
if (ent.Comp.Disguised is not {} uid)
|
||||
return;
|
||||
|
||||
var xform = Transform(uid);
|
||||
if (xform.Anchored)
|
||||
_xform.Unanchor(uid, xform);
|
||||
else
|
||||
_xform.AnchorEntity((uid, xform));
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnDeselected(Entity<ChameleonProjectorComponent> ent, ref HandDeselectedEvent args)
|
||||
{
|
||||
RevealProjector(ent);
|
||||
}
|
||||
|
||||
private void OnUnequipped(Entity<ChameleonProjectorComponent> ent, ref GotUnequippedHandEvent args)
|
||||
{
|
||||
RevealProjector(ent);
|
||||
}
|
||||
|
||||
private void OnProjectorShutdown(Entity<ChameleonProjectorComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
RevealProjector(ent);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region API
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if an entity cannot be used as a disguise.
|
||||
/// </summary>
|
||||
public bool IsInvalid(ChameleonProjectorComponent comp, EntityUid target)
|
||||
{
|
||||
return _whitelistSystem.IsWhitelistFail(comp.Whitelist, target)
|
||||
|| _whitelistSystem.IsBlacklistPass(comp.Blacklist, target);
|
||||
return _whitelist.IsWhitelistFail(comp.Whitelist, target)
|
||||
|| _whitelist.IsBlacklistPass(comp.Blacklist, target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On server, polymorphs the user into an entity and sets up the disguise.
|
||||
/// </summary>
|
||||
public virtual void Disguise(ChameleonProjectorComponent comp, EntityUid user, EntityUid entity)
|
||||
public void Disguise(Entity<ChameleonProjectorComponent> ent, EntityUid user, EntityUid entity)
|
||||
{
|
||||
var proj = ent.Comp;
|
||||
|
||||
// no spawning prediction sorry
|
||||
if (_net.IsClient)
|
||||
return;
|
||||
|
||||
// reveal first to allow quick switching
|
||||
TryReveal(user);
|
||||
|
||||
// add actions for controlling transform aspects
|
||||
_actions.AddAction(user, ref proj.NoRotActionEntity, proj.NoRotAction, container: ent);
|
||||
_actions.AddAction(user, ref proj.AnchorActionEntity, proj.AnchorAction, container: ent);
|
||||
|
||||
proj.Disguised = user;
|
||||
|
||||
var disguise = SpawnAttachedTo(proj.DisguiseProto, user.ToCoordinates());
|
||||
|
||||
var disguised = AddComp<ChameleonDisguisedComponent>(user);
|
||||
disguised.Disguise = disguise;
|
||||
Dirty(user, disguised);
|
||||
|
||||
// make disguise look real (for simple things at least)
|
||||
var meta = MetaData(entity);
|
||||
_meta.SetEntityName(disguise, meta.EntityName);
|
||||
_meta.SetEntityDescription(disguise, meta.EntityDescription);
|
||||
|
||||
var comp = EnsureComp<ChameleonDisguiseComponent>(disguise);
|
||||
comp.User = user;
|
||||
comp.Projector = ent;
|
||||
comp.SourceEntity = entity;
|
||||
comp.SourceProto = Prototype(entity)?.ID;
|
||||
Dirty(disguise, comp);
|
||||
|
||||
// item disguises can be picked up to be revealed, also makes sure their examine size is correct
|
||||
CopyComp<ItemComponent>((disguise, comp));
|
||||
|
||||
_appearance.CopyData(entity, disguise);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the disguise, if the user is disguised.
|
||||
/// </summary>
|
||||
public bool TryReveal(Entity<ChameleonDisguisedComponent?> ent)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp, false))
|
||||
return false;
|
||||
|
||||
if (TryComp<ChameleonDisguiseComponent>(ent.Comp.Disguise, out var disguise)
|
||||
&& TryComp<ChameleonProjectorComponent>(disguise.Projector, out var proj))
|
||||
{
|
||||
proj.Disguised = null;
|
||||
}
|
||||
|
||||
var xform = Transform(ent);
|
||||
xform.NoLocalRotation = false;
|
||||
_xform.Unanchor(ent, xform);
|
||||
|
||||
Del(ent.Comp.Disguise);
|
||||
RemComp<ChameleonDisguisedComponent>(ent);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reveal a projector's user, if any.
|
||||
/// </summary>
|
||||
public void RevealProjector(Entity<ChameleonProjectorComponent> ent)
|
||||
{
|
||||
if (ent.Comp.Disguised is {} user)
|
||||
TryReveal(user);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Copy a component from the source entity/prototype to the disguise entity.
|
||||
/// </summary>
|
||||
|
||||
@@ -8,6 +8,12 @@ namespace Content.Shared.Projectiles;
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ProjectileComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The angle of the fired projectile.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public Angle Angle;
|
||||
|
||||
/// <summary>
|
||||
/// The effect that appears when a projectile collides with an entity.
|
||||
/// </summary>
|
||||
|
||||
@@ -26,10 +26,10 @@ public abstract partial class SharedSalvageSystem : EntitySystem
|
||||
[ValidatePrototypeId<SalvageLootPrototype>]
|
||||
public const string ExpeditionsLootProto = "SalvageLoot";
|
||||
|
||||
public static string GetFTLName(DatasetPrototype dataset, int seed)
|
||||
public string GetFTLName(LocalizedDatasetPrototype dataset, int seed)
|
||||
{
|
||||
var random = new System.Random(seed);
|
||||
return $"{dataset.Values[random.Next(dataset.Values.Count)]}-{random.Next(10, 100)}-{(char) (65 + random.Next(26))}";
|
||||
return $"{Loc.GetString(dataset.Values[random.Next(dataset.Values.Count)])}-{random.Next(10, 100)}-{(char) (65 + random.Next(26))}";
|
||||
}
|
||||
|
||||
public SalvageMission GetMission(SalvageDifficultyPrototype difficulty, int seed)
|
||||
|
||||
155
Content.Shared/Silicons/Borgs/BorgTypePrototype.cs
Normal file
155
Content.Shared/Silicons/Borgs/BorgTypePrototype.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Information for a borg type that can be selected by <see cref="BorgSwitchableTypeComponent"/>.
|
||||
/// </summary>
|
||||
/// <seealso cref="SharedBorgSwitchableTypeSystem"/>
|
||||
[Prototype]
|
||||
public sealed partial class BorgTypePrototype : IPrototype
|
||||
{
|
||||
[ValidatePrototypeId<SoundCollectionPrototype>]
|
||||
private static readonly ProtoId<SoundCollectionPrototype> DefaultFootsteps = new("FootstepBorg");
|
||||
|
||||
[IdDataField]
|
||||
public required string ID { get; init; }
|
||||
|
||||
//
|
||||
// Description info (name/desc) is configured via localization strings directly.
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// The prototype displayed in the selection menu for this type.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public required EntProtoId DummyPrototype { get; init; }
|
||||
|
||||
//
|
||||
// Functional information
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// The amount of free module slots this borg type has.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This count is on top of the modules specified in <see cref="DefaultModules"/>.
|
||||
/// </remarks>
|
||||
/// <seealso cref="BorgChassisComponent.ModuleCount"/>
|
||||
[DataField]
|
||||
public int ExtraModuleCount { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The whitelist for borg modules that can be inserted into this borg type.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgChassisComponent.ModuleWhitelist"/>
|
||||
[DataField]
|
||||
public EntityWhitelist? ModuleWhitelist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Inventory template used by this borg.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This template must be compatible with the normal borg templates,
|
||||
/// so in practice it can only be used to differentiate the visual position of the slots on the character sprites.
|
||||
/// </remarks>
|
||||
/// <seealso cref="InventorySystem.SetTemplateId"/>
|
||||
[DataField]
|
||||
public ProtoId<InventoryTemplatePrototype> InventoryTemplateId { get; set; } = "borgShort";
|
||||
|
||||
/// <summary>
|
||||
/// Radio channels that this borg will gain access to from this module.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These channels are provided on top of the ones specified in
|
||||
/// <see cref="BorgSwitchableTypeComponent.InherentRadioChannels"/>.
|
||||
/// </remarks>
|
||||
[DataField]
|
||||
public ProtoId<RadioChannelPrototype>[] RadioChannels = [];
|
||||
|
||||
/// <summary>
|
||||
/// Borg module types that are always available to borgs of this type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These modules still work like modules, although they cannot be removed from the borg.
|
||||
/// </remarks>
|
||||
/// <seealso cref="BorgModuleComponent.DefaultModule"/>
|
||||
[DataField]
|
||||
public EntProtoId[] DefaultModules = [];
|
||||
|
||||
/// <summary>
|
||||
/// Additional components to add to the borg entity when this type is selected.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ComponentRegistry? AddComponents { get; set; }
|
||||
|
||||
//
|
||||
// Visual information
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// The sprite state for the main borg body.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string SpriteBodyState { get; set; } = "robot";
|
||||
|
||||
/// <summary>
|
||||
/// An optional movement sprite state for the main borg body.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string? SpriteBodyMovementState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sprite state used to indicate that the borg has a mind in it.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgChassisComponent.HasMindState"/>
|
||||
[DataField]
|
||||
public string SpriteHasMindState { get; set; } = "robot_e";
|
||||
|
||||
/// <summary>
|
||||
/// Sprite state used to indicate that the borg has no mind in it.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgChassisComponent.NoMindState"/>
|
||||
[DataField]
|
||||
public string SpriteNoMindState { get; set; } = "robot_e_r";
|
||||
|
||||
/// <summary>
|
||||
/// Sprite state used when the borg's flashlight is on.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string SpriteToggleLightState { get; set; } = "robot_l";
|
||||
|
||||
//
|
||||
// Minor information
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// String to use on petting success.
|
||||
/// </summary>
|
||||
/// <seealso cref="InteractionPopupComponent"/>
|
||||
[DataField]
|
||||
public string PetSuccessString { get; set; } = "petting-success-generic-cyborg";
|
||||
|
||||
/// <summary>
|
||||
/// String to use on petting failure.
|
||||
/// </summary>
|
||||
/// <seealso cref="InteractionPopupComponent"/>
|
||||
[DataField]
|
||||
public string PetFailureString { get; set; } = "petting-failure-generic-cyborg";
|
||||
|
||||
//
|
||||
// Sounds
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Sound specifier for footstep sounds created by this borg.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier FootstepCollection { get; set; } = new SoundCollectionSpecifier(DefaultFootsteps);
|
||||
}
|
||||
@@ -89,5 +89,18 @@ public enum BorgVisuals : byte
|
||||
[Serializable, NetSerializable]
|
||||
public enum BorgVisualLayers : byte
|
||||
{
|
||||
Light
|
||||
/// <summary>
|
||||
/// Main borg body layer.
|
||||
/// </summary>
|
||||
Body,
|
||||
|
||||
/// <summary>
|
||||
/// Layer for the borg's mind state.
|
||||
/// </summary>
|
||||
Light,
|
||||
|
||||
/// <summary>
|
||||
/// Layer for the borg flashlight status.
|
||||
/// </summary>
|
||||
LightStatus,
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Content.Shared.Silicons.Borgs.Components;
|
||||
/// to give them unique abilities and attributes.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedBorgSystem))]
|
||||
[AutoGenerateComponentState]
|
||||
public sealed partial class BorgModuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
@@ -16,6 +17,13 @@ public sealed partial class BorgModuleComponent : Component
|
||||
public EntityUid? InstalledEntity;
|
||||
|
||||
public bool Installed => InstalledEntity != null;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this is a "default" module that cannot be removed from a borg.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[AutoNetworkedField]
|
||||
public bool DefaultModule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Radio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Silicons.Borgs.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Component for borgs that can switch their "type" after being created.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is used by all NT borgs, on construction and round-start spawn.
|
||||
/// Borgs are effectively useless until they have made their choice of type.
|
||||
/// Borg type selections are currently irreversible.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Available types are specified in <see cref="BorgTypePrototype"/>s.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <seealso cref="SharedBorgSwitchableTypeSystem"/>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState(raiseAfterAutoHandleState: true)]
|
||||
[Access(typeof(SharedBorgSwitchableTypeSystem))]
|
||||
public sealed partial class BorgSwitchableTypeComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Action entity used by players to select their type.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? SelectTypeAction;
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected borg type, if any.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This can be set in a prototype to immediately apply a borg type, and not have switching support.
|
||||
/// </remarks>
|
||||
[DataField, AutoNetworkedField]
|
||||
public ProtoId<BorgTypePrototype>? SelectedBorgType;
|
||||
|
||||
/// <summary>
|
||||
/// Radio channels that the borg will always have. These are added on top of the selected type's radio channels.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<RadioChannelPrototype>[] InherentRadioChannels = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action event used to open the selection menu of a <see cref="BorgSwitchableTypeComponent"/>.
|
||||
/// </summary>
|
||||
public sealed partial class BorgToggleSelectTypeEvent : InstantActionEvent;
|
||||
|
||||
/// <summary>
|
||||
/// UI message used by a borg to select their type with <see cref="BorgSwitchableTypeComponent"/>.
|
||||
/// </summary>
|
||||
/// <param name="prototype">The borg type prototype that the user selected.</param>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BorgSelectTypeMessage(ProtoId<BorgTypePrototype> prototype) : BoundUserInterfaceMessage
|
||||
{
|
||||
public ProtoId<BorgTypePrototype> Prototype = prototype;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI key used by the selection menu for <see cref="BorgSwitchableTypeComponent"/>.
|
||||
/// </summary>
|
||||
[NetSerializable, Serializable]
|
||||
public enum BorgSwitchableTypeUiKey : byte
|
||||
{
|
||||
SelectBorgType,
|
||||
}
|
||||
125
Content.Shared/Silicons/Borgs/SharedBorgSwitchableTypeSystem.cs
Normal file
125
Content.Shared/Silicons/Borgs/SharedBorgSwitchableTypeSystem.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Implements borg type switching.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgSwitchableTypeComponent"/>
|
||||
public abstract class SharedBorgSwitchableTypeSystem : EntitySystem
|
||||
{
|
||||
// TODO: Allow borgs to be reset to default configuration.
|
||||
|
||||
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
|
||||
[Dependency] protected readonly IPrototypeManager Prototypes = default!;
|
||||
[Dependency] private readonly InteractionPopupSystem _interactionPopup = default!;
|
||||
|
||||
[ValidatePrototypeId<EntityPrototype>]
|
||||
public const string ActionId = "ActionSelectBorgType";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<BorgSwitchableTypeComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<BorgSwitchableTypeComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<BorgSwitchableTypeComponent, BorgToggleSelectTypeEvent>(OnSelectBorgTypeAction);
|
||||
|
||||
Subs.BuiEvents<BorgSwitchableTypeComponent>(BorgSwitchableTypeUiKey.SelectBorgType,
|
||||
sub =>
|
||||
{
|
||||
sub.Event<BorgSelectTypeMessage>(SelectTypeMessageHandler);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// UI-adjacent code
|
||||
//
|
||||
|
||||
private void OnMapInit(Entity<BorgSwitchableTypeComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
_actionsSystem.AddAction(ent, ref ent.Comp.SelectTypeAction, ActionId);
|
||||
Dirty(ent);
|
||||
|
||||
if (ent.Comp.SelectedBorgType != null)
|
||||
{
|
||||
SelectBorgModule(ent, ent.Comp.SelectedBorgType.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShutdown(Entity<BorgSwitchableTypeComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_actionsSystem.RemoveAction(ent, ent.Comp.SelectTypeAction);
|
||||
}
|
||||
|
||||
private void OnSelectBorgTypeAction(Entity<BorgSwitchableTypeComponent> ent, ref BorgToggleSelectTypeEvent args)
|
||||
{
|
||||
if (args.Handled || !TryComp<ActorComponent>(ent, out var actor))
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
_userInterface.TryToggleUi((ent.Owner, null), BorgSwitchableTypeUiKey.SelectBorgType, actor.PlayerSession);
|
||||
}
|
||||
|
||||
private void SelectTypeMessageHandler(Entity<BorgSwitchableTypeComponent> ent, ref BorgSelectTypeMessage args)
|
||||
{
|
||||
if (ent.Comp.SelectedBorgType != null)
|
||||
return;
|
||||
|
||||
if (!Prototypes.HasIndex(args.Prototype))
|
||||
return;
|
||||
|
||||
SelectBorgModule(ent, args.Prototype);
|
||||
}
|
||||
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
|
||||
protected virtual void SelectBorgModule(
|
||||
Entity<BorgSwitchableTypeComponent> ent,
|
||||
ProtoId<BorgTypePrototype> borgType)
|
||||
{
|
||||
ent.Comp.SelectedBorgType = borgType;
|
||||
|
||||
_actionsSystem.RemoveAction(ent, ent.Comp.SelectTypeAction);
|
||||
ent.Comp.SelectTypeAction = null;
|
||||
Dirty(ent);
|
||||
|
||||
_userInterface.CloseUi((ent.Owner, null), BorgSwitchableTypeUiKey.SelectBorgType);
|
||||
|
||||
UpdateEntityAppearance(ent);
|
||||
}
|
||||
|
||||
protected void UpdateEntityAppearance(Entity<BorgSwitchableTypeComponent> entity)
|
||||
{
|
||||
if (!Prototypes.TryIndex(entity.Comp.SelectedBorgType, out var proto))
|
||||
return;
|
||||
|
||||
UpdateEntityAppearance(entity, proto);
|
||||
}
|
||||
|
||||
protected virtual void UpdateEntityAppearance(
|
||||
Entity<BorgSwitchableTypeComponent> entity,
|
||||
BorgTypePrototype prototype)
|
||||
{
|
||||
if (TryComp(entity, out InteractionPopupComponent? popup))
|
||||
{
|
||||
_interactionPopup.SetInteractSuccessString((entity.Owner, popup), prototype.PetSuccessString);
|
||||
_interactionPopup.SetInteractFailureString((entity.Owner, popup), prototype.PetFailureString);
|
||||
}
|
||||
|
||||
if (TryComp(entity, out FootstepModifierComponent? footstepModifier))
|
||||
{
|
||||
footstepModifier.FootstepSoundCollection = prototype.FootstepCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user