diff --git a/baystation12.dme b/baystation12.dme index 722e05dfe7e..0695839aea3 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -79,6 +79,7 @@ #include "code\controllers\autotransfer.dm" #include "code\controllers\configuration.dm" #include "code\controllers\failsafe.dm" +#include "code\controllers\hooks.dm" #include "code\controllers\lighting_controller.dm" #include "code\controllers\master_controller.dm" #include "code\controllers\shuttle_controller.dm" @@ -653,7 +654,6 @@ #include "code\modules\admin\holder2.dm" #include "code\modules\admin\IsBanned.dm" #include "code\modules\admin\NewBan.dm" -#include "code\modules\admin\newbanjob.dm" #include "code\modules\admin\player_notes.dm" #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\topic.dm" diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm index 3eccad7e913..9a829633e2b 100644 --- a/code/ZAS/FEA_gas_mixture.dm +++ b/code/ZAS/FEA_gas_mixture.dm @@ -14,6 +14,20 @@ What are the archived variables for? #define QUANTIZE(variable) (round(variable,0.0001)) #define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer +/hook/startup/proc/createGasOverlays() + plmaster = new /obj/effect/overlay() + plmaster.icon = 'icons/effects/tile_effects.dmi' + plmaster.icon_state = "plasma" + plmaster.layer = FLY_LAYER + plmaster.mouse_opacity = 0 + + slmaster = new /obj/effect/overlay() + slmaster.icon = 'icons/effects/tile_effects.dmi' + slmaster.icon_state = "sleeping_agent" + slmaster.layer = FLY_LAYER + slmaster.mouse_opacity = 0 + return 1 + /datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy. /datum/gas/oxygen_agent_b/specific_heat = 300 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index ce8d788f25f..07a22f56932 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -42,7 +42,7 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al /////Initial Building///// ////////////////////////// -/proc/make_datum_references_lists() +/hook/startup/proc/makeDatumRefLists() var/list/paths //Hair - Initialise all /datum/sprite_accessory/hair into an list indexed by hair-style name @@ -97,6 +97,8 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al if(S.flags & WHITELISTED) whitelisted_species += S.name + return 1 + /* // Uncomment to debug chemical reaction list. /client/verb/debug_chemical_list() diff --git a/code/controllers/hooks.dm b/code/controllers/hooks.dm new file mode 100644 index 00000000000..5045da75925 --- /dev/null +++ b/code/controllers/hooks.dm @@ -0,0 +1,39 @@ +/** + * @file hooks.dm + * Implements hooks, a simple way to run code on pre-defined events. + */ + +/** @page hooks Code hooks + * @section hooks Hooks + * A hook is defined under /hook in the type tree. + * + * To add some code to be called by the hook, define a proc under the type, as so: + * @code + /hook/foo/proc/bar() + if(1) + return 1 //Sucessful + else + return 0 //Error, or runtime. + * @endcode + * All hooks must return nonzero on success, as runtimes will force return null. + */ + +/** + * Calls a hook, executing every piece of code that's attached to it. + * @param hook Identifier of the hook to call. + * @returns 1 if all hooked code runs successfully, 0 otherwise. + */ +/proc/callHook(hook) + var/hook_path = text2path("/hook/[hook]") + if(!hook_path) + error("Invalid hook '/hook/[hook]' called.") + return 0 + + var/caller = new hook_path + var/status = 1 + for(var/P in typesof("[hook_path]/proc")) + if(!call(caller, P)()) + error("Hook '[P]' failed or runtimed.") + status = 0 + + return status diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 1a7d97e99cf..2be4c6e82a1 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -1,3 +1,6 @@ +/hook/startup/proc/createDatacore() + data_core = new /obj/effect/datacore() + return 1 /obj/effect/datacore/proc/manifest(var/nosleep = 0) spawn() diff --git a/code/datums/sun.dm b/code/datums/sun.dm index 9ce8a73cb72..82acfa0cff0 100644 --- a/code/datums/sun.dm +++ b/code/datums/sun.dm @@ -14,6 +14,10 @@ if(prob(50)) rate = -rate +/hook/startup/proc/createSun() + sun = new /datum/sun() + return 1 + // calculate the sun's position given the time of day /datum/sun/proc/calc_position() diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 9ba221c64d6..9ff5a6e0cd5 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -56,7 +56,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ var/list/teleportlocs = list() -proc/process_teleport_locs() +/hook/startup/proc/setupTeleportLocs() for(var/area/AR in world) if(istype(AR, /area/shuttle) || istype(AR, /area/syndicate_station) || istype(AR, /area/wizard_station)) continue if(teleportlocs.Find(AR.name)) continue @@ -65,20 +65,13 @@ proc/process_teleport_locs() teleportlocs += AR.name teleportlocs[AR.name] = AR - var/not_in_order = 0 - do - not_in_order = 0 - if(teleportlocs.len <= 1) - break - for(var/i = 1, i <= (teleportlocs.len - 1), i++) - if(sorttext(teleportlocs[i], teleportlocs[i+1]) == -1) - teleportlocs.Swap(i, i+1) - not_in_order = 1 - while(not_in_order) + teleportlocs = sortAssoc(teleportlocs) + + return 1 var/list/ghostteleportlocs = list() -proc/process_ghost_teleport_locs() +/hook/startup/proc/setupGhostTeleportLocs() for(var/area/AR in world) if(ghostteleportlocs.Find(AR.name)) continue if(istype(AR, /area/turret_protected/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome)) @@ -89,17 +82,9 @@ proc/process_ghost_teleport_locs() ghostteleportlocs += AR.name ghostteleportlocs[AR.name] = AR - var/not_in_order = 0 - do - not_in_order = 0 - if(ghostteleportlocs.len <= 1) - break - for(var/i = 1, i <= (ghostteleportlocs.len - 1), i++) - if(sorttext(ghostteleportlocs[i], ghostteleportlocs[i+1]) == -1) - ghostteleportlocs.Swap(i, i+1) - not_in_order = 1 - while(not_in_order) + ghostteleportlocs = sortAssoc(ghostteleportlocs) + return 1 /*-----------------------------------------------------------------------------*/ diff --git a/code/game/communications.dm b/code/game/communications.dm index 32d8ca69348..3bc3ee70092 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -140,6 +140,10 @@ var/const/RADIO_MAGNETS = "9" var/global/datum/controller/radio/radio_controller +/hook/startup/proc/createRadioController() + radio_controller = new /datum/controller/radio() + return 1 + datum/controller/radio var/list/datum/radio_frequency/frequencies = list() diff --git a/code/game/gamemodes/events/holidays/Holidays.dm b/code/game/gamemodes/events/holidays/Holidays.dm index d2481eae441..2cd06199bd8 100644 --- a/code/game/gamemodes/events/holidays/Holidays.dm +++ b/code/game/gamemodes/events/holidays/Holidays.dm @@ -12,6 +12,10 @@ var/global/Holiday = null ////////////////////////////////////////////////////////////////////////////////////////////////////////// // ~Carn +/hook/startup/proc/updateHoliday() + Get_Holiday() + return 1 + //sets up the Holiday global variable. Shouldbe called on game configuration or something. /proc/Get_Holiday() if(!Holiday) return // Holiday stuff was not enabled in the config! diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index ea9fbaec4a7..a834a3cc0b3 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -118,6 +118,7 @@ var/global/datum/controller/gameticker/ticker data_core.manifest() current_state = GAME_STATE_PLAYING + callHook("roundstart") //here to initialize the random events nicely at round start setup_economy() @@ -309,6 +310,8 @@ var/global/datum/controller/gameticker/ticker declare_completion() spawn(50) + callHook("roundend") + if (mode.station_was_nuked) feedback_set_details("end_proper","nuke") if(!delay_end) diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm index f28de56dc41..98efaf92733 100644 --- a/code/game/jobs/whitelist.dm +++ b/code/game/jobs/whitelist.dm @@ -2,6 +2,11 @@ var/list/whitelist = list() +/hook/startup/proc/loadWhitelist() + if(config.usewhitelist) + load_whitelist() + return 1 + /proc/load_whitelist() whitelist = file2list(WHITELISTFILE) if(!whitelist.len) whitelist = null @@ -11,9 +16,14 @@ var/list/whitelist = list() return 0 return ("[M.ckey]" in whitelist) -var/list/alien_whitelist = list() +/var/list/alien_whitelist = list() -proc/load_alienwhitelist() +/hook/startup/proc/loadAlienWhitelist() + if(config.usealienwhitelist) + load_alienwhitelist() + return 1 + +/proc/load_alienwhitelist() var/text = file2text("config/alienwhitelist.txt") if (!text) diary << "Failed to load config/alienwhitelist.txt\n" diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 477fd67cab0..9826505fd02 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -35,7 +35,7 @@ var/global/list/autolathe_recipes = list( \ new /obj/item/weapon/reagent_containers/syringe(), \ new /obj/item/ammo_casing/shotgun/blank(), \ new /obj/item/ammo_casing/shotgun/beanbag(), \ - new /obj/item/ammo_magazine/c38(), \ + new /obj/item/ammo_magazine/c45r(), \ new /obj/item/device/taperecorder(), \ new /obj/item/device/assembly/igniter(), \ new /obj/item/device/assembly/signaler(), \ @@ -57,6 +57,7 @@ var/global/list/autolathe_recipes_hidden = list( \ new /obj/item/weapon/weldingtool/largetank(), \ new /obj/item/weapon/handcuffs(), \ new /obj/item/ammo_magazine/a357(), \ + new /obj/item/ammo_magazine/c45(), \ new /obj/item/ammo_casing/shotgun(), \ new /obj/item/ammo_casing/shotgun/dart(), \ /* new /obj/item/weapon/shield/riot(), */ \ diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 011f19f198a..e44847f137b 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -247,20 +247,24 @@ ..() sleep(2) new /obj/item/clothing/under/det(src) + new /obj/item/clothing/under/det/black(src) + new /obj/item/clothing/under/det/slob(src) new /obj/item/clothing/suit/storage/det_suit(src) + new /obj/item/clothing/suit/storage/det_suit/black(src) new /obj/item/clothing/suit/storage/forensics/blue(src) new /obj/item/clothing/suit/storage/forensics/red(src) new /obj/item/clothing/gloves/black(src) new /obj/item/clothing/head/det_hat(src) + new /obj/item/clothing/head/det_hat/black(src) new /obj/item/clothing/shoes/brown(src) new /obj/item/weapon/storage/box/evidence(src) new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/device/detective_scanner(src) new /obj/item/clothing/suit/armor/det_suit(src) - new /obj/item/ammo_magazine/c38(src) - new /obj/item/ammo_magazine/c38(src) + new /obj/item/ammo_magazine/c45r(src) + new /obj/item/ammo_magazine/c45r(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/gun/projectile/detective(src) + new /obj/item/weapon/gun/projectile/detective/semiauto(src) new /obj/item/clothing/tie/holster/armpit(src) return diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm index 83447d1a239..035b2d23096 100644 --- a/code/modules/admin/NewBan.dm +++ b/code/modules/admin/NewBan.dm @@ -58,6 +58,9 @@ var/savefile/Banlist CMinutes = (world.realtime / 10) / 60 return 1 +/hook/startup/proc/loadBans() + return LoadBans() + /proc/LoadBans() Banlist = new("data/banlist.bdb") diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index e2bf6f7be2e..c6dcc662a6f 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1014,14 +1014,6 @@ var/global/floorIsLava = 0 message_admins("\blue [key_name_admin(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.", 1) feedback_add_details("admin_verb","TGU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/unjobban_panel() - set name = "Unjobban Panel" - set category = "Admin" - if (src.holder) - src.holder.unjobbanpanel() - feedback_add_details("admin_verb","UJBP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - /datum/admins/proc/output_ai_laws() var/ai_number = 0 for(var/mob/living/silicon/S in mob_list) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index e601f069c68..a0627884385 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -11,6 +11,10 @@ /proc/investigate_subject2file(var/subject) return file("[INVESTIGATE_DIR][subject].html") +/hook/startup/proc/resetInvestigate() + investigate_reset() + return 1 + /proc/investigate_reset() if(fdel(INVESTIGATE_DIR)) return 1 return 0 diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 115fafba82d..86624e0bd2e 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -53,6 +53,10 @@ var/list/admin_ranks = list() //list of all ranks with associated rights #endif +/hook/startup/proc/loadAdmins() + load_admins() + return 1 + /proc/load_admins() //clear the datums references admin_datums.Cut() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 1158633bf80..1196f14ebd8 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -76,9 +76,7 @@ var/list/admin_verbs_admin = list( ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, - /client/proc/jobbans, - /client/proc/unjobban_panel, - // /client/proc/DB_ban_panel + /client/proc/jobbans ) var/list/admin_verbs_sounds = list( /client/proc/play_local_sound, diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm index b6d1ea53b65..42326711d35 100644 --- a/code/modules/admin/banjob.dm +++ b/code/modules/admin/banjob.dm @@ -50,6 +50,10 @@ DEBUG jobban_loadbanfile() */ +/hook/startup/proc/loadJobBans() + jobban_loadbanfile() + return 1 + /proc/jobban_loadbanfile() if(config.ban_legacy_system) var/savefile/S=new("data/job_full.ban") @@ -101,15 +105,6 @@ DEBUG text2file(formatted_log,"data/ban_unban_log.txt") -/proc/jobban_updatelegacybans() - if(!jobban_runonce) - log_admin("Updating jobbanfile!") - // Updates bans.. Or fixes them. Either way. - for(var/T in jobban_keylist) - if(!T) continue - jobban_runonce++ //don't run this update again - - /proc/jobban_remove(X) for (var/i = 1; i <= length(jobban_keylist); i++) if( findtext(jobban_keylist[i], "[X]") ) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 66de256c9e4..cacf616392a 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -891,19 +891,6 @@ if("Cancel") return - else if(href_list["unjobbanf"]) - if(!check_rights(R_BAN)) return - - var/banfolder = href_list["unjobbanf"] - Banlist.cd = "/base/[banfolder]" - var/key = Banlist["key"] - if(alert(usr, "Are you sure you want to unban [key]?", "Confirmation", "Yes", "No") == "Yes") - if (RemoveBanjob(banfolder)) - unjobbanpanel() - else - alert(usr,"This ban has already been lifted / does not exist.","Error","Ok") - unjobbanpanel() - else if(href_list["mute"]) if(!check_rights(R_MOD,0) && !check_rights(R_ADMIN)) return diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index fd525eacdb5..f3c960cc3d0 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -77,6 +77,9 @@ allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) armor = list(melee = 50, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) +/obj/item/clothing/suit/storage/det_suit/black + icon_state = "detective2" + //Forensics /obj/item/clothing/suit/storage/forensics name = "jacket" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index b279a2fd35f..c35910d060c 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -71,6 +71,22 @@ flags = FPRINT | TABLEPASS siemens_coefficient = 0.9 +/obj/item/clothing/under/det/black + icon_state = "detective2" + item_color = "detective2" + +/obj/item/clothing/under/det/slob + icon_state = "polsuit" + item_color = "polsuit" + +/obj/item/clothing/under/det/slob/verb/rollup() + set name = "Roll suit sleevels" + set category = "Object" + set src in usr + item_color = item_color == "polsuit" ? "polsuit_rolled" : "polsuit" + if (ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_w_uniform(1) /obj/item/clothing/head/det_hat name = "hat" @@ -80,6 +96,10 @@ armor = list(melee = 50, bullet = 5, laser = 25,energy = 10, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0.9 +/obj/item/clothing/head/det_hat/black + icon_state = "detective2" + + /* * Head of Security */ diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 05bb2a30dd1..3644b7ae69f 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -494,12 +494,6 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "chal_appara_1" -/obj/item/clothing/gloves/fluff/ashley_rifler_1 //Vinceluk: Ashley Rifler - name = "Purple Glove" - desc = "A single, purple glove. Initials A.R. are written on the inside of it." - icon = 'icons/obj/custom_items.dmi' - icon_state = "ashley_rifler_1" - //////////// Eye Wear //////////// /obj/item/clothing/glasses/meson/fluff/book_berner_1 //asanadas: Book Berner @@ -591,14 +585,6 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "labcoat_pink_open" -/obj/item/clothing/suit/storage/det_suit/fluff/graycoat //vinceluk: Seth Sealis - name = "gray coat" - desc = "Old, worn out coat. It's seen better days." - icon = 'icons/obj/custom_items.dmi' - icon_state = "graycoat" - item_state = "graycoat" - item_color = "graycoat" - /obj/item/clothing/suit/storage/det_suit/fluff/leatherjack //atomicdog92: Seth Sealis name = "leather jacket" desc = "A black leather coat, popular amongst punks, greasers, and other galactic scum." @@ -949,3 +935,26 @@ name = "[labeled] bottle" desc = "A small bottle. Contains [labeled]" icon_state = "bottle[color]" + +/obj/item/weapon/reagent_containers/food/drinks/flask/fluff/yuri_kornienkovich_flask + name = "Yuri's Flask" + desc = "An old gold plated flask. Nothing noteworthy about it besides it being gold and the red star on the worn out leather around it. There is also an engraving on the cap that is rather hard to see but it looks like \"Kornienkovich\" " + icon = 'icons/obj/custom_items.dmi' + icon_state = "yuri_kornienkovich_flask" + +/obj/item/clothing/under/fluff/mai_yang_dress // Mai Yang's pretty pretty dress. + name = "White Cheongsam" + desc = "It is a white cheongsam dress." + icon = 'icons/obj/custom_items.dmi' + icon_state = "mai_yang" + item_state = "mai_yang" + item_color = "mai_yang" + +/obj/item/clothing/under/fluff/sakura_hokkaido_kimono + name = "Sakura Kimono" + desc = "A pale-pink, nearly white, kimono with a red and gold obi. There is a embroidered design of cherry blossom flowers covering the kimono." + icon = 'icons/obj/custom_items.dmi' + icon_state = "sakura_hokkaido_kimono" + item_state = "sakura_hokkaido_kimono" + item_color = "sakura_hokkaido_kimono" + diff --git a/code/modules/ext_scripts/irc.dm b/code/modules/ext_scripts/irc.dm index f4e94f3ffc4..3976904efb6 100644 --- a/code/modules/ext_scripts/irc.dm +++ b/code/modules/ext_scripts/irc.dm @@ -4,11 +4,16 @@ return /proc/send2mainirc(var/msg) - if(config.use_irc_bot && config.main_irc && config.irc_bot_host) - ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [config.main_irc] [msg]") + if(config.main_irc) + send2irc(config.main_irc, msg) return /proc/send2adminirc(var/msg) - if(config.use_irc_bot && config.admin_irc && config.irc_bot_host) - ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [config.admin_irc] [msg]") + if(config.admin_irc) + send2irc(config.admin_irc, msg) return + + +/hook/startup/proc/ircNotify() + send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]") + return 1 diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index ec4ccf50f5e..a297cb61830 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -1142,4 +1142,19 @@ I said no! /datum/recipe/cracker reagents = list("flour" = 5, "sodiumchloride" = 1) - result = /obj/item/weapon/reagent_containers/food/snacks/cracker \ No newline at end of file + result = /obj/item/weapon/reagent_containers/food/snacks/cracker + +/datum/recipe/stuffing + reagents = list("water" = 5, "sodiumchloride" = 1, "blackpepper" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/stuffing + +/datum/recipe/tofurkey + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/stuffing, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tofurkey diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index 270e2ba7637..399a94c0393 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -13,6 +13,10 @@ var/datum/paiController/paiController // Global handler for pAI candidates var/ready = 0 +/hook/startup/proc/paiControllerSetup() + paiController = new /datum/paiController() + return 1 + /datum/paiController var/list/pai_candidates = list() diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index b94901a6373..986f81d6c84 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -79,6 +79,9 @@ // rebuild all power networks from scratch +/hook/startup/proc/buildPowernets() + return makepowernets() + /proc/makepowernets() for(var/datum/powernet/PN in powernets) del(PN) @@ -101,6 +104,8 @@ if(!M.powernet) continue // APCs have powernet=0 so they don't count as network nodes directly M.powernet.nodes[M] = M + return 1 + // returns a list of all power-related objects (nodes, cable, junctions) in turf, // excluding source, that match the direction d diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index fa7567bcb28..87fa97ef697 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -14,6 +14,25 @@ multiple_sprites = 1 +/obj/item/ammo_magazine/c45 + name = "magazine (.45)" + icon_state = "45" + ammo_type = "/obj/item/ammo_casing/c45" + max_ammo = 7 + multiple_sprites = 1 + +/obj/item/ammo_magazine/c45/empty + max_ammo = 0 + +/obj/item/ammo_magazine/c45r + name = "magazine (.45 rubber)" + icon_state = "45" + ammo_type = "/obj/item/ammo_casing/c45r" + max_ammo = 7 + multiple_sprites = 1 + +/obj/item/ammo_magazine/c45r/empty + max_ammo = 0 /obj/item/ammo_magazine/a418 name = "ammo box (.418)" diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm index 41443469d38..a2b11b7ffc0 100644 --- a/code/modules/projectiles/ammunition/bullets.dm +++ b/code/modules/projectiles/ammunition/bullets.dm @@ -43,6 +43,10 @@ caliber = ".45" projectile_type = "/obj/item/projectile/bullet/midbullet" +/obj/item/ammo_casing/c45r + desc = "A .45 rubber bullet casing." + caliber = ".45" + projectile_type = "/obj/item/projectile/bullet/weakbullet" /obj/item/ammo_casing/a12mm desc = "A 12mm bullet casing." diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 0f6fca68b2b..b6a305cbf73 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -70,6 +70,26 @@ user << "You remove the modifications on [src]! Now it will fire .38 rounds." +/obj/item/weapon/gun/projectile/detective/semiauto + desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds." + name = "\improper Colt M1911" + icon_state = "colt" + max_shells = 7 + caliber = ".45" + ammo_type = "/obj/item/ammo_casing/c45r" + load_method = 2 + +/obj/item/weapon/gun/projectile/detective/semiauto/New() + ..() + empty_mag = new /obj/item/ammo_magazine/c45r/empty(src) + return + +/obj/item/weapon/gun/projectile/detective/semiauto/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) + ..() + if(!loaded.len && empty_mag) + empty_mag.loc = get_turf(src.loc) + empty_mag = null + return /obj/item/weapon/gun/projectile/mateba diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 771d49a2da8..5d22bdf8a09 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -542,6 +542,24 @@ reagents.add_reagent("nutriment", 3) src.bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/tofurkey + name = "Tofurkey" + desc = "A fake turkey made from tofu." + icon_state = "tofurkey" + New() + ..() + reagents.add_reagent("nutriment", 12) + reagents.add_reagent("stoxin", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/stuffing + name = "Stuffing" + desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" + icon_state = "stuffing" + New() + ..() + reagents.add_reagent("nutriment", 3) + bitesize = 1 /obj/item/weapon/reagent_containers/food/snacks/carpmeat name = "carp fillet" diff --git a/code/world.dm b/code/world.dm index abc49976992..95453243430 100644 --- a/code/world.dm +++ b/code/world.dm @@ -7,7 +7,7 @@ -#define RECOMMENDED_VERSION 495 +#define RECOMMENDED_VERSION 501 /world/New() //logs var/date_string = time2text(world.realtime, "YYYY/MM-Month/DD-Day") @@ -22,59 +22,13 @@ if(byond_version < RECOMMENDED_VERSION) world.log << "Your server's byond version does not meet the recommended requirements for this server. Please update BYOND" - make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) - load_configuration() - load_mode() - load_motd() - load_admins() - load_mods() - LoadBansjob() - if(config.usewhitelist) - load_whitelist() - if(config.usealienwhitelist) - load_alienwhitelist() - jobban_loadbanfile() - jobban_updatelegacybans() - LoadBans() if(config && config.server_name != null && config.server_suffix && world.port > 0) // dumb and hardcoded but I don't care~ config.server_name += " #[(world.port % 1000) / 100]" - investigate_reset() - Get_Holiday() //~Carn, needs to be here when the station is named so :P - - src.update_status() - - makepowernets() - - sun = new /datum/sun() - radio_controller = new /datum/controller/radio() - data_core = new /obj/effect/datacore() - paiController = new /datum/paiController() - - if(!setup_database_connection()) - world.log << "Your server failed to establish a connection with the feedback database." - else - world.log << "Feedback database connection established." - - if(!setup_old_database_connection()) - world.log << "Your server failed to establish a connection with the SQL database." - else - world.log << "SQL database connection established." - - plmaster = new /obj/effect/overlay() - plmaster.icon = 'icons/effects/tile_effects.dmi' - plmaster.icon_state = "plasma" - plmaster.layer = FLY_LAYER - plmaster.mouse_opacity = 0 - - slmaster = new /obj/effect/overlay() - slmaster.icon = 'icons/effects/tile_effects.dmi' - slmaster.icon_state = "sleeping_agent" - slmaster.layer = FLY_LAYER - slmaster.mouse_opacity = 0 + callHook("startup") src.update_status() @@ -82,15 +36,10 @@ sleep_offline = 1 - send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]") - master_controller = new /datum/controller/game_controller() spawn(1) master_controller.setup() - process_teleport_locs() //Sets up the wizard teleport locations - process_ghost_teleport_locs() //Sets up ghost teleport locations. - spawn(3000) //so we aren't adding to the round-start lag if(config.ToRban) ToRban_autoupdate() @@ -184,6 +133,10 @@ #undef INACTIVITY_KICK +/hook/startup/proc/loadMode() + world.load_mode() + return 1 + /world/proc/load_mode() var/list/Lines = file2list("data/mode.txt") if(Lines.len) @@ -196,9 +149,15 @@ fdel(F) F << the_mode + +/hook/startup/proc/loadMOTD() + world.load_motd() + return 1 + /world/proc/load_motd() join_motd = file2text("config/motd.txt") + /world/proc/load_configuration() config = new /datum/configuration() config.load("config/config.txt") @@ -208,6 +167,11 @@ // apply some settings from config.. abandon_allowed = config.respawn + +/hook/startup/proc/loadMods() + world.load_mods() + return 1 + /world/proc/load_mods() if(config.admin_legacy_system) var/text = file2text("config/moderators.txt") @@ -290,6 +254,13 @@ var/failed_db_connections = 0 var/failed_old_db_connections = 0 +/hook/startup/proc/connectDB() + if(!setup_database_connection()) + world.log << "Your server failed to establish a connection with the feedback database." + else + world.log << "Feedback database connection established." + return 1 + proc/setup_database_connection() if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore. @@ -325,7 +296,12 @@ proc/establish_db_connection() return 1 - +/hook/startup/proc/connectOldDB() + if(!setup_old_database_connection()) + world.log << "Your server failed to establish a connection with the SQL database." + else + world.log << "SQL database connection established." + return 1 //These two procs are for the old database, while it's being phased out. See the tgstation.sql file in the SQL folder for more information. proc/setup_old_database_connection() diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 0396dd6ce08..97794bab718 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi index af2daeb4de6..b15d273426e 100644 Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi index 287fd36614e..c3c098b0a26 100644 Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index cafdb88f336..52ee7b48a62 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 90bf359dc30..a47622b6056 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 95f8db0ee1e..1796d4bf1b2 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 7ec3f3ee2a0..85dc31a6aac 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 6a72147f32c..5678e44ec70 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 769d8ac9a38..157a78e440f 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 5cc07c12b38..8d52a549b37 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index 9c31373db12..96f50c2df30 100644 Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index 2ad4316d4a0..8dd01d7d2c5 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ