diff --git a/Content.Common.Data/_Goobstation/CCVar/CCVars.Goob.cs b/Content.Common.Data/_Goobstation/CCVar/CCVars.Goob.cs new file mode 100644 index 0000000000..02b68a7739 --- /dev/null +++ b/Content.Common.Data/_Goobstation/CCVar/CCVars.Goob.cs @@ -0,0 +1,682 @@ +// SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Aiden +// SPDX-FileCopyrightText: 2025 Aidenkrz +// SPDX-FileCopyrightText: 2025 Armok <155400926+ARMOKS@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 August Eymann +// SPDX-FileCopyrightText: 2025 Aviu00 <93730715+Aviu00@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Aviu00 +// SPDX-FileCopyrightText: 2025 Conchelle +// SPDX-FileCopyrightText: 2025 DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 DrSmugleaf +// SPDX-FileCopyrightText: 2025 Ducks <97200673+TwoDucksOnnaPlane@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Eagle +// SPDX-FileCopyrightText: 2025 GoobBot +// SPDX-FileCopyrightText: 2025 Ichaie <167008606+Ichaie@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Ilya246 <57039557+Ilya246@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 JORJ949 <159719201+JORJ949@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Misandry +// SPDX-FileCopyrightText: 2025 MortalBaguette <169563638+MortalBaguette@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Panela <107573283+AgentePanela@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Piras314 +// SPDX-FileCopyrightText: 2025 Poips +// SPDX-FileCopyrightText: 2025 PuroSlavKing <103608145+PuroSlavKing@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 SX-7 <92227810+SX-7@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 SX-7 +// SPDX-FileCopyrightText: 2025 Sara Aldrete's Top Guy +// SPDX-FileCopyrightText: 2025 Solstice +// SPDX-FileCopyrightText: 2025 SolsticeOfTheWinter +// SPDX-FileCopyrightText: 2025 Steve +// SPDX-FileCopyrightText: 2025 Ted Lukin <66275205+pheenty@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 TheBorzoiMustConsume <197824988+TheBorzoiMustConsume@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Tim +// SPDX-FileCopyrightText: 2025 Timfa +// SPDX-FileCopyrightText: 2025 VMSolidus +// SPDX-FileCopyrightText: 2025 Whisper <121047731+QuietlyWhisper@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 blobadoodle +// SPDX-FileCopyrightText: 2025 coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 deltanedas <39013340+deltanedas@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 deltanedas <@deltanedas:kde.org> +// SPDX-FileCopyrightText: 2025 github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 gluesniffler <159397573+gluesniffler@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 gluesniffler +// SPDX-FileCopyrightText: 2025 gus +// SPDX-FileCopyrightText: 2025 kamkoi +// SPDX-FileCopyrightText: 2025 marc-pelletier <113944176+marc-pelletier@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 shibe <95730644+shibechef@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 tetra <169831122+Foralemes@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 vanx <61917534+Vaaankas@users.noreply.github.com> +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +using Robust.Shared.Configuration; + +namespace Content.Goobstation.Common.CCVar; + +[CVarDefs] +public sealed partial class GoobCVars +{ + /// + /// Whether pipes will unanchor on ANY conflicting connection. May break maps. + /// If false, allows you to stack pipes as long as new directions are added (i.e. in a new pipe rotation, layer or multi-Z link), otherwise unanchoring them. + /// + public static readonly CVarDef StrictPipeStacking = + CVarDef.Create("atmos.strict_pipe_stacking", false, CVar.SERVERONLY); + + /// + /// If an object's mass is below this number, then this number is used in place of mass to determine whether air pressure can throw an object. + /// This has nothing to do with throwing force, only acting as a way of reducing the odds of tiny 5 gram objects from being yeeted by people's breath + /// + /// + /// If you are reading this because you want to change it, consider looking into why almost every item in the game weighs only 5 grams + /// And maybe do your part to fix that? :) + /// + public static readonly CVarDef SpaceWindMinimumCalculatedMass = + CVarDef.Create("atmos.space_wind_minimum_calculated_mass", 10f, CVar.SERVERONLY); + + /// + /// Calculated as 1/Mass, where Mass is the physics.Mass of the desired threshold. + /// If an object's inverse mass is lower than this, it is capped at this. Basically, an upper limit to how heavy an object can be before it stops resisting space wind more. + /// + public static readonly CVarDef SpaceWindMaximumCalculatedInverseMass = + CVarDef.Create("atmos.space_wind_maximum_calculated_inverse_mass", 0.04f, CVar.SERVERONLY); + + /// + /// Increases default airflow calculations to O(n^2) complexity, for use with heavy space wind optimizations. Potato servers BEWARE + /// This solves the problem of objects being trapped in an infinite loop of slamming into a wall repeatedly. + /// + public static readonly CVarDef MonstermosUseExpensiveAirflow = + CVarDef.Create("atmos.mmos_expensive_airflow", true, CVar.SERVERONLY); + + /// + /// A multiplier on the amount of force applied to Humanoid entities, as tracked by HumanoidAppearanceComponent + /// This multiplier is added after all other checks are made, and applies to both throwing force, and how easy it is for an entity to be thrown. + /// + public static readonly CVarDef AtmosHumanoidThrowMultiplier = + CVarDef.Create("atmos.humanoid_throw_multiplier", 2f, CVar.SERVERONLY); + + /// + /// Taken as the cube of a tile's mass, this acts as a minimum threshold of mass for which air pressure calculates whether or not to rip a tile from the floor + /// This should be set by default to the cube of the game's lowest mass tile as defined in their prototypes, but can be increased for server performance reasons + /// + public static readonly CVarDef MonstermosRipTilesMinimumPressure = + CVarDef.Create("atmos.monstermos_rip_tiles_min_pressure", 7500f, CVar.SERVERONLY); + + /// + /// Taken after the minimum pressure is checked, the effective pressure is multiplied by this amount. + /// This allows server hosts to finely tune how likely floor tiles are to be ripped apart by air pressure + /// + public static readonly CVarDef MonstermosRipTilesPressureOffset = + CVarDef.Create("atmos.monstermos_rip_tiles_pressure_offset", 0.44f, CVar.SERVERONLY); + + /// + /// Indicates how much players are required for the round to be considered lowpop. + /// Used for dynamic gamemode. + /// + public static readonly CVarDef LowpopThreshold = + CVarDef.Create("game.players.lowpop_threshold", 15f, CVar.SERVERONLY); + + /// + /// Indicates how much players are required for the round to be considered highpop. + /// Used for dynamic gamemode. + /// + public static readonly CVarDef HighpopThreshold = + CVarDef.Create("game.players.highpop_threshold", 50f, CVar.SERVERONLY); + + /// + /// Is ore silo enabled. + /// + public static readonly CVarDef SiloEnabled = + CVarDef.Create("goob.silo_enabled", true, CVar.SERVER | CVar.REPLICATED); + + /// + /// Set a max drunk time in seconds to prevent permanent drunkeness. + /// + public static readonly CVarDef MaxDrunkTime = + CVarDef.Create("goob.max_drunk_time", 1500f, CVar.SERVER | CVar.REPLICATED); + + #region Player Listener + + /// + /// Is sprint enabled. + /// + public static readonly CVarDef ToggleSprint = + CVarDef.Create("control.toggle_sprint", true, CVar.CLIENTONLY | CVar.ARCHIVE); + + /// + /// Enable Dorm Notifier + /// + public static readonly CVarDef DormNotifier = + CVarDef.Create("dorm_notifier.enable", true, CVar.SERVER); + + /// + /// Check for dorm activity every X amount of ticks + /// Default is 10. + /// + public static readonly CVarDef DormNotifierFrequency = + CVarDef.Create("dorm_notifier.frequency", 10, CVar.SERVER); + + /// + /// Time given to be found to be engaging in dorm activity + /// Default is 180. + /// + public static readonly CVarDef DormNotifierPresenceTimeout = + CVarDef.Create("dorm_notifier.timeout", 180, CVar.SERVER, "Mark as condemned if present near a dorm marker for more than X amount of seconds."); + + /// + /// Time given to be found engaging in dorm activity if any of the sinners are nude + /// Default if 60. + /// + public static readonly CVarDef DormNotifierPresenceTimeoutNude = + CVarDef.Create("dorm_notifier.timeout_nude", 60, CVar.SERVER, "Mark as condemned if present near a dorm marker for more than X amount of seconds while being nude."); + + /// + /// Broadcast to all players that a player has ragequit. + /// + public static readonly CVarDef PlayerRageQuitNotify = + CVarDef.Create("ragequit.notify", true, CVar.SERVERONLY); + + /// + /// Time between being eligible for a "rage quit" after reaching a damage threshold. + /// Default is 5f. + /// + public static readonly CVarDef PlayerRageQuitTimeThreshold = + CVarDef.Create("ragequit.threshold", 30f, CVar.SERVERONLY); + + /// + /// Log ragequits to a discord webhook, set to empty to disable. + /// + public static readonly CVarDef PlayerRageQuitDiscordWebhook = + CVarDef.Create("ragequit.discord_webhook", "", CVar.SERVERONLY | CVar.CONFIDENTIAL); + + #endregion PlayerListener + + #region Discord AHelp Reply System + + /// + /// If an admin replies to users from discord, should it use their discord role color? (if applicable) + /// Overrides DiscordReplyColor and AdminBwoinkColor. + /// + public static readonly CVarDef UseDiscordRoleColor = + CVarDef.Create("admin.use_discord_role_color", true, CVar.SERVERONLY); + + /// + /// If an admin replies to users from discord, should it use their discord role name? (if applicable) + /// + public static readonly CVarDef UseDiscordRoleName = + CVarDef.Create("admin.use_discord_role_name", true, CVar.SERVERONLY); + + /// + /// The text before an admin's name when replying from discord to indicate they're speaking from discord. + /// + public static readonly CVarDef DiscordReplyPrefix = + CVarDef.Create("admin.discord_reply_prefix", "(DISCORD) ", CVar.SERVERONLY); + + /// + /// The color of the names of admins. This is the fallback color for admins. + /// + public static readonly CVarDef AdminBwoinkColor = + CVarDef.Create("admin.admin_bwoink_color", "red", CVar.SERVERONLY); + + /// + /// The color of the names of admins who reply from discord. Leave empty to disable. + /// Overrides AdminBwoinkColor. + /// + public static readonly CVarDef DiscordReplyColor = + CVarDef.Create("admin.discord_reply_color", string.Empty, CVar.SERVERONLY); + + /// + /// Use the admin's Admin OOC color in bwoinks. + /// If either the ooc color or this is not set, uses the admin.admin_bwoink_color value. + /// + public static readonly CVarDef UseAdminOOCColorInBwoinks = + CVarDef.Create("admin.bwoink_use_admin_ooc_color", true, CVar.SERVERONLY); + + /// + /// Discord Webhook for the station report + /// + public static readonly CVarDef StationReportDiscordWebHook = + CVarDef.Create("stationreport.discord_webhook", "", CVar.SERVERONLY | CVar.CONFIDENTIAL); + + #endregion + + /// + /// Goobstation: The amount of time between NPC Silicons draining their battery in seconds. + /// + public static readonly CVarDef SiliconNpcUpdateTime = + CVarDef.Create("silicon.npcupdatetime", 1.5f, CVar.SERVERONLY); + + /// + /// Should the player automatically get up after being knocked down + /// + public static readonly CVarDef AutoGetUp = + CVarDef.Create("white.auto_get_up", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); // WD EDIT + + /// + /// Sets the size of the hitbox where projectile/laser will hit any entity regardless of crawling + /// + public static readonly CVarDef CrawlHitzoneSize = + CVarDef.Create("goob.crawl_hitzone_size", 0.4f, CVar.SERVER | CVar.REPLICATED); + + #region Blob + public static readonly CVarDef BlobMax = + CVarDef.Create("blob.max", 3, CVar.SERVERONLY); + + public static readonly CVarDef BlobPlayersPer = + CVarDef.Create("blob.players_per", 20, CVar.SERVERONLY); + + public static readonly CVarDef BlobCanGrowInSpace = + CVarDef.Create("blob.grow_space", true, CVar.SERVER); + + #endregion + + #region Mechs + + /// + /// Whether or not players can use mech guns outside of mechs. + /// + public static readonly CVarDef MechGunOutsideMech = + CVarDef.Create("mech.gun_outside_mech", true, CVar.SERVER | CVar.REPLICATED); + + #endregion + + #region RMC + + public static readonly CVarDef RMCPatronLobbyMessageTimeSeconds = + CVarDef.Create("rmc.patron_lobby_message_time_seconds", 30, CVar.REPLICATED | CVar.SERVER); + + public static readonly CVarDef RMCPatronLobbyMessageInitialDelaySeconds = + CVarDef.Create("rmc.patron_lobby_message_initial_delay_seconds", 5, CVar.REPLICATED | CVar.SERVER); + + public static readonly CVarDef RMCDiscordAccountLinkingMessageLink = + CVarDef.Create("rmc.discord_account_linking_message_link", "", CVar.REPLICATED | CVar.SERVER); + + #endregion + + public static readonly CVarDef PatronSupportLastShown = + CVarDef.Create("patron.support_last_shown", "", CVar.CLIENTONLY | CVar.ARCHIVE); + + public static readonly CVarDef PatronAskSupport = + CVarDef.Create("patron.ask_support", 7, CVar.REPLICATED | CVar.SERVER); + + #region Xenobiology + + public static readonly CVarDef BreedingInterval = + CVarDef.Create("xenobiology.breeding.interval", 1f, CVar.REPLICATED | CVar.SERVER); + + #endregion + + #region Goobcoins + + public static readonly CVarDef GoobcoinsPerPlayer = + CVarDef.Create("servercurrency.per_player", 10, CVar.SERVERONLY); + + public static readonly CVarDef GoobcoinNonAntagMultiplier = + CVarDef.Create("servercurrency.non_antag_multiplier", 1, CVar.SERVERONLY); + + public static readonly CVarDef GoobcoinServerMultiplier = + CVarDef.Create("servercurrency.server_multiplier", 1, CVar.SERVERONLY); + + public static readonly CVarDef GoobcoinMinPlayers = + CVarDef.Create("servercurrency.min_players", 5, CVar.SERVERONLY); + + public static readonly CVarDef GoobcoinUseLowpopMultiplier = + CVarDef.Create("servercurrency.use_lowpop_multiplier", true, CVar.SERVERONLY); + + public static readonly CVarDef GoobcoinLowpopMultiplierStrength = + CVarDef.Create("servercurrency.lowpop_multiplier_strength", 1.0, CVar.SERVERONLY); + + public static readonly CVarDef GoobcoinUseShortRoundPenalty = + CVarDef.Create("servercurrency.use_shortround_penalty", true, CVar.SERVERONLY); + + public static readonly CVarDef GoobcoinShortRoundPenaltyTargetMinutes = + CVarDef.Create("servercurrency.shortround_penalty_target_minutes", 90, CVar.SERVERONLY); + + #endregion + + #region Station Events + + /// + /// Makes station event schedulers behave as if time is sped up by this much. + /// Supported for secret, secret+, and game director. + /// + public static readonly CVarDef StationEventSpeedup = + CVarDef.Create("stationevents.debug_speedup", 1f, CVar.SERVERONLY); + + /// + /// Makes station event schedulers consider the server to have this many extra living players. + /// Supported for secret+ and game director. + /// + public static readonly CVarDef StationEventPlayerBias = + CVarDef.Create("stationevents.debug_player_bias", 0, CVar.SERVERONLY); + + #region Game Director + + // also used by secret+ + public static readonly CVarDef MinimumTimeUntilFirstEvent = + CVarDef.Create("gamedirector.minimumtimeuntilfirstevent", 300f, CVar.SERVERONLY); + + // used by secret+ + public static readonly CVarDef RoundstartChaosScoreMultiplier = + CVarDef.Create("gamedirector.roundstart_chaos_score_multiplier", 1f, CVar.SERVERONLY); + + public static readonly CVarDef GameDirectorDebugPlayerCount = + CVarDef.Create("gamedirector.debug_player_count", 80, CVar.SERVERONLY); + + #endregion + + #endregion + + #region Contests System + + /// + /// The MASTER TOGGLE for the entire Contests System. + /// ALL CONTESTS BELOW, regardless of type or setting will output 1f when false. + /// + public static readonly CVarDef DoContestsSystem = + CVarDef.Create("contests.do_contests_system", true, CVar.REPLICATED | CVar.SERVER); + + /// + /// Contest functions normally include an optional override to bypass the clamp set by max_percentage. + /// This CVar disables the bypass when false, forcing all implementations to comply with max_percentage. + /// + public static readonly CVarDef AllowClampOverride = + CVarDef.Create("contests.allow_clamp_override", true, CVar.REPLICATED | CVar.SERVER); + /// + /// Toggles all MassContest functions. All mass contests output 1f when false + /// + public static readonly CVarDef DoMassContests = + CVarDef.Create("contests.do_mass_contests", true, CVar.REPLICATED | CVar.SERVER); + + /// + /// Toggles all StaminaContest functions. All stamina contests output 1f when false + /// + public static readonly CVarDef DoStaminaContests = + CVarDef.Create("contests.do_stamina_contests", true, CVar.REPLICATED | CVar.SERVER); + + /// + /// Toggles all HealthContest functions. All health contests output 1f when false + /// + public static readonly CVarDef DoHealthContests = + CVarDef.Create("contests.do_health_contests", true, CVar.REPLICATED | CVar.SERVER); + + /// + /// Toggles all MindContest functions. All mind contests output 1f when false. + /// MindContests are not currently implemented, and are awaiting completion of the Psionic Refactor + /// + public static readonly CVarDef DoMindContests = + CVarDef.Create("contests.do_mind_contests", true, CVar.REPLICATED | CVar.SERVER); + + /// + /// The maximum amount that Mass Contests can modify a physics multiplier, given as a +/- percentage + /// Default of 0.25f outputs between * 0.75f and 1.25f + /// + public static readonly CVarDef MassContestsMaxPercentage = + CVarDef.Create("contests.max_percentage", 1f, CVar.REPLICATED | CVar.SERVER); + + #endregion + + #region Shoving - WD Port + /// + /// Shove range multiplier. + /// + public static readonly CVarDef ShoveRange = + CVarDef.Create("game.shove_range", 0.6f, CVar.SERVER | CVar.ARCHIVE); + + /// + /// Shove speed multiplier, does not affect range. + /// + public static readonly CVarDef ShoveSpeed = + CVarDef.Create("game.shove_speed", 4f, CVar.SERVER | CVar.ARCHIVE); + + /// + /// How much should the mass difference affect shove range & speed. + /// + public static readonly CVarDef ShoveMassFactor = + CVarDef.Create("game.shove_mass_factor", 3f, CVar.SERVER | CVar.ARCHIVE); + #endregion + + #region Chat + + /// + /// Whether or not to log actions in the chat. + /// + public static readonly CVarDef LogInChat = + CVarDef.Create("chat.log_in_chat", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); + + /// + /// Whether or not to coalesce identical messages in the chat. + /// + public static readonly CVarDef CoalesceIdenticalMessages = + CVarDef.Create("chat.coalesce_identical_messages", true, CVar.CLIENT | CVar.ARCHIVE | CVar.CLIENTONLY); + + /// + /// Set to true to enable voice barks and disable default speech sounds. + /// + public static readonly CVarDef BarksEnabled = + CVarDef.Create("voice.barks_enabled", false, CVar.SERVER | CVar.REPLICATED | CVar.ARCHIVE); + + /// + /// Client volume setting for barks. + /// + public static readonly CVarDef BarksVolume = + CVarDef.Create("voice.barks_volume", 1f, CVar.CLIENTONLY | CVar.ARCHIVE); + + #endregion + + #region Voicechat + + /// + /// Controls whether the Lidgren voice chat server is enabled and running. + /// + public static readonly CVarDef VoiceChatEnabled = + CVarDef.Create("voice.enabled", false, CVar.SERVER | CVar.REPLICATED | CVar.ARCHIVE, "Is the voice chat server enabled?"); + + /// + /// The UDP port the Lidgren voice chat server will listen on. + /// + public static readonly CVarDef VoiceChatPort = + CVarDef.Create("voice.vc_server_port", 1213, CVar.SERVER | CVar.REPLICATED, "Port for the voice chat server."); + + public static readonly CVarDef VoiceChatVolume = + CVarDef.Create("voice.volume", 5f, CVar.CLIENTONLY | CVar.ARCHIVE); + + /// + /// Multiplier for the adaptive buffer target size calculation. + /// + public static readonly CVarDef VoiceChatBufferTargetMultiplier = + CVarDef.Create("voice.buffer_target_multiplier", 1.0f, CVar.CLIENTONLY | CVar.ARCHIVE, "Multiplier for adaptive buffer target size calculation."); + + /// + /// Minimum buffer size for voice chat, regardless of network conditions. + /// + public static readonly CVarDef VoiceChatMinBufferSize = + CVarDef.Create("voice.min_buffer_size", 10, CVar.CLIENTONLY | CVar.ARCHIVE, "Minimum buffer size for voice chat."); + + /// + /// Maximum buffer size for voice chat to prevent excessive memory usage. + /// + public static readonly CVarDef VoiceChatMaxBufferSize = + CVarDef.Create("voice.max_buffer_size", 50, CVar.CLIENTONLY | CVar.ARCHIVE, "Maximum buffer size for voice chat."); + + /// + /// Enable advanced time-stretching algorithms for better audio quality. + /// + public static readonly CVarDef VoiceChatAdvancedTimeStretch = + CVarDef.Create("voice.advanced_time_stretch", true, CVar.CLIENTONLY | CVar.ARCHIVE, "Enable advanced time-stretching for voice chat."); + + /// + /// Enable debug logging for voice chat buffer management. + /// + public static readonly CVarDef VoiceChatDebugLogging = + CVarDef.Create("voice.debug_logging", false, CVar.CLIENTONLY | CVar.ARCHIVE, "Enable debug logging for voice chat buffer management."); + + /// + /// Whether to hear audio from your own entity (useful for testing). + /// + public static readonly CVarDef VoiceChatHearSelf = + CVarDef.Create("voice.hear_self", false, CVar.CLIENTONLY | CVar.ARCHIVE, "Whether to hear audio from your own entity."); + + #endregion + + #region Queue + + /// + /// Controls if the connections queue is enabled + /// If enabled plyaers will be added to a queue instead of being kicked after SoftMaxPlayers is reached + /// + public static readonly CVarDef QueueEnabled = + CVarDef.Create("queue.enabled", false, CVar.SERVERONLY); + + /// + /// If enabled patrons will be sent to the front of the queue. + /// + public static readonly CVarDef PatreonSkip = + CVarDef.Create("queue.patreon_skip", true, CVar.SERVERONLY); + + #endregion + + #region Admin Overlay + + /// + /// If true, the admin overlay will show the characters name. + /// + public static readonly CVarDef AdminOverlayShowCharacterName = + CVarDef.Create("ui.admin_overlay_show_character_name", true, CVar.CLIENTONLY | CVar.ARCHIVE); + + /// + /// If true, the admin overlay will show their username. + /// + public static readonly CVarDef AdminOverlayShowUserName = + CVarDef.Create("ui.admin_overlay_show_user_name", true, CVar.CLIENTONLY | CVar.ARCHIVE); + + /// + /// If true, the admin overlay will show their job. + /// + public static readonly CVarDef AdminOverlayShowJob = + CVarDef.Create("ui.admin_overlay_show_job", true, CVar.CLIENTONLY | CVar.ARCHIVE); + + #endregion + + #region Movement + + public static readonly CVarDef MaxSpeed = + CVarDef.Create("movement.max_speed", 2.7f, CVar.SERVER | CVar.REPLICATED); + + #endregion + + #region LightDetection + + /// + /// Lookup range for LightDetectionSystem to use. Normally should be the same value as the strongest light source. + /// + public static readonly CVarDef LightDetectionRange = + CVarDef.Create("light.detection_range", 10f, CVar.SERVER); + + /// + /// How often will light detection update its value, in seconds. + /// + public static readonly CVarDef LightUpdateFrequency = + CVarDef.Create("light.detection_update_frequency", 1f, CVar.SERVER); + + /// + /// Maximum light level for light detection system to check. + /// + public static readonly CVarDef LightMaximumLevel = + CVarDef.Create("light.maximum_light_level", 10f, CVar.SERVER); + + + #endregion + + # region Explosions + + /// + /// Random variation to limb damage on explosion + /// 0 means no variation - all limbs are damaged the same + /// + public static readonly CVarDef ExplosionLimbDamageVariation = + CVarDef.Create("explosion.damage_variation", 2f, CVar.SERVERONLY); + + /// + /// Multiplier to wounds caused by explosion damage + /// Applies to Brute and Burn damage + /// + public static readonly CVarDef ExplosionWoundMultiplier = + CVarDef.Create("explosion.wounding_multiplier", 8f, CVar.SERVERONLY); + + #endregion + + #region Misc + + /// + /// Whether or not to automatically focus the search bar when opening the build menu. + /// + public static readonly CVarDef AutoFocusSearchOnBuildMenu = + CVarDef.Create("ui.auto_focus_search_on_build_menu", true, CVar.CLIENTONLY | CVar.ARCHIVE); + + /// + /// Whether or not to show detailed examine text. + /// + public static readonly CVarDef DetailedExamine = + CVarDef.Create("misc.detailed_examine", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); + + /// + /// Fire damage + /// + public static readonly CVarDef FireStackHeat = + CVarDef.Create("misc.fire_stack_heat", 1500, CVar.SERVER); + + /// + /// Set to true to enable the dynamic hostname system. + /// + public static readonly CVarDef UseDynamicHostname = + CVarDef.Create("hub.use_dynamic_hostname", false, CVar.SERVERONLY); + + /// + /// Determines minimum amount of solution you have to step into for footprints to be created. + /// + public static readonly CVarDef MinimumPuddleSizeForFootprints = + CVarDef.Create("footprints.minimum_puddle_size", 6f, CVar.SERVERONLY); + + /// + /// Should heretic ascension ritual be cancelled if heretic hasn't completed their objectives. + /// + public static readonly CVarDef AscensionRequiresObjectives = + CVarDef.Create("heretic.ascension_requires_objectives", true, CVar.SERVERONLY); + + /// + /// A multiplier for bloodloss damage and heal. + /// + public static readonly CVarDef BleedMultiplier = + CVarDef.Create("medical.bloodloss_multiplier", 4.0f, CVar.SERVER); + + /// + /// Enable admin notification sounds + /// + public static readonly CVarDef AdminNotificationVolume = + CVarDef.Create("admin.notification_volume", 1f, CVar.CLIENT | CVar.CLIENTONLY | CVar.ARCHIVE); + + /// + /// Whether or not to spawn space whales if the entity is too far away from the station + /// + public static readonly CVarDef SpaceWhaleSpawn = + CVarDef.Create("misc.space_whale_spawn", true, CVar.SERVER); + + /// + /// The distance to spawn a space whale from the station + /// + public static readonly CVarDef SpaceWhaleSpawnDistance = + CVarDef.Create("misc.space_whale_spawn_distance", 1965, CVar.SERVER); + + #endregion + /// + /// Enables or disables contraband icons. + /// + public static readonly CVarDef ContrabandIconsEnabled = + CVarDef.Create("contraband.icons_enabled", false, CVar.SERVER | CVar.REPLICATED); + + /// + /// Controls how often GPS updates. + /// + public static readonly CVarDef GpsUpdateRate = + CVarDef.Create("gps.update_rate", 1f, CVar.SERVER | CVar.REPLICATED); +} diff --git a/Content.Common.Data/_Goobstation/Chemistry/ChemistryEvents.cs b/Content.Common.Data/_Goobstation/Chemistry/ChemistryEvents.cs new file mode 100644 index 0000000000..3ccba42b7e --- /dev/null +++ b/Content.Common.Data/_Goobstation/Chemistry/ChemistryEvents.cs @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2025 GoobBot +// SPDX-FileCopyrightText: 2025 SolsticeOfTheWinter +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +namespace Content.Goobstation.Common.Chemistry; + +/// +/// This event is fired off when a solution reacts. +/// +[ByRefEvent] +public sealed partial class SolutionReactedEvent : EntityEventArgs; + +/// +/// This event is fired off before a solution reacts. +/// +[ByRefEvent] +public sealed partial class BeforeSolutionReactEvent : CancellableEntityEventArgs; diff --git a/Content.Module.Client/_Goobstation/Xenobiology/MobGrowthVisualizerSystem.cs b/Content.Module.Client/_Goobstation/Xenobiology/MobGrowthVisualizerSystem.cs new file mode 100644 index 0000000000..faaf244920 --- /dev/null +++ b/Content.Module.Client/_Goobstation/Xenobiology/MobGrowthVisualizerSystem.cs @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2025 GoobBot +// SPDX-FileCopyrightText: 2025 SolsticeOfTheWinter +// SPDX-FileCopyrightText: 2025 TheBorzoiMustConsume <197824988+TheBorzoiMustConsume@users.noreply.github.com> +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +using Content.Client.DamageState; +using Content.Goobstation.Shared.Xenobiology; +using Content.Goobstation.Shared.Xenobiology.Components; +using Content.Shared.Mobs; +using Robust.Client.GameObjects; + +namespace Content.Goobstation.Client.Xenobiology; + +/// +/// This handles visual changes in mobs which can transition growth states. +/// +public sealed class MobGrowthVisualizerSystem : VisualizerSystem +{ + //I have a feeling this may need some protective functions. + protected override void OnAppearanceChange(EntityUid uid, MobGrowthComponent component, ref AppearanceChangeEvent args) + { + if (args.Sprite == null + || !AppearanceSystem.TryGetData(uid, GrowthStateVisuals.Sprite, out var rsi, args.Component)) + return; + + args.Sprite.LayerSetRSI(DamageStateVisualLayers.Base, rsi); + } +} diff --git a/Content.Module.Client/_Goobstation/Xenobiology/XenoSlimeVisualizerSystem.cs b/Content.Module.Client/_Goobstation/Xenobiology/XenoSlimeVisualizerSystem.cs new file mode 100644 index 0000000000..c96b2c87cd --- /dev/null +++ b/Content.Module.Client/_Goobstation/Xenobiology/XenoSlimeVisualizerSystem.cs @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2025 GoobBot +// SPDX-FileCopyrightText: 2025 SolsticeOfTheWinter +// SPDX-FileCopyrightText: 2025 TheBorzoiMustConsume <197824988+TheBorzoiMustConsume@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 gluesniffler <159397573+gluesniffler@users.noreply.github.com> +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +using System.Diagnostics; +using Content.Client.DamageState; +using Content.Goobstation.Shared.Xenobiology; +using Content.Goobstation.Shared.Xenobiology.Components; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Shared.Prototypes; + +namespace Content.Goobstation.Client.Xenobiology; + +/// +/// This handles visual changes in slimes between breeds. +/// +public sealed class XenoSlimeVisualizerSystem : VisualizerSystem +{ + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly SpriteSystem _sprite = default!; + + protected override void OnAppearanceChange(EntityUid uid, SlimeComponent component, ref AppearanceChangeEvent args) + { + if (args.Sprite == null || !AppearanceSystem.TryGetData(uid, XenoSlimeVisuals.Color, out var color, args.Component) || !TryComp(uid, out var spriteComponent)) + return; + + foreach (var layer in args.Sprite.AllLayers) + layer.Color = color.WithAlpha(layer.Color.A); + + if (!AppearanceSystem.TryGetData(uid, XenoSlimeVisuals.Shader, out var shader, args.Component)) + return; + var spriteComp = args.Sprite; + var newShader = _proto.Index(shader).InstanceUnique(); + + var layerExists = _sprite.LayerMapTryGet(uid, DamageStateVisualLayers.Base, out var layerKey, false); + if (!layerExists) + return; + spriteComp.LayerSetShader(layerKey, newShader); + spriteComp.GetScreenTexture = true; + spriteComp.RaiseShaderEvent = true; + } +} diff --git a/Content.Module.Client/_Goobstation/Xenobiology/XenobiologyBountyConsole/XenobiologyBountyConsoleBoundUserInterface.cs b/Content.Module.Client/_Goobstation/Xenobiology/XenobiologyBountyConsole/XenobiologyBountyConsoleBoundUserInterface.cs new file mode 100644 index 0000000000..556f8b081e --- /dev/null +++ b/Content.Module.Client/_Goobstation/Xenobiology/XenobiologyBountyConsole/XenobiologyBountyConsoleBoundUserInterface.cs @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: 2025 GoobBot +// SPDX-FileCopyrightText: 2025 SolsticeOfTheWinter +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +using Content.Goobstation.Shared.Xenobiology.XenobiologyBountyConsole; +using Content.Shared.Cargo.Components; +using JetBrains.Annotations; +using Robust.Client.UserInterface; + +namespace Content.Goobstation.Client.Xenobiology.XenobiologyBountyConsole; + +[UsedImplicitly] +public sealed class XenobiologyBountyConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) +{ + [ViewVariables] + private XenobiologyBountyMenu? _menu; + + protected override void Open() + { + base.Open(); + + _menu = this.CreateWindow(); + + _menu.OnFulfillButtonPressed += id => + { + SendMessage(new BountyFulfillMessage(id)); + }; + + _menu.OnSkipButtonPressed += id => + { + SendMessage(new BountySkipMessage(id)); + }; + } + + protected override void UpdateState(BoundUserInterfaceState message) + { + base.UpdateState(message); + + if (message is not XenobiologyBountyConsoleState state) + return; + + _menu?.UpdateEntries(state.Bounties, state.History, state.UntilNextSkip, state.UntilNextGlobalRefresh); + } +} diff --git a/Content.Module.Client/_Goobstation/Xenobiology/XenobiologyBountyConsole/XenobiologyBountyEntry.xaml b/Content.Module.Client/_Goobstation/Xenobiology/XenobiologyBountyConsole/XenobiologyBountyEntry.xaml new file mode 100644 index 0000000000..d242e5bbcb --- /dev/null +++ b/Content.Module.Client/_Goobstation/Xenobiology/XenobiologyBountyConsole/XenobiologyBountyEntry.xaml @@ -0,0 +1,37 @@ + + + + + + + + + + + +