Captain Functions"
dat += " \[ Make a Captain's Announcement \]"
- if(config.cross_allowed)
+ if(CONFIG_GET(string/cross_server_address))
dat += " \[ Send a message to an allied station \]"
if(SSmapping.config.allow_custom_shuttles == "yes")
dat += " \[ Purchase Shuttle \]"
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index f2ea3238ef..6ec144d257 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -124,7 +124,7 @@
dat += "
Security Record - (SR-[GLOB.data_core.securityPrintCount])
"
if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))
P.info += text("Name: [] ID: [] \nSex: [] \nAge: [] ", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"])
- if(config.mutant_races)
+ if(CONFIG_GET(flag/join_with_mutant_race))
P.info += "\nSpecies: [active1.fields["species"]] "
P.info += text("\nFingerprint: [] \nPhysical Status: [] \nMental Status: [] ", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"])
else
@@ -519,7 +519,7 @@ What a mess.*/
G.fields["rank"] = "Unassigned"
G.fields["sex"] = "Male"
G.fields["age"] = "Unknown"
- if(config.mutant_races)
+ if(CONFIG_GET(flag/join_with_mutant_race))
G.fields["species"] = "Human"
G.fields["photo_front"] = new /icon()
G.fields["photo_side"] = new /icon()
@@ -604,7 +604,7 @@ What a mess.*/
active1.fields["age"] = t1
if("species")
if(istype(active1, /datum/data/record))
- var/t1 = input("Select a species", "Species Selection") as null|anything in GLOB.roundstart_species
+ var/t1 = input("Select a species", "Species Selection") as null|anything in CONFIG_GET(keyed_flag_list/roundstart_races)
if(!canUseSecurityRecordsConsole(usr, t1, a1))
return
active1.fields["species"] = t1
@@ -772,7 +772,7 @@ What a mess.*/
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
if(7)
- R.fields["species"] = pick(GLOB.roundstart_species)
+ R.fields["species"] = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
if(8)
var/datum/data/record/G = pick(GLOB.data_core.general)
R.fields["photo_front"] = G.fields["photo_front"]
diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm
index fd7a87ac8c..45788b77b9 100644
--- a/code/game/objects/items/AI_modules.dm
+++ b/code/game/objects/items/AI_modules.dm
@@ -54,7 +54,7 @@ AI MODULES
for(var/mylaw in lawlist)
if(mylaw != "")
tot_laws++
- if(tot_laws > config.silicon_max_law_amount && !bypass_law_amt_check)//allows certain boards to avoid this check, eg: reset
+ if(tot_laws > CONFIG_GET(number/silicon_max_law_amount) && !bypass_law_amt_check)//allows certain boards to avoid this check, eg: reset
to_chat(user, "Not enough memory allocated to [law_datum.owner ? law_datum.owner : "the AI core"]'s law processor to handle this amount of laws.")
message_admins("[key_name_admin(user)] tried to upload laws to [law_datum.owner ? key_name_admin(law_datum.owner) : "an AI core"] that would exceed the law cap.")
overflow = TRUE
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index ca5fa2c28b..23905200e9 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -72,16 +72,15 @@
user.visible_message("[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!")
return (BRUTELOSS|OXYLOSS)
-/obj/item/toy/crayon/New()
- ..()
+/obj/item/toy/crayon/Initialize()
+ . = ..()
// Makes crayons identifiable in things like grinders
if(name == "crayon")
name = "[item_color] crayon"
- if(config)
- if(config.mutant_races == 1)
- graffiti |= "antilizard"
- graffiti |= "prolizard"
+ if(CONFIG_GET(flag/join_with_mutant_race))
+ graffiti |= "antilizard"
+ graffiti |= "prolizard"
all_drawables = graffiti + letters + numerals + oriented + runes + graffiti_large_h
drawtype = pick(all_drawables)
diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm
index 7ee1f49a48..a8bdce5fe9 100644
--- a/code/game/objects/items/manuals.dm
+++ b/code/game/objects/items/manuals.dm
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
/*********************MANUALS (BOOKS)***********************/
//Oh god what the fuck I am not good at computer
@@ -956,3 +957,964 @@
author = "Engineering Encyclopedia"
title = "Hacking"
page_link = "Hacking"
+=======
+/*********************MANUALS (BOOKS)***********************/
+
+//Oh god what the fuck I am not good at computer
+/obj/item/book/manual
+ icon = 'icons/obj/library.dmi'
+ due_date = 0 // Game time in 1/10th seconds
+ unique = 1 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
+
+/obj/item/book/manual/engineering_particle_accelerator
+ name = "Particle Accelerator User's Guide"
+ icon_state ="bookParticleAccelerator"
+ author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
+ title = "Particle Accelerator User's Guide"
+ dat = {"
+
+
+
+
+
+
Experienced user's guide
+
+
Setting up
+
+
+
Wrench all pieces to the floor
+
Add wires to all the pieces
+
Close all the panels with your screwdriver
+
+
+
Use
+
+
+
Open the control panel
+
Set the speed to 2
+
Start firing at the singularity generator
+
When the singularity reaches a large enough size so it starts moving on its own set the speed down to 0, but don't shut it off
+
Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
+
+
+
+ "}
+
+
+/obj/item/book/manual/engineering_singularity_safety
+ name = "Singularity Safety in Special Circumstances"
+ icon_state ="bookEngineeringSingularitySafety"
+ author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
+ title = "Singularity Safety in Special Circumstances"
+//big pile of shit below.
+
+ dat = {"
+
+
+
+
+
Singularity Safety in Special Circumstances
+
+
Power outage
+
+ A power problem has made the entire station lose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps:
+
+ Step one:PANIC!
+ Step two: Get your ass over to engineering! QUICKLY!!!
+ Step three: Make sure the SMES is still powering the emitters, if not, setup the generator in secure storage and disconnect the emitters from the SMES.
+ Step four: Next, head over to the APC and swipe it with your ID card - if it doesn't unlock, continue with step 15.
+ Step five: Open the console and disengage the cover lock.
+ Step six: Pry open the APC with a Crowbar.
+ Step seven: Take out the empty power cell.
+ Step eight: Put in the new, full power cell - if you don't have one, continue with step 15.
+ Step nine: Quickly put on a Radiation suit.
+ Step ten: Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
+ Step eleven: Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
+ Step twelve: Grab your crowbar and pry away the tile closest to the APC.
+ Step thirteen: Use the wirecutters to cut the wire which is conecting the grid to the terminal.
+ Step fourteen: Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
+ Step fifteen:GET THE FUCK OUT OF THERE!!!
+
+
+
Shields get damaged
+
+ Step one: GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
+
+
+ "}
+
+/obj/item/book/manual/hydroponics_pod_people
+ name = "The Human Harvest - From seed to market"
+ icon_state ="bookHydroponicsPodPeople"
+ author = "Farmer John"
+ title = "The Human Harvest - From seed to market"
+ dat = {"
+
+
+
+
+
Growing Humans
+
+ Why would you want to grow humans? Well I'm expecting most readers to be in the slave trade, but a few might actually
+ want to revive fallen comrades. Growing pod people is easy, but prone to disaster.
+
+
+
Find a dead person who is in need of cloning.
+
Take a blood sample with a syringe.
+
Inject a seed pack with the blood sample.
+
Plant the seeds.
+
Tend to the plants water and nutrition levels until it is time to harvest the cloned human.
+
+
+ It really is that easy! Good luck!
+
+
+
+ "}
+
+/obj/item/book/manual/medical_cloning
+ name = "Cloning techniques of the 26th century"
+ icon_state ="bookCloning"
+ author = "Medical Journal, volume 3" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
+ title = "Cloning techniques of the 26th century"
+//big pile of shit below.
+
+ dat = {"
+
+
+
+
+
+
How to Clone People
+ So there’s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven’t the foggiest idea of what to do? Not to worry! This guide is intended to teach you how to clone people and how to do it right, in a simple step-by-step process! If at any point of the guide you have a mental meltdown, genetics probably isn’t for you and you should get a job-change as soon as possible before you’re sued for malpractice.
+
+
+
+ The Exosuit Fabricator is the most important piece of equipment related to cyborgs. It allows the construction of the core cyborg parts. Without these machines, cyborgs can not be built. It seems that they may also benefit from advanced research techniques.
+
+
Cyborg Recharging Station
+ This useful piece of equipment will suck power out of the power systems to charge a cyborg's power cell back up to full charge.
+
+
Robotics Control Console
+ This useful piece of equipment can be used to immobolize or destroy a cyborg. A word of warning: Cyborgs are expensive pieces of equipment, do not destroy them without good reason, or Nanotrasen may see to it that it never happens again.
+
+
+
+ When a cyborg is created it picks out of an array of modules to designate its purpose. There are 6 different cyborg modules.
+
+
Standard Cyborg
+ The standard cyborg module is a multi-purpose cyborg. It is equipped with various modules, allowing it to do basic tasks.
+
+
Engineering Cyborg
+ The Engineering cyborg module comes equipped with various engineering-related tools to help with engineering-related tasks.
+
+
Mining Cyborg
+ The Mining Cyborg module comes equipped with the latest in mining equipment. They are efficient at mining due to no need for oxygen, but their power cells limit their time in the mines.
+
+
Security Cyborg
+ The Security Cyborg module is equipped with effective security measures used to apprehend and arrest criminals without harming them a bit.
+
+
Janitor Cyborg
+ The Janitor Cyborg module is equipped with various cleaning-facilitating devices.
+
+
Service Cyborg
+ The service cyborg module comes ready to serve your human needs. It includes various entertainment and refreshment devices. Occasionally some service cyborgs may have been referred to as "Bros"
+
+
+ Cyborg construction is a rather easy process, requiring a decent amount of metal and a few other supplies. The required materials to make a cyborg are:
+
+
Metal
+
Two Flashes
+
One Power Cell (Preferrably rated to 15000w)
+
Some electrical wires
+
One Human Brain
+
One Man-Machine Interface
+
+ Once you have acquired the materials, you can start on construction of your cyborg. To construct a cyborg, follow the steps below:
+
+
Start the Exosuit Fabricators constructing all of the cyborg parts
+
While the parts are being constructed, take your human brain, and place it inside the Man-Machine Interface
+
Once you have a Robot Head, place your two flashes inside the eye sockets
+
Once you have your Robot Chest, wire the Robot chest, then insert the power cell
+
Attach all of the Robot parts to the Robot frame
+
Insert the Man-Machine Interface (With the Brain inside) Into the Robot Body
+ If you want to deconstruct a cyborg, say to remove its MMI without blowing the Cyborg to pieces, they come apart very quickly, and very safely, in a few simple steps.
+
+
Crowbar
+
Wrench
+ Optional:
+
Screwdriver
+
Wirecutters
+
+
+
Begin by unlocking the Cyborg's access panel using your ID
+
Use your crowbar to open the Cyborg's access panel
+
Using your bare hands, remove the power cell from the Cyborg
+
Lockdown the Cyborg to disengage safety protocols
+
+ Option 1: Robotics console
+
Use the Robotics console in the RD's office
+
Find the entry for your Cyborg
+
Press the Lockdown button on the Robotics console
+
+
+ Option 2: Lockdown wire
+
Use your screwdriver to expose the Cyborg's wiring
+
Use your wirecutters to start cutting all of the wires until the lockdown light turns off, cutting all of the wires irregardless of the lockdown light works as well
+
+
Use your wrench to unfasten the Cyborg's bolts, the Cyborg will then fall apart onto the floor, the MMI will be there as well
+ Occasionally Cyborgs may require maintenance of a couple types, this could include replacing a power cell with a charged one, or possibly maintaining the cyborg's internal wiring.
+
+
Replacing a Power Cell
+ Replacing a Power cell is a common type of maintenance for cyborgs. It usually involves replacing the cell with a fully charged one, or upgrading the cell with a larger capacity cell. The steps to replace a cell are follows:
+
+
Unlock the Cyborg's Interface by swiping your ID on it
+
Open the Cyborg's outer panel using a crowbar
+
Remove the old power cell
+
Insert the new power cell
+
Close the Cyborg's outer panel using a crowbar
+
Lock the Cyborg's Interface by swiping your ID on it, this will prevent non-qualified personnel from attempting to remove the power cell
+
+
+
Exposing the Internal Wiring
+ Exposing the internal wiring of a cyborg is fairly easy to do, and is mainly used for cyborg repairs. You can easily expose the internal wiring by following the steps below:
+
+
Follow Steps 1 - 3 of "Replacing a Cyborg's Power Cell"
+
Open the cyborg's internal wiring panel by using a screwdriver to unsecure the panel
+
+ To re-seal the cyborg's internal wiring:
+
+
Use a screwdriver to secure the cyborg's internal panel
+
Follow steps 4 - 6 of "Replacing a Cyborg's Power Cell" to close up the cyborg
+ Occasionally a Cyborg may become damaged. This could be in the form of impact damage from a heavy or fast-travelling object, or it could be heat damage from high temperatures, or even lasers or Electromagnetic Pulses (EMPs).
+
+
Dents
+ If a cyborg becomes damaged due to impact from heavy or fast-moving objects, it will become dented. Sure, a dent may not seem like much, but it can compromise the structural integrity of the cyborg, possibly causing a critical failure.
+ Dents in a cyborg's frame are rather easy to repair, all you need is to apply a welding tool to the dented area, and the high-tech cyborg frame will repair the dent under the heat of the welder.
+
+
Excessive Heat Damage
+ If a cyborg becomes damaged due to excessive heat, it is likely that the internal wires will have been damaged. You must replace those wires to ensure that the cyborg remains functioning properly. To replace the internal wiring follow the steps below:
+
+
Unlock the Cyborg's Interface by swiping your ID
+
Open the Cyborg's External Panel using a crowbar
+
Remove the Cyborg's Power Cell
+
Using a screwdriver, expose the internal wiring or the Cyborg
+
Replace the damaged wires inside the cyborg
+
Secure the internal wiring cover using a screwdriver
+
Insert the Cyborg's Power Cell
+
Close the Cyborg's External Panel using a crowbar
+
Lock the Cyborg's Interface by swiping your ID
+
+ These repair tasks may seem difficult, but are essential to keep your cyborgs running at peak efficiency.
+
+
+ In case of emergency, there are a few steps you can take.
+
+
"Rogue" Cyborgs
+ If the cyborgs seem to become "rogue", they may have non-standard laws. In this case, use extreme caution.
+ To repair the situation, follow these steps:
+
+
Locate the nearest robotics console
+
Determine which cyborgs are "Rogue"
+
Press the lockdown button to immobolize the cyborg
+
Locate the cyborg
+
Expose the cyborg's internal wiring
+
Check to make sure the LawSync and AI Sync lights are lit
+
If they are not lit, pulse the LawSync wire using a multitool to enable the cyborg's Law Sync
+
Proceed to a cyborg upload console. Nanotrasen usually places these in the same location as AI uplaod consoles.
+
Use a "Reset" upload moduleto reset the cyborg's laws
+
Proceed to a Robotics Control console
+
Remove the lockdown on the cyborg
+
+
+
As a last resort
+ If all else fails in a case of cyborg-related emergency. There may be only one option. Using a Robotics Control console, you may have to remotely detonate the cyborg.
+
WARNING:
Do not detonate a borg without an explicit reason for doing so. Cyborgs are expensive pieces of Nanotrasen equipment, and you may be punished for detonating them without reason.
+
+
+
+ "}
+
+
+
+/obj/item/book/manual/chef_recipes
+ name = "Chef Recipes"
+ icon_state = "cooked_book"
+ author = "Lord Frenrir Cageth"
+ title = "Chef Recipes"
+ dat = {"
+
+
+
+
+
+
Food for Dummies
+ Here is a guide on basic food recipes and also how to not poison your customers accidentally.
+
+
+
Basic ingredients preparation:
+
+ Dough: 10u water + 15u flour for simple dough.
+ 15u egg yolk + 15u flour + 5u sugar for cake batter.
+ Doughs can be transformed by using a knife and rolling pin.
+ All doughs can be microwaved.
+ Bowl: Add water to it for soup preparation.
+ Meat: Microwave it, process it, slice it into microwavable cutlets with your knife, or use it raw.
+ Cheese: Add 5u universal enzyme (catalyst) to milk and soy milk to prepare cheese (sliceable) and tofu.
+ Rice: Mix 10u rice with 10u water in a bowl then microwave it.
+
+
Custom food:
+ Add ingredients to a base item to prepare a custom meal.
+ The bases are:
+ - bun (burger)
+ - breadslices(sandwich)
+ - plain bread
+ - plain pie
+ - vanilla cake
+ - empty bowl (salad)
+ - bowl with 10u water (soup)
+ - boiled spaghetti
+ - pizza bread
+ - metal rod (kebab)
+
+
Table Craft:
+ Put ingredients on table, then click and drag the table onto yourself to see what recipes you can prepare.
+
+
Microwave:
+ Use it to cook or boil food ingredients (meats, doughs, egg, spaghetti, donkpocket, etc...).
+ It can cook multiple items at once.
+
+
Processor:
+ Use it to process certain ingredients (meat into faggot, doughslice into spaghetti, potato into fries,etc...)
+
+
Gibber:
+ Stuff an animal in it to grind it into meat.
+
+
Meat spike:
+ Stick an animal on it then begin collecting its meat.
+
+
+
Example recipes:
+ Vanilla Cake: Microwave cake batter.
+ Burger: 1 bun + 1 meat steak
+ Bread: Microwave dough.
+ Waffles: 2 pastry base
+ Popcorn: Microwave corn.
+ Meat Steak: Microwave meat.
+ Meat Pie: 1 plain pie + 1u black pepper + 1u salt + 2 meat cutlets
+ Boiled Spagetti: Microwave spaghetti.
+ Donuts: 1u sugar + 1 pastry base
+ Fries: Process potato.
+
+
Sharing your food:
+ You can put your meals on your kitchen counter or load them in the snack vending machines.
+
+
+ "}
+
+
+/obj/item/book/manual/barman_recipes
+ name = "Barman Recipes"
+ icon_state = "barbook"
+ author = "Sir John Rose"
+ title = "Barman Recipes"
+ dat = {"
+
+
+
+
+
+
Drinks for dummies
+ Heres a guide for some basic drinks.
+
+
Manly Dorf:
+ Mix ale and beer into a glass.
+
+
Grog:
+ Mix rum and water into a glass.
+
+
Black Russian:
+ Mix vodka and kahlua into a glass.
+
+
Irish Cream:
+ Mix cream and whiskey into a glass.
+
+
Screwdriver:
+ Mix vodka and orange juice into a glass.
+
+
Cafe Latte:
+ Mix milk and coffee into a glass.
+
+
Mead:
+ Mix Enzyme, water and sugar into a glass.
+
+
Gin Tonic:
+ Mix gin and tonic into a glass.
+
+
Classic Martini:
+ Mix vermouth and gin into a glass.
+
+
+
+
+ "}
+
+
+/obj/item/book/manual/detective
+ name = "The Film Noir: Proper Procedures for Investigations"
+ icon_state ="bookDetective"
+ author = "Nanotrasen"
+ title = "The Film Noir: Proper Procedures for Investigations"
+ dat = {"
+
+
+
+
+
Detective Work
+
+ Between your bouts of self-narration, and drinking whiskey on the rocks, you might get a case or two to solve.
+ To have the best chance to solve your case, follow these directions:
+
+
+
Go to the crime scene.
+
Take your scanner and scan EVERYTHING (Yes, the doors, the tables, even the dog.)
+
Once you are reasonably certain you have every scrap of evidence you can use, find all possible entry points and scan them, too.
+
Return to your office.
+
Using your forensic scanning computer, scan your Scanner to upload all of your evidence into the database.
+
Browse through the resulting dossiers, looking for the one that either has the most complete set of prints, or the most suspicious items handled.
+
If you have 80% or more of the print (The print is displayed) go to step 10, otherwise continue to step 8.
+
Look for clues from the suit fibres you found on your perp, and go about looking for more evidence with this new information, scanning as you go.
+
Try to get a fingerprint card of your perp, as if used in the computer, the prints will be completed on their dossier.
+
Assuming you have enough of a print to see it, grab the biggest complete piece of the print and search the security records for it.
+
Since you now have both your dossier and the name of the person, print both out as evidence, and get security to nab your baddie.
+
Give yourself a pat on the back and a bottle of the ships finest vodka, you did it!
+
+
+ It really is that easy! Good luck!
+
+
+ "}
+
+/obj/item/book/manual/nuclear
+ name = "Fission Mailed: Nuclear Sabotage 101"
+ icon_state ="bookNuclear"
+ author = "Syndicate"
+ title = "Fission Mailed: Nuclear Sabotage 101"
+ dat = {"
+ Nuclear Explosives 101:
+ Hello and thank you for choosing the Syndicate for your nuclear information needs.
+ Today's crash course will deal with the operation of a Fusion Class Nanotrasen made Nuclear Device.
+ First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.
+ Pressing any button on the compacted bomb will cause it to extend and bolt itself into place.
+ If this is done to unbolt it one must completely log in which at this time may not be possible.
+ To make the nuclear device functional:
+
Place the nuclear device in the designated detonation zone.
+
Extend and anchor the nuclear device from its interface.
+
Insert the nuclear authorisation disk into slot.
+
Type numeric authorisation code into the keypad. This should have been provided. Note: If you make a mistake press R to reset the device.
+
Press the E button to log onto the device.
+ You now have activated the device. To deactivate the buttons at anytime for example when you've already prepped the bomb for detonation remove the auth disk OR press the R on the keypad.
+ Now the bomb CAN ONLY be detonated using the timer. Manual detonation is not an option.
+ Note: Nanotrasen is a pain in the neck.
+ Toggle off the SAFETY.
+ Note: You wouldn't believe how many Syndicate Operatives with doctorates have forgotten this step.
+ So use the - - and + + to set a det time between 5 seconds and 10 minutes.
+ Then press the timer toggle button to start the countdown.
+ Now remove the auth. disk so that the buttons deactivate.
+ Note: THE BOMB IS STILL SET AND WILL DETONATE
+ Now before you remove the disk if you need to move the bomb you can:
+ Toggle off the anchor, move it, and re-anchor.
+ Good luck. Remember the order:
+ Disk, Code, Safety, Timer, Disk, RUN!
+ Intelligence Analysts believe that normal Nanotrasen procedure is for the Captain to secure the nuclear authorisation disk.
+ Good luck!
+ "}
+
+// Wiki books that are linked to the configured wiki link.
+
+// A book that links to the wiki
+/obj/item/book/manual/wiki
+ var/page_link = ""
+ window_size = "970x710"
+
+/obj/item/book/manual/wiki/attack_self()
+ if(!dat)
+ initialize_wikibook()
+ ..()
+
+/obj/item/book/manual/wiki/proc/initialize_wikibook()
+ var/wikiurl = CONFIG_GET(string/wikiurl)
+ if(wikiurl)
+ dat = {"
+
+
+
+
+
+
+
You start skimming through the manual...
+
+
+
+
+
+ "}
+
+/obj/item/book/manual/wiki/chemistry
+ name = "Chemistry Textbook"
+ icon_state ="chemistrybook"
+ author = "Nanotrasen"
+ title = "Chemistry Textbook"
+ page_link = "Guide_to_chemistry"
+
+/obj/item/book/manual/wiki/engineering_construction
+ name = "Station Repairs and Construction"
+ icon_state ="bookEngineering"
+ author = "Engineering Encyclopedia"
+ title = "Station Repairs and Construction"
+ page_link = "Guide_to_construction"
+
+/obj/item/book/manual/wiki/engineering_guide
+ name = "Engineering Textbook"
+ icon_state ="bookEngineering2"
+ author = "Engineering Encyclopedia"
+ title = "Engineering Textbook"
+ page_link = "Guide_to_engineering"
+
+/obj/item/book/manual/wiki/security_space_law
+ name = "Space Law"
+ desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations."
+ icon_state = "bookSpaceLaw"
+ author = "Nanotrasen"
+ title = "Space Law"
+ page_link = "Space_Law"
+
+/obj/item/book/manual/wiki/infections
+ name = "Infections - Making your own pandemic!"
+ icon_state = "bookInfections"
+ author = "Infections Encyclopedia"
+ title = "Infections - Making your own pandemic!"
+ page_link = "Infections"
+
+/obj/item/book/manual/wiki/telescience
+ name = "Teleportation Science - Bluespace for dummies!"
+ icon_state = "book7"
+ author = "University of Bluespace"
+ title = "Teleportation Science - Bluespace for dummies!"
+ page_link = "Guide_to_telescience"
+
+/obj/item/book/manual/wiki/engineering_hacking
+ name = "Hacking"
+ icon_state ="bookHacking"
+ author = "Engineering Encyclopedia"
+ title = "Hacking"
+ page_link = "Hacking"
+>>>>>>> 4178c20... Configuration datum refactor (#30763)
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 0a7b9eb312..709d86d4d7 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -134,7 +134,7 @@
to_chat(user, "Sticking an inactive [M.name] into the frame would sort of defeat the purpose.")
return
- if((config) && (!config.allow_ai) || jobban_isbanned(M.brainmob, "AI"))
+ if(!CONFIG_GET(flag/allow_ai) || jobban_isbanned(M.brainmob, "AI"))
to_chat(user, "This [M.name] does not seem to fit!")
return
diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm
index 4754cc63e7..7a4f04a4e3 100644
--- a/code/game/objects/structures/beds_chairs/chair.dm
+++ b/code/game/objects/structures/beds_chairs/chair.dm
@@ -93,7 +93,7 @@
set category = "Object"
set src in oview(1)
- if(config.ghost_interaction)
+ if(CONFIG_GET(flag/ghost_interaction))
spin()
else
if(!usr || !isturf(usr.loc))
diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
index a920a53c7f..1bf7daf2e2 100644
--- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
+++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
@@ -23,7 +23,7 @@
return
move_delay = 1
if(step(src, direction))
- spawn(config.walk_speed*move_speed_multiplier)
+ spawn(CONFIG_GET(number/walk_delay) * move_speed_multiplier)
move_delay = 0
else
move_delay = 0
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index a32db59bc5..c2e082810f 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
//wip wip wup
/obj/structure/mirror
name = "mirror"
@@ -223,3 +224,231 @@
/obj/structure/mirror/magic/proc/curse(mob/living/user)
return
+=======
+//wip wip wup
+/obj/structure/mirror
+ name = "mirror"
+ desc = "Mirror mirror on the wall, who's the most robust of them all?"
+ icon = 'icons/obj/watercloset.dmi'
+ icon_state = "mirror"
+ density = FALSE
+ anchored = TRUE
+ max_integrity = 200
+ integrity_failure = 100
+
+
+/obj/structure/mirror/attack_hand(mob/user)
+ if(broken || !Adjacent(user))
+ return
+
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+
+ var/userloc = H.loc
+
+ //see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments!
+ //this is largely copypasted from there.
+
+ //handle facial hair (if necessary)
+ if(H.gender == MALE)
+ var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list
+ if(userloc != H.loc)
+ return //no tele-grooming
+ if(new_style)
+ H.facial_hair_style = new_style
+ else
+ H.facial_hair_style = "Shaved"
+
+ //handle normal hair
+ var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list
+ if(userloc != H.loc)
+ return //no tele-grooming
+ if(new_style)
+ H.hair_style = new_style
+
+ H.update_hair()
+
+/obj/structure/mirror/examine_status(mob/user)
+ if(broken)
+ return // no message spam
+ ..()
+
+/obj/structure/mirror/obj_break(damage_flag)
+ if(!broken && !(flags_1 & NODECONSTRUCT_1))
+ icon_state = "mirror_broke"
+ playsound(src, "shatter", 70, 1)
+ desc = "Oh no, seven years of bad luck!"
+ broken = 1
+
+/obj/structure/mirror/deconstruct(disassembled = TRUE)
+ if(!(flags_1 & NODECONSTRUCT_1))
+ if(!disassembled)
+ new /obj/item/shard( src.loc )
+ qdel(src)
+
+/obj/structure/mirror/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/weldingtool) && user.a_intent != INTENT_HARM)
+ var/obj/item/weldingtool/WT = I
+ if(broken)
+ user.changeNext_move(CLICK_CD_MELEE)
+ if(WT.remove_fuel(0, user))
+ to_chat(user, "You begin repairing [src]...")
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
+ if(do_after(user, 10*I.toolspeed, target = src))
+ if(!user || !WT || !WT.isOn())
+ return
+ to_chat(user, "You repair [src].")
+ broken = 0
+ icon_state = initial(icon_state)
+ desc = initial(desc)
+ else
+ return ..()
+
+/obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
+ switch(damage_type)
+ if(BRUTE)
+ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
+ if(BURN)
+ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
+
+
+/obj/structure/mirror/magic
+ name = "magic mirror"
+ desc = "Turn and face the strange... face."
+ icon_state = "magic_mirror"
+ var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombie")
+ var/list/choosable_races = list()
+
+/obj/structure/mirror/magic/New()
+ if(!choosable_races.len)
+ for(var/speciestype in subtypesof(/datum/species))
+ var/datum/species/S = new speciestype()
+ if(!(S.id in races_blacklist))
+ choosable_races += S.id
+ ..()
+
+/obj/structure/mirror/magic/lesser/New()
+ var/list/L = CONFIG_GET(keyed_flag_list/roundstart_races)
+ choosable_races = L.Copy()
+ ..()
+
+/obj/structure/mirror/magic/badmin/New()
+ for(var/speciestype in subtypesof(/datum/species))
+ var/datum/species/S = new speciestype()
+ choosable_races += S.id
+ ..()
+
+/obj/structure/mirror/magic/attack_hand(mob/user)
+ if(!ishuman(user))
+ return
+
+ var/mob/living/carbon/human/H = user
+
+ var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes")
+
+ if(!Adjacent(user))
+ return
+
+ switch(choice)
+ if("name")
+ var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN)
+
+ if(!newname)
+ return
+ if(!Adjacent(user))
+ return
+ H.real_name = newname
+ H.name = newname
+ if(H.dna)
+ H.dna.real_name = newname
+ if(H.mind)
+ H.mind.name = newname
+
+ if("race")
+ var/newrace
+ var/racechoice = input(H, "What are we again?", "Race change") as null|anything in choosable_races
+ newrace = GLOB.species_list[racechoice]
+
+ if(!newrace)
+ return
+ if(!Adjacent(user))
+ return
+ H.set_species(newrace, icon_update=0)
+
+ if(H.dna.species.use_skintones)
+ var/new_s_tone = input(user, "Choose your skin tone:", "Race change") as null|anything in GLOB.skin_tones
+
+ if(new_s_tone)
+ H.skin_tone = new_s_tone
+ H.dna.update_ui_block(DNA_SKIN_TONE_BLOCK)
+
+ if(MUTCOLORS in H.dna.species.species_traits)
+ var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null
+ if(new_mutantcolor)
+ var/temp_hsv = RGBtoHSV(new_mutantcolor)
+
+ if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright
+ H.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
+
+ else
+ to_chat(H, "Invalid color. Your color is not bright enough.")
+
+ H.update_body()
+ H.update_hair()
+ H.update_body_parts()
+ H.update_mutations_overlay() // no hulk lizard
+
+ if("gender")
+ if(!(H.gender in list("male", "female"))) //blame the patriarchy
+ return
+ if(!Adjacent(user))
+ return
+ if(H.gender == "male")
+ if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes")
+ H.gender = "female"
+ to_chat(H, "Man, you feel like a woman!")
+ else
+ return
+
+ else
+ if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes")
+ H.gender = "male"
+ to_chat(H, "Whoa man, you feel like a man!")
+ else
+ return
+ H.dna.update_ui_block(DNA_GENDER_BLOCK)
+ H.update_body()
+ H.update_mutations_overlay() //(hulk male/female)
+
+ if("hair")
+ var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color")
+ if(!Adjacent(user))
+ return
+ if(hairchoice == "Style") //So you just want to use a mirror then?
+ ..()
+ else
+ var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color
+ if(new_hair_color)
+ H.hair_color = sanitize_hexcolor(new_hair_color)
+ H.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK)
+ if(H.gender == "male")
+ var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color
+ if(new_face_color)
+ H.facial_hair_color = sanitize_hexcolor(new_face_color)
+ H.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK)
+ H.update_hair()
+
+ if("eyes")
+ var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color
+ if(!Adjacent(user))
+ return
+ if(new_eye_color)
+ H.eye_color = sanitize_hexcolor(new_eye_color)
+ H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
+ H.update_body()
+ if(choice)
+ curse(user)
+
+/obj/structure/mirror/magic/proc/curse(mob/living/user)
+ return
+>>>>>>> 4178c20... Configuration datum refactor (#30763)
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index b1b00b3e55..6eec793c0e 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -66,7 +66,7 @@
return
/turf/open/space/proc/update_starlight()
- if(config.starlight)
+ if(CONFIG_GET(flag/starlight))
for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
if(isspaceturf(t))
//let's NOT update this that much pls
diff --git a/code/game/world.dm b/code/game/world.dm
index 3763a408ac..316ed70961 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -12,7 +12,7 @@ GLOBAL_PROTECT(security_mode)
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
- config = new
+ new /datum/controller/configuration
CheckSchemaVersion()
SetRoundID()
@@ -25,7 +25,7 @@ GLOBAL_PROTECT(security_mode)
load_motd()
load_admins()
LoadVerbs(/datum/verbs/menu)
- if(config.usewhitelist)
+ if(CONFIG_GET(flag/usewhitelist))
load_whitelist()
LoadBans()
@@ -33,7 +33,7 @@ GLOBAL_PROTECT(security_mode)
Master.Initialize(10, FALSE)
- if(config.irc_announce_new_game)
+ if(CONFIG_GET(flag/irc_announce_new_game))
IRCBroadcast("New round starting on [SSmapping.config.map_name]!")
/world/proc/SetupExternalRSC()
@@ -48,7 +48,7 @@ GLOBAL_PROTECT(security_mode)
#endif
/world/proc/CheckSchemaVersion()
- if(config.sql_enabled)
+ if(CONFIG_GET(flag/sql_enabled))
if(SSdbcore.Connect())
log_world("Database connection established.")
var/datum/DBQuery/query_db_version = SSdbcore.NewQuery("SELECT major, minor FROM [format_table_name("schema_revision")] ORDER BY date DESC LIMIT 1")
@@ -68,7 +68,7 @@ GLOBAL_PROTECT(security_mode)
log_world("Your server failed to establish a connection with the database.")
/world/proc/SetRoundID()
- if(config.sql_enabled)
+ if(CONFIG_GET(flag/sql_enabled))
if(SSdbcore.Connect())
var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (start_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
query_round_start.Execute()
@@ -122,12 +122,13 @@ GLOBAL_PROTECT(security_mode)
var/pinging = ("ping" in input)
var/playing = ("players" in input)
- if(!pinging && !playing && config && config.log_world_topic)
+ if(!pinging && !playing && config && CONFIG_GET(flag/log_world_topic))
WRITE_FILE(GLOB.world_game_log, "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]")
if(input[SERVICE_CMD_PARAM_KEY])
return ServiceCommand(input)
- var/key_valid = (global.comms_allowed && input["key"] == global.comms_key)
+ var/comms_key = CONFIG_GET(string/comms_key)
+ var/key_valid = (comms_key && input["key"] == comms_key)
if(pinging)
var/x = 1
@@ -157,10 +158,10 @@ GLOBAL_PROTECT(security_mode)
var/list/s = list()
s["version"] = GLOB.game_version
s["mode"] = GLOB.master_mode
- s["respawn"] = config ? GLOB.abandon_allowed : 0
+ s["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
s["enter"] = GLOB.enter_allowed
- s["vote"] = config.allow_vote_mode
- s["ai"] = config.allow_ai
+ s["vote"] = CONFIG_GET(flag/allow_vote_mode)
+ s["ai"] = CONFIG_GET(flag/allow_ai)
s["host"] = host ? host : null
s["active_players"] = get_active_player_count()
s["players"] = GLOB.clients.len
@@ -262,17 +263,6 @@ GLOBAL_PROTECT(security_mode)
GLOB.join_motd = file2text("config/motd.txt") + " " + GLOB.revdata.GetTestMergeInfo()
/world/proc/update_status()
- var/s = ""
-
- if (config && config.server_name)
- s += "[config.server_name] — "
-
- s += "[station_name()]";
- s += " ("
- s += "" //Change this to wherever you want the hub to link to.
- s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version.
- s += ""
- s += ")"
var/list/features = list()
@@ -282,13 +272,25 @@ GLOBAL_PROTECT(security_mode)
if (!GLOB.enter_allowed)
features += "closed"
- features += GLOB.abandon_allowed ? "respawn" : "no respawn"
+ var/s = ""
+ var/hostedby
+ if(config)
+ var/server_name = CONFIG_GET(string/servername)
+ if (server_name)
+ s += "[server_name] — "
+ features += "[CONFIG_GET(flag/norespawn) ? "no " : ""]respawn"
+ if(CONFIG_GET(flag/allow_vote_mode))
+ features += "vote"
+ if(CONFIG_GET(flag/allow_ai))
+ features += "AI allowed"
+ hostedby = CONFIG_GET(string/hostedby)
- if (config && config.allow_vote_mode)
- features += "vote"
-
- if (config && config.allow_ai)
- features += "AI allowed"
+ s += "[station_name()]";
+ s += " ("
+ s += "" //Change this to wherever you want the hub to link to.
+ s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version.
+ s += ""
+ s += ")"
var/n = 0
for (var/mob/M in GLOB.player_list)
@@ -300,8 +302,8 @@ GLOBAL_PROTECT(security_mode)
else if (n > 0)
features += "~[n] player"
- if (!host && config && config.hostedby)
- features += "hosted by [config.hostedby]"
+ if (!host && hostedby)
+ features += "hosted by [hostedby]"
if (features)
s += ": [jointext(features, ", ")]"
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 39a465d2b4..10a3774ae1 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -20,7 +20,7 @@
admin = 1
//Whitelist
- if(config.usewhitelist)
+ if(CONFIG_GET(flag/usewhitelist))
if(!check_whitelist(ckey(key)))
if (admin)
log_admin("The admin [key] has been allowed to bypass the whitelist")
@@ -32,19 +32,20 @@
//Guest Checking
if(IsGuestKey(key))
- if (!GLOB.guests_allowed)
+ if (CONFIG_GET(flag/guest_ban))
log_access("Failed Login: [key] - Guests not allowed")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
- if (config.panic_bunker && SSdbcore && SSdbcore.IsConnected())
+ if (CONFIG_GET(flag/panic_bunker) && SSdbcore.Connect())
log_access("Failed Login: [key] - Guests not allowed during panic bunker")
return list("reason"="guest", "desc"="\nReason: Sorry but the server is currently not accepting connections from never before seen players or guests. If you have played on this server with a byond account before, please log in to the byond account you have played from.")
//Population Cap Checking
- if(config.extreme_popcap && living_player_count() >= config.extreme_popcap && !admin)
+ var/extreme_popcap = CONFIG_GET(number/extreme_popcap)
+ if(extreme_popcap && living_player_count() >= extreme_popcap && !admin)
log_access("Failed Login: [key] - Population cap reached")
- return list("reason"="popcap", "desc"= "\nReason: [config.extreme_popcap_message]")
+ return list("reason"="popcap", "desc"= "\nReason: [CONFIG_GET(string/extreme_popcap_message)]")
- if(config.ban_legacy_system)
+ if(CONFIG_GET(flag/ban_legacy_system))
//Ban Checking
. = CheckBan( ckey(key), computer_id, address )
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index 5ea980a91d..27d5502edf 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -11,8 +11,9 @@ GLOBAL_PROTECT(Banlist)
. = list()
var/appeal
- if(config && config.banappeals)
- appeal = "\nFor more information on your ban, or to appeal, head to [config.banappeals]"
+ var/bran = CONFIG_GET(string/banappeals)
+ if(bran)
+ appeal = "\nFor more information on your ban, or to appeal, head to [bran]"
GLOB.Banlist.cd = "/base"
if( "[ckey][id]" in GLOB.Banlist.dir )
GLOB.Banlist.cd = "[ckey][id]"
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index b56caa4e9a..881e59204d 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -31,7 +31,7 @@
if(M.client)
body += " played by [M.client] "
body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\]"
- if(config.use_exp_tracking)
+ if(CONFIG_GET(flag/use_exp_tracking))
body += "\[" + M.client.get_exp_living() + "\]"
if(isnewplayer(M))
@@ -555,28 +555,30 @@
set category = "Server"
set desc="People can't be AI"
set name="Toggle AI"
- config.allow_ai = !( config.allow_ai )
- if (!( config.allow_ai ))
+ var/alai = CONFIG_GET(flag/allow_ai)
+ CONFIG_SET(flag/allow_ai, !alai)
+ if (alai)
to_chat(world, "The AI job is no longer chooseable.")
else
to_chat(world, "The AI job is chooseable now.")
log_admin("[key_name(usr)] toggled AI allowed.")
world.update_status()
- SSblackbox.add_details("admin_toggle","Toggle AI|[config.allow_ai]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_toggle","Toggle AI|[!alai]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleaban()
set category = "Server"
set desc="Respawn basically"
set name="Toggle Respawn"
- GLOB.abandon_allowed = !( GLOB.abandon_allowed )
- if (GLOB.abandon_allowed)
+ var/new_nores = !CONFIG_GET(flag/norespawn)
+ CONFIG_SET(flag/norespawn, new_nores)
+ if (!new_nores)
to_chat(world, "You may now respawn.")
else
to_chat(world, "You may no longer respawn :(")
- message_admins("[key_name_admin(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].")
- log_admin("[key_name(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].")
+ message_admins("[key_name_admin(usr)] toggled respawn to [!new_nores ? "On" : "Off"].")
+ log_admin("[key_name(usr)] toggled respawn to [!new_nores ? "On" : "Off"].")
world.update_status()
- SSblackbox.add_details("admin_toggle","Toggle Respawn|[GLOB.abandon_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_toggle","Toggle Respawn|[!new_nores]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/delay()
set category = "Server"
@@ -683,14 +685,15 @@
set category = "Server"
set desc="Guests can't enter"
set name="Toggle guests"
- GLOB.guests_allowed = !( GLOB.guests_allowed )
- if (!( GLOB.guests_allowed ))
+ var/new_guest_ban = !CONFIG_GET(flag/guest_ban)
+ CONFIG_SET(flag/guest_ban, new_guest_ban)
+ if (new_guest_ban)
to_chat(world, "Guests may no longer enter the game.")
else
to_chat(world, "Guests may now enter the game.")
- log_admin("[key_name(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.")
- message_admins("[key_name_admin(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.")
- SSblackbox.add_details("admin_toggle","Toggle Guests|[GLOB.guests_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ log_admin("[key_name(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed.")
+ message_admins("[key_name_admin(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed.")
+ SSblackbox.add_details("admin_toggle","Toggle Guests|[!new_guest_ban]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/output_ai_laws()
var/ai_number = 0
@@ -828,10 +831,10 @@
/client/proc/adminGreet(logout)
if(SSticker.HasRoundStarted())
var/string
- if(logout && config && config.announce_admin_logout)
+ if(logout && CONFIG_GET(flag/announce_admin_logout))
string = pick(
"Admin logout: [key_name(src)]")
- else if(!logout && config && config.announce_admin_login && (prefs.toggles & ANNOUNCE_LOGIN))
+ else if(!logout && CONFIG_GET(flag/announce_admin_login) && (prefs.toggles & ANNOUNCE_LOGIN))
string = pick(
"Admin login: [key_name(src)]")
if(string)
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index 828fbb2e91..343c5686f2 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -117,7 +117,7 @@ GLOBAL_PROTECT(admin_ranks)
return
GLOB.admin_ranks.Cut()
- if(config.admin_legacy_system)
+ if(CONFIG_GET(flag/admin_legacy_system))
var/previous_rights = 0
//load text from file and process each line separately
for(var/line in world.file2list("config/admin_ranks.txt"))
@@ -143,7 +143,7 @@ GLOBAL_PROTECT(admin_ranks)
if(!SSdbcore.Connect())
log_world("Failed to connect to database in load_admin_ranks(). Reverting to legacy system.")
WRITE_FILE(GLOB.world_game_log, "Failed to connect to database in load_admin_ranks(). Reverting to legacy system.")
- config.admin_legacy_system = 1
+ CONFIG_SET(flag/admin_legacy_system, TRUE)
load_admin_ranks()
return
@@ -191,7 +191,7 @@ GLOBAL_PROTECT(admin_ranks)
for(var/datum/admin_rank/R in GLOB.admin_ranks)
rank_names[R.name] = R
- if(config.admin_legacy_system)
+ if(CONFIG_GET(flag/admin_legacy_system))
//load text from file
var/list/lines = world.file2list("config/admins.txt")
@@ -221,7 +221,7 @@ GLOBAL_PROTECT(admin_ranks)
if(!SSdbcore.Connect())
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
WRITE_FILE(GLOB.world_game_log, "Failed to connect to database in load_admins(). Reverting to legacy system.")
- config.admin_legacy_system = 1
+ CONFIG_SET(flag/admin_legacy_system, TRUE)
load_admins()
return
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 526d05b76b..0f2702f3b6 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -262,7 +262,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
verbs += GLOB.admin_verbs_poll
if(rights & R_SOUNDS)
verbs += GLOB.admin_verbs_sounds
- if(config.invoke_youtubedl)
+ if(CONFIG_GET(string/invoke_youtubedl))
verbs += /client/proc/play_web_sound
if(rights & R_SPAWN)
verbs += GLOB.admin_verbs_spawn
@@ -399,7 +399,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
set name = "Unban Panel"
set category = "Admin"
if(holder)
- if(config.ban_legacy_system)
+ if(CONFIG_GET(flag/ban_legacy_system))
holder.unbanpanel()
else
holder.DB_ban_panel()
diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm
index 50f81e01c3..d048b71170 100644
--- a/code/modules/admin/ipintel.dm
+++ b/code/modules/admin/ipintel.dm
@@ -14,18 +14,18 @@
. = FALSE
if (intel < 0)
return
- if (intel <= config.ipintel_rating_bad)
- if (world.realtime < cacherealtime+(config.ipintel_save_good*60*60*10))
+ if (intel <= CONFIG_GET(number/ipintel_rating_bad))
+ if (world.realtime < cacherealtime + (CONFIG_GET(number/ipintel_save_good) * 60 * 60 * 10))
return TRUE
else
- if (world.realtime < cacherealtime+(config.ipintel_save_bad*60*60*10))
+ if (world.realtime < cacherealtime + (CONFIG_GET(number/ipintel_save_bad) * 60 * 60 * 10))
return TRUE
/proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE)
var/datum/ipintel/res = new()
res.ip = ip
. = res
- if (!ip || !config.ipintel_email || !SSipintel.enabled)
+ if (!ip || !CONFIG_GET(string/ipintel_email) || !SSipintel.enabled)
return
if (!bypasscache)
var/datum/ipintel/cachedintel = SSipintel.cache[ip]
@@ -34,19 +34,20 @@
return cachedintel
if(SSdbcore.Connect())
+ var/rating_bad = CONFIG_GET(number/ipintel_rating_bad)
var/datum/DBQuery/query_get_ip_intel = SSdbcore.NewQuery({"
SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW())
FROM [format_table_name("ipintel")]
WHERE
ip = INET_ATON('[ip]')
AND ((
- intel < [config.ipintel_rating_bad]
+ intel < [rating_bad]
AND
- date + INTERVAL [config.ipintel_save_good] HOUR > NOW()
+ date + INTERVAL [CONFIG_GET(number/ipintel_save_good)] HOUR > NOW()
) OR (
- intel >= [config.ipintel_rating_bad]
+ intel >= [rating_bad]
AND
- date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()
+ date + INTERVAL [CONFIG_GET(number/ipintel_save_bad)] HOUR > NOW()
))
"})
if(!query_get_ip_intel.Execute())
@@ -77,7 +78,11 @@
if (!SSipintel.enabled)
return
+<<<<<<< HEAD
var/list/http[] = world.Export("http://[config.ipintel_domain]/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json&flags_1=f")
+=======
+ var/list/http[] = world.Export("http://[CONFIG_GET(string/ipintel_domain)]/check.php?ip=[ip]&contact=[CONFIG_GET(string/ipintel_email)]&format=json&flags=f")
+>>>>>>> 4178c20... Configuration datum refactor (#30763)
if (http)
var/status = text2num(http["STATUS"])
diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm
index f0f263f815..24a53eff2b 100644
--- a/code/modules/admin/permissionverbs/permissionedit.dm
+++ b/code/modules/admin/permissionverbs/permissionedit.dm
@@ -51,7 +51,7 @@
usr << browse(output,"window=editrights;size=900x650")
/datum/admins/proc/log_admin_rank_modification(adm_ckey, new_rank)
- if(config.admin_legacy_system)
+ if(CONFIG_GET(flag/admin_legacy_system))
return
if(!usr.client)
@@ -105,7 +105,7 @@
/datum/admins/proc/log_admin_permission_modification(adm_ckey, new_permission)
- if(config.admin_legacy_system)
+ if(CONFIG_GET(flag/admin_legacy_system))
return
if(!usr.client)
return
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 39e07e0a9f..9e43ef92f8 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -329,14 +329,14 @@
else
dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)] "
dat += "Continuous Round Status "
- dat += "[config.continuous[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]"
- if(config.continuous[SSticker.mode.config_tag])
- dat += ", [config.midround_antag[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"] "
+ dat += "[CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]"
+ if(CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag])
+ dat += ", [CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"] "
else
dat += " "
- if(config.midround_antag[SSticker.mode.config_tag])
- dat += "Time limit: [config.midround_antag_time_check] minutes into round "
- dat += "Living crew limit: [config.midround_antag_life_check * 100]% of crew alive "
+ if(CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
+ dat += "Time limit: [CONFIG_GET(number/midround_antag_time_check)] minutes into round "
+ dat += "Living crew limit: [CONFIG_GET(number/midround_antag_life_check) * 100]% of crew alive "
dat += "If limits past: [SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"] "
dat += "End Round Now "
dat += "[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]"
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 99f95cd6f4..9fd49ed497 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -354,16 +354,9 @@
SSblackbox.add_details("admin_secrets_fun_used","Bomb Cap")
var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be above 4)", "New Bomb Cap", GLOB.MAX_EX_LIGHT_RANGE) as num|null
- if (newBombCap < 4)
+ if (!CONFIG_SET(number/bombcap, newBombCap))
return
- GLOB.MAX_EX_DEVESTATION_RANGE = round(newBombCap/4)
- GLOB.MAX_EX_HEAVY_RANGE = round(newBombCap/2)
- GLOB.MAX_EX_LIGHT_RANGE = newBombCap
- //I don't know why these are their own variables, but fuck it, they are.
- GLOB.MAX_EX_FLASH_RANGE = newBombCap
- GLOB.MAX_EX_FLAME_RANGE = newBombCap
-
message_admins("[key_name_admin(usr)] changed the bomb cap to [GLOB.MAX_EX_DEVESTATION_RANGE], [GLOB.MAX_EX_HEAVY_RANGE], [GLOB.MAX_EX_LIGHT_RANGE]")
log_admin("[key_name(usr)] changed the bomb cap to [GLOB.MAX_EX_DEVESTATION_RANGE], [GLOB.MAX_EX_HEAVY_RANGE], [GLOB.MAX_EX_LIGHT_RANGE]")
diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm
index 50236c548d..587bd6b26c 100644
--- a/code/modules/admin/sql_message_system.dm
+++ b/code/modules/admin/sql_message_system.dm
@@ -33,8 +33,9 @@
if(!timestamp)
timestamp = SQLtime()
if(!server)
- if (config && config.server_sql_name)
- server = config.server_sql_name
+ var/ssqlname = CONFIG_GET(string/serversqlname)
+ if (ssqlname)
+ server = ssqlname
server = sanitizeSQL(server)
if(isnull(secret))
switch(alert("Hide note from being viewed by players?", "Secret note?","Yes","No","Cancel"))
@@ -216,8 +217,10 @@
var/editor_ckey = query_get_messages.item[8]
var/age = text2num(query_get_messages.item[9])
var/alphatext = ""
- if (agegate && type == "note" && isnum(config.note_stale_days) && isnum(config.note_fresh_days) && config.note_stale_days > config.note_fresh_days)
- var/alpha = Clamp(100 - (age - config.note_fresh_days) * (85 / (config.note_stale_days - config.note_fresh_days)), 15, 100)
+ var/nsd = CONFIG_GET(number/note_stale_days)
+ var/nfd = CONFIG_GET(number/note_fresh_days)
+ if (agegate && type == "note" && isnum(nsd) && isnum(nfd) && nsd > nfd)
+ var/alpha = Clamp(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100)
if (alpha < 100)
if (alpha <= 15)
if (skipped)
@@ -353,8 +356,9 @@ proc/get_message_output(type, target_ckey)
var/notetext
notesfile >> notetext
var/server
- if(config && config.server_sql_name)
- server = config.server_sql_name
+ var/ssqlname = CONFIG_GET(string/serversqlname)
+ if (ssqlname)
+ server = ssqlname
var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i")
note.Find(notetext)
var/timestamp = note.group[1]
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 7f9f5a7d27..c182107a6a 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -5,7 +5,7 @@
return
var/msg = !auth ? "no" : "a bad"
message_admins("[key_name_admin(usr)] clicked an href with [msg] authorization key!")
- if(config.debug_admin_hrefs)
+ if(CONFIG_GET(flag/debug_admin_hrefs))
message_admins("Debug mode enabled, call not blocked. Please ask your coders to review this round's logs.")
log_world("UAH: [href]")
return TRUE
@@ -318,35 +318,36 @@
else if(href_list["toggle_continuous"])
if(!check_rights(R_ADMIN))
return
-
- if(!config.continuous[SSticker.mode.config_tag])
- config.continuous[SSticker.mode.config_tag] = 1
+ var/list/continuous = CONFIG_GET(keyed_flag_list/continuous)
+ if(!continuous[SSticker.mode.config_tag])
+ continuous[SSticker.mode.config_tag] = TRUE
else
- config.continuous[SSticker.mode.config_tag] = 0
+ continuous[SSticker.mode.config_tag] = FALSE
- message_admins("[key_name_admin(usr)] toggled the round to [config.continuous[SSticker.mode.config_tag] ? "continue if all antagonists die" : "end with the antagonists"].")
+ message_admins("[key_name_admin(usr)] toggled the round to [continuous[SSticker.mode.config_tag] ? "continue if all antagonists die" : "end with the antagonists"].")
check_antagonists()
else if(href_list["toggle_midround_antag"])
if(!check_rights(R_ADMIN))
return
- if(!config.midround_antag[SSticker.mode.config_tag])
- config.midround_antag[SSticker.mode.config_tag] = 1
+ var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag)
+ if(!midround_antag[SSticker.mode.config_tag])
+ midround_antag[SSticker.mode.config_tag] = TRUE
else
- config.midround_antag[SSticker.mode.config_tag] = 0
+ midround_antag[SSticker.mode.config_tag] = FALSE
- message_admins("[key_name_admin(usr)] toggled the round to [config.midround_antag[SSticker.mode.config_tag] ? "use" : "skip"] the midround antag system.")
+ message_admins("[key_name_admin(usr)] toggled the round to [midround_antag[SSticker.mode.config_tag] ? "use" : "skip"] the midround antag system.")
check_antagonists()
else if(href_list["alter_midround_time_limit"])
if(!check_rights(R_ADMIN))
return
- var/timer = input("Enter new maximum time",, config.midround_antag_time_check ) as num|null
+ var/timer = input("Enter new maximum time",, CONFIG_GET(number/midround_antag_time_check)) as num|null
if(!timer)
return
- config.midround_antag_time_check = timer
+ CONFIG_SET(number/midround_antag_time_check, timer)
message_admins("[key_name_admin(usr)] edited the maximum midround antagonist time to [timer] minutes.")
check_antagonists()
@@ -354,9 +355,10 @@
if(!check_rights(R_ADMIN))
return
- var/ratio = input("Enter new life ratio",, config.midround_antag_life_check*100) as num
- if(ratio)
- config.midround_antag_life_check = ratio/100
+ var/ratio = input("Enter new life ratio",, CONFIG_GET(number/midround_antag_life_check) * 100) as num
+ if(!ratio)
+ return
+ CONFIG_SET(number/midround_antag_life_check, ratio / 100)
message_admins("[key_name_admin(usr)] edited the midround antagonist living crew ratio to [ratio]% alive.")
check_antagonists()
@@ -586,8 +588,9 @@
to_chat(M, "You have been appearance banned by [usr.client.ckey].")
to_chat(M, "The reason is: [reason]")
to_chat(M, "Appearance ban can be lifted only upon request.")
- if(config.banappeals)
- to_chat(M, "To try to resolve this matter head to [config.banappeals]")
+ var/bran = CONFIG_GET(string/banappeals)
+ if(bran)
+ to_chat(M, "To try to resolve this matter head to [bran]")
else
to_chat(M, "No ban appeals URL has been set.")
if("No")
@@ -1156,8 +1159,9 @@
to_chat(M, "This is a temporary ban, it will be removed in [mins] minutes.")
SSblackbox.inc("ban_tmp",1)
SSblackbox.inc("ban_tmp_mins",mins)
- if(config.banappeals)
- to_chat(M, "To try to resolve this matter head to [config.banappeals]")
+ var/bran = CONFIG_GET(string/banappeals)
+ if(bran)
+ to_chat(M, "To try to resolve this matter head to [bran]")
else
to_chat(M, "No ban appeals URL has been set.")
log_admin_private("[key_name(usr)] has banned [M.ckey].\nReason: [key_name(M)]\nThis will be removed in [mins] minutes.")
@@ -1180,8 +1184,9 @@
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0)
to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason]")
to_chat(M, "This is a permanent ban.")
- if(config.banappeals)
- to_chat(M, "To try to resolve this matter head to [config.banappeals]")
+ var/bran = CONFIG_GET(string/banappeals)
+ if(bran)
+ to_chat(M, "To try to resolve this matter head to [bran]")
else
to_chat(M, "No ban appeals URL has been set.")
if(!DB_ban_record(BANTYPE_PERMA, M, -1, reason))
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 7922a89c80..a61de11c30 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -589,19 +589,20 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
/proc/send2irc(msg,msg2)
if(world.RunningService())
world.ExportService("[SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE] [msg] | [msg2]")
- else if(config.useircbot)
+ else if(CONFIG_GET(flag/useircbot))
shell("python nudge.py [msg] [msg2]")
/proc/send2otherserver(source,msg,type = "Ahelp")
- if(config.cross_allowed)
+ var/comms_key = CONFIG_GET(string/comms_key)
+ if(comms_key)
var/list/message = list()
message["message_sender"] = source
message["message"] = msg
- message["source"] = "([config.cross_name])"
- message["key"] = global.comms_key
+ message["source"] = "([CONFIG_GET(string/cross_comms_name)])"
+ message["key"] = comms_key
message["crossmessage"] = type
- world.Export("[config.cross_address]?[list2params(message)]")
+ world.Export("[CONFIG_GET(string/cross_server_address)]?[list2params(message)]")
/proc/ircadminwho()
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index db29021463..038e454a24 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -185,7 +185,7 @@
SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg'))
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
- if(config.popup_admin_pm)
+ if(CONFIG_GET(flag/popup_admin_pm))
spawn() //so we don't hold the caller proc up
var/sender = src
var/sendername = key
@@ -277,7 +277,7 @@
return "Error: Ticket could not be found"
var/static/stealthkey
- var/adminname = config.showircname ? irc_tagged : "Administrator"
+ var/adminname = CONFIG_GET(flag/show_irc_name) ? irc_tagged : "Administrator"
if(!C)
return "Error: No client"
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index f8131ec5c7..ba42dbb9ba 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -836,11 +836,11 @@ GLOBAL_PROTECT(AdminProcCallCount)
if(!holder)
return
- global.medals_enabled = !global.medals_enabled
+ GLOB.medals_enabled = !GLOB.medals_enabled
- message_admins("[key_name_admin(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
+ message_admins("[key_name_admin(src)] [GLOB.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
SSblackbox.add_details("admin_verb","Toggle Medal Disable") // If...
- log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
+ log_admin("[key_name(src)] [GLOB.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
/client/proc/view_runtimes()
set category = "Debug"
diff --git a/code/modules/admin/verbs/fps.dm b/code/modules/admin/verbs/fps.dm
index bedcd0a6e5..f893c43e08 100644
--- a/code/modules/admin/verbs/fps.dm
+++ b/code/modules/admin/verbs/fps.dm
@@ -7,13 +7,14 @@
if(!check_rights(R_DEBUG))
return
- var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [config.fps])","FPS", world.fps) as num|null)
+ var/cfg_fps = CONFIG_GET(number/fps)
+ var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [cfg_fps])","FPS", world.fps) as num|null)
if(new_fps <= 0)
to_chat(src, "Error: set_server_fps(): Invalid world.fps value. No changes made.")
return
- if(new_fps > config.fps*1.5)
- if(alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [config.fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
+ if(new_fps > cfg_fps * 1.5)
+ if(alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [cfg_fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
return
var/msg = "[key_name(src)] has modified world.fps to [new_fps]"
@@ -21,4 +22,5 @@
message_admins(msg, 0)
SSblackbox.add_details("admin_toggle","Set Server FPS|[new_fps]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ CONFIG_SET(number/fps, new_fps)
world.fps = new_fps
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index e8ba7c8bab..d14fb1f167 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -31,10 +31,10 @@
/datum/admins/proc/makeTraitors()
var/datum/game_mode/traitor/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
@@ -67,10 +67,10 @@
/datum/admins/proc/makeChanglings()
var/datum/game_mode/changeling/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
@@ -100,10 +100,10 @@
/datum/admins/proc/makeRevs()
var/datum/game_mode/revolution/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
@@ -142,10 +142,10 @@
/datum/admins/proc/makeCult()
var/datum/game_mode/cult/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
@@ -175,10 +175,10 @@
/datum/admins/proc/makeClockCult()
var/datum/game_mode/clockwork_cult/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
@@ -340,7 +340,7 @@
missiondesc += " Your Mission: [mission]"
to_chat(Commando, missiondesc)
- if(config.enforce_human_authority)
+ if(CONFIG_GET(flag/enforce_human_authority))
Commando.set_species(/datum/species/human)
//Logging and cleanup
@@ -382,7 +382,7 @@
missionobj.completed = 1
newmob.mind.objectives += missionobj
- if(config.enforce_human_authority)
+ if(CONFIG_GET(flag/enforce_human_authority))
newmob.set_species(/datum/species/human)
//Greet the official
@@ -497,7 +497,7 @@
missiondesc += " Your Mission: [mission]"
to_chat(ERTOperative, missiondesc)
- if(config.enforce_human_authority)
+ if(CONFIG_GET(flag/enforce_human_authority))
ERTOperative.set_species(/datum/species/human)
//Logging and cleanup
diff --git a/code/modules/admin/verbs/panicbunker.dm b/code/modules/admin/verbs/panicbunker.dm
index 3da486be78..b159445963 100644
--- a/code/modules/admin/verbs/panicbunker.dm
+++ b/code/modules/admin/verbs/panicbunker.dm
@@ -1,15 +1,16 @@
/client/proc/panicbunker()
set category = "Server"
set name = "Toggle Panic Bunker"
- if (!config.sql_enabled)
+ if (!CONFIG_GET(flag/sql_enabled))
to_chat(usr, "The Database is not enabled!")
return
- config.panic_bunker = (!config.panic_bunker)
+ var/new_pb = !CONFIG_GET(flag/panic_bunker)
+ CONFIG_SET(flag/panic_bunker, new_pb)
- log_admin("[key_name(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker?"on":"off")]")
- message_admins("[key_name_admin(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker?"enabled":"disabled")].")
- if (config.panic_bunker && (!SSdbcore || !SSdbcore.IsConnected()))
+ log_admin("[key_name(usr)] has toggled the Panic Bunker, it is now [new_pb ? "on" : "off"]")
+ message_admins("[key_name_admin(usr)] has toggled the Panic Bunker, it is now [new_pb ? "enabled" : "disabled"].")
+ if (new_pb && !SSdbcore.Connect())
message_admins("The Database is not connected! Panic bunker will not work until the connection is reestablished.")
- SSblackbox.add_details("admin_toggle","Toggle Panic Bunker|[config.panic_bunker]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_toggle","Toggle Panic Bunker|[new_pb]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm
index 61df0cb8d1..d63d0d712f 100644
--- a/code/modules/admin/verbs/playsound.dm
+++ b/code/modules/admin/verbs/playsound.dm
@@ -62,7 +62,8 @@
if(!check_rights(R_SOUNDS))
return
- if(!config.invoke_youtubedl)
+ var/ytdl = CONFIG_GET(string/invoke_youtubedl)
+ if(!ytdl)
to_chat(src, "Youtube-dl was not configured, action unavailable") //Check config.txt for the INVOKE_YOUTUBEDL value
return
@@ -79,7 +80,7 @@
to_chat(src, "For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website.")
return
var/shell_scrubbed_input = shell_url_scrub(web_sound_input)
- var/list/output = world.shelleo("[config.invoke_youtubedl] --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --get-url \"[shell_scrubbed_input]\"")
+ var/list/output = world.shelleo("[ytdl] --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --get-url \"[shell_scrubbed_input]\"")
var/errorlevel = output[SHELLEO_ERRORLEVEL]
var/stdout = output[SHELLEO_STDOUT]
var/stderr = output[SHELLEO_STDERR]
diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm
index e271cdb3a7..483c9470a2 100644
--- a/code/modules/admin/verbs/possess.dm
+++ b/code/modules/admin/verbs/possess.dm
@@ -2,7 +2,7 @@
set name = "Possess Obj"
set category = "Object"
- if(O.dangerous_possession && config.forbid_singulo_possession)
+ if(O.dangerous_possession && CONFIG_GET(flag/forbid_singulo_possession))
to_chat(usr, "[O] is too powerful for you to possess.")
return
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 975e8aa731..c30308223f 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list)
set category = null
set name = "Drop Everything"
@@ -1256,4 +1257,1265 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
to_chat(usr, "ERROR: Unable to update player flags. Please check logs.")
else
message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]")
+=======
+/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list)
+ set category = null
+ set name = "Drop Everything"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ for(var/obj/item/W in M)
+ if(!M.dropItemToGround(W))
+ qdel(W)
+ M.regenerate_icons()
+
+ log_admin("[key_name(usr)] made [key_name(M)] drop everything!")
+ var/msg = "[key_name_admin(usr)] made [key_name_admin(M)] drop everything!"
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_verb","Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Subtle Message"
+
+ if(!ismob(M))
+ return
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ message_admins("[key_name_admin(src)] has started answering [key_name(M.key, 0, 0)]'s prayer.")
+ var/msg = input("Message:", text("Subtle PM to [M.key]")) as text
+
+ if (!msg)
+ message_admins("[key_name_admin(src)] decided not to answer [key_name(M.key, 0, 0)]'s prayer")
+ return
+ if(usr)
+ if (usr.client)
+ if(usr.client.holder)
+ to_chat(M, "You hear a voice in your head... [msg]")
+
+ log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
+ msg = " SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]"
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_verb","Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_world_narrate()
+ set category = "Special Verbs"
+ set name = "Global Narrate"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text
+
+ if (!msg)
+ return
+ to_chat(world, "[msg]")
+ log_admin("GlobalNarrate: [key_name(usr)] : [msg]")
+ message_admins("[key_name_admin(usr)] Sent a global narrate")
+ SSblackbox.add_details("admin_verb","Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_direct_narrate(mob/M)
+ set category = "Special Verbs"
+ set name = "Direct Narrate"
+
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ if(!M)
+ M = input("Direct narrate to whom?", "Active Players") as null|anything in GLOB.player_list
+
+ if(!M)
+ return
+
+ var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text
+
+ if( !msg )
+ return
+
+ to_chat(M, msg)
+ log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]")
+ msg = " DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg] "
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_verb","Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_local_narrate(atom/A)
+ set category = "Special Verbs"
+ set name = "Local Narrate"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ if(!A)
+ return
+ var/range = input("Range:", "Narrate to mobs within how many tiles:", 7) as num
+ if(!range)
+ return
+ var/msg = input("Message:", text("Enter the text you wish to appear to everyone within view:")) as text
+ if (!msg)
+ return
+ for(var/mob/M in view(range,A))
+ to_chat(M, msg)
+
+ log_admin("LocalNarrate: [key_name(usr)] at [get_area(A)][COORD(A)]: [msg]")
+ message_admins(" LocalNarrate: [key_name_admin(usr)] at [get_area(A)][ADMIN_JMP(A)]: [msg] ")
+ SSblackbox.add_details("admin_verb","Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Godmode"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ M.status_flags ^= GODMODE
+ to_chat(usr, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]")
+
+ log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]")
+ var/msg = "[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]"
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_toggle","Godmode|[M.status_flags & GODMODE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/proc/cmd_admin_mute(whom, mute_type, automute = 0)
+ if(!whom)
+ return
+
+ var/muteunmute
+ var/mute_string
+ var/feedback_string
+ switch(mute_type)
+ if(MUTE_IC)
+ mute_string = "IC (say and emote)"
+ feedback_string = "IC"
+ if(MUTE_OOC)
+ mute_string = "OOC"
+ feedback_string = "OOC"
+ if(MUTE_PRAY)
+ mute_string = "pray"
+ feedback_string = "Pray"
+ if(MUTE_ADMINHELP)
+ mute_string = "adminhelp, admin PM and ASAY"
+ feedback_string = "Adminhelp"
+ if(MUTE_DEADCHAT)
+ mute_string = "deadchat and DSAY"
+ feedback_string = "Deadchat"
+ if(MUTE_ALL)
+ mute_string = "everything"
+ feedback_string = "Everything"
+ else
+ return
+
+ var/client/C
+ if(istype(whom, /client))
+ C = whom
+ else if(istext(whom))
+ C = GLOB.directory[whom]
+ else
+ return
+
+ var/datum/preferences/P
+ if(C)
+ P = C.prefs
+ else
+ P = GLOB.preferences_datums[whom]
+ if(!P)
+ return
+
+ if(automute)
+ if(!CONFIG_GET(flag/automute_on))
+ return
+ else
+ if(!check_rights())
+ return
+
+ if(automute)
+ muteunmute = "auto-muted"
+ P.muted |= mute_type
+ log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(whom)] from [mute_string]")
+ message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(whom)] from [mute_string].")
+ if(C)
+ to_chat(C, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.")
+ SSblackbox.add_details("admin_toggle","Auto Mute [feedback_string]|1") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return
+
+ if(P.muted & mute_type)
+ muteunmute = "unmuted"
+ P.muted &= ~mute_type
+ else
+ muteunmute = "muted"
+ P.muted |= mute_type
+
+ log_admin("[key_name(usr)] has [muteunmute] [key_name(whom)] from [mute_string]")
+ message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(whom)] from [mute_string].")
+ if(C)
+ to_chat(C, "You have been [muteunmute] from [mute_string] by [key_name(usr, include_name = FALSE)].")
+ SSblackbox.add_details("admin_toggle","Mute [feedback_string]|[P.muted & mute_type]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+//I use this proc for respawn character too. /N
+/proc/create_xeno(ckey)
+ if(!ckey)
+ var/list/candidates = list()
+ for(var/mob/M in GLOB.player_list)
+ if(M.stat != DEAD)
+ continue //we are not dead!
+ if(!(ROLE_ALIEN in M.client.prefs.be_special))
+ continue //we don't want to be an alium
+ if(M.client.is_afk())
+ continue //we are afk
+ if(M.mind && M.mind.current && M.mind.current.stat != DEAD)
+ continue //we have a live body we are tied to
+ candidates += M.ckey
+ if(candidates.len)
+ ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates
+ else
+ to_chat(usr, "Error: create_xeno(): no suitable candidates.")
+ if(!istext(ckey))
+ return 0
+
+ var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Praetorian","Hunter","Sentinel","Drone","Larva")
+ var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : null
+ var/mob/living/carbon/alien/new_xeno
+ switch(alien_caste)
+ if("Queen")
+ new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(spawn_here)
+ if("Praetorian")
+ new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(spawn_here)
+ if("Hunter")
+ new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here)
+ if("Sentinel")
+ new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here)
+ if("Drone")
+ new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here)
+ if("Larva")
+ new_xeno = new /mob/living/carbon/alien/larva(spawn_here)
+ else
+ return 0
+ if(!spawn_here)
+ SSjob.SendToLateJoin(new_xeno, FALSE)
+
+ new_xeno.ckey = ckey
+ var/msg = "[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste]."
+ message_admins(msg)
+ admin_ticket_log(new_xeno, msg)
+ return 1
+
+/*
+If a guy was gibbed and you want to revive him, this is a good way to do so.
+Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one.
+Traitors and the like can also be revived with the previous role mostly intact.
+/N */
+/client/proc/respawn_character()
+ set category = "Special Verbs"
+ set name = "Respawn Character"
+ set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into."
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", ""))
+ if(!input)
+ return
+
+ var/mob/dead/observer/G_found
+ for(var/mob/dead/observer/G in GLOB.player_list)
+ if(G.ckey == input)
+ G_found = G
+ break
+
+ if(!G_found)//If a ghost was not found.
+ to_chat(usr, "There is no active key like that in the game or the person is not currently a ghost.")
+ return
+
+ if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
+ //Check if they were an alien
+ if(G_found.mind.assigned_role=="Alien")
+ if(alert("This character appears to have been an alien. Would you like to respawn them as such?",,"Yes","No")=="Yes")
+ var/turf/T
+ if(GLOB.xeno_spawn.len)
+ T = pick(GLOB.xeno_spawn)
+
+ var/mob/living/carbon/alien/new_xeno
+ switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were.
+ if("Hunter")
+ new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T)
+ if("Sentinel")
+ new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T)
+ if("Drone")
+ new_xeno = new /mob/living/carbon/alien/humanoid/drone(T)
+ if("Praetorian")
+ new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(T)
+ if("Queen")
+ new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(T)
+ else//If we don't know what special role they have, for whatever reason, or they're a larva.
+ create_xeno(G_found.ckey)
+ return
+
+ if(!T)
+ SSjob.SendToLateJoin(new_xeno, FALSE)
+
+ //Now to give them their mind back.
+ G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
+ new_xeno.key = G_found.key
+ to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
+ var/msg = "[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno."
+ message_admins(msg)
+ admin_ticket_log(new_xeno, msg)
+ return //all done. The ghost is auto-deleted
+
+ //check if they were a monkey
+ else if(findtext(G_found.real_name,"monkey"))
+ if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes")
+ var/mob/living/carbon/monkey/new_monkey = new
+ SSjob.SendToLateJoin(new_monkey)
+ G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
+ new_monkey.key = G_found.key
+ to_chat(new_monkey, "You have been fully respawned. Enjoy the game.")
+ var/msg = "[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno."
+ message_admins(msg)
+ admin_ticket_log(new_monkey, msg)
+ return //all done. The ghost is auto-deleted
+
+
+ //Ok, it's not a xeno or a monkey. So, spawn a human.
+ var/mob/living/carbon/human/new_character = new//The mob being spawned.
+ SSjob.SendToLateJoin(new_character)
+
+ var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
+ if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
+ /*Try and locate a record for the person being respawned through GLOB.data_core.
+ This isn't an exact science but it does the trick more often than not.*/
+ var/id = md5("[G_found.real_name][G_found.mind.assigned_role]")
+
+ record_found = find_record("id", id, GLOB.data_core.locked)
+
+ if(record_found)//If they have a record we can determine a few things.
+ new_character.real_name = record_found.fields["name"]
+ new_character.gender = record_found.fields["sex"]
+ new_character.age = record_found.fields["age"]
+ new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"])
+ else
+ var/datum/preferences/A = new()
+ A.copy_to(new_character)
+ A.real_name = G_found.real_name
+ new_character.dna.update_dna_identity()
+
+ new_character.name = new_character.real_name
+
+ if(G_found.mind && !G_found.mind.active)
+ G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
+ else
+ new_character.mind_initialize()
+ if(!new_character.mind.assigned_role)
+ new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
+
+ new_character.key = G_found.key
+
+ /*
+ The code below functions with the assumption that the mob is already a traitor if they have a special role.
+ So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role.
+ If they don't have a mind, they obviously don't have a special role.
+ */
+
+ //Two variables to properly announce later on.
+ var/admin = key_name_admin(src)
+ var/player_key = G_found.key
+
+ //Now for special roles and equipment.
+ var/datum/antagonist/traitor/traitordatum = new_character.mind.has_antag_datum(ANTAG_DATUM_TRAITOR)
+ if(traitordatum)
+ SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)
+ traitordatum.equip()
+
+
+ switch(new_character.mind.special_role)
+ if("Wizard")
+ new_character.loc = pick(GLOB.wizardstart)
+ //SSticker.mode.learn_basic_spells(new_character)
+ SSticker.mode.equip_wizard(new_character)
+ if("Syndicate")
+ var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn")
+ if(synd_spawn)
+ new_character.loc = get_turf(synd_spawn)
+ call(/datum/game_mode/proc/equip_syndicate)(new_character)
+ if("Space Ninja")
+ var/list/ninja_spawn = list()
+ for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ if(L.name=="carpspawn")
+ ninja_spawn += L
+ var/datum/antagonist/ninja/ninjadatum = new_character.mind.has_antag_datum(ANTAG_DATUM_NINJA)
+ ninjadatum.equip_space_ninja()
+ if(ninja_spawn.len)
+ var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn)
+ new_character.loc = ninja_spawn_here.loc
+
+ else//They may also be a cyborg or AI.
+ switch(new_character.mind.assigned_role)
+ if("Cyborg")//More rigging to make em' work and check if they're traitor.
+ new_character = new_character.Robotize()
+ if("AI")
+ new_character = new_character.AIize()
+ else
+ SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
+
+ //Announces the character on all the systems, based on the record.
+ if(!issilicon(new_character))//If they are not a cyborg/AI.
+ if(!record_found&&new_character.mind.assigned_role!=new_character.mind.special_role)//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway.
+ //Power to the user!
+ if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes")
+ GLOB.data_core.manifest_inject(new_character)
+
+ if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes")
+ AnnounceArrival(new_character, new_character.mind.assigned_role)
+
+ var/msg = "[admin] has respawned [player_key] as [new_character.real_name]."
+ message_admins(msg)
+ admin_ticket_log(new_character, msg)
+
+ to_chat(new_character, "You have been fully respawned. Enjoy the game.")
+
+ SSblackbox.add_details("admin_verb","Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return new_character
+
+/client/proc/cmd_admin_add_freeform_ai_law()
+ set category = "Fun"
+ set name = "Add Custom AI law"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null
+ if(!input)
+ return
+
+ log_admin("Admin [key_name(usr)] has added a new AI law - [input]")
+ message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]")
+
+ var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No")
+ var/announce_ion_laws = (show_log == "Yes" ? 1 : -1)
+
+ var/datum/round_event/ion_storm/add_law_only/ion = new()
+ ion.announceEvent = announce_ion_laws
+ ion.ionMessage = input
+
+ SSblackbox.add_details("admin_verb","Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Rejuvenate"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ if(!mob)
+ return
+ if(!istype(M))
+ alert("Cannot revive a ghost")
+ return
+ M.revive(full_heal = 1, admin_revive = 1)
+
+ log_admin("[key_name(usr)] healed / revived [key_name(M)]")
+ var/msg = "Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!"
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_verb","Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_create_centcom_report()
+ set category = "Special Verbs"
+ set name = "Create Command Report"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
+ if(!input)
+ return
+
+ var/confirm = alert(src, "Do you want to announce the contents of the report to the crew?", "Announce", "Yes", "No", "Cancel")
+ var/announce_command_report = TRUE
+ switch(confirm)
+ if("Yes")
+ priority_announce(input, null, 'sound/ai/commandreport.ogg')
+ announce_command_report = FALSE
+ if("Cancel")
+ return
+
+ print_command_report(input, "[announce_command_report ? "Classified " : ""][command_name()] Update", announce_command_report)
+
+ log_admin("[key_name(src)] has created a command report: [input]")
+ message_admins("[key_name_admin(src)] has created a command report")
+ SSblackbox.add_details("admin_verb","Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_change_command_name()
+ set category = "Special Verbs"
+ set name = "Change Command Name"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null
+ if(!input)
+ return
+ change_command_name(input)
+ message_admins("[key_name_admin(src)] has changed Central Command's name to [input]")
+ log_admin("[key_name(src)] has changed the Central Command name to: [input]")
+
+/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world)
+ set category = "Admin"
+ set name = "Delete"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ admin_delete(A)
+
+/client/proc/admin_delete(datum/D)
+ var/atom/A = D
+ var/coords = istype(A) ? " at ([A.x], [A.y], [A.z])" : ""
+ if (alert(src, "Are you sure you want to delete:\n[D]\nat[coords]?", "Confirmation", "Yes", "No") == "Yes")
+ log_admin("[key_name(usr)] deleted [D][coords]")
+ message_admins("[key_name_admin(usr)] deleted [D][coords]")
+ SSblackbox.add_details("admin_verb","Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ if(isturf(D))
+ var/turf/T = D
+ T.ChangeTurf(T.baseturf)
+ else
+ qdel(D)
+
+/client/proc/cmd_admin_list_open_jobs()
+ set category = "Admin"
+ set name = "Manage Job Slots"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ holder.manage_free_slots()
+ SSblackbox.add_details("admin_verb","Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
+ set category = "Special Verbs"
+ set name = "Explosion"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
+ if(devastation == null) return
+ var/heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null
+ if(heavy == null) return
+ var/light = input("Range of light impact. -1 to none", text("Input")) as num|null
+ if(light == null) return
+ var/flash = input("Range of flash. -1 to none", text("Input")) as num|null
+ if(flash == null) return
+ var/flames = input("Range of flames. -1 to none", text("Input")) as num|null
+ if(flames == null) return
+
+ if ((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1) || (flames != -1))
+ if ((devastation > 20) || (heavy > 20) || (light > 20) || (flames > 20))
+ if (alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No")
+ return
+
+ explosion(O, devastation, heavy, light, flash, null, null,flames)
+ log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
+ message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
+ SSblackbox.add_details("admin_verb","Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return
+ else
+ return
+
+/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
+ set category = "Special Verbs"
+ set name = "EM Pulse"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
+ if(heavy == null) return
+ var/light = input("Range of light pulse.", text("Input")) as num|null
+ if(light == null) return
+
+ if (heavy || light)
+
+ empulse(O, heavy, light)
+ log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
+ message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
+ SSblackbox.add_details("admin_verb","EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+ return
+ else
+ return
+
+/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Gib"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/confirm = alert(src, "Drop a brain?", "Confirm", "Yes", "No","Cancel")
+ if(confirm == "Cancel")
+ return
+ //Due to the delay here its easy for something to have happened to the mob
+ if(!M)
+ return
+
+ log_admin("[key_name(usr)] has gibbed [key_name(M)]")
+ message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]")
+
+ if(isobserver(M))
+ new /obj/effect/gibspawner/generic(get_turf(M))
+ return
+ if(confirm == "Yes")
+ M.gib()
+ else
+ M.gib(1)
+ SSblackbox.add_details("admin_verb","Gib") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_gib_self()
+ set name = "Gibself"
+ set category = "Fun"
+
+ var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
+ if(confirm == "Yes")
+ log_admin("[key_name(usr)] used gibself.")
+ message_admins("[key_name_admin(usr)] used gibself.")
+ SSblackbox.add_details("admin_verb","Gib Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ mob.gib(1, 1, 1)
+
+/client/proc/cmd_admin_check_contents(mob/living/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Check Contents"
+
+ var/list/L = M.get_contents()
+ for(var/t in L)
+ to_chat(usr, "[t]")
+ SSblackbox.add_details("admin_verb","Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/toggle_view_range()
+ set category = "Special Verbs"
+ set name = "Change View Range"
+ set desc = "switches between 1x and custom views"
+
+ if(view == world.view)
+ change_view(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128))
+ else
+ change_view(world.view)
+
+ log_admin("[key_name(usr)] changed their view range to [view].")
+ //message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI
+
+ SSblackbox.add_details("admin_toggle","Change View Range|[view]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/admin_call_shuttle()
+
+ set category = "Admin"
+ set name = "Call Shuttle"
+
+ if(EMERGENCY_AT_LEAST_DOCKED)
+ return
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ SSshuttle.emergency.request()
+ SSblackbox.add_details("admin_verb","Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ log_admin("[key_name(usr)] admin-called the emergency shuttle.")
+ message_admins("[key_name_admin(usr)] admin-called the emergency shuttle.")
+ return
+
+/client/proc/admin_cancel_shuttle()
+ set category = "Admin"
+ set name = "Cancel Shuttle"
+ if(!check_rights(0))
+ return
+ if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes")
+ return
+
+ if(EMERGENCY_AT_LEAST_DOCKED)
+ return
+
+ SSshuttle.emergency.cancel()
+ SSblackbox.add_details("admin_verb","Cancel Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ log_admin("[key_name(usr)] admin-recalled the emergency shuttle.")
+ message_admins("[key_name_admin(usr)] admin-recalled the emergency shuttle.")
+
+ return
+
+/client/proc/everyone_random()
+ set category = "Fun"
+ set name = "Make Everyone Random"
+ set desc = "Make everyone have a random appearance. You can only use this before rounds!"
+
+ if(SSticker.HasRoundStarted())
+ to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!")
+ return
+
+ var/frn = CONFIG_GET(flag/force_random_names)
+ if(frn)
+ CONFIG_SET(flag/force_random_names, FALSE)
+ message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.")
+ to_chat(usr, "Disabled.")
+ return
+
+
+ var/notifyplayers = alert(src, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel")
+ if(notifyplayers == "Cancel")
+ return
+
+ log_admin("Admin [key_name(src)] has forced the players to have random appearances.")
+ message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.")
+
+ if(notifyplayers == "Yes")
+ to_chat(world, "Admin [usr.key] has forced the players to have completely random identities!")
+
+ to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.")
+
+ CONFIG_SET(flag/force_random_names, TRUE)
+ SSblackbox.add_details("admin_verb","Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/client/proc/toggle_random_events()
+ set category = "Server"
+ set name = "Toggle random events on/off"
+ set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off"
+ var/new_are = !CONFIG_GET(flag/allow_random_events)
+ CONFIG_SET(flag/allow_random_events, new_are)
+ if(new_are)
+ to_chat(usr, "Random events enabled")
+ message_admins("Admin [key_name_admin(usr)] has enabled random events.")
+ else
+ to_chat(usr, "Random events disabled")
+ message_admins("Admin [key_name_admin(usr)] has disabled random events.")
+ SSblackbox.add_details("admin_toggle","Toggle Random Events|[new_are]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/client/proc/admin_change_sec_level()
+ set category = "Special Verbs"
+ set name = "Set Security Level"
+ set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/level = input("Select security level to change to","Set Security Level") as null|anything in list("green","blue","red","delta")
+ if(level)
+ set_security_level(level)
+
+ log_admin("[key_name(usr)] changed the security level to [level]")
+ message_admins("[key_name_admin(usr)] changed the security level to [level]")
+ SSblackbox.add_details("admin_verb","Set Security Level [capitalize(level)]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list)
+ set name = "Toggle Nuke"
+ set category = "Fun"
+ set popup_menu = 0
+ if(!check_rights(R_DEBUG))
+ return
+
+ if(!N.timing)
+ var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num
+ if(!newtime)
+ return
+ N.timer_set = newtime
+ N.set_safety()
+ N.set_active()
+
+ log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).")
+ message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_COORDJMP(N)].")
+ SSblackbox.add_details("admin_toggle","Toggle Nuke|[N.timing]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
+
+/client/proc/create_outfits()
+ set category = "Debug"
+ set name = "Create Custom Outfit"
+
+ if(!check_rights(R_DEBUG))
+ return
+
+ holder.create_outfit()
+
+/datum/admins/proc/create_outfit()
+ var/list/uniforms = typesof(/obj/item/clothing/under)
+ var/list/suits = typesof(/obj/item/clothing/suit)
+ var/list/gloves = typesof(/obj/item/clothing/gloves)
+ var/list/shoes = typesof(/obj/item/clothing/shoes)
+ var/list/headwear = typesof(/obj/item/clothing/head)
+ var/list/glasses = typesof(/obj/item/clothing/glasses)
+ var/list/masks = typesof(/obj/item/clothing/mask)
+ var/list/ids = typesof(/obj/item/card/id)
+
+ var/uniform_select = ""
+
+ var/suit_select = ""
+
+ var/gloves_select = ""
+
+ var/shoes_select = ""
+
+ var/head_select = ""
+
+ var/glasses_select = ""
+
+ var/mask_select = ""
+
+ var/id_select = ""
+
+ var/dat = {"
+ Create Outfit
+
+ "}
+ usr << browse(dat, "window=dressup;size=550x600")
+
+/client/proc/toggle_antag_hud()
+ set category = "Admin"
+ set name = "Toggle AntagHUD"
+ set desc = "Toggles the Admin AntagHUD"
+
+ if(!holder) return
+
+ var/adding_hud = !has_antag_hud()
+
+ for(var/datum/atom_hud/H in GLOB.huds)
+ if(istype(H, /datum/atom_hud/antag))
+ (adding_hud) ? H.add_hud_to(usr) : H.remove_hud_from(usr)
+
+ to_chat(usr, "You toggled your admin antag HUD [adding_hud ? "ON" : "OFF"].")
+ message_admins("[key_name_admin(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].")
+ log_admin("[key_name(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].")
+ SSblackbox.add_details("admin_toggle","Toggle Antag HUD|[adding_hud]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/has_antag_hud()
+ var/datum/atom_hud/A = GLOB.huds[ANTAG_HUD_TRAITOR]
+ return A.hudusers[mob]
+
+/client/proc/open_shuttle_manipulator()
+ set category = "Admin"
+ set name = "Shuttle Manipulator"
+ set desc = "Opens the shuttle manipulator UI."
+
+ for(var/obj/machinery/shuttle_manipulator/M in GLOB.machines)
+ M.ui_interact(usr)
+
+/client/proc/mass_zombie_infection()
+ set category = "Fun"
+ set name = "Mass Zombie Infection"
+ set desc = "Infects all humans with a latent organ that will zombify \
+ them on death."
+
+ if(!holder)
+ return
+
+ var/confirm = alert(src, "Please confirm you want to add latent zombie organs in all humans?", "Confirm Zombies", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ for(var/mob/living/carbon/human/H in GLOB.mob_list)
+ new /obj/item/organ/zombie_infection(H)
+
+ message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.")
+ log_admin("[key_name(usr)] added a latent zombie infection to all humans.")
+ SSblackbox.add_details("admin_verb","Mass Zombie Infection")
+
+/client/proc/mass_zombie_cure()
+ set category = "Fun"
+ set name = "Mass Zombie Cure"
+ set desc = "Removes the zombie infection from all humans, returning them to normal."
+ if(!holder)
+ return
+
+ var/confirm = alert(src, "Please confirm you want to cure all zombies?", "Confirm Zombie Cure", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ for(var/obj/item/organ/zombie_infection/I in GLOB.zombie_infection_list)
+ qdel(I)
+
+ message_admins("[key_name_admin(usr)] cured all zombies.")
+ log_admin("[key_name(usr)] cured all zombies.")
+ SSblackbox.add_details("admin_verb","Mass Zombie Cure")
+
+/client/proc/polymorph_all()
+ set category = "Fun"
+ set name = "Polymorph All"
+ set desc = "Applies the effects of the bolt of change to every single mob."
+
+ if(!holder)
+ return
+
+ var/confirm = alert(src, "Please confirm you want polymorph all mobs?", "Confirm Polymorph", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ var/list/mobs = shuffle(GLOB.living_mob_list.Copy()) // might change while iterating
+ var/who_did_it = key_name_admin(usr)
+
+ message_admins("[key_name_admin(usr)] started polymorphed all living mobs.")
+ log_admin("[key_name(usr)] polymorphed all living mobs.")
+ SSblackbox.add_details("admin_verb","Polymorph All")
+
+ for(var/mob/living/M in mobs)
+ CHECK_TICK
+
+ if(!M)
+ continue
+
+ M.audible_message("...wabbajack...wabbajack...")
+ playsound(M.loc, 'sound/magic/staff_change.ogg', 50, 1, -1)
+
+ wabbajack(M)
+
+ message_admins("Mass polymorph started by [who_did_it] is complete.")
+
+
+/client/proc/show_tip()
+ set category = "Admin"
+ set name = "Show Tip"
+ set desc = "Sends a tip (that you specify) to all players. After all \
+ you're the experienced player here."
+
+ if(!holder)
+ return
+
+ var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null
+ if(!input)
+ return
+
+ if(!SSticker)
+ return
+
+ SSticker.selected_tip = input
+
+ // If we've already tipped, then send it straight away.
+ if(SSticker.tipped)
+ SSticker.send_tip_of_the_round()
+
+
+ message_admins("[key_name_admin(usr)] sent a tip of the round.")
+ log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.")
+ SSblackbox.add_details("admin_verb","Show Tip")
+
+#define ON_PURRBATION(H) (!(H.dna.features["tail_human"] == "None" && H.dna.features["ears"] == "None"))
+
+/proc/mass_purrbation()
+ for(var/M in GLOB.mob_list)
+ if(ishumanbasic(M))
+ purrbation_apply(M)
+ CHECK_TICK
+
+/proc/mass_remove_purrbation()
+ for(var/M in GLOB.mob_list)
+ if(ishumanbasic(M))
+ purrbation_remove(M)
+ CHECK_TICK
+
+/proc/purrbation_toggle(mob/living/carbon/human/H)
+ if(!ishumanbasic(H))
+ return
+ if(!ON_PURRBATION(H))
+ purrbation_apply(H)
+ . = TRUE
+ else
+ purrbation_remove(H)
+ . = FALSE
+
+/proc/purrbation_apply(mob/living/carbon/human/H)
+ if(!ishuman(H))
+ return
+ if(ON_PURRBATION(H))
+ return
+ to_chat(H, "Something is nya~t right.")
+ H.dna.features["tail_human"] = "Cat"
+ H.dna.features["ears"] = "Cat"
+ H.regenerate_icons()
+ playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1)
+
+/proc/purrbation_remove(mob/living/carbon/human/H)
+ if(!ishuman(H))
+ return
+ if(!ON_PURRBATION(H))
+ return
+ to_chat(H, "You are no longer a cat.")
+ H.dna.features["tail_human"] = "None"
+ H.dna.features["ears"] = "None"
+ H.regenerate_icons()
+
+#undef ON_PURRBATION
+
+/client/proc/modify_goals()
+ set category = "Debug"
+ set name = "Modify goals"
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ holder.modify_goals()
+
+/datum/admins/proc/modify_goals()
+ var/dat = ""
+ for(var/datum/station_goal/S in SSticker.mode.station_goals)
+ dat += "[S.name] - Announce | Remove "
+ dat += " Add New Goal"
+ usr << browse(dat, "window=goals;size=400x400")
+
+
+/client/proc/toggle_hub()
+ set category = "Server"
+ set name = "Toggle Hub"
+
+ world.update_hub_visibility(!GLOB.hub_visibility)
+
+ log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.")
+ message_admins("[key_name_admin(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.")
+ if (GLOB.hub_visibility && !world.reachable)
+ message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.")
+
+ SSblackbox.add_details("admin_toggle","Toggled Hub Visibility|[GLOB.hub_visibility]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/smite(mob/living/carbon/human/target as mob)
+ set name = "Smite"
+ set category = "Fun"
+ if(!holder)
+ return
+
+ var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA)
+
+ var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
+
+ if(QDELETED(target) || !punishment)
+ return
+
+ switch(punishment)
+ if(ADMIN_PUNISHMENT_LIGHTNING)
+ var/turf/T = get_step(get_step(target, NORTH), NORTH)
+ T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5)
+ target.adjustFireLoss(75)
+ target.electrocution_animation(40)
+ to_chat(target, "The gods have punished you for your sins!")
+ if(ADMIN_PUNISHMENT_BRAINDAMAGE)
+ target.adjustBrainLoss(75)
+ if(ADMIN_PUNISHMENT_GIB)
+ target.gib(FALSE)
+ if(ADMIN_PUNISHMENT_BSA)
+ bluespace_artillery(target)
+
+ var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
+ message_admins(msg)
+ admin_ticket_log(target, msg)
+ log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].")
+
+
+/client/proc/trigger_centcom_recall()
+ if(!holder)
+ return
+ var/message = pick(GLOB.admiral_messages)
+ message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as text|null
+
+ if(!message)
+ return
+
+ message_admins("[key_name_admin(usr)] triggered a CentCom recall, with the admiral message of: [message]")
+ log_game("[key_name(usr)] triggered a CentCom recall, with the message of: [message]")
+ SSshuttle.centcom_recall(SSshuttle.emergency.timer, message)
+
+/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are.
+ set category = "Admin"
+ set name = "Player Playtime"
+ if(!check_rights(R_ADMIN))
+ return
+
+ var/list/msg = list()
+ msg += "Playtime ReportPlaytime:
"
+ src << browse(msg.Join(), "window=Player_playtime_check")
+
+/datum/admins/proc/cmd_show_exp_panel(client/C)
+ if(!check_rights(R_ADMIN))
+ return
+ if(!C)
+ to_chat(usr, "ERROR: Client not found.")
+ return
+
+ var/list/body = list()
+ body += "Playtime for [C.key] Playtime:"
+ body += C.get_exp_report()
+ body += "Toggle Exempt status"
+ body += ""
+ usr << browse(body.Join(), "window=playerplaytime[C.ckey];size=550x615")
+
+/datum/admins/proc/toggle_exempt_status(client/C)
+ if(!check_rights(R_ADMIN))
+ return
+ if(!C)
+ to_chat(usr, "ERROR: Client not found.")
+ return
+
+ if(!C.set_db_player_flags())
+ to_chat(usr, "ERROR: Unable read player flags from database. Please check logs.")
+ var/dbflags = C.prefs.db_flags
+ var/newstate = FALSE
+ if(dbflags & DB_FLAG_EXEMPT)
+ newstate = FALSE
+ else
+ newstate = TRUE
+
+ if(C.update_flag_db(DB_FLAG_EXEMPT, newstate))
+ to_chat(usr, "ERROR: Unable to update player flags. Please check logs.")
+ else
+ message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]")
+>>>>>>> 4178c20... Configuration datum refactor (#30763)
log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]")
\ No newline at end of file
diff --git a/code/modules/admin/verbs/reestablish_db_connection.dm b/code/modules/admin/verbs/reestablish_db_connection.dm
index 3578e98b1b..5c5edf6d17 100644
--- a/code/modules/admin/verbs/reestablish_db_connection.dm
+++ b/code/modules/admin/verbs/reestablish_db_connection.dm
@@ -1,7 +1,7 @@
/client/proc/reestablish_db_connection()
set category = "Special Verbs"
set name = "Reestablish DB Connection"
- if (!config.sql_enabled)
+ if (!CONFIG_GET(flag/sql_enabled))
to_chat(usr, "The Database is not enabled!")
return
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm
index 9a721bee62..12f99f3c50 100644
--- a/code/modules/awaymissions/gateway.dm
+++ b/code/modules/awaymissions/gateway.dm
@@ -80,7 +80,7 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
if(!GLOB.the_gateway)
GLOB.the_gateway = src
update_icon()
- wait = world.time + config.gateway_delay //+ thirty minutes default
+ wait = world.time + CONFIG_GET(number/gateway_delay) //+ thirty minutes default
awaygate = locate(/obj/machinery/gateway/centeraway)
/obj/machinery/gateway/centerstation/Destroy()
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 6fbc7d552f..60936aa5fb 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -42,7 +42,8 @@
to_chat(src, "An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)")
src << browse("...", "window=asset_cache_browser")
- if (!holder && config.minutetopiclimit)
+ var/mtl = CONFIG_GET(number/minute_topic_limit)
+ if (!holder && mtl)
var/minute = round(world.time, 600)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
@@ -50,17 +51,18 @@
topiclimiter[CURRENT_MINUTE] = minute
topiclimiter[MINUTE_COUNT] = 0
topiclimiter[MINUTE_COUNT] += 1
- if (topiclimiter[MINUTE_COUNT] > config.minutetopiclimit)
+ if (topiclimiter[MINUTE_COUNT] > mtl)
var/msg = "Your previous action was ignored because you've done too many in a minute."
if (minute != topiclimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them)
topiclimiter[ADMINSWARNED_AT] = minute
msg += " Administrators have been informed."
- log_game("[key_name(src)] Has hit the per-minute topic limit of [config.minutetopiclimit] topic calls in a given game minute")
- message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [config.minutetopiclimit] topic calls in a given game minute")
+ log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
+ message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
to_chat(src, "[msg]")
return
- if (!holder && config.secondtopiclimit)
+ var/stl = CONFIG_GET(number/second_topic_limit)
+ if (!holder && stl)
var/second = round(world.time, 10)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
@@ -68,7 +70,7 @@
topiclimiter[CURRENT_SECOND] = second
topiclimiter[SECOND_COUNT] = 0
topiclimiter[SECOND_COUNT] += 1
- if (topiclimiter[SECOND_COUNT] > config.secondtopiclimit)
+ if (topiclimiter[SECOND_COUNT] > stl)
to_chat(src, "Your previous action was ignored because you've done too many in a second")
return
@@ -110,7 +112,7 @@
return 1
/client/proc/handle_spam_prevention(message, mute_type)
- if(config.automute_on && !holder && src.last_message == message)
+ if(CONFIG_GET(flag/automute_on) && !holder && last_message == message)
src.last_message_count++
if(src.last_message_count >= SPAM_TRIGGER_AUTOMUTE)
to_chat(src, "You have exceeded the spam filter limit for identical messages. An auto-mute was applied.")
@@ -174,11 +176,11 @@ GLOBAL_LIST(external_rsc_urls)
if(localhost_rank)
var/datum/admins/localhost_holder = new(localhost_rank, ckey)
localhost_holder.associate(src)
- if(config.autoadmin)
+ if(CONFIG_GET(flag/autoadmin))
if(!GLOB.admin_datums[ckey])
var/datum/admin_rank/autorank
for(var/datum/admin_rank/R in GLOB.admin_ranks)
- if(R.name == config.autoadmin_rank)
+ if(R.name == CONFIG_GET(string/autoadmin_rank))
autorank = R
break
if(!autorank)
@@ -206,7 +208,7 @@ GLOBAL_LIST(external_rsc_urls)
log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[byond_version]")
var/alert_mob_dupe_login = FALSE
- if(config.log_access)
+ if(CONFIG_GET(flag/log_access))
for(var/I in GLOB.clients)
if(!I || I == src)
continue
@@ -240,30 +242,32 @@ GLOBAL_LIST(external_rsc_urls)
connection_realtime = world.realtime
connection_timeofday = world.timeofday
winset(src, null, "command=\".configure graphics-hwmode on\"")
- if (byond_version < config.client_error_version) //Out of date client.
+ var/cev = CONFIG_GET(number/client_error_version)
+ var/cwv = CONFIG_GET(number/client_warn_version)
+ if (byond_version < cev) //Out of date client.
to_chat(src, "Your version of byond is too old:")
- to_chat(src, config.client_error_message)
+ to_chat(src, CONFIG_GET(string/client_error_message))
to_chat(src, "Your version: [byond_version]")
- to_chat(src, "Required version: [config.client_error_version] or later")
+ to_chat(src, "Required version: [cev] or later")
to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.")
if (holder)
to_chat(src, "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade")
else
qdel(src)
return 0
- else if (byond_version < config.client_warn_version) //We have words for this client.
+ else if (byond_version < cwv) //We have words for this client.
to_chat(src, "Your version of byond may be getting out of date:")
- to_chat(src, config.client_warn_message)
+ to_chat(src, CONFIG_GET(string/client_warn_message))
to_chat(src, "Your version: [byond_version]")
- to_chat(src, "Required version to remove this message: [config.client_warn_version] or later")
+ to_chat(src, "Required version to remove this message: [cwv] or later")
to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.")
if (connection == "web" && !holder)
- if (!config.allowwebclient)
+ if (!CONFIG_GET(flag/allow_webclient))
to_chat(src, "Web client is disabled")
qdel(src)
return 0
- if (config.webclientmembersonly && !IsByondMember())
+ if (CONFIG_GET(flag/webclient_only_byond_members) && !IsByondMember())
to_chat(src, "Sorry, but the web client is restricted to byond members only.")
qdel(src)
return 0
@@ -276,25 +280,24 @@ GLOBAL_LIST(external_rsc_urls)
add_admin_verbs()
to_chat(src, get_message_output("memo"))
adminGreet()
- if((global.comms_key == "default_pwd" || length(global.comms_key) <= 6) && global.comms_allowed) //It's the default value or less than 6 characters long, but it somehow didn't disable comms.
- to_chat(src, "The server's API key is either too short or is the default value! Consider changing it immediately!")
add_verbs_from_config()
var/cached_player_age = set_client_age_from_db(tdata) //we have to cache this because other shit may change it and we need it's current value now down below.
if (isnum(cached_player_age) && cached_player_age == -1) //first connection
player_age = 0
+ var/nnpa = CONFIG_GET(number/notify_new_player_age)
if (isnum(cached_player_age) && cached_player_age == -1) //first connection
- if (config.notify_new_player_age >= 0)
+ if (nnpa >= 0)
message_admins("New user: [key_name_admin(src)] is connecting here for the first time.")
- if (config.irc_first_connection_alert)
+ if (CONFIG_GET(flag/irc_first_connection_alert))
send2irc_adminless_only("New-user", "[key_name(src)] is connecting for the first time!")
- else if (isnum(cached_player_age) && cached_player_age < config.notify_new_player_age)
+ else if (isnum(cached_player_age) && cached_player_age < nnpa)
message_admins("New user: [key_name_admin(src)] just connected with an age of [cached_player_age] day[(player_age==1?"":"s")]")
- if(config.use_account_age_for_jobs && account_age >= 0)
+ if(CONFIG_GET(flag/use_account_age_for_jobs) && account_age >= 0)
player_age = account_age
- if(account_age >= 0 && account_age < config.notify_new_player_account_age)
+ if(account_age >= 0 && account_age < nnpa)
message_admins("[key_name_admin(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].")
- if (config.irc_first_connection_alert)
+ if (CONFIG_GET(flag/irc_first_connection_alert))
send2irc_adminless_only("new_byond_user", "[key_name(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].")
get_message_output("watchlist entry", ckey)
check_ip_intel()
@@ -306,7 +309,7 @@ GLOBAL_LIST(external_rsc_urls)
if(prefs.lastchangelog != GLOB.changelog_hash) //bolds the changelog button on the interface so we know there are updates.
to_chat(src, "You have unread updates in the changelog.")
- if(config.aggressive_changelog)
+ if(CONFIG_GET(flag/aggressive_changelog))
changelog()
else
winset(src, "infowindow.changelog", "font-style=bold")
@@ -316,7 +319,7 @@ GLOBAL_LIST(external_rsc_urls)
to_chat(src, message)
GLOB.clientmessages.Remove(ckey)
- if(config && config.autoconvert_notes)
+ if(CONFIG_GET(flag/autoconvert_notes))
convert_notes_sql(ckey)
to_chat(src, get_message_output("message", ckey))
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
@@ -432,15 +435,17 @@ GLOBAL_LIST(external_rsc_urls)
if(!query_client_in_db.Execute())
return
if(!query_client_in_db.NextRow())
- if (config.panic_bunker && !holder && !(ckey in GLOB.deadmins))
+ if (CONFIG_GET(flag/panic_bunker) && !holder && !(ckey in GLOB.deadmins))
log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
message_admins("Failed Login: [key] - New account attempting to connect during panic bunker")
to_chat(src, "Sorry but the server is currently not accepting connections from never before seen players.")
var/list/connectiontopic_a = params2list(connectiontopic)
- if(config.panic_address && !connectiontopic_a["redirect"])
- to_chat(src, "Sending you to [config.panic_server_name ? config.panic_server_name : config.panic_address].")
+ var/list/panic_addr = CONFIG_GET(string/panic_address)
+ if(panic_addr && !connectiontopic_a["redirect"])
+ var/panic_name = CONFIG_GET(string/panic_server_name)
+ to_chat(src, "Sending you to [panic_name ? panic_name : panic_addr].")
winset(src, null, "command=.options")
- src << link("[config.panic_address]?redirect=1")
+ src << link("[panic_addr]?redirect=1")
qdel(src)
return
@@ -501,7 +506,7 @@ GLOBAL_LIST(external_rsc_urls)
if (connection != "seeker")
return
topic = params2list(topic)
- if (!config.check_randomizer)
+ if (!CONFIG_GET(flag/check_randomizer))
return
var/static/cidcheck = list()
var/static/tokens = list()
@@ -594,15 +599,15 @@ GLOBAL_LIST(external_rsc_urls)
/client/proc/check_ip_intel()
set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep
- if (config.ipintel_email)
+ if (CONFIG_GET(string/ipintel_email))
var/datum/ipintel/res = get_ip_intel(address)
- if (res.intel >= config.ipintel_rating_bad)
+ if (res.intel >= CONFIG_GET(number/ipintel_rating_bad))
message_admins("Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.")
ip_intel = res.intel
/client/proc/add_verbs_from_config()
- if(config.see_own_notes)
+ if(CONFIG_GET(flag/see_own_notes))
verbs += /client/proc/self_notes
@@ -612,7 +617,7 @@ GLOBAL_LIST(external_rsc_urls)
//checks if a client is afk
//3000 frames = 5 minutes
-/client/proc/is_afk(duration = config.inactivity_period)
+/client/proc/is_afk(duration = CONFIG_GET(number/inactivity_period))
if(inactivity > duration)
return inactivity
return FALSE
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 15b0bd95df..b576829240 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -274,8 +274,174 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "
"
dat += ""
+<<<<<<< HEAD
// dat += "Size:[character_size] "
dat += " "
+=======
+
+ dat += "
"
+
+ if(CONFIG_GET(flag/join_with_mutant_race)) //We don't allow mutant bodyparts for humans either unless this is true.
+
+ if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits))
+
+ dat += "