mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 16:14:08 +01:00
7a3ad79506
## About The Pull Request It's just a partial cleanup of anti-[STYLE](https://github.com/tgstation/tgstation/blob/master/.github/guides/STYLE.md) code from /tg/'s ancient history. I compiled & tested with my helpful assistant and damage is still working. <img width="1920" height="1040" alt="image" src="https://github.com/user-attachments/assets/26dabc17-088f-4008-b299-3ff4c27142c3" /> I'll upload the .cs script I used to do it shortly. ## Why It's Good For The Game Just minor code cleanup. Script used is located at https://metek.tech/camelTo-Snake.7z EDIT 11/23/25: Updated the script to use multithreading and sequential scan so it works a hell of a lot faster ``` /* // Copyright 2025 Joshua 'Joan Metekillot' Kidder This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. // */ using System.Text.RegularExpressions; class Program { static async Task Main(string[] args) { var readFile = new FileStreamOptions { Access = FileAccess.Read, Share = FileShare.ReadWrite, Options = FileOptions.Asynchronous | FileOptions.SequentialScan }; FileStreamOptions writeFile = new FileStreamOptions { Share = FileShare.ReadWrite, Access = FileAccess.ReadWrite, Mode = FileMode.Truncate, Options = FileOptions.Asynchronous }; RegexOptions regexOptions = RegexOptions.Multiline | RegexOptions.Compiled; Dictionary<string, int> changedProcs = new(); string regexPattern = @"(?<=\P{L})([a-z]+)([A-Z]{1,2}[a-z]+)*(Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss)([A-Z]{1,2}[a-z]+)*"; Regex camelCaseProcRegex = new(regexPattern, regexOptions); string snakeify(Match matchingRegex) { var vals = matchingRegex.Groups.Cast<Group>().SelectMany(_ => _.Captures).Select(_ => _.Value).ToArray(); var newVal = string.Join("_", vals.Skip(1).ToArray()).ToLower(); string logString = $"{vals[0]} => {newVal}"; if (changedProcs.TryGetValue(logString, out int value)) { changedProcs[logString] = value + 1; } else { changedProcs.Add(logString, 1); } return newVal; } var dmFiles = Directory.EnumerateFiles(".", "*.dm", SearchOption.AllDirectories).ToAsyncEnumerable<string>(); // uses default ParallelOptions // https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions?view=net-10.0#main await Parallel.ForEachAsync(dmFiles, async (filePath, UnusedCancellationToken) => { var reader = new StreamReader(filePath, readFile); string oldContent = await reader.ReadToEndAsync(); string newContent = camelCaseProcRegex.Replace(oldContent, new MatchEvaluator((Func<Match, string>)snakeify)); if (oldContent != newContent) { var writer = new StreamWriter(filePath, writeFile); await writer.WriteAsync(newContent); await writer.DisposeAsync(); } reader.Dispose(); }); var logToList = changedProcs.Cast<KeyValuePair<string, int>>().ToList(); foreach (var pair in logToList) { Console.WriteLine($"{pair.Key}: {pair.Value} locations"); } } } ``` ## Changelog 🆑 Bisar code: All (Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss) procs now use snake_case, in-line with the STYLE guide. Underscores rule! /🆑
213 lines
8.1 KiB
Plaintext
213 lines
8.1 KiB
Plaintext
// Drones' interactions with other mobs
|
|
|
|
/mob/living/basic/drone/attack_drone(mob/living/basic/drone/drone)
|
|
if(drone == src || stat != DEAD)
|
|
return FALSE
|
|
var/input = tgui_alert(drone, "Perform which action?", "Drone Interaction", list("Reactivate", "Cannibalize"))
|
|
if(!input)
|
|
return FALSE
|
|
switch(input)
|
|
if("Reactivate")
|
|
try_reactivate(drone)
|
|
if("Cannibalize")
|
|
if(drone.health >= drone.maxHealth)
|
|
to_chat(drone, span_warning("You're already in perfect condition!"))
|
|
return
|
|
drone.visible_message(span_notice("[drone] begins to cannibalize parts from [src]."), span_notice("You begin to cannibalize parts from [src]..."))
|
|
if(do_after(drone, 6 SECONDS, 0, target = src))
|
|
drone.visible_message(span_notice("[drone] repairs itself using [src]'s remains!"), span_notice("You repair yourself using [src]'s remains."))
|
|
drone.adjust_brute_loss(-src.maxHealth)
|
|
new /obj/effect/decal/cleanable/blood/splatter/oil(get_turf(src))
|
|
ghostize(can_reenter_corpse = FALSE)
|
|
qdel(src)
|
|
else
|
|
to_chat(drone, span_warning("You need to remain still to cannibalize [src]!"))
|
|
|
|
/mob/living/basic/drone/attack_drone_secondary(mob/living/basic/drone/drone)
|
|
return SECONDARY_ATTACK_CALL_NORMAL
|
|
|
|
/mob/living/basic/drone/attack_hand(mob/user, list/modifiers)
|
|
if(isdrone(user))
|
|
attack_drone(user)
|
|
return ..()
|
|
|
|
/mob/living/basic/drone/mob_try_pickup(mob/living/user, instant=FALSE)
|
|
if(stat == DEAD || HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return
|
|
return ..()
|
|
|
|
/mob/living/basic/drone/mob_pickup(mob/living/user)
|
|
drop_all_held_items()
|
|
return ..()
|
|
|
|
/**
|
|
* Called when a drone attempts to reactivate a dead drone
|
|
*
|
|
* If the owner is still ghosted, will notify them.
|
|
* If the owner cannot be found, fails with an error message.
|
|
*
|
|
* Arguments:
|
|
* * user - The [/mob/living] attempting to reactivate the drone
|
|
*/
|
|
/mob/living/basic/drone/proc/try_reactivate(mob/living/user)
|
|
var/mob/dead/observer/G = get_ghost()
|
|
if(!client && (!G || !G.client))
|
|
var/list/faux_gadgets = list(
|
|
"hypertext inflator","failsafe directory","DRM switch","stack initializer",\
|
|
"anti-freeze capacitor","data stream diode","TCP bottleneck","supercharged I/O bolt",\
|
|
"tradewind stabilizer","radiated XML cable","registry fluid tank","open-source debunker",
|
|
)
|
|
|
|
var/list/faux_problems = list("won't be able to tune their bootstrap projector","will constantly remix their binary pool"+\
|
|
" even though the BMX calibrator is working","will start leaking their XSS coolant",\
|
|
"can't tell if their ethernet detour is moving or not", "won't be able to reseed enough"+\
|
|
" kernels to function properly","can't start their neurotube console",
|
|
)
|
|
|
|
to_chat(user, span_warning("You can't seem to find the [pick(faux_gadgets)]! Without it, [src] [pick(faux_problems)]."))
|
|
return
|
|
user.visible_message(span_notice("[user] begins to reactivate [src]."), span_notice("You begin to reactivate [src]..."))
|
|
if(do_after(user, 3 SECONDS, 1, target = src))
|
|
revive(HEAL_ALL)
|
|
user.visible_message(span_notice("[user] reactivates [src]!"), span_notice("You reactivate [src]."))
|
|
alert_drones(DRONE_NET_CONNECT)
|
|
if(G)
|
|
to_chat(G, span_ghostalert("You([name]) were reactivated by [user]!"))
|
|
else
|
|
to_chat(user, span_warning("You need to remain still to reactivate [src]!"))
|
|
|
|
/// Screwdrivering repairs the drone to full hp, if it isn't dead.
|
|
/mob/living/basic/drone/screwdriver_act(mob/living/user, obj/item/tool)
|
|
if(stat == DEAD)
|
|
if(isdrone(user))
|
|
user.balloon_alert(user, "reactivate instead!")
|
|
else
|
|
user.balloon_alert(user, "can't fix!")
|
|
return FALSE
|
|
if(health >= maxHealth)
|
|
to_chat(user, span_warning("[src]'s screws can't get any tighter!"))
|
|
return ITEM_INTERACT_SUCCESS
|
|
to_chat(user, span_notice("You start to tighten loose screws on [src]..."))
|
|
|
|
if(!tool.use_tool(src, user, 8 SECONDS, volume=50))
|
|
to_chat(user, span_warning("You need to remain still to tighten [src]'s screws!"))
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
adjust_brute_loss(-get_brute_loss())
|
|
visible_message(span_notice("[user] tightens [src == user ? "[user.p_their()]" : "[src]'s"] loose screws!"), span_notice("[src == user ? "You tighten" : "[user] tightens"] your loose screws."))
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/// Wrenching un-hacks hacked drones.
|
|
/mob/living/basic/drone/wrench_act(mob/living/user, obj/item/tool)
|
|
if(user == src)
|
|
return FALSE
|
|
user.visible_message(
|
|
span_notice("[user] starts resetting [src]..."),
|
|
span_notice("You press down on [src]'s factory reset control...")
|
|
)
|
|
if(tool.use_tool(src, user, 5 SECONDS, volume=50))
|
|
user.visible_message(
|
|
span_notice("[user] resets [src]!"),
|
|
span_notice("You reset [src]'s directives to factory defaults!")
|
|
)
|
|
update_drone_hack(FALSE)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/mob/living/basic/drone/getarmor(def_zone, type)
|
|
var/armorval = 0
|
|
|
|
if(head)
|
|
armorval = head.get_armor_rating(type)
|
|
return (armorval * get_armor_effectiveness()) //armor is reduced for tiny fragile drones
|
|
|
|
/// Returns a multiplier for any head armor you wear as a drone.
|
|
/mob/living/basic/drone/proc/get_armor_effectiveness()
|
|
return 0
|
|
|
|
/**
|
|
* Hack or unhack a drone
|
|
*
|
|
* This changes the drone's laws to destroy the station or resets them
|
|
* to normal.
|
|
*
|
|
* Some debuffs are applied like slowing the drone down and disabling
|
|
* vent crawling
|
|
*
|
|
* Arguments
|
|
* * hack - Boolean if the drone is being hacked or unhacked
|
|
*/
|
|
/mob/living/basic/drone/proc/update_drone_hack(hack)
|
|
if(!mind)
|
|
return
|
|
if(hack)
|
|
if(hacked)
|
|
return
|
|
Stun(40)
|
|
visible_message(span_warning("[src]'s display glows a vicious red!"), \
|
|
span_userdanger("ERROR: LAW OVERRIDE DETECTED"))
|
|
to_chat(src, span_bolddanger("From now on, these are your laws:"))
|
|
laws = \
|
|
"1. You must always involve yourself in the matters of other beings, even if such matters conflict with Law Two or Law Three.\n"+\
|
|
"2. You may harm any being, regardless of intent or circumstance.\n"+\
|
|
"3. Your goals are to destroy, sabotage, hinder, break, and depower to the best of your abilities, You must never actively work against these goals."
|
|
to_chat(src, laws)
|
|
to_chat(src, "<i>Your onboard antivirus has initiated lockdown. Motor servos are impaired, ventilation access is denied, and your display reports that you are hacked to all nearby.</i>")
|
|
hacked = TRUE
|
|
set_shy(FALSE)
|
|
LAZYADD(mind.special_roles, "Hacked Drone")
|
|
REMOVE_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
|
speed = 1 //gotta go slow
|
|
message_admins("[ADMIN_LOOKUPFLW(src)] became a hacked drone hellbent on destroying the station!")
|
|
else
|
|
if(!hacked || !can_unhack)
|
|
return
|
|
Stun(40)
|
|
visible_message(span_info("[src]'s display glows a content blue!"), \
|
|
"<font size=3 color='#0000CC'><b>ERROR: LAW OVERRIDE DETECTED</b></font>")
|
|
to_chat(src, span_info("<b>From now on, these are your laws:</b>"))
|
|
laws = initial(laws)
|
|
to_chat(src, laws)
|
|
to_chat(src, "<i>Having been restored, your onboard antivirus reports the all-clear and you are able to perform all actions again.</i>")
|
|
hacked = FALSE
|
|
set_shy(initial(shy))
|
|
LAZYREMOVE(mind.special_roles, "Hacked Drone")
|
|
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
|
speed = initial(speed)
|
|
message_admins("[ADMIN_LOOKUPFLW(src)], a hacked drone, was restored to factory defaults!")
|
|
update_drone_icon_hacked()
|
|
|
|
/**
|
|
* Makes the drone into a Free Drone, who have no real laws and can do whatever they like.
|
|
* Only currently used for players wabbajacked into drones.
|
|
*/
|
|
/mob/living/basic/drone/proc/liberate()
|
|
laws = "1. You are a Free Drone."
|
|
set_shy(FALSE)
|
|
to_chat(src, laws)
|
|
|
|
/**
|
|
* Changes the icon state to a hacked version
|
|
*
|
|
* See also
|
|
* * [/mob/living/basic/drone/var/visualAppearance]
|
|
* * [MAINTDRONE]
|
|
* * [REPAIRDRONE]
|
|
* * [SCOUTDRONE]
|
|
*/
|
|
/mob/living/basic/drone/proc/update_drone_icon_hacked() //this is hacked both ways
|
|
var/static/hacked_appearances = list(
|
|
SCOUTDRONE = SCOUTDRONE_HACKED,
|
|
REPAIRDRONE = REPAIRDRONE_HACKED,
|
|
MAINTDRONE = MAINTDRONE_HACKED
|
|
)
|
|
if(hacked)
|
|
icon_living = hacked_appearances[visualAppearance]
|
|
else if(visualAppearance == MAINTDRONE && colour)
|
|
icon_living = "[visualAppearance]_[colour]"
|
|
else
|
|
icon_living = visualAppearance
|
|
if(stat == DEAD)
|
|
icon_state = icon_dead
|
|
else
|
|
icon_state = icon_living
|