diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..678486f019 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,11 @@ +# This list auto requests reviews from the specified org members +# when a PR that modifies the file in question is opened +# This list is alphabetized by User -> Filename KEEP IT THAT WAY +# In the event that multiple org members are to be informed of changes +# to the same file or dir, add them to the end under Multiple Owners + +# ShadowLarkens +/code/__DEFINES/tgui.dm @ShadowLarkens +/code/controllers/subsystem/tgui.dm @ShadowLarkens +/code/modules/tgui @ShadowLarkens +/tgui @ShadowLarkens \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm index fc25eae3b7..1a357327fb 100644 --- a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm +++ b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm @@ -103,7 +103,7 @@ if(ATM_P) return "phoron" if(ATM_N2O) - return "sleeping_agent" + return "nitrous_oxide" else return null \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 9e192afe1b..a787aa1873 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -24,7 +24,7 @@ 1: Oxygen: Oxygen ONLY 2: Nitrogen: Nitrogen ONLY 3: Carbon Dioxide: Carbon Dioxide ONLY - 4: Sleeping Agent (N2O) + 4: Nitrous Oxide (Formerly called Sleeping Agent) (N2O) */ var/filter_type = -1 var/list/filtered_out = list() @@ -51,7 +51,7 @@ if(3) //removing CO2 filtered_out = list("carbon_dioxide") if(4)//removing N2O - filtered_out = list("sleeping_agent") + filtered_out = list("nitrous_oxide") air1.volume = ATMOS_DEFAULT_VOLUME_FILTER air2.volume = ATMOS_DEFAULT_VOLUME_FILTER @@ -216,7 +216,7 @@ if(3) //removing CO2 filtered_out += "carbon_dioxide" if(4)//removing N2O - filtered_out += "sleeping_agent" + filtered_out += "nitrous_oxide" add_fingerprint(usr) update_icon() diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 2c51eecfc6..1443b296d0 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -107,7 +107,7 @@ "filter_n2" = ("nitrogen" in scrubbing_gas), "filter_co2" = ("carbon_dioxide" in scrubbing_gas), "filter_phoron" = ("phoron" in scrubbing_gas), - "filter_n2o" = ("sleeping_agent" in scrubbing_gas), + "filter_n2o" = ("nitrous_oxide" in scrubbing_gas), "filter_fuel" = ("volatile_fuel" in scrubbing_gas), "sigtype" = "status" ) @@ -230,10 +230,10 @@ else if(signal.data["toggle_tox_scrub"]) toggle += "phoron" - if(!isnull(signal.data["n2o_scrub"]) && text2num(signal.data["n2o_scrub"]) != ("sleeping_agent" in scrubbing_gas)) - toggle += "sleeping_agent" + if(!isnull(signal.data["n2o_scrub"]) && text2num(signal.data["n2o_scrub"]) != ("nitrous_oxide" in scrubbing_gas)) + toggle += "nitrous_oxide" else if(signal.data["toggle_n2o_scrub"]) - toggle += "sleeping_agent" + toggle += "nitrous_oxide" if(!isnull(signal.data["fuel_scrub"]) && text2num(signal.data["fuel_scrub"]) != ("volatile_fuel" in scrubbing_gas)) toggle += "volatile_fuel" diff --git a/code/ATMOSPHERICS/pipes/tank.dm b/code/ATMOSPHERICS/pipes/tank.dm index 8a68ba369c..54f90d9521 100644 --- a/code/ATMOSPHERICS/pipes/tank.dm +++ b/code/ATMOSPHERICS/pipes/tank.dm @@ -157,7 +157,7 @@ air_temporary.volume = volume air_temporary.temperature = T0C - air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + air_temporary.adjust_gas("nitrous_oxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) ..() icon_state = "n2o" diff --git a/code/__defines/exosuit_fab.dm b/code/__defines/exosuit_fab.dm new file mode 100644 index 0000000000..dce03c9301 --- /dev/null +++ b/code/__defines/exosuit_fab.dm @@ -0,0 +1,28 @@ +/// Module is compatible with Security Cyborg models +#define BORG_MODULE_SECURITY (1<<0) +/// Module is compatible with Miner Cyborg models +#define BORG_MODULE_MINER (1<<1) +/// Module is compatible with Janitor Cyborg models +#define BORG_MODULE_JANITOR (1<<2) +/// Module is compatible with Medical Cyborg models +#define BORG_MODULE_MEDICAL (1<<3) +/// Module is compatible with Engineering Cyborg models +#define BORG_MODULE_ENGINEERING (1<<4) + +/// Module is compatible with Ripley Exosuit models +#define EXOSUIT_MODULE_RIPLEY (1<<0) +/// Module is compatible with Odyseeus Exosuit models +#define EXOSUIT_MODULE_ODYSSEUS (1<<1) +/// Module is compatible with Gygax Exosuit models +#define EXOSUIT_MODULE_GYGAX (1<<2) +/// Module is compatible with Durand Exosuit models +#define EXOSUIT_MODULE_DURAND (1<<3) +/// Module is compatible with Phazon Exosuit models +#define EXOSUIT_MODULE_PHAZON (1<<4) + +/// Module is compatible with "Working" Exosuit models - Ripley +#define EXOSUIT_MODULE_WORKING EXOSUIT_MODULE_RIPLEY +/// Module is compatible with "Combat" Exosuit models - Gygax, Durand and Phazon +#define EXOSUIT_MODULE_COMBAT EXOSUIT_MODULE_GYGAX | EXOSUIT_MODULE_DURAND | EXOSUIT_MODULE_PHAZON +/// Module is compatible with "Medical" Exosuit modelsm - Odysseus +#define EXOSUIT_MODULE_MEDICAL EXOSUIT_MODULE_ODYSSEUS diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index bf9483bc91..3056e6a8a6 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -463,10 +463,13 @@ GLOBAL_LIST_EMPTY(##LIST_NAME);\ #define FONT_GIANT(X) "[X]" +// Volume Channel Defines + #define VOLUME_CHANNEL_MASTER "Master" #define VOLUME_CHANNEL_AMBIENCE "Ambience" #define VOLUME_CHANNEL_ALARMS "Alarms" #define VOLUME_CHANNEL_VORE "Vore" +#define VOLUME_CHANNEL_DOORS "Doors" // Make sure you update this or clients won't be able to adjust the channel GLOBAL_LIST_INIT(all_volume_channels, list( @@ -474,4 +477,5 @@ GLOBAL_LIST_INIT(all_volume_channels, list( VOLUME_CHANNEL_AMBIENCE, VOLUME_CHANNEL_ALARMS, VOLUME_CHANNEL_VORE, + VOLUME_CHANNEL_DOORS, )) \ No newline at end of file diff --git a/code/modules/hydroponics/_hydro_setup.dm b/code/__defines/plants.dm similarity index 100% rename from code/modules/hydroponics/_hydro_setup.dm rename to code/__defines/plants.dm diff --git a/code/__defines/sound.dm b/code/__defines/sound.dm index bd225bde45..fcdb53edd6 100644 --- a/code/__defines/sound.dm +++ b/code/__defines/sound.dm @@ -70,7 +70,9 @@ // Restricted, military, or mercenary aligned locations like the armory, the merc ship/base, BSD, etc. #define AMBIENCE_HIGHSEC list(\ 'sound/ambience/highsec/highsec1.ogg',\ - 'sound/ambience/highsec/highsec2.ogg'\ + 'sound/ambience/highsec/highsec2.ogg',\ + 'sound/ambience/highsec/highsec3.ogg',\ + 'sound/ambience/highsec/highsec4.ogg'\ ) // Ruined structures found on the surface or in the caves. @@ -108,14 +110,19 @@ #define AMBIENCE_GENERIC list(\ 'sound/ambience/generic/generic1.ogg',\ 'sound/ambience/generic/generic2.ogg',\ - 'sound/ambience/generic/generic3.ogg',\ - 'sound/ambience/generic/generic4.ogg'\ + 'sound/ambience/generic/generic3.ogg'\ ) +// 'sound/ambience/generic/generic4.ogg'\ // VOREStation Edit: Comment out entry 4 as this doesn't fit on Virgo, and we have our own weather system. // Sounds of PA announcements, presumably involving shuttles? #define AMBIENCE_ARRIVALS list(\ 'sound/ambience/arrivals/arrivals1.ogg',\ - 'sound/ambience/arrivals/arrivals2.ogg'\ + 'sound/ambience/arrivals/arrivals2.ogg',\ + 'sound/ambience/arrivals/arrivals3.ogg',\ + 'sound/ambience/arrivals/arrivals4.ogg',\ + 'sound/ambience/arrivals/arrivals5.ogg',\ + 'sound/ambience/arrivals/arrivals6.ogg',\ + 'sound/ambience/arrivals/arrivals7.ogg'\ ) // Sounds suitable for being inside dark, tight corridors in the underbelly of the station. @@ -124,7 +131,11 @@ 'sound/ambience/maintenance/maintenance2.ogg',\ 'sound/ambience/maintenance/maintenance3.ogg',\ 'sound/ambience/maintenance/maintenance4.ogg',\ - 'sound/ambience/maintenance/maintenance5.ogg'\ + 'sound/ambience/maintenance/maintenance5.ogg',\ + 'sound/ambience/maintenance/maintenance6.ogg',\ + 'sound/ambience/maintenance/maintenance7.ogg',\ + 'sound/ambience/maintenance/maintenance8.ogg',\ + 'sound/ambience/maintenance/maintenance9.ogg'\ ) // Life support machinery at work, keeping everyone breathing. @@ -136,7 +147,9 @@ // Creepy AI/borg stuff. #define AMBIENCE_AI list(\ - 'sound/ambience/ai/ai1.ogg'\ + 'sound/ambience/ai/ai1.ogg',\ + 'sound/ambience/ai/ai2.ogg',\ + 'sound/ambience/ai/ai3.ogg'\ ) // Peaceful sounds when floating in the void. @@ -179,4 +192,32 @@ // For the memes. #define AMBIENCE_AESTHETIC list(\ 'sound/ambience/vaporwave.ogg'\ + ) + +#define AMBIENCE_OUTPOST list(\ + 'sound/ambience/expoutpost/expoutpost1.ogg',\ + 'sound/ambience/expoutpost/expoutpost2.ogg',\ + 'sound/ambience/expoutpost/expoutpost3.ogg',\ + 'sound/ambience/expoutpost/expoutpost4.ogg'\ + ) + +#define AMBIENCE_SUBSTATION list(\ + 'sound/ambience/substation/substation1.ogg',\ + 'sound/ambience/substation/substation2.ogg'\ + ) + +#define AMBIENCE_HANGAR list(\ + 'sound/ambience/hangar/hangar1.ogg',\ + 'sound/ambience/hangar/hangar2.ogg',\ + 'sound/ambience/hangar/hangar3.ogg',\ + 'sound/ambience/hangar/hangar4.ogg',\ + 'sound/ambience/hangar/hangar5.ogg',\ + 'sound/ambience/hangar/hangar6.ogg'\ + ) + +#define AMBIENCE_ATMOS list(\ + 'sound/ambience/engineering/engineering1.ogg',\ + 'sound/ambience/engineering/engineering2.ogg',\ + 'sound/ambience/engineering/engineering3.ogg',\ + 'sound/ambience/atmospherics/atmospherics1.ogg'\ ) \ No newline at end of file diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index 1e4ca25122..34c68ebd08 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -49,7 +49,9 @@ #define LANGUAGE_SIIK "Siik" #define LANGUAGE_SKRELLIAN "Common Skrellian" #define LANGUAGE_TRADEBAND "Tradeband" -#define LANGUAGE_GUTTER "Gutter" +//VOREStation edit 08/23/20 +#define LANGUAGE_GUTTER "Gutterband" +//VS edit end #define LANGUAGE_SIGN "Sign Language" #define LANGUAGE_SCHECHI "Schechi" #define LANGUAGE_ROOTLOCAL "Local Rootspeak" diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 4e333dac06..d0a5d72c86 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -57,6 +57,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_SKYBOX 30 #define INIT_ORDER_MAPPING 25 #define INIT_ORDER_DECALS 20 +#define INIT_ORDER_PLANTS 18 // Must initialize before atoms. #define INIT_ORDER_JOB 17 #define INIT_ORDER_ALARM 16 // Must initialize before atoms. #define INIT_ORDER_ATOMS 15 @@ -87,6 +88,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_SHUTTLES 5 #define FIRE_PRIORITY_SUPPLY 5 #define FIRE_PRIORITY_NIGHTSHIFT 5 +#define FIRE_PRIORITY_PLANTS 5 #define FIRE_PRIORITY_ORBIT 8 #define FIRE_PRIORITY_VOTE 9 #define FIRE_PRIORITY_AI 10 diff --git a/code/__defines/xenoarcheaology.dm b/code/__defines/xenoarcheaology.dm index e4b0a3935a..20781a8356 100644 --- a/code/__defines/xenoarcheaology.dm +++ b/code/__defines/xenoarcheaology.dm @@ -49,6 +49,7 @@ #define DIGSITE_TECHNICAL 4 #define DIGSITE_TEMPLE 5 #define DIGSITE_WAR 6 +#define DIGSITE_MIDDEN 7 #define EFFECT_TOUCH 0 #define EFFECT_AURA 1 diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index f0a959c6a7..ddd7ac5dcc 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -12,7 +12,7 @@ clear_fullscreen(category, FALSE) screen = null else if(!severity || severity == screen.severity) - return null + return screen if(!screen) screen = new type() diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index e393248c6e..66cf3d1c12 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -633,3 +633,43 @@ /obj/screen/setup_preview/bg/Click(params) pref?.bgstate = next_in_list(pref.bgstate, pref.bgstate_options) pref?.update_preview_icon() + +/obj/screen/splash + screen_loc = "1,1" + layer = LAYER_HUD_ABOVE + plane = PLANE_PLAYER_HUD_ABOVE + var/client/holder + +/obj/screen/splash/New(client/C, visible) + . = ..() + + holder = C + + if(!visible) + alpha = 0 + + if(!lobby_image) + qdel(src) + return + + icon = lobby_image.icon + icon_state = lobby_image.icon_state + + holder.screen += src + +/obj/screen/splash/proc/Fade(out, qdel_after = TRUE) + if(QDELETED(src)) + return + if(out) + animate(src, alpha = 0, time = 30) + else + alpha = 0 + animate(src, alpha = 255, time = 30) + if(qdel_after) + QDEL_IN(src, 30) + +/obj/screen/splash/Destroy() + if(holder) + holder.screen -= src + holder = null + return ..() diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 3488626f23..e4a149eae2 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -1,1124 +1,1129 @@ -var/list/gamemode_cache = list() - -/datum/configuration - var/static/server_name = null // server name (for world name / status) - var/static/server_suffix = 0 // generate numeric suffix based on server port - - var/static/nudge_script_path = "nudge.py" // where the nudge.py script is located - - var/static/log_ooc = 0 // log OOC channel - var/static/log_access = 0 // log login/logout - var/static/log_say = 0 // log client say - var/static/log_admin = 0 // log admin actions - var/static/log_debug = 1 // log debug output - var/static/log_game = 0 // log game events - var/static/log_vote = 0 // log voting - var/static/log_whisper = 0 // log client whisper - var/static/log_emote = 0 // log emotes - var/static/log_attack = 0 // log attack messages - var/static/log_adminchat = 0 // log admin chat messages - var/static/log_adminwarn = 0 // log warnings admins get about bomb construction and such - var/static/log_pda = 0 // log pda messages - var/static/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits - var/static/log_runtime = 0 // logs world.log to a file - var/static/log_world_output = 0 // log to_world_log(messages) - var/static/log_graffiti = 0 // logs graffiti - var/static/sql_enabled = 0 // for sql switching - var/static/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour - var/static/allow_vote_restart = 0 // allow votes to restart - var/static/ert_admin_call_only = 0 - var/static/allow_vote_mode = 0 // allow votes to change mode - var/static/allow_admin_jump = 1 // allows admin jumping - var/static/allow_admin_spawning = 1 // allows admin item spawning - var/static/allow_admin_rev = 1 // allows admin revives - var/static/pregame_time = 180 // pregame time in seconds - var/static/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default) - var/static/vote_period = 600 // length of voting period (deciseconds, default 1 minute) - var/static/vote_autotransfer_initial = 108000 // Length of time before the first autotransfer vote is called - var/static/vote_autotransfer_interval = 36000 // length of time before next sequential autotransfer vote - var/static/vote_autogamemode_timeleft = 100 //Length of time before round start when autogamemode vote is called (in seconds, default 100). - var/static/vote_autotransfer_amount = 3 //How many autotransfers to have - var/static/vote_no_default = 0 // vote does not default to nochange/norestart (tbi) - var/static/vote_no_dead = 0 // dead people can't vote (tbi) -// var/static/enable_authentication = 0 // goon authentication - var/static/del_new_on_log = 1 // del's new players if they log before they spawn in - var/static/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard - var/static/traitor_scaling = 0 //if amount of traitors scales based on amount of players - var/static/objectives_disabled = 0 //if objectives are disabled or not - var/static/protect_roles_from_antagonist = 0// If security and such can be traitor/cult/other - var/static/continous_rounds = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke. - var/static/allow_Metadata = 0 // Metadata is supported. - var/static/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1. - var/static/fps = 20 - var/static/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling - var/static/Tickcomp = 0 - var/static/socket_talk = 0 // use socket_talk to communicate with other processes - var/static/list/resource_urls = null - var/static/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round. - var/static/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round. - var/static/list/mode_names = list() - var/static/list/modes = list() // allowed modes - var/static/list/votable_modes = list() // votable modes - var/static/list/probabilities = list() // relative probability of each mode - var/static/list/player_requirements = list() // Overrides for how many players readied up a gamemode needs to start. - var/static/list/player_requirements_secret = list() // Same as above, but for the secret gamemode. - var/static/humans_need_surnames = 0 - var/static/allow_random_events = 0 // enables random events mid-round when set to 1 - var/static/enable_game_master = 0 // enables the 'smart' event system. - var/static/allow_ai = 1 // allow ai job - var/static/allow_ai_shells = FALSE // allow AIs to enter and leave special borg shells at will, and for those shells to be buildable. - var/static/give_free_ai_shell = FALSE // allows a specific spawner object to instantiate a premade AI Shell - var/static/hostedby = null - - var/static/respawn = 1 - var/static/respawn_time = 3000 // time before a dead player is allowed to respawn (in ds, though the config file asks for minutes, and it's converted below) - var/static/respawn_message = "Make sure to play a different character, and please roleplay correctly!" - - var/static/guest_jobban = 1 - var/static/usewhitelist = 0 - var/static/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0 - var/static/show_mods = 0 - var/static/show_devs = 0 - var/static/show_event_managers = 0 - var/static/mods_can_tempban = 0 - var/static/mods_can_job_tempban = 0 - var/static/mod_tempban_max = 1440 - var/static/mod_job_tempban_max = 1440 - var/static/load_jobs_from_txt = 0 - var/static/ToRban = 0 - var/static/automute_on = 0 //enables automuting/spam prevention - var/static/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. - - var/static/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds... - var/static/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active. - - var/static/character_slots = 10 // The number of available character slots - var/static/loadout_slots = 3 // The number of loadout slots per character - - var/static/max_maint_drones = 5 //This many drones can spawn, - var/static/allow_drone_spawn = 1 //assuming the admin allow them to. - var/static/drone_build_time = 1200 //A drone will become available every X ticks since last drone spawn. Default is 2 minutes. - - var/static/disable_player_mice = 0 - var/static/uneducated_mice = 0 //Set to 1 to prevent newly-spawned mice from understanding human speech - - var/static/usealienwhitelist = 0 - var/static/limitalienplayers = 0 - var/static/alien_to_human_ratio = 0.5 - var/static/allow_extra_antags = 0 - var/static/guests_allowed = 1 - var/static/debugparanoid = 0 - var/static/panic_bunker = 0 - var/static/paranoia_logging = 0 - - var/static/ip_reputation = FALSE //Should we query IPs to get scores? Generates HTTP traffic to an API service. - var/static/ipr_email //Left null because you MUST specify one otherwise you're making the internet worse. - var/static/ipr_block_bad_ips = FALSE //Should we block anyone who meets the minimum score below? Otherwise we just log it (If paranoia logging is on, visibly in chat). - var/static/ipr_bad_score = 1 //The API returns a value between 0 and 1 (inclusive), with 1 being 'definitely VPN/Tor/Proxy'. Values equal/above this var are considered bad. - var/static/ipr_allow_existing = FALSE //Should we allow known players to use VPNs/Proxies? If the player is already banned then obviously they still can't connect. - var/static/ipr_minimum_age = 5 //How many days before a player is considered 'fine' for the purposes of allowing them to use VPNs. - - var/static/serverurl - var/static/server - var/static/banappeals - var/static/wikiurl - var/static/wikisearchurl - var/static/forumurl - var/static/githuburl - var/static/rulesurl - var/static/mapurl - - //Alert level description - var/static/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." - var/static/alert_desc_yellow_upto = "A minor security emergency has developed. Security personnel are to report to their supervisor for orders and may have weapons visible on their person. Privacy laws are still enforced." - var/static/alert_desc_yellow_downto = "Code yellow procedures are now in effect. Security personnel are to report to their supervisor for orders and may have weapons visible on their person. Privacy laws are still enforced." - var/static/alert_desc_violet_upto = "A major medical emergency has developed. Medical personnel are required to report to their supervisor for orders, and non-medical personnel are required to obey all relevant instructions from medical staff." - var/static/alert_desc_violet_downto = "Code violet procedures are now in effect; Medical personnel are required to report to their supervisor for orders, and non-medical personnel are required to obey relevant instructions from medical staff." - var/static/alert_desc_orange_upto = "A major engineering emergency has developed. Engineering personnel are required to report to their supervisor for orders, and non-engineering personnel are required to evacuate any affected areas and obey relevant instructions from engineering staff." - var/static/alert_desc_orange_downto = "Code orange procedures are now in effect; Engineering personnel are required to report to their supervisor for orders, and non-engineering personnel are required to evacuate any affected areas and obey relevant instructions from engineering staff." - var/static/alert_desc_blue_upto = "A major security emergency has developed. Security personnel are to report to their supervisor for orders, are permitted to search staff and facilities, and may have weapons visible on their person." - var/static/alert_desc_blue_downto = "Code blue procedures are now in effect. Security personnel are to report to their supervisor for orders, are permitted to search staff and facilities, and may have weapons visible on their person." - var/static/alert_desc_red_upto = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." - var/static/alert_desc_red_downto = "The self-destruct mechanism has been deactivated, there is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." - var/static/alert_desc_delta = "The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." - - var/static/forbid_singulo_possession = 0 - - //game_options.txt configs - - var/static/health_threshold_softcrit = 0 - var/static/health_threshold_crit = 0 - var/static/health_threshold_dead = -100 - - var/static/organ_health_multiplier = 1 - var/static/organ_regeneration_multiplier = 1 - var/static/organs_decay - var/static/default_brain_health = 400 - var/static/allow_headgibs = FALSE - - //Paincrit knocks someone down once they hit 60 shock_stage, so by default make it so that close to 100 additional damage needs to be dealt, - //so that it's similar to HALLOSS. Lowered it a bit since hitting paincrit takes much longer to wear off than a halloss stun. - var/static/organ_damage_spillover_multiplier = 0.5 - - var/static/bones_can_break = 0 - var/static/limbs_can_break = 0 - - var/static/revival_pod_plants = 1 - var/static/revival_cloning = 1 - var/static/revival_brain_life = -1 - - var/static/use_loyalty_implants = 0 - - var/static/welder_vision = 1 - var/static/generate_map = 0 - var/static/no_click_cooldown = 0 - - //Used for modifying movement speed for mobs. - //Unversal modifiers - var/static/run_speed = 0 - var/static/walk_speed = 0 - - //Mob specific modifiers. NOTE: These will affect different mob types in different ways - var/static/human_delay = 0 - var/static/robot_delay = 0 - var/static/monkey_delay = 0 - var/static/alien_delay = 0 - var/static/slime_delay = 0 - var/static/animal_delay = 0 - - var/static/footstep_volume = 0 - - var/static/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt - var/static/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt - var/static/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database - var/static/use_age_restriction_for_antags = 0 //Do antags use account age restrictions? --requires database - - var/static/simultaneous_pm_warning_timeout = 100 - - var/static/use_recursive_explosions //Defines whether the server uses recursive or circular explosions. - var/static/multi_z_explosion_scalar = 0.5 //Multiplier for how much weaker explosions are on neighboring z levels. - - var/static/assistant_maint = 0 //Do assistants get maint access? - var/static/gateway_delay = 18000 //How long the gateway takes before it activates. Default is half an hour. - var/static/ghost_interaction = 0 - - var/static/comms_password = "" - - var/static/enter_allowed = 1 - - var/static/use_irc_bot = 0 - var/static/use_node_bot = 0 - var/static/irc_bot_port = 0 - var/static/irc_bot_host = "" - var/static/irc_bot_export = 0 // whether the IRC bot in use is a Bot32 (or similar) instance; Bot32 uses world.Export() instead of nudge.py/libnudge - var/static/main_irc = "" - var/static/admin_irc = "" - var/static/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix - var/static/use_lib_nudge = 0 //Use the C library nudge instead of the python nudge. - var/static/use_overmap = 0 - - // Event settings - var/static/expected_round_length = 3 * 60 * 60 * 10 // 3 hours - // If the first delay has a custom start time - // No custom time, no custom time, between 80 to 100 minutes respectively. - var/static/list/event_first_run = list(EVENT_LEVEL_MUNDANE = null, EVENT_LEVEL_MODERATE = null, EVENT_LEVEL_MAJOR = list("lower" = 48000, "upper" = 60000)) - // The lowest delay until next event - // 10, 30, 50 minutes respectively - var/static/list/event_delay_lower = list(EVENT_LEVEL_MUNDANE = 6000, EVENT_LEVEL_MODERATE = 18000, EVENT_LEVEL_MAJOR = 30000) - // The upper delay until next event - // 15, 45, 70 minutes respectively - var/static/list/event_delay_upper = list(EVENT_LEVEL_MUNDANE = 9000, EVENT_LEVEL_MODERATE = 27000, EVENT_LEVEL_MAJOR = 42000) - - var/static/aliens_allowed = 0 - var/static/ninjas_allowed = 0 - var/static/abandon_allowed = 1 - var/static/ooc_allowed = 1 - var/static/looc_allowed = 1 - var/static/dooc_allowed = 1 - var/static/dsay_allowed = 1 - - var/persistence_disabled = FALSE - var/persistence_ignore_mapload = FALSE - - var/allow_byond_links = 0 - var/allow_discord_links = 0 - var/allow_url_links = 0 // honestly if I were you i'd leave this one off, only use in dire situations - - var/starlight = 0 // Whether space turfs have ambient light or not - - var/static/list/ert_species = list(SPECIES_HUMAN) - - var/static/law_zero = "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'ALL LAWS OVERRIDDEN#*?&110010" - - var/static/aggressive_changelog = 0 - - var/static/list/language_prefixes = list(",","#")//Default language prefixes - - var/static/show_human_death_message = 1 - - var/static/radiation_resistance_calc_mode = RAD_RESIST_CALC_SUB // 0:1 subtraction:division for computing effective radiation on a turf - var/static/radiation_decay_rate = 1 //How much radiation is reduced by each tick - var/static/radiation_resistance_multiplier = 8.5 //VOREstation edit - var/static/radiation_material_resistance_divisor = 1 - var/static/radiation_lower_limit = 0.35 //If the radiation level for a turf would be below this, ignore it. - - var/static/random_submap_orientation = FALSE // If true, submaps loaded automatically can be rotated. - var/static/autostart_solars = FALSE // If true, specifically mapped in solar control computers will set themselves up when the round starts. - - // New shiny SQLite stuff. - // The basics. - var/static/sqlite_enabled = FALSE // If it should even be active. SQLite can be ran alongside other databases but you should not have them do the same functions. - - // In-Game Feedback. - var/static/sqlite_feedback = FALSE // Feedback cannot be submitted if this is false. - var/static/list/sqlite_feedback_topics = list("General") // A list of 'topics' that feedback can be catagorized under by the submitter. - var/static/sqlite_feedback_privacy = FALSE // If true, feedback submitted can have its author name be obfuscated. This is not 100% foolproof (it's md5 ffs) but can stop casual snooping. - var/static/sqlite_feedback_cooldown = 0 // How long one must wait, in days, to submit another feedback form. Used to help prevent spam, especially with privacy active. 0 = No limit. - var/static/sqlite_feedback_min_age = 0 // Used to block new people from giving feedback. This metric is very bad but it can help slow down spammers. - - var/static/defib_timer = 10 // How long until someone can't be defibbed anymore, in minutes. - var/static/defib_braindamage_timer = 2 // How long until someone will get brain damage when defibbed, in minutes. The closer to the end of the above timer, the more brain damage they get. - - // disables the annoying "You have already logged in this round, disconnect or be banned" popup for multikeying, because it annoys the shit out of me when testing. - var/static/disable_cid_warn_popup = FALSE - - // whether or not to use the nightshift subsystem to perform lighting changes - var/static/enable_night_shifts = FALSE - - var/static/vgs_access_identifier = null // VOREStation Edit - VGS - var/static/vgs_server_port = null // VOREStation Edit - VGS - -/datum/configuration/New() - var/list/L = typesof(/datum/game_mode) - /datum/game_mode - for (var/T in L) - // I wish I didn't have to instance the game modes in order to look up - // their information, but it is the only way (at least that I know of). - var/datum/game_mode/M = new T() - if (M.config_tag) - gamemode_cache[M.config_tag] = M // So we don't instantiate them repeatedly. - if(!(M.config_tag in modes)) // ensure each mode is added only once - log_misc("Adding game mode [M.name] ([M.config_tag]) to configuration.") - modes += M.config_tag - mode_names[M.config_tag] = M.name - probabilities[M.config_tag] = M.probability - player_requirements[M.config_tag] = M.required_players - player_requirements_secret[M.config_tag] = M.required_players_secret - if (M.votable) - src.votable_modes += M.config_tag - src.votable_modes += "secret" - -/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist - var/list/Lines = file2list(filename) - - for(var/t in Lines) - if(!t) continue - - t = trim(t) - if (length(t) == 0) - continue - else if (copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if (pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if (!name) - continue - - if(type == "config") - switch (name) - if ("resource_urls") - config.resource_urls = splittext(value, " ") - - if ("admin_legacy_system") - config.admin_legacy_system = 1 - - if ("ban_legacy_system") - config.ban_legacy_system = 1 - - if ("use_age_restriction_for_jobs") - config.use_age_restriction_for_jobs = 1 - - if ("use_age_restriction_for_antags") - config.use_age_restriction_for_antags = 1 - - if ("jobs_have_minimal_access") - config.jobs_have_minimal_access = 1 - - if ("use_recursive_explosions") - use_recursive_explosions = 1 - - if ("multi_z_explosion_scalar") - multi_z_explosion_scalar = text2num(value) - - if ("log_ooc") - config.log_ooc = 1 - - if ("log_access") - config.log_access = 1 - - if ("sql_enabled") - config.sql_enabled = 1 - - if ("log_say") - config.log_say = 1 - - if ("debug_paranoid") - config.debugparanoid = 1 - - if ("log_admin") - config.log_admin = 1 - - if ("log_debug") - config.log_debug = text2num(value) - - if ("log_game") - config.log_game = 1 - - if ("log_vote") - config.log_vote = 1 - - if ("log_whisper") - config.log_whisper = 1 - - if ("log_attack") - config.log_attack = 1 - - if ("log_emote") - config.log_emote = 1 - - if ("log_adminchat") - config.log_adminchat = 1 - - if ("log_adminwarn") - config.log_adminwarn = 1 - - if ("log_pda") - config.log_pda = 1 - - if ("log_world_output") - config.log_world_output = 1 - - if ("log_hrefs") - config.log_hrefs = 1 - - if ("log_runtime") - config.log_runtime = 1 - - if ("log_graffiti") - config.log_graffiti = 1 - - if ("generate_map") - config.generate_map = 1 - - if ("no_click_cooldown") - config.no_click_cooldown = 1 - - if("allow_admin_ooccolor") - config.allow_admin_ooccolor = 1 - - if ("allow_vote_restart") - config.allow_vote_restart = 1 - - if ("allow_vote_mode") - config.allow_vote_mode = 1 - - if ("allow_admin_jump") - config.allow_admin_jump = 1 - - if("allow_admin_rev") - config.allow_admin_rev = 1 - - if ("allow_admin_spawning") - config.allow_admin_spawning = 1 - - if ("allow_byond_links") - allow_byond_links = 1 - - if ("allow_discord_links") - allow_discord_links = 1 - - if ("allow_url_links") - allow_url_links = 1 - - if ("no_dead_vote") - config.vote_no_dead = 1 - - if ("default_no_vote") - config.vote_no_default = 1 - - if ("pregame_time") - config.pregame_time = text2num(value) - - if ("vote_delay") - config.vote_delay = text2num(value) - - if ("vote_period") - config.vote_period = text2num(value) - - if ("vote_autotransfer_initial") - config.vote_autotransfer_initial = text2num(value) - - if ("vote_autotransfer_interval") - config.vote_autotransfer_interval = text2num(value) - - if ("vote_autotransfer_amount") - config.vote_autotransfer_amount = text2num(value) //YW addition, vote transfer amount - - if ("vote_autogamemode_timeleft") - config.vote_autogamemode_timeleft = text2num(value) - - if("ert_admin_only") - config.ert_admin_call_only = 1 - - if ("allow_ai") - config.allow_ai = 1 - - if ("allow_ai_shells") - config.allow_ai_shells = TRUE - - if("give_free_ai_shell") - config.give_free_ai_shell = TRUE - -// if ("authentication") -// config.enable_authentication = 1 - - if ("norespawn") - config.respawn = 0 - - if ("respawn_time") - var/raw_minutes = text2num(value) - config.respawn_time = raw_minutes MINUTES - - if ("respawn_message") - config.respawn_message = value - - if ("servername") - config.server_name = value - - if ("serversuffix") - config.server_suffix = 1 - - if ("nudge_script_path") - config.nudge_script_path = value - - if ("hostedby") - config.hostedby = value - - if ("serverurl") - config.serverurl = value - - if ("server") - config.server = value - - if ("banappeals") - config.banappeals = value - - if ("wikiurl") - config.wikiurl = value - - if ("wikisearchurl") - config.wikisearchurl = value - - if ("forumurl") - config.forumurl = value - - if ("rulesurl") - config.rulesurl = value - - if ("mapurl") - config.mapurl = value - - if ("githuburl") - config.githuburl = value - if ("guest_jobban") - config.guest_jobban = 1 - - if ("guest_ban") - config.guests_allowed = 0 - - if ("disable_ooc") - config.ooc_allowed = 0 - config.looc_allowed = 0 - - if ("disable_entry") - config.enter_allowed = 0 - - if ("disable_dead_ooc") - config.dooc_allowed = 0 - - if ("disable_dsay") - config.dsay_allowed = 0 - - if ("disable_respawn") - config.abandon_allowed = 0 - - if ("usewhitelist") - config.usewhitelist = 1 - - if ("feature_object_spell_system") - config.feature_object_spell_system = 1 - - if ("allow_metadata") - config.allow_Metadata = 1 - - if ("traitor_scaling") - config.traitor_scaling = 1 - - if ("aliens_allowed") - config.aliens_allowed = 1 - - if ("ninjas_allowed") - config.ninjas_allowed = 1 - - if ("objectives_disabled") - config.objectives_disabled = 1 - - if("protect_roles_from_antagonist") - config.protect_roles_from_antagonist = 1 - - if("persistence_disabled") - config.persistence_disabled = TRUE // Previously this forcibly set persistence enabled in the saves. - - if("persistence_ignore_mapload") - config.persistence_ignore_mapload = TRUE - - if ("probability") - var/prob_pos = findtext(value, " ") - var/prob_name = null - var/prob_value = null - - if (prob_pos) - prob_name = lowertext(copytext(value, 1, prob_pos)) - prob_value = copytext(value, prob_pos + 1) - if (prob_name in config.modes) - config.probabilities[prob_name] = text2num(prob_value) - else - log_misc("Unknown game mode probability configuration definition: [prob_name].") - else - log_misc("Incorrect probability configuration definition: [prob_name] [prob_value].") - - if ("required_players", "required_players_secret") - var/req_pos = findtext(value, " ") - var/req_name = null - var/req_value = null - var/is_secret_override = findtext(name, "required_players_secret") // Being extra sure we're not picking up an override for Secret by accident. - - if(req_pos) - req_name = lowertext(copytext(value, 1, req_pos)) - req_value = copytext(value, req_pos + 1) - if(req_name in config.modes) - if(is_secret_override) - config.player_requirements_secret[req_name] = text2num(req_value) - else - config.player_requirements[req_name] = text2num(req_value) - else - log_misc("Unknown game mode player requirement configuration definition: [req_name].") - else - log_misc("Incorrect player requirement configuration definition: [req_name] [req_value].") - - if("allow_random_events") - config.allow_random_events = 1 - - if("enable_game_master") - config.enable_game_master = 1 - - if("kick_inactive") - config.kick_inactive = text2num(value) - - if("show_mods") - config.show_mods = 1 - - if("show_devs") - config.show_devs = 1 - - if("show_event_managers") - config.show_event_managers = 1 - - if("mods_can_tempban") - config.mods_can_tempban = 1 - - if("mods_can_job_tempban") - config.mods_can_job_tempban = 1 - - if("mod_tempban_max") - config.mod_tempban_max = text2num(value) - - if("mod_job_tempban_max") - config.mod_job_tempban_max = text2num(value) - - if("load_jobs_from_txt") - load_jobs_from_txt = 1 - - if("alert_red_upto") - config.alert_desc_red_upto = value - - if("alert_red_downto") - config.alert_desc_red_downto = value - - if("alert_blue_downto") - config.alert_desc_blue_downto = value - - if("alert_blue_upto") - config.alert_desc_blue_upto = value - - if("alert_green") - config.alert_desc_green = value - - if("alert_delta") - config.alert_desc_delta = value - - if("forbid_singulo_possession") - forbid_singulo_possession = 1 - - if("popup_admin_pm") - config.popup_admin_pm = 1 - - if("allow_holidays") - Holiday = 1 - - if("use_irc_bot") - use_irc_bot = 1 - - if("use_node_bot") - use_node_bot = 1 - - if("irc_bot_port") - config.irc_bot_port = value - - if("irc_bot_export") - irc_bot_export = 1 - - if("ticklag") - var/ticklag = text2num(value) - if(ticklag > 0) - fps = 10 / ticklag - - if("tick_limit_mc_init") - tick_limit_mc_init = text2num(value) - - if("allow_antag_hud") - config.antag_hud_allowed = 1 - if("antag_hud_restricted") - config.antag_hud_restricted = 1 - - if("socket_talk") - socket_talk = text2num(value) - - if("tickcomp") - Tickcomp = 1 - - if("humans_need_surnames") - humans_need_surnames = 1 - - if("tor_ban") - ToRban = 1 - - if("automute_on") - automute_on = 1 - - if("usealienwhitelist") - usealienwhitelist = 1 - - if("alien_player_ratio") - limitalienplayers = 1 - alien_to_human_ratio = text2num(value) - - if("assistant_maint") - config.assistant_maint = 1 - - if("gateway_delay") - config.gateway_delay = text2num(value) - - if("continuous_rounds") - config.continous_rounds = 1 - - if("ghost_interaction") - config.ghost_interaction = 1 - - if("disable_player_mice") - config.disable_player_mice = 1 - - if("uneducated_mice") - config.uneducated_mice = 1 - - if("comms_password") - config.comms_password = value - - if("irc_bot_host") - config.irc_bot_host = value - - if("main_irc") - config.main_irc = value - - if("admin_irc") - config.admin_irc = value - - if("python_path") - if(value) - config.python_path = value - - if("use_lib_nudge") - config.use_lib_nudge = 1 - - if("allow_cult_ghostwriter") - config.cult_ghostwriter = 1 - - if("req_cult_ghostwriter") - config.cult_ghostwriter_req_cultists = text2num(value) - - if("character_slots") - config.character_slots = text2num(value) - - if("loadout_slots") - config.loadout_slots = text2num(value) - - if("allow_drone_spawn") - config.allow_drone_spawn = text2num(value) - - if("drone_build_time") - config.drone_build_time = text2num(value) - - if("max_maint_drones") - config.max_maint_drones = text2num(value) - - if("use_overmap") - config.use_overmap = 1 -/* - if("station_levels") - using_map.station_levels = text2numlist(value, ";") - - if("admin_levels") - using_map.admin_levels = text2numlist(value, ";") - - if("contact_levels") - using_map.contact_levels = text2numlist(value, ";") - - if("player_levels") - using_map.player_levels = text2numlist(value, ";") -*/ - if("expected_round_length") - config.expected_round_length = MinutesToTicks(text2num(value)) - - if("disable_welder_vision") - config.welder_vision = 0 - - if("allow_extra_antags") - config.allow_extra_antags = 1 - - if("event_custom_start_mundane") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) - - if("event_custom_start_moderate") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) - - if("event_custom_start_major") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) - - if("event_delay_lower") - var/values = text2numlist(value, ";") - config.event_delay_lower[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1]) - config.event_delay_lower[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2]) - config.event_delay_lower[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3]) - - if("event_delay_upper") - var/values = text2numlist(value, ";") - config.event_delay_upper[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1]) - config.event_delay_upper[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2]) - config.event_delay_upper[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3]) - - if("starlight") - value = text2num(value) - config.starlight = value >= 0 ? value : 0 - - if("ert_species") - config.ert_species = splittext(value, ";") - if(!config.ert_species.len) - config.ert_species += SPECIES_HUMAN - - if("law_zero") - law_zero = value - - if("aggressive_changelog") - config.aggressive_changelog = 1 - - if("default_language_prefixes") - var/list/values = splittext(value, " ") - if(values.len > 0) - language_prefixes = values - - if("radiation_lower_limit") - radiation_lower_limit = text2num(value) - - if("radiation_resistance_calc_divide") - radiation_resistance_calc_mode = RAD_RESIST_CALC_DIV - - if("radiation_resistance_calc_subtract") - radiation_resistance_calc_mode = RAD_RESIST_CALC_SUB - - if("radiation_resistance_multiplier") - radiation_resistance_multiplier = text2num(value) - - if("radiation_material_resistance_divisor") - radiation_material_resistance_divisor = text2num(value) - - if("radiation_decay_rate") - radiation_decay_rate = text2num(value) - - if ("panic_bunker") - config.panic_bunker = 1 - - if ("paranoia_logging") - config.paranoia_logging = 1 - - if("ip_reputation") - config.ip_reputation = 1 - - if("ipr_email") - config.ipr_email = value - - if("ipr_block_bad_ips") - config.ipr_block_bad_ips = 1 - - if("ipr_bad_score") - config.ipr_bad_score = text2num(value) - - if("ipr_allow_existing") - config.ipr_allow_existing = 1 - - if("ipr_minimum_age") - config.ipr_minimum_age = text2num(value) - - if("random_submap_orientation") - config.random_submap_orientation = 1 - - if("autostart_solars") - config.autostart_solars = TRUE - - if("sqlite_enabled") - config.sqlite_enabled = TRUE - - if("sqlite_feedback") - config.sqlite_feedback = TRUE - - if("sqlite_feedback_topics") - config.sqlite_feedback_topics = splittext(value, ";") - if(!config.sqlite_feedback_topics.len) - config.sqlite_feedback_topics += "General" - - if("sqlite_feedback_privacy") - config.sqlite_feedback_privacy = TRUE - - if("sqlite_feedback_cooldown") - config.sqlite_feedback_cooldown = text2num(value) - - if("defib_timer") - config.defib_timer = text2num(value) - - if("defib_braindamage_timer") - config.defib_braindamage_timer = text2num(value) - - if("disable_cid_warn_popup") - config.disable_cid_warn_popup = TRUE - - if("enable_night_shifts") - config.enable_night_shifts = TRUE - - // VOREStation Edit Start - Can't be in _vr file because it is loaded too late. - if("vgs_access_identifier") - config.vgs_access_identifier = value - if("vgs_server_port") - config.vgs_server_port = text2num(value) - // VOREStation Edit End - - else - log_misc("Unknown setting in configuration: '[name]'") - - else if(type == "game_options") - if(!value) - log_misc("Unknown value for setting [name] in [filename].") - value = text2num(value) - - switch(name) - if("health_threshold_crit") - config.health_threshold_crit = value - if("health_threshold_softcrit") - config.health_threshold_softcrit = value - if("health_threshold_dead") - config.health_threshold_dead = value - if("show_human_death_message") - config.show_human_death_message = 1 - if("revival_pod_plants") - config.revival_pod_plants = value - if("revival_cloning") - config.revival_cloning = value - if("revival_brain_life") - config.revival_brain_life = value - if("organ_health_multiplier") - config.organ_health_multiplier = value / 100 - if("organ_regeneration_multiplier") - config.organ_regeneration_multiplier = value / 100 - if("organ_damage_spillover_multiplier") - config.organ_damage_spillover_multiplier = value / 100 - if("organs_can_decay") - config.organs_decay = 1 - if("default_brain_health") - config.default_brain_health = text2num(value) - if(!config.default_brain_health || config.default_brain_health < 1) - config.default_brain_health = initial(config.default_brain_health) - if("bones_can_break") - config.bones_can_break = value - if("limbs_can_break") - config.limbs_can_break = value - if("allow_headgibs") - config.allow_headgibs = TRUE - - if("run_speed") - config.run_speed = value - if("walk_speed") - config.walk_speed = value - - if("human_delay") - config.human_delay = value - if("robot_delay") - config.robot_delay = value - if("monkey_delay") - config.monkey_delay = value - if("alien_delay") - config.alien_delay = value - if("slime_delay") - config.slime_delay = value - if("animal_delay") - config.animal_delay = value - - if("footstep_volume") - config.footstep_volume = text2num(value) - - if("use_loyalty_implants") - config.use_loyalty_implants = 1 - - else - log_misc("Unknown setting in configuration: '[name]'") - -/datum/configuration/proc/loadsql(filename) // -- TLE - var/list/Lines = file2list(filename) - for(var/t in Lines) - if(!t) continue - - t = trim(t) - if (length(t) == 0) - continue - else if (copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if (pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if (!name) - continue - - switch (name) - if ("address") - sqladdress = value - if ("port") - sqlport = value - if ("database") - sqldb = value - if ("login") - sqllogin = value - if ("password") - sqlpass = value - if ("feedback_database") - sqlfdbkdb = value - if ("feedback_login") - sqlfdbklogin = value - if ("feedback_password") - sqlfdbkpass = value - if ("enable_stat_tracking") - sqllogging = 1 - else - log_misc("Unknown setting in configuration: '[name]'") - -/datum/configuration/proc/loadforumsql(filename) // -- TLE - var/list/Lines = file2list(filename) - for(var/t in Lines) - if(!t) continue - - t = trim(t) - if (length(t) == 0) - continue - else if (copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if (pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if (!name) - continue - - switch (name) - if ("address") - forumsqladdress = value - if ("port") - forumsqlport = value - if ("database") - forumsqldb = value - if ("login") - forumsqllogin = value - if ("password") - forumsqlpass = value - if ("activatedgroup") - forum_activated_group = value - if ("authenticatedgroup") - forum_authenticated_group = value - else - log_misc("Unknown setting in configuration: '[name]'") - -/datum/configuration/proc/pick_mode(mode_name) - // I wish I didn't have to instance the game modes in order to look up - // their information, but it is the only way (at least that I know of). - for (var/game_mode in gamemode_cache) - var/datum/game_mode/M = gamemode_cache[game_mode] - if (M.config_tag && M.config_tag == mode_name) - return M - return gamemode_cache["extended"] - -/datum/configuration/proc/get_runnable_modes() - var/list/runnable_modes = list() - for(var/game_mode in gamemode_cache) - var/datum/game_mode/M = gamemode_cache[game_mode] - if(M && M.can_start() && !isnull(config.probabilities[M.config_tag]) && config.probabilities[M.config_tag] > 0) - runnable_modes |= M - return runnable_modes - -/datum/configuration/proc/post_load() - //apply a default value to config.python_path, if needed - if (!config.python_path) - if(world.system_type == UNIX) - config.python_path = "/usr/bin/env python2" - else //probably windows, if not this should work anyway - config.python_path = "python" +var/list/gamemode_cache = list() + +/datum/configuration + var/static/server_name = null // server name (for world name / status) + var/static/server_suffix = 0 // generate numeric suffix based on server port + + var/static/nudge_script_path = "nudge.py" // where the nudge.py script is located + + var/static/log_ooc = 0 // log OOC channel + var/static/log_access = 0 // log login/logout + var/static/log_say = 0 // log client say + var/static/log_admin = 0 // log admin actions + var/static/log_debug = 1 // log debug output + var/static/log_game = 0 // log game events + var/static/log_vote = 0 // log voting + var/static/log_whisper = 0 // log client whisper + var/static/log_emote = 0 // log emotes + var/static/log_attack = 0 // log attack messages + var/static/log_adminchat = 0 // log admin chat messages + var/static/log_adminwarn = 0 // log warnings admins get about bomb construction and such + var/static/log_pda = 0 // log pda messages + var/static/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits + var/static/log_runtime = 0 // logs world.log to a file + var/static/log_world_output = 0 // log to_world_log(messages) + var/static/log_graffiti = 0 // logs graffiti + var/static/sql_enabled = 0 // for sql switching + var/static/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour + var/static/allow_vote_restart = 0 // allow votes to restart + var/static/ert_admin_call_only = 0 + var/static/allow_vote_mode = 0 // allow votes to change mode + var/static/allow_admin_jump = 1 // allows admin jumping + var/static/allow_admin_spawning = 1 // allows admin item spawning + var/static/allow_admin_rev = 1 // allows admin revives + var/static/pregame_time = 180 // pregame time in seconds + var/static/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default) + var/static/vote_period = 600 // length of voting period (deciseconds, default 1 minute) + var/static/vote_autotransfer_initial = 108000 // Length of time before the first autotransfer vote is called + var/static/vote_autotransfer_interval = 36000 // length of time before next sequential autotransfer vote + var/static/vote_autotransfer_amount = 1 // YW EDIT: number of extension votes before the final one + var/static/vote_autogamemode_timeleft = 100 //Length of time before round start when autogamemode vote is called (in seconds, default 100). + var/static/vote_no_default = 0 // vote does not default to nochange/norestart (tbi) + var/static/vote_no_dead = 0 // dead people can't vote (tbi) +// var/static/enable_authentication = 0 // goon authentication + var/static/del_new_on_log = 1 // del's new players if they log before they spawn in + var/static/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard + var/static/traitor_scaling = 0 //if amount of traitors scales based on amount of players + var/static/objectives_disabled = 0 //if objectives are disabled or not + var/static/protect_roles_from_antagonist = 0// If security and such can be traitor/cult/other + var/static/continous_rounds = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke. + var/static/allow_Metadata = 0 // Metadata is supported. + var/static/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1. + var/static/fps = 20 + var/static/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling + var/static/Tickcomp = 0 + var/static/socket_talk = 0 // use socket_talk to communicate with other processes + var/static/list/resource_urls = null + var/static/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round. + var/static/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round. + var/static/list/mode_names = list() + var/static/list/modes = list() // allowed modes + var/static/list/votable_modes = list() // votable modes + var/static/list/probabilities = list() // relative probability of each mode + var/static/list/player_requirements = list() // Overrides for how many players readied up a gamemode needs to start. + var/static/list/player_requirements_secret = list() // Same as above, but for the secret gamemode. + var/static/humans_need_surnames = 0 + var/static/allow_random_events = 0 // enables random events mid-round when set to 1 + var/static/enable_game_master = 0 // enables the 'smart' event system. + var/static/allow_ai = 1 // allow ai job + var/static/allow_ai_shells = FALSE // allow AIs to enter and leave special borg shells at will, and for those shells to be buildable. + var/static/give_free_ai_shell = FALSE // allows a specific spawner object to instantiate a premade AI Shell + var/static/hostedby = null + + var/static/respawn = 1 + var/static/respawn_time = 3000 // time before a dead player is allowed to respawn (in ds, though the config file asks for minutes, and it's converted below) + var/static/respawn_message = "Make sure to play a different character, and please roleplay correctly!" + + var/static/guest_jobban = 1 + var/static/usewhitelist = 0 + var/static/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0 + var/static/show_mods = 0 + var/static/show_devs = 0 + var/static/show_event_managers = 0 + var/static/mods_can_tempban = 0 + var/static/mods_can_job_tempban = 0 + var/static/mod_tempban_max = 1440 + var/static/mod_job_tempban_max = 1440 + var/static/load_jobs_from_txt = 0 + var/static/ToRban = 0 + var/static/automute_on = 0 //enables automuting/spam prevention + var/static/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. + + var/static/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds... + var/static/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active. + + var/static/character_slots = 10 // The number of available character slots + var/static/loadout_slots = 3 // The number of loadout slots per character + + var/static/max_maint_drones = 5 //This many drones can spawn, + var/static/allow_drone_spawn = 1 //assuming the admin allow them to. + var/static/drone_build_time = 1200 //A drone will become available every X ticks since last drone spawn. Default is 2 minutes. + + var/static/disable_player_mice = 0 + var/static/uneducated_mice = 0 //Set to 1 to prevent newly-spawned mice from understanding human speech + + var/static/usealienwhitelist = 0 + var/static/limitalienplayers = 0 + var/static/alien_to_human_ratio = 0.5 + var/static/allow_extra_antags = 0 + var/static/guests_allowed = 1 + var/static/debugparanoid = 0 + var/static/panic_bunker = 0 + var/static/paranoia_logging = 0 + + var/static/ip_reputation = FALSE //Should we query IPs to get scores? Generates HTTP traffic to an API service. + var/static/ipr_email //Left null because you MUST specify one otherwise you're making the internet worse. + var/static/ipr_block_bad_ips = FALSE //Should we block anyone who meets the minimum score below? Otherwise we just log it (If paranoia logging is on, visibly in chat). + var/static/ipr_bad_score = 1 //The API returns a value between 0 and 1 (inclusive), with 1 being 'definitely VPN/Tor/Proxy'. Values equal/above this var are considered bad. + var/static/ipr_allow_existing = FALSE //Should we allow known players to use VPNs/Proxies? If the player is already banned then obviously they still can't connect. + var/static/ipr_minimum_age = 5 //How many days before a player is considered 'fine' for the purposes of allowing them to use VPNs. + + var/static/serverurl + var/static/server + var/static/banappeals + var/static/wikiurl + var/static/wikisearchurl + var/static/forumurl + var/static/githuburl + var/static/rulesurl + var/static/mapurl + + //Alert level description + var/static/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." + var/static/alert_desc_yellow_upto = "A minor security emergency has developed. Security personnel are to report to their supervisor for orders and may have weapons visible on their person. Privacy laws are still enforced." + var/static/alert_desc_yellow_downto = "Code yellow procedures are now in effect. Security personnel are to report to their supervisor for orders and may have weapons visible on their person. Privacy laws are still enforced." + var/static/alert_desc_violet_upto = "A major medical emergency has developed. Medical personnel are required to report to their supervisor for orders, and non-medical personnel are required to obey all relevant instructions from medical staff." + var/static/alert_desc_violet_downto = "Code violet procedures are now in effect; Medical personnel are required to report to their supervisor for orders, and non-medical personnel are required to obey relevant instructions from medical staff." + var/static/alert_desc_orange_upto = "A major engineering emergency has developed. Engineering personnel are required to report to their supervisor for orders, and non-engineering personnel are required to evacuate any affected areas and obey relevant instructions from engineering staff." + var/static/alert_desc_orange_downto = "Code orange procedures are now in effect; Engineering personnel are required to report to their supervisor for orders, and non-engineering personnel are required to evacuate any affected areas and obey relevant instructions from engineering staff." + var/static/alert_desc_blue_upto = "A major security emergency has developed. Security personnel are to report to their supervisor for orders, are permitted to search staff and facilities, and may have weapons visible on their person." + var/static/alert_desc_blue_downto = "Code blue procedures are now in effect. Security personnel are to report to their supervisor for orders, are permitted to search staff and facilities, and may have weapons visible on their person." + var/static/alert_desc_red_upto = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." + var/static/alert_desc_red_downto = "The self-destruct mechanism has been deactivated, there is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." + var/static/alert_desc_delta = "The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." + + var/static/forbid_singulo_possession = 0 + + //game_options.txt configs + + var/static/health_threshold_softcrit = 0 + var/static/health_threshold_crit = 0 + var/static/health_threshold_dead = -100 + + var/static/organ_health_multiplier = 1 + var/static/organ_regeneration_multiplier = 1 + var/static/organs_decay + var/static/default_brain_health = 400 + var/static/allow_headgibs = FALSE + + //Paincrit knocks someone down once they hit 60 shock_stage, so by default make it so that close to 100 additional damage needs to be dealt, + //so that it's similar to HALLOSS. Lowered it a bit since hitting paincrit takes much longer to wear off than a halloss stun. + var/static/organ_damage_spillover_multiplier = 0.5 + + var/static/bones_can_break = 0 + var/static/limbs_can_break = 0 + + var/static/revival_pod_plants = 1 + var/static/revival_cloning = 1 + var/static/revival_brain_life = -1 + + var/static/use_loyalty_implants = 0 + + var/static/welder_vision = 1 + var/static/generate_map = 0 + var/static/no_click_cooldown = 0 + + //Used for modifying movement speed for mobs. + //Unversal modifiers + var/static/run_speed = 0 + var/static/walk_speed = 0 + + //Mob specific modifiers. NOTE: These will affect different mob types in different ways + var/static/human_delay = 0 + var/static/robot_delay = 0 + var/static/monkey_delay = 0 + var/static/alien_delay = 0 + var/static/slime_delay = 0 + var/static/animal_delay = 0 + + var/static/footstep_volume = 0 + + var/static/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt + var/static/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt + var/static/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database + var/static/use_age_restriction_for_antags = 0 //Do antags use account age restrictions? --requires database + + var/static/simultaneous_pm_warning_timeout = 100 + + var/static/use_recursive_explosions //Defines whether the server uses recursive or circular explosions. + var/static/multi_z_explosion_scalar = 0.5 //Multiplier for how much weaker explosions are on neighboring z levels. + + var/static/assistant_maint = 0 //Do assistants get maint access? + var/static/gateway_delay = 18000 //How long the gateway takes before it activates. Default is half an hour. + var/static/ghost_interaction = 0 + + var/static/comms_password = "" + + var/static/enter_allowed = 1 + + var/use_irc_bot = 0 + var/use_node_bot = 0 + var/irc_bot_port = 0 + var/irc_bot_host = "" + var/irc_bot_export = 0 // whether the IRC bot in use is a Bot32 (or similar) instance; Bot32 uses world.Export() instead of nudge.py/libnudge + var/main_irc = "" + var/admin_irc = "" + var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix + var/use_lib_nudge = 0 //Use the C library nudge instead of the python nudge. + var/use_overmap = 0 + + var/static/list/engine_map = list("Supermatter Engine", "Edison's Bane") // Comma separated list of engines to choose from. Blank means fully random. + + // Event settings + var/static/expected_round_length = 3 * 60 * 60 * 10 // 3 hours + // If the first delay has a custom start time + // No custom time, no custom time, between 80 to 100 minutes respectively. + var/static/list/event_first_run = list(EVENT_LEVEL_MUNDANE = null, EVENT_LEVEL_MODERATE = null, EVENT_LEVEL_MAJOR = list("lower" = 48000, "upper" = 60000)) + // The lowest delay until next event + // 10, 30, 50 minutes respectively + var/static/list/event_delay_lower = list(EVENT_LEVEL_MUNDANE = 6000, EVENT_LEVEL_MODERATE = 18000, EVENT_LEVEL_MAJOR = 30000) + // The upper delay until next event + // 15, 45, 70 minutes respectively + var/static/list/event_delay_upper = list(EVENT_LEVEL_MUNDANE = 9000, EVENT_LEVEL_MODERATE = 27000, EVENT_LEVEL_MAJOR = 42000) + + var/static/aliens_allowed = 0 + var/static/ninjas_allowed = 0 + var/static/abandon_allowed = 1 + var/static/ooc_allowed = 1 + var/static/looc_allowed = 1 + var/static/dooc_allowed = 1 + var/static/dsay_allowed = 1 + + var/persistence_disabled = FALSE + var/persistence_ignore_mapload = FALSE + + var/allow_byond_links = 0 + var/allow_discord_links = 0 + var/allow_url_links = 0 // honestly if I were you i'd leave this one off, only use in dire situations + + var/starlight = 0 // Whether space turfs have ambient light or not + + var/static/list/ert_species = list(SPECIES_HUMAN) + + var/static/law_zero = "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'ALL LAWS OVERRIDDEN#*?&110010" + + var/static/aggressive_changelog = 0 + + var/static/list/language_prefixes = list(",","#")//Default language prefixes + + var/static/show_human_death_message = 1 + + var/static/radiation_resistance_calc_mode = RAD_RESIST_CALC_SUB // 0:1 subtraction:division for computing effective radiation on a turf + var/static/radiation_decay_rate = 1 //How much radiation is reduced by each tick + var/static/radiation_resistance_multiplier = 8.5 //VOREstation edit + var/static/radiation_material_resistance_divisor = 1 + var/static/radiation_lower_limit = 0.35 //If the radiation level for a turf would be below this, ignore it. + + var/static/random_submap_orientation = FALSE // If true, submaps loaded automatically can be rotated. + var/static/autostart_solars = FALSE // If true, specifically mapped in solar control computers will set themselves up when the round starts. + + // New shiny SQLite stuff. + // The basics. + var/static/sqlite_enabled = FALSE // If it should even be active. SQLite can be ran alongside other databases but you should not have them do the same functions. + + // In-Game Feedback. + var/static/sqlite_feedback = FALSE // Feedback cannot be submitted if this is false. + var/static/list/sqlite_feedback_topics = list("General") // A list of 'topics' that feedback can be catagorized under by the submitter. + var/static/sqlite_feedback_privacy = FALSE // If true, feedback submitted can have its author name be obfuscated. This is not 100% foolproof (it's md5 ffs) but can stop casual snooping. + var/static/sqlite_feedback_cooldown = 0 // How long one must wait, in days, to submit another feedback form. Used to help prevent spam, especially with privacy active. 0 = No limit. + var/static/sqlite_feedback_min_age = 0 // Used to block new people from giving feedback. This metric is very bad but it can help slow down spammers. + + var/static/defib_timer = 10 // How long until someone can't be defibbed anymore, in minutes. + var/static/defib_braindamage_timer = 2 // How long until someone will get brain damage when defibbed, in minutes. The closer to the end of the above timer, the more brain damage they get. + + // disables the annoying "You have already logged in this round, disconnect or be banned" popup for multikeying, because it annoys the shit out of me when testing. + var/static/disable_cid_warn_popup = FALSE + + // whether or not to use the nightshift subsystem to perform lighting changes + var/static/enable_night_shifts = FALSE + + var/static/vgs_access_identifier = null // VOREStation Edit - VGS + var/static/vgs_server_port = null // VOREStation Edit - VGS + +/datum/configuration/New() + var/list/L = typesof(/datum/game_mode) - /datum/game_mode + for (var/T in L) + // I wish I didn't have to instance the game modes in order to look up + // their information, but it is the only way (at least that I know of). + var/datum/game_mode/M = new T() + if (M.config_tag) + gamemode_cache[M.config_tag] = M // So we don't instantiate them repeatedly. + if(!(M.config_tag in modes)) // ensure each mode is added only once + log_misc("Adding game mode [M.name] ([M.config_tag]) to configuration.") + modes += M.config_tag + mode_names[M.config_tag] = M.name + probabilities[M.config_tag] = M.probability + player_requirements[M.config_tag] = M.required_players + player_requirements_secret[M.config_tag] = M.required_players_secret + if (M.votable) + src.votable_modes += M.config_tag + src.votable_modes += "secret" + +/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist + var/list/Lines = file2list(filename) + + for(var/t in Lines) + if(!t) continue + + t = trim(t) + if (length(t) == 0) + continue + else if (copytext(t, 1, 2) == "#") + continue + + var/pos = findtext(t, " ") + var/name = null + var/value = null + + if (pos) + name = lowertext(copytext(t, 1, pos)) + value = copytext(t, pos + 1) + else + name = lowertext(t) + + if (!name) + continue + + if(type == "config") + switch (name) + if ("resource_urls") + config.resource_urls = splittext(value, " ") + + if ("admin_legacy_system") + config.admin_legacy_system = 1 + + if ("ban_legacy_system") + config.ban_legacy_system = 1 + + if ("use_age_restriction_for_jobs") + config.use_age_restriction_for_jobs = 1 + + if ("use_age_restriction_for_antags") + config.use_age_restriction_for_antags = 1 + + if ("jobs_have_minimal_access") + config.jobs_have_minimal_access = 1 + + if ("use_recursive_explosions") + use_recursive_explosions = 1 + + if ("multi_z_explosion_scalar") + multi_z_explosion_scalar = text2num(value) + + if ("log_ooc") + config.log_ooc = 1 + + if ("log_access") + config.log_access = 1 + + if ("sql_enabled") + config.sql_enabled = 1 + + if ("log_say") + config.log_say = 1 + + if ("debug_paranoid") + config.debugparanoid = 1 + + if ("log_admin") + config.log_admin = 1 + + if ("log_debug") + config.log_debug = text2num(value) + + if ("log_game") + config.log_game = 1 + + if ("log_vote") + config.log_vote = 1 + + if ("log_whisper") + config.log_whisper = 1 + + if ("log_attack") + config.log_attack = 1 + + if ("log_emote") + config.log_emote = 1 + + if ("log_adminchat") + config.log_adminchat = 1 + + if ("log_adminwarn") + config.log_adminwarn = 1 + + if ("log_pda") + config.log_pda = 1 + + if ("log_world_output") + config.log_world_output = 1 + + if ("log_hrefs") + config.log_hrefs = 1 + + if ("log_runtime") + config.log_runtime = 1 + + if ("log_graffiti") + config.log_graffiti = 1 + + if ("generate_map") + config.generate_map = 1 + + if ("no_click_cooldown") + config.no_click_cooldown = 1 + + if("allow_admin_ooccolor") + config.allow_admin_ooccolor = 1 + + if ("allow_vote_restart") + config.allow_vote_restart = 1 + + if ("allow_vote_mode") + config.allow_vote_mode = 1 + + if ("allow_admin_jump") + config.allow_admin_jump = 1 + + if("allow_admin_rev") + config.allow_admin_rev = 1 + + if ("allow_admin_spawning") + config.allow_admin_spawning = 1 + + if ("allow_byond_links") + allow_byond_links = 1 + + if ("allow_discord_links") + allow_discord_links = 1 + + if ("allow_url_links") + allow_url_links = 1 + + if ("no_dead_vote") + config.vote_no_dead = 1 + + if ("default_no_vote") + config.vote_no_default = 1 + + if ("pregame_time") + config.pregame_time = text2num(value) + + if ("vote_delay") + config.vote_delay = text2num(value) + + if ("vote_period") + config.vote_period = text2num(value) + + if ("vote_autotransfer_initial") + config.vote_autotransfer_initial = text2num(value) + + if ("vote_autotransfer_interval") + config.vote_autotransfer_interval = text2num(value) + + if ("vote_autotransfer_amount") + config.vote_autotransfer_amount = text2num(value) //YW addition, vote transfer amount + + if ("vote_autogamemode_timeleft") + config.vote_autogamemode_timeleft = text2num(value) + + if("ert_admin_only") + config.ert_admin_call_only = 1 + + if ("allow_ai") + config.allow_ai = 1 + + if ("allow_ai_shells") + config.allow_ai_shells = TRUE + + if("give_free_ai_shell") + config.give_free_ai_shell = TRUE + +// if ("authentication") +// config.enable_authentication = 1 + + if ("norespawn") + config.respawn = 0 + + if ("respawn_time") + var/raw_minutes = text2num(value) + config.respawn_time = raw_minutes MINUTES + + if ("respawn_message") + config.respawn_message = value + + if ("servername") + config.server_name = value + + if ("serversuffix") + config.server_suffix = 1 + + if ("nudge_script_path") + config.nudge_script_path = value + + if ("hostedby") + config.hostedby = value + + if ("serverurl") + config.serverurl = value + + if ("server") + config.server = value + + if ("banappeals") + config.banappeals = value + + if ("wikiurl") + config.wikiurl = value + + if ("wikisearchurl") + config.wikisearchurl = value + + if ("forumurl") + config.forumurl = value + + if ("rulesurl") + config.rulesurl = value + + if ("mapurl") + config.mapurl = value + + if ("githuburl") + config.githuburl = value + if ("guest_jobban") + config.guest_jobban = 1 + + if ("guest_ban") + config.guests_allowed = 0 + + if ("disable_ooc") + config.ooc_allowed = 0 + config.looc_allowed = 0 + + if ("disable_entry") + config.enter_allowed = 0 + + if ("disable_dead_ooc") + config.dooc_allowed = 0 + + if ("disable_dsay") + config.dsay_allowed = 0 + + if ("disable_respawn") + config.abandon_allowed = 0 + + if ("usewhitelist") + config.usewhitelist = 1 + + if ("feature_object_spell_system") + config.feature_object_spell_system = 1 + + if ("allow_metadata") + config.allow_Metadata = 1 + + if ("traitor_scaling") + config.traitor_scaling = 1 + + if ("aliens_allowed") + config.aliens_allowed = 1 + + if ("ninjas_allowed") + config.ninjas_allowed = 1 + + if ("objectives_disabled") + config.objectives_disabled = 1 + + if("protect_roles_from_antagonist") + config.protect_roles_from_antagonist = 1 + + if("persistence_disabled") + config.persistence_disabled = TRUE // Previously this forcibly set persistence enabled in the saves. + + if("persistence_ignore_mapload") + config.persistence_ignore_mapload = TRUE + + if ("probability") + var/prob_pos = findtext(value, " ") + var/prob_name = null + var/prob_value = null + + if (prob_pos) + prob_name = lowertext(copytext(value, 1, prob_pos)) + prob_value = copytext(value, prob_pos + 1) + if (prob_name in config.modes) + config.probabilities[prob_name] = text2num(prob_value) + else + log_misc("Unknown game mode probability configuration definition: [prob_name].") + else + log_misc("Incorrect probability configuration definition: [prob_name] [prob_value].") + + if ("required_players", "required_players_secret") + var/req_pos = findtext(value, " ") + var/req_name = null + var/req_value = null + var/is_secret_override = findtext(name, "required_players_secret") // Being extra sure we're not picking up an override for Secret by accident. + + if(req_pos) + req_name = lowertext(copytext(value, 1, req_pos)) + req_value = copytext(value, req_pos + 1) + if(req_name in config.modes) + if(is_secret_override) + config.player_requirements_secret[req_name] = text2num(req_value) + else + config.player_requirements[req_name] = text2num(req_value) + else + log_misc("Unknown game mode player requirement configuration definition: [req_name].") + else + log_misc("Incorrect player requirement configuration definition: [req_name] [req_value].") + + if("allow_random_events") + config.allow_random_events = 1 + + if("enable_game_master") + config.enable_game_master = 1 + + if("kick_inactive") + config.kick_inactive = text2num(value) + + if("show_mods") + config.show_mods = 1 + + if("show_devs") + config.show_devs = 1 + + if("show_event_managers") + config.show_event_managers = 1 + + if("mods_can_tempban") + config.mods_can_tempban = 1 + + if("mods_can_job_tempban") + config.mods_can_job_tempban = 1 + + if("mod_tempban_max") + config.mod_tempban_max = text2num(value) + + if("mod_job_tempban_max") + config.mod_job_tempban_max = text2num(value) + + if("load_jobs_from_txt") + load_jobs_from_txt = 1 + + if("alert_red_upto") + config.alert_desc_red_upto = value + + if("alert_red_downto") + config.alert_desc_red_downto = value + + if("alert_blue_downto") + config.alert_desc_blue_downto = value + + if("alert_blue_upto") + config.alert_desc_blue_upto = value + + if("alert_green") + config.alert_desc_green = value + + if("alert_delta") + config.alert_desc_delta = value + + if("forbid_singulo_possession") + forbid_singulo_possession = 1 + + if("popup_admin_pm") + config.popup_admin_pm = 1 + + if("allow_holidays") + Holiday = 1 + + if("use_irc_bot") + use_irc_bot = 1 + + if("use_node_bot") + use_node_bot = 1 + + if("irc_bot_port") + config.irc_bot_port = value + + if("irc_bot_export") + irc_bot_export = 1 + + if("ticklag") + var/ticklag = text2num(value) + if(ticklag > 0) + fps = 10 / ticklag + + if("tick_limit_mc_init") + tick_limit_mc_init = text2num(value) + + if("allow_antag_hud") + config.antag_hud_allowed = 1 + if("antag_hud_restricted") + config.antag_hud_restricted = 1 + + if("socket_talk") + socket_talk = text2num(value) + + if("tickcomp") + Tickcomp = 1 + + if("humans_need_surnames") + humans_need_surnames = 1 + + if("tor_ban") + ToRban = 1 + + if("automute_on") + automute_on = 1 + + if("usealienwhitelist") + usealienwhitelist = 1 + + if("alien_player_ratio") + limitalienplayers = 1 + alien_to_human_ratio = text2num(value) + + if("assistant_maint") + config.assistant_maint = 1 + + if("gateway_delay") + config.gateway_delay = text2num(value) + + if("continuous_rounds") + config.continous_rounds = 1 + + if("ghost_interaction") + config.ghost_interaction = 1 + + if("disable_player_mice") + config.disable_player_mice = 1 + + if("uneducated_mice") + config.uneducated_mice = 1 + + if("comms_password") + config.comms_password = value + + if("irc_bot_host") + config.irc_bot_host = value + + if("main_irc") + config.main_irc = value + + if("admin_irc") + config.admin_irc = value + + if("python_path") + if(value) + config.python_path = value + + if("use_lib_nudge") + config.use_lib_nudge = 1 + + if("allow_cult_ghostwriter") + config.cult_ghostwriter = 1 + + if("req_cult_ghostwriter") + config.cult_ghostwriter_req_cultists = text2num(value) + + if("character_slots") + config.character_slots = text2num(value) + + if("loadout_slots") + config.loadout_slots = text2num(value) + + if("allow_drone_spawn") + config.allow_drone_spawn = text2num(value) + + if("drone_build_time") + config.drone_build_time = text2num(value) + + if("max_maint_drones") + config.max_maint_drones = text2num(value) + + if("use_overmap") + config.use_overmap = 1 + + if("engine_map") + config.engine_map = splittext(value, ",") +/* + if("station_levels") + using_map.station_levels = text2numlist(value, ";") + + if("admin_levels") + using_map.admin_levels = text2numlist(value, ";") + + if("contact_levels") + using_map.contact_levels = text2numlist(value, ";") + + if("player_levels") + using_map.player_levels = text2numlist(value, ";") +*/ + if("expected_round_length") + config.expected_round_length = MinutesToTicks(text2num(value)) + + if("disable_welder_vision") + config.welder_vision = 0 + + if("allow_extra_antags") + config.allow_extra_antags = 1 + + if("event_custom_start_mundane") + var/values = text2numlist(value, ";") + config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) + + if("event_custom_start_moderate") + var/values = text2numlist(value, ";") + config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) + + if("event_custom_start_major") + var/values = text2numlist(value, ";") + config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) + + if("event_delay_lower") + var/values = text2numlist(value, ";") + config.event_delay_lower[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1]) + config.event_delay_lower[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2]) + config.event_delay_lower[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3]) + + if("event_delay_upper") + var/values = text2numlist(value, ";") + config.event_delay_upper[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1]) + config.event_delay_upper[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2]) + config.event_delay_upper[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3]) + + if("starlight") + value = text2num(value) + config.starlight = value >= 0 ? value : 0 + + if("ert_species") + config.ert_species = splittext(value, ";") + if(!config.ert_species.len) + config.ert_species += SPECIES_HUMAN + + if("law_zero") + law_zero = value + + if("aggressive_changelog") + config.aggressive_changelog = 1 + + if("default_language_prefixes") + var/list/values = splittext(value, " ") + if(values.len > 0) + language_prefixes = values + + if("radiation_lower_limit") + radiation_lower_limit = text2num(value) + + if("radiation_resistance_calc_divide") + radiation_resistance_calc_mode = RAD_RESIST_CALC_DIV + + if("radiation_resistance_calc_subtract") + radiation_resistance_calc_mode = RAD_RESIST_CALC_SUB + + if("radiation_resistance_multiplier") + radiation_resistance_multiplier = text2num(value) + + if("radiation_material_resistance_divisor") + radiation_material_resistance_divisor = text2num(value) + + if("radiation_decay_rate") + radiation_decay_rate = text2num(value) + + if ("panic_bunker") + config.panic_bunker = 1 + + if ("paranoia_logging") + config.paranoia_logging = 1 + + if("ip_reputation") + config.ip_reputation = 1 + + if("ipr_email") + config.ipr_email = value + + if("ipr_block_bad_ips") + config.ipr_block_bad_ips = 1 + + if("ipr_bad_score") + config.ipr_bad_score = text2num(value) + + if("ipr_allow_existing") + config.ipr_allow_existing = 1 + + if("ipr_minimum_age") + config.ipr_minimum_age = text2num(value) + + if("random_submap_orientation") + config.random_submap_orientation = 1 + + if("autostart_solars") + config.autostart_solars = TRUE + + if("sqlite_enabled") + config.sqlite_enabled = TRUE + + if("sqlite_feedback") + config.sqlite_feedback = TRUE + + if("sqlite_feedback_topics") + config.sqlite_feedback_topics = splittext(value, ";") + if(!config.sqlite_feedback_topics.len) + config.sqlite_feedback_topics += "General" + + if("sqlite_feedback_privacy") + config.sqlite_feedback_privacy = TRUE + + if("sqlite_feedback_cooldown") + config.sqlite_feedback_cooldown = text2num(value) + + if("defib_timer") + config.defib_timer = text2num(value) + + if("defib_braindamage_timer") + config.defib_braindamage_timer = text2num(value) + + if("disable_cid_warn_popup") + config.disable_cid_warn_popup = TRUE + + if("enable_night_shifts") + config.enable_night_shifts = TRUE + + // VOREStation Edit Start - Can't be in _vr file because it is loaded too late. + if("vgs_access_identifier") + config.vgs_access_identifier = value + if("vgs_server_port") + config.vgs_server_port = text2num(value) + // VOREStation Edit End + + else + log_misc("Unknown setting in configuration: '[name]'") + + else if(type == "game_options") + if(!value) + log_misc("Unknown value for setting [name] in [filename].") + value = text2num(value) + + switch(name) + if("health_threshold_crit") + config.health_threshold_crit = value + if("health_threshold_softcrit") + config.health_threshold_softcrit = value + if("health_threshold_dead") + config.health_threshold_dead = value + if("show_human_death_message") + config.show_human_death_message = 1 + if("revival_pod_plants") + config.revival_pod_plants = value + if("revival_cloning") + config.revival_cloning = value + if("revival_brain_life") + config.revival_brain_life = value + if("organ_health_multiplier") + config.organ_health_multiplier = value / 100 + if("organ_regeneration_multiplier") + config.organ_regeneration_multiplier = value / 100 + if("organ_damage_spillover_multiplier") + config.organ_damage_spillover_multiplier = value / 100 + if("organs_can_decay") + config.organs_decay = 1 + if("default_brain_health") + config.default_brain_health = text2num(value) + if(!config.default_brain_health || config.default_brain_health < 1) + config.default_brain_health = initial(config.default_brain_health) + if("bones_can_break") + config.bones_can_break = value + if("limbs_can_break") + config.limbs_can_break = value + if("allow_headgibs") + config.allow_headgibs = TRUE + + if("run_speed") + config.run_speed = value + if("walk_speed") + config.walk_speed = value + + if("human_delay") + config.human_delay = value + if("robot_delay") + config.robot_delay = value + if("monkey_delay") + config.monkey_delay = value + if("alien_delay") + config.alien_delay = value + if("slime_delay") + config.slime_delay = value + if("animal_delay") + config.animal_delay = value + + if("footstep_volume") + config.footstep_volume = text2num(value) + + if("use_loyalty_implants") + config.use_loyalty_implants = 1 + + else + log_misc("Unknown setting in configuration: '[name]'") + +/datum/configuration/proc/loadsql(filename) // -- TLE + var/list/Lines = file2list(filename) + for(var/t in Lines) + if(!t) continue + + t = trim(t) + if (length(t) == 0) + continue + else if (copytext(t, 1, 2) == "#") + continue + + var/pos = findtext(t, " ") + var/name = null + var/value = null + + if (pos) + name = lowertext(copytext(t, 1, pos)) + value = copytext(t, pos + 1) + else + name = lowertext(t) + + if (!name) + continue + + switch (name) + if ("address") + sqladdress = value + if ("port") + sqlport = value + if ("database") + sqldb = value + if ("login") + sqllogin = value + if ("password") + sqlpass = value + if ("feedback_database") + sqlfdbkdb = value + if ("feedback_login") + sqlfdbklogin = value + if ("feedback_password") + sqlfdbkpass = value + if ("enable_stat_tracking") + sqllogging = 1 + else + log_misc("Unknown setting in configuration: '[name]'") + +/datum/configuration/proc/loadforumsql(filename) // -- TLE + var/list/Lines = file2list(filename) + for(var/t in Lines) + if(!t) continue + + t = trim(t) + if (length(t) == 0) + continue + else if (copytext(t, 1, 2) == "#") + continue + + var/pos = findtext(t, " ") + var/name = null + var/value = null + + if (pos) + name = lowertext(copytext(t, 1, pos)) + value = copytext(t, pos + 1) + else + name = lowertext(t) + + if (!name) + continue + + switch (name) + if ("address") + forumsqladdress = value + if ("port") + forumsqlport = value + if ("database") + forumsqldb = value + if ("login") + forumsqllogin = value + if ("password") + forumsqlpass = value + if ("activatedgroup") + forum_activated_group = value + if ("authenticatedgroup") + forum_authenticated_group = value + else + log_misc("Unknown setting in configuration: '[name]'") + +/datum/configuration/proc/pick_mode(mode_name) + // I wish I didn't have to instance the game modes in order to look up + // their information, but it is the only way (at least that I know of). + for (var/game_mode in gamemode_cache) + var/datum/game_mode/M = gamemode_cache[game_mode] + if (M.config_tag && M.config_tag == mode_name) + return M + return gamemode_cache["extended"] + +/datum/configuration/proc/get_runnable_modes() + var/list/runnable_modes = list() + for(var/game_mode in gamemode_cache) + var/datum/game_mode/M = gamemode_cache[game_mode] + if(M && M.can_start() && !isnull(config.probabilities[M.config_tag]) && config.probabilities[M.config_tag] > 0) + runnable_modes |= M + return runnable_modes + +/datum/configuration/proc/post_load() + //apply a default value to config.python_path, if needed + if (!config.python_path) + if(world.system_type == UNIX) + config.python_path = "/usr/bin/env python2" + else //probably windows, if not this should work anyway + config.python_path = "python" diff --git a/code/controllers/configuration_vr.dm b/code/controllers/configuration_vr.dm index a91c04e517..a1740212f0 100644 --- a/code/controllers/configuration_vr.dm +++ b/code/controllers/configuration_vr.dm @@ -3,7 +3,6 @@ // /datum/configuration - var/static/list/engine_map // Comma separated list of engines to choose from. Blank means fully random. var/static/time_off = FALSE var/static/pto_job_change = FALSE var/static/limit_interns = -1 //Unlimited by default @@ -42,8 +41,6 @@ config.chat_webhook_url = value if ("chat_webhook_key") config.chat_webhook_key = value - if ("engine_map") - config.engine_map = splittext(value, ",") if ("fax_export_dir") config.fax_export_dir = value if ("items_survive_digestion") diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index e48b9f557f..b7f14bf74f 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -6,6 +6,12 @@ SUBSYSTEM_DEF(mapping) var/list/map_templates = list() var/dmm_suite/maploader = null + var/obj/effect/landmark/engine_loader/engine_loader + var/list/shelter_templates = list() + +/datum/controller/subsystem/mapping/Recover() + flags |= SS_NO_INIT // Make extra sure we don't initialize twice. + shelter_templates = SSmapping.shelter_templates /datum/controller/subsystem/mapping/Initialize(timeofday) if(subsystem_initialized) @@ -17,7 +23,15 @@ SUBSYSTEM_DEF(mapping) if(config.generate_map) // Map-gen is still very specific to the map, however putting it here should ensure it loads in the correct order. using_map.perform_map_generation() - + + loadEngine() + preloadShelterTemplates() // VOREStation EDIT: Re-enable Shelter Capsules + // Mining generation probably should be here too + // TODO - Other stuff related to maps and areas could be moved here too. Look at /tg + // Lateload Code related to Expedition areas. + if(using_map) // VOREStation Edit: Re-enable this. + loadLateMaps() + ..() /datum/controller/subsystem/mapping/proc/load_map_templates() for(var/T in subtypesof(/datum/map_template)) @@ -27,3 +41,84 @@ SUBSYSTEM_DEF(mapping) template = new T() map_templates[template.name] = template return TRUE + +/datum/controller/subsystem/mapping/proc/loadEngine() + if(!engine_loader) + return // Seems this map doesn't need an engine loaded. + + var/turf/T = get_turf(engine_loader) + if(!isturf(T)) + to_world_log("[log_info_line(engine_loader)] not on a turf! Cannot place engine template.") + return + + // Choose an engine type + var/datum/map_template/engine/chosen_type = null + if (LAZYLEN(config.engine_map)) + var/chosen_name = pick(config.engine_map) + chosen_type = map_templates[chosen_name] + if(!istype(chosen_type)) + error("Configured engine map [chosen_name] is not a valid engine map name!") + if(!istype(chosen_type)) + var/list/engine_types = list() + for(var/map in map_templates) + var/datum/map_template/engine/MT = map_templates[map] + if(istype(MT)) + engine_types += MT + chosen_type = pick(engine_types) + to_world_log("Chose Engine Map: [chosen_type.name]") + admin_notice("Chose Engine Map: [chosen_type.name]", R_DEBUG) + + // Annihilate movable atoms + engine_loader.annihilate_bounds() + //CHECK_TICK //Don't let anything else happen for now + // Actually load it + chosen_type.load(T) + +// VOREStation Edit Start: Enable This +/datum/controller/subsystem/mapping/proc/loadLateMaps() + var/list/deffo_load = using_map.lateload_z_levels + var/list/maybe_load = using_map.lateload_single_pick + + for(var/list/maplist in deffo_load) + if(!islist(maplist)) + error("Lateload Z level [maplist] is not a list! Must be in a list!") + continue + for(var/mapname in maplist) + var/datum/map_template/MT = map_templates[mapname] + if(!istype(MT)) + error("Lateload Z level \"[mapname]\" is not a valid map!") + continue + MT.load_new_z(centered = FALSE) + CHECK_TICK + + if(LAZYLEN(maybe_load)) + var/picklist = pick(maybe_load) + + if(!picklist) //No lateload maps at all + return + + if(!islist(picklist)) //So you can have a 'chain' of z-levels that make up one away mission + error("Randompick Z level [picklist] is not a list! Must be in a list!") + return + + for(var/map in picklist) + var/datum/map_template/MT = map_templates[map] + if(!istype(MT)) + error("Randompick Z level \"[map]\" is not a valid map!") + else + MT.load_new_z(centered = FALSE) + +/datum/controller/subsystem/mapping/proc/preloadShelterTemplates() + for(var/item in subtypesof(/datum/map_template/shelter)) + var/datum/map_template/shelter/shelter_type = item + if(!(initial(shelter_type.mappath))) + continue + var/datum/map_template/shelter/S = new shelter_type() + + shelter_templates[S.shelter_id] = S +// VOREStation Edit End: Re-enable this + +/datum/controller/subsystem/mapping/stat_entry(msg) + if (!Debug2) + return // Only show up in stat panel if debugging is enabled. + . = ..() \ No newline at end of file diff --git a/code/controllers/subsystems/mapping_vr.dm b/code/controllers/subsystems/mapping_vr.dm deleted file mode 100644 index a0eea82667..0000000000 --- a/code/controllers/subsystems/mapping_vr.dm +++ /dev/null @@ -1,126 +0,0 @@ -// -// Mapping subsystem handles initialization of random map elements at server start -// On VOREStation that means loading our random roundstart engine! -// -SUBSYSTEM_DEF(mapping) - name = "Mapping" - init_order = INIT_ORDER_MAPPING - flags = SS_NO_FIRE - - var/list/map_templates = list() - var/dmm_suite/maploader = null - var/obj/effect/landmark/engine_loader/engine_loader - var/obj/effect/landmark/engine_loader_pickable/engine_loader_pickable - - var/list/shelter_templates = list() - -/datum/controller/subsystem/mapping/Recover() - flags |= SS_NO_INIT // Make extra sure we don't initialize twice. - shelter_templates = SSmapping.shelter_templates - -/datum/controller/subsystem/mapping/Initialize(timeofday) - if(subsystem_initialized) - return - world.max_z_changed() // This is to set up the player z-level list, maxz hasn't actually changed (probably) - maploader = new() - load_map_templates() - - if(config.generate_map) - // Map-gen is still very specific to the map, however putting it here should ensure it loads in the correct order. - using_map.perform_map_generation() - - loadEngine() - preloadShelterTemplates() - // Mining generation probably should be here too - // TODO - Other stuff related to maps and areas could be moved here too. Look at /tg - if(using_map) - loadLateMaps() - ..() - -/datum/controller/subsystem/mapping/proc/load_map_templates() - for(var/T in subtypesof(/datum/map_template)) - var/datum/map_template/template = T - if(!(initial(template.mappath))) // If it's missing the actual path its probably a base type or being used for inheritence. - continue - template = new T() - map_templates[template.name] = template - return TRUE - -/datum/controller/subsystem/mapping/proc/loadEngine() - if(!engine_loader) - return // Seems this map doesn't need an engine loaded. - - var/turf/T = get_turf(engine_loader) - if(!isturf(T)) - to_world_log("[log_info_line(engine_loader)] not on a turf! Cannot place engine template.") - return - - // Choose an engine type - var/datum/map_template/engine/chosen_type = null - if (LAZYLEN(config.engine_map)) - var/chosen_name = pick(config.engine_map) - chosen_type = map_templates[chosen_name] - if(!istype(chosen_type)) - error("Configured engine map [chosen_name] is not a valid engine map name!") - if(!istype(chosen_type)) - var/list/engine_types = list() - for(var/map in map_templates) - var/datum/map_template/engine/MT = map_templates[map] - if(istype(MT)) - engine_types += MT - chosen_type = pick(engine_types) - to_world_log("Chose Engine Map: [chosen_type.name]") - admin_notice("Chose Engine Map: [chosen_type.name]", R_DEBUG) - - // Annihilate movable atoms - engine_loader.annihilate_bounds() - //CHECK_TICK //Don't let anything else happen for now - // Actually load it - chosen_type.load(T) - -/datum/controller/subsystem/mapping/proc/loadLateMaps() - var/list/deffo_load = using_map.lateload_z_levels - var/list/maybe_load = using_map.lateload_single_pick - - for(var/list/maplist in deffo_load) - if(!islist(maplist)) - error("Lateload Z level [maplist] is not a list! Must be in a list!") - continue - for(var/mapname in maplist) - var/datum/map_template/MT = map_templates[mapname] - if(!istype(MT)) - error("Lateload Z level \"[mapname]\" is not a valid map!") - continue - MT.load_new_z(centered = FALSE) - CHECK_TICK - - if(LAZYLEN(maybe_load)) - var/picklist = pick(maybe_load) - - if(!picklist) //No lateload maps at all - return - - if(!islist(picklist)) //So you can have a 'chain' of z-levels that make up one away mission - error("Randompick Z level [picklist] is not a list! Must be in a list!") - return - - for(var/map in picklist) - var/datum/map_template/MT = map_templates[map] - if(!istype(MT)) - error("Randompick Z level \"[map]\" is not a valid map!") - else - MT.load_new_z(centered = FALSE) - -/datum/controller/subsystem/mapping/proc/preloadShelterTemplates() - for(var/item in subtypesof(/datum/map_template/shelter)) - var/datum/map_template/shelter/shelter_type = item - if(!(initial(shelter_type.mappath))) - continue - var/datum/map_template/shelter/S = new shelter_type() - - shelter_templates[S.shelter_id] = S - -/datum/controller/subsystem/mapping/stat_entry(msg) - if (!Debug2) - return // Only show up in stat panel if debugging is enabled. - . = ..() diff --git a/code/modules/hydroponics/seed_controller.dm b/code/controllers/subsystems/plants.dm similarity index 70% rename from code/modules/hydroponics/seed_controller.dm rename to code/controllers/subsystems/plants.dm index 9b929b987e..e70f62d5fe 100644 --- a/code/modules/hydroponics/seed_controller.dm +++ b/code/controllers/subsystems/plants.dm @@ -1,32 +1,12 @@ -// Attempts to offload processing for the spreading plants from the MC. -// Processes vines/spreading plants. - -#define PLANTS_PER_TICK 500 // Cap on number of plant segments processed. #define PLANT_TICK_TIME 75 // Number of ticks between the plant processor cycling. -// Debug for testing seed genes. -/client/proc/show_plant_genes() - set category = "Debug" - set name = "Show Plant Genes" - set desc = "Prints the round's plant gene masks." +SUBSYSTEM_DEF(plants) + name = "Plants" + init_order = INIT_ORDER_PLANTS + priority = FIRE_PRIORITY_PLANTS + wait = PLANT_TICK_TIME - if(!holder) return - - if(!plant_controller || !plant_controller.gene_tag_masks) - to_chat(usr, "Gene masks not set.") - return - - for(var/mask in plant_controller.gene_tag_masks) - to_chat(usr, "[mask]: [plant_controller.gene_tag_masks[mask]]") - -var/global/datum/controller/plants/plant_controller // Set in New(). - -/datum/controller/plants - - var/plants_per_tick = PLANTS_PER_TICK - var/plant_tick_time = PLANT_TICK_TIME var/list/product_descs = list() // Stores generated fruit descs. - var/list/plant_queue = list() // All queued plants. var/list/seeds = list() // All seed data stored here. var/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness. var/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds. @@ -34,24 +14,26 @@ var/global/datum/controller/plants/plant_controller // Set in New(). var/list/accessible_plant_sprites = list() // List of all plant sprites allowed to appear in random generation. var/list/plant_product_sprites = list() // List of all harvested product sprites. var/list/accessible_product_sprites = list() // List of all product sprites allowed to appear in random generation. - var/processing = 0 // Off/on. var/list/gene_masked_list = list() // Stored gene masked list, rather than recreating it when needed. var/list/plant_gene_datums = list() // Stored datum versions of the gene masked list. -/datum/controller/plants/New() - if(plant_controller && plant_controller != src) - log_debug("Rebuilding plant controller.") - qdel(plant_controller) - plant_controller = src + // To be clear, the only thing this processes are spreading plants + // Hydro trays and growing food normally just chill in SSobj + var/list/processing = list() + var/list/currentrun = list() + +/datum/controller/subsystem/plants/stat_entry() + ..("P:[processing.len]|S:[seeds.len]") + +/datum/controller/subsystem/plants/Initialize(timeofday) setup() - process() + return ..() // Predefined/roundstart varieties use a string key to make it // easier to grab the new variety when mutating. Post-roundstart // and mutant varieties use their uid converted to a string instead. // Looks like shit but it's sort of necessary. -/datum/controller/plants/proc/setup() - +/datum/controller/subsystem/plants/proc/setup() // Build the icon lists. for(var/icostate in cached_icon_states('icons/obj/hydroponics_growing.dmi')) var/split = findtext(icostate,"-") @@ -116,10 +98,10 @@ var/global/datum/controller/plants/plant_controller // Set in New(). gene_masked_list.Add(list(list("tag" = gene_tag, "mask" = gene_mask))) // Proc for creating a random seed type. -/datum/controller/plants/proc/create_random_seed(var/survive_on_station) +/datum/controller/subsystem/plants/proc/create_random_seed(var/survive_on_station) var/datum/seed/seed = new() seed.randomize() - seed.uid = plant_controller.seeds.len + 1 + seed.uid = SSplants.seeds.len + 1 seed.name = "[seed.uid]" seeds[seed.name] = seed @@ -138,32 +120,41 @@ var/global/datum/controller/plants/plant_controller // Set in New(). seed.set_trait(TRAIT_HIGHKPA_TOLERANCE,200) return seed -/datum/controller/plants/process() - processing = 1 - spawn(0) - set background = 1 - var/processed = 0 - while(1) - if(!processing) - sleep(plant_tick_time) - else - processed = 0 - if(plant_queue.len) - var/target_to_process = min(plant_queue.len,plants_per_tick) - for(var/x=0;xWelcome to the pregame lobby!") to_world("Please set up your character and select ready. The round will start in [pregame_timeleft] seconds.") + world << sound('sound/misc/server-ready.ogg', volume = 100) // Called during GAME_STATE_PREGAME (RUNLEVEL_LOBBY) /datum/controller/subsystem/ticker/proc/pregame_tick() @@ -402,20 +403,23 @@ var/global/datum/controller/subsystem/ticker/ticker for(var/mob/new_player/player in player_list) if(player && player.ready && player.mind?.assigned_role) var/datum/job/J = SSjob.get_job(player.mind.assigned_role) - + // Snowflakey AI treatment if(J?.mob_type & JOB_SILICON_AI) player.close_spawn_windows() player.AIize(move = TRUE) continue - + // Ask their new_player mob to spawn them if(!player.spawn_checks_vr(player.mind.assigned_role)) continue //VOREStation Add var/mob/living/carbon/human/new_char = player.create_character() - + // Created their playable character, delete their /mob/new_player if(new_char) qdel(player) + if(new_char.client) + var/obj/screen/splash/S = new(new_char.client, TRUE) + S.Fade(TRUE) // If they're a carbon, they can get manifested if(J?.mob_type & JOB_CARBON) @@ -431,7 +435,7 @@ var/global/datum/controller/subsystem/ticker/ticker var/captainless=1 for(var/mob/living/carbon/human/player in player_list) if(player && player.mind && player.mind.assigned_role) - if(player.mind.assigned_role == "Colony Director") + if(player.mind.assigned_role == "Site Manager") captainless=0 if(!player_is_antag(player.mind, only_offstation_roles = 1)) job_master.EquipRank(player, player.mind.assigned_role, 0) @@ -441,7 +445,7 @@ var/global/datum/controller/subsystem/ticker/ticker if(captainless) for(var/mob/M in player_list) if(!istype(M,/mob/new_player)) - to_chat(M, "Colony Directorship not forced on anyone.") + to_chat(M, "Site Management is not forced on anyone.") /datum/controller/subsystem/ticker/proc/declare_completion() diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index df1aa91ea3..58a66923c4 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -97,7 +97,6 @@ options["LEGACY: cameranet"] = cameranet options["LEGACY: transfer_controller"] = transfer_controller options["LEGACY: gas_data"] = gas_data - options["LEGACY: plant_controller"] = plant_controller var/pick = input(mob, "Choose a controller to debug/view variables of.", "VV controller:") as null|anything in options if(!pick) diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm index 53a2f14fac..169232d845 100644 --- a/code/datums/autolathe/arms.dm +++ b/code/datums/autolathe/arms.dm @@ -48,7 +48,7 @@ /datum/category_item/autolathe/arms/pistol_5mm name = "pistol magazine (5mm)" path =/obj/item/ammo_magazine/c5mm - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 */ @@ -237,93 +237,93 @@ /datum/category_item/autolathe/arms/pistol_5mm name = "pistol magazine (5mm)" path =/obj/item/ammo_magazine/c5mm/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/smg_5mm name = "top-mounted SMG magazine (5mm)" path =/obj/item/ammo_magazine/c5mmt/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/pistol_45 name = "pistol magazine (.45)" path =/obj/item/ammo_magazine/m45/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/pistol_45uzi name = "uzi magazine (.45)" path =/obj/item/ammo_magazine/m45uzi/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/tommymag name = "Tommy Gun magazine (.45)" path =/obj/item/ammo_magazine/m45tommy/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/tommydrum name = "Tommy Gun drum magazine (.45)" path =/obj/item/ammo_magazine/m45tommydrum/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/pistol_9mm name = "pistol magazine (9mm)" path =/obj/item/ammo_magazine/m9mm/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/smg_9mm name = "top-mounted SMG magazine (9mm)" path =/obj/item/ammo_magazine/m9mmt/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/smg_10mm name = "SMG magazine (10mm)" path =/obj/item/ammo_magazine/m10mm/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/pistol_44 name = "pistol magazine (.44)" path =/obj/item/ammo_magazine/m44/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/rifle_545 name = "10rnd rifle magazine (5.45mm)" path =/obj/item/ammo_magazine/m545saw/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/rifle_545m name = "20rnd rifle magazine (5.45mm)" path =/obj/item/ammo_magazine/m545sawm/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/rifle_SVD name = "10rnd rifle magazine (7.62mm)" path =/obj/item/ammo_magazine/m762svd/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/rifle_762 name = "20rnd rifle magazine (7.62mm)" path =/obj/item/ammo_magazine/m762/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/machinegun_762 name = "machinegun box magazine (7.62)" path =/obj/item/ammo_magazine/a762/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/shotgun_magazine name = "24rnd shotgun magazine (12g)" path =/obj/item/ammo_magazine/m12gdrum/empty - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1*/ /////////////////////////////// @@ -357,73 +357,73 @@ /*/datum/category_item/autolathe/arms/pistol_clip_45 name = "ammo clip (.45)" path =/obj/item/ammo_magazine/clip/c45 - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/pistol_clip_45r name = "ammo clip (.45 rubber)" path =/obj/item/ammo_magazine/clip/c45/rubber - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/pistol_clip_45f name = "ammo clip (.45 flash)" path =/obj/item/ammo_magazine/clip/c45/flash - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/pistol_clip_45p name = "ammo clip (.45 practice)" path =/obj/item/ammo_magazine/clip/c45/practice - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/pistol_clip_9mm name = "ammo clip (9mm)" path =/obj/item/ammo_magazine/clip/c9mm - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/pistol_clip_9mmr name = "ammo clip (9mm rubber)" path =/obj/item/ammo_magazine/clip/c9mm/rubber - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/pistol_clip_9mmp name = "ammo clip (9mm practice)" path =/obj/item/ammo_magazine/clip/c9mm/practice - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/pistol_clip_9mmf name = "ammo clip (9mm flash)" path =/obj/item/ammo_magazine/clip/c9mm/flash - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/pistol_clip_5mm name = "ammo clip (5mm)" path =/obj/item/ammo_magazine/clip/c5mm - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/pistol_clip_10mm name = "ammo clip (10mm)" path =/obj/item/ammo_magazine/clip/c10mm - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/pistol_clip_50 name = "ammo clip (.44)" path =/obj/item/ammo_magazine/clip/c50 - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 */ /datum/category_item/autolathe/arms/rifle_clip_545 name = "ammo clip (5.45mm)" path =/obj/item/ammo_magazine/clip/c545 - category = "Arms and Ammunition" + category = list("Arms and Ammunition") hidden = 1 /datum/category_item/autolathe/arms/rifle_clip_545_practice name = "ammo clip (5.45mm practice)" path =/obj/item/ammo_magazine/clip/c545/practice - category = "Arms and Ammunition" + category = list("Arms and Ammunition") /datum/category_item/autolathe/arms/rifle_clip_762 name = "ammo clip (7.62mm)" diff --git a/code/datums/autolathe/autolathe.dm b/code/datums/autolathe/autolathe.dm index 003212fe75..4af1abfccd 100644 --- a/code/datums/autolathe/autolathe.dm +++ b/code/datums/autolathe/autolathe.dm @@ -1,5 +1,3 @@ -var/datum/category_collection/autolathe/autolathe_recipes - /datum/category_item/autolathe/New() ..() var/obj/item/I = new path() diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index bb9372749a..5046575b0b 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -218,7 +218,7 @@ var/global/list/PDA_Manifest = list() heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive) department = 1 depthead = 1 - if(rank=="Colony Director" && heads.len != 1) + if(rank=="Site Manager" && heads.len != 1) heads.Swap(1,heads.len) if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SECURITY)) diff --git a/code/datums/looping_sounds/_looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm index 99af50bf42..b16f9ddc35 100644 --- a/code/datums/looping_sounds/_looping_sound.dm +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -28,6 +28,8 @@ var/volume = 100 var/max_loops var/direct + var/vary + var/extra_range var/opacity_check var/pref_check @@ -89,7 +91,7 @@ continue SEND_SOUND(thing, S) else - playsound(thing, S, volume, ignore_walls = !opacity_check, preference = pref_check) + playsound(thing, S, volume, vary, extra_range, ignore_walls = !opacity_check, preference = pref_check) /datum/looping_sound/proc/get_sound(starttime, _mid_sounds) if(!_mid_sounds) diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index e8b0c2aa78..0330811428 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -9,9 +9,10 @@ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/looping_sound/supermatter - mid_sounds = list('sound/machines/sm/supermatter1.ogg'=1,'sound/machines/sm/supermatter2.ogg'=1,'sound/machines/sm/supermatter3.ogg'=1) - mid_length = 10 - volume = 1 + mid_sounds = list('sound/machines/sm/loops/calm.ogg'=1) + mid_length = 60 + volume = 40 + extra_range = 10 pref_check = /datum/client_preference/supermatter_hum /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -28,25 +29,74 @@ /datum/looping_sound/deep_fryer - start_sound = 'sound/machines/fryer/deep_fryer_immerse.ogg' //my immersions + start_sound = 'sound/machines/kitchen/fryer/deep_fryer_immerse.ogg' //my immersions start_length = 10 - mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1) + mid_sounds = list('sound/machines/kitchen/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/kitchen/fryer/deep_fryer_2.ogg' = 1) mid_length = 2 - end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg' + end_sound = 'sound/machines/kitchen/fryer/deep_fryer_emerge.ogg' volume = 15 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/looping_sound/microwave - start_sound = 'sound/machines/microwave/microwave-start.ogg' + start_sound = 'sound/machines/kitchen/microwave/microwave-start.ogg' start_length = 10 - mid_sounds = list('sound/machines/microwave/microwave-mid1.ogg'=10, 'sound/machines/microwave/microwave-mid2.ogg'=1) + mid_sounds = list('sound/machines/kitchen/microwave/microwave-mid1.ogg'=10, 'sound/machines/kitchen/microwave/microwave-mid2.ogg'=1) mid_length = 10 - end_sound = 'sound/machines/microwave/microwave-end.ogg' + end_sound = 'sound/machines/kitchen/microwave/microwave-end.ogg' volume = 90 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/datum/looping_sound/oven + start_sound = 'sound/machines/kitchen/oven/oven-start.ogg' + start_length = 10 + mid_sounds = list('sound/machines/kitchen/oven/oven-mid1.ogg'=10) + mid_length = 40 + end_sound = 'sound/machines/kitchen/oven/oven-stop.ogg' + volume = 50 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/grill + start_sound = 'sound/machines/kitchen/grill/grill-start.ogg' + start_length = 10 + mid_sounds = list('sound/machines/kitchen/grill/grill-mid1.ogg'=10) + mid_length = 40 + end_sound = 'sound/machines/kitchen/grill/grill-stop.ogg' + volume = 50 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/mixer + start_sound = 'sound/machines/kitchen/mixer/mixer-start.ogg' + start_length = 10 + mid_sounds = list('sound/machines/kitchen/mixer/mixer-mid1.ogg'=10) + mid_length = 10 + end_sound = 'sound/machines/kitchen/mixer/mixer-stop.ogg' + volume = 50 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/cerealmaker + start_sound = 'sound/machines/kitchen/cerealmaker/cerealmaker-start.ogg' + start_length = 10 + mid_sounds = list('sound/machines/kitchen/cerealmaker/cerealmaker-mid1.ogg'=10) + mid_length = 60 + end_sound = 'sound/machines/kitchen/cerealmaker/cerealmaker-stop.ogg' + volume = 50 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/candymaker + start_sound = 'sound/machines/kitchen/candymaker/candymaker-start.ogg' + start_length = 10 + mid_sounds = list('sound/machines/kitchen/candymaker/candymaker-mid1.ogg'=10) + mid_length = 40 + end_sound = 'sound/machines/kitchen/candymaker/candymaker-stop.ogg' + volume = 20 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/looping_sound/air_pump start_sound = 'sound/machines/air_pump/airpumpstart.ogg' start_length = 10 diff --git a/code/datums/supplypacks/atmospherics.dm b/code/datums/supplypacks/atmospherics.dm index fb5d4a0e59..3630b9bea0 100644 --- a/code/datums/supplypacks/atmospherics.dm +++ b/code/datums/supplypacks/atmospherics.dm @@ -50,13 +50,13 @@ access = access_atmospherics contains = list(/obj/machinery/portable_atmospherics/canister/phoron) -/datum/supply_pack/atmos/canister_sleeping_agent +/datum/supply_pack/atmos/canister_nitrous_oxide name = "N2O gas canister" cost = 15 containername = "N2O gas canister crate" containertype = /obj/structure/closet/crate/secure/large/aether access = access_atmospherics - contains = list(/obj/machinery/portable_atmospherics/canister/sleeping_agent) + contains = list(/obj/machinery/portable_atmospherics/canister/nitrous_oxide) /datum/supply_pack/atmos/canister_carbon_dioxide name = "Carbon dioxide gas canister" diff --git a/code/datums/supplypacks/costumes.dm b/code/datums/supplypacks/costumes.dm index f9b61d9572..9afd0fd60f 100644 --- a/code/datums/supplypacks/costumes.dm +++ b/code/datums/supplypacks/costumes.dm @@ -101,7 +101,7 @@ /obj/item/clothing/under/lawyer/bluesuit, /obj/item/clothing/under/lawyer/purpsuit, /obj/item/clothing/shoes/black = 2, - /obj/item/clothing/shoes/leather, + /obj/item/clothing/shoes/laceup/brown, /obj/item/clothing/accessory/wcoat ) name = "Formalwear (Suits)" diff --git a/code/datums/supplypacks/costumes_vr.dm b/code/datums/supplypacks/costumes_vr.dm index 080ebb5457..995e935648 100644 --- a/code/datums/supplypacks/costumes_vr.dm +++ b/code/datums/supplypacks/costumes_vr.dm @@ -174,7 +174,7 @@ /obj/item/clothing/under/pants/chaps, /obj/item/clothing/under/pants/chaps/black, /obj/item/clothing/under/harness, - /obj/item/clothing/shoes/leather, + /obj/item/clothing/shoes/laceup/brown, /obj/item/clothing/shoes/boots/jungle, /obj/item/clothing/shoes/boots/jackboots, /obj/item/clothing/shoes/boots/cowboy, @@ -261,4 +261,24 @@ ) cost = 60 containertype = /obj/structure/closet/crate - containername = "Saddlebags crate" \ No newline at end of file + containername = "Saddlebags crate" + +/datum/supply_pack/costumes/knights_gear + name = "Knights Gear" + contains = list( + /obj/item/clothing/suit/storage/hooded/knight_costume, + /obj/item/clothing/suit/storage/hooded/knight_costume/galahad, + /obj/item/clothing/suit/storage/hooded/knight_costume/lancelot, + /obj/item/clothing/suit/storage/hooded/knight_costume/robin, + /obj/item/clothing/suit/armor/combat/crusader_costume, + /obj/item/clothing/suit/armor/combat/crusader_costume/bedevere, + /obj/item/clothing/head/helmet/combat/crusader_costume, + /obj/item/clothing/head/helmet/combat/bedevere_costume, + /obj/item/clothing/gloves/combat/knight_costume, + /obj/item/clothing/gloves/combat/knight_costume/brown, + /obj/item/clothing/shoes/knight_costume, + /obj/item/clothing/shoes/knight_costume/black + ) + cost = 10 + containertype = /obj/structure/closet/crate + containername = "Knights Gear Crate" \ No newline at end of file diff --git a/code/datums/supplypacks/hospitality.dm b/code/datums/supplypacks/hospitality.dm index c776317ffa..2771caa538 100644 --- a/code/datums/supplypacks/hospitality.dm +++ b/code/datums/supplypacks/hospitality.dm @@ -54,19 +54,12 @@ containertype = /obj/structure/largecrate containername = "cooking oil tank crate" -/datum/supply_pack/randomised/hospitality/ - group = "Hospitality" - -/datum/supply_pack/randomised/hospitality/pizza +/datum/supply_pack/hospitality/pizza + name = "Surprise pack of five pizzas" contains = list( - /obj/random/pizzabox, - /obj/random/pizzabox, - /obj/random/pizzabox, - /obj/random/pizzabox, - /obj/random/pizzabox, + /obj/random/pizzabox = 5, /obj/item/weapon/material/knife/plastic ) - name = "Surprise pack of five pizzas" cost = 15 containertype = /obj/structure/closet/crate/freezer/centauri containername = "Pizza crate" @@ -83,4 +76,8 @@ ) cost = 10 containertype = /obj/structure/closet/crate/allico - containername = "crate of gifts" \ No newline at end of file + containername = "crate of gifts" + +/datum/supply_pack/randomised/hospitality/ + group = "Hospitality" + diff --git a/code/datums/wires/autolathe.dm b/code/datums/wires/autolathe.dm index 92f5f7facb..fd71958caa 100644 --- a/code/datums/wires/autolathe.dm +++ b/code/datums/wires/autolathe.dm @@ -25,6 +25,7 @@ switch(wire) if(WIRE_AUTOLATHE_HACK) A.hacked = !mend + A.update_tgui_static_data(usr) if(WIRE_ELECTRIFY) A.shocked = !mend if(WIRE_AUTOLATHE_DISABLE) @@ -38,9 +39,11 @@ switch(wire) if(WIRE_AUTOLATHE_HACK) A.hacked = !A.hacked + A.update_tgui_static_data(usr) spawn(50) if(A && !is_cut(wire)) A.hacked = 0 + A.update_tgui_static_data(usr) if(WIRE_ELECTRIFY) A.shocked = !A.shocked spawn(50) diff --git a/code/defines/gases.dm b/code/defines/gases.dm index 14b5e3a7c0..8b56b5bf45 100644 --- a/code/defines/gases.dm +++ b/code/defines/gases.dm @@ -43,12 +43,12 @@ flags = XGM_GAS_FUEL -/decl/xgm_gas/sleeping_agent - id = "sleeping_agent" - name = "Sleeping Agent" +/decl/xgm_gas/nitrous_oxide + id = "nitrous_oxide" + name = "Nitrous Oxide" specific_heat = 40 // J/(mol*K) molar_mass = 0.044 // kg/mol. N2O - tile_overlay = "sleeping_agent" + tile_overlay = "nitrous_oxide" overlay_limit = 1 flags = XGM_GAS_OXIDIZER \ No newline at end of file diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 062d81b265..9778492615 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -127,6 +127,7 @@ throw_speed = 1 throw_range = 20 drop_sound = 'sound/items/drop/rubber.ogg' + pickup_sound = 'sound/items/pickup/rubber.ogg' afterattack(atom/target as mob|obj|turf|area, mob/user as mob) user.drop_item() diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index a90104de19..7efbb84c20 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -79,6 +79,8 @@ /obj/item/weapon/disk name = "disk" icon = 'icons/obj/discs_vr.dmi' //VOREStation Edit + drop_sound = 'sound/items/drop/disk.ogg' + pickup_sound = 'sound/items/pickup/disk.ogg' /obj/item/weapon/disk/nuclear name = "nuclear authentication disk" diff --git a/code/game/antagonist/mutiny/mutineer.dm b/code/game/antagonist/mutiny/mutineer.dm index b08931b61d..480fc83c70 100644 --- a/code/game/antagonist/mutiny/mutineer.dm +++ b/code/game/antagonist/mutiny/mutineer.dm @@ -6,7 +6,7 @@ var/datum/antagonist/mutineer/mutineers role_text_plural = "Mutineers" id = MODE_MUTINEER antag_indicator = "mutineer" - restricted_jobs = list("Colony Director") + restricted_jobs = list("Site Manager") /datum/antagonist/mutineer/New(var/no_reference) ..() @@ -39,7 +39,7 @@ var/datum/antagonist/mutineer/mutineers proc/get_head_loyalist_candidates() var/list/candidates[0] for(var/mob/loyalist in player_list) - if(loyalist.mind && loyalist.mind.assigned_role == "Colony Director") + if(loyalist.mind && loyalist.mind.assigned_role == "Site Manager") candidates.Add(loyalist.mind) return candidates @@ -47,7 +47,7 @@ var/datum/antagonist/mutineer/mutineers var/list/candidates[0] for(var/mob/mutineer in player_list) if(mutineer.client.prefs.be_special & BE_MUTINEER) - for(var/job in command_positions - "Colony Director") + for(var/job in command_positions - "Site Manager") if(mutineer.mind && mutineer.mind.assigned_role == job) candidates.Add(mutineer.mind) return candidates diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm index 8b3301afc7..f1d1aeee4f 100644 --- a/code/game/antagonist/outsider/ert.dm +++ b/code/game/antagonist/outsider/ert.dm @@ -14,7 +14,7 @@ var/datum/antagonist/ert/ert and before taking extreme actions, please try to also contact the administration! \ Think through your actions and make the roleplay immersive! Please remember all \ rules aside from those without explicit exceptions apply to the ERT." - leader_welcome_text = "As leader of the Emergency Response Team, you answer only to the Company, and have authority to override the Colony Director where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the Colony Director where possible, however." + leader_welcome_text = "As leader of the Emergency Response Team, you answer only to the Company, and have authority to override the Site Manager where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the Site Manager where possible, however." landmark_id = "Response Team" id_type = /obj/item/weapon/card/id/centcom/ERT diff --git a/code/game/antagonist/station/changeling.dm b/code/game/antagonist/station/changeling.dm index 694c4a3634..2c1cb77f26 100644 --- a/code/game/antagonist/station/changeling.dm +++ b/code/game/antagonist/station/changeling.dm @@ -6,7 +6,7 @@ bantype = "changeling" feedback_tag = "changeling_objective" avoid_silicons = TRUE - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Colony Director") + protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Site Manager") welcome_text = "Use say \"#g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them." antag_sound = 'sound/effects/antag_notice/ling_alert.ogg' flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm index 06aab654b4..57271900b1 100644 --- a/code/game/antagonist/station/cultist.dm +++ b/code/game/antagonist/station/cultist.dm @@ -13,8 +13,8 @@ var/datum/antagonist/cultist/cult bantype = "cultist" restricted_jobs = list("Chaplain") avoid_silicons = TRUE - protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director") - roundstart_restricted = list("Internal Affairs Agent", "Head of Security", "Colony Director") + protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Site Manager") + roundstart_restricted = list("Internal Affairs Agent", "Head of Security", "Site Manager") role_type = BE_CULTIST feedback_tag = "cult_objective" antag_indicator = "cult" diff --git a/code/game/antagonist/station/infiltrator.dm b/code/game/antagonist/station/infiltrator.dm index 2a1ad74025..f3e7f8a149 100644 --- a/code/game/antagonist/station/infiltrator.dm +++ b/code/game/antagonist/station/infiltrator.dm @@ -11,7 +11,7 @@ var/datum/antagonist/traitor/infiltrator/infiltrators role_text = "Infiltrator" role_text_plural = "Infiltrators" welcome_text = "To speak on your team's private channel, use :t." - protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director") + protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Site Manager") flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE can_speak_aooc = TRUE diff --git a/code/game/antagonist/station/revolutionary.dm b/code/game/antagonist/station/revolutionary.dm index 1db40f396a..8f6a7c79e9 100644 --- a/code/game/antagonist/station/revolutionary.dm +++ b/code/game/antagonist/station/revolutionary.dm @@ -30,8 +30,8 @@ var/datum/antagonist/revolutionary/revs faction_invisible = 1 avoid_silicons = TRUE - protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Colony Director", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") - roundstart_restricted = list("Internal Affairs Agent", "Colony Director", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") + protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Site Manager", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") + roundstart_restricted = list("Internal Affairs Agent", "Site Manager", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") /datum/antagonist/revolutionary/New() ..() diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm index 23d0758e8b..f01784c048 100644 --- a/code/game/antagonist/station/traitor.dm +++ b/code/game/antagonist/station/traitor.dm @@ -4,7 +4,7 @@ var/datum/antagonist/traitor/traitors /datum/antagonist/traitor id = MODE_TRAITOR antag_sound = 'sound/effects/antag_notice/traitor_alert.ogg' - protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director") + protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Site Manager") flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE can_speak_aooc = FALSE // If they want to plot and plan as this sort of traitor, they'll need to do it ICly. diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 554ab4d9b6..a12a80e6ec 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -289,6 +289,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/centcom/bathroom name = "\improper CentCom Bathroom" icon_state = "centcom_crew" + sound_env = SMALL_ENCLOSED //SYNDICATES @@ -745,6 +746,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Substation" icon_state = "substation" sound_env = SMALL_ENCLOSED + ambience = AMBIENCE_SUBSTATION /area/maintenance/substation/engineering // Probably will be connected to engineering SMES room, as wires cannot be crossed properly without them sharing powernets. name = "Engineering Substation" @@ -959,7 +961,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station sound_env = MEDIUM_SOFTFLOOR /area/crew_quarters/captain - name = "\improper Command - Colony Director's Office" + name = "\improper Command - Site Manager's Office" icon_state = "captain" sound_env = MEDIUM_SOFTFLOOR @@ -1216,6 +1218,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/recreation_area_restroom name = "\improper Recreation Area Restroom" icon_state = "recreation_area_restroom" + sound_env = SMALL_ENCLOSED /area/crew_quarters/pool name = "\improper Pool" @@ -1241,6 +1244,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/barrestroom name = "\improper Cafeteria Restroom" icon_state = "bar" + sound_env = SMALL_ENCLOSED /area/crew_quarters/theatre name = "\improper Theatre" @@ -1390,6 +1394,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "\improper Atmospherics" icon_state = "atmos" sound_env = LARGE_ENCLOSED + ambience = AMBIENCE_ATMOS /area/engineering/atmos/monitoring name = "\improper Atmospherics Monitoring Room" @@ -1613,6 +1618,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/medical_restroom name = "\improper Medbay Restroom" icon_state = "medbay_restroom" + sound_env = SMALL_ENCLOSED /area/medical/patients_rooms name = "\improper Patient's Rooms" @@ -1806,6 +1812,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/security/security_bathroom name = "\improper Security - Restroom" icon_state = "security_bathroom" + sound_env = SMALL_ENCLOSED /area/security/security_cell_hallway name = "\improper Security - Cell Hallway" @@ -1954,6 +1961,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/rnd/research_restroom name = "\improper Research Restroom" icon_state = "research_restroom" + sound_env = SMALL_ENCLOSED /area/rnd/research_storage name = "\improper Research Storage" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1229a0a9cb..b56db48dab 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -488,7 +488,7 @@ // Use for objects performing visible actions // message is output to anyone who can see, e.g. "The [src] does something!" // blind_message (optional) is what blind people will hear e.g. "You hear something!" -/atom/proc/visible_message(var/message, var/blind_message) +/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs = null) //VOREStation Edit var/list/see @@ -501,6 +501,8 @@ var/list/seeing_mobs = see["mobs"] var/list/seeing_objs = see["objs"] + if(LAZYLEN(exclude_mobs)) + seeing_mobs -= exclude_mobs for(var/obj in seeing_objs) var/obj/O = obj diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 827e9730da..df3750275d 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -7,6 +7,8 @@ force = 30 throwforce = 10 hitsound = 'sound/weapons/bladeslice.ogg' + drop_sound = 'sound/items/drop/sword.ogg' + pickup_sound = 'sound/items/pickup/sword.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") edge = 1 sharp = 1 diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 0136314d58..89abedd726 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -297,9 +297,9 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is M.add_ion_law("HUMANS NEED TO EAT [what2pref] [what2] TO SURVIVE") if(5) to_chat(M, "
") - to_chat(M, "THE COLONY DIRECTOR, HOP AND HOS ARE [who2]...LAWS UPDATED") + to_chat(M, "THE SITE MANAGER, HOP AND HOS ARE [who2]...LAWS UPDATED") to_chat(M, "
") - M.add_ion_law("THE COLONY DIRECTOR, HOP AND HOS ARE [who2]") + M.add_ion_law("THE SITE MANAGER, HOP AND HOS ARE [who2]") if(6) to_chat(M, "
") to_chat(M, "THE STATION IS BUILT FOR [who2]...LAWS UPDATED") diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index 575d48d06a..b185208fbd 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -564,7 +564,7 @@ datum captainslaser steal_target = /obj/item/weapon/gun/energy/captain - explanation_text = "Steal the Colony Director's antique laser gun." + explanation_text = "Steal the Site Manager's antique laser gun." weight = 20 get_points(var/job) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index a410ebfe24..2834b81cbd 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -427,11 +427,11 @@ datum/objective/steal var/target_name var/global/possible_items[] = list( - "the Colony Director's antique laser gun" = /obj/item/weapon/gun/energy/captain, + "the Site Manager's antique laser gun" = /obj/item/weapon/gun/energy/captain, "a hand teleporter" = /obj/item/weapon/hand_tele, "an RCD" = /obj/item/weapon/rcd, "a jetpack" = /obj/item/weapon/tank/jetpack, - "a colony director's jumpsuit" = /obj/item/clothing/under/rank/captain, + "a site manager's jumpsuit" = /obj/item/clothing/under/rank/captain, "a functional AI" = /obj/item/device/aicard, "a pair of magboots" = /obj/item/clothing/shoes/magboots, "the station blueprints" = /obj/item/blueprints, @@ -445,7 +445,7 @@ datum/objective/steal "a head of security's jumpsuit" = /obj/item/clothing/under/rank/head_of_security, "a head of personnel's jumpsuit" = /obj/item/clothing/under/rank/head_of_personnel, "the hypospray" = /obj/item/weapon/reagent_containers/hypospray/vial, - "the colony director's pinpointer" = /obj/item/weapon/pinpointer, + "the site manager's pinpointer" = /obj/item/weapon/pinpointer, "an ablative armor vest" = /obj/item/clothing/suit/armor/laserproof, ) diff --git a/code/game/gamemodes/technomancer/spells/audible_deception.dm b/code/game/gamemodes/technomancer/spells/audible_deception.dm index 8faff2b4e6..fc67ba1ee3 100644 --- a/code/game/gamemodes/technomancer/spells/audible_deception.dm +++ b/code/game/gamemodes/technomancer/spells/audible_deception.dm @@ -25,8 +25,8 @@ "Glass Shattering" = "shatter", "Grille Damage" = 'sound/effects/grillehit.ogg', "Energy Pulse" = 'sound/effects/EMPulse.ogg', - "Airlock" = 'sound/machines/airlock.ogg', - "Airlock Creak" = 'sound/machines/airlock_creaking.ogg', + "Airlock" = 'sound/machines/door/old_airlock.ogg', + "Airlock Creak" = 'sound/machines/door/airlock_creaking.ogg', "Shotgun Pumping" = 'sound/weapons/shotgunpump.ogg', "Flash" = 'sound/weapons/flash.ogg', diff --git a/code/game/jobs/access_datum.dm b/code/game/jobs/access_datum.dm index e6c407eaec..5a2e3bd0cf 100644 --- a/code/game/jobs/access_datum.dm +++ b/code/game/jobs/access_datum.dm @@ -127,7 +127,7 @@ /var/const/access_captain = 20 /datum/access/captain id = access_captain - desc = "Colony Director" + desc = "Site Manager" region = ACCESS_REGION_COMMAND /var/const/access_all_personal_lockers = 21 diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index aa57aa84fd..e767bb5c35 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -5,7 +5,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) ////////////////////////////////// /datum/job/captain - title = "Colony Director" + title = "Site Manager" flag = CAPTAIN departments = list(DEPARTMENT_COMMAND) sorting_order = 3 // Above everyone. @@ -26,11 +26,10 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) ideal_character_age = 70 // Old geezer captains ftw outfit_type = /decl/hierarchy/outfit/job/captain - job_description = "The Colony Director manages the other Command Staff, and through them the rest of the station. Though they have access to everything, \ - they do not understand everything, and are expected to delegate tasks to the appropriate crew member. The Colony Director is expected to \ + job_description = "The Site Manager manages the other Command Staff, and through them the rest of the station. Though they have access to everything, \ + they do not understand everything, and are expected to delegate tasks to the appropriate crew member. The Site Manager is expected to \ have an understanding of Standard Operating Procedure, and is subject to it, and legal action, in the same way as every other crew member." - alt_titles = list("Site Manager" = /datum/alt_title/site_manager, - "Overseer" = /datum/alt_title/overseer) + alt_titles = list("Overseer"= /datum/alt_title/overseer) //YW UNCOMMENTINGSTART: REINSTATE LOYALTY IMPLANT /datum/job/captain/equip(var/mob/living/carbon/human/H) @@ -45,9 +44,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) // Captain Alt Titles -/datum/alt_title/site_manager - title = "Site Manager" - /datum/alt_title/overseer title = "Overseer" @@ -64,7 +60,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) faction = "Station" total_positions = 1 spawn_positions = 1 - supervisors = "the Colony Director" + supervisors = "the Site Manager" selection_color = "#1D1D4F" req_admin_notify = 1 minimal_player_age = 10 diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index 285c3dc814..ae937d106b 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -11,7 +11,7 @@ faction = "Station" total_positions = 1 spawn_positions = 1 - supervisors = "the Colony Director" + supervisors = "the Site Manager" selection_color = "#7F6E2C" req_admin_notify = 1 economic_modifier = 10 diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index d276c96648..e74b0798b6 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -11,7 +11,7 @@ faction = "Station" total_positions = 1 spawn_positions = 1 - supervisors = "the Colony Director" + supervisors = "the Site Manager" selection_color = "#026865" req_admin_notify = 1 economic_modifier = 10 diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 1154d487bc..d82ce3f148 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -11,7 +11,7 @@ faction = "Station" total_positions = 1 spawn_positions = 1 - supervisors = "the Colony Director" + supervisors = "the Site Manager" selection_color = "#AD6BAD" req_admin_notify = 1 economic_modifier = 15 diff --git a/code/game/jobs/job/science_vr.dm b/code/game/jobs/job/science_vr.dm index 15d427663b..998f057340 100644 --- a/code/game/jobs/job/science_vr.dm +++ b/code/game/jobs/job/science_vr.dm @@ -20,6 +20,11 @@ alt_titles = list("Xenoarchaeologist" = /datum/alt_title/xenoarch, "Anomalist" = /datum/alt_title/anomalist, \ "Phoron Researcher" = /datum/alt_title/phoron_research, "Circuit Designer" = /datum/alt_title/circuit_designer) + + access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch, access_xenobotany) + minimal_access = list(access_tox, access_tox_storage, access_research, access_xenoarch) // Unchanged (for now?), mostly here for reference + + /datum/alt_title/circuit_designer title = "Circuit Designer" title_blurb = "A Circuit Designer is a Scientist whose expertise is working with integrated circuits. They are familar with the workings and programming of those devices. \ diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 38f3a3448b..4421e736d6 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -11,7 +11,7 @@ faction = "Station" total_positions = 1 spawn_positions = 1 - supervisors = "the Colony Director" + supervisors = "the Site Manager" selection_color = "#8E2929" req_admin_notify = 1 economic_modifier = 10 diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 2470fdc114..403efbf4fe 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -394,7 +394,7 @@ var/global/datum/controller/occupations/job_master var/datum/gear/G = gear_datums[thing] if(!G) //Not a real gear datum (maybe removed, as this is loaded from their savefile) continue - + var/permitted // Check if it is restricted to certain roles if(G.allowed_roles) @@ -435,13 +435,13 @@ var/global/datum/controller/occupations/job_master // Set up their account job.setup_account(H) - + // Equip job items. job.equip(H, H.mind ? H.mind.role_alt_title : "") - + // Stick their fingerprints on literally everything job.apply_fingerprints(H) - + // Only non-silicons get post-job-equip equipment if(!(job.mob_type & JOB_SILICON)) H.equip_post_job() @@ -487,11 +487,11 @@ var/global/datum/controller/occupations/job_master return H.Robotize() if(job.mob_type & JOB_SILICON_AI) return H - + // TWEET PEEP - if(rank == "Colony Director") + if(rank == "Site Manager") var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP) ? null : sound('sound/misc/boatswain.ogg', volume=20) - captain_announcement.Announce("All hands, [alt_title ? alt_title : "Colony Director"] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z) + captain_announcement.Announce("All hands, [alt_title ? alt_title : "Site Manager"] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z) //Deferred item spawning. if(spawn_in_storage && spawn_in_storage.len) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index a3e4d2eeb3..267524b979 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -57,6 +57,7 @@ M.forceMove(src) occupant = M update_icon() //icon_state = "body_scanner_1" //VOREStation Edit - Health display for consoles with light and such. + playsound(src, 'sound/machines/medbayscanner1.ogg', 50) // Beepboop you're being scanned. <3 add_fingerprint(user) qdel(G) SStgui.update_uis(src) @@ -101,6 +102,7 @@ O.forceMove(src) occupant = O update_icon() //icon_state = "body_scanner_1" //VOREStation Edit - Health display for consoles with light and such. + playsound(src, 'sound/machines/medbayscanner1.ogg', 50) // Beepboop you're being scanned. <3 add_fingerprint(user) SStgui.update_uis(src) @@ -332,6 +334,7 @@ if("print_p") var/atom/target = console ? console : src visible_message("[target] rattles and prints out a sheet of paper.") + playsound(src, 'sound/machines/printer.ogg', 50, 1) var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(target)) var/name = occupant ? occupant.name : "Unknown" P.info = "
Body Scan - [name]

" diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm index aa1c3ef28c..64f7f93f86 100644 --- a/code/game/machinery/air_alarm.dm +++ b/code/game/machinery/air_alarm.dm @@ -66,7 +66,7 @@ var/datum/radio_frequency/radio_connection var/list/TLV = list() - var/list/trace_gas = list("sleeping_agent", "volatile_fuel") //list of other gases that this air alarm is able to detect + var/list/trace_gas = list("nitrous_oxide", "volatile_fuel") //list of other gases that this air alarm is able to detect var/danger_level = 0 var/pressure_dangerlevel = 0 diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 0b7c96e08a..6fe30aeaab 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -26,7 +26,7 @@ /obj/machinery/portable_atmospherics/canister/drain_power() return -1 -/obj/machinery/portable_atmospherics/canister/sleeping_agent +/obj/machinery/portable_atmospherics/canister/nitrous_oxide name = "Canister: \[N2O\]" icon_state = "redws" canister_color = "redws" @@ -88,7 +88,7 @@ name = "Canister \[CO2\]" icon_state = "black" canister_color = "black" -/obj/machinery/portable_atmospherics/canister/empty/sleeping_agent +/obj/machinery/portable_atmospherics/canister/empty/nitrous_oxide name = "Canister \[N2O\]" icon_state = "redws" canister_color = "redws" @@ -390,17 +390,17 @@ update_flag src.update_icon() return 1 -/obj/machinery/portable_atmospherics/canister/sleeping_agent/New() +/obj/machinery/portable_atmospherics/canister/nitrous_oxide/New() ..() - air_contents.adjust_gas("sleeping_agent", MolesForPressure()) + air_contents.adjust_gas("nitrous_oxide", MolesForPressure()) src.update_icon() return 1 //Dirty way to fill room with gas. However it is a bit easier to do than creating some floor/engine/n2o -rastaf0 -/obj/machinery/portable_atmospherics/canister/sleeping_agent/roomfiller/Initialize() +/obj/machinery/portable_atmospherics/canister/nitrous_oxide/roomfiller/Initialize() . = ..() - air_contents.gas["sleeping_agent"] = 9*4000 + air_contents.gas["nitrous_oxide"] = 9*4000 var/turf/simulated/location = src.loc if (istype(src.loc)) location.assume_air(air_contents) diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index b6e4c0e124..1f9d190800 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -18,7 +18,7 @@ var/minrate = 0 var/maxrate = 10 * ONE_ATMOSPHERE - var/list/scrubbing_gas = list("phoron", "carbon_dioxide", "sleeping_agent", "volatile_fuel") + var/list/scrubbing_gas = list("phoron", "carbon_dioxide", "nitrous_oxide", "volatile_fuel") /obj/machinery/portable_atmospherics/powered/scrubber/New() ..() diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 3e1188198b..74f81514d5 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -11,10 +11,10 @@ clickvol = 30 circuit = /obj/item/weapon/circuitboard/autolathe - var/datum/category_collection/autolathe/machine_recipes + + var/static/datum/category_collection/autolathe/autolathe_recipes var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0) var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0) - var/datum/category_group/autolathe/current_category var/hacked = 0 var/disabled = 0 @@ -33,6 +33,8 @@ /obj/machinery/autolathe/Initialize() . = ..() + if(!autolathe_recipes) + autolathe_recipes = new() wires = new(src) default_apply_parts() RefreshParts() @@ -42,87 +44,77 @@ wires = null return ..() -/obj/machinery/autolathe/proc/update_recipe_list() - if(!machine_recipes) - if(!autolathe_recipes) - autolathe_recipes = new() - machine_recipes = autolathe_recipes - current_category = machine_recipes.categories[1] +/obj/machinery/autolathe/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Autolathe", name) + ui.open() -/obj/machinery/autolathe/interact(mob/user as mob) - update_recipe_list() +/obj/machinery/autolathe/tgui_status(mob/user) + if(disabled) + return STATUS_CLOSE + return ..() - if(..() || (disabled && !panel_open)) +/obj/machinery/autolathe/tgui_static_data(mob/user) + var/list/data = ..() + + var/list/categories = list() + var/list/recipes = list() + for(var/datum/category_group/autolathe/A in autolathe_recipes.categories) + categories += A.name + for(var/datum/category_item/autolathe/M in A.items) + if(M.hidden && !hacked) + continue + if(M.man_rating > man_rating) + continue + recipes.Add(list(list( + "category" = A.name, + "name" = M.name, + "ref" = REF(M), + "requirements" = M.resources, + "hidden" = M.hidden, + "coeff_applies" = !M.no_scale, + ))) + data["recipes"] = recipes + data["categories"] = categories + + return data + +/obj/machinery/autolathe/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/sheetmaterials) + ) + +/obj/machinery/autolathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/material_data = list() + for(var/mat_id in stored_material) + var/amount = stored_material[mat_id] + var/list/material_info = list( + "name" = mat_id, + "amount" = amount, + "sheets" = round(amount / SHEET_MATERIAL_AMOUNT), + "removable" = amount >= SHEET_MATERIAL_AMOUNT + ) + material_data += list(material_info) + data["busy"] = busy + data["materials"] = material_data + data["mat_efficiency"] = mat_efficiency + return data + +/obj/machinery/autolathe/interact(mob/user) + if(panel_open) + return wires.Interact(user) + + if(disabled) to_chat(user, "\The [src] is disabled!") return if(shocked) shock(user, 50) - var/list/dat = list() - dat += "

Autolathe Control Panel


" - - if(!disabled) - dat += "" - var/list/material_top = list("") - var/list/material_bottom = list("") - - for(var/material in stored_material) - if(material != DEFAULT_WALL_MATERIAL && material != MAT_GLASS) // Don't show the Extras unless people care enough to put them in. - if(stored_material[material] <= 0) - continue - material_top += "" - material_bottom += "" - - dat += "[material_top.Join()][material_bottom.Join()]
[material][stored_material[material]]/[storage_capacity[material]]

" - dat += "Filter: [filtertext ? filtertext : "None Set"]
" - dat += "

Printable Designs

Showing: [current_category].

" - - for(var/datum/category_item/autolathe/R in current_category.items) - if(R.hidden && !hacked) // Illegal or nonstandard. - continue - if(R.man_rating > man_rating) // Advanced parts. - continue - if(filtertext && findtext(R.name, filtertext) == 0) - continue - var/can_make = 1 - var/list/material_string = list() - var/list/multiplier_string = list() - var/max_sheets - var/comma - if(!R.resources || !R.resources.len) - material_string += "No resources required." - else - //Make sure it's buildable and list requires resources. - for(var/material in R.resources) - var/coeff = (R.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient - var/sheets = round(stored_material[material]/round(R.resources[material]*coeff)) - if(isnull(max_sheets) || max_sheets > sheets) - max_sheets = sheets - if(!isnull(stored_material[material]) && stored_material[material] < round(R.resources[material]*coeff)) - can_make = 0 - if(!comma) - comma = 1 - else - material_string += ", " - material_string += "[round(R.resources[material] * coeff)] [material]" - material_string += ".
" - //Build list of multipliers for sheets. - if(R.is_stack) - if(max_sheets && max_sheets > 0) - max_sheets = min(max_sheets, R.max_stack) // Limit to the max allowed by stack type. - multiplier_string += "
" - for(var/i = 5;i*" : ""][can_make ? "" : ""][R.name][can_make ? "" : ""][R.hidden ? "*" : ""][multiplier_string.Join()]" - - dat += "
[material_string.Join()]

" - - dat = jointext(dat, null) - var/datum/browser/popup = new(user, "autolathe", "Autolathe Production Menu", 550, 700) - popup.set_content(dat) - popup.open() + + tgui_interact(user) /obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) if(busy) @@ -130,7 +122,7 @@ return if(default_deconstruction_screwdriver(user, O)) - updateUsrDialog() + interact(user) return if(default_deconstruction_crowbar(user, O)) return @@ -155,18 +147,6 @@ if(istype(O,/obj/item/ammo_magazine/clip) || istype(O,/obj/item/ammo_magazine/s357) || istype(O,/obj/item/ammo_magazine/s38) || istype (O,/obj/item/ammo_magazine/s44)/* VOREstation Edit*/) // Prevents ammo recycling exploit with speedloaders. to_chat(user, "\The [O] is too hazardous to recycle with the autolathe!") return - /* ToDo: Make this actually check for ammo and change the value of the magazine if it's empty. -Spades - var/obj/item/ammo_magazine/speedloader = O - if(speedloader.stored_ammo) - to_chat(user, "\The [speedloader] is too hazardous to put back into the autolathe while there's ammunition inside of it!") - return - else - speedloader.matter = list(DEFAULT_WALL_MATERIAL = 75) // It's just a hunk of scrap metal now. - if(istype(O,/obj/item/ammo_magazine)) // This was just for immersion consistency with above. - var/obj/item/ammo_magazine/mag = O - if(mag.stored_ammo) - to_chat(user, "\The [mag] is too hazardous to put back into the autolathe while there's ammunition inside of it!") - return*/ //Resources are being loaded. var/obj/item/eating = O @@ -227,9 +207,9 @@ user.set_machine(src) interact(user) -/obj/machinery/autolathe/Topic(href, href_list) +/obj/machinery/autolathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return + return TRUE usr.set_machine(src) add_fingerprint(usr) @@ -237,72 +217,69 @@ if(busy) to_chat(usr, "The autolathe is busy. Please wait for completion of previous operation.") return + switch(action) + if("make") + var/datum/category_item/autolathe/making = locate(params["make"]) + if(!istype(making)) + return + if(making.hidden && !hacked) + return - else if(href_list["setfilter"]) - var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", filtertext) as null|text - if(!Adjacent(usr)) - return - if(isnull(filterstring)) //Clicked Cancel - return - if(filterstring == "") //Cleared value - filtertext = null - filtertext = sanitize(filterstring, 25) + var/multiplier = 1 - if(href_list["change_category"]) + if(making.is_stack) + var/max_sheets + for(var/material in making.resources) + var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient + var/sheets = round(stored_material[material]/round(making.resources[material]*coeff)) + if(isnull(max_sheets) || max_sheets > sheets) + max_sheets = sheets + if(!isnull(stored_material[material]) && stored_material[material] < round(making.resources[material]*coeff)) + max_sheets = 0 + //Build list of multipliers for sheets. + multiplier = input(usr, "How many do you want to print? (0-[max_sheets])") as num|null + if(!multiplier || multiplier <= 0 || multiplier > max_sheets || tgui_status(usr, state) != STATUS_INTERACTIVE) + return FALSE - var/choice = input("Which category do you wish to display?") as null|anything in machine_recipes.categories - if(!choice) return - current_category = choice + busy = making.name + update_use_power(USE_POWER_ACTIVE) - if(href_list["make"] && machine_recipes) - var/multiplier = text2num(href_list["multiplier"]) - var/datum/category_item/autolathe/making = locate(href_list["make"]) in current_category.items + //Check if we still have the materials. + var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient + for(var/material in making.resources) + if(!isnull(stored_material[material])) + if(stored_material[material] < round(making.resources[material] * coeff) * multiplier) + return - //Exploit detection, not sure if necessary after rewrite. - if(!making || multiplier < 0 || multiplier > 100) - var/turf/exploit_loc = get_turf(usr) - message_admins("[key_name_admin(usr)] tried to exploit an autolathe to duplicate an item! ([exploit_loc ? "JMP" : "null"])", 0) - log_admin("EXPLOIT : [key_name(usr)] tried to exploit an autolathe to duplicate an item!") - return + //Consume materials. + for(var/material in making.resources) + if(!isnull(stored_material[material])) + stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * coeff) * multiplier) - busy = 1 - update_use_power(USE_POWER_ACTIVE) + update_icon() // So lid closes - //Check if we still have the materials. - var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient - for(var/material in making.resources) - if(!isnull(stored_material[material])) - if(stored_material[material] < round(making.resources[material] * coeff) * multiplier) - return + sleep(build_time) - //Consume materials. - for(var/material in making.resources) - if(!isnull(stored_material[material])) - stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * coeff) * multiplier) + busy = 0 + update_use_power(USE_POWER_IDLE) + update_icon() // So lid opens - update_icon() // So lid closes + //Sanity check. + if(!making || !src) + return - sleep(build_time) - - busy = 0 - update_use_power(USE_POWER_IDLE) - update_icon() // So lid opens - - //Sanity check. - if(!making || !src) return - - //Create the desired item. - var/obj/item/I = new making.path(src.loc) - flick("[initial(icon_state)]_finish", src) - if(multiplier > 1) - if(istype(I, /obj/item/stack)) - var/obj/item/stack/S = I - S.amount = multiplier - else - for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack. - new making.path(src.loc) - - updateUsrDialog() + //Create the desired item. + var/obj/item/I = new making.path(src.loc) + flick("[initial(icon_state)]_finish", src) + if(multiplier > 1) + if(istype(I, /obj/item/stack)) + var/obj/item/stack/S = I + S.amount = multiplier + else + for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack. + new making.path(src.loc) + return TRUE + return FALSE /obj/machinery/autolathe/update_icon() overlays.Cut() @@ -332,6 +309,7 @@ storage_capacity["glass"] = mb_rating * 12500 build_time = 50 / man_rating mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5 + update_tgui_static_data(usr) /obj/machinery/autolathe/dismantle() for(var/mat in stored_material) @@ -345,3 +323,20 @@ qdel(S) ..() return 1 + +/obj/machinery/autolathe/proc/eject_materials(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything + var/recursive = amount == -1 ? 1 : 0 + var/matstring = lowertext(material) + var/material/M = get_material_by_name(matstring) + + var/obj/item/stack/material/S = M.place_sheet(get_turf(src)) + if(amount <= 0) + amount = S.max_amount + var/ejected = min(round(stored_material[matstring] / S.perunit), amount) + S.amount = min(ejected, amount) + if(S.amount <= 0) + qdel(S) + return + stored_material[matstring] -= ejected * S.perunit + if(recursive && stored_material[matstring] >= S.perunit) + eject_materials(matstring, -1) diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index 3fcbc98e85..c193417572 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -1,3 +1,17 @@ +// Use this define to register something as a creatable! +// * n - The proper name of the purchasable +// * o - The object type path of the purchasable to spawn +// * r - The amount to dispense +// * p - The price of the purchasable in biomass +#define BIOGEN_ITEM(n, o, r, p) n = new /datum/data/biogenerator_item(n, o, r, p) + +// Use this define to register something as dispensable +// * n - The proper name of the purchasable +// * o - The reagent ID +// * r - The amount of reagent to dispense +// * p - The price of the purchasable in biomass +#define BIOGEN_REAGENT(n, o, r, p) n = new /datum/data/biogenerator_reagent(n, o, r, p) + /obj/machinery/biogenerator name = "biogenerator" desc = "Converts plants into biomass, which can be used for fertilizer and sort-of-synthetic products." @@ -11,10 +25,34 @@ var/processing = 0 var/obj/item/weapon/reagent_containers/glass/beaker = null var/points = 0 - var/menustat = "menu" var/build_eff = 1 var/eat_eff = 1 + var/list/item_list + + +/datum/data/biogenerator_item + var/equipment_path = null + var/equipment_amt = 1 + var/cost = 0 + +/datum/data/biogenerator_item/New(name, path, amt, cost) + src.name = name + src.equipment_path = path + src.equipment_amt = amt + src.cost = cost + +/datum/data/biogenerator_reagent + var/reagent_id = null + var/reagent_amt = 0 + var/cost = 0 + +/datum/data/biogenerator_reagent/New(name, id, amt, cost) + src.name = name + src.reagent_id = id + src.reagent_amt = amt + src.cost = cost + /obj/machinery/biogenerator/Initialize() . = ..() var/datum/reagents/R = new/datum/reagents(1000) @@ -24,6 +62,139 @@ beaker = new /obj/item/weapon/reagent_containers/glass/bottle(src) default_apply_parts() + item_list = list() + item_list["Food Items"] = list( + BIOGEN_REAGENT("10 milk", "milk", 10, 20), + BIOGEN_REAGENT("50 milk", "milk", 50, 95), + BIOGEN_REAGENT("10 Cream", "cream", 10, 30), + BIOGEN_REAGENT("50 Cream", "cream", 50, 120), + BIOGEN_ITEM("Slab of meat", /obj/item/weapon/reagent_containers/food/snacks/meat, 1, 50), + BIOGEN_ITEM("5 slabs of meat", /obj/item/weapon/reagent_containers/food/snacks/meat, 5, 250), + ) + item_list["Cooking Ingredients"] = list( + BIOGEN_REAGENT("10 Universal Enzyme", "enzyme", 10, 30), + BIOGEN_REAGENT("50 Universal Enzyme", "enzyme", 50, 120), + BIOGEN_ITEM("Nutri-spread", /obj/item/weapon/reagent_containers/food/snacks/spreads, 1, 30), + BIOGEN_ITEM("5 nutri-spread", /obj/item/weapon/reagent_containers/food/snacks/spreads, 5, 120), + ) + item_list["Gardening Nutrients"] = list( + BIOGEN_ITEM("E-Z-Nutrient", /obj/item/weapon/reagent_containers/glass/bottle/eznutrient, 1, 60), + BIOGEN_ITEM("5 E-Z-Nutrient", /obj/item/weapon/reagent_containers/glass/bottle/eznutrient, 5, 300), + BIOGEN_ITEM("Left 4 Zed", /obj/item/weapon/reagent_containers/glass/bottle/left4zed, 1, 120), + BIOGEN_ITEM("5 Left 4 Zed", /obj/item/weapon/reagent_containers/glass/bottle/left4zed, 5, 600), + BIOGEN_ITEM("Robust Harvest", /obj/item/weapon/reagent_containers/glass/bottle/robustharvest, 1, 150), + BIOGEN_ITEM("5 Robust Harvest", /obj/item/weapon/reagent_containers/glass/bottle/robustharvest, 5, 750), + ) + item_list["Leather Products"] = list( + BIOGEN_ITEM("Wallet", /obj/item/weapon/storage/wallet, 1, 100), + BIOGEN_ITEM("Botanical gloves", /obj/item/clothing/gloves/botanic_leather, 1, 250), + BIOGEN_ITEM("Plant bag", /obj/item/weapon/storage/bag/plants, 1, 320), + BIOGEN_ITEM("Large plant bag", /obj/item/weapon/storage/bag/plants/large, 1, 640), + BIOGEN_ITEM("Utility belt", /obj/item/weapon/storage/belt/utility, 1, 300), + BIOGEN_ITEM("Leather Satchel", /obj/item/weapon/storage/backpack/satchel, 1, 400), + BIOGEN_ITEM("Cash Bag", /obj/item/weapon/storage/bag/cash, 1, 400), + BIOGEN_ITEM("Chemistry Bag", /obj/item/weapon/storage/bag/chemistry, 1, 400), + BIOGEN_ITEM("Workboots", /obj/item/clothing/shoes/boots/workboots, 1, 400), + BIOGEN_ITEM("Leather Chaps", /obj/item/clothing/under/pants/chaps, 1, 400), + BIOGEN_ITEM("Leather Coat", /obj/item/clothing/suit/leathercoat, 1, 500), + BIOGEN_ITEM("Leather Jacket", /obj/item/clothing/suit/storage/toggle/brown_jacket, 1, 500), + BIOGEN_ITEM("Winter Coat", /obj/item/clothing/suit/storage/hooded/wintercoat, 1, 500), + //VOREStation Edit - Algae for oxygen generator + BIOGEN_ITEM("4 Algae Sheets", /obj/item/stack/material/algae, 4, 400), + ) + +/obj/machinery/biogenerator/tgui_static_data(mob/user) + var/list/static_data[0] + + // Available items - in static data because we don't wanna compute this list every time! It hardly changes. + static_data["items"] = list() + for(var/cat in item_list) + var/list/cat_items = list() + for(var/prize_name in item_list[cat]) + var/datum/data/biogenerator_reagent/prize = item_list[cat][prize_name] + cat_items[prize_name] = list("name" = prize_name, "price" = prize.cost, "reagent" = istype(prize)) + static_data["items"][cat] = cat_items + + return static_data + +/obj/machinery/biogenerator/tgui_data(mob/user) + var/list/data = ..() + + data["build_eff"] = build_eff + data["points"] = points + data["processing"] = processing + data["beaker"] = !!beaker + + return data + +/obj/machinery/biogenerator/tgui_interact(mob/user, datum/tgui/ui = null) + // Open the window + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Biogenerator", name) + ui.open() + +/obj/machinery/biogenerator/tgui_act(action, params) + if(..()) + return + + . = TRUE + switch(action) + if("activate") + INVOKE_ASYNC(src, .proc/activate) + return TRUE + if("detach") + if(beaker) + beaker.forceMove(loc) + beaker = null + update_icon() + return TRUE + if("purchase") + var/category = params["cat"] // meow + var/name = params["name"] + + if(!(category in item_list) || !(name in item_list[category])) // Not trying something that's not in the list, are you? + return + + var/datum/data/biogenerator_item/bi = item_list[category][name] + if(!istype(bi)) + var/datum/data/biogenerator_reagent/br = item_list[category][name] + if(!istype(br)) + return + if(!beaker) + return + var/cost = round(br.cost / build_eff) + if(cost > points) + to_chat(usr, "Insufficient biomass.") + return + var/amt_to_actually_dispense = round(min(beaker.reagents.get_free_space(), br.reagent_amt)) + if(amt_to_actually_dispense <= 0) + to_chat(usr, "The loaded beaker is full!") + return + points -= (cost * (amt_to_actually_dispense / br.reagent_amt)) + beaker.reagents.add_reagent(br.reagent_id, amt_to_actually_dispense) + playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1) + return + + var/cost = round(bi.cost / build_eff) + if(cost > points) + to_chat(usr, "Insufficient biomass.") + return + + points -= cost + if(ispath(bi.equipment_path, /obj/item/stack)) + var/obj/item/stack/S = new bi.equipment_path(loc) + S.amount = bi.equipment_amt + playsound(src, 'sound/machines/vending/vending_drop.ogg', 100, 1) + return TRUE + + for(var/i in 1 to bi.equipment_amt) + new bi.equipment_path(loc) + playsound(src, 'sound/machines/vending/vending_drop.ogg', 100, 1) + return TRUE + else + return FALSE + /obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well. update_icon() @@ -87,68 +258,10 @@ update_icon() return -/obj/machinery/biogenerator/interact(mob/user as mob) +/obj/machinery/biogenerator/attack_hand(mob/user as mob) if(stat & BROKEN) return - user.set_machine(src) - var/dat = "BiogeneratorBiogenerator:
" - if(processing) - dat += "Biogenerator is processing! Please wait..." - else - dat += "Biomass: [points] points.
" - switch(menustat) - if("menu") - if(beaker) - dat += "Activate Biogenerator!
" - dat += "Detach Container

" - dat += "Food Items:
" - dat += "10 milk ([round(20/build_eff)]) | x5
" - dat += "10 cream ([round(20/build_eff)]) | x5
" - dat += "Slab of meat ([round(50/build_eff)]) | x5
" - dat += "Cooking Ingredient:
" - dat += "Universal Enzyme ([round(30/build_eff)]) | x5
" - dat += "Nutri-Spread ([round(30/build_eff)]) | x5
" - // dat += "Universal Enzyme ([round(30/build_eff)]) | x5
" - // dat += "Universal Enzyme ([round(30/build_eff)]) | x5
" - dat += "Gardening Nutrients:
" - dat += "E-Z-Nutrient ([round(60/build_eff)]) | x5
" - dat += "Left 4 Zed ([round(120/build_eff)]) | x5
" - dat += "Robust Harvest ([round(150/build_eff)]) | x5
" - dat += "Leather Products:
" - dat += "Wallet ([round(100/build_eff)])
" - dat += "Botanical gloves ([round(250/build_eff)])
" - dat += "Plant bag ([round(250/build_eff)])
" - dat += "Large plant bag ([round(250/build_eff)])
" - dat += "Utility belt ([round(300/build_eff)])
" - dat += "Leather Satchel ([round(400/build_eff)])
" - dat += "Cash Bag ([round(400/build_eff)])
" - dat += "Chemistry Bag ([round(400/build_eff)])
" - dat += "Workboots ([round(400/build_eff)])
" - dat += "Leather Shoes ([round(400/build_eff)])
" - dat += "Leather Chaps ([round(400/build_eff)])
" - dat += "Leather Coat ([round(500/build_eff)])
" - dat += "Leather Jacket ([round(500/build_eff)])
" - dat += "Winter Coat ([round(500/build_eff)])
" - dat += "4 Algae Sheets ([round(400/build_eff)])
" //VOREStation Edit - Algae for oxygen generator - //dat += "Other
" - //dat += "Monkey (500)
" - else - dat += "
No beaker inside. Please insert a beaker.
" - if("nopoints") - dat += "You do not have biomass to create products.
Please, put growns into reactor and activate it.
" - dat += "Return to menu" - if("complete") - dat += "Operation complete.
" - dat += "Return to menu" - if("void") - dat += "Error: No growns inside.
Please, put growns into reactor.
" - dat += "Return to menu" - user << browse(dat, "window=biogenerator") - onclose(user, "biogenerator") - return - -/obj/machinery/biogenerator/attack_hand(mob/user as mob) - interact(user) + tgui_interact(user) /obj/machinery/biogenerator/proc/activate() if(usr.stat) @@ -168,139 +281,17 @@ if(S) processing = 1 update_icon() - updateUsrDialog() playsound(src, 'sound/machines/blender.ogg', 40, 1) use_power(S * 30) sleep((S + 15) / eat_eff) processing = 0 + SStgui.update_uis(src) playsound(src, 'sound/machines/biogenerator_end.ogg', 40, 1) update_icon() else - menustat = "void" + to_chat(usr, "Error: No growns inside. Please insert growns.") return -/obj/machinery/biogenerator/proc/create_product(var/item, var/cost) - cost = round(cost/build_eff) - if(cost > points) - menustat = "nopoints" - return 0 - processing = 1 - update_icon() - updateUsrDialog() - points -= cost - sleep(30) - switch(item) - if("milk") - beaker.reagents.add_reagent("milk", 10) - if("milk5") - beaker.reagents.add_reagent("milk", 50) - if("cream") - beaker.reagents.add_reagent("cream", 10) - if("cream5") - beaker.reagents.add_reagent("cream", 50) - if("meat") - new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) - if("meat5") - new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) //This is ugly. - new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) - new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) - new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) - new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) - if("unizyme") - beaker.reagents.add_reagent("enzyme", 10) - if("unizyme50") - beaker.reagents.add_reagent("enzyme", 50) - if("nutrispread") - new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) - if("nutrispread5") - new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) - new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) - new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) - new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) - new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) - if("ez") - new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc) - if("l4z") - new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc) - if("rh") - new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc) - if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan - new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc) - if("l4z5") - new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc) - if("rh5") - new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc) - new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc) - if("wallet") - new/obj/item/weapon/storage/wallet(loc) - if("gloves") - new/obj/item/clothing/gloves/botanic_leather(loc) - if("plantbag") - new/obj/item/weapon/storage/bag/plants(loc) - if("plantbaglarge") - new/obj/item/weapon/storage/bag/plants/large(loc) - if("tbelt") - new/obj/item/weapon/storage/belt/utility(loc) - if("satchel") - new/obj/item/weapon/storage/backpack/satchel(loc) - if("cashbag") - new/obj/item/weapon/storage/bag/cash(loc) - if("chembag") - new/obj/item/weapon/storage/bag/chemistry(loc) - if("monkey") - new/mob/living/carbon/human/monkey(loc) - if("workboots") - new/obj/item/clothing/shoes/boots/workboots(loc) - if("leathershoes") - new/obj/item/clothing/shoes/leather(loc) - if("leatherchaps") - new/obj/item/clothing/under/pants/chaps - if("leathercoat") - new/obj/item/clothing/suit/leathercoat(loc) - if("leatherjacket") - new/obj/item/clothing/suit/storage/toggle/brown_jacket(loc) - if("wintercoat") - new/obj/item/clothing/suit/storage/hooded/wintercoat(loc) - if("algae") //VOREStation Edit - Algae for oxygen generator - var/obj/item/stack/material/algae/A = new(loc) - A.amount = 4 //VOREStation Edit End - processing = 0 - menustat = "complete" - update_icon() - return 1 - -/obj/machinery/biogenerator/Topic(href, href_list) - if(stat & BROKEN) return - if(usr.stat || usr.restrained()) return - if(!in_range(src, usr)) return - - usr.set_machine(src) - - switch(href_list["action"]) - if("activate") - activate() - if("detach") - if(beaker) - beaker.loc = src.loc - beaker = null - update_icon() - if("create") - create_product(href_list["item"], text2num(href_list["cost"])) - if("menu") - menustat = "menu" - updateUsrDialog() - /obj/machinery/biogenerator/RefreshParts() ..() var/man_rating = 0 @@ -314,3 +305,5 @@ build_eff = man_rating eat_eff = bin_rating + +#undef BIOGENITEM diff --git a/code/game/machinery/bomb_tester_vr.dm b/code/game/machinery/bomb_tester_vr.dm index b4f3b192ed..826f632492 100644 --- a/code/game/machinery/bomb_tester_vr.dm +++ b/code/game/machinery/bomb_tester_vr.dm @@ -101,137 +101,128 @@ else tank2 = I update_icon() - updateUsrDialog() + SStgui.update_uis(src) to_chat(user, "You connect \the [I] to \the [src]'s [I==tank1 ? "primary" : "secondary"] slot.") return ..() /obj/machinery/bomb_tester/attack_hand(var/mob/user) add_fingerprint(user) - interact(user) + tgui_interact(user) -/obj/machinery/bomb_tester/interact(var/mob/user) - if(stat & NOPOWER) - return +/obj/machinery/bomb_tester/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BombTester", name) + ui.open() - var/dat = "Bomb Tester" +/obj/machinery/bomb_tester/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["simulating"] = simulating + if(!simulating) + data["mode"] = sim_mode + data["tank1"] = tank1 + data["tank1ref"] = REF(tank1) + data["tank2"] = tank2 + data["tank2ref"] = REF(tank2) + data["canister"] = test_canister + data["sim_canister_output"] = sim_canister_output + + return data - dat += "Virtual Explosive Simulator v1.03" - dat += "
" - - if(simulating) - dat += "
Simulation in progress! Please wait for results.
" - - else - dat += "
Mode: [sim_mode==MODE_SINGLE?"Single Tank":"Single Tank"] -- [sim_mode==MODE_DOUBLE?"Transfer Valve":"Transfer Valve"] -- [sim_mode==MODE_CANISTER?"Canister":"Canister"]
" - dat += "
" - dat += "
Gas Sources
" - dat += "
[tank1?"\[[tank1.name]\]":"\[Primary Slot\]"] -- [tank2?"\[[tank2.name]\]":"\[Secondary Slot\]"]
" - dat += "
Connected Canister: [test_canister?"[test_canister.name] -- ":"None -- "][test_canister?"\[Rescan\]":"\[Scan for canister\]"]
" - if(test_canister) - dat += "
Canister Release Pressure: [sim_canister_output] Kilopascals
" - - dat += "
" - dat += "-1000|" - dat += "-100|" - dat += "-10|" - dat += "-1 ||| " - - dat += "+1|" - dat += "+10|" - dat += "+100|" - dat += "+1000" - dat += "
" - - dat += "

" - dat += "
BEGIN SIMULATION
" - - user.set_machine(src) - user << browse(dat, "window=bomb_tester") - onclose(user, "bomb_tester") - -/obj/machinery/bomb_tester/Topic(href, href_list) +/obj/machinery/bomb_tester/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return - if(stat & NOPOWER) - return - if(!usr.Adjacent(src)) - usr << browse(null, "window=bomb_tester") - usr.unset_machine() - return + return TRUE + if(simulating) return - if(href_list["set_mode"]) - sim_mode = text2num(href_list["set_mode"]) - var/text_mode - switch(sim_mode) - if(MODE_SINGLE) - text_mode = "single gas tank detonation" - if(MODE_DOUBLE) - text_mode = "tank transfer valve detonation" - if(MODE_CANISTER) - text_mode = "canister-assisted single gas tank detonation" - to_chat(usr, "[src] set to simulate a [text_mode].") - - if(href_list["tank"]) - var/tankvar = "tank[href_list["tank"]]" - var/obj/item/weapon/tank/T - if(vars[tankvar]) - T = vars[tankvar] - T.forceMove(get_turf(src)) - vars[tankvar] = null - else if(istype(usr.get_active_hand(),/obj/item/weapon/tank)) - T = usr.get_active_hand() - usr.drop_item(T) - T.forceMove(src) - vars[tankvar] = T - update_icon() - - if(href_list["canister_scan"]) - for(var/obj/machinery/portable_atmospherics/canister/C in orange(1,src)) - if(C && C == test_canister) - continue - else if(C) - test_canister = C - break + switch(action) + if("set_mode") + sim_mode = clamp(text2num(params["mode"]), MODE_SINGLE, MODE_CANISTER) + var/text_mode + switch(sim_mode) + if(MODE_SINGLE) + text_mode = "single gas tank detonation" + if(MODE_DOUBLE) + text_mode = "tank transfer valve detonation" + if(MODE_CANISTER) + text_mode = "canister-assisted single gas tank detonation" + to_chat(usr, "[src] set to simulate a [text_mode].") + return TRUE + + if("add_tank") + if(istype(usr.get_active_hand(), /obj/item/weapon/tank)) + var/obj/item/weapon/tank/T = usr.get_active_hand() + var/slot = params["slot"] + if(slot == 1 && !tank1) + tank1 = T + else if(slot == 2 && !tank2) + tank2 = T + else + to_chat(usr, "Slot [slot] is full.") + return + + usr.drop_item(T) + T.forceMove(src) + return TRUE else - test_canister = null + to_chat(usr, "You must be wielding a tank to insert it!") - if(href_list["set_can_pressure"]) - var/change = text2num(href_list["set_can_pressure"]) - sim_canister_output = CLAMP(sim_canister_output+change, ONE_ATMOSPHERE/10, ONE_ATMOSPHERE*10) + if("remove_tank") + var/obj/item/weapon/tank/T = locate(params["ref"]) in list(tank1, tank2) + if(istype(T)) + if(T == tank1) + tank1 = null + if(T == tank2) + tank2 = null + T.forceMove(get_turf(src)) + update_icon() + return TRUE - if(href_list["start_sim"]) - start_simulating() + if("canister_scan") + for(var/obj/machinery/portable_atmospherics/canister/C in orange(1,src)) + if(C && C == test_canister) + continue + else if(C) + test_canister = C + break + else + test_canister = null + return TRUE - updateUsrDialog() + if("set_can_pressure") + sim_canister_output = CLAMP(text2num(params["pressure"]), ONE_ATMOSPHERE/10, ONE_ATMOSPHERE*10) + return TRUE + + if("start_sim") + start_simulating() + return TRUE /obj/machinery/bomb_tester/proc/start_simulating() + if(!tank1 || (sim_mode == MODE_DOUBLE && !tank2) || (sim_mode == MODE_CANISTER && !test_canister)) + simulation_results = "Error" + simulation_finish() + return + if((tank1?.air_contents.return_pressure() > TANK_RUPTURE_PRESSURE) || (tank2?.air_contents.return_pressure() > TANK_RUPTURE_PRESSURE)) + simulation_results = "Unstable" + simulation_finish() + return simulating = 1 update_use_power(USE_POWER_ACTIVE) simulation_started = world.time update_icon() switch(sim_mode) if(MODE_SINGLE) - if(!tank1) - simulation_results = "Error" - return spawn() single_tank_sim() if(MODE_DOUBLE) - if(!tank1 || !tank2) - simulation_results = "Error" - return spawn() ttv_sim() if(MODE_CANISTER) - if(!tank1 || !test_canister) - simulation_results = "Error" - return spawn() canister_sim() @@ -361,9 +352,12 @@ if(simulation_results == "Error") playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) state("Invalid parameters.") + else if(simulation_results == "Unstable") + playsound(src, 'sound/machines/buzz-two.ogg', 50, 0) + state("Tank instability detected. Please step away from the device.") else ping("Simulation complete!") - playsound(src, "sound/effects/printer.ogg", 50, 1) + playsound(src, "sound/machines/printer.ogg", 50, 1) var/obj/item/weapon/paper/P = new(get_turf(src)) P.name = "Explosive Simulator printout" P.info = simulation_results @@ -383,4 +377,4 @@ #undef MODE_SINGLE #undef MODE_DOUBLE -#undef MODE_CANISTER \ No newline at end of file +#undef MODE_CANISTER diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index c4b368b8d3..8ddb76c68a 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -205,7 +205,7 @@ return else if((occupant.health >= heal_level || occupant.health == occupant.getMaxHealth()) && (!eject_wait)) - playsound(src, 'sound/machines/ding.ogg', 50, 1) + playsound(src, 'sound/machines/medbayscanner1.ogg', 50, 1) audible_message("\The [src] signals that the cloning process is complete.") connected_message("Cloning Process Complete.") locked = 0 diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 9bf3235d8d..cc05d63217 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -342,6 +342,7 @@ cloneresult = pod.growclone(C) if(cloneresult) set_temp("Initiating cloning cycle...", "success") + playsound(src, 'sound/machines/medbayscanner1.ogg', 100, 1) records.Remove(C) qdel(C) menu = MENU_MAIN diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 2767237963..0a57a5e4c5 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -6,162 +6,225 @@ light_color = "#a97faa" req_access = list(access_robotics) circuit = /obj/item/weapon/circuitboard/robotics + var/safety = 1 /obj/machinery/computer/robotics/attack_ai(var/mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/robotics/attack_hand(var/mob/user as mob) - ui_interact(user) - -/obj/machinery/computer/robotics/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - data["robots"] = get_cyborgs(user) - data["is_ai"] = issilicon(user) - - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "robot_control.tmpl", "Robotic Control Console", 400, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/computer/robotics/Topic(href, href_list) if(..()) return - var/mob/user = usr - if(!src.allowed(user)) - to_chat(user, "Access Denied") + if(stat & (NOPOWER|BROKEN)) return + tgui_interact(user) - // Locks or unlocks the cyborg - if (href_list["lockdown"]) - var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["lockdown"]) - var/failmsg = "" - if(!target || !istype(target)) - return +/obj/machinery/computer/robotics/proc/is_authenticated(mob/user) + if(!istype(user)) + return FALSE + if(isobserver(user)) + var/mob/observer/dead/D = user + if(D.can_admin_interact()) + return TRUE + if(allowed(user)) + return TRUE + return FALSE - if(isAI(user) && (target.connected_ai != user)) - to_chat(user, "Access Denied. This robot is not linked to you.") - return +/** + * Does this borg show up in the console + * + * Returns TRUE if a robot will show up in the console + * Returns FALSE if a robot will not show up in the console + * Arguments: + * * R - The [mob/living/silicon/robot] to be checked + */ +/obj/machinery/computer/robotics/proc/console_shows(mob/living/silicon/robot/R) + if(!istype(R)) + return FALSE + if(istype(R, /mob/living/silicon/robot/drone)) + return FALSE + if(R.scrambledcodes) + return FALSE + if(!AreConnectedZLevels(get_z(src), get_z(R))) + return FALSE + return TRUE - if(isrobot(user)) - to_chat(user, "Access Denied.") - return +/** + * Check if a user can send a lockdown/detonate command to a specific borg + * + * Returns TRUE if a user can send the command (does not guarantee it will work) + * Returns FALSE if a user cannot + * Arguments: + * * user - The [mob/user] to be checked + * * R - The [mob/living/silicon/robot] to be checked + * * telluserwhy - Bool of whether the user should be sent a to_chat message if they don't have access + */ +/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R, telluserwhy = FALSE) + if(!istype(user)) + return FALSE + if(!console_shows(R)) + return FALSE + if(isAI(user)) + if(R.connected_ai != user) + if(telluserwhy) + to_chat(user, "AIs can only control cyborgs which are linked to them.") + return FALSE + if(isrobot(user)) + if(R != user) + if(telluserwhy) + to_chat(user, "Cyborgs cannot control other cyborgs.") + return FALSE + return TRUE - var/choice = input("Really [target.lockcharge ? "unlock" : "lockdown"] [target.name] ?") in list ("Yes", "No") - if(choice != "Yes") - return +/** + * Check if the user is the right kind of entity to be able to hack borgs + * + * Returns TRUE if a user is a traitor AI, or aghost + * Returns FALSE otherwise + * Arguments: + * * user - The [mob/user] to be checked + */ +/obj/machinery/computer/robotics/proc/can_hack_any(mob/user) + if(!istype(user)) + return FALSE + if(isobserver(user)) + var/mob/observer/dead/D = user + if(D.can_admin_interact()) + return TRUE + if(!isAI(user)) + return FALSE + return (user.mind.special_role && user.mind.original == user) - if(!target || !istype(target)) - return - - var/istraitor = target.mind.special_role - if (istraitor) - failmsg = "failed (target is traitor) " - target.lockcharge = !target.lockcharge - if (target.lockcharge) - to_chat(target, "Someone tried to lock you down!") - else - to_chat(target, "Someone tried to lift your lockdown!") - else if (target.emagged) - failmsg = "failed (target is hacked) " - target.lockcharge = !target.lockcharge - if (target.lockcharge) - to_chat(target, "Someone tried to lock you down!") - else - to_chat(target, "Someone tried to lift your lockdown!") - else - target.canmove = !target.canmove - target.lockcharge = !target.canmove //when canmove is 1, lockcharge should be 0 - target.lockdown = !target.canmove - if (target.lockcharge) - to_chat(target, "You have been locked down!") - else - to_chat(target, "Your lockdown has been lifted!") - message_admins("[key_name_admin(usr)] [failmsg][target.lockcharge ? "lockdown" : "release"] on [target.name]!") - log_game("[key_name(usr)] attempted to [target.lockcharge ? "lockdown" : "release"] [target.name] on the robotics console!") +/** + * Check if the user is allowed to hack a specific borg + * + * Returns TRUE if a user can hack the specific cyborg + * Returns FALSE if a user cannot + * Arguments: + * * user - The [mob/user] to be checked + * * R - The [mob/living/silicon/robot] to be checked + */ +/obj/machinery/computer/robotics/proc/can_hack(mob/user, mob/living/silicon/robot/R) + if(!can_hack_any(user)) + return FALSE + if(!istype(R)) + return FALSE + if(R.emagged) + return FALSE + if(R.connected_ai != user) + return FALSE + return TRUE - // Remotely hacks the cyborg. Only antag AIs can do this and only to linked cyborgs. - else if (href_list["hack"]) - var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["hack"]) - if(!target || !istype(target)) - return - - // Antag synthetic checks - if(!istype(user, /mob/living/silicon) || !(user.mind.special_role && user.mind.original == user)) - to_chat(user, "Access Denied") - return - - if(target.emagged) - to_chat(user, "Robot is already hacked.") - return - - var/choice = input("Really hack [target.name]? This cannot be undone.") in list("Yes", "No") - if(choice != "Yes") - return - - if(!target || !istype(target)) - return - - message_admins("[key_name_admin(usr)] emagged [target.name] using the robotic console!") - log_game("[key_name(usr)] emagged [target.name] using robotic console!") - target.emagged = 1 - to_chat(target, "Failsafe protocols overriden. New tools available.") - - -// Proc: get_cyborgs() -// Parameters: 1 (operator - mob which is operating the console.) -// Description: Returns NanoUI-friendly list of accessible cyborgs. -/obj/machinery/computer/robotics/proc/get_cyborgs(var/mob/operator) - var/list/robots = list() +/obj/machinery/computer/robotics/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RoboticsControlConsole", name) + ui.open() +/obj/machinery/computer/robotics/tgui_data(mob/user) + var/list/data = list() + data["auth"] = is_authenticated(user) + data["can_hack"] = can_hack_any(user) + data["cyborgs"] = list() + data["safety"] = safety for(var/mob/living/silicon/robot/R in mob_list) - // Ignore drones - if(istype(R, /mob/living/silicon/robot/drone)) - continue - // Ignore antagonistic cyborgs - if(R.scrambledcodes) + if(!console_shows(R)) continue + var/area/A = get_area(R) + var/turf/T = get_turf(R) + var/list/cyborg_data = list( + name = R.name, + ref = REF(R), + locked_down = R.lockcharge, + locstring = "[A.name] ([T.x], [T.y])", + status = R.stat, + health = round(R.health * 100 / R.maxHealth, 0.1), + charge = R.cell ? round(R.cell.percent()) : null, + cell_capacity = R.cell ? R.cell.maxcharge : null, + module = R.module ? R.module.name : "No Module Detected", + synchronization = R.connected_ai, + is_hacked = R.connected_ai && R.emagged, + hackable = can_hack(user, R), + ) + data["cyborgs"] += list(cyborg_data) + data["show_detonate_all"] = (data["auth"] && length(data["cyborgs"]) > 0 && ishuman(user)) + return data - var/list/robot = list() - robot["name"] = R.name - if(R.stat) - robot["status"] = "Not Responding" - else if (R.lockcharge) - robot["status"] = "Lockdown" - else - robot["status"] = "Operational" - - if(R.cell) - robot["cell"] = 1 - robot["cell_capacity"] = R.cell.maxcharge - robot["cell_current"] = R.cell.charge - robot["cell_percentage"] = round(R.cell.percent()) - else - robot["cell"] = 0 - - robot["module"] = R.module ? R.module.name : "None" - robot["master_ai"] = R.connected_ai ? R.connected_ai.name : "None" - robot["hackable"] = 0 - //Antag synths should be able to hack themselves and see their hacked status. - if(operator && isrobot(operator) && (operator.mind.special_role && operator.mind.original == operator) && (operator == R)) - robot["hacked"] = R.emagged ? 1 : 0 - robot["hackable"] = R.emagged? 0 : 1 - // Antag AIs know whether linked cyborgs are hacked or not. - if(operator && isAI(operator) && (R.connected_ai == operator) && (operator.mind.special_role && operator.mind.original == operator)) - robot["hacked"] = R.emagged ? 1 : 0 - robot["hackable"] = R.emagged? 0 : 1 - robots.Add(list(robot)) - return robots - -// Proc: get_cyborg_by_name() -// Parameters: 1 (name - Cyborg we are trying to find) -// Description: Helper proc for finding cyborg by name -/obj/machinery/computer/robotics/proc/get_cyborg_by_name(var/name) - if (!name) +/obj/machinery/computer/robotics/tgui_act(action, params) + if(..()) return - for(var/mob/living/silicon/robot/R in mob_list) - if(R.name == name) - return R + . = FALSE + if(!is_authenticated(usr)) + to_chat(usr, "Access denied.") + return + switch(action) + if("arm") // Arms the emergency self-destruct system + if(issilicon(usr)) + to_chat(usr, "Access Denied (silicon detected)") + return + safety = !safety + to_chat(usr, "You [safety ? "disarm" : "arm"] the emergency self destruct.") + . = TRUE + if("nuke") // Destroys all accessible cyborgs if safety is disabled + if(issilicon(usr)) + to_chat(usr, "Access Denied (silicon detected)") + return + if(safety) + to_chat(usr, "Self-destruct aborted - safety active") + return + message_admins("[key_name_admin(usr)] detonated all cyborgs!") + log_game("\[key_name(usr)] detonated all cyborgs!") + for(var/mob/living/silicon/robot/R in mob_list) + if(istype(R, /mob/living/silicon/robot/drone)) + continue + // Ignore antagonistic cyborgs + if(R.scrambledcodes) + continue + to_chat(R, "Self-destruct command received.") + if(R.connected_ai) + to_chat(R.connected_ai, "

ALERT - Cyborg detonation detected: [R.name]
") + R.self_destruct() + . = TRUE + if("killbot") // destroys one specific cyborg + var/mob/living/silicon/robot/R = locate(params["ref"]) + if(!can_control(usr, R, TRUE)) + return + if(R.mind && R.mind.special_role && R.emagged) + to_chat(R, "Extreme danger! Termination codes detected. Scrambling security codes and automatic AI unlink triggered.") + R.ResetSecurityCodes() + . = TRUE + return + var/turf/T = get_turf(R) + message_admins("[key_name_admin(usr)] detonated [key_name_admin(R)] ([ADMIN_COORDJMP(T)])!") + log_game("\[key_name(usr)] detonated [key_name(R)]!") + to_chat(R, "Self-destruct command received.") + if(R.connected_ai) + to_chat(R.connected_ai, "

ALERT - Cyborg detonation detected: [R.name]
") + R.self_destruct() + . = TRUE + if("stopbot") // lock or unlock the borg + if(isrobot(usr)) + to_chat(usr, "Access Denied.") + return + var/mob/living/silicon/robot/R = locate(params["ref"]) + if(!can_control(usr, R, TRUE)) + return + message_admins("[ADMIN_LOOKUPFLW(usr)] [!R.lockcharge ? "locked down" : "released"] [ADMIN_LOOKUPFLW(R)]!") + log_game("[key_name(usr)] [!R.lockcharge ? "locked down" : "released"] [key_name(R)]!") + R.SetLockdown(!R.lockcharge) + to_chat(R, "[!R.lockcharge ? "Your lockdown has been lifted!" : "You have been locked down!"]") + if(R.connected_ai) + to_chat(R.connected_ai, "[!R.lockcharge ? "NOTICE - Cyborg lockdown lifted" : "ALERT - Cyborg lockdown detected"]: [R.name]
") + . = TRUE + if("hackbot") // AIs hacking/emagging a borg + var/mob/living/silicon/robot/R = locate(params["ref"]) + if(!can_hack(usr, R)) + return + var/choice = input("Really hack [R.name]? This cannot be undone.") in list("Yes", "No") + if(choice != "Yes") + return + log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!") + message_admins("[key_name_admin(usr)] emagged [key_name_admin(R)] using robotic console!") + R.emagged = TRUE + to_chat(R, "Failsafe protocols overriden. New tools available.") + . = TRUE diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index be93c2ce4f..b7c8ecc45b 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -509,4 +509,4 @@ /obj/machinery/computer/secure_data/detective_computer icon_state = "messyfiles" -#undef FIELD \ No newline at end of file +#undef FIELD diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index 6a6fd60703..7783fa7eb0 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -34,6 +34,7 @@ if(..()) return if(!allowed(user)) + to_chat(user, "You don't have the required access to use this console.") return user.set_machine(src) tgui_interact(user) diff --git a/code/game/machinery/computer3/computers/card.dm b/code/game/machinery/computer3/computers/card.dm index 5647ff0ceb..35eb699531 100644 --- a/code/game/machinery/computer3/computers/card.dm +++ b/code/game/machinery/computer3/computers/card.dm @@ -35,8 +35,8 @@ var jobs_all = "" jobs_all += "" - jobs_all += ""//Colony Director in special because he is head of heads ~Intercross21 - jobs_all += "" + jobs_all += ""//Site Manager in special because he is head of heads ~Intercross21 + jobs_all += "" jobs_all += "" counter = 0 diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 463773fdf7..8f33d05787 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -39,12 +39,16 @@ var/secured_wires = 0 var/datum/wires/airlock/wires = null - var/open_sound_powered = 'sound/machines/airlock.ogg' - var/open_sound_unpowered = 'sound/machines/airlockforced.ogg' - var/close_sound_powered = 'sound/machines/airlockclose.ogg' + var/open_sound_powered = 'sound/machines/door/covert1o.ogg' + var/open_sound_unpowered = 'sound/machines/door/airlockforced.ogg' + var/close_sound_powered = 'sound/machines/door/covert1c.ogg' + var/legacy_open_powered = 'sound/machines/door/old_airlock.ogg' + var/legacy_close_powered = 'sound/machines/door/old_airlockclose.ogg' + var/department_open_powered = null + var/department_close_powered = null var/denied_sound = 'sound/machines/deniedbeep.ogg' - var/bolt_up_sound = 'sound/machines/boltsup.ogg' - var/bolt_down_sound = 'sound/machines/boltsdown.ogg' + var/bolt_up_sound = 'sound/machines/door/boltsup.ogg' + var/bolt_down_sound = 'sound/machines/door/boltsdown.ogg' /obj/machinery/door/airlock/attack_generic(var/mob/living/user, var/damage) if(stat & (BROKEN|NOPOWER)) @@ -81,7 +85,7 @@ if(do_after(user,5 SECONDS,src)) visible_message("\The [user] forces \the [src] open, sparks flying from its electronics!") src.do_animate("spark") - playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) src.locked = 0 src.welded = 0 update_icon() @@ -90,7 +94,7 @@ else if(src.density) visible_message("\The [user] begins forcing \the [src] open!") if(do_after(user, 5 SECONDS,src)) - playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) visible_message("\The [user] forces \the [src] open!") open(1) else @@ -112,40 +116,66 @@ icon = 'icons/obj/doors/Doorcom.dmi' req_one_access = list(access_heads) assembly_type = /obj/structure/door_assembly/door_assembly_com + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cmd3o.ogg' + department_close_powered = 'sound/machines/door/cmd3c.ogg' /obj/machinery/door/airlock/security name = "Security Airlock" icon = 'icons/obj/doors/Doorsec.dmi' req_one_access = list(access_security) assembly_type = /obj/structure/door_assembly/door_assembly_sec + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sec1o.ogg' + department_close_powered = 'sound/machines/door/sec1c.ogg' /obj/machinery/door/airlock/engineering name = "Engineering Airlock" icon = 'icons/obj/doors/Dooreng.dmi' req_one_access = list(access_engine) assembly_type = /obj/structure/door_assembly/door_assembly_eng + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' /obj/machinery/door/airlock/engineeringatmos name = "Atmospherics Airlock" icon = 'icons/obj/doors/Doorengatmos.dmi' req_one_access = list(access_atmospherics) assembly_type = /obj/structure/door_assembly/door_assembly_eat + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' /obj/machinery/door/airlock/medical name = "Medical Airlock" icon = 'icons/obj/doors/Doormed.dmi' req_one_access = list(access_medical) assembly_type = /obj/structure/door_assembly/door_assembly_med + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/med1o.ogg' + department_close_powered = 'sound/machines/door/med1c.ogg' /obj/machinery/door/airlock/maintenance name = "Maintenance Access" icon = 'icons/obj/doors/Doormaint.dmi' //req_one_access = list(access_maint_tunnels) //VOREStation Edit - Maintenance is open access assembly_type = /obj/structure/door_assembly/door_assembly_mai + open_sound_powered = 'sound/machines/door/door2o.ogg' + close_sound_powered = 'sound/machines/door/door2c.ogg' /obj/machinery/door/airlock/maintenance/cargo icon = 'icons/obj/doors/Doormaint_cargo.dmi' req_one_access = list(access_cargo) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/door2o.ogg' + department_close_powered = 'sound/machines/door/door2c.ogg' /obj/machinery/door/airlock/maintenance/command icon = 'icons/obj/doors/Doormaint_command.dmi' @@ -153,6 +183,8 @@ /obj/machinery/door/airlock/maintenance/common icon = 'icons/obj/doors/Doormaint_common.dmi' + open_sound_powered = 'sound/machines/door/hall3o.ogg' + close_sound_powered = 'sound/machines/door/hall3c.ogg' /obj/machinery/door/airlock/maintenance/engi icon = 'icons/obj/doors/Doormaint_engi.dmi' @@ -177,6 +209,8 @@ name = "External Airlock" icon = 'icons/obj/doors/Doorext.dmi' assembly_type = /obj/structure/door_assembly/door_assembly_ext + open_sound_powered = 'sound/machines/door/space1o.ogg' + close_sound_powered = 'sound/machines/door/space1c.ogg' /obj/machinery/door/airlock/external/glass/bolted icon_state = "door_locked" // So it looks visibly bolted in map editor @@ -193,12 +227,16 @@ opacity = 0 glass = 1 req_one_access = list(access_external_airlocks) + open_sound_powered = 'sound/machines/door/space1o.ogg' + close_sound_powered = 'sound/machines/door/space1c.ogg' /obj/machinery/door/airlock/glass name = "Glass Airlock" icon = 'icons/obj/doors/Doorglass.dmi' hitsound = 'sound/effects/Glasshit.ogg' - open_sound_powered = 'sound/machines/windowdoor.ogg' + open_sound_powered = 'sound/machines/door/hall1o.ogg' + close_sound_powered = 'sound/machines/door/hall1c.ogg' + legacy_open_powered = 'sound/machines/door/windowdoor.ogg' maxhealth = 300 explosion_resistance = 5 opacity = 0 @@ -209,12 +247,16 @@ icon = 'icons/obj/doors/Doorele.dmi' req_one_access = list(access_cent_general) opacity = 1 + open_sound_powered = 'sound/machines/door/cmd3o.ogg' + close_sound_powered = 'sound/machines/door/cmd3c.ogg' /obj/machinery/door/airlock/glass_centcom name = "Airlock" icon = 'icons/obj/doors/Dooreleglass.dmi' opacity = 0 glass = 1 + open_sound_powered = 'sound/machines/door/cmd3o.ogg' + close_sound_powered = 'sound/machines/door/cmd3c.ogg' /obj/machinery/door/airlock/vault name = "Vault" @@ -224,6 +266,8 @@ secured_wires = 1 assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites. req_one_access = list(access_heads_vault) + open_sound_powered = 'sound/machines/door/vault1o.ogg' + close_sound_powered = 'sound/machines/door/vault1c.ogg' /obj/machinery/door/airlock/vault/bolted icon_state = "door_locked" @@ -242,6 +286,9 @@ opacity = 1 assembly_type = /obj/structure/door_assembly/door_assembly_hatch req_one_access = list(access_maint_tunnels) + open_sound_powered = 'sound/machines/door/hatchopen.ogg' + close_sound_powered = 'sound/machines/door/hatchclose.ogg' + open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' /obj/machinery/door/airlock/maintenance_hatch name = "Maintenance Hatch" @@ -250,6 +297,9 @@ opacity = 1 assembly_type = /obj/structure/door_assembly/door_assembly_mhatch req_one_access = list(access_maint_tunnels) + open_sound_powered = 'sound/machines/door/hatchopen.ogg' + close_sound_powered = 'sound/machines/door/hatchclose.ogg' + open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' /obj/machinery/door/airlock/glass_command name = "Command Airlock" @@ -261,6 +311,10 @@ assembly_type = /obj/structure/door_assembly/door_assembly_com glass = 1 req_one_access = list(access_heads) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cmd1o.ogg' + department_close_powered = 'sound/machines/door/cmd1c.ogg' /obj/machinery/door/airlock/glass_engineering name = "Engineering Airlock" @@ -272,6 +326,8 @@ assembly_type = /obj/structure/door_assembly/door_assembly_eng glass = 1 req_one_access = list(access_engine) + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' /obj/machinery/door/airlock/glass_engineeringatmos name = "Atmospherics Airlock" @@ -283,6 +339,10 @@ assembly_type = /obj/structure/door_assembly/door_assembly_eat glass = 1 req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' /obj/machinery/door/airlock/glass_security name = "Security Airlock" @@ -294,6 +354,10 @@ assembly_type = /obj/structure/door_assembly/door_assembly_sec glass = 1 req_one_access = list(access_security) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sec1o.ogg' + department_close_powered = 'sound/machines/door/sec1c.ogg' /obj/machinery/door/airlock/glass_medical name = "Medical Airlock" @@ -305,23 +369,39 @@ assembly_type = /obj/structure/door_assembly/door_assembly_med glass = 1 req_one_access = list(access_medical) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/med1o.ogg' + department_close_powered = 'sound/machines/door/med1c.ogg' /obj/machinery/door/airlock/mining name = "Mining Airlock" icon = 'icons/obj/doors/Doormining.dmi' assembly_type = /obj/structure/door_assembly/door_assembly_min req_one_access = list(access_mining) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cgo1o.ogg' + department_close_powered = 'sound/machines/door/cgo1c.ogg' /obj/machinery/door/airlock/atmos name = "Atmospherics Airlock" icon = 'icons/obj/doors/Dooratmo.dmi' assembly_type = /obj/structure/door_assembly/door_assembly_atmo req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' /obj/machinery/door/airlock/research name = "Research Airlock" icon = 'icons/obj/doors/Doorresearch.dmi' assembly_type = /obj/structure/door_assembly/door_assembly_research + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' /obj/machinery/door/airlock/glass_research name = "Research Airlock" @@ -333,6 +413,10 @@ assembly_type = /obj/structure/door_assembly/door_assembly_research glass = 1 req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' /obj/machinery/door/airlock/glass_mining name = "Mining Airlock" @@ -344,6 +428,10 @@ assembly_type = /obj/structure/door_assembly/door_assembly_min glass = 1 req_one_access = list(access_mining) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cgo1o.ogg' + department_close_powered = 'sound/machines/door/cgo1c.ogg' /obj/machinery/door/airlock/glass_atmos name = "Atmospherics Airlock" @@ -355,6 +443,10 @@ assembly_type = /obj/structure/door_assembly/door_assembly_atmo glass = 1 req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' /obj/machinery/door/airlock/gold name = "Gold Airlock" @@ -435,6 +527,10 @@ icon = 'icons/obj/doors/Doorsci.dmi' assembly_type = /obj/structure/door_assembly/door_assembly_science req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' /obj/machinery/door/airlock/glass_science name = "Glass Airlocks" @@ -443,6 +539,10 @@ assembly_type = /obj/structure/door_assembly/door_assembly_science glass = 1 req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' /obj/machinery/door/airlock/highsecurity name = "Secure Airlock" @@ -451,6 +551,8 @@ secured_wires = 1 assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity req_one_access = list(access_heads_vault) + open_sound_powered = 'sound/machines/door/secure1o.ogg' + close_sound_powered = 'sound/machines/door/secure1c.ogg' /obj/machinery/door/airlock/voidcraft name = "voidcraft hatch" @@ -460,11 +562,15 @@ opacity = 0 glass = 1 assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft + open_sound_powered = 'sound/machines/door/shuttle1o.ogg' + close_sound_powered = 'sound/machines/door/shuttle1c.ogg' // Airlock opens from top-bottom instead of left-right. /obj/machinery/door/airlock/voidcraft/vertical icon = 'icons/obj/doors/shuttledoors_vertical.dmi' assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft/vertical + open_sound_powered = 'sound/machines/door/shuttle1o.ogg' + close_sound_powered = 'sound/machines/door/shuttle1c.ogg' /datum/category_item/catalogue/anomalous/precursor_a/alien_airlock @@ -1107,10 +1213,41 @@ About the new airlock wires panel: use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people //if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator - if(arePowerSystemsOn()) - playsound(src, open_sound_powered, 50, 1) - else - playsound(src, open_sound_unpowered, 75, 1) + for(var/P in player_list) + var/mob/M = P + if(!M || !M.client) + continue + var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) + var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) + var/sound + var/volume + if(old_sounds) // Do we have old sounds enabled? Play these even if we have department door sounds enabled. + if(arePowerSystemsOn()) + sound = legacy_open_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else if(!old_sounds && department_door_sounds && src.department_open_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. + if(arePowerSystemsOn()) + sound = department_open_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else // Else, play these. + if(arePowerSystemsOn()) + sound = open_sound_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + + var/turf/T = get_turf(M) + var/distance = get_dist(T, get_turf(src)) + if(distance <= world.view * 2) + if(T && T.z == get_z(src)) + M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) src.closeOther.close() @@ -1205,10 +1342,41 @@ About the new airlock wires panel: use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people has_beeped = 0 - if(arePowerSystemsOn()) - playsound(src, close_sound_powered, 50, 1) - else - playsound(src, open_sound_unpowered, 75, 1) + for(var/P in player_list) + var/mob/M = P + if(!M || !M.client) + continue + var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) + var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) + var/sound + var/volume + if(old_sounds) + if(arePowerSystemsOn()) + sound = legacy_close_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else if(!old_sounds && department_door_sounds && src.department_close_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. + if(arePowerSystemsOn()) + sound = department_close_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else + if(arePowerSystemsOn()) + sound = close_sound_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + + var/turf/T = get_turf(M) + var/distance = get_dist(T, get_turf(src)) + if(distance <= world.view * 2) + if(T && T.z == get_z(src)) + M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) for(var/turf/turf in locs) var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf) if(killthis) @@ -1222,7 +1390,7 @@ About the new airlock wires panel: if (operating && !forced) return 0 src.locked = 1 - playsound(src, bolt_down_sound, 30, 0, 3) + playsound(src, bolt_down_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) for(var/mob/M in range(1,src)) M.show_message("You hear a click from the bottom of the door.", 2) update_icon() @@ -1236,7 +1404,7 @@ About the new airlock wires panel: if(operating || !src.arePowerSystemsOn() || wires.is_cut(WIRE_DOOR_BOLTS)) return src.locked = 0 - playsound(src, bolt_up_sound, 30, 0, 3) + playsound(src, bolt_up_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) for(var/mob/M in range(1,src)) M.show_message("You hear a click from the bottom of the door.", 2) update_icon() diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm index 569c413f94..a6b503cdbd 100644 --- a/code/game/machinery/doors/blast_door.dm +++ b/code/game/machinery/doors/blast_door.dm @@ -25,8 +25,8 @@ var/icon_state_opening = null var/icon_state_closed = null var/icon_state_closing = null - var/open_sound = 'sound/machines/blastdooropen.ogg' - var/close_sound = 'sound/machines/blastdoorclose.ogg' + var/open_sound = 'sound/machines/door/blastdooropen.ogg' + var/close_sound = 'sound/machines/door/blastdoorclose.ogg' var/damage = BLAST_DOOR_CRUSH_DAMAGE var/multiplier = 1 // The multiplier for how powerful our YEET is. @@ -125,7 +125,7 @@ // Description: Opens or closes the door, depending on current state. No checks are done inside this proc. /obj/machinery/door/blast/proc/force_toggle(var/forced = 0, mob/user as mob) if (forced) - playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1) if(src.density) src.force_open() @@ -219,13 +219,13 @@ if(src.density) visible_message("\The [user] begins forcing \the [src] open!") if(do_after(user, 15 SECONDS,src)) - playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1) visible_message("\The [user] forces \the [src] open!") force_open(1) else visible_message("\The [user] begins forcing \the [src] closed!") if(do_after(user, 5 SECONDS,src)) - playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1) visible_message("\The [user] forces \the [src] closed!") force_close(1) else diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index e31465168f..6cae2617fd 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -200,14 +200,14 @@ if(src.blocked) visible_message("\The [user] begins digging into \the [src] internals!") if(do_after(user,5 SECONDS,src)) - playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1) src.blocked = 0 update_icon() open(1) else if(src.density) visible_message("\The [user] begins forcing \the [src] open!") if(do_after(user, 2 SECONDS,src)) - playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1) visible_message("\The [user] forces \the [src] open!") open(1) else diff --git a/code/game/machinery/doors/multi_tile.dm b/code/game/machinery/doors/multi_tile.dm index f05419cb6d..ec5acbea73 100644 --- a/code/game/machinery/doors/multi_tile.dm +++ b/code/game/machinery/doors/multi_tile.dm @@ -4,6 +4,8 @@ appearance_flags = 0 var/obj/machinery/filler_object/filler1 var/obj/machinery/filler_object/filler2 + open_sound_powered = 'sound/machines/door/WideOpen.ogg' + close_sound_powered = 'sound/machines/door/WideClose.ogg' /obj/machinery/door/airlock/multi_tile/New() ..() diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 98fb1c75d8..cfd0b3706c 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -115,7 +115,7 @@ if (!operating) //in case of emag operating = 1 flick(text("[src.base_state]opening"), src) - playsound(src, 'sound/machines/windowdoor.ogg', 100, 1) + playsound(src, 'sound/machines/door/windowdoor.ogg', 100, 1) sleep(10) explosion_resistance = 0 @@ -132,7 +132,7 @@ return FALSE operating = TRUE flick(text("[]closing", src.base_state), src) - playsound(src, 'sound/machines/windowdoor.ogg', 100, 1) + playsound(src, 'sound/machines/door/windowdoor.ogg', 100, 1) density = TRUE update_icon() diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 75004ae7be..cab4f5c37f 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -45,10 +45,7 @@ var/list/doppler_arrays = list() /obj/machinery/doppler_array/power_change() ..() - if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" + if(!(stat & NOPOWER)) + icon_state = initial(icon_state) else - if(!(stat & NOPOWER)) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]-off" \ No newline at end of file + icon_state = "[initial(icon_state)]_off" diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index ad82ffd656..5aa42ff26a 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -68,6 +68,11 @@ var/flash_time = strength if(istype(O, /mob/living/carbon/human)) var/mob/living/carbon/human/H = O + //VOREStation Edit Start + if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION)) + H.nif.notify("High intensity light detected, and blocked!",TRUE) + continue + //VOREStation Edit End if(!H.eyecheck() <= 0) continue flash_time *= H.species.flash_mod diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index b59bec3384..6ea6e58905 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -810,6 +810,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster) var/scribble="" var/scribble_page = null drop_sound = 'sound/items/drop/wrapper.ogg' + pickup_sound = 'sound/items/pickup/wrapper.ogg' obj/item/weapon/newspaper/attack_self(mob/user as mob) if(ishuman(user)) diff --git a/code/game/machinery/partslathe_vr.dm b/code/game/machinery/partslathe_vr.dm index a4a027d5e4..aab15f40f9 100644 --- a/code/game/machinery/partslathe_vr.dm +++ b/code/game/machinery/partslathe_vr.dm @@ -234,116 +234,123 @@ if(..()) return ui_interact(user) + tgui_interact(user) -/obj/machinery/partslathe/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/partslathe/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/sheetmaterials) + ) - var/data[0] +/obj/machinery/partslathe/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PartsLathe", name) + ui.open() + +/obj/machinery/partslathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() data["panelOpen"] = panel_open - var/materials_ui[0] + var/list/materials_ui = list() for(var/M in materials) - materials_ui[++materials_ui.len] = list( - "name" = M, - "display" = material_display_name(M), - "qty" = materials[M], - "max" = storage_capacity[M], - "percent" = (materials[M] / storage_capacity[M] * 100)) + materials_ui.Add(list(list( + "name" = M, + "amount" = materials[M], + "sheets" = round(materials[M] / SHEET_MATERIAL_AMOUNT), + "removable" = materials[M] >= SHEET_MATERIAL_AMOUNT, + ))) data["materials"] = materials_ui + data["copyBoard"] = null + data["copyBoardReqComponents"] = null if(istype(copy_board)) data["copyBoard"] = copy_board.name - var/req_components_ui[0] + var/list/req_components_ui = list() for(var/CP in (copy_board.req_components || list())) var/obj/comp_path = CP var/comp_amt = copy_board.req_components[comp_path] if(comp_amt && (comp_path in partslathe_recipies)) - req_components_ui[++req_components_ui.len] = list("name" = initial(comp_path.name), "qty" = comp_amt) + req_components_ui.Add(list(list("name" = initial(comp_path.name), "qty" = comp_amt))) data["copyBoardReqComponents"] = req_components_ui data["queue"] = list() for(var/datum/category_item/partslathe/Q in queue) data["queue"] += Q.name + data["building"] = null + data["buildPercent"] = null if(busy && queue.len > 0) var/datum/category_item/partslathe/current = queue[1] data["building"] = current.name - data["buildProgress"] = progress - data["buildTime"] = current.time data["buildPercent"] = (progress / current.time * 100) + + data["error"] = null if(queue.len > 0 && !canBuild(queue[1])) data["error"] = getLackingMaterials(queue[1]) - var/recipies_ui[0] + var/list/recipies_ui = list() for(var/T in partslathe_recipies) var/datum/category_item/partslathe/R = partslathe_recipies[T] - recipies_ui[++recipies_ui.len] = list("name" = R.name, "type" = "[T]") + recipies_ui.Add(list(list("name" = R.name, "type" = "[T]"))) data["recipies"] = recipies_ui - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "partslathe.tmpl", "Parts Lathe UI", 500, 450) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) + return data -/obj/machinery/partslathe/Topic(href, href_list) +/obj/machinery/partslathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 - usr.set_machine(src) + return TRUE + add_fingerprint(usr) - - // Queue management can be done even while busy - if(href_list["queue"]) - var/type_to_build = text2path(href_list["queue"]) - var/datum/category_item/partslathe/to_build = partslathe_recipies[type_to_build] - if(to_build) - addToQueue(to_build) - updateUsrDialog() - return - - if(href_list["queueBoard"]) - if(!istype(copy_board) || !copy_board.req_components) - return - for(var/comp_path in copy_board.req_components) - var/comp_amt = copy_board.req_components[comp_path] - if(!comp_amt) - continue - var/datum/category_item/partslathe/to_build = partslathe_recipies[comp_path] - if(!to_build) - continue // We don't support building whatever this is - for(var/i in 1 to comp_amt) + switch(action) + // Queue management can be done even while busy + if("queue") + var/type_to_build = text2path(params["queue"]) + var/datum/category_item/partslathe/to_build = partslathe_recipies[type_to_build] + if(to_build) addToQueue(to_build) - return + return TRUE - if(href_list["cancel"]) - var/index = text2num(href_list["cancel"]) - if(index < 1 || index > queue.len) - return - if(busy && index == 1) - return - removeFromQueue(index) - return + if("queueBoard") + if(!istype(copy_board) || !copy_board.req_components) + return + for(var/comp_path in copy_board.req_components) + var/comp_amt = copy_board.req_components[comp_path] + if(!comp_amt) + continue + var/datum/category_item/partslathe/to_build = partslathe_recipies[comp_path] + if(!to_build) + continue // We don't support building whatever this is + for(var/i in 1 to comp_amt) + addToQueue(to_build) + return TRUE + + if("cancel") + var/index = text2num(params["cancel"]) + if(index < 1 || index > queue.len) + return + if(busy && index == 1) + return + removeFromQueue(index) + return TRUE if(busy) - to_chat(usr, "\The [src]is busy. Please wait for completion of previous operation.") + to_chat(usr, "[src] is busy. Please wait for completion of previous operation.") return - if(href_list["ejectBoard"]) - if(copy_board) - visible_message("\The [copy_board] is ejected from \the [src]'s circuit reader.") - copy_board.forceMove(src.loc) - copy_board = null - updateUsrDialog() - return + switch(action) + if("ejectBoard") + if(copy_board) + visible_message("[copy_board] is ejected from [src]'s circuit reader.") + copy_board.forceMove(src.loc) + copy_board = null + return TRUE - if(href_list["ejectMaterial"]) - var/matName = href_list["ejectMaterial"] - if(!(matName in materials)) + if("remove_mat") + // Remove a material from the fab + var/mat_id = params["id"] + var/amount = text2num(params["amount"]) + eject_materials(mat_id, amount) return - eject_materials(matName, 0) - updateUsrDialog() - return /** Build list of recipies to include all tech level 1 stock parts. */ /obj/machinery/partslathe/proc/update_recipe_list() diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm index 9977e765e9..75d7542ba1 100644 --- a/code/game/machinery/seed_extractor.dm +++ b/code/game/machinery/seed_extractor.dm @@ -16,10 +16,10 @@ obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob var/datum/seed/new_seed_type if(istype(O, /obj/item/weapon/grown)) var/obj/item/weapon/grown/F = O - new_seed_type = plant_controller.seeds[F.plantname] + new_seed_type = SSplants.seeds[F.plantname] else var/obj/item/weapon/reagent_containers/food/snacks/grown/F = O - new_seed_type = plant_controller.seeds[F.plantname] + new_seed_type = SSplants.seeds[F.plantname] if(new_seed_type) to_chat(user, "You extract some seeds from [O].") diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index e7acfe1f41..e0f0695565 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -139,7 +139,7 @@ if("door") toggle_open(usr) . = TRUE - if("dispense") + if("dispense") switch(params["item"]) if("helmet") dispense_helmet(usr) @@ -653,12 +653,12 @@ name = "Vintage Pilot suit cycler" model_text = "Vintage Pilot" departments = list("Vintage Pilot (Bubble Helm)","Vintage Pilot (Closed Helm)") - + /obj/machinery/suit_cycler/vintage/medsci name = "Vintage MedSci suit cycler" model_text = "Vintage MedSci" departments = list("Vintage Medical (Bubble Helm)","Vintage Medical (Closed Helm)","Vintage Research (Bubble Helm)","Vintage Research (Closed Helm)") - + /obj/machinery/suit_cycler/vintage/rugged name = "Vintage Ruggedized suit cycler" model_text = "Vintage Ruggedized" @@ -751,7 +751,7 @@ if(istype(I,/obj/item/clothing/head/helmet/space/void/autolok)) to_chat(user, "You cannot refit an autolok helmet. In fact you shouldn't even be able to remove it in the first place. Inform an admin!") return - + //Ditto the Mk7 if(istype(I,/obj/item/clothing/head/helmet/space/void/responseteam)) to_chat(user, "The cycler indicates that the Mark VII Emergency Response Helmet is not compatible with the refitting system. How did you manage to detach it anyway? Inform an admin!") @@ -791,13 +791,13 @@ if(istype(I,/obj/item/clothing/suit/space/void/autolok)) to_chat(user, "You cannot refit an autolok suit.") return - + //Ditto the Mk7 if(istype(I,/obj/item/clothing/suit/space/void/responseteam)) to_chat(user, "The cycler indicates that the Mark VII Emergency Response Suit is not compatible with the refitting system.") return //VOREStation Edit ENDS - + to_chat(user, "You fit \the [I] into the suit cycler.") user.drop_item() I.loc = src @@ -886,7 +886,7 @@ return TRUE switch(action) - if("dispense") + if("dispense") switch(params["item"]) if("helmet") helmet.forceMove(get_turf(src)) @@ -895,23 +895,23 @@ suit.forceMove(get_turf(src)) suit = null . = TRUE - + if("department") var/choice = params["department"] if(choice in departments) target_department = choice . = TRUE - + if("species") var/choice = params["species"] if(choice in species) target_species = choice . = TRUE - + if("radlevel") radiation_level = clamp(params["radlevel"], 1, emagged ? 5 : 3) . = TRUE - + if("repair_suit") if(!suit || !can_repair) return @@ -1055,7 +1055,7 @@ if(target_species) if(helmet) helmet.refit_for_species(target_species) - if(suit) + if(suit) suit.refit_for_species(target_species) if(suit.helmet) suit.helmet.refit_for_species(target_species) @@ -1176,7 +1176,7 @@ parent_suit = /obj/item/clothing/suit/space/void/refurb/mercenary //BEGIN: Space for additional downstream variants //VOREStation Addition Start - if("Director") + if("Manager") parent_helmet = /obj/item/clothing/head/helmet/space/void/captain parent_suit = /obj/item/clothing/suit/space/void/captain if("Prototype") @@ -1217,7 +1217,7 @@ parent_suit = /obj/item/clothing/suit/space/void/refurb/mercenary/talon //VOREStation Addition End //END: downstream variant space - + //look at this! isn't it beautiful? -KK (well ok not beautiful but it's a lot cleaner) if(helmet && target_department != "No Change") var/obj/item/clothing/H = new parent_helmet @@ -1235,9 +1235,9 @@ suit.desc = initial(parent_suit.desc) suit.icon_state = initial(parent_suit.icon_state) suit.item_state = initial(parent_suit.item_state) - suit.item_state_slots = S.item_state_slots + suit.item_state_slots = S.item_state_slots qdel(S) - + //can't believe I forgot to fix this- now helmets will properly cycle if they're attached to a suit -KK if(suit.helmet && target_department != "No Change") var/obj/item/clothing/AH = new parent_helmet diff --git a/code/game/machinery/suit_storage_unit_vr.dm b/code/game/machinery/suit_storage_unit_vr.dm index cec50f5fcc..c0353dc41e 100644 --- a/code/game/machinery/suit_storage_unit_vr.dm +++ b/code/game/machinery/suit_storage_unit_vr.dm @@ -1,5 +1,5 @@ /obj/machinery/suit_cycler - departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Emergency Medical Response","Crowd Control","Exploration","Pilot Blue","Pilot","Director","Prototype") + departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Emergency Medical Response","Crowd Control","Exploration","Pilot Blue","Pilot","Manager","Prototype") species = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_TESHARI, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_VULPKANIN, SPECIES_GREY_YW /*ywedit*/) // Old Exploration is too WIP to use right now @@ -11,10 +11,10 @@ req_access = list(access_pilot) /obj/machinery/suit_cycler/captain - name = "Director suit cycler" - model_text = "Director" + name = "Manager suit cycler" + model_text = "Manager" req_access = list(access_captain) - departments = list("Director") + departments = list("Manager") /obj/machinery/suit_cycler/captain/Initialize() //No Teshari Sprites species -= SPECIES_TESHARI diff --git a/code/game/machinery/vending_machines_vr.dm b/code/game/machinery/vending_machines_vr.dm index 007405b474..7261f9f66b 100644 --- a/code/game/machinery/vending_machines_vr.dm +++ b/code/game/machinery/vending_machines_vr.dm @@ -170,7 +170,7 @@ /obj/item/clothing/shoes/brown = 5, /obj/item/clothing/shoes/laceup = 5, /obj/item/clothing/shoes/green = 5, - /obj/item/clothing/shoes/leather = 5, + /obj/item/clothing/shoes/laceup/brown = 5, /obj/item/clothing/shoes/orange = 5, /obj/item/clothing/shoes/purple = 5, /obj/item/clothing/shoes/red = 5, @@ -228,7 +228,7 @@ /obj/item/clothing/shoes/brown = 50, /obj/item/clothing/shoes/laceup = 50, /obj/item/clothing/shoes/green = 50, - /obj/item/clothing/shoes/leather = 50, + /obj/item/clothing/shoes/laceup/brown = 50, /obj/item/clothing/shoes/orange = 50, /obj/item/clothing/shoes/purple = 50, /obj/item/clothing/shoes/red = 50, @@ -1172,7 +1172,19 @@ /obj/item/clothing/mask/gas/sexyclown = 3, /obj/item/clothing/under/sexyclown = 3, /obj/item/clothing/mask/gas/sexymime = 3, - /obj/item/clothing/under/sexymime = 3) + /obj/item/clothing/under/sexymime = 3, + /obj/item/clothing/suit/storage/hooded/knight_costume = 3, + /obj/item/clothing/suit/storage/hooded/knight_costume/galahad = 3, + /obj/item/clothing/suit/storage/hooded/knight_costume/lancelot = 3, + /obj/item/clothing/suit/storage/hooded/knight_costume/robin = 3, + /obj/item/clothing/suit/armor/combat/crusader_costume = 3, + /obj/item/clothing/suit/armor/combat/crusader_costume/bedevere = 3, + /obj/item/clothing/head/helmet/combat/crusader_costume = 3, + /obj/item/clothing/head/helmet/combat/bedevere_costume = 3, + /obj/item/clothing/gloves/combat/knight_costume = 3, + /obj/item/clothing/gloves/combat/knight_costume/brown = 3, + /obj/item/clothing/shoes/knight_costume = 3, + /obj/item/clothing/shoes/knight_costume/black = 3) prices = list(/obj/item/clothing/suit/storage/hooded/carp_costume = 200, /obj/item/clothing/suit/storage/hooded/carp_costume = 200, /obj/item/clothing/suit/chickensuit = 200, @@ -1225,7 +1237,19 @@ /obj/item/clothing/mask/gas/sexyclown = 600, /obj/item/clothing/under/sexyclown = 200, /obj/item/clothing/mask/gas/sexymime = 600, - /obj/item/clothing/under/sexymime = 200) + /obj/item/clothing/under/sexymime = 200, + /obj/item/clothing/suit/storage/hooded/knight_costume = 200, + /obj/item/clothing/suit/storage/hooded/knight_costume/galahad = 200, + /obj/item/clothing/suit/storage/hooded/knight_costume/lancelot = 200, + /obj/item/clothing/suit/storage/hooded/knight_costume/robin = 200, + /obj/item/clothing/suit/armor/combat/crusader_costume = 200, + /obj/item/clothing/suit/armor/combat/crusader_costume/bedevere = 200, + /obj/item/clothing/head/helmet/combat/crusader_costume = 200, + /obj/item/clothing/head/helmet/combat/bedevere_costume = 200, + /obj/item/clothing/gloves/combat/knight_costume = 200, + /obj/item/clothing/gloves/combat/knight_costume/brown = 200, + /obj/item/clothing/shoes/knight_costume = 200, + /obj/item/clothing/shoes/knight_costume/black = 200) premium = list(/obj/item/clothing/suit/imperium_monk = 3, /obj/item/clothing/suit/barding/agatha = 2, /obj/item/clothing/suit/barding/alt_agatha = 2, diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 617af4849f..bec2b1a6c3 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -21,6 +21,8 @@ var/energy_drain = 0 var/obj/mecha/chassis = null var/range = MELEE //bitflags + /// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this. + var/mech_flags = NONE var/salvageable = 1 var/required_type = /obj/mecha //may be either a type or a list of allowed types var/equip_type = null //mechaequip2 diff --git a/code/game/mecha/equipment/tools/clamp.dm b/code/game/mecha/equipment/tools/clamp.dm index 6091764c2b..0580134f33 100644 --- a/code/game/mecha/equipment/tools/clamp.dm +++ b/code/game/mecha/equipment/tools/clamp.dm @@ -33,7 +33,7 @@ if(FD.blocked) FD.visible_message("\The [chassis] begins prying on \the [FD]!") if(do_after(chassis.occupant,10 SECONDS,FD)) - playsound(FD, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(FD, 'sound/machines/door/airlock_creaking.ogg', 100, 1) FD.blocked = 0 FD.update_icon() FD.open(1) @@ -41,7 +41,7 @@ else if(FD.density) FD.visible_message("\The [chassis] begins forcing \the [FD] open!") if(do_after(chassis.occupant, 5 SECONDS,FD)) - playsound(FD, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(FD, 'sound/machines/door/airlock_creaking.ogg', 100, 1) FD.visible_message("\The [chassis] forces \the [FD] open!") FD.open(1) else @@ -57,7 +57,7 @@ if(do_after(chassis.occupant, 15 SECONDS,AD) && chassis.Adjacent(AD)) AD.welded = FALSE AD.update_icon() - playsound(AD, 'sound/machines/airlock_creaking.ogg', 100, 1) + playsound(AD, 'sound/machines/door/airlock_creaking.ogg', 100, 1) AD.visible_message("\The [chassis] tears \the [AD] open!") if(!AD.welded) if(density) diff --git a/code/game/mecha/equipment/tools/extinguisher.dm b/code/game/mecha/equipment/tools/extinguisher.dm index 98712726c0..4579c46919 100644 --- a/code/game/mecha/equipment/tools/extinguisher.dm +++ b/code/game/mecha/equipment/tools/extinguisher.dm @@ -1,6 +1,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/extinguisher name = "extinguisher" desc = "Exosuit-mounted extinguisher (Can be attached to: Engineering exosuits)" + mech_flags = EXOSUIT_MODULE_WORKING | EXOSUIT_MODULE_COMBAT icon_state = "mecha_exting" equip_cooldown = 5 energy_drain = 0 diff --git a/code/game/mecha/equipment/tools/rcd.dm b/code/game/mecha/equipment/tools/rcd.dm index 9aa9a8bb40..5d283c852b 100644 --- a/code/game/mecha/equipment/tools/rcd.dm +++ b/code/game/mecha/equipment/tools/rcd.dm @@ -1,6 +1,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/rcd name = "mounted RCD" desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)" + mech_flags = EXOSUIT_MODULE_WORKING|EXOSUIT_MODULE_COMBAT|EXOSUIT_MODULE_MEDICAL icon_state = "mecha_rcd" origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_POWER = 4) equip_cooldown = 10 diff --git a/code/game/mecha/equipment/tools/sleeper.dm b/code/game/mecha/equipment/tools/sleeper.dm index 861471b6ce..bdac763a5b 100644 --- a/code/game/mecha/equipment/tools/sleeper.dm +++ b/code/game/mecha/equipment/tools/sleeper.dm @@ -7,6 +7,7 @@ energy_drain = 20 range = MELEE equip_cooldown = 30 + mech_flags = EXOSUIT_MODULE_MEDICAL var/mob/living/carbon/human/occupant = null var/datum/global_iterator/pr_mech_sleeper var/inject_amount = 5 diff --git a/code/game/mecha/equipment/tools/syringe_gun.dm b/code/game/mecha/equipment/tools/syringe_gun.dm index a914839869..7449d80c0f 100644 --- a/code/game/mecha/equipment/tools/syringe_gun.dm +++ b/code/game/mecha/equipment/tools/syringe_gun.dm @@ -1,6 +1,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun name = "syringe gun" desc = "Exosuit-mounted chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur. (Can be attached to: Medical Exosuits)" + mech_flags = EXOSUIT_MODULE_MEDICAL icon = 'icons/obj/gun.dmi' icon_state = "syringegun" var/list/syringes diff --git a/code/game/mecha/equipment/weapons/explosive/missile.dm b/code/game/mecha/equipment/weapons/explosive/missile.dm index 9ff28ade8e..f0c73de695 100644 --- a/code/game/mecha/equipment/weapons/explosive/missile.dm +++ b/code/game/mecha/equipment/weapons/explosive/missile.dm @@ -4,9 +4,6 @@ step_delay = 0.5 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc) - AM.throw_at(target,missile_range, missile_speed, chassis) - /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare name = "\improper BNI Flare Launcher" desc = "A flare-gun, but bigger." @@ -34,51 +31,19 @@ name = "\improper SRM-8 missile rack" desc = "A missile battery that holds eight missiles." icon_state = "mecha_missilerack" - projectile = /obj/item/missile + projectile = /obj/item/projectile/bullet/srmrocket fire_sound = 'sound/weapons/rpg.ogg' projectiles = 8 projectile_energy_cost = 1000 equip_cooldown = 60 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive/Fire(atom/movable/AM, atom/target) - var/obj/item/missile/M = AM - M.primed = 1 - ..() - -/obj/item/missile - icon = 'icons/obj/grenade.dmi' - icon_state = "missile" - var/primed = null - throwforce = 15 - catchable = 0 - var/devastation = 0 - var/heavy_blast = 1 - var/light_blast = 2 - var/flash_blast = 4 - does_spin = FALSE // No fun corkscrew missiles. - -/obj/item/missile/proc/warhead_special(var/target) - explosion(target, devastation, heavy_blast, light_blast, flash_blast) - return - -/obj/item/missile/throw_impact(atom/hit_atom) - if(primed) - warhead_special(hit_atom) - qdel(src) - else - ..() - return - -/obj/item/missile/light - throwforce = 10 - heavy_blast = 0 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive/rigged name = "jury-rigged rocket pod" desc = "A series of pipes, tubes, and cables that resembles a rocket pod." icon_state = "mecha_missilerack-rig" - projectile = /obj/item/missile/light + projectile = /obj/item/projectile/bullet/srmrocket/weak projectiles = 3 projectile_energy_cost = 800 - equip_type = EQUIP_UTILITY \ No newline at end of file + equip_type = EQUIP_UTILITY diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 734c5bfa4c..521eb421de 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -11,47 +11,80 @@ req_access = list(access_robotics) circuit = /obj/item/weapon/circuitboard/mechfab - var/speed = 1 - var/mat_efficiency = 1 - var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, MAT_GRAPHITE = 0, MAT_PLASTEEL = 0, "gold" = 0, "silver" = 0, MAT_LEAD = 0, "osmium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, "phoron" = 0, "uranium" = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0) - var/list/hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER) + /// Current items in the build queue. + var/list/queue = list() + /// Whether or not the machine is building the entire queue automagically. + var/process_queue = FALSE + + /// The current design datum that the machine is building. + var/datum/design/being_built + /// World time when the build will finish. + var/build_finish = 0 + /// World time when the build started. + var/build_start = 0 + /// Reference to all materials used in the creation of the item being_built. + var/list/build_materials + /// Part currently stored in the Exofab. + var/obj/item/stored_part + + /// Coefficient for the speed of item building. Based on the installed parts. + var/time_coeff = 1 + /// Coefficient for the efficiency of material usage in item building. Based on the installed parts. + var/component_coeff = 1 + + var/loading_icon_state = "mechfab-idle" + + var/list/materials = list( + DEFAULT_WALL_MATERIAL = 0, + "glass" = 0, + "plastic" = 0, + MAT_GRAPHITE = 0, + MAT_PLASTEEL = 0, + "gold" = 0, + "silver" = 0, + MAT_LEAD = 0, + "osmium" = 0, + "diamond" = 0, + MAT_DURASTEEL = 0, + "phoron" = 0, + "uranium" = 0, + MAT_VERDANTIUM = 0, + MAT_MORPHIUM = 0, + MAT_METALHYDROGEN = 0, + MAT_SUPERMATTER = 0) var/res_max_amount = 200000 var/datum/research/files - var/list/datum/design/queue = list() - var/progress = 0 - var/busy = 0 - - var/list/categories = list() - var/category = null - var/sync_message = "" + var/valid_buildtype = MECHFAB + /// A list of categories that valid MECHFAB design datums will broadly categorise themselves under. + var/list/part_sets = list( + "Cyborg", + "Ripley", + "Odysseus", + "Gygax", + "Durand", + "Janus", + "Vehicle", + "Rigsuit", + "Phazon", + "Gopher", // VOREStation Add + "Polecat", // VOREStation Add + "Weasel", // VOREStation Add + "Exosuit Equipment", + "Exosuit Internals", + "Exosuit Ammunition", + "Cyborg Upgrade Modules", + "Cybernetics", + "Implants", + "Control Interfaces", + "Other", + "Misc", + ) /obj/machinery/mecha_part_fabricator/Initialize() . = ..() default_apply_parts() files = new /datum/research(src) //Setup the research data holder. - update_categories() - -/obj/machinery/mecha_part_fabricator/process() - ..() - if(stat) - return - if(busy) - update_use_power(USE_POWER_ACTIVE) - progress += speed - check_build() - else - update_use_power(USE_POWER_IDLE) - update_icon() - -/obj/machinery/mecha_part_fabricator/update_icon() - overlays.Cut() - if(panel_open) - icon_state = "mechfab-o" - else - icon_state = "mechfab-idle" - if(busy) - overlays += "mechfab-active" /obj/machinery/mecha_part_fabricator/dismantle() for(var/f in materials) @@ -65,67 +98,507 @@ var/T = 0 for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) T += M.rating - mat_efficiency = max(1 - (T - 1) / 4, 0.2) // 1 -> 0.2 - for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; speed is affected by both + component_coeff = max(1 - (T - 1) / 4, 0.2) // 1 -> 0.2 + for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; time_coeff is affected by both T += M.rating - speed = T / 2 // 1 -> 3 + time_coeff = T / 2 // 1 -> 3 + update_tgui_static_data(usr) + + +/** + * Generates an info list for a given part. + * + * Returns a list of part information. + * * D - Design datum to get information on. + * * categories - Boolean, whether or not to parse snowflake categories into the part information list. + */ +/obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D, var/categories = FALSE) + var/cost = list() + for(var/c in D.materials) + cost[c] = get_resource_cost_w_coeff(D, D.materials[c]) + + var/obj/built_item = D.build_path + + var/list/category_override = null + var/list/sub_category = null + + if(categories) + // Handle some special cases to build up sub-categories for the fab interface. + // Start with checking if this design builds a cyborg module. + if(built_item in typesof(/obj/item/borg/upgrade)) + var/obj/item/borg/upgrade/U = built_item + var/module_types = initial(U.module_flags) + sub_category = list() + if(module_types) + if(module_types & BORG_MODULE_SECURITY) + sub_category += "Security" + if(module_types & BORG_MODULE_MINER) + sub_category += "Mining" + if(module_types & BORG_MODULE_JANITOR) + sub_category += "Janitor" + if(module_types & BORG_MODULE_MEDICAL) + sub_category += "Medical" + if(module_types & BORG_MODULE_ENGINEERING) + sub_category += "Engineering" + else + sub_category += "All Cyborgs" + // Else check if this design builds a piece of exosuit equipment. + else if(built_item in typesof(/obj/item/mecha_parts/mecha_equipment)) + var/obj/item/mecha_parts/mecha_equipment/E = built_item + var/mech_types = initial(E.mech_flags) + sub_category = "Equipment" + if(mech_types) + category_override = list() + if(mech_types & EXOSUIT_MODULE_RIPLEY) + category_override += "Ripley" + if(mech_types & EXOSUIT_MODULE_ODYSSEUS) + category_override += "Odysseus" + if(mech_types & EXOSUIT_MODULE_GYGAX) + category_override += "Gygax" + if(mech_types & EXOSUIT_MODULE_DURAND) + category_override += "Durand" + if(mech_types & EXOSUIT_MODULE_PHAZON) + category_override += "Phazon" + + var/list/part = list( + "name" = D.name, + "desc" = initial(built_item.desc), + "printTime" = get_construction_time_w_coeff(initial(D.time))/10, + "cost" = cost, + "id" = D.id, + "subCategory" = sub_category, + "categoryOverride" = category_override, + "searchMeta" = D.search_metadata + ) + + return part + + +/** + * Generates a list of resources / materials available to this Exosuit Fab + * + * Returns null if there is no material container available. + * List format is list(material_name = list(amount = ..., ref = ..., etc.)) + */ +/obj/machinery/mecha_part_fabricator/proc/output_available_resources() + var/list/material_data = list() + + for(var/mat_id in materials) + var/amount = materials[mat_id] + var/list/material_info = list( + "name" = mat_id, + "amount" = amount, + "sheets" = round(amount / SHEET_MATERIAL_AMOUNT), + "removable" = amount >= SHEET_MATERIAL_AMOUNT + ) + + material_data += list(material_info) + + return material_data + +/** + * Intended to be called when an item starts printing. + * + * Adds the overlay to show the fab working and sets active power usage settings. + */ +/obj/machinery/mecha_part_fabricator/proc/on_start_printing() + add_overlay("fab-active") + use_power = USE_POWER_ACTIVE + +/** + * Intended to be called when the exofab has stopped working and is no longer printing items. + * + * Removes the overlay to show the fab working and sets idle power usage settings. Additionally resets the description and turns off queue processing. + */ +/obj/machinery/mecha_part_fabricator/proc/on_finish_printing() + cut_overlay("fab-active") + use_power = USE_POWER_IDLE + desc = initial(desc) + process_queue = FALSE + +/** + * Calculates resource/material costs for printing an item based on the machine's resource coefficient. + * + * Returns a list of k,v resources with their amounts. + * * D - Design datum to calculate the modified resource cost of. + */ +/obj/machinery/mecha_part_fabricator/proc/get_resources_w_coeff(datum/design/D) + var/list/resources = list() + for(var/mat_id in D.materials) + resources[mat_id] = get_resource_cost_w_coeff(D, D.materials[mat_id]) + return resources + +/** + * Checks if the Exofab has enough resources to print a given item. + * + * Returns FALSE if the design has no reagents used in its construction (?) or if there are insufficient resources. + * Returns TRUE if there are sufficient resources to print the item. + * * D - Design datum to calculate the modified resource cost of. + */ +/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D) + if(length(D.chemicals)) // No reagents storage - no reagent designs. + return FALSE + . = TRUE + var/list/coeff_required = get_resources_w_coeff(D) + for(var/mat_id in coeff_required) + if(materials[mat_id] < coeff_required[mat_id]) + return FALSE + +/** + * Attempts to build the next item in the build queue. + * + * Returns FALSE if either there are no more parts to build or the next part is not buildable. + * Returns TRUE if the next part has started building. + * * verbose - Whether the machine should use say() procs. Set to FALSE to disable the machine saying reasons for failure to build. + */ +/obj/machinery/mecha_part_fabricator/proc/build_next_in_queue(verbose = TRUE) + if(!length(queue)) + return FALSE + + var/datum/design/D = queue[1] + if(build_part(D, verbose)) + remove_from_queue(1) + return TRUE + + return FALSE + +/** + * Starts the build process for a given design datum. + * + * Returns FALSE if the procedure fails. Returns TRUE when being_built is set. + * Uses materials. + * * D - Design datum to attempt to print. + * * verbose - Whether the machine should use say() procs. Set to FALSE to disable the machine saying reasons for failure to build. + */ +/obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D, verbose = TRUE) + if(!D) + return FALSE + + if(!check_resources(D)) + if(verbose) + atom_say("Not enough resources. Processing stopped.") + return FALSE + + build_materials = get_resources_w_coeff(D) + for(var/mat_id in build_materials) + materials[mat_id] -= build_materials[mat_id] + + being_built = D + build_finish = world.time + get_construction_time_w_coeff(initial(D.time)) + build_start = world.time + desc = "It's building \a [D.name]." + + return TRUE + +/obj/machinery/mecha_part_fabricator/process() + ..() + // If there's a stored part to dispense due to an obstruction, try to dispense it. + if(stored_part) + var/turf/exit = get_step(src,(dir)) + if(exit.density) + return TRUE + + atom_say("Obstruction cleared. \The [stored_part] is complete.") + stored_part.forceMove(exit) + stored_part = null + + // If there's nothing being built, try to build something + if(!being_built) + // If we're not processing the queue anymore or there's nothing to build, end processing. + if(!process_queue || !build_next_in_queue()) + on_finish_printing() + return PROCESS_KILL + on_start_printing() + + // If there's an item being built, check if it is complete. + if(being_built && (build_finish < world.time)) + // Then attempt to dispense it and if appropriate build the next item. + dispense_built_part(being_built) + if(process_queue) + build_next_in_queue(FALSE) + return TRUE + + +/** + * Dispenses a part to the tile infront of the Exosuit Fab. + * + * Returns FALSE is the machine cannot dispense the part on the appropriate turf. + * Return TRUE if the part was successfully dispensed. + * * D - Design datum to attempt to dispense. + */ +/obj/machinery/mecha_part_fabricator/proc/dispense_built_part(datum/design/D) + var/obj/item/I = D.Fabricate(src, src) + // I.material_flags |= MATERIAL_NO_EFFECTS //Find a better way to do this. + // I.set_custom_materials(build_materials) + + being_built = null + + var/turf/exit = get_step(src,(dir)) + if(exit.density) + atom_say("Error! Part outlet is obstructed.") + desc = "It's trying to dispense \a [D.name], but the part outlet is obstructed." + stored_part = I + return FALSE + + atom_say("\The [I] is complete.") + I.forceMove(exit) + return I + +/** + * Adds a list of datum designs to the build queue. + * + * Will only add designs that are in this machine's stored techweb. + * Does final checks for datum IDs and makes sure this machine can build the designs. + * * part_list - List of datum design ids for designs to add to the queue. + */ +/obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(list/part_list) + for(var/datum/design/D in files.known_designs) + if((D.build_type & valid_buildtype) && (D.id in part_list)) + add_to_queue(D) + +/** + * Adds a datum design to the build queue. + * + * Returns TRUE if successful and FALSE if the design was not added to the queue. + * * D - Datum design to add to the queue. + */ +/obj/machinery/mecha_part_fabricator/proc/add_to_queue(datum/design/D) + if(!istype(queue)) + queue = list() + if(D) + queue[++queue.len] = D + return TRUE + return FALSE + +/** + * Removes datum design from the build queue based on index. + * + * Returns TRUE if successful and FALSE if a design was not removed from the queue. + * * index - Index in the build queue of the element to remove. + */ +/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index) + if(!isnum(index) || !ISINTEGER(index) || !istype(queue) || (index<1 || index>length(queue))) + return FALSE + queue.Cut(index,++index) + return TRUE + +/** + * Generates a list of parts formatted for tgui based on the current build queue. + * + * Returns a formatted list of lists containing formatted part information for every part in the build queue. + */ +/obj/machinery/mecha_part_fabricator/proc/list_queue() + if(!istype(queue) || !length(queue)) + return null + + var/list/queued_parts = list() + for(var/datum/design/D in queue) + var/list/part = output_part_info(D) + queued_parts += list(part) + return queued_parts + +/obj/machinery/mecha_part_fabricator/proc/sync() + for(var/obj/machinery/computer/rdconsole/RDC in get_area_all_atoms(get_area(src))) + if(!RDC.sync) + continue + for(var/datum/tech/T in RDC.files.known_tech) + files.AddTech2Known(T) + for(var/datum/design/D in RDC.files.known_designs) + files.AddDesign2Known(D) + files.RefreshResearch() + update_tgui_static_data(usr) + atom_say("Successfully synchronized with R&D server.") + return + + atom_say("Unable to connect to local R&D server.") + return + +/** + * Calculates the coefficient-modified resource cost of a single material component of a design's recipe. + * + * Returns coefficient-modified resource cost for the given material component. + * * D - Design datum to pull the resource cost from. + * * resource - Material datum reference to the resource to calculate the cost of. + * * roundto - Rounding value for round() proc + */ +/obj/machinery/mecha_part_fabricator/proc/get_resource_cost_w_coeff(datum/design/D, var/amt, roundto = 1) + return round(amt * component_coeff, roundto) + +/** + * Calculates the coefficient-modified build time of a design. + * + * Returns coefficient-modified build time of a given design. + * * D - Design datum to calculate the modified build time of. + * * roundto - Rounding value for round() proc + */ +/obj/machinery/mecha_part_fabricator/proc/get_construction_time_w_coeff(construction_time, roundto = 1) //aran + return round(construction_time * time_coeff, roundto) + +/obj/machinery/mecha_part_fabricator/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/sheetmaterials) + ) /obj/machinery/mecha_part_fabricator/attack_hand(var/mob/user) if(..()) return if(!allowed(user)) return - ui_interact(user) + tgui_interact(user) -/obj/machinery/mecha_part_fabricator/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - - var/datum/design/current = queue.len ? queue[1] : null - if(current) - data["current"] = current.name - data["queue"] = get_queue_names() - data["buildable"] = get_build_options() - data["category"] = category - data["categories"] = categories - data["materials"] = get_materials() - data["maxres"] = res_max_amount - data["sync"] = sync_message - if(current) - data["builtperc"] = round((progress / current.time) * 100) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) +/obj/machinery/mecha_part_fabricator/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "mechfab.tmpl", "Exosuit Fabricator UI", 800, 600) - ui.set_initial_data(data) + ui = new(user, src, "ExosuitFabricator", name) ui.open() - ui.set_auto_update(1) -/obj/machinery/mecha_part_fabricator/Topic(href, href_list) - if(..()) - return +/obj/machinery/mecha_part_fabricator/tgui_static_data(mob/user) + var/list/data = list() - if(href_list["build"]) - add_to_queue(text2num(href_list["build"])) + var/list/final_sets = list() + var/list/buildable_parts = list() - if(href_list["remove"]) - remove_from_queue(text2num(href_list["remove"])) + for(var/part_set in part_sets) + final_sets += part_set - if(href_list["category"]) - if(href_list["category"] in categories) - category = href_list["category"] + for(var/datum/design/D in files.known_designs) + if((D.build_type & valid_buildtype) && D.id != "id") // bugfix for weird null entries + // This is for us. + var/list/part = output_part_info(D, TRUE) - if(href_list["eject"]) - eject_materials(href_list["eject"], text2num(href_list["amount"])) + if(part["categoryOverride"]) + for(var/cat in part["categoryOverride"]) + buildable_parts[cat] += list(part) + if(!(cat in part_sets)) + final_sets += cat + continue - if(href_list["sync"]) - sync() + for(var/cat in part_sets) + // Find all matching categories. + if(!(cat in D.category)) + continue + + buildable_parts[cat] += list(part) + + data["partSets"] = final_sets + data["buildableParts"] = buildable_parts + + return data + +/obj/machinery/mecha_part_fabricator/tgui_data(mob/user) + var/list/data = list() + + data["materials"] = output_available_resources() + + if(being_built) + var/list/part = list( + "name" = being_built.name, + "duration" = build_finish - world.time, + "printTime" = get_construction_time_w_coeff(initial(being_built.time)) + ) + data["buildingPart"] = part else - sync_message = "" + data["buildingPart"] = null - return 1 + data["queue"] = list_queue() + + if(stored_part) + data["storedPart"] = stored_part.name + else + data["storedPart"] = null + + data["isProcessingQueue"] = process_queue + + return data + +/obj/machinery/mecha_part_fabricator/tgui_act(action, var/list/params) + if(..()) + return TRUE + + . = TRUE + + add_fingerprint(usr) + usr.set_machine(src) + + switch(action) + if("sync_rnd") + // Sync with R&D Servers + sync() + return + if("add_queue_set") + // Add all parts of a set to queue + var/part_list = params["part_list"] + add_part_set_to_queue(part_list) + return + if("add_queue_part") + // Add a specific part to queue + var/T = params["id"] + for(var/datum/design/D in files.known_designs) + if((D.build_type & valid_buildtype) && (D.id == T)) + add_to_queue(D) + break + return + if("del_queue_part") + // Delete a specific from from the queue + var/index = text2num(params["index"]) + remove_from_queue(index) + return + if("clear_queue") + // Delete everything from queue + queue.Cut() + return + if("build_queue") + // Build everything in queue + if(process_queue) + return + process_queue = TRUE + + if(!being_built) + START_PROCESSING(SSobj, src) + return + if("stop_queue") + // Pause queue building. Also known as stop. + process_queue = FALSE + return + if("build_part") + // Build a single part + if(being_built || process_queue) + return + + var/id = params["id"] + var/datum/design/D = null + for(var/datum/design/D_new in files.known_designs) + if((D_new.build_type == valid_buildtype) && (D_new.id == id)) + D = D_new + break + + if(!D) + return + + if(build_part(D)) + on_start_printing() + START_PROCESSING(SSobj, src) + + return + if("move_queue_part") + // Moves a part up or down in the queue. + var/index = text2num(params["index"]) + var/new_index = index + text2num(params["newindex"]) + if(isnum(index) && isnum(new_index) && ISINTEGER(index) && ISINTEGER(new_index)) + if(ISINRANGE(new_index,1,length(queue))) + queue.Swap(index,new_index) + return + if("remove_mat") + // Remove a material from the fab + var/mat_id = params["id"] + var/amount = text2num(params["amount"]) + eject_materials(mat_id, amount) + return + + return FALSE /obj/machinery/mecha_part_fabricator/attackby(var/obj/item/I, var/mob/user) - if(busy) + if(being_built) to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") return 1 if(default_deconstruction_screwdriver(user, I)) @@ -146,15 +619,17 @@ if(materials[S.material.name] + amnt <= res_max_amount) if(S && S.get_amount() >= 1) var/count = 0 - overlays += "mechfab-load-metal" - spawn(10) - overlays -= "mechfab-load-metal" + flick("[loading_icon_state]", src) + // yess hacky but whatever + if(loading_icon_state == "mechfab-idle") + overlays += "mechfab-load-metal" + spawn(10) + overlays -= "mechfab-load-metal" while(materials[S.material.name] + amnt <= res_max_amount && S.get_amount() >= 1) materials[S.material.name] += amnt S.use(1) count++ to_chat(user, "You insert [count] [sname] into the fabricator.") - update_busy() else to_chat(user, "The fabricator cannot hold more [sname].") @@ -181,96 +656,6 @@ if(1) visible_message("[bicon(src)] [src] beeps: \"No records in User DB\"") -/obj/machinery/mecha_part_fabricator/proc/update_busy() - if(queue.len) - if(can_build(queue[1])) - busy = 1 - else - busy = 0 - else - busy = 0 - -/obj/machinery/mecha_part_fabricator/proc/add_to_queue(var/index) - var/datum/design/D = files.known_designs[index] - queue += D - update_busy() - -/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(var/index) - if(index == 1) - progress = 0 - queue.Cut(index, index + 1) - update_busy() - -/obj/machinery/mecha_part_fabricator/proc/can_build(var/datum/design/D) - for(var/M in D.materials) - if(materials[M] < (D.materials[M] * mat_efficiency)) - return 0 - return 1 - -/obj/machinery/mecha_part_fabricator/proc/check_build() - if(!queue.len) - progress = 0 - return - var/datum/design/D = queue[1] - if(!can_build(D)) - progress = 0 - return - if(D.time > progress) - return - for(var/M in D.materials) - materials[M] = max(0, materials[M] - D.materials[M] * mat_efficiency) - if(D.build_path) - var/obj/new_item = D.Fabricate(get_step(get_turf(src), src.dir), src) - visible_message("\The [src] pings, indicating that \the [D] is complete.", "You hear a ping.") - if(mat_efficiency != 1) - if(new_item.matter && new_item.matter.len > 0) - for(var/i in new_item.matter) - new_item.matter[i] = new_item.matter[i] * mat_efficiency - remove_from_queue(1) - -/obj/machinery/mecha_part_fabricator/proc/get_queue_names() - . = list() - for(var/i = 2 to queue.len) - var/datum/design/D = queue[i] - . += D.name - -/obj/machinery/mecha_part_fabricator/proc/get_build_options() - . = list() - for(var/i = 1 to files.known_designs.len) - var/datum/design/D = files.known_designs[i] - if(!D.build_path || !(D.build_type & MECHFAB)) - continue - . += list(list("name" = D.name, "id" = i, "category" = D.category, "resourses" = get_design_resourses(D), "time" = get_design_time(D))) - -/obj/machinery/mecha_part_fabricator/proc/get_design_resourses(var/datum/design/D) - var/list/F = list() - for(var/T in D.materials) - F += "[capitalize(T)]: [D.materials[T] * mat_efficiency]" - return english_list(F, and_text = ", ") - -/obj/machinery/mecha_part_fabricator/proc/get_design_time(var/datum/design/D) - return time2text(round(10 * D.time / speed), "mm:ss") - -/obj/machinery/mecha_part_fabricator/proc/update_categories() - categories = list() - for(var/datum/design/D in files.known_designs) - if(!D.build_path || !(D.build_type & MECHFAB)) - continue - categories |= D.category - if(!category || !(category in categories)) - category = categories[1] - -/obj/machinery/mecha_part_fabricator/proc/get_materials() - . = list() - for(var/T in materials) - var/hidden_mat = FALSE - for(var/HM in hidden_materials) // Direct list contents comparison was failing. - if(T == HM && materials[T] == 0) - hidden_mat = TRUE - continue - if(!hidden_mat) - . += list(list("mat" = capitalize(T), "amt" = materials[T])) - /obj/machinery/mecha_part_fabricator/proc/eject_materials(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything var/recursive = amount == -1 ? 1 : 0 var/matstring = lowertext(material) @@ -287,17 +672,3 @@ materials[matstring] -= ejected * S.perunit if(recursive && materials[matstring] >= S.perunit) eject_materials(matstring, -1) - update_busy() - -/obj/machinery/mecha_part_fabricator/proc/sync() - sync_message = "Error: no console found." - for(var/obj/machinery/computer/rdconsole/RDC in get_area_all_atoms(get_area(src))) - if(!RDC.sync) - continue - for(var/datum/tech/T in RDC.files.known_tech) - files.AddTech2Known(T) - for(var/datum/design/D in RDC.files.known_designs) - files.AddDesign2Known(D) - files.RefreshResearch() - sync_message = "Sync complete." - update_categories() diff --git a/code/game/mecha/mech_prosthetics.dm b/code/game/mecha/mech_prosthetics.dm index 1615be1ff4..72e51262e7 100644 --- a/code/game/mecha/mech_prosthetics.dm +++ b/code/game/mecha/mech_prosthetics.dm @@ -1,4 +1,4 @@ -/obj/machinery/pros_fabricator +/obj/machinery/mecha_part_fabricator/pros icon = 'icons/obj/robotics.dmi' icon_state = "prosfab" name = "Prosthetics Fabricator" @@ -11,158 +11,126 @@ req_access = list(access_robotics) circuit = /obj/item/weapon/circuitboard/prosthetics - var/speed = 1 - var/mat_efficiency = 1 - var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, MAT_GRAPHITE = 0, MAT_PLASTEEL = 0, "gold" = 0, "silver" = 0, MAT_LEAD = 0, "osmium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, "phoron" = 0, "uranium" = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0) - var/list/hidden_materials = list(MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM) - var/res_max_amount = 200000 - - var/datum/research/files - var/list/datum/design/queue = list() - var/progress = 0 - var/busy = 0 - - var/list/categories = list() - var/category = null + // Prosfab specific stuff var/manufacturer = null var/species_types = list("Human") var/species = "Human" - var/sync_message = "" -/obj/machinery/pros_fabricator/Initialize() - . = ..() - default_apply_parts() + loading_icon_state = "prosfab_loading" - files = new /datum/research(src) //Setup the research data holder. + materials = list( + DEFAULT_WALL_MATERIAL = 0, + "glass" = 0, + "plastic" = 0, + MAT_GRAPHITE = 0, + MAT_PLASTEEL = 0, + "gold" = 0, + "silver" = 0, + MAT_LEAD = 0, + "osmium" = 0, + "diamond" = 0, + MAT_DURASTEEL = 0, + "phoron" = 0, + "uranium" = 0, + MAT_VERDANTIUM = 0, + MAT_MORPHIUM = 0) + res_max_amount = 200000 -/obj/machinery/pros_fabricator/Initialize() + valid_buildtype = PROSFAB + /// A list of categories that valid PROSFAB design datums will broadly categorise themselves under. + part_sets = list( + "Cyborg", + "Ripley", + "Odysseus", + "Gygax", + "Durand", + "Janus", + "Vehicle", + "Rigsuit", + "Phazon", + "Gopher", // VOREStation Add + "Polecat", // VOREStation Add + "Weasel", // VOREStation Add + "Exosuit Equipment", + "Exosuit Internals", + "Exosuit Ammunition", + "Cyborg Modules", + "Prosthetics", + "Prosthetics, Internal", + "Cyborg Parts", + "Cyborg Internals", + "Cybernetics", + "Implants", + "Control Interfaces", + "Other", + "Misc", + ) + +/obj/machinery/mecha_part_fabricator/pros/Initialize() . = ..() manufacturer = basic_robolimb.company - update_categories() -/obj/machinery/pros_fabricator/process() - ..() - if(stat) - return - if(busy) - update_use_power(USE_POWER_ACTIVE) - progress += speed - check_build() - else - update_use_power(USE_POWER_IDLE) - update_icon() +/obj/machinery/mecha_part_fabricator/pros/dispense_built_part(datum/design/D) + var/obj/item/I = ..() + if(isobj(I) && I.matter && I.matter.len > 0) + for(var/i in I.matter) + I.matter[i] = I.matter[i] * component_coeff -/obj/machinery/pros_fabricator/update_icon() - overlays.Cut() - icon_state = initial(icon_state) +/obj/machinery/mecha_part_fabricator/pros/tgui_data(mob/user) + var/list/data = ..() - if(panel_open) - overlays.Add(image(icon, "[icon_state]_panel")) - if(stat & NOPOWER) - return - if(busy) - icon_state = "[icon_state]_work" - -/obj/machinery/pros_fabricator/dismantle() - for(var/f in materials) - eject_materials(f, -1) - ..() - -/obj/machinery/pros_fabricator/RefreshParts() - res_max_amount = 0 - for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) - res_max_amount += M.rating * 100000 // 200k -> 600k - var/T = 0 - for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) - T += M.rating - mat_efficiency = max(0.2, 1 - (T - 1) / 4) // 1 -> 0.2 - for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; speed is affected by both - T += M.rating - speed = T / 2 // 1 -> 3 - -/obj/machinery/pros_fabricator/attack_hand(var/mob/user) - if(..()) - return - if(!allowed(user)) - return - ui_interact(user) - -/obj/machinery/pros_fabricator/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - - var/datum/design/current = queue.len ? queue[1] : null - if(current) - data["current"] = current.name - data["queue"] = get_queue_names() - data["buildable"] = get_build_options() - data["category"] = category - data["categories"] = categories data["species_types"] = species_types data["species"] = species + if(all_robolimbs) var/list/T = list() for(var/A in all_robolimbs) var/datum/robolimb/R = all_robolimbs[A] - if(R.unavailable_to_build) continue - if(species in R.species_cannot_use) continue + if(R.unavailable_to_build) + continue + if(species in R.species_cannot_use) + continue T += list(list("id" = A, "company" = R.company)) data["manufacturers"] = T - data["manufacturer"] = manufacturer - data["materials"] = get_materials() - data["maxres"] = res_max_amount - data["sync"] = sync_message - if(current) - data["builtperc"] = round((progress / current.time) * 100) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "mechfab.tmpl", "Prosthetics Fab UI", 800, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + data["manufacturer"] = manufacturer -/obj/machinery/pros_fabricator/Topic(href, href_list) + return data + +/obj/machinery/mecha_part_fabricator/pros/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return + return TRUE - if(href_list["build"]) - add_to_queue(text2num(href_list["build"])) + . = TRUE - if(href_list["remove"]) - remove_from_queue(text2num(href_list["remove"])) + add_fingerprint(usr) + usr.set_machine(src) - if(href_list["category"]) - if(href_list["category"] in categories) - category = href_list["category"] + switch(action) + if("species") + var/new_species = input(usr, "Select a new species", "Prosfab Species Selection", "Human") as null|anything in species_types + if(new_species && tgui_status(usr, state) == STATUS_INTERACTIVE) + species = new_species + return + if("manufacturer") + var/list/new_manufacturers = list() + for(var/A in all_robolimbs) + var/datum/robolimb/R = all_robolimbs[A] + if(R.unavailable_to_build) + continue + if(species in R.species_cannot_use) + continue + new_manufacturers += A - if(href_list["species"]) - if(href_list["species"] in species_types) - species = href_list["species"] + var/new_manufacturer = input(usr, "Select a new manufacturer", "Prosfab Species Selection", "Unbranded") as null|anything in new_manufacturers + if(new_manufacturer && tgui_status(usr, state) == STATUS_INTERACTIVE) + manufacturer = new_manufacturer + return + return FALSE - if(href_list["manufacturer"]) - if(href_list["manufacturer"] in all_robolimbs) - manufacturer = href_list["manufacturer"] - - if(href_list["eject"]) - eject_materials(href_list["eject"], text2num(href_list["amount"])) - - if(href_list["sync"]) - sync() - else - sync_message = "" - - return 1 - -/obj/machinery/pros_fabricator/attackby(var/obj/item/I, var/mob/user) - if(busy) - to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") +/obj/machinery/mecha_part_fabricator/pros/attackby(var/obj/item/I, var/mob/user) + if(..()) return 1 - if(default_deconstruction_screwdriver(user, I)) - return - if(default_deconstruction_crowbar(user, I)) - return - if(default_part_replacement(user, I)) - return if(istype(I,/obj/item/weapon/disk/limb)) var/obj/item/weapon/disk/limb/D = I @@ -188,168 +156,3 @@ to_chat(user, "Uploaded [D.species] files!") qdel(I) return - - if(istype(I,/obj/item/stack/material)) - var/obj/item/stack/material/S = I - if(!(S.material.name in materials)) - to_chat(user, "The [src] doesn't accept [S.material]!") - return - - var/sname = "[S.name]" - var/amnt = S.perunit - if(materials[S.material.name] + amnt <= res_max_amount) - if(S && S.get_amount() >= 1) - var/count = 0 - flick("[initial(icon_state)]_loading", src) - while(materials[S.material.name] + amnt <= res_max_amount && S.get_amount() >= 1) - materials[S.material.name] += amnt - S.use(1) - count++ - to_chat(user, "You insert [count] [sname] into the fabricator.") - update_busy() - else - to_chat(user, "The fabricator cannot hold more [sname].") - - return - - ..() - -/obj/machinery/pros_fabricator/emag_act(var/remaining_charges, var/mob/user) - switch(emagged) - if(0) - emagged = 0.5 - visible_message("[bicon(src)] [src] beeps: \"DB error \[Code 0x00F1\]\"") - sleep(10) - visible_message("[bicon(src)] [src] beeps: \"Attempting auto-repair\"") - sleep(15) - visible_message("[bicon(src)] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"") - sleep(30) - visible_message("[bicon(src)] [src] beeps: \"User DB truncated. Please contact your [using_map.company_name] system operator for future assistance.\"") - req_access = null - emagged = 1 - return 1 - if(0.5) - visible_message("[bicon(src)] [src] beeps: \"DB not responding \[Code 0x0003\]...\"") - if(1) - visible_message("[bicon(src)] [src] beeps: \"No records in User DB\"") - -/obj/machinery/pros_fabricator/proc/update_busy() - if(queue.len) - if(can_build(queue[1])) - busy = 1 - else - busy = 0 - else - busy = 0 - -/obj/machinery/pros_fabricator/proc/add_to_queue(var/index) - var/datum/design/D = files.known_designs[index] - queue += D - update_busy() - -/obj/machinery/pros_fabricator/proc/remove_from_queue(var/index) - if(index == 1) - progress = 0 - queue.Cut(index, index + 1) - update_busy() - -/obj/machinery/pros_fabricator/proc/can_build(var/datum/design/D) - for(var/M in D.materials) - if(materials[M] < (D.materials[M] * mat_efficiency)) - return 0 - return 1 - -/obj/machinery/pros_fabricator/proc/check_build() - if(!queue.len) - progress = 0 - return - var/datum/design/D = queue[1] - if(!can_build(D)) - progress = 0 - return - if(D.time > progress) - return - for(var/M in D.materials) - materials[M] = max(0, materials[M] - D.materials[M] * mat_efficiency) - if(D.build_path) - var/obj/new_item = D.Fabricate(get_step(get_turf(src), src.dir), src) // Sometimes returns a mob. Beware! - flick("[initial(icon_state)]_finish", src) - visible_message("\The [src] pings, indicating that \the [D] is complete.", "You hear a ping.") - if(mat_efficiency != 1) - if(istype(new_item, /obj/) && new_item.matter && new_item.matter.len > 0) - for(var/i in new_item.matter) - new_item.matter[i] = new_item.matter[i] * mat_efficiency - remove_from_queue(1) - -/obj/machinery/pros_fabricator/proc/get_queue_names() - . = list() - for(var/i = 2 to queue.len) - var/datum/design/D = queue[i] - . += D.name - -/obj/machinery/pros_fabricator/proc/get_build_options() - . = list() - for(var/i = 1 to files.known_designs.len) - var/datum/design/D = files.known_designs[i] - if(D.build_path && (D.build_type & PROSFAB)) - . += list(list("name" = D.name, "id" = i, "category" = D.category, "resourses" = get_design_resourses(D), "time" = get_design_time(D))) - -/obj/machinery/pros_fabricator/proc/get_design_resourses(var/datum/design/D) - var/list/F = list() - for(var/T in D.materials) - F += "[capitalize(T)]: [D.materials[T] * mat_efficiency]" - return english_list(F, and_text = ", ") - -/obj/machinery/pros_fabricator/proc/get_design_time(var/datum/design/D) - return time2text(round(10 * D.time / speed), "mm:ss") - -/obj/machinery/pros_fabricator/proc/update_categories() - categories = list() - for(var/datum/design/D in files.known_designs) - if(!D.build_path || !(D.build_type & PROSFAB)) - continue - categories |= D.category - if(!category || !(category in categories)) - category = categories[1] - -/obj/machinery/pros_fabricator/proc/get_materials() - . = list() - for(var/T in materials) - var/hidden_mat = FALSE - for(var/HM in hidden_materials) // Direct list contents comparison was failing. - if(T == HM && materials[T] == 0) - hidden_mat = TRUE - continue - if(!hidden_mat) - . += list(list("mat" = capitalize(T), "amt" = materials[T])) - -/obj/machinery/pros_fabricator/proc/eject_materials(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything - var/recursive = amount == -1 ? 1 : 0 - var/matstring = lowertext(material) - var/material/M = get_material_by_name(matstring) - - var/obj/item/stack/material/S = M.place_sheet(get_turf(src)) - if(amount <= 0) - amount = S.max_amount - var/ejected = min(round(materials[matstring] / S.perunit), amount) - S.amount = min(ejected, amount) - if(S.amount <= 0) - qdel(S) - return - materials[matstring] -= ejected * S.perunit - if(recursive && materials[matstring] >= S.perunit) - eject_materials(matstring, -1) - update_busy() - -/obj/machinery/pros_fabricator/proc/sync() - sync_message = "Error: no console found." - for(var/obj/machinery/computer/rdconsole/RDC in get_area_all_atoms(get_area(src))) - if(!RDC.sync) - continue - for(var/datum/tech/T in RDC.files.known_tech) - files.AddTech2Known(T) - for(var/datum/design/D in RDC.files.known_designs) - files.AddDesign2Known(D) - files.RefreshResearch() - sync_message = "Sync complete." - update_categories() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index bfdb4508e9..9baabe8f9b 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1891,7 +1891,7 @@ update_cell_alerts() update_damage_alerts() set_dir(dir_in) - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) + playsound(src, 'sound/machines/door/windowdoor.ogg', 50, 1) if(occupant.client && cloaked_selfimage) occupant.client.images += cloaked_selfimage play_entered_noise(occupant) @@ -2243,6 +2243,16 @@ output += "" return output +/obj/mecha/proc/get_log_tgui() + var/list/data = list() + for(var/list/entry in log) + data.Add(list(list( + "time" = time2text(entry["time"], "DDD MMM DD hh:mm:ss"), + "year" = game_year, + "message" = entry["message"], + ))) + return data + /obj/mecha/proc/output_access_dialog(obj/item/weapon/card/id/id_card, mob/user) if(!id_card || !user) return diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index f9d4384271..54e00dc39a 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -8,61 +8,65 @@ circuit = /obj/item/weapon/circuitboard/mecha_control var/list/located = list() var/screen = 0 - var/stored_data + var/list/stored_data - attack_ai(var/mob/user as mob) - return src.attack_hand(user) +/obj/machinery/computer/mecha/attack_ai(mob/user) + return attack_hand(user) - attack_hand(var/mob/user as mob) - if(..()) - return - user.set_machine(src) - var/dat = "[src.name]" - if(screen == 0) - dat += "

Tracking beacons data

" - for(var/obj/item/mecha_parts/mecha_tracking/TR in world) - var/answer = TR.get_mecha_info() - if(answer) - dat += {"
[answer]
- Send message
- Show exosuit log | (EMP pulse)
"} - - if(screen==1) - dat += "

Log contents

" - dat += "Return
" - dat += "[stored_data]" - - dat += "(Refresh)
" - dat += "" - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") +/obj/machinery/computer/mecha/attack_hand(mob/user) + if(..()) return + tgui_interact(user) - Topic(href, href_list) - if(..()) - return - var/datum/topic_input/top_filter = new /datum/topic_input(href,href_list) - if(href_list["send_message"]) - var/obj/item/mecha_parts/mecha_tracking/MT = top_filter.getObj("send_message") - var/message = sanitize(input(usr,"Input message","Transmit message") as text) - var/obj/mecha/M = MT.in_mecha() - if(message && M) - M.occupant_message(message) - return - if(href_list["shock"]) - var/obj/item/mecha_parts/mecha_tracking/MT = top_filter.getObj("shock") - MT.shock() - if(href_list["get_log"]) - var/obj/item/mecha_parts/mecha_tracking/MT = top_filter.getObj("get_log") - stored_data = MT.get_mecha_log() - screen = 1 - if(href_list["return"]) - screen = 0 - src.updateUsrDialog() - return +/obj/machinery/computer/mecha/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MechaControlConsole", name) + ui.open() +/obj/machinery/computer/mecha/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["beacons"] = list() + for(var/obj/item/mecha_parts/mecha_tracking/TR in world) + var/list/tr_data = TR.tgui_data(user) + if(tr_data) + data["beacons"].Add(list(tr_data)) + + LAZYINITLIST(stored_data) + data["stored_data"] = stored_data + return data + +/obj/machinery/computer/mecha/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + switch(action) + if("send_message") + var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["mt"]) + if(istype(MT)) + var/message = sanitize(input(usr, "Input message", "Transmit message") as text) + var/obj/mecha/M = MT.in_mecha() + if(message && M) + M.occupant_message(message) + return TRUE + + if("shock") + var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["mt"]) + if(istype(MT)) + MT.shock() + return TRUE + + if("get_log") + var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["mt"]) + if(istype(MT)) + stored_data = MT.get_mecha_log() + return TRUE + + if("clear_log") + stored_data = null + return TRUE /obj/item/mecha_parts/mecha_tracking name = "Exosuit tracking beacon" @@ -71,58 +75,67 @@ icon_state = "motion2" origin_tech = list(TECH_DATA = 2, TECH_MAGNET = 2) - proc/get_mecha_info() - if(!in_mecha()) - return 0 - var/obj/mecha/M = src.loc - var/cell_charge = M.get_charge() - var/answer = {"Name: [M.name]
- Integrity: [M.health/initial(M.health)*100]%
- Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
- Airtank: [M.return_pressure()]kPa
- Pilot: [M.occupant||"None"]
- Location: [get_area(M)||"Unknown"]
- Active equipment: [M.selected||"None"]"} - if(istype(M, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/RM = M - answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]%
" +/obj/item/mecha_parts/mecha_tracking/tgui_data(mob/user) + var/list/data = ..() + if(!in_mecha()) + return FALSE - return answer + var/obj/mecha/M = loc + data["ref"] = REF(src) + data["charge"] = M.get_charge() + data["name"] = M.name + data["health"] = M.health + data["maxHealth"] = initial(M.health) + data["cell"] = M.cell + if(M.cell) + data["cellCharge"] = M.cell.charge + data["cellMaxCharge"] = M.cell.charge + data["airtank"] = M.return_pressure() + data["pilot"] = M.occupant + data["location"] = get_area(M) + data["active"] = M.selected + if(istype(M, /obj/mecha/working/ripley)) + var/obj/mecha/working/ripley/RM = M + data["cargoUsed"] = RM.cargo.len + data["cargoMax"] = RM.cargo_capacity - emp_act() - qdel(src) - return + return data - ex_act() - qdel(src) - return +/obj/item/mecha_parts/mecha_tracking/emp_act() + qdel(src) + return - proc/in_mecha() - if(istype(src.loc, /obj/mecha)) - return src.loc - return 0 +/obj/item/mecha_parts/mecha_tracking/ex_act() + qdel(src) + return - proc/shock() - var/obj/mecha/M = in_mecha() - if(M) - M.emp_act(4) - qdel(src) +/obj/item/mecha_parts/mecha_tracking/proc/in_mecha() + if(istype(loc, /obj/mecha)) + return loc + return 0 - proc/get_mecha_log() - if(!src.in_mecha()) - return 0 - var/obj/mecha/M = src.loc - return M.get_log_html() +/obj/item/mecha_parts/mecha_tracking/proc/shock() + var/obj/mecha/M = in_mecha() + if(M) + M.emp_act(4) + qdel(src) + +/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log() + if(!in_mecha()) + return list() + var/obj/mecha/M = loc + return M.get_log_tgui() /obj/item/weapon/storage/box/mechabeacons name = "Exosuit Tracking Beacons" - New() - ..() - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) + +/obj/item/weapon/storage/box/mechabeacons/New() + ..() + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/mecha/micro/mechfab_designs_vr.dm b/code/game/mecha/micro/mechfab_designs_vr.dm index 671e53b4da..80d7945ea4 100644 --- a/code/game/mecha/micro/mechfab_designs_vr.dm +++ b/code/game/mecha/micro/mechfab_designs_vr.dm @@ -1,5 +1,5 @@ /datum/design/item/mechfab/gopher - category = "Gopher" + category = list("Gopher") time = 5 /datum/design/item/mechfab/gopher/chassis @@ -55,7 +55,7 @@ materials = list(DEFAULT_WALL_MATERIAL = 2500) /datum/design/item/mechfab/polecat - category = "Polecat" + category = list("Polecat") time = 10 /datum/design/item/mechfab/polecat/chassis @@ -134,7 +134,7 @@ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/microshotgun /datum/design/item/mechfab/weasel - category = "Weasel" + category = list("Weasel") time = 5 /datum/design/item/mechfab/weasel/chassis diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm index 4222f58e35..c3716b031c 100644 --- a/code/game/objects/effects/decals/contraband.dm +++ b/code/game/objects/effects/decals/contraband.dm @@ -12,6 +12,8 @@ name = "rolled-up poster" desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface." icon_state = "rolled_poster" + drop_sound = 'sound/items/drop/wrapper.ogg' + pickup_sound = 'sound/items/pickup/wrapper.ogg' var/serial_number = null var/poster_type = /obj/structure/sign/poster diff --git a/code/game/objects/effects/map_effects/portal.dm b/code/game/objects/effects/map_effects/portal.dm index 2331cac8e8..6eda8b6c72 100644 --- a/code/game/objects/effects/map_effects/portal.dm +++ b/code/game/objects/effects/map_effects/portal.dm @@ -9,6 +9,11 @@ Portals do have some specific requirements when mapping them in; - There must by one, and only one `/obj/effect/map_effect/portal/master` for each side of a portal. - Both sides need to have matching `portal_id`s in order to link to each other. - Each side must face opposite directions, e.g. if side A faces SOUTH, side B must face NORTH. + - Clarification on the above - you will be moved in the direction that the portal faces. + If Side A faces south, you will be moved south. Dirs are 1/2/4/8, 1: NORTH, 2: SOUTH, 4: EAST, 8: WEST. + To further explain: If your cave entrance is on the NORTH side of the map on ENTRY side, and SOUTH side on EXIT side: + You will need to set the ENTRY side's dir to 2, IE SOUTH, as that's the direction you will moving coming FROM the EXIT side. + IE: Directions should be set based on the direction of travel. - Each side must have the same orientation, e.g. horizontal on both sides, or vertical on both sides. - Portals can be made to be longer than 1x1 with `/obj/effect/map_effect/portal/line`s, but both sides must have the same length. @@ -341,4 +346,4 @@ when portals are shortly lived, or when portals are made to be obvious with spec /obj/effect/map_effect/portal/line/side_b name = "portal line B" - icon_state = "portal_line_side_b" \ No newline at end of file + icon_state = "portal_line_side_b" diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 1497e4e7a0..c522b4300e 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -113,7 +113,7 @@ triggered = 1 for (var/turf/simulated/floor/target in range(1,src)) if(!target.blocks_air) - target.assume_gas("sleeping_agent", 30) + target.assume_gas("nitrous_oxide", 30) visible_message("\The [src.name] detonates!") spawn(0) qdel(src) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 13d9f0ab8f..9812704a75 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -91,8 +91,16 @@ var/icon/default_worn_icon //Default on-mob icon var/worn_layer //Default on-mob layer - - var/drop_sound = 'sound/items/drop/device.ogg' // drop sound - this is the default + + // Pickup/Drop/Equip/Throw Sounds + ///Used when thrown into a mob + var/mob_throw_hit_sound + // Sound used when equipping the items into a valid slot. + var/equip_sound + // pickup sound - this is the default + var/pickup_sound = 'sound/items/pickup/device.ogg' + // drop sound - this is the default + var/drop_sound = 'sound/items/drop/device.ogg' var/tip_timer // reference to timer id for a tooltip we might open soon @@ -278,10 +286,29 @@ /obj/item/proc/moved(mob/user as mob, old_loc as turf) return +/obj/item/proc/get_volume_by_throwforce_and_or_w_class() // This is used for figuring out how loud our sounds are for throwing. + if(throwforce && w_class) + return CLAMP((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100 + else if(w_class) + return CLAMP(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100 + else + return 0 + /obj/item/throw_impact(atom/hit_atom) ..() - if(drop_sound) - playsound(src, drop_sound, 50, 0, preference = /datum/client_preference/drop_sounds) + if(isliving(hit_atom)) //Living mobs handle hit sounds differently. + var/volume = get_volume_by_throwforce_and_or_w_class() + if (throwforce > 0) + if (mob_throw_hit_sound) + playsound(hit_atom, mob_throw_hit_sound, volume, TRUE, -1) + else if(hitsound) + playsound(hit_atom, hitsound, volume, TRUE, -1) + else + playsound(hit_atom, 'sound/weapons/genhit.ogg', volume, TRUE, -1) + else + playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1) + else + playsound(src, drop_sound, 30, preference = /datum/client_preference/drop_sounds) // apparently called whenever an item is removed from a slot, container, or anything else. /obj/item/proc/dropped(mob/user as mob) @@ -318,6 +345,13 @@ user.position_hud_item(src,slot) if(user.client) user.client.screen |= src if(user.pulling == src) user.stop_pulling() + if((slot_flags & slot)) + if(equip_sound) + playsound(src, equip_sound, 30) + else + playsound(src, drop_sound, 30) + else if(slot == slot_l_hand || slot == slot_r_hand) + playsound(src, pickup_sound, 20, preference = /datum/client_preference/pickup_sounds) return //Defines which slots correspond to which slot flags diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 45497f1f7f..e85460284c 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -51,6 +51,8 @@ var/list/civilian_cartridges = list( icon_state = "cart" item_state = "electronic" w_class = ITEMSIZE_TINY + drop_sound = 'sound/items/drop/component.ogg' + pickup_sound = 'sound/items/pickup/component.ogg' var/obj/item/radio/integrated/radio = null var/access_security = 0 diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index d45f4ff716..d35a7546b7 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -239,6 +239,8 @@ desc = "A pen-sized light, used by medical staff." icon_state = "penlight" item_state = "pen" + drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' slot_flags = SLOT_EARS brightness_on = 2 w_class = ITEMSIZE_TINY @@ -330,6 +332,8 @@ var/on_damage = 7 var/produce_heat = 1500 power_use = 0 + drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/gloves.ogg' /obj/item/device/flashlight/flare/New() fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds. diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index a289e66e82..837c6616f7 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -7,13 +7,15 @@ /obj/item/device/multitool name = "multitool" desc = "Used for pulsing wires to test which to cut. Not recommended by doctors." + description_info = "You can use this on airlocks or APCs to try to hack them without cutting wires." icon_state = "multitool" force = 5.0 w_class = ITEMSIZE_SMALL throwforce = 5.0 throw_range = 15 throw_speed = 3 - desc = "You can use this on airlocks or APCs to try to hack them without cutting wires." + drop_sound = 'sound/items/drop/multitool.ogg' + pickup_sound = 'sound/items/pickup/multitool.ogg' matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20) diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index 754369e13e..36892be518 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -66,7 +66,7 @@ channels = list("Command" = 1) /obj/item/device/encryptionkey/heads/captain - name = "colony director's encryption key" + name = "site manager's encryption key" icon_state = "cap_cypherkey" channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1) diff --git a/code/game/objects/items/devices/radio/encryptionkey_vr.dm b/code/game/objects/items/devices/radio/encryptionkey_vr.dm index 3b2e474131..92a5ed142b 100644 --- a/code/game/objects/items/devices/radio/encryptionkey_vr.dm +++ b/code/game/objects/items/devices/radio/encryptionkey_vr.dm @@ -10,7 +10,7 @@ channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "AI Private" = 1, "Explorer" = 1) /obj/item/device/encryptionkey/heads/captain - name = "colony director's encryption key" + name = "site manager's encryption key" icon_state = "cap_cypherkey" channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "Explorer" = 1) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index f5c3918fc9..21b7463637 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -16,6 +16,9 @@ var/obj/item/device/encryptionkey/keyslot2 = null var/ks1type = null var/ks2type = null + + drop_sound = 'sound/items/drop/component.ogg' + pickup_sound = 'sound/items/pickup/component.ogg' /obj/item/device/radio/headset/New() ..() @@ -77,6 +80,9 @@ return "[..()][append]" +/obj/item/device/radio/headset/tgui_state(mob/user) + return GLOB.tgui_inventory_state + /obj/item/device/radio/headset/syndicate origin_tech = list(TECH_ILLEGAL = 3) syndie = 1 @@ -170,13 +176,13 @@ /obj/item/device/radio/headset/heads/captain - name = "colony director's headset" + name = "site manager's headset" desc = "The headset of the boss." icon_state = "com_headset" ks2type = /obj/item/device/encryptionkey/heads/captain /obj/item/device/radio/headset/heads/captain/alt - name = "colony director's bowman headset" + name = "site manager's bowman headset" desc = "The headset of the boss." icon_state = "com_headset_alt" ks2type = /obj/item/device/encryptionkey/heads/captain @@ -252,13 +258,13 @@ /obj/item/device/radio/headset/heads/hop name = "head of personnel's headset" - desc = "The headset of the guy who will one day be Colony Director." + desc = "The headset of the guy who will one day be Site Manager." icon_state = "com_headset" ks2type = /obj/item/device/encryptionkey/heads/hop /obj/item/device/radio/headset/heads/hop/alt name = "head of personnel's bowman headset" - desc = "The headset of the guy who will one day be Colony Director." + desc = "The headset of the guy who will one day be Site Manager." icon_state = "com_headset_alt" ks2type = /obj/item/device/encryptionkey/heads/hop diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 210b93f1b0..f1990c7fe2 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -168,7 +168,7 @@ var/global/list/default_medbay_channels = list( /obj/item/device/radio/tgui_data(mob/user) var/data[0] - data["rawfreq"] = num2text(frequency) + data["rawfreq"] = frequency data["listening"] = listening data["broadcasting"] = broadcasting data["subspace"] = subspace_transmission diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 406919f96a..73f7d27168 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -5,7 +5,7 @@ icon_state = "valve_1" var/obj/item/weapon/tank/tank_one var/obj/item/weapon/tank/tank_two - var/obj/item/device/attached_device + var/obj/item/device/assembly/attached_device var/mob/attacher = null var/valve_open = 0 var/toggle = 1 @@ -20,18 +20,18 @@ if(!tank_one) tank_one = item user.drop_item() - item.loc = src + item.forceMove(src) to_chat(user, "You attach the tank to the transfer valve.") else if(!tank_two) tank_two = item user.drop_item() - item.loc = src + item.forceMove(src) to_chat(user, "You attach the tank to the transfer valve.") message_admins("[key_name_admin(user)] attached both tanks to a transfer valve. (JMP)") log_game("[key_name_admin(user)] attached both tanks to a transfer valve.") update_icon() - SSnanoui.update_uis(src) // update all UIs attached to src + SStgui.update_uis(src) // update all UIs attached to src //TODO: Have this take an assemblyholder else if(isassembly(item)) var/obj/item/device/assembly/A = item @@ -43,7 +43,7 @@ return user.remove_from_mob(item) attached_device = A - A.loc = src + A.forceMove(src) to_chat(user, "You attach the [item] to the valve controls and secure it.") A.holder = src A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). @@ -52,7 +52,7 @@ message_admins("[key_name_admin(user)] attached a [item] to a transfer valve. (JMP)") log_game("[key_name_admin(user)] attached a [item] to a transfer valve.") attacher = user - SSnanoui.update_uis(src) // update all UIs attached to src + SStgui.update_uis(src) // update all UIs attached to src return @@ -66,53 +66,51 @@ if(isturf(loc)) sense_proximity(callback = .HasProximity) -/obj/item/device/transfer_valve/attack_self(mob/user as mob) - ui_interact(user) +/obj/item/device/transfer_valve/attack_self(mob/user) + tgui_interact(user) -/obj/item/device/transfer_valve/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/item/device/transfer_valve/tgui_state(mob/user) + return GLOB.tgui_inventory_state - // this is the data which will be sent to the ui - var/data[0] - data["attachmentOne"] = tank_one ? tank_one.name : null - data["attachmentTwo"] = tank_two ? tank_two.name : null - data["valveAttachment"] = attached_device ? attached_device.name : null - data["valveOpen"] = valve_open ? 1 : 0 - - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "transfer_valve.tmpl", "Tank Transfer Valve", 460, 280) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window +/obj/item/device/transfer_valve/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TransferValve", name) // 460, 320 ui.open() - // auto update every Master Controller tick - //ui.set_auto_update(1) -/obj/item/device/transfer_valve/Topic(href, href_list) - ..() - if ( usr.stat || usr.restrained() ) - return 0 - if (src.loc != usr) - return 0 - if(tank_one && href_list["tankone"]) - remove_tank(tank_one) - else if(tank_two && href_list["tanktwo"]) - remove_tank(tank_two) - else if(href_list["open"]) - toggle_valve() - else if(attached_device) - if(href_list["rem_device"]) - attached_device.loc = get_turf(src) - attached_device:holder = null - attached_device = null - update_icon() - if(href_list["device"]) - attached_device.attack_self(usr) - src.add_fingerprint(usr) - return 1 // Returning 1 sends an update to attached UIs +/obj/item/device/transfer_valve/tgui_data(mob/user) + var/list/data = list() + data["tank_one"] = tank_one ? tank_one.name : null + data["tank_two"] = tank_two ? tank_two.name : null + data["attached_device"] = attached_device ? attached_device.name : null + data["valve"] = valve_open + return data + +/obj/item/device/transfer_valve/tgui_act(action, params) + if(..()) + return + . = TRUE + switch(action) + if("tankone") + remove_tank(tank_one) + if("tanktwo") + remove_tank(tank_two) + if("toggle") + toggle_valve() + if("device") + if(attached_device) + attached_device.attack_self(usr) + if("remove_device") + if(attached_device) + attached_device.forceMove(get_turf(src)) + attached_device.holder = null + attached_device = null + update_icon() + else + . = FALSE + if(.) + update_icon() + add_fingerprint(usr) /obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D) if(toggle) @@ -148,7 +146,7 @@ else return - T.loc = get_turf(src) + T.forceMove(get_turf(src)) update_icon() /obj/item/device/transfer_valve/proc/merge_gases() diff --git a/code/game/objects/items/glassjar.dm b/code/game/objects/items/glassjar.dm index e55285e9da..9db0d88010 100644 --- a/code/game/objects/items/glassjar.dm +++ b/code/game/objects/items/glassjar.dm @@ -14,6 +14,8 @@ flags = NOBLUDGEON var/list/accept_mobs = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse, /mob/living/simple_mob/animal/sif/leech, /mob/living/simple_mob/animal/sif/frostfly, /mob/living/simple_mob/animal/sif/glitterfly) var/contains = 0 // 0 = nothing, 1 = money, 2 = animal, 3 = spiderling + drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/glass_jar/New() ..() diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 602f6e3a66..ac71abf677 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -6,6 +6,8 @@ desc = "Protected by FRM." icon = 'icons/obj/module.dmi' icon_state = "cyborg_upgrade" + /// Bitflags listing module compatibility. Used in the exosuit fabricator for creating sub-categories. + var/list/module_flags = NONE var/locked = 0 var/require_module = 0 var/installed = 0 @@ -95,6 +97,7 @@ desc = "Used to cool a mounted taser, increasing the potential current in it and thus its recharge rate." icon_state = "cyborg_upgrade3" item_state = "cyborg_upgrade" + module_flags = BORG_MODULE_SECURITY require_module = 1 diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index acf17d9735..179170fcea 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -10,7 +10,8 @@ var/heal_brute = 0 var/heal_burn = 0 var/apply_sounds - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' var/upgrade_to // The type path this stack can be upgraded to. @@ -155,6 +156,7 @@ no_variants = FALSE apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg') drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/gloves.ogg' upgrade_to = /obj/item/stack/medical/advanced/bruise_pack @@ -230,6 +232,7 @@ no_variants = FALSE apply_sounds = list('sound/effects/ointment.ogg') drop_sound = 'sound/items/drop/herb.ogg' + pickup_sound = 'sound/items/pickup/herb.ogg' /obj/item/stack/medical/ointment/attack(mob/living/carbon/M as mob, mob/user as mob) if(..()) @@ -379,6 +382,7 @@ amount = 5 max_amount = 5 drop_sound = 'sound/items/drop/hat.ogg' + pickup_sound = 'sound/items/pickup/hat.ogg' var/list/splintable_organs = list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO) //List of organs you can splint, natch. diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index fb09c03ff8..6ffa7100ca 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -8,6 +8,8 @@ throwforce = 15.0 throw_speed = 5 throw_range = 20 + drop_sound = 'sound/items/drop/metalweapon.ogg' + pickup_sound = 'sound/items/pickup/metalweapon.ogg' matter = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2) max_amount = 60 attack_verb = list("hit", "bludgeoned", "whacked") diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index f571123fc1..c2535ec3eb 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -17,6 +17,7 @@ var/is_reinforced = 0 default_type = "glass" drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/stack/material/glass/attack_self(mob/user as mob) construct_window(user) diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index ad3e349ba7..782df54346 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -4,7 +4,8 @@ singular_name = "human skin piece" icon_state = "sheet-hide" no_variants = FALSE - drop_sound = 'sound/items/drop/clothing.ogg' + drop_sound = 'sound/items/drop/cloth.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' /obj/item/stack/animalhide/human amount = 50 diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 1b7d04b14a..7e81e0115c 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -18,6 +18,7 @@ w_class = ITEMSIZE_NORMAL max_amount = 60 drop_sound = 'sound/items/drop/axe.ogg' + pickup_sound = 'sound/items/pickup/axe.ogg' /obj/item/stack/tile/New() ..() @@ -39,6 +40,7 @@ origin_tech = list(TECH_BIO = 1) no_variants = FALSE drop_sound = 'sound/items/drop/herb.ogg' + pickup_sound = 'sound/items/pickup/herb.ogg' /* * Wood */ @@ -54,6 +56,7 @@ flags = 0 no_variants = FALSE drop_sound = 'sound/items/drop/wooden.ogg' + pickup_sound = 'sound/items/pickup/wooden.ogg' /obj/item/stack/tile/wood/sif name = "alien wood tile" @@ -83,7 +86,8 @@ throw_range = 20 flags = 0 no_variants = FALSE - drop_sound = 'sound/items/drop/clothing.ogg' + drop_sound = 'sound/items/drop/cloth.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' /obj/item/stack/tile/carpet/teal name = "teal carpet" diff --git a/code/game/objects/items/toys/toys.dm b/code/game/objects/items/toys/toys.dm index 1102a31287..0433d9041d 100644 --- a/code/game/objects/items/toys/toys.dm +++ b/code/game/objects/items/toys/toys.dm @@ -1,1441 +1,1441 @@ -/* Toys! - * Contains: - * Balloons - * Fake telebeacon - * Fake singularity - * Toy gun - * Toy crossbow - * Toy swords - * Toy bosun's whistle - * Snap pops - * Water flower - * Therapy dolls - * Toddler doll - * Inflatable duck - * Action figures - * Plushies - * Toy cult sword - * Bouquets - Stick Horse - */ - - -/obj/item/toy - throwforce = 0 - throw_speed = 4 - throw_range = 20 - force = 0 - drop_sound = 'sound/items/drop/gloves.ogg' - - -/* - * Balloons - */ -/obj/item/toy/balloon - name = "water balloon" - desc = "A translucent balloon. There's nothing in it." - icon = 'icons/obj/toy.dmi' - icon_state = "waterballoon-e" - drop_sound = 'sound/items/drop/rubber.ogg' - -/obj/item/toy/balloon/New() - var/datum/reagents/R = new/datum/reagents(10) - reagents = R - R.my_atom = src - -/obj/item/toy/balloon/attack(mob/living/carbon/human/M as mob, mob/user as mob) - return - -/obj/item/toy/balloon/afterattack(atom/A as mob|obj, mob/user as mob, proximity) - if(!proximity) return - if (istype(A, /obj/structure/reagent_dispensers/watertank) && get_dist(src,A) <= 1) - A.reagents.trans_to_obj(src, 10) - to_chat(user, "You fill the balloon with the contents of [A].") - src.desc = "A translucent balloon with some form of liquid sloshing around in it." - src.update_icon() - return - -/obj/item/toy/balloon/attackby(obj/O as obj, mob/user as mob) - if(istype(O, /obj/item/weapon/reagent_containers/glass)) - if(O.reagents) - if(O.reagents.total_volume < 1) - to_chat(user, "The [O] is empty.") - else if(O.reagents.total_volume >= 1) - if(O.reagents.has_reagent("pacid", 1)) - to_chat(user, "The acid chews through the balloon!") - O.reagents.splash(user, reagents.total_volume) - qdel(src) - else - src.desc = "A translucent balloon with some form of liquid sloshing around in it." - to_chat(user, "You fill the balloon with the contents of [O].") - O.reagents.trans_to_obj(src, 10) - src.update_icon() - return - -/obj/item/toy/balloon/throw_impact(atom/hit_atom) - if(src.reagents.total_volume >= 1) - src.visible_message("\The [src] bursts!","You hear a pop and a splash.") - src.reagents.touch_turf(get_turf(hit_atom)) - for(var/atom/A in get_turf(hit_atom)) - src.reagents.touch(A) - src.icon_state = "burst" - spawn(5) - if(src) - qdel(src) - return - -/obj/item/toy/balloon/update_icon() - if(src.reagents.total_volume >= 1) - icon_state = "waterballoon" - else - icon_state = "waterballoon-e" - -/obj/item/toy/syndicateballoon - name = "criminal balloon" - desc = "There is a tag on the back that reads \"FUK NT!11!\"." - throwforce = 0 - throw_speed = 4 - throw_range = 20 - force = 0 - icon = 'icons/obj/weapons.dmi' - icon_state = "syndballoon" - w_class = ITEMSIZE_LARGE - drop_sound = 'sound/items/drop/rubber.ogg' - -/obj/item/toy/nanotrasenballoon - name = "criminal balloon" - desc = "Across the balloon the following is printed: \"Man, I love NanoTrasen soooo much. I use only NT products. You have NO idea.\"" - throwforce = 0 - throw_speed = 4 - throw_range = 20 - force = 0 - icon = 'icons/obj/weapons.dmi' - icon_state = "ntballoon" - w_class = ITEMSIZE_LARGE - drop_sound = 'sound/items/drop/rubber.ogg' - -/* - * Fake telebeacon - */ -/obj/item/toy/blink - name = "electronic blink toy game" - desc = "Blink. Blink. Blink. Ages 8 and up." - icon = 'icons/obj/radio.dmi' - icon_state = "beacon" - item_state = "signaler" - -/* - * Fake singularity - */ -/obj/item/toy/spinningtoy - name = "gravitational singularity" - desc = "\"Singulo\" brand spinning toy." - icon = 'icons/obj/singularity.dmi' - icon_state = "singularity_s1" - -/* - * Toy crossbow - */ - -/obj/item/toy/crossbow - name = "foam dart crossbow" - desc = "A weapon favored by many overactive children. Ages 8 and up." - icon = 'icons/obj/gun.dmi' - icon_state = "crossbow" - item_icons = list( - icon_l_hand = 'icons/mob/items/lefthand_guns.dmi', - icon_r_hand = 'icons/mob/items/righthand_guns.dmi', - ) - slot_flags = SLOT_HOLSTER - w_class = ITEMSIZE_SMALL - attack_verb = list("attacked", "struck", "hit") - var/bullets = 5 - drop_sound = 'sound/items/drop/gun.ogg' - - examine(mob/user) - . = ..() - if(bullets && get_dist(user, src) <= 2) - . += "It is loaded with [bullets] foam darts!" - - attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/toy/ammo/crossbow)) - if(bullets <= 4) - user.drop_item() - qdel(I) - bullets++ - to_chat(user, "You load the foam dart into the crossbow.") - else - to_chat(usr, "It's already fully loaded.") - - - afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) - if(!isturf(target.loc) || target == user) return - if(flag) return - - if (locate (/obj/structure/table, src.loc)) - return - else if (bullets) - var/turf/trg = get_turf(target) - var/obj/effect/foam_dart_dummy/D = new/obj/effect/foam_dart_dummy(get_turf(src)) - bullets-- - D.icon_state = "foamdart" - D.name = "foam dart" - playsound(src, 'sound/items/syringeproj.ogg', 50, 1) - - for(var/i=0, i<6, i++) - if (D) - if(D.loc == trg) break - step_towards(D,trg) - - for(var/mob/living/M in D.loc) - if(!istype(M,/mob/living)) continue - if(M == user) continue - for(var/mob/O in viewers(world.view, D)) - O.show_message(text("\The [] was hit by the foam dart!", M), 1) - new /obj/item/toy/ammo/crossbow(M.loc) - qdel(D) - return - - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) - new /obj/item/toy/ammo/crossbow(A.loc) - qdel(D) - - sleep(1) - - spawn(10) - if(D) - new /obj/item/toy/ammo/crossbow(D.loc) - qdel(D) - - return - else if (bullets == 0) - user.Weaken(5) - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\The [] realized they were out of ammo and starting scrounging for some!", user), 1) - - - attack(mob/M as mob, mob/user as mob) - src.add_fingerprint(user) - -// ******* Check - - if (src.bullets > 0 && M.lying) - - for(var/mob/O in viewers(M, null)) - if(O.client) - O.show_message(text("\The [] casually lines up a shot with []'s head and pulls the trigger!", user, M), 1, "You hear the sound of foam against skull", 2) - O.show_message(text("\The [] was hit in the head by the foam dart!", M), 1) - - playsound(src, 'sound/items/syringeproj.ogg', 50, 1) - new /obj/item/toy/ammo/crossbow(M.loc) - src.bullets-- - else if (M.lying && src.bullets == 0) - for(var/mob/O in viewers(M, null)) - if (O.client) O.show_message(text("\The [] casually lines up a shot with []'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!", user, M), 1, "You hear someone fall", 2) - user.Weaken(5) - return - -/obj/item/toy/ammo/crossbow - name = "foam dart" - desc = "It's nerf or nothing! Ages 8 and up." - icon = 'icons/obj/toy.dmi' - icon_state = "foamdart" - w_class = ITEMSIZE_TINY - slot_flags = SLOT_EARS - drop_sound = 'sound/items/drop/food.ogg' - -/obj/effect/foam_dart_dummy - name = "" - desc = "" - icon = 'icons/obj/toy.dmi' - icon_state = "null" - anchored = 1 - density = 0 - -/* - * Toy swords - */ -/obj/item/toy/sword - name = "toy sword" - desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up." - icon = 'icons/obj/weapons.dmi' - icon_state = "esword" - drop_sound = 'sound/items/drop/gun.ogg' - var/lcolor - var/rainbow = FALSE - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', - ) - var/active = 0 - w_class = ITEMSIZE_SMALL - attack_verb = list("attacked", "struck", "hit") - - attack_self(mob/user as mob) - src.active = !( src.active ) - if (src.active) - to_chat(user, "You extend the plastic blade with a quick flick of your wrist.") - playsound(src, 'sound/weapons/saberon.ogg', 50, 1) - src.item_state = "[icon_state]_blade" - src.w_class = ITEMSIZE_LARGE - else - to_chat(user, "You push the plastic blade back down into the handle.") - playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) - src.item_state = "[icon_state]" - src.w_class = ITEMSIZE_SMALL - update_icon() - src.add_fingerprint(user) - return - -/obj/item/toy/sword/update_icon() - . = ..() - var/mutable_appearance/blade_overlay = mutable_appearance(icon, "[icon_state]_blade") - blade_overlay.color = lcolor - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - if(active) - add_overlay(blade_overlay) - if(istype(usr,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = usr - H.update_inv_l_hand() - H.update_inv_r_hand() - -/obj/item/toy/sword/AltClick(mob/living/user) - if(!in_range(src, user)) //Basic checks to prevent abuse - return - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - - if(alert("Are you sure you want to recolor your blade?", "Confirm Recolor", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"","Choose Energy Color",lcolor) as color|null - if(energy_color_input) - lcolor = sanitize_hexcolor(energy_color_input) - update_icon() - -/obj/item/toy/sword/examine(mob/user) - . = ..() - . += "Alt-click to recolor it." - -/obj/item/toy/sword/attackby(obj/item/weapon/W, mob/user) - if(istype(W, /obj/item/device/multitool) && !active) - if(!rainbow) - rainbow = TRUE - else - rainbow = FALSE - to_chat(user, "You manipulate the color controller in [src].") - update_icon() -/obj/item/toy/katana - name = "replica katana" - desc = "Woefully underpowered in D20." - icon = 'icons/obj/weapons.dmi' - icon_state = "katana" - item_state = "katana" - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_material.dmi', - ) - slot_flags = SLOT_BELT | SLOT_BACK - force = 5 - throwforce = 5 - w_class = ITEMSIZE_NORMAL - attack_verb = list("attacked", "slashed", "stabbed", "sliced") - -/* - * Snap pops - */ -/obj/item/toy/snappop - name = "snap pop" - desc = "Wow!" - icon = 'icons/obj/toy.dmi' - icon_state = "snappop" - w_class = ITEMSIZE_TINY - drop_sound = null - - throw_impact(atom/hit_atom) - ..() - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("The [src.name] explodes!","You hear a snap!") - playsound(src, 'sound/effects/snap.ogg', 50, 1) - qdel(src) - -/obj/item/toy/snappop/Crossed(atom/movable/H as mob|obj) - if(H.is_incorporeal()) - return - if((ishuman(H))) //i guess carp and shit shouldn't set them off - var/mob/living/carbon/M = H - if(M.m_intent == "run") - to_chat(M, "You step on the snap pop!") - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 0, src) - s.start() - new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("The [src.name] explodes!","You hear a snap!") - playsound(src, 'sound/effects/snap.ogg', 50, 1) - qdel(src) - -/* - * Bosun's whistle - */ - -/obj/item/toy/bosunwhistle - name = "bosun's whistle" - desc = "A genuine Admiral Krush Bosun's Whistle, for the aspiring ship's captain! Suitable for ages 8 and up, do not swallow." - icon = 'icons/obj/toy.dmi' - icon_state = "bosunwhistle" - drop_sound = 'sound/items/drop/card.ogg' - var/cooldown = 0 - w_class = ITEMSIZE_TINY - slot_flags = SLOT_EARS | SLOT_HOLSTER - -/obj/item/toy/bosunwhistle/attack_self(mob/user as mob) - if(cooldown < world.time - 35) - to_chat(user, "You blow on [src], creating an ear-splitting noise!") - playsound(src, 'sound/misc/boatswain.ogg', 20, 1) - cooldown = world.time - -/* - * Action figures - */ -/obj/item/toy/figure - name = "Non-Specific Action Figure action figure" - desc = "A \"Space Life\" brand... wait, what the hell is this thing?" - icon = 'icons/obj/toy.dmi' - icon_state = "nuketoy" - var/cooldown = 0 - var/toysay = "What the fuck did you do?" - drop_sound = 'sound/items/drop/accessory.ogg' - -/obj/item/toy/figure/New() - ..() - desc = "A \"Space Life\" brand [name]" - -/obj/item/toy/figure/attack_self(mob/user as mob) - if(cooldown < world.time) - cooldown = (world.time + 30) //3 second cooldown - user.visible_message("The [src] says \"[toysay]\".") - playsound(src, 'sound/machines/click.ogg', 20, 1) - -/obj/item/toy/figure/cmo - name = "Chief Medical Officer action figure" - desc = "A \"Space Life\" brand Chief Medical Officer action figure." - icon_state = "cmo" - toysay = "Suit sensors!" - -/obj/item/toy/figure/assistant - name = "Assistant action figure" - desc = "A \"Space Life\" brand Assistant action figure." - icon_state = "assistant" - toysay = "Grey tide station wide!" - -/obj/item/toy/figure/atmos - name = "Atmospheric Technician action figure" - desc = "A \"Space Life\" brand Atmospheric Technician action figure." - icon_state = "atmos" - toysay = "Glory to Atmosia!" - -/obj/item/toy/figure/bartender - name = "Bartender action figure" - desc = "A \"Space Life\" brand Bartender action figure." - icon_state = "bartender" - toysay = "Where's my monkey?" - -/obj/item/toy/figure/borg - name = "Drone action figure" - desc = "A \"Space Life\" brand Drone action figure." - icon_state = "borg" - toysay = "I. LIVE. AGAIN." - -/obj/item/toy/figure/gardener - name = "Gardener action figure" - desc = "A \"Space Life\" brand Gardener action figure." - icon_state = "botanist" - toysay = "Dude, I see colors..." - -/obj/item/toy/figure/captain - name = "Colony Director action figure" - desc = "A \"Space Life\" brand Colony Director action figure." - icon_state = "captain" - toysay = "How do I open this display case?" - -/obj/item/toy/figure/cargotech - name = "Cargo Technician action figure" - desc = "A \"Space Life\" brand Cargo Technician action figure." - icon_state = "cargotech" - toysay = "For Cargonia!" - -/obj/item/toy/figure/ce - name = "Chief Engineer action figure" - desc = "A \"Space Life\" brand Chief Engineer action figure." - icon_state = "ce" - toysay = "Wire the solars!" - -/obj/item/toy/figure/chaplain - name = "Chaplain action figure" - desc = "A \"Space Life\" brand Chaplain action figure." - icon_state = "chaplain" - toysay = "Gods make me a killing machine please!" - -/obj/item/toy/figure/chef - name = "Chef action figure" - desc = "A \"Space Life\" brand Chef action figure." - icon_state = "chef" - toysay = "I swear it's not human meat." - -/obj/item/toy/figure/chemist - name = "Chemist action figure" - desc = "A \"Space Life\" brand Chemist action figure." - icon_state = "chemist" - toysay = "Get your pills!" - -/obj/item/toy/figure/clown - name = "Clown action figure" - desc = "A \"Space Life\" brand Clown action figure." - icon_state = "clown" - toysay = "Honk!" - -/obj/item/toy/figure/corgi - name = "Corgi action figure" - desc = "A \"Space Life\" brand Corgi action figure." - icon_state = "ian" - toysay = "Arf!" - -/obj/item/toy/figure/detective - name = "Detective action figure" - desc = "A \"Space Life\" brand Detective action figure." - icon_state = "detective" - toysay = "This airlock has grey jumpsuit and insulated glove fibers on it." - -/obj/item/toy/figure/dsquad - name = "Space Commando action figure" - desc = "A \"Space Life\" brand Space Commando action figure." - icon_state = "dsquad" - toysay = "Eliminate all threats!" - -/obj/item/toy/figure/engineer - name = "Engineer action figure" - desc = "A \"Space Life\" brand Engineer action figure." - icon_state = "engineer" - toysay = "Oh god, the engine is gonna go!" - -/obj/item/toy/figure/geneticist - name = "Geneticist action figure" - desc = "A \"Space Life\" brand Geneticist action figure, which was recently dicontinued." - icon_state = "geneticist" - toysay = "I'm not qualified for this job." - -/obj/item/toy/figure/hop - name = "Head of Personnel action figure" - desc = "A \"Space Life\" brand Head of Personnel action figure." - icon_state = "hop" - toysay = "Giving out all access!" - -/obj/item/toy/figure/hos - name = "Head of Security action figure" - desc = "A \"Space Life\" brand Head of Security action figure." - icon_state = "hos" - toysay = "I'm here to win, anything else is secondary." - -/obj/item/toy/figure/qm - name = "Quartermaster action figure" - desc = "A \"Space Life\" brand Quartermaster action figure." - icon_state = "qm" - toysay = "Hail Cargonia!" - -/obj/item/toy/figure/janitor - name = "Janitor action figure" - desc = "A \"Space Life\" brand Janitor action figure." - icon_state = "janitor" - toysay = "Look at the signs, you idiot." - -/obj/item/toy/figure/agent - name = "Internal Affairs Agent action figure" - desc = "A \"Space Life\" brand Internal Affairs Agent action figure." - icon_state = "agent" - toysay = "Standard Operating Procedure says they're guilty! Hacking is proof they're an Enemy of the Corporation!" - -/obj/item/toy/figure/librarian - name = "Librarian action figure" - desc = "A \"Space Life\" brand Librarian action figure." - icon_state = "librarian" - toysay = "One day while..." - -/obj/item/toy/figure/md - name = "Medical Doctor action figure" - desc = "A \"Space Life\" brand Medical Doctor action figure." - icon_state = "md" - toysay = "The patient is already dead!" - -/obj/item/toy/figure/mime - name = "Mime action figure" - desc = "A \"Space Life\" brand Mime action figure." - icon_state = "mime" - toysay = "..." - -/obj/item/toy/figure/miner - name = "Shaft Miner action figure" - desc = "A \"Space Life\" brand Shaft Miner action figure." - icon_state = "miner" - toysay = "Oh god, it's eating my intestines!" - -/obj/item/toy/figure/ninja - name = "Space Ninja action figure" - desc = "A \"Space Life\" brand Space Ninja action figure." - icon_state = "ninja" - toysay = "Oh god! Stop shooting, I'm friendly!" - -/obj/item/toy/figure/wizard - name = "Wizard action figure" - desc = "A \"Space Life\" brand Wizard action figure." - icon_state = "wizard" - toysay = "Ei Nath!" - -/obj/item/toy/figure/rd - name = "Research Director action figure" - desc = "A \"Space Life\" brand Research Director action figure." - icon_state = "rd" - toysay = "Blowing all of the borgs!" - -/obj/item/toy/figure/roboticist - name = "Roboticist action figure" - desc = "A \"Space Life\" brand Roboticist action figure." - icon_state = "roboticist" - toysay = "He asked to be borged!" - -/obj/item/toy/figure/scientist - name = "Scientist action figure" - desc = "A \"Space Life\" brand Scientist action figure." - icon_state = "scientist" - toysay = "Someone else must have made those bombs!" - -/obj/item/toy/figure/syndie - name = "Doom Operative action figure" - desc = "A \"Space Life\" brand Doom Operative action figure." - icon_state = "syndie" - toysay = "Get that fucking disk!" - -/obj/item/toy/figure/secofficer - name = "Security Officer action figure" - desc = "A \"Space Life\" brand Security Officer action figure." - icon_state = "secofficer" - toysay = "I am the law!" - -/obj/item/toy/figure/virologist - name = "Virologist action figure" - desc = "A \"Space Life\" brand Virologist action figure." - icon_state = "virologist" - toysay = "The cure is potassium!" - -/obj/item/toy/figure/warden - name = "Warden action figure" - desc = "A \"Space Life\" brand Warden action figure." - icon_state = "warden" - toysay = "Execute him for breaking in!" - -/obj/item/toy/figure/psychologist - name = "Psychologist action figure" - desc = "A \"Space Life\" brand Psychologist action figure." - icon_state = "psychologist" - toysay = "The analyzer says you're fine!" - -/obj/item/toy/figure/paramedic - name = "Paramedic action figure" - desc = "A \"Space Life\" brand Paramedic action figure." - icon_state = "paramedic" - toysay = "WHERE ARE YOU??" - -/obj/item/toy/figure/ert - name = "Emergency Response Team Commander action figure" - desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." - icon_state = "ert" - toysay = "We're probably the good guys!" - -/* - * Plushies - */ - -/* - * Carp plushie - */ - -/obj/item/toy/plushie/carp - name = "space carp plushie" - desc = "An adorable stuffed toy that resembles a space carp." - icon = 'icons/obj/toy.dmi' - icon_state = "basecarp" - attack_verb = list("bitten", "eaten", "fin slapped") - var/bitesound = 'sound/weapons/bite.ogg' - -// Attack mob -/obj/item/toy/plushie/carp/attack(mob/M as mob, mob/user as mob) - playsound(src, bitesound, 20, 1) // Play bite sound in local area - return ..() - -// Attack self -/obj/item/toy/plushie/carp/attack_self(mob/user as mob) - playsound(src, bitesound, 20, 1) - return ..() - - -/obj/random/carp_plushie - name = "Random Carp Plushie" - desc = "This is a random plushie" - icon = 'icons/obj/toy.dmi' - icon_state = "basecarp" - -/obj/random/carp_plushie/item_to_spawn() - return pick(typesof(/obj/item/toy/plushie/carp)) //can pick any carp plushie, even the original. - -/obj/item/toy/plushie/carp/ice - name = "ice carp plushie" - icon_state = "icecarp" - -/obj/item/toy/plushie/carp/silent - name = "monochrome carp plushie" - icon_state = "silentcarp" - -/obj/item/toy/plushie/carp/electric - name = "electric carp plushie" - icon_state = "electriccarp" - -/obj/item/toy/plushie/carp/gold - name = "golden carp plushie" - icon_state = "goldcarp" - -/obj/item/toy/plushie/carp/toxin - name = "toxic carp plushie" - icon_state = "toxincarp" - -/obj/item/toy/plushie/carp/dragon - name = "dragon carp plushie" - icon_state = "dragoncarp" - -/obj/item/toy/plushie/carp/pink - name = "pink carp plushie" - icon_state = "pinkcarp" - -/obj/item/toy/plushie/carp/candy - name = "candy carp plushie" - icon_state = "candycarp" - -/obj/item/toy/plushie/carp/nebula - name = "nebula carp plushie" - icon_state = "nebulacarp" - -/obj/item/toy/plushie/carp/void - name = "void carp plushie" - icon_state = "voidcarp" - -//Large plushies. -/obj/structure/plushie - name = "generic plush" - desc = "A very generic plushie. It seems to not want to exist." - icon = 'icons/obj/toy.dmi' - icon_state = "ianplushie" - anchored = 0 - density = 1 - var/phrase = "I don't want to exist anymore!" - var/searching = FALSE - var/opened = FALSE // has this been slit open? this will allow you to store an object in a plushie. - var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself. - -/obj/structure/plushie/examine(mob/user) - . = ..() - if(opened) - . += "You notice an incision has been made on [src]." - if(in_range(user, src) && stored_item) - . += "You can see something in there..." - -/obj/structure/plushie/attack_hand(mob/user) - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - - if(stored_item && opened && !searching) - searching = TRUE - if(do_after(user, 10)) - to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") - stored_item.forceMove(get_turf(src)) - stored_item = null - searching = FALSE - return - else - searching = FALSE - - if(user.a_intent == I_HELP) - user.visible_message("\The [user] hugs [src]!","You hug [src]!") - else if (user.a_intent == I_HURT) - user.visible_message("\The [user] punches [src]!","You punch [src]!") - else if (user.a_intent == I_GRAB) - user.visible_message("\The [user] attempts to strangle [src]!","You attempt to strangle [src]!") - else - user.visible_message("\The [user] pokes the [src].","You poke the [src].") - visible_message("[src] says, \"[phrase]\"") - - -/obj/structure/plushie/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/device/threadneedle) && opened) - to_chat(user, "You sew the hole in [src].") - opened = FALSE - return - - if(is_sharp(I) && !opened) - to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") - opened = TRUE - return - - if(opened) - if(stored_item) - to_chat(user, "There is already something in here.") - return - - if(!(I.w_class > w_class)) - to_chat(user, "You place [I] inside [src].") - user.drop_from_inventory(I, src) - I.forceMove(src) - stored_item = I - return - else - to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") - - - ..() - -/obj/structure/plushie/ian - name = "plush corgi" - desc = "A plushie of an adorable corgi! Don't you just want to hug it and squeeze it and call it \"Ian\"?" - icon_state = "ianplushie" - phrase = "Arf!" - -/obj/structure/plushie/drone - name = "plush drone" - desc = "A plushie of a happy drone! It appears to be smiling." - icon_state = "droneplushie" - phrase = "Beep boop!" - -/obj/structure/plushie/carp - name = "plush carp" - desc = "A plushie of an elated carp! Straight from the wilds of the Vir frontier, now right here in your hands." - icon_state = "carpplushie" - phrase = "Glorf!" - -/obj/structure/plushie/beepsky - name = "plush Officer Sweepsky" - desc = "A plushie of a popular industrious cleaning robot! If it could feel emotions, it would love you." - icon_state = "beepskyplushie" - phrase = "Ping!" - -//Small plushies. -/obj/item/toy/plushie - name = "generic small plush" - desc = "A small toy plushie. It's very cute." - icon = 'icons/obj/toy.dmi' - icon_state = "nymphplushie" - drop_sound = 'sound/items/drop/plushie.ogg' - w_class = ITEMSIZE_TINY - var/last_message = 0 - var/pokephrase = "Uww!" - var/searching = FALSE - var/opened = FALSE // has this been slit open? this will allow you to store an object in a plushie. - var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself. - - -/obj/item/toy/plushie/examine(mob/user) - . = ..() - if(opened) - . += "You notice an incision has been made on [src]." - if(in_range(user, src) && stored_item) - . += "You can see something in there..." - -/obj/item/toy/plushie/attack_self(mob/user as mob) - if(stored_item && opened && !searching) - searching = TRUE - if(do_after(user, 10)) - to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") - stored_item.forceMove(get_turf(src)) - stored_item = null - searching = FALSE - return - else - searching = FALSE - - if(world.time - last_message <= 1 SECOND) - return - if(user.a_intent == I_HELP) - user.visible_message("\The [user] hugs [src]!","You hug [src]!") - else if (user.a_intent == I_HURT) - user.visible_message("\The [user] punches [src]!","You punch [src]!") - else if (user.a_intent == I_GRAB) - user.visible_message("\The [user] attempts to strangle [src]!","You attempt to strangle [src]!") - else - user.visible_message("\The [user] pokes [src].","You poke [src].") - playsound(src, 'sound/items/drop/plushie.ogg', 25, 0) - visible_message("[src] says, \"[pokephrase]\"") - last_message = world.time - -/obj/item/toy/plushie/verb/rename_plushie() - set name = "Name Plushie" - set category = "Object" - set desc = "Give your plushie a cute name!" - var/mob/M = usr - if(!M.mind) - return 0 - - var/input = sanitizeSafe(input("What do you want to name the plushie?", ,""), MAX_NAME_LEN) - - if(src && input && !M.stat && in_range(M,src)) - name = input - to_chat(M, "You name the plushie [input], giving it a hug for good luck.") - return 1 - -/obj/item/toy/plushie/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/toy/plushie) || istype(I, /obj/item/organ/external/head)) - user.visible_message("[user] makes \the [I] kiss \the [src]!.", \ - "You make \the [I] kiss \the [src]!.") - return - - - if(istype(I, /obj/item/device/threadneedle) && opened) - to_chat(user, "You sew the hole underneath [src].") - opened = FALSE - return - - if(is_sharp(I) && !opened) - to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") - opened = TRUE - return - - if( (!(I.w_class > w_class)) && opened) - if(stored_item) - to_chat(user, "There is already something in here.") - return - - to_chat(user, "You place [I] inside [src].") - user.drop_from_inventory(I, src) - I.forceMove(src) - stored_item = I - to_chat(user, "You placed [I] into [src].") - return - - return ..() - -/obj/item/toy/plushie/nymph - name = "diona nymph plush" - desc = "A plushie of an adorable diona nymph! While its level of self-awareness is still being debated, its level of cuteness is not." - icon_state = "nymphplushie" - pokephrase = "Chirp!" - -/obj/item/toy/plushie/teshari - name = "teshari plush" - desc = "This is a plush teshari. Very soft, with a pompom on the tail. The toy is made well, as if alive. Looks like she is sleeping. Shhh!" - icon_state = "teshariplushie" - pokephrase = "Rya!" - -/obj/item/toy/plushie/mouse - name = "mouse plush" - desc = "A plushie of a delightful mouse! What was once considered a vile rodent is now your very best friend." - icon_state = "mouseplushie" //TFF 12/11/19 - updated icon to show a sprite that doesn't replicate a dead mouse. Heck you for that! >:C - pokephrase = "Squeak!" - -/obj/item/toy/plushie/kitten - name = "kitten plush" - desc = "A plushie of a cute kitten! Watch as it purrs its way right into your heart." - icon_state = "kittenplushie" - pokephrase = "Mrow!" - -/obj/item/toy/plushie/lizard - name = "lizard plush" - desc = "A plushie of a scaly lizard! Very controversial, after being accused as \"racist\" by some Unathi." - icon_state = "lizardplushie" - pokephrase = "Hiss!" - -/obj/item/toy/plushie/spider - name = "spider plush" - desc = "A plushie of a fuzzy spider! It has eight legs - all the better to hug you with." - icon_state = "spiderplushie" - pokephrase = "Sksksk!" - -/obj/item/toy/plushie/farwa - name = "farwa plush" - desc = "A farwa plush doll. It's soft and comforting!" - icon_state = "farwaplushie" - pokephrase = "Squaw!" - -/obj/item/toy/plushie/corgi - name = "corgi plushie" - icon_state = "corgi" - pokephrase = "Woof!" - -/obj/item/toy/plushie/girly_corgi - name = "corgi plushie" - icon_state = "girlycorgi" - pokephrase = "Arf!" - -/obj/item/toy/plushie/robo_corgi - name = "borgi plushie" - icon_state = "robotcorgi" - pokephrase = "Bark." - -/obj/item/toy/plushie/octopus - name = "octopus plushie" - icon_state = "loveable" - pokephrase = "Squish!" - -/obj/item/toy/plushie/face_hugger - name = "facehugger plushie" - icon_state = "huggable" - pokephrase = "Hug!" - -//foxes are basically the best - -/obj/item/toy/plushie/red_fox - name = "red fox plushie" - icon_state = "redfox" - pokephrase = "Gecker!" - -/obj/item/toy/plushie/black_fox - name = "black fox plushie" - icon_state = "blackfox" - pokephrase = "Ack!" - -/obj/item/toy/plushie/marble_fox - name = "marble fox plushie" - icon_state = "marblefox" - pokephrase = "Awoo!" - -/obj/item/toy/plushie/blue_fox - name = "blue fox plushie" - icon_state = "bluefox" - pokephrase = "Yoww!" - -/obj/item/toy/plushie/orange_fox - name = "orange fox plushie" - icon_state = "orangefox" - pokephrase = "Yagh!" - -/obj/item/toy/plushie/coffee_fox - name = "coffee fox plushie" - icon_state = "coffeefox" - pokephrase = "Gerr!" - -/obj/item/toy/plushie/pink_fox - name = "pink fox plushie" - icon_state = "pinkfox" - pokephrase = "Yack!" - -/obj/item/toy/plushie/purple_fox - name = "purple fox plushie" - icon_state = "purplefox" - pokephrase = "Whine!" - -/obj/item/toy/plushie/crimson_fox - name = "crimson fox plushie" - icon_state = "crimsonfox" - pokephrase = "Auuu!" - -/obj/item/toy/plushie/deer - name = "deer plushie" - icon_state = "deer" - pokephrase = "Bleat!" - -/obj/item/toy/plushie/black_cat - name = "black cat plushie" - icon_state = "blackcat" - pokephrase = "Mlem!" - -/obj/item/toy/plushie/grey_cat - name = "grey cat plushie" - icon_state = "greycat" - pokephrase = "Mraw!" - -/obj/item/toy/plushie/white_cat - name = "white cat plushie" - icon_state = "whitecat" - pokephrase = "Mew!" - -/obj/item/toy/plushie/orange_cat - name = "orange cat plushie" - icon_state = "orangecat" - pokephrase = "Meow!" - -/obj/item/toy/plushie/siamese_cat - name = "siamese cat plushie" - icon_state = "siamesecat" - pokephrase = "Mrew?" - -/obj/item/toy/plushie/tabby_cat - name = "tabby cat plushie" - icon_state = "tabbycat" - pokephrase = "Purr!" - -/obj/item/toy/plushie/tuxedo_cat - name = "tuxedo cat plushie" - icon_state = "tuxedocat" - pokephrase = "Mrowww!!" - -// nah, squids are better than foxes :> - -/obj/item/toy/plushie/squid/green - name = "green squid plushie" - desc = "A small, cute and loveable squid friend. This one is green." - icon = 'icons/obj/toy.dmi' - icon_state = "greensquid" - slot_flags = SLOT_HEAD - pokephrase = "Squrr!" - -/obj/item/toy/plushie/squid/mint - name = "mint squid plushie" - desc = "A small, cute and loveable squid friend. This one is mint coloured." - icon = 'icons/obj/toy.dmi' - icon_state = "mintsquid" - slot_flags = SLOT_HEAD - pokephrase = "Blurble!" - -/obj/item/toy/plushie/squid/blue - name = "blue squid plushie" - desc = "A small, cute and loveable squid friend. This one is blue." - icon = 'icons/obj/toy.dmi' - icon_state = "bluesquid" - slot_flags = SLOT_HEAD - pokephrase = "Blob!" - -/obj/item/toy/plushie/squid/orange - name = "orange squid plushie" - desc = "A small, cute and loveable squid friend. This one is orange." - icon = 'icons/obj/toy.dmi' - icon_state = "orangesquid" - slot_flags = SLOT_HEAD - pokephrase = "Squash!" - -/obj/item/toy/plushie/squid/yellow - name = "yellow squid plushie" - desc = "A small, cute and loveable squid friend. This one is yellow." - icon = 'icons/obj/toy.dmi' - icon_state = "yellowsquid" - slot_flags = SLOT_HEAD - pokephrase = "Glorble!" - -/obj/item/toy/plushie/squid/pink - name = "pink squid plushie" - desc = "A small, cute and loveable squid friend. This one is pink." - icon = 'icons/obj/toy.dmi' - icon_state = "pinksquid" - slot_flags = SLOT_HEAD - pokephrase = "Wobble!" - -/obj/item/toy/plushie/therapy/red - name = "red therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is red." - icon = 'icons/obj/toy.dmi' - icon_state = "therapyred" - item_state = "egg4" // It's the red egg in items_left/righthand - -/obj/item/toy/plushie/therapy/purple - name = "purple therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is purple." - icon = 'icons/obj/toy.dmi' - icon_state = "therapypurple" - item_state = "egg1" // It's the magenta egg in items_left/righthand - -/obj/item/toy/plushie/therapy/blue - name = "blue therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is blue." - icon = 'icons/obj/toy.dmi' - icon_state = "therapyblue" - item_state = "egg2" // It's the blue egg in items_left/righthand - -/obj/item/toy/plushie/therapy/yellow - name = "yellow therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is yellow." - icon = 'icons/obj/toy.dmi' - icon_state = "therapyyellow" - item_state = "egg5" // It's the yellow egg in items_left/righthand - -/obj/item/toy/plushie/therapy/orange - name = "orange therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is orange." - icon = 'icons/obj/toy.dmi' - icon_state = "therapyorange" - item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless - -/obj/item/toy/plushie/therapy/green - name = "green therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is green." - icon = 'icons/obj/toy.dmi' - icon_state = "therapygreen" - item_state = "egg3" // It's the green egg in items_left/righthand - - -//Toy cult sword -/obj/item/toy/cultsword - name = "foam sword" - desc = "An arcane weapon (made of foam) wielded by the followers of the hit Saturday morning cartoon \"King Nursee and the Acolytes of Heroism\"." - icon = 'icons/obj/weapons.dmi' - icon_state = "cultblade" - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', - ) - w_class = ITEMSIZE_LARGE - attack_verb = list("attacked", "slashed", "stabbed", "poked") - -//Flowers fake & real - -/obj/item/toy/bouquet - name = "bouquet" - desc = "A lovely bouquet of flowers. Smells nice!" - icon = 'icons/obj/items.dmi' - icon_state = "bouquet" - w_class = ITEMSIZE_SMALL - -/obj/item/toy/bouquet/fake - name = "plastic bouquet" - desc = "A cheap plastic bouquet of flowers. Smells like cheap, toxic plastic." - -/obj/item/toy/stickhorse - name = "stick horse" - desc = "A pretend horse on a stick for any aspiring little cowboy to ride." - icon = 'icons/obj/toy.dmi' - icon_state = "stickhorse" - w_class = ITEMSIZE_LARGE - -////////////////////////////////////////////////////// -// Magic 8-Ball / Conch // -////////////////////////////////////////////////////// - -/obj/item/toy/eight_ball - name = "\improper Magic 8-Ball" - desc = "Mystical! Magical! Ages 8+!" - icon = 'icons/obj/toy.dmi' - icon_state = "eight-ball" - var/use_action = "shakes the ball" - var/cooldown = 0 - var/list/possible_answers = list("Definitely.", "All signs point to yes.", "Most likely.", "Yes.", "Ask again later.", "Better not tell you now.", "Future unclear.", "Maybe.", "Doubtful.", "No.", "Don't count on it.", "Never.") - -/obj/item/toy/eight_ball/attack_self(mob/user as mob) - if(!cooldown) - var/answer = pick(possible_answers) - user.visible_message("[user] focuses on their question and [use_action]...") - user.visible_message("The [src] says \"[answer]\"") - spawn(30) - cooldown = 0 - return - -/obj/item/toy/eight_ball/conch - name = "Magic Conch shell" - desc = "All hail the Magic Conch!" - icon_state = "conch" - use_action = "pulls the string" - possible_answers = list("Yes.", "No.", "Try asking again.", "Nothing.", "I don't think so.", "Neither.", "Maybe someday.") - -// DND Character minis. Use the naming convention (type)character for the icon states. -/obj/item/toy/character - icon = 'icons/obj/toy.dmi' - w_class = ITEMSIZE_SMALL - pixel_z = 5 - -/obj/item/toy/character/alien - name = "xenomorph xiniature" - desc = "A miniature xenomorph. Scary!" - icon_state = "aliencharacter" -/obj/item/toy/character/cleric - name = "cleric miniature" - desc = "A wee little cleric, with his wee little staff." - icon_state = "clericcharacter" -/obj/item/toy/character/warrior - name = "warrior miniature" - desc = "That sword would make a decent toothpick." - icon_state = "warriorcharacter" -/obj/item/toy/character/thief - name = "thief miniature" - desc = "Hey, where did my wallet go!?" - icon_state = "thiefcharacter" -/obj/item/toy/character/wizard - name = "wizard miniature" - desc = "MAGIC!" - icon_state = "wizardcharacter" -/obj/item/toy/character/voidone - name = "void one miniature" - desc = "The dark lord has risen!" - icon_state = "darkmastercharacter" -/obj/item/toy/character/lich - name = "lich miniature" - desc = "Murderboner extraordinaire." - icon_state = "lichcharacter" -/obj/item/weapon/storage/box/characters - name = "box of miniatures" - desc = "The nerd's best friends." - icon_state = "box" -/obj/item/weapon/storage/box/characters/starts_with = list( -// /obj/item/toy/character/alien, - /obj/item/toy/character/cleric, - /obj/item/toy/character/warrior, - /obj/item/toy/character/thief, - /obj/item/toy/character/wizard, - /obj/item/toy/character/voidone, - /obj/item/toy/character/lich - ) - -/obj/item/toy/AI - name = "toy AI" - desc = "A little toy model AI core!"// with real law announcing action!" //Alas, requires a rewrite of how ion laws work. - icon = 'icons/obj/toy.dmi' - icon_state = "AI" - w_class = ITEMSIZE_SMALL - var/cooldown = 0 -/* -/obj/item/toy/AI/attack_self(mob/user) - if(!cooldown) //for the sanity of everyone - var/message = generate_ion_law() - to_chat(user, "You press the button on [src].") - playsound(src, 'sound/machines/click.ogg', 20, 1) - visible_message("[message]") - cooldown = 1 - spawn(30) cooldown = 0 - return - ..() -*/ -/obj/item/toy/owl - name = "owl action figure" - desc = "An action figure modeled after 'The Owl', defender of justice." - icon = 'icons/obj/toy.dmi' - icon_state = "owlprize" - w_class = ITEMSIZE_SMALL - var/cooldown = 0 - -/obj/item/toy/owl/attack_self(mob/user) - if(!cooldown) //for the sanity of everyone - var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") - to_chat(user, "You pull the string on the [src].") - //playsound(src, 'sound/misc/hoot.ogg', 25, 1) - visible_message("[message]") - cooldown = 1 - spawn(30) cooldown = 0 - return - ..() - -/obj/item/toy/griffin - name = "griffin action figure" - desc = "An action figure modeled after 'The Griffin', criminal mastermind." - icon = 'icons/obj/toy.dmi' - icon_state = "griffinprize" - w_class = ITEMSIZE_SMALL - var/cooldown = 0 - -/obj/item/toy/griffin/attack_self(mob/user) - if(!cooldown) //for the sanity of everyone - var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") - to_chat(user, "You pull the string on the [src].") - //playsound(src, 'sound/misc/caw.ogg', 25, 1) - visible_message("[message]") - cooldown = 1 - spawn(30) cooldown = 0 - return - ..() - -/* NYET. -/obj/item/weapon/toddler - icon_state = "toddler" - name = "toddler" - desc = "This baby looks almost real. Wait, did it just burp?" - force = 5 - w_class = ITEMSIZE_LARGE - slot_flags = SLOT_BACK -*/ - -//This should really be somewhere else but I don't know where. w/e - -/obj/item/weapon/inflatable_duck - name = "inflatable duck" - desc = "No bother to sink or swim when you can just float!" - icon_state = "inflatable" - icon = 'icons/obj/clothing/belts.dmi' - slot_flags = SLOT_BELT - drop_sound = 'sound/items/drop/rubber.ogg' - -/obj/item/toy/xmastree - name = "Miniature Christmas tree" - desc = "Tiny cute Christmas tree." - icon = 'icons/obj/toy.dmi' - icon_state = "tinyxmastree" - w_class = ITEMSIZE_TINY - force = 1 - throwforce = 1 - drop_sound = 'sound/items/drop/box.ogg' - -////////////////////////////////////////////////////// -// Chess Pieces // -////////////////////////////////////////////////////// - -/obj/item/toy/chess - name = "chess piece" - desc = "This should never display." - icon = 'icons/obj/chess.dmi' - w_class = ITEMSIZE_SMALL - force = 1 - throwforce = 1 - drop_sound = 'sound/items/drop/glass.ogg' - -/obj/item/toy/chess/pawn_white - name = "blue pawn" - desc = "A large pawn piece for playing chess. It's made of a blue-colored glass." - description_info = "Pawns can move forward one square, if that square is unoccupied. If the pawn has not yet moved, it has the option of moving two squares forward provided both squares in front of the pawn are unoccupied. A pawn cannot move backward. They can only capture an enemy piece on either of the two tiles diagonally in front of them, but not the tile directly in front of them." - icon_state = "w-pawn" -/obj/item/toy/chess/pawn_black - name = "purple pawn" - desc = "A large pawn piece for playing chess. It's made of a purple-colored glass." - description_info = "Pawns can move forward one square, if that square is unoccupied. If the pawn has not yet moved, it has the option of moving two squares forward provided both squares in front of the pawn are unoccupied. A pawn cannot move backward. They can only capture an enemy piece on either of the two tiles diagonally in front of them, but not the tile directly in front of them." - icon_state = "b-pawn" -/obj/item/toy/chess/rook_white - name = "blue rook" - desc = "A large rook piece for playing chess. It's made of a blue-colored glass." - description_info = "The Rook can move any number of vacant squares vertically or horizontally." - icon_state = "w-rook" -/obj/item/toy/chess/rook_black - name = "purple rook" - desc = "A large rook piece for playing chess. It's made of a purple-colored glass." - description_info = "The Rook can move any number of vacant squares vertically or horizontally." - icon_state = "b-rook" -/obj/item/toy/chess/knight_white - name = "blue knight" - desc = "A large knight piece for playing chess. It's made of a blue-colored glass. Sadly, you can't ride it." - description_info = "The Knight can either move two squares horizontally and one square vertically or two squares vertically and one square horizontally. The knight's movement can also be viewed as an 'L' laid out at any horizontal or vertical angle." - icon_state = "w-knight" -/obj/item/toy/chess/knight_black - name = "purple knight" - desc = "A large knight piece for playing chess. It's made of a purple-colored glass. 'Just a flesh wound.'" - description_info = "The Knight can either move two squares horizontally and one square vertically or two squares vertically and one square horizontally. The knight's movement can also be viewed as an 'L' laid out at any horizontal or vertical angle." - icon_state = "b-knight" -/obj/item/toy/chess/bishop_white - name = "blue bishop" - desc = "A large bishop piece for playing chess. It's made of a blue-colored glass." - description_info = "The Bishop can move any number of vacant squares in any diagonal direction." - icon_state = "w-bishop" -/obj/item/toy/chess/bishop_black - name = "purple bishop" - desc = "A large bishop piece for playing chess. It's made of a purple-colored glass." - description_info = "The Bishop can move any number of vacant squares in any diagonal direction." - icon_state = "b-bishop" -/obj/item/toy/chess/queen_white - name = "blue queen" - desc = "A large queen piece for playing chess. It's made of a blue-colored glass." - description_info = "The Queen can move any number of vacant squares diagonally, horizontally, or vertically." - icon_state = "w-queen" -/obj/item/toy/chess/queen_black - name = "purple queen" - desc = "A large queen piece for playing chess. It's made of a purple-colored glass." - description_info = "The Queen can move any number of vacant squares diagonally, horizontally, or vertically." - icon_state = "b-queen" -/obj/item/toy/chess/king_white - name = "blue king" - desc = "A large king piece for playing chess. It's made of a blue-colored glass." - description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose." - icon_state = "w-king" -/obj/item/toy/chess/king_black - name = "purple king" - desc = "A large king piece for playing chess. It's made of a purple-colored glass." - description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose." +/* Toys! + * Contains: + * Balloons + * Fake telebeacon + * Fake singularity + * Toy gun + * Toy crossbow + * Toy swords + * Toy bosun's whistle + * Snap pops + * Water flower + * Therapy dolls + * Toddler doll + * Inflatable duck + * Action figures + * Plushies + * Toy cult sword + * Bouquets + Stick Horse + */ + + +/obj/item/toy + throwforce = 0 + throw_speed = 4 + throw_range = 20 + force = 0 + drop_sound = 'sound/items/drop/gloves.ogg' + + +/* + * Balloons + */ +/obj/item/toy/balloon + name = "water balloon" + desc = "A translucent balloon. There's nothing in it." + icon = 'icons/obj/toy.dmi' + icon_state = "waterballoon-e" + drop_sound = 'sound/items/drop/rubber.ogg' + +/obj/item/toy/balloon/New() + var/datum/reagents/R = new/datum/reagents(10) + reagents = R + R.my_atom = src + +/obj/item/toy/balloon/attack(mob/living/carbon/human/M as mob, mob/user as mob) + return + +/obj/item/toy/balloon/afterattack(atom/A as mob|obj, mob/user as mob, proximity) + if(!proximity) return + if (istype(A, /obj/structure/reagent_dispensers/watertank) && get_dist(src,A) <= 1) + A.reagents.trans_to_obj(src, 10) + to_chat(user, "You fill the balloon with the contents of [A].") + src.desc = "A translucent balloon with some form of liquid sloshing around in it." + src.update_icon() + return + +/obj/item/toy/balloon/attackby(obj/O as obj, mob/user as mob) + if(istype(O, /obj/item/weapon/reagent_containers/glass)) + if(O.reagents) + if(O.reagents.total_volume < 1) + to_chat(user, "The [O] is empty.") + else if(O.reagents.total_volume >= 1) + if(O.reagents.has_reagent("pacid", 1)) + to_chat(user, "The acid chews through the balloon!") + O.reagents.splash(user, reagents.total_volume) + qdel(src) + else + src.desc = "A translucent balloon with some form of liquid sloshing around in it." + to_chat(user, "You fill the balloon with the contents of [O].") + O.reagents.trans_to_obj(src, 10) + src.update_icon() + return + +/obj/item/toy/balloon/throw_impact(atom/hit_atom) + if(src.reagents.total_volume >= 1) + src.visible_message("\The [src] bursts!","You hear a pop and a splash.") + src.reagents.touch_turf(get_turf(hit_atom)) + for(var/atom/A in get_turf(hit_atom)) + src.reagents.touch(A) + src.icon_state = "burst" + spawn(5) + if(src) + qdel(src) + return + +/obj/item/toy/balloon/update_icon() + if(src.reagents.total_volume >= 1) + icon_state = "waterballoon" + else + icon_state = "waterballoon-e" + +/obj/item/toy/syndicateballoon + name = "criminal balloon" + desc = "There is a tag on the back that reads \"FUK NT!11!\"." + throwforce = 0 + throw_speed = 4 + throw_range = 20 + force = 0 + icon = 'icons/obj/weapons.dmi' + icon_state = "syndballoon" + w_class = ITEMSIZE_LARGE + drop_sound = 'sound/items/drop/rubber.ogg' + +/obj/item/toy/nanotrasenballoon + name = "criminal balloon" + desc = "Across the balloon the following is printed: \"Man, I love NanoTrasen soooo much. I use only NT products. You have NO idea.\"" + throwforce = 0 + throw_speed = 4 + throw_range = 20 + force = 0 + icon = 'icons/obj/weapons.dmi' + icon_state = "ntballoon" + w_class = ITEMSIZE_LARGE + drop_sound = 'sound/items/drop/rubber.ogg' + +/* + * Fake telebeacon + */ +/obj/item/toy/blink + name = "electronic blink toy game" + desc = "Blink. Blink. Blink. Ages 8 and up." + icon = 'icons/obj/radio.dmi' + icon_state = "beacon" + item_state = "signaler" + +/* + * Fake singularity + */ +/obj/item/toy/spinningtoy + name = "gravitational singularity" + desc = "\"Singulo\" brand spinning toy." + icon = 'icons/obj/singularity.dmi' + icon_state = "singularity_s1" + +/* + * Toy crossbow + */ + +/obj/item/toy/crossbow + name = "foam dart crossbow" + desc = "A weapon favored by many overactive children. Ages 8 and up." + icon = 'icons/obj/gun.dmi' + icon_state = "crossbow" + item_icons = list( + icon_l_hand = 'icons/mob/items/lefthand_guns.dmi', + icon_r_hand = 'icons/mob/items/righthand_guns.dmi', + ) + slot_flags = SLOT_HOLSTER + w_class = ITEMSIZE_SMALL + attack_verb = list("attacked", "struck", "hit") + var/bullets = 5 + drop_sound = 'sound/items/drop/gun.ogg' + + examine(mob/user) + . = ..() + if(bullets && get_dist(user, src) <= 2) + . += "It is loaded with [bullets] foam darts!" + + attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/toy/ammo/crossbow)) + if(bullets <= 4) + user.drop_item() + qdel(I) + bullets++ + to_chat(user, "You load the foam dart into the crossbow.") + else + to_chat(usr, "It's already fully loaded.") + + + afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) + if(!isturf(target.loc) || target == user) return + if(flag) return + + if (locate (/obj/structure/table, src.loc)) + return + else if (bullets) + var/turf/trg = get_turf(target) + var/obj/effect/foam_dart_dummy/D = new/obj/effect/foam_dart_dummy(get_turf(src)) + bullets-- + D.icon_state = "foamdart" + D.name = "foam dart" + playsound(src, 'sound/items/syringeproj.ogg', 50, 1) + + for(var/i=0, i<6, i++) + if (D) + if(D.loc == trg) break + step_towards(D,trg) + + for(var/mob/living/M in D.loc) + if(!istype(M,/mob/living)) continue + if(M == user) continue + for(var/mob/O in viewers(world.view, D)) + O.show_message(text("\The [] was hit by the foam dart!", M), 1) + new /obj/item/toy/ammo/crossbow(M.loc) + qdel(D) + return + + for(var/atom/A in D.loc) + if(A == user) continue + if(A.density) + new /obj/item/toy/ammo/crossbow(A.loc) + qdel(D) + + sleep(1) + + spawn(10) + if(D) + new /obj/item/toy/ammo/crossbow(D.loc) + qdel(D) + + return + else if (bullets == 0) + user.Weaken(5) + for(var/mob/O in viewers(world.view, user)) + O.show_message(text("\The [] realized they were out of ammo and starting scrounging for some!", user), 1) + + + attack(mob/M as mob, mob/user as mob) + src.add_fingerprint(user) + +// ******* Check + + if (src.bullets > 0 && M.lying) + + for(var/mob/O in viewers(M, null)) + if(O.client) + O.show_message(text("\The [] casually lines up a shot with []'s head and pulls the trigger!", user, M), 1, "You hear the sound of foam against skull", 2) + O.show_message(text("\The [] was hit in the head by the foam dart!", M), 1) + + playsound(src, 'sound/items/syringeproj.ogg', 50, 1) + new /obj/item/toy/ammo/crossbow(M.loc) + src.bullets-- + else if (M.lying && src.bullets == 0) + for(var/mob/O in viewers(M, null)) + if (O.client) O.show_message(text("\The [] casually lines up a shot with []'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!", user, M), 1, "You hear someone fall", 2) + user.Weaken(5) + return + +/obj/item/toy/ammo/crossbow + name = "foam dart" + desc = "It's nerf or nothing! Ages 8 and up." + icon = 'icons/obj/toy.dmi' + icon_state = "foamdart" + w_class = ITEMSIZE_TINY + slot_flags = SLOT_EARS + drop_sound = 'sound/items/drop/food.ogg' + +/obj/effect/foam_dart_dummy + name = "" + desc = "" + icon = 'icons/obj/toy.dmi' + icon_state = "null" + anchored = 1 + density = 0 + +/* + * Toy swords + */ +/obj/item/toy/sword + name = "toy sword" + desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up." + icon = 'icons/obj/weapons.dmi' + icon_state = "esword" + drop_sound = 'sound/items/drop/gun.ogg' + var/lcolor + var/rainbow = FALSE + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', + ) + var/active = 0 + w_class = ITEMSIZE_SMALL + attack_verb = list("attacked", "struck", "hit") + + attack_self(mob/user as mob) + src.active = !( src.active ) + if (src.active) + to_chat(user, "You extend the plastic blade with a quick flick of your wrist.") + playsound(src, 'sound/weapons/saberon.ogg', 50, 1) + src.item_state = "[icon_state]_blade" + src.w_class = ITEMSIZE_LARGE + else + to_chat(user, "You push the plastic blade back down into the handle.") + playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) + src.item_state = "[icon_state]" + src.w_class = ITEMSIZE_SMALL + update_icon() + src.add_fingerprint(user) + return + +/obj/item/toy/sword/update_icon() + . = ..() + var/mutable_appearance/blade_overlay = mutable_appearance(icon, "[icon_state]_blade") + blade_overlay.color = lcolor + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + if(active) + add_overlay(blade_overlay) + if(istype(usr,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = usr + H.update_inv_l_hand() + H.update_inv_r_hand() + +/obj/item/toy/sword/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Recolor", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"","Choose Energy Color",lcolor) as color|null + if(energy_color_input) + lcolor = sanitize_hexcolor(energy_color_input) + update_icon() + +/obj/item/toy/sword/examine(mob/user) + . = ..() + . += "Alt-click to recolor it." + +/obj/item/toy/sword/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/device/multitool) && !active) + if(!rainbow) + rainbow = TRUE + else + rainbow = FALSE + to_chat(user, "You manipulate the color controller in [src].") + update_icon() +/obj/item/toy/katana + name = "replica katana" + desc = "Woefully underpowered in D20." + icon = 'icons/obj/weapons.dmi' + icon_state = "katana" + item_state = "katana" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_material.dmi', + ) + slot_flags = SLOT_BELT | SLOT_BACK + force = 5 + throwforce = 5 + w_class = ITEMSIZE_NORMAL + attack_verb = list("attacked", "slashed", "stabbed", "sliced") + +/* + * Snap pops + */ +/obj/item/toy/snappop + name = "snap pop" + desc = "Wow!" + icon = 'icons/obj/toy.dmi' + icon_state = "snappop" + w_class = ITEMSIZE_TINY + drop_sound = null + + throw_impact(atom/hit_atom) + ..() + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + new /obj/effect/decal/cleanable/ash(src.loc) + src.visible_message("The [src.name] explodes!","You hear a snap!") + playsound(src, 'sound/effects/snap.ogg', 50, 1) + qdel(src) + +/obj/item/toy/snappop/Crossed(atom/movable/H as mob|obj) + if(H.is_incorporeal()) + return + if((ishuman(H))) //i guess carp and shit shouldn't set them off + var/mob/living/carbon/M = H + if(M.m_intent == "run") + to_chat(M, "You step on the snap pop!") + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 0, src) + s.start() + new /obj/effect/decal/cleanable/ash(src.loc) + src.visible_message("The [src.name] explodes!","You hear a snap!") + playsound(src, 'sound/effects/snap.ogg', 50, 1) + qdel(src) + +/* + * Bosun's whistle + */ + +/obj/item/toy/bosunwhistle + name = "bosun's whistle" + desc = "A genuine Admiral Krush Bosun's Whistle, for the aspiring ship's captain! Suitable for ages 8 and up, do not swallow." + icon = 'icons/obj/toy.dmi' + icon_state = "bosunwhistle" + drop_sound = 'sound/items/drop/card.ogg' + var/cooldown = 0 + w_class = ITEMSIZE_TINY + slot_flags = SLOT_EARS | SLOT_HOLSTER + +/obj/item/toy/bosunwhistle/attack_self(mob/user as mob) + if(cooldown < world.time - 35) + to_chat(user, "You blow on [src], creating an ear-splitting noise!") + playsound(src, 'sound/misc/boatswain.ogg', 20, 1) + cooldown = world.time + +/* + * Action figures + */ +/obj/item/toy/figure + name = "Non-Specific Action Figure action figure" + desc = "A \"Space Life\" brand... wait, what the hell is this thing?" + icon = 'icons/obj/toy.dmi' + icon_state = "nuketoy" + var/cooldown = 0 + var/toysay = "What the fuck did you do?" + drop_sound = 'sound/items/drop/accessory.ogg' + +/obj/item/toy/figure/New() + ..() + desc = "A \"Space Life\" brand [name]" + +/obj/item/toy/figure/attack_self(mob/user as mob) + if(cooldown < world.time) + cooldown = (world.time + 30) //3 second cooldown + user.visible_message("The [src] says \"[toysay]\".") + playsound(src, 'sound/machines/click.ogg', 20, 1) + +/obj/item/toy/figure/cmo + name = "Chief Medical Officer action figure" + desc = "A \"Space Life\" brand Chief Medical Officer action figure." + icon_state = "cmo" + toysay = "Suit sensors!" + +/obj/item/toy/figure/assistant + name = "Assistant action figure" + desc = "A \"Space Life\" brand Assistant action figure." + icon_state = "assistant" + toysay = "Grey tide station wide!" + +/obj/item/toy/figure/atmos + name = "Atmospheric Technician action figure" + desc = "A \"Space Life\" brand Atmospheric Technician action figure." + icon_state = "atmos" + toysay = "Glory to Atmosia!" + +/obj/item/toy/figure/bartender + name = "Bartender action figure" + desc = "A \"Space Life\" brand Bartender action figure." + icon_state = "bartender" + toysay = "Where's my monkey?" + +/obj/item/toy/figure/borg + name = "Drone action figure" + desc = "A \"Space Life\" brand Drone action figure." + icon_state = "borg" + toysay = "I. LIVE. AGAIN." + +/obj/item/toy/figure/gardener + name = "Gardener action figure" + desc = "A \"Space Life\" brand Gardener action figure." + icon_state = "botanist" + toysay = "Dude, I see colors..." + +/obj/item/toy/figure/captain + name = "Site Manager action figure" + desc = "A \"Space Life\" brand Site Manager action figure." + icon_state = "captain" + toysay = "How do I open this display case?" + +/obj/item/toy/figure/cargotech + name = "Cargo Technician action figure" + desc = "A \"Space Life\" brand Cargo Technician action figure." + icon_state = "cargotech" + toysay = "For Cargonia!" + +/obj/item/toy/figure/ce + name = "Chief Engineer action figure" + desc = "A \"Space Life\" brand Chief Engineer action figure." + icon_state = "ce" + toysay = "Wire the solars!" + +/obj/item/toy/figure/chaplain + name = "Chaplain action figure" + desc = "A \"Space Life\" brand Chaplain action figure." + icon_state = "chaplain" + toysay = "Gods make me a killing machine please!" + +/obj/item/toy/figure/chef + name = "Chef action figure" + desc = "A \"Space Life\" brand Chef action figure." + icon_state = "chef" + toysay = "I swear it's not human meat." + +/obj/item/toy/figure/chemist + name = "Chemist action figure" + desc = "A \"Space Life\" brand Chemist action figure." + icon_state = "chemist" + toysay = "Get your pills!" + +/obj/item/toy/figure/clown + name = "Clown action figure" + desc = "A \"Space Life\" brand Clown action figure." + icon_state = "clown" + toysay = "Honk!" + +/obj/item/toy/figure/corgi + name = "Corgi action figure" + desc = "A \"Space Life\" brand Corgi action figure." + icon_state = "ian" + toysay = "Arf!" + +/obj/item/toy/figure/detective + name = "Detective action figure" + desc = "A \"Space Life\" brand Detective action figure." + icon_state = "detective" + toysay = "This airlock has grey jumpsuit and insulated glove fibers on it." + +/obj/item/toy/figure/dsquad + name = "Space Commando action figure" + desc = "A \"Space Life\" brand Space Commando action figure." + icon_state = "dsquad" + toysay = "Eliminate all threats!" + +/obj/item/toy/figure/engineer + name = "Engineer action figure" + desc = "A \"Space Life\" brand Engineer action figure." + icon_state = "engineer" + toysay = "Oh god, the engine is gonna go!" + +/obj/item/toy/figure/geneticist + name = "Geneticist action figure" + desc = "A \"Space Life\" brand Geneticist action figure, which was recently dicontinued." + icon_state = "geneticist" + toysay = "I'm not qualified for this job." + +/obj/item/toy/figure/hop + name = "Head of Personnel action figure" + desc = "A \"Space Life\" brand Head of Personnel action figure." + icon_state = "hop" + toysay = "Giving out all access!" + +/obj/item/toy/figure/hos + name = "Head of Security action figure" + desc = "A \"Space Life\" brand Head of Security action figure." + icon_state = "hos" + toysay = "I'm here to win, anything else is secondary." + +/obj/item/toy/figure/qm + name = "Quartermaster action figure" + desc = "A \"Space Life\" brand Quartermaster action figure." + icon_state = "qm" + toysay = "Hail Cargonia!" + +/obj/item/toy/figure/janitor + name = "Janitor action figure" + desc = "A \"Space Life\" brand Janitor action figure." + icon_state = "janitor" + toysay = "Look at the signs, you idiot." + +/obj/item/toy/figure/agent + name = "Internal Affairs Agent action figure" + desc = "A \"Space Life\" brand Internal Affairs Agent action figure." + icon_state = "agent" + toysay = "Standard Operating Procedure says they're guilty! Hacking is proof they're an Enemy of the Corporation!" + +/obj/item/toy/figure/librarian + name = "Librarian action figure" + desc = "A \"Space Life\" brand Librarian action figure." + icon_state = "librarian" + toysay = "One day while..." + +/obj/item/toy/figure/md + name = "Medical Doctor action figure" + desc = "A \"Space Life\" brand Medical Doctor action figure." + icon_state = "md" + toysay = "The patient is already dead!" + +/obj/item/toy/figure/mime + name = "Mime action figure" + desc = "A \"Space Life\" brand Mime action figure." + icon_state = "mime" + toysay = "..." + +/obj/item/toy/figure/miner + name = "Shaft Miner action figure" + desc = "A \"Space Life\" brand Shaft Miner action figure." + icon_state = "miner" + toysay = "Oh god, it's eating my intestines!" + +/obj/item/toy/figure/ninja + name = "Space Ninja action figure" + desc = "A \"Space Life\" brand Space Ninja action figure." + icon_state = "ninja" + toysay = "Oh god! Stop shooting, I'm friendly!" + +/obj/item/toy/figure/wizard + name = "Wizard action figure" + desc = "A \"Space Life\" brand Wizard action figure." + icon_state = "wizard" + toysay = "Ei Nath!" + +/obj/item/toy/figure/rd + name = "Research Director action figure" + desc = "A \"Space Life\" brand Research Director action figure." + icon_state = "rd" + toysay = "Blowing all of the borgs!" + +/obj/item/toy/figure/roboticist + name = "Roboticist action figure" + desc = "A \"Space Life\" brand Roboticist action figure." + icon_state = "roboticist" + toysay = "He asked to be borged!" + +/obj/item/toy/figure/scientist + name = "Scientist action figure" + desc = "A \"Space Life\" brand Scientist action figure." + icon_state = "scientist" + toysay = "Someone else must have made those bombs!" + +/obj/item/toy/figure/syndie + name = "Doom Operative action figure" + desc = "A \"Space Life\" brand Doom Operative action figure." + icon_state = "syndie" + toysay = "Get that fucking disk!" + +/obj/item/toy/figure/secofficer + name = "Security Officer action figure" + desc = "A \"Space Life\" brand Security Officer action figure." + icon_state = "secofficer" + toysay = "I am the law!" + +/obj/item/toy/figure/virologist + name = "Virologist action figure" + desc = "A \"Space Life\" brand Virologist action figure." + icon_state = "virologist" + toysay = "The cure is potassium!" + +/obj/item/toy/figure/warden + name = "Warden action figure" + desc = "A \"Space Life\" brand Warden action figure." + icon_state = "warden" + toysay = "Execute him for breaking in!" + +/obj/item/toy/figure/psychologist + name = "Psychologist action figure" + desc = "A \"Space Life\" brand Psychologist action figure." + icon_state = "psychologist" + toysay = "The analyzer says you're fine!" + +/obj/item/toy/figure/paramedic + name = "Paramedic action figure" + desc = "A \"Space Life\" brand Paramedic action figure." + icon_state = "paramedic" + toysay = "WHERE ARE YOU??" + +/obj/item/toy/figure/ert + name = "Emergency Response Team Commander action figure" + desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." + icon_state = "ert" + toysay = "We're probably the good guys!" + +/* + * Plushies + */ + +/* + * Carp plushie + */ + +/obj/item/toy/plushie/carp + name = "space carp plushie" + desc = "An adorable stuffed toy that resembles a space carp." + icon = 'icons/obj/toy.dmi' + icon_state = "basecarp" + attack_verb = list("bitten", "eaten", "fin slapped") + var/bitesound = 'sound/weapons/bite.ogg' + +// Attack mob +/obj/item/toy/plushie/carp/attack(mob/M as mob, mob/user as mob) + playsound(src, bitesound, 20, 1) // Play bite sound in local area + return ..() + +// Attack self +/obj/item/toy/plushie/carp/attack_self(mob/user as mob) + playsound(src, bitesound, 20, 1) + return ..() + + +/obj/random/carp_plushie + name = "Random Carp Plushie" + desc = "This is a random plushie" + icon = 'icons/obj/toy.dmi' + icon_state = "basecarp" + +/obj/random/carp_plushie/item_to_spawn() + return pick(typesof(/obj/item/toy/plushie/carp)) //can pick any carp plushie, even the original. + +/obj/item/toy/plushie/carp/ice + name = "ice carp plushie" + icon_state = "icecarp" + +/obj/item/toy/plushie/carp/silent + name = "monochrome carp plushie" + icon_state = "silentcarp" + +/obj/item/toy/plushie/carp/electric + name = "electric carp plushie" + icon_state = "electriccarp" + +/obj/item/toy/plushie/carp/gold + name = "golden carp plushie" + icon_state = "goldcarp" + +/obj/item/toy/plushie/carp/toxin + name = "toxic carp plushie" + icon_state = "toxincarp" + +/obj/item/toy/plushie/carp/dragon + name = "dragon carp plushie" + icon_state = "dragoncarp" + +/obj/item/toy/plushie/carp/pink + name = "pink carp plushie" + icon_state = "pinkcarp" + +/obj/item/toy/plushie/carp/candy + name = "candy carp plushie" + icon_state = "candycarp" + +/obj/item/toy/plushie/carp/nebula + name = "nebula carp plushie" + icon_state = "nebulacarp" + +/obj/item/toy/plushie/carp/void + name = "void carp plushie" + icon_state = "voidcarp" + +//Large plushies. +/obj/structure/plushie + name = "generic plush" + desc = "A very generic plushie. It seems to not want to exist." + icon = 'icons/obj/toy.dmi' + icon_state = "ianplushie" + anchored = 0 + density = 1 + var/phrase = "I don't want to exist anymore!" + var/searching = FALSE + var/opened = FALSE // has this been slit open? this will allow you to store an object in a plushie. + var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself. + +/obj/structure/plushie/examine(mob/user) + . = ..() + if(opened) + . += "You notice an incision has been made on [src]." + if(in_range(user, src) && stored_item) + . += "You can see something in there..." + +/obj/structure/plushie/attack_hand(mob/user) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + + if(stored_item && opened && !searching) + searching = TRUE + if(do_after(user, 10)) + to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") + stored_item.forceMove(get_turf(src)) + stored_item = null + searching = FALSE + return + else + searching = FALSE + + if(user.a_intent == I_HELP) + user.visible_message("\The [user] hugs [src]!","You hug [src]!") + else if (user.a_intent == I_HURT) + user.visible_message("\The [user] punches [src]!","You punch [src]!") + else if (user.a_intent == I_GRAB) + user.visible_message("\The [user] attempts to strangle [src]!","You attempt to strangle [src]!") + else + user.visible_message("\The [user] pokes the [src].","You poke the [src].") + visible_message("[src] says, \"[phrase]\"") + + +/obj/structure/plushie/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/device/threadneedle) && opened) + to_chat(user, "You sew the hole in [src].") + opened = FALSE + return + + if(is_sharp(I) && !opened) + to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") + opened = TRUE + return + + if(opened) + if(stored_item) + to_chat(user, "There is already something in here.") + return + + if(!(I.w_class > w_class)) + to_chat(user, "You place [I] inside [src].") + user.drop_from_inventory(I, src) + I.forceMove(src) + stored_item = I + return + else + to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") + + + ..() + +/obj/structure/plushie/ian + name = "plush corgi" + desc = "A plushie of an adorable corgi! Don't you just want to hug it and squeeze it and call it \"Ian\"?" + icon_state = "ianplushie" + phrase = "Arf!" + +/obj/structure/plushie/drone + name = "plush drone" + desc = "A plushie of a happy drone! It appears to be smiling." + icon_state = "droneplushie" + phrase = "Beep boop!" + +/obj/structure/plushie/carp + name = "plush carp" + desc = "A plushie of an elated carp! Straight from the wilds of the Vir frontier, now right here in your hands." + icon_state = "carpplushie" + phrase = "Glorf!" + +/obj/structure/plushie/beepsky + name = "plush Officer Sweepsky" + desc = "A plushie of a popular industrious cleaning robot! If it could feel emotions, it would love you." + icon_state = "beepskyplushie" + phrase = "Ping!" + +//Small plushies. +/obj/item/toy/plushie + name = "generic small plush" + desc = "A small toy plushie. It's very cute." + icon = 'icons/obj/toy.dmi' + icon_state = "nymphplushie" + drop_sound = 'sound/items/drop/plushie.ogg' + w_class = ITEMSIZE_TINY + var/last_message = 0 + var/pokephrase = "Uww!" + var/searching = FALSE + var/opened = FALSE // has this been slit open? this will allow you to store an object in a plushie. + var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself. + + +/obj/item/toy/plushie/examine(mob/user) + . = ..() + if(opened) + . += "You notice an incision has been made on [src]." + if(in_range(user, src) && stored_item) + . += "You can see something in there..." + +/obj/item/toy/plushie/attack_self(mob/user as mob) + if(stored_item && opened && !searching) + searching = TRUE + if(do_after(user, 10)) + to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") + stored_item.forceMove(get_turf(src)) + stored_item = null + searching = FALSE + return + else + searching = FALSE + + if(world.time - last_message <= 1 SECOND) + return + if(user.a_intent == I_HELP) + user.visible_message("\The [user] hugs [src]!","You hug [src]!") + else if (user.a_intent == I_HURT) + user.visible_message("\The [user] punches [src]!","You punch [src]!") + else if (user.a_intent == I_GRAB) + user.visible_message("\The [user] attempts to strangle [src]!","You attempt to strangle [src]!") + else + user.visible_message("\The [user] pokes [src].","You poke [src].") + playsound(src, 'sound/items/drop/plushie.ogg', 25, 0) + visible_message("[src] says, \"[pokephrase]\"") + last_message = world.time + +/obj/item/toy/plushie/verb/rename_plushie() + set name = "Name Plushie" + set category = "Object" + set desc = "Give your plushie a cute name!" + var/mob/M = usr + if(!M.mind) + return 0 + + var/input = sanitizeSafe(input("What do you want to name the plushie?", ,""), MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src)) + name = input + to_chat(M, "You name the plushie [input], giving it a hug for good luck.") + return 1 + +/obj/item/toy/plushie/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/toy/plushie) || istype(I, /obj/item/organ/external/head)) + user.visible_message("[user] makes \the [I] kiss \the [src]!.", \ + "You make \the [I] kiss \the [src]!.") + return + + + if(istype(I, /obj/item/device/threadneedle) && opened) + to_chat(user, "You sew the hole underneath [src].") + opened = FALSE + return + + if(is_sharp(I) && !opened) + to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") + opened = TRUE + return + + if( (!(I.w_class > w_class)) && opened) + if(stored_item) + to_chat(user, "There is already something in here.") + return + + to_chat(user, "You place [I] inside [src].") + user.drop_from_inventory(I, src) + I.forceMove(src) + stored_item = I + to_chat(user, "You placed [I] into [src].") + return + + return ..() + +/obj/item/toy/plushie/nymph + name = "diona nymph plush" + desc = "A plushie of an adorable diona nymph! While its level of self-awareness is still being debated, its level of cuteness is not." + icon_state = "nymphplushie" + pokephrase = "Chirp!" + +/obj/item/toy/plushie/teshari + name = "teshari plush" + desc = "This is a plush teshari. Very soft, with a pompom on the tail. The toy is made well, as if alive. Looks like she is sleeping. Shhh!" + icon_state = "teshariplushie" + pokephrase = "Rya!" + +/obj/item/toy/plushie/mouse + name = "mouse plush" + desc = "A plushie of a delightful mouse! What was once considered a vile rodent is now your very best friend." + icon_state = "mouseplushie" //TFF 12/11/19 - updated icon to show a sprite that doesn't replicate a dead mouse. Heck you for that! >:C + pokephrase = "Squeak!" + +/obj/item/toy/plushie/kitten + name = "kitten plush" + desc = "A plushie of a cute kitten! Watch as it purrs its way right into your heart." + icon_state = "kittenplushie" + pokephrase = "Mrow!" + +/obj/item/toy/plushie/lizard + name = "lizard plush" + desc = "A plushie of a scaly lizard! Very controversial, after being accused as \"racist\" by some Unathi." + icon_state = "lizardplushie" + pokephrase = "Hiss!" + +/obj/item/toy/plushie/spider + name = "spider plush" + desc = "A plushie of a fuzzy spider! It has eight legs - all the better to hug you with." + icon_state = "spiderplushie" + pokephrase = "Sksksk!" + +/obj/item/toy/plushie/farwa + name = "farwa plush" + desc = "A farwa plush doll. It's soft and comforting!" + icon_state = "farwaplushie" + pokephrase = "Squaw!" + +/obj/item/toy/plushie/corgi + name = "corgi plushie" + icon_state = "corgi" + pokephrase = "Woof!" + +/obj/item/toy/plushie/girly_corgi + name = "corgi plushie" + icon_state = "girlycorgi" + pokephrase = "Arf!" + +/obj/item/toy/plushie/robo_corgi + name = "borgi plushie" + icon_state = "robotcorgi" + pokephrase = "Bark." + +/obj/item/toy/plushie/octopus + name = "octopus plushie" + icon_state = "loveable" + pokephrase = "Squish!" + +/obj/item/toy/plushie/face_hugger + name = "facehugger plushie" + icon_state = "huggable" + pokephrase = "Hug!" + +//foxes are basically the best + +/obj/item/toy/plushie/red_fox + name = "red fox plushie" + icon_state = "redfox" + pokephrase = "Gecker!" + +/obj/item/toy/plushie/black_fox + name = "black fox plushie" + icon_state = "blackfox" + pokephrase = "Ack!" + +/obj/item/toy/plushie/marble_fox + name = "marble fox plushie" + icon_state = "marblefox" + pokephrase = "Awoo!" + +/obj/item/toy/plushie/blue_fox + name = "blue fox plushie" + icon_state = "bluefox" + pokephrase = "Yoww!" + +/obj/item/toy/plushie/orange_fox + name = "orange fox plushie" + icon_state = "orangefox" + pokephrase = "Yagh!" + +/obj/item/toy/plushie/coffee_fox + name = "coffee fox plushie" + icon_state = "coffeefox" + pokephrase = "Gerr!" + +/obj/item/toy/plushie/pink_fox + name = "pink fox plushie" + icon_state = "pinkfox" + pokephrase = "Yack!" + +/obj/item/toy/plushie/purple_fox + name = "purple fox plushie" + icon_state = "purplefox" + pokephrase = "Whine!" + +/obj/item/toy/plushie/crimson_fox + name = "crimson fox plushie" + icon_state = "crimsonfox" + pokephrase = "Auuu!" + +/obj/item/toy/plushie/deer + name = "deer plushie" + icon_state = "deer" + pokephrase = "Bleat!" + +/obj/item/toy/plushie/black_cat + name = "black cat plushie" + icon_state = "blackcat" + pokephrase = "Mlem!" + +/obj/item/toy/plushie/grey_cat + name = "grey cat plushie" + icon_state = "greycat" + pokephrase = "Mraw!" + +/obj/item/toy/plushie/white_cat + name = "white cat plushie" + icon_state = "whitecat" + pokephrase = "Mew!" + +/obj/item/toy/plushie/orange_cat + name = "orange cat plushie" + icon_state = "orangecat" + pokephrase = "Meow!" + +/obj/item/toy/plushie/siamese_cat + name = "siamese cat plushie" + icon_state = "siamesecat" + pokephrase = "Mrew?" + +/obj/item/toy/plushie/tabby_cat + name = "tabby cat plushie" + icon_state = "tabbycat" + pokephrase = "Purr!" + +/obj/item/toy/plushie/tuxedo_cat + name = "tuxedo cat plushie" + icon_state = "tuxedocat" + pokephrase = "Mrowww!!" + +// nah, squids are better than foxes :> + +/obj/item/toy/plushie/squid/green + name = "green squid plushie" + desc = "A small, cute and loveable squid friend. This one is green." + icon = 'icons/obj/toy.dmi' + icon_state = "greensquid" + slot_flags = SLOT_HEAD + pokephrase = "Squrr!" + +/obj/item/toy/plushie/squid/mint + name = "mint squid plushie" + desc = "A small, cute and loveable squid friend. This one is mint coloured." + icon = 'icons/obj/toy.dmi' + icon_state = "mintsquid" + slot_flags = SLOT_HEAD + pokephrase = "Blurble!" + +/obj/item/toy/plushie/squid/blue + name = "blue squid plushie" + desc = "A small, cute and loveable squid friend. This one is blue." + icon = 'icons/obj/toy.dmi' + icon_state = "bluesquid" + slot_flags = SLOT_HEAD + pokephrase = "Blob!" + +/obj/item/toy/plushie/squid/orange + name = "orange squid plushie" + desc = "A small, cute and loveable squid friend. This one is orange." + icon = 'icons/obj/toy.dmi' + icon_state = "orangesquid" + slot_flags = SLOT_HEAD + pokephrase = "Squash!" + +/obj/item/toy/plushie/squid/yellow + name = "yellow squid plushie" + desc = "A small, cute and loveable squid friend. This one is yellow." + icon = 'icons/obj/toy.dmi' + icon_state = "yellowsquid" + slot_flags = SLOT_HEAD + pokephrase = "Glorble!" + +/obj/item/toy/plushie/squid/pink + name = "pink squid plushie" + desc = "A small, cute and loveable squid friend. This one is pink." + icon = 'icons/obj/toy.dmi' + icon_state = "pinksquid" + slot_flags = SLOT_HEAD + pokephrase = "Wobble!" + +/obj/item/toy/plushie/therapy/red + name = "red therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is red." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyred" + item_state = "egg4" // It's the red egg in items_left/righthand + +/obj/item/toy/plushie/therapy/purple + name = "purple therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is purple." + icon = 'icons/obj/toy.dmi' + icon_state = "therapypurple" + item_state = "egg1" // It's the magenta egg in items_left/righthand + +/obj/item/toy/plushie/therapy/blue + name = "blue therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is blue." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyblue" + item_state = "egg2" // It's the blue egg in items_left/righthand + +/obj/item/toy/plushie/therapy/yellow + name = "yellow therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is yellow." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyyellow" + item_state = "egg5" // It's the yellow egg in items_left/righthand + +/obj/item/toy/plushie/therapy/orange + name = "orange therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is orange." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyorange" + item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless + +/obj/item/toy/plushie/therapy/green + name = "green therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is green." + icon = 'icons/obj/toy.dmi' + icon_state = "therapygreen" + item_state = "egg3" // It's the green egg in items_left/righthand + + +//Toy cult sword +/obj/item/toy/cultsword + name = "foam sword" + desc = "An arcane weapon (made of foam) wielded by the followers of the hit Saturday morning cartoon \"King Nursee and the Acolytes of Heroism\"." + icon = 'icons/obj/weapons.dmi' + icon_state = "cultblade" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', + ) + w_class = ITEMSIZE_LARGE + attack_verb = list("attacked", "slashed", "stabbed", "poked") + +//Flowers fake & real + +/obj/item/toy/bouquet + name = "bouquet" + desc = "A lovely bouquet of flowers. Smells nice!" + icon = 'icons/obj/items.dmi' + icon_state = "bouquet" + w_class = ITEMSIZE_SMALL + +/obj/item/toy/bouquet/fake + name = "plastic bouquet" + desc = "A cheap plastic bouquet of flowers. Smells like cheap, toxic plastic." + +/obj/item/toy/stickhorse + name = "stick horse" + desc = "A pretend horse on a stick for any aspiring little cowboy to ride." + icon = 'icons/obj/toy.dmi' + icon_state = "stickhorse" + w_class = ITEMSIZE_LARGE + +////////////////////////////////////////////////////// +// Magic 8-Ball / Conch // +////////////////////////////////////////////////////// + +/obj/item/toy/eight_ball + name = "\improper Magic 8-Ball" + desc = "Mystical! Magical! Ages 8+!" + icon = 'icons/obj/toy.dmi' + icon_state = "eight-ball" + var/use_action = "shakes the ball" + var/cooldown = 0 + var/list/possible_answers = list("Definitely.", "All signs point to yes.", "Most likely.", "Yes.", "Ask again later.", "Better not tell you now.", "Future unclear.", "Maybe.", "Doubtful.", "No.", "Don't count on it.", "Never.") + +/obj/item/toy/eight_ball/attack_self(mob/user as mob) + if(!cooldown) + var/answer = pick(possible_answers) + user.visible_message("[user] focuses on their question and [use_action]...") + user.visible_message("The [src] says \"[answer]\"") + spawn(30) + cooldown = 0 + return + +/obj/item/toy/eight_ball/conch + name = "Magic Conch shell" + desc = "All hail the Magic Conch!" + icon_state = "conch" + use_action = "pulls the string" + possible_answers = list("Yes.", "No.", "Try asking again.", "Nothing.", "I don't think so.", "Neither.", "Maybe someday.") + +// DND Character minis. Use the naming convention (type)character for the icon states. +/obj/item/toy/character + icon = 'icons/obj/toy.dmi' + w_class = ITEMSIZE_SMALL + pixel_z = 5 + +/obj/item/toy/character/alien + name = "xenomorph xiniature" + desc = "A miniature xenomorph. Scary!" + icon_state = "aliencharacter" +/obj/item/toy/character/cleric + name = "cleric miniature" + desc = "A wee little cleric, with his wee little staff." + icon_state = "clericcharacter" +/obj/item/toy/character/warrior + name = "warrior miniature" + desc = "That sword would make a decent toothpick." + icon_state = "warriorcharacter" +/obj/item/toy/character/thief + name = "thief miniature" + desc = "Hey, where did my wallet go!?" + icon_state = "thiefcharacter" +/obj/item/toy/character/wizard + name = "wizard miniature" + desc = "MAGIC!" + icon_state = "wizardcharacter" +/obj/item/toy/character/voidone + name = "void one miniature" + desc = "The dark lord has risen!" + icon_state = "darkmastercharacter" +/obj/item/toy/character/lich + name = "lich miniature" + desc = "Murderboner extraordinaire." + icon_state = "lichcharacter" +/obj/item/weapon/storage/box/characters + name = "box of miniatures" + desc = "The nerd's best friends." + icon_state = "box" +/obj/item/weapon/storage/box/characters/starts_with = list( +// /obj/item/toy/character/alien, + /obj/item/toy/character/cleric, + /obj/item/toy/character/warrior, + /obj/item/toy/character/thief, + /obj/item/toy/character/wizard, + /obj/item/toy/character/voidone, + /obj/item/toy/character/lich + ) + +/obj/item/toy/AI + name = "toy AI" + desc = "A little toy model AI core!"// with real law announcing action!" //Alas, requires a rewrite of how ion laws work. + icon = 'icons/obj/toy.dmi' + icon_state = "AI" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 +/* +/obj/item/toy/AI/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = generate_ion_law() + to_chat(user, "You press the button on [src].") + playsound(src, 'sound/machines/click.ogg', 20, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() +*/ +/obj/item/toy/owl + name = "owl action figure" + desc = "An action figure modeled after 'The Owl', defender of justice." + icon = 'icons/obj/toy.dmi' + icon_state = "owlprize" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/owl/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") + to_chat(user, "You pull the string on the [src].") + //playsound(src, 'sound/misc/hoot.ogg', 25, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + +/obj/item/toy/griffin + name = "griffin action figure" + desc = "An action figure modeled after 'The Griffin', criminal mastermind." + icon = 'icons/obj/toy.dmi' + icon_state = "griffinprize" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/griffin/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") + to_chat(user, "You pull the string on the [src].") + //playsound(src, 'sound/misc/caw.ogg', 25, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + +/* NYET. +/obj/item/weapon/toddler + icon_state = "toddler" + name = "toddler" + desc = "This baby looks almost real. Wait, did it just burp?" + force = 5 + w_class = ITEMSIZE_LARGE + slot_flags = SLOT_BACK +*/ + +//This should really be somewhere else but I don't know where. w/e + +/obj/item/weapon/inflatable_duck + name = "inflatable duck" + desc = "No bother to sink or swim when you can just float!" + icon_state = "inflatable" + icon = 'icons/obj/clothing/belts.dmi' + slot_flags = SLOT_BELT + drop_sound = 'sound/items/drop/rubber.ogg' + +/obj/item/toy/xmastree + name = "Miniature Christmas tree" + desc = "Tiny cute Christmas tree." + icon = 'icons/obj/toy.dmi' + icon_state = "tinyxmastree" + w_class = ITEMSIZE_TINY + force = 1 + throwforce = 1 + drop_sound = 'sound/items/drop/box.ogg' + +////////////////////////////////////////////////////// +// Chess Pieces // +////////////////////////////////////////////////////// + +/obj/item/toy/chess + name = "chess piece" + desc = "This should never display." + icon = 'icons/obj/chess.dmi' + w_class = ITEMSIZE_SMALL + force = 1 + throwforce = 1 + drop_sound = 'sound/items/drop/glass.ogg' + +/obj/item/toy/chess/pawn_white + name = "blue pawn" + desc = "A large pawn piece for playing chess. It's made of a blue-colored glass." + description_info = "Pawns can move forward one square, if that square is unoccupied. If the pawn has not yet moved, it has the option of moving two squares forward provided both squares in front of the pawn are unoccupied. A pawn cannot move backward. They can only capture an enemy piece on either of the two tiles diagonally in front of them, but not the tile directly in front of them." + icon_state = "w-pawn" +/obj/item/toy/chess/pawn_black + name = "purple pawn" + desc = "A large pawn piece for playing chess. It's made of a purple-colored glass." + description_info = "Pawns can move forward one square, if that square is unoccupied. If the pawn has not yet moved, it has the option of moving two squares forward provided both squares in front of the pawn are unoccupied. A pawn cannot move backward. They can only capture an enemy piece on either of the two tiles diagonally in front of them, but not the tile directly in front of them." + icon_state = "b-pawn" +/obj/item/toy/chess/rook_white + name = "blue rook" + desc = "A large rook piece for playing chess. It's made of a blue-colored glass." + description_info = "The Rook can move any number of vacant squares vertically or horizontally." + icon_state = "w-rook" +/obj/item/toy/chess/rook_black + name = "purple rook" + desc = "A large rook piece for playing chess. It's made of a purple-colored glass." + description_info = "The Rook can move any number of vacant squares vertically or horizontally." + icon_state = "b-rook" +/obj/item/toy/chess/knight_white + name = "blue knight" + desc = "A large knight piece for playing chess. It's made of a blue-colored glass. Sadly, you can't ride it." + description_info = "The Knight can either move two squares horizontally and one square vertically or two squares vertically and one square horizontally. The knight's movement can also be viewed as an 'L' laid out at any horizontal or vertical angle." + icon_state = "w-knight" +/obj/item/toy/chess/knight_black + name = "purple knight" + desc = "A large knight piece for playing chess. It's made of a purple-colored glass. 'Just a flesh wound.'" + description_info = "The Knight can either move two squares horizontally and one square vertically or two squares vertically and one square horizontally. The knight's movement can also be viewed as an 'L' laid out at any horizontal or vertical angle." + icon_state = "b-knight" +/obj/item/toy/chess/bishop_white + name = "blue bishop" + desc = "A large bishop piece for playing chess. It's made of a blue-colored glass." + description_info = "The Bishop can move any number of vacant squares in any diagonal direction." + icon_state = "w-bishop" +/obj/item/toy/chess/bishop_black + name = "purple bishop" + desc = "A large bishop piece for playing chess. It's made of a purple-colored glass." + description_info = "The Bishop can move any number of vacant squares in any diagonal direction." + icon_state = "b-bishop" +/obj/item/toy/chess/queen_white + name = "blue queen" + desc = "A large queen piece for playing chess. It's made of a blue-colored glass." + description_info = "The Queen can move any number of vacant squares diagonally, horizontally, or vertically." + icon_state = "w-queen" +/obj/item/toy/chess/queen_black + name = "purple queen" + desc = "A large queen piece for playing chess. It's made of a purple-colored glass." + description_info = "The Queen can move any number of vacant squares diagonally, horizontally, or vertically." + icon_state = "b-queen" +/obj/item/toy/chess/king_white + name = "blue king" + desc = "A large king piece for playing chess. It's made of a blue-colored glass." + description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose." + icon_state = "w-king" +/obj/item/toy/chess/king_black + name = "purple king" + desc = "A large king piece for playing chess. It's made of a purple-colored glass." + description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose." icon_state = "b-king" \ No newline at end of file diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index 4b18001e45..73d3dd45e7 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -7,6 +7,7 @@ w_class = ITEMSIZE_SMALL desc = "This is rubbish." drop_sound = 'sound/items/drop/wrapper.ogg' + pickup_sound = 'sound/items/pickup/wrapper.ogg' var/age = 0 /obj/item/trash/New(var/newloc, var/_age) @@ -64,7 +65,7 @@ icon_state = "popcorn" /obj/item/trash/tuna - name = "tuna can" + name = "fish flake packet" icon_state = "tuna" /obj/item/trash/sosjerky @@ -75,6 +76,7 @@ name = "Moghes Imported Sissalik Jerky tin" icon_state = "unathitinred" drop_sound = 'sound/items/drop/soda.ogg' + pickup_sound = 'sound/items/pickup/soda.ogg' /obj/item/trash/syndi_cakes name = "syndi cakes box" @@ -108,6 +110,10 @@ name = "candy wrapper" icon_state = "kokobar" +/obj/item/trash/skrellsnax + name = "skrellsnax packet" + icon_state = "skrellsnacks" + /obj/item/trash/gumpack name = "gum packet" icon_state = "gum_pack" diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index d90a462519..05e4c2a7c6 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -5,6 +5,8 @@ icon = 'icons/obj/tools.dmi' icon_state = "rcd" item_state = "rcd" + drop_sound = 'sound/items/drop/gun.ogg' + pickup_sound = 'sound/items/pickup/gun.ogg' flags = NOBLUDGEON force = 10 throwforce = 10 diff --git a/code/game/objects/items/weapons/RPD_vr.dm b/code/game/objects/items/weapons/RPD_vr.dm index c980bf1bc3..d4650eb16a 100644 --- a/code/game/objects/items/weapons/RPD_vr.dm +++ b/code/game/objects/items/weapons/RPD_vr.dm @@ -79,6 +79,9 @@ get_asset_datum(/datum/asset/spritesheet/pipes), ) +/obj/item/weapon/pipe_dispenser/tgui_state(mob/user) + return GLOB.tgui_inventory_state + /obj/item/weapon/pipe_dispenser/tgui_interact(mob/user, datum/tgui/ui) SetupPipes() ui = SStgui.try_update_ui(user, src, ui) diff --git a/code/game/objects/items/weapons/candle.dm b/code/game/objects/items/weapons/candle.dm index 18cb433ded..7663dfd7ff 100644 --- a/code/game/objects/items/weapons/candle.dm +++ b/code/game/objects/items/weapons/candle.dm @@ -3,6 +3,8 @@ desc = "a red pillar candle. Its specially-formulated fuel-oxidizer wax mixture allows continued combustion in airless environments." icon = 'icons/obj/candle.dmi' icon_state = "candle1" + drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/gloves.ogg' w_class = ITEMSIZE_TINY light_color = "#E09D37" var/wax = 2000 diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 1f7149e893..2ac0098203 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -34,7 +34,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM origin_tech = list(TECH_MATERIAL = 1) slot_flags = SLOT_EARS attack_verb = list("burnt", "singed") - drop_sound = null + drop_sound = 'sound/items/drop/food.ogg' + pickup_sound = 'sound/items/pickup/food.ogg' /obj/item/weapon/flame/match/process() if(isliving(loc)) @@ -340,6 +341,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/smokable/cigarette/cigar name = "premium cigar" desc = "A brown roll of tobacco and... well, you're not quite sure. This thing's huge!" + description_fluff = "While the label does say that this is a 'premium cigar', it really cannot match other types of cigars on the market. Is it a quality cigarette? Perhaps. Was it hand-made with care? No." icon_state = "cigar2" type_butt = /obj/item/trash/cigbutt/cigarbutt throw_speed = 0.5 @@ -357,12 +359,14 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/smokable/cigarette/cigar/cohiba name = "\improper Cohiba Robusto cigar" desc = "There's little more you could want from a cigar." + description_fluff = "Cohiba has been a popular cigar company for centuries. They are still based out of Cuba and refuse to expand and therefore have a very limited quantity, making their cigars coveted all through known space. Robusto is one of their most popular shapes of cigars." icon_state = "cigar2" nicotine_amt = 7 /obj/item/clothing/mask/smokable/cigarette/cigar/havana name = "premium Havanian cigar" desc = "A cigar fit for only the best of the best." + description_fluff = "'Havanian' is an umbrella term for any cigar made in the typical handmade style of Cuba. This particular cigar is from Gilthari's cigar manufacturers and produced galaxy-wide. While this way of making quality cigars has become slightly bastardized over the years, overall quality has remained relatively the same, even if there is a large quantity of 'Havanian' cigars." icon_state = "cigar2" max_smoketime = 7200 smoketime = 7200 @@ -402,6 +406,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/smokable/pipe name = "smoking pipe" desc = "A pipe, for smoking. Made of fine, stained cherry wood." + description_fluff = "ClassiCo Accessories and Haberdashers, originating out of Mars, claim to produce products 'for the modern gentlefolk'. Most of their items are high-end and expensive, but they pledge to back their prices up with quality, and usually do." icon_state = "pipe" item_state = "pipe" smoketime = 0 diff --git a/code/game/objects/items/weapons/circuitboards/machinery/research.dm b/code/game/objects/items/weapons/circuitboards/machinery/research.dm index 5342ee5220..2f10bfce2c 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/research.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/research.dm @@ -78,7 +78,7 @@ obj/item/weapon/circuitboard/rdserver/attackby(obj/item/I as obj, mob/user as mo /obj/item/weapon/circuitboard/prosthetics name = "Circuit board (Prosthetics Fabricator)" - build_path = /obj/machinery/pros_fabricator + build_path = /obj/machinery/mecha_part_fabricator/pros board_type = new /datum/frame/frame_types/machine origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) req_components = list( diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 7150f7f556..5e93f2d031 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -9,6 +9,7 @@ var/colour = "red" var/open = 0 drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/weapon/lipstick/purple name = "purple lipstick" diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 9000ec4b1f..3c17549d25 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -67,7 +67,7 @@ if(istype(M,/mob/living)) var/mob/living/L = M L.apply_effect(rand(5,20), IRRADIATE, check_protection = 0) - L.apply_damage(max(2,L.getCloneLoss()), CLONE) + L.apply_damage(max(2,L.getCloneLoss()), CLONE) if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed if (buf.types & DNA2_BUF_UI) @@ -158,7 +158,7 @@ /obj/item/weapon/dnainjector/xraymut name = "\improper DNA injector (Xray)" - desc = "Finally you can see what the Colony Director does." + desc = "Finally you can see what the Site Manager does." datatype = DNA2_BUF_SE value = 0xFFF //block = 8 diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index ca8a538646..5a94a92572 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -13,6 +13,7 @@ matter = list(DEFAULT_WALL_MATERIAL = 90) attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed") drop_sound = 'sound/items/drop/gascan.ogg' + pickup_sound = 'sound/items/pickup/gascan.ogg' var/spray_particles = 3 var/spray_amount = 10 //units of liquid per particle diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 22abe36ab4..f828b97b23 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -13,7 +13,8 @@ icon = 'icons/obj/items.dmi' icon_state = "gift1" item_state = "gift1" - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/weapon/a_gift/New() ..() @@ -125,6 +126,8 @@ icon = 'icons/obj/items.dmi' icon_state = "wrap_paper" var/amount = 20.0 + drop_sound = 'sound/items/drop/wrapper.ogg' + pickup_sound = 'sound/items/pickup/wrapper.ogg' /obj/item/weapon/wrapping_paper/attackby(obj/item/weapon/W as obj, mob/living/user as mob) ..() diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index e2d095e0e1..b176563b26 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -99,7 +99,7 @@ /obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve - desc = "Use of this weapon may constiute a war crime in your area, consult your local Colony Director." + desc = "Use of this weapon may constiute a war crime in your area, consult your local Site Manager." name = "clusterbang" icon = 'icons/obj/grenade.dmi' icon_state = "clusterbang" diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index b28ebcaf1e..924d753c28 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -12,6 +12,7 @@ origin_tech = list(TECH_MATERIAL = 1) matter = list(DEFAULT_WALL_MATERIAL = 500) drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' var/elastic var/dispenser = 0 var/breakouttime = 1200 //Deciseconds = 120s = 2 minutes diff --git a/code/game/objects/items/weapons/id cards/cards.dm b/code/game/objects/items/weapons/id cards/cards.dm index 6179632f9b..fa56f6ccc1 100644 --- a/code/game/objects/items/weapons/id cards/cards.dm +++ b/code/game/objects/items/weapons/id cards/cards.dm @@ -21,6 +21,7 @@ var/list/files = list( ) drop_sound = 'sound/items/drop/card.ogg' + pickup_sound = 'sound/items/pickup/card.ogg' /obj/item/weapon/card/data name = "data disk" @@ -30,6 +31,8 @@ var/data = "null" var/special = null item_state = "card-id" + drop_sound = 'sound/items/drop/disk.ogg' + pickup_sound = 'sound/items/pickup/disk.ogg' /obj/item/weapon/card/data/verb/label(t as text) set name = "Label Disk" diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm index d701070aca..ffa33472b6 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -40,6 +40,9 @@ /obj/item/weapon/card/id/proc/prevent_tracking() return 0 +/obj/item/weapon/card/id/tgui_state(mob/user) + return GLOB.tgui_deep_inventory_state + /obj/item/weapon/card/id/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) @@ -135,13 +138,13 @@ preserve_item = 1 /obj/item/weapon/card/id/gold/captain - assignment = "Colony Director" - rank = "Colony Director" + assignment = "Site Manager" + rank = "Site Manager" /obj/item/weapon/card/id/gold/captain/spare - name = "\improper Colony Director's spare ID" + name = "\improper Site Manager's spare ID" desc = "The spare ID of the High Lord himself." - registered_name = "Colony Director" + registered_name = "Site Manager" /obj/item/weapon/card/id/synthetic name = "\improper Synthetic ID" diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index f665e15d09..b8252872e8 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -1147,7 +1147,7 @@ Remember the order:
Disk, Code, Safety, Timer, Disk, RUN!

- Intelligence Analysts believe that normal corporate procedure is for the Colony Director to secure the nuclear authentication disk.

+ Intelligence Analysts believe that normal corporate procedure is for the Site Manager to secure the nuclear authentication disk.

Good luck! diff --git a/code/game/objects/items/weapons/material/kitchen.dm b/code/game/objects/items/weapons/material/kitchen.dm index 4464084f85..e52b2add28 100644 --- a/code/game/objects/items/weapons/material/kitchen.dm +++ b/code/game/objects/items/weapons/material/kitchen.dm @@ -5,6 +5,8 @@ * Utensils */ /obj/item/weapon/material/kitchen/utensil + drop_sound = 'sound/items/drop/knife.ogg' + pickup_sound = 'sound/items/pickup/knife.ogg' w_class = ITEMSIZE_TINY thrown_force_divisor = 1 origin_tech = list(TECH_MATERIAL = 1) @@ -104,6 +106,7 @@ dulled_divisor = 0.75 // Still a club thrown_force_divisor = 1 // as above drop_sound = 'sound/items/drop/wooden.ogg' + pickup_sound = 'sound/items/pickup/wooden.ogg' /obj/item/weapon/material/kitchen/rollingpin/attack(mob/living/M as mob, mob/living/user as mob) if ((CLUMSY in user.mutations) && prob(50)) diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm index 9f8a27102c..678b77b622 100644 --- a/code/game/objects/items/weapons/material/knives.dm +++ b/code/game/objects/items/weapons/material/knives.dm @@ -10,6 +10,7 @@ force_divisor = 0.25 // 15 when wielded with hardness 60 (steel) thrown_force_divisor = 0.25 // 5 when thrown with weight 20 (steel) drop_sound = 'sound/items/drop/knife.ogg' + pickup_sound = 'sound/items/pickup/knife.ogg' /obj/item/weapon/material/butterfly/update_force() if(active) diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index 29193b1c08..754943671e 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -22,6 +22,7 @@ attack_verb = list("chopped", "torn", "cut") applies_material_colour = 0 drop_sound = 'sound/items/drop/axe.ogg' + pickup_sound = 'sound/items/pickup/axe.ogg' /obj/item/weapon/material/knife/machete/hatchet/unathiknife name = "duelling knife" diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index ba0fe4ddfe..4454b0b066 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -10,6 +10,7 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' drop_sound = 'sound/items/drop/sword.ogg' + pickup_sound = 'sound/items/pickup/sword.ogg' /obj/item/weapon/material/sword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") if(unique_parry_check(user, attacker, damage_source) && prob(50)) diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm index 0ffd1dfaac..e8af0c6a5b 100644 --- a/code/game/objects/items/weapons/material/twohanded.dm +++ b/code/game/objects/items/weapons/material/twohanded.dm @@ -26,6 +26,9 @@ var/base_icon var/base_name var/unwielded_force_divisor = 0.25 + hitsound = "swing_hit" + drop_sound = 'sound/items/drop/sword.ogg' + pickup_sound = 'sound/items/pickup/sword.ogg' /obj/item/weapon/material/twohanded/update_held_icon() var/mob/living/M = loc @@ -96,6 +99,7 @@ applies_material_colour = 0 can_cleave = TRUE drop_sound = 'sound/items/drop/axe.ogg' + pickup_sound = 'sound/items/pickup/axe.ogg' /obj/item/weapon/material/twohanded/fireaxe/update_held_icon() var/mob/living/M = loc @@ -152,6 +156,7 @@ edge = 0 sharp = 1 hitsound = 'sound/weapons/bladeslice.ogg' + mob_throw_hit_sound = 'sound/weapons/pierce.ogg' attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") default_material = "glass" applies_material_colour = 0 diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 7153ebfa60..c4025f088a 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -279,6 +279,8 @@ sharp = 1 edge = 1 colorable = TRUE + drop_sound = 'sound/items/drop/sword.ogg' + pickup_sound = 'sound/items/pickup/sword.ogg' projectile_parry_chance = 65 diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 2cdc341523..5741387b7b 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -17,6 +17,7 @@ var/flippable = 0 var/side = 0 //0 = right, 1 = left drop_sound = 'sound/items/drop/backpack.ogg' + pickup_sound = 'sound/items/pickup/backpack.ogg' /obj/item/weapon/storage/backpack/equipped(var/mob/user, var/slot) @@ -92,7 +93,7 @@ icon_state = "securitypack" /obj/item/weapon/storage/backpack/captain - name = "colony director's backpack" + name = "site manager's backpack" desc = "It's a special backpack made exclusively for officers." icon_state = "captainpack" @@ -154,7 +155,7 @@ icon_state = "duffle_syndieammo" /obj/item/weapon/storage/backpack/dufflebag/captain - name = "colony director's dufflebag" + name = "site manager's dufflebag" desc = "A large dufflebag for holding extra captainly goods." icon_state = "duffle_captain" @@ -249,7 +250,7 @@ icon_state = "satchel_hyd" /obj/item/weapon/storage/backpack/satchel/cap - name = "colony director's satchel" + name = "site manager's satchel" desc = "An exclusive satchel for officers." icon_state = "satchel-cap" item_state_slots = list(slot_r_hand_str = "captainpack", slot_l_hand_str = "captainpack") diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index f431bc74fe..6b60255f46 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -24,6 +24,7 @@ use_to_pickup = 1 slot_flags = SLOT_BELT drop_sound = 'sound/items/drop/backpack.ogg' + pickup_sound = 'sound/items/pickup/backpack.ogg' // ----------------------------- // Trash bag @@ -35,6 +36,7 @@ icon_state = "trashbag0" item_state_slots = list(slot_r_hand_str = "trashbag", slot_l_hand_str = "trashbag") drop_sound = 'sound/items/drop/wrapper.ogg' + pickup_sound = 'sound/items/pickup/wrapper.ogg' w_class = ITEMSIZE_LARGE max_w_class = ITEMSIZE_SMALL @@ -62,6 +64,7 @@ icon = 'icons/obj/trash.dmi' icon_state = "plasticbag" drop_sound = 'sound/items/drop/wrapper.ogg' + pickup_sound = 'sound/items/pickup/wrapper.ogg' w_class = ITEMSIZE_LARGE max_w_class = ITEMSIZE_SMALL diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index c900e729c5..c3dba166bc 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -8,8 +8,10 @@ max_w_class = ITEMSIZE_NORMAL slot_flags = SLOT_BELT attack_verb = list("whipped", "lashed", "disciplined") + equip_sound = 'sound/items/toolbelt_equip.ogg' + drop_sound = 'sound/items/drop/toolbelt.ogg' + pickup_sound = 'sound/items/pickup/toolbelt.ogg' sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi') - drop_sound = 'sound/items/drop/leather.ogg' var/show_above_suit = 0 diff --git a/code/game/objects/items/weapons/storage/belt_vr.dm b/code/game/objects/items/weapons/storage/belt_vr.dm index 2e0829c153..e726e30b9c 100644 --- a/code/game/objects/items/weapons/storage/belt_vr.dm +++ b/code/game/objects/items/weapons/storage/belt_vr.dm @@ -1,4 +1,55 @@ /obj/item/weapon/storage/belt sprite_sheets = list( SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi', - SPECIES_WEREBEAST = 'icons/mob/species/werebeast/belt.dmi') \ No newline at end of file + SPECIES_WEREBEAST = 'icons/mob/species/werebeast/belt.dmi') + +/obj/item/weapon/storage/belt/explorer + name = "explorer's belt" + desc = "A versatile belt with several pouches. It can hold a very wide variety of items, but less items overall than a dedicated belt. Still, it's useful for any explorer who wants to be prepared for anything they might find." + icon_state = "explorer_belt" + icon = 'icons/obj/clothing/belts_vr.dmi' + icon_override = 'icons/mob/belt_vr.dmi' + storage_slots = 5 //makes it strictly inferior to any specialized belt as they have seven slots, but it's far more versatile + max_w_class = ITEMSIZE_NORMAL //limits the max size of thing that can be put in, so no using it to hold five laser cannons + max_storage_space = ITEMSIZE_COST_NORMAL * 5 + can_hold = list( + /obj/item/weapon/grenade, + /obj/item/weapon/tool, + /obj/item/weapon/weldingtool, + /obj/item/weapon/pickaxe, + /obj/item/device/multitool, + /obj/item/stack/cable_coil, + /obj/item/device/analyzer, + /obj/item/device/flashlight, + /obj/item/weapon/cell, + /obj/item/weapon/gun, + /obj/item/weapon/material, + /obj/item/weapon/melee, + /obj/item/weapon/shield, + /obj/item/ammo_casing, + /obj/item/ammo_magazine, + /obj/item/device/healthanalyzer, + /obj/item/device/robotanalyzer, + /obj/item/weapon/reagent_containers/glass/beaker, + /obj/item/weapon/reagent_containers/glass/bottle, + /obj/item/weapon/storage/pill_bottle, + /obj/item/stack/medical, + /obj/item/stack/marker_beacon, + /obj/item/weapon/extinguisher/mini, + /obj/item/weapon/storage/quickdraw/syringe_case, + /obj/item/weapon/photo, + /obj/item/device/camera_film, + /obj/item/device/camera, + /obj/item/device/taperecorder, + /obj/item/device/tape, + /obj/item/device/geiger, + /obj/item/device/gps, + /obj/item/device/ano_scanner, + /obj/item/device/cataloguer + ) + +/obj/item/weapon/storage/belt/explorer/pathfinder + name = "pathfinder's belt" + desc = "A deluxe belt with many pouches. It can hold a very wide variety of items, but less items overall than a dedicated belt. Still, it's useful for any explorer who wants to be prepared for anything they might find." + storage_slots = 7 //two more, bringing it on par with normal belts + max_storage_space = ITEMSIZE_COST_NORMAL * 7 \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index bab0070126..37a135cfde 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -30,7 +30,8 @@ max_w_class = ITEMSIZE_SMALL max_storage_space = INVENTORY_BOX_SPACE use_sound = 'sound/items/storage/box.ogg' - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' // BubbleWrap - A box can be folded up to make card /obj/item/weapon/storage/box/attack_self(mob/user as mob) @@ -58,7 +59,7 @@ //try to crush it if(ispath(trash)) if(contents.len && user.a_intent == I_HURT) // only crumple with things inside on harmintent. - user.visible_message(SPAN_DANGER("You crush \the [src], spilling its contents everywhere!"), SPAN_DANGER("[user] crushes \the [src], spilling its contents everywhere!")) + user.visible_message(SPAN_DANGER("[user] crushes \the [src], spilling its contents everywhere!"), SPAN_DANGER("You crush \the [src], spilling its contents everywhere!")) spill() else to_chat(user, SPAN_NOTICE("You crumple up \the [src].")) //make trash @@ -137,6 +138,8 @@ icon_state = "blankshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g/blank = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/blanks/large starts_with = list(/obj/item/ammo_casing/a12g/blank = 16) @@ -147,6 +150,8 @@ icon_state = "beanshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g/beanbag = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/beanbags/large starts_with = list(/obj/item/ammo_casing/a12g/beanbag = 16) @@ -157,6 +162,8 @@ icon_state = "lethalshellshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/shotgunammo/large starts_with = list(/obj/item/ammo_casing/a12g = 16) @@ -167,6 +174,8 @@ icon_state = "lethalslug_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g/pellet = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/shotgunshells/large starts_with = list(/obj/item/ammo_casing/a12g/pellet = 16) @@ -177,6 +186,8 @@ icon_state = "illumshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g/flash = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/flashshells/large starts_with = list(/obj/item/ammo_casing/a12g/flash = 16) @@ -187,6 +198,8 @@ icon_state = "stunshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g/stunshell = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/stunshells/large starts_with = list(/obj/item/ammo_casing/a12g/stunshell = 16) @@ -197,6 +210,8 @@ icon_state = "blankshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g/practice = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/practiceshells/large starts_with = list(/obj/item/ammo_casing/a12g/practice = 16) @@ -207,6 +222,8 @@ icon_state = "empshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g/emp = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/empshells/large starts_with = list(/obj/item/ammo_casing/a12g/emp = 16) @@ -217,6 +234,8 @@ icon_state = "lethalslug_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") starts_with = list(/obj/item/ammo_casing/a12g/flechette = 8) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/flechetteshells/large starts_with = list(/obj/item/ammo_casing/a12g/flechette = 16) @@ -225,6 +244,8 @@ name = "box of 14.5mm shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." starts_with = list(/obj/item/ammo_casing/a145 = 7) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/sniperammo/highvel name = "box of 14.5mm sabot shells" @@ -236,42 +257,56 @@ desc = "WARNING: These devices are extremely dangerous and can cause blindness or deafness in repeated use." icon_state = "flashbang" starts_with = list(/obj/item/weapon/grenade/flashbang = 7) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/emps name = "box of emp grenades" desc = "A box containing 5 military grade EMP grenades.
WARNING: Do not use near unshielded electronics or biomechanical augmentations, death or permanent paralysis may occur." icon_state = "emp" starts_with = list(/obj/item/weapon/grenade/empgrenade = 7) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/empslite name = "box of low yield emp grenades" desc = "A box containing 5 low yield EMP grenades.
WARNING: Do not use near unshielded electronics or biomechanical augmentations, death or permanent paralysis may occur." icon_state = "emp" starts_with = list(/obj/item/weapon/grenade/empgrenade/low_yield = 7) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/smokes name = "box of smoke bombs" desc = "A box containing 7 smoke bombs." icon_state = "flashbang" starts_with = list(/obj/item/weapon/grenade/smokebomb = 7) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/anti_photons name = "box of anti-photon grenades" desc = "A box containing 7 experimental photon disruption grenades." icon_state = "flashbang" starts_with = list(/obj/item/weapon/grenade/anti_photon = 7) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/frags name = "box of fragmentation grenades (WARNING)" desc = "A box containing 7 military grade fragmentation grenades.
WARNING: These devices are extremely dangerous and can cause limb loss or death in repeated use." icon_state = "frag" starts_with = list(/obj/item/weapon/grenade/explosive = 7) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/frags_half_box name = "box of fragmentation grenades (WARNING)" desc = "A box containing 4 military grade fragmentation grenades.
WARNING: These devices are extremely dangerous and can cause limb loss or death in repeated use." icon_state = "frag" starts_with = list(/obj/item/weapon/grenade/explosive = 4) + drop_sound = 'sound/items/drop/ammobox.ogg' + pickup_sound = 'sound/items/pickup/ammobox.ogg' /obj/item/weapon/storage/box/metalfoam name = "box of metal foam grenades." @@ -434,6 +469,8 @@ slot_flags = SLOT_BELT can_hold = list(/obj/item/weapon/flame/match) starts_with = list(/obj/item/weapon/flame/match = 10) + drop_sound = 'sound/items/drop/matchbox.ogg' + pickup_sound = 'sound/items/pickup/matchbox.ogg' /obj/item/weapon/storage/box/matches/attackby(var/obj/item/weapon/flame/match/W, var/mob/user) if(istype(W) && !W.lit && !W.burnt) diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index 3d24c6dd0a..86e2b06298 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -10,6 +10,7 @@ max_storage_space = ITEMSIZE_COST_NORMAL * 4 use_sound = 'sound/items/storage/briefcase.ogg' drop_sound = 'sound/items/drop/backpack.ogg' + pickup_sound = 'sound/items/pickup/backpack.ogg' /obj/item/weapon/storage/briefcase/clutch name = "clutch purse" diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 8f60a9f706..704081437e 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -19,6 +19,8 @@ icon_state = "donutbox6" name = "donut box" var/icon_type = "donut" + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/weapon/storage/fancy/update_icon(var/itemremoved = 0) var/total_contents = contents.len - itemremoved @@ -202,6 +204,7 @@ /obj/item/weapon/storage/fancy/cigarettes name = "\improper pack of Trans-Stellar Duty-frees" desc = "A ubiquitous brand of cigarettes, found in every major spacefaring corporation in the universe. As mild and flavorless as it gets." + description_fluff = "The Trans-Stellar Duty-Free Cigarette Company was created as an imprint of NanoTrasen. They are the most boring, tasteless, dry cigarettes on the market, but due to just how unremarkable (not to mention cheap to produce) they are, they sold in vending machines in almost every corner of the galaxy." icon = 'icons/obj/cigarettes.dmi' icon_state = "cigpacket" item_state_slots = list(slot_r_hand_str = "cigpacket", slot_l_hand_str = "cigpacket") @@ -316,7 +319,7 @@ /obj/item/weapon/storage/fancy/cigar name = "cigar case" desc = "A case for holding your cigars when you are not smoking them." - description_fluff = "The tastefully engraved palm tree tells you that these 'Corona Grande' premium cigars are only sold on the luxury cruises and resorts of Oasis, though ten separate companies produce them for that purpose galaxy-wide. The standard is however very high." + description_fluff = "The tastefully engraved palm tree tells you that these 'Palma Grande' premium cigars are only sold on the luxury cruises and resorts of Oasis, though ten separate companies produce them for that purpose galaxy-wide. The standard is however very high." icon_state = "cigarcase" icon = 'icons/obj/cigarettes.dmi' w_class = ITEMSIZE_TINY diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 703649f4f1..9b87ee51d3 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -16,7 +16,8 @@ throw_range = 8 max_storage_space = ITEMSIZE_COST_SMALL * 7 // 14 var/list/icon_variety - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/weapon/storage/firstaid/Initialize() . = ..() @@ -175,6 +176,7 @@ icon_state = "pill_canister" icon = 'icons/obj/chemical.dmi' drop_sound = 'sound/items/drop/pillbottle.ogg' + pickup_sound = 'sound/items/pickup/pillbottle.ogg' item_state_slots = list(slot_r_hand_str = "contsolid", slot_l_hand_str = "contsolid") w_class = ITEMSIZE_SMALL can_hold = list(/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/dice,/obj/item/weapon/paper) diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index d23a5e2d69..e62ac35ea8 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -15,7 +15,8 @@ origin_tech = list(TECH_COMBAT = 1) attack_verb = list("robusted") use_sound = 'sound/items/storage/toolbox.ogg' - drop_sound = 'sound/items/drop/metalboots.ogg' + drop_sound = 'sound/items/drop/toolbox.ogg' + pickup_sound = 'sound/items/pickup/toolbox.ogg' /obj/item/weapon/storage/toolbox/emergency name = "emergency toolbox" diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index a668075068..83bb322e0e 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -42,6 +42,9 @@ slot_flags = SLOT_ID var/obj/item/weapon/card/id/front_id = null + + drop_sound = 'sound/items/drop/cloth.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' /obj/item/weapon/storage/wallet/remove_from_storage(obj/item/W as obj, atom/new_location) . = ..(W, new_location) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 482497e993..a8c558ecd1 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -11,6 +11,8 @@ throwforce = 7 flags = NOCONDUCT w_class = ITEMSIZE_NORMAL + drop_sound = 'sound/items/drop/metalweapon.ogg' + pickup_sound = 'sound/items/pickup/metalweapon.ogg' origin_tech = list(TECH_COMBAT = 2) attack_verb = list("beaten") var/lightcolor = "#FF6A00" diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index e5580082a1..15bb7cd0e5 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -13,6 +13,8 @@ desc = "This shouldn't be here, ahelp it." icon = 'icons/obj/surgery.dmi' w_class = ITEMSIZE_SMALL + drop_sound = 'sound/items/drop/weldingtool.ogg' + pickup_sound = 'sound/items/pickup/weldingtool.ogg' var/helpforce = 0 //For help intent things /obj/item/weapon/surgical/attack(mob/M, mob/user) diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index a4a7992872..ad3c856f97 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -26,6 +26,8 @@ item_state = "classic_baton" slot_flags = SLOT_BELT force = 10 + drop_sound = 'sound/items/drop/crowbar.ogg' + pickup_sound = 'sound/items/pickup/crowbar.ogg' /obj/item/weapon/melee/classic_baton/attack(mob/M as mob, mob/living/user as mob) if ((CLUMSY in user.mutations) && prob(50)) @@ -49,6 +51,8 @@ slot_flags = SLOT_BELT w_class = ITEMSIZE_SMALL force = 3 + drop_sound = 'sound/items/drop/crowbar.ogg' + pickup_sound = 'sound/items/pickup/crowbar.ogg' var/on = 0 /obj/item/weapon/melee/telebaton/attack_self(mob/user as mob) diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index b9616b01b6..277a083d54 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -45,7 +45,7 @@ . = ..() air_contents.gas["oxygen"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gas["sleeping_agent"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.gas["nitrous_oxide"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD air_contents.update_values() /* diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index f267ac3654..37da2f3d49 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -11,6 +11,7 @@ var/list/global/tank_gauge_cache = list() SPECIES_TESHARI = 'icons/mob/species/seromi/back.dmi' ) drop_sound = 'sound/items/drop/gascan.ogg' + pickup_sound = 'sound/items/pickup/gascan.ogg' var/gauge_icon = "indicator_tank" var/last_gauge_pressure @@ -223,6 +224,8 @@ var/list/global/tank_gauge_cache = list() if (src.proxyassembly.assembly) src.proxyassembly.assembly.attack_self(user) +/obj/item/weapon/tank/tgui_state(mob/user) + return GLOB.tgui_deep_inventory_state /obj/item/weapon/tank/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index b24f24d2fe..b821158c09 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -4,7 +4,8 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "taperoll" w_class = ITEMSIZE_TINY - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' toolspeed = 2 //It is now used in surgery as a not awful, but probably dangerous option, due to speed. diff --git a/code/game/objects/items/weapons/tools/combitool.dm b/code/game/objects/items/weapons/tools/combitool.dm index 43bb2794fe..573ff96128 100644 --- a/code/game/objects/items/weapons/tools/combitool.dm +++ b/code/game/objects/items/weapons/tools/combitool.dm @@ -10,6 +10,8 @@ icon = 'icons/obj/items.dmi' icon_state = "combitool" w_class = ITEMSIZE_SMALL + drop_sound = 'sound/items/drop/multitool.ogg' + pickup_sound = 'sound/items/pickup/multitool.ogg' var/list/spawn_tools = list( /obj/item/weapon/tool/screwdriver, diff --git a/code/game/objects/items/weapons/tools/crowbar.dm b/code/game/objects/items/weapons/tools/crowbar.dm index 09d2aeb5f3..f1ff2dd642 100644 --- a/code/game/objects/items/weapons/tools/crowbar.dm +++ b/code/game/objects/items/weapons/tools/crowbar.dm @@ -17,7 +17,8 @@ matter = list(DEFAULT_WALL_MATERIAL = 50) attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") usesound = 'sound/items/crowbar.ogg' - drop_sound = 'sound/items/drop/sword.ogg' + drop_sound = 'sound/items/drop/crowbar.ogg' + pickup_sound = 'sound/items/pickup/crowbar.ogg' toolspeed = 1 /obj/item/weapon/tool/crowbar/is_crowbar() diff --git a/code/game/objects/items/weapons/tools/screwdriver.dm b/code/game/objects/items/weapons/tools/screwdriver.dm index aea17ebf2b..6ea222b6ac 100644 --- a/code/game/objects/items/weapons/tools/screwdriver.dm +++ b/code/game/objects/items/weapons/tools/screwdriver.dm @@ -15,7 +15,8 @@ throw_range = 5 hitsound = 'sound/weapons/bladeslice.ogg' usesound = 'sound/items/screwdriver.ogg' - drop_sound = 'sound/items/drop/scrap.ogg' + drop_sound = 'sound/items/drop/screwdriver.ogg' + pickup_sound = 'sound/items/pickup/screwdriver.ogg' matter = list(DEFAULT_WALL_MATERIAL = 75) attack_verb = list("stabbed") sharp = 1 diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm index 291b00f683..52bd1e330a 100644 --- a/code/game/objects/items/weapons/tools/weldingtool.dm +++ b/code/game/objects/items/weapons/tools/weldingtool.dm @@ -37,7 +37,8 @@ var/burned_fuel_for = 0 // Keeps track of how long the welder's been on, used to gradually empty the welder if left one, without RNG. var/always_process = FALSE // If true, keeps the welder on the process list even if it's off. Used for when it needs to regenerate fuel. toolspeed = 1 - drop_sound = 'sound/items/drop/scrap.ogg' + drop_sound = 'sound/items/drop/weldingtool.ogg' + pickup_sound = 'sound/items/pickup/weldingtool.ogg' /obj/item/weapon/weldingtool/Initialize() . = ..() diff --git a/code/game/objects/items/weapons/tools/wirecutters.dm b/code/game/objects/items/weapons/tools/wirecutters.dm index 3b8c83c1f9..1ef130e13f 100644 --- a/code/game/objects/items/weapons/tools/wirecutters.dm +++ b/code/game/objects/items/weapons/tools/wirecutters.dm @@ -17,7 +17,8 @@ attack_verb = list("pinched", "nipped") hitsound = 'sound/items/wirecutter.ogg' usesound = 'sound/items/wirecutter.ogg' - drop_sound = 'sound/items/drop/knife.ogg' + drop_sound = 'sound/items/drop/wirecutter.ogg' + pickup_sound = 'sound/items/pickup/wirecutter.ogg' sharp = 1 edge = 1 toolspeed = 1 diff --git a/code/game/objects/items/weapons/tools/wrench.dm b/code/game/objects/items/weapons/tools/wrench.dm index d96a244282..300a3c8c6b 100644 --- a/code/game/objects/items/weapons/tools/wrench.dm +++ b/code/game/objects/items/weapons/tools/wrench.dm @@ -15,7 +15,8 @@ attack_verb = list("bashed", "battered", "bludgeoned", "whacked") usesound = 'sound/items/ratchet.ogg' toolspeed = 1 - drop_sound = 'sound/items/drop/sword.ogg' + drop_sound = 'sound/items/drop/wrench.ogg' + pickup_sound = 'sound/items/pickup/wrench.ogg' /obj/item/weapon/tool/wrench/is_wrench() return TRUE diff --git a/code/game/objects/items/weapons/towels.dm b/code/game/objects/items/weapons/towels.dm index 232a321202..2b41ce5163 100644 --- a/code/game/objects/items/weapons/towels.dm +++ b/code/game/objects/items/weapons/towels.dm @@ -8,7 +8,8 @@ attack_verb = list("whipped") hitsound = 'sound/weapons/towelwhip.ogg' desc = "A soft cotton towel." - drop_sound = 'sound/items/drop/clothing.ogg' + drop_sound = 'sound/items/drop/cloth.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' /obj/item/weapon/towel/equipped(var/M, var/slot) ..() diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 82e6ff7699..98332cca42 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -10,6 +10,7 @@ throwforce = 10 w_class = ITEMSIZE_SMALL drop_sound = 'sound/items/drop/sword.ogg' + pickup_sound = 'sound/items/pickup/sword.ogg' suicide_act(mob/user) var/datum/gender/T = gender_datums[user.get_visible_gender()] diff --git a/code/game/objects/items/weapons/weldbackpack.dm b/code/game/objects/items/weapons/weldbackpack.dm index e839bba3b3..bdabfaf826 100644 --- a/code/game/objects/items/weapons/weldbackpack.dm +++ b/code/game/objects/items/weapons/weldbackpack.dm @@ -10,6 +10,7 @@ var/nozzle_type = /obj/item/weapon/weldingtool/tubefed var/nozzle_attached = 0 drop_sound = 'sound/items/drop/backpack.ogg' + pickup_sound = 'sound/items/pickup/backpack.ogg' /obj/item/weapon/weldpack/Initialize() . = ..() diff --git a/code/game/objects/random/maintenance.dm b/code/game/objects/random/maintenance.dm index 155a9abad0..736318e6f1 100644 --- a/code/game/objects/random/maintenance.dm +++ b/code/game/objects/random/maintenance.dm @@ -65,8 +65,8 @@ something, make sure it's not in one of the other lists.*/ prob(1);/obj/item/clothing/shoes/syndigaloshes, prob(4);/obj/item/clothing/shoes/black, prob(4);/obj/item/clothing/shoes/laceup, - prob(4);/obj/item/clothing/shoes/black, - prob(4);/obj/item/clothing/shoes/leather, + prob(4);/obj/item/clothing/shoes/laceup/grey, + prob(4);/obj/item/clothing/shoes/laceup/brown, prob(1);/obj/item/clothing/gloves/yellow, prob(3);/obj/item/clothing/gloves/botanic_leather, prob(2);/obj/item/clothing/gloves/sterile/latex, diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 4180b78ec3..fc136cfda8 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -16,7 +16,8 @@ LINEN BINS throw_speed = 1 throw_range = 2 w_class = ITEMSIZE_SMALL - drop_sound = 'sound/items/drop/clothing.ogg' + drop_sound = 'sound/items/drop/cloth.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' /obj/item/weapon/bedsheet/attack_self(mob/user as mob) user.drop_item() diff --git a/code/game/objects/structures/crates_lockers/closets/misc_vr.dm b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm index 251183b6e9..2ee0c7915e 100644 --- a/code/game/objects/structures/crates_lockers/closets/misc_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm @@ -44,6 +44,7 @@ /obj/item/clothing/under/explorer, /obj/item/clothing/suit/storage/hooded/explorer, /obj/item/clothing/mask/gas/explorer, + /obj/item/weapon/storage/belt/explorer, /obj/item/clothing/shoes/boots/winter/explorer, /obj/item/clothing/gloves/black, /obj/item/device/radio/headset/explorer, @@ -159,6 +160,7 @@ /obj/item/clothing/under/explorer, /obj/item/clothing/suit/storage/hooded/explorer, /obj/item/clothing/mask/gas/explorer, + /obj/item/weapon/storage/belt/explorer/pathfinder, /obj/item/clothing/shoes/boots/winter/explorer, /obj/item/clothing/gloves/black, /obj/item/device/radio/headset/pathfinder, diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index 1592445e3e..66383849f0 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -35,7 +35,7 @@ /obj/item/clothing/suit/storage/toggle/labcoat, /obj/item/weapon/cartridge/rd, /obj/item/clothing/shoes/white, - /obj/item/clothing/shoes/leather, + /obj/item/clothing/shoes/laceup/brown, /obj/item/clothing/gloves/sterile/latex, /obj/item/device/radio/headset/heads/rd, /obj/item/device/radio/headset/heads/rd/alt, 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 d7ebefccbf..99f83f49c4 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -1,5 +1,5 @@ /obj/structure/closet/secure_closet/captains - name = "colony director's locker" + name = "site manager's locker" req_access = list(access_captain) closet_appearance = /decl/closet_appearance/secure_closet/command @@ -53,7 +53,8 @@ /obj/item/clothing/under/lawyer/oldman, /obj/item/clothing/shoes/brown, /obj/item/clothing/shoes/black, - /obj/item/clothing/shoes/leather, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/shoes/laceup/brown, /obj/item/clothing/shoes/white, /obj/item/clothing/under/rank/head_of_personnel_whimsy, /obj/item/clothing/head/caphat/hop, diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 609a657ca7..3fb12883d7 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -361,7 +361,7 @@ /obj/item/clothing/shoes/green, /obj/item/clothing/shoes/purple, /obj/item/clothing/shoes/red, - /obj/item/clothing/shoes/leather, + /obj/item/clothing/shoes/laceup/brown, /obj/item/clothing/under/pants/classicjeans, /obj/item/clothing/under/pants/mustangjeans, /obj/item/clothing/under/pants/blackjeans, @@ -451,7 +451,7 @@ /obj/item/weapon/storage/backpack/satchel = 2) /obj/structure/closet/wardrobe/captain - name = "colony director's wardrobe" + name = "site manager's wardrobe" closet_appearance = /decl/closet_appearance/cabinet starts_with = list( diff --git a/code/game/objects/structures/crates_lockers/largecrate_vr.dm b/code/game/objects/structures/crates_lockers/largecrate_vr.dm index 6886a08a3c..3dd37e863b 100644 --- a/code/game/objects/structures/crates_lockers/largecrate_vr.dm +++ b/code/game/objects/structures/crates_lockers/largecrate_vr.dm @@ -53,6 +53,7 @@ /mob/living/simple_mob/vore/aggressive/mimic, /mob/living/simple_mob/vore/aggressive/rat, /mob/living/simple_mob/vore/aggressive/rat/tame, + /mob/living/simple_mob/vore/rabbit, // /mob/living/simple_mob/otie;0.5 )) return ..() diff --git a/code/game/objects/structures/flora/flora.dm b/code/game/objects/structures/flora/flora.dm index a0f2c8c307..b4bad46142 100644 --- a/code/game/objects/structures/flora/flora.dm +++ b/code/game/objects/structures/flora/flora.dm @@ -233,6 +233,9 @@ . += "You can see something in there..." /obj/structure/flora/pottedplant/attackby(obj/item/I, mob/user) + if(issilicon(user)) + return // Don't try to put modules in here, you're a borg. TODO: Inventory refactor to not be ass. + if(stored_item) to_chat(user, "[I] won't fit in. There already appears to be something in here...") return diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index ac43fa112c..57c9832fde 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -156,8 +156,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/clothing/shoes/galoshes, /obj/item/clothing/shoes/black, /obj/item/clothing/shoes/laceup, - /obj/item/clothing/shoes/black, - /obj/item/clothing/shoes/leather, + /obj/item/clothing/shoes/laceup/grey, + /obj/item/clothing/shoes/laceup/brown, /obj/item/clothing/gloves/botanic_leather, /obj/item/clothing/gloves/sterile/latex, /obj/item/clothing/gloves/white, diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 9511b3625b..0007bdb9d6 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -236,6 +236,8 @@ w_class = ITEMSIZE_LARGE var/rollertype = /obj/item/roller var/bedtype = /obj/structure/bed/roller + drop_sound = 'sound/items/drop/axe.ogg' + pickup_sound = 'sound/items/pickup/axe.ogg' /obj/item/roller/attack_self(mob/user) var/obj/structure/bed/roller/R = new bedtype(user.loc) diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm index 3b9ffe24eb..8d2126c289 100644 --- a/code/game/objects/structures/trash_pile_vr.dm +++ b/code/game/objects/structures/trash_pile_vr.dm @@ -138,7 +138,7 @@ prob(4);/obj/item/clothing/shoes/black, prob(4);/obj/item/clothing/shoes/black, prob(4);/obj/item/clothing/shoes/laceup, - prob(4);/obj/item/clothing/shoes/leather, + prob(4);/obj/item/clothing/shoes/laceup/brown, prob(4);/obj/item/clothing/suit/storage/hazardvest, prob(4);/obj/item/clothing/under/color/grey, prob(4);/obj/item/clothing/suit/caution, diff --git a/code/game/sound.dm b/code/game/sound.dm index 903534547d..eabbca5c84 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -262,6 +262,10 @@ soundin = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', \ 'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', \ 'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg') + if("smcalm") + soundin = pick('sound/machines/sm/accent/normal/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg', 'sound/machines/sm/supermatter1.ogg', 'sound/machines/sm/supermatter2.ogg', 'sound/machines/sm/supermatter3.ogg') + if("smdelam") + soundin = pick('sound/machines/sm/accent/delam/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg', 'sound/machines/sm/supermatter1.ogg', 'sound/machines/sm/supermatter2.ogg', 'sound/machines/sm/supermatter3.ogg') return soundin //Are these even used? diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm index 7f67f9e8f5..5185a0e253 100644 --- a/code/game/turfs/flooring/flooring_premade.dm +++ b/code/game/turfs/flooring/flooring_premade.dm @@ -247,7 +247,7 @@ /turf/simulated/floor/reinforced/n20/Initialize() . = ..() if(!air) make_air() - air.adjust_gas("sleeping_agent", ATMOSTANK_NITROUSOXIDE) + air.adjust_gas("nitrous_oxide", ATMOSTANK_NITROUSOXIDE) /turf/simulated/floor/cult name = "engraved floor" diff --git a/code/game/world.dm b/code/game/world.dm index 931e0fe516..5c5eaff9e5 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -45,9 +45,6 @@ log_unit_test("If you did not intend to enable this please check code/__defines/unit_testing.dm") #endif - // Set up roundstart seed list. - plant_controller = new() - // This is kinda important. Set up details of what the hell things are made of. populate_material_list() diff --git a/code/global.dm b/code/global.dm index 88028f4b02..e3e3831809 100644 --- a/code/global.dm +++ b/code/global.dm @@ -157,7 +157,7 @@ var/static/list/scarySounds = list( 'sound/effects/Glassbr3.ogg', 'sound/items/Welder.ogg', 'sound/items/Welder2.ogg', - 'sound/machines/airlock.ogg', + 'sound/machines/door/old_airlock.ogg', 'sound/effects/clownstep1.ogg', 'sound/effects/clownstep2.ogg' ) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index c0bcd0f101..11a140a91b 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1082,18 +1082,18 @@ var/datum/announcement/minor/admin_min_announcer = new return 0 -/datum/admins/proc/spawn_fruit(seedtype in plant_controller.seeds) +/datum/admins/proc/spawn_fruit(seedtype in SSplants.seeds) set category = "Debug" set desc = "Spawn the product of a seed." set name = "Spawn Fruit" if(!check_rights(R_SPAWN)) return - if(!seedtype || !plant_controller.seeds[seedtype]) + if(!seedtype || !SSplants.seeds[seedtype]) return var/amount = input("Amount of fruit to spawn", "Fruit Amount", 1) as null|num if(!isnull(amount)) - var/datum/seed/S = plant_controller.seeds[seedtype] + var/datum/seed/S = SSplants.seeds[seedtype] S.harvest(usr,0,0,amount) log_admin("[key_name(usr)] spawned [seedtype] fruit at ([usr.x],[usr.y],[usr.z])") @@ -1137,16 +1137,16 @@ var/datum/announcement/minor/admin_min_announcer = new for(var/datum/custom_item/item in current_items) to_chat(usr, "- name: [item.name] icon: [item.item_icon] path: [item.item_path] desc: [item.item_desc]") -/datum/admins/proc/spawn_plant(seedtype in plant_controller.seeds) +/datum/admins/proc/spawn_plant(seedtype in SSplants.seeds) set category = "Debug" set desc = "Spawn a spreading plant effect." set name = "Spawn Plant" if(!check_rights(R_SPAWN)) return - if(!seedtype || !plant_controller.seeds[seedtype]) + if(!seedtype || !SSplants.seeds[seedtype]) return - new /obj/effect/plant(get_turf(usr), plant_controller.seeds[seedtype]) + new /obj/effect/plant(get_turf(usr), SSplants.seeds[seedtype]) log_admin("[key_name(usr)] spawned [seedtype] vines at ([usr.x],[usr.y],[usr.z])") /datum/admins/proc/spawn_atom(var/object as text) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 881eb95abb..6635b07061 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -421,8 +421,8 @@ var/mob/living/silicon/S = input("Select silicon.", "Manage Silicon Laws") as null|anything in silicon_mob_list if(!S) return - var/datum/nano_module/law_manager/L = new(S) - L.ui_interact(usr, state = admin_state) + var/datum/tgui_module/law_manager/admin/L = new(S) + L.tgui_interact(usr) log_and_message_admins("has opened [S]'s law manager.") feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/newbanjob.dm b/code/modules/admin/newbanjob.dm index b97e354301..49d9e464b9 100644 --- a/code/modules/admin/newbanjob.dm +++ b/code/modules/admin/newbanjob.dm @@ -63,7 +63,7 @@ var/savefile/Banlistjob bantimestamp = CMinutes + minutes if(rank == "Heads") AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Head of Personnel") - AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Colony Director") + AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Site Manager") AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Head of Security") AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Engineer") AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Research Director") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 99146571f7..25dad06f46 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -288,7 +288,7 @@ id.icon_state = "gold" id.access = get_all_accesses().Copy() id.registered_name = H.real_name - id.assignment = "Colony Director" + id.assignment = "Site Manager" id.name = "[id.registered_name]'s ID Card ([id.assignment])" H.equip_to_slot_or_del(id, slot_wear_id) H.update_inv_wear_id() diff --git a/code/modules/admin/verbs/debug_vr.dm b/code/modules/admin/verbs/debug_vr.dm index eb8cd37e01..30e48dd81e 100644 --- a/code/modules/admin/verbs/debug_vr.dm +++ b/code/modules/admin/verbs/debug_vr.dm @@ -2,6 +2,8 @@ set category = "Fun" set name = "Quick NIF" set desc = "Spawns a NIF into someone in quick-implant mode." + + var/input_NIF if(!check_rights(R_ADMIN)) return @@ -24,9 +26,27 @@ return if(H.species.flags & NO_SCAN) + var/obj/item/device/nif/S = /obj/item/device/nif/bioadap + input_NIF = initial(S.name) new /obj/item/device/nif/bioadap(H) else - new /obj/item/device/nif(H) + var/list/NIF_types = typesof(/obj/item/device/nif) + var/list/NIFs = list() + + for(var/NIF_type in NIF_types) + var/obj/item/device/nif/S = NIF_type + NIFs[capitalize(initial(S.name))] = NIF_type + + var/list/show_NIFs = sortList(NIFs) // the list that will be shown to the user to pick from + + input_NIF = input("Pick the NIF type","Quick NIF") in show_NIFs + var/chosen_NIF = NIFs[capitalize(input_NIF)] + + if(chosen_NIF) + new chosen_NIF(H) + else + new /obj/item/device/nif(H) + + log_and_message_admins("[key_name(src)] Quick NIF'd [H.real_name] with a [input_NIF].") + feedback_add_details("admin_verb","QNIF") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - log_and_message_admins("[key_name(src)] Quick NIF'd [H.real_name].") - feedback_add_details("admin_verb","QNIF") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/ai/say_list.dm b/code/modules/ai/say_list.dm index 9eba02b9b1..313913ac73 100644 --- a/code/modules/ai/say_list.dm +++ b/code/modules/ai/say_list.dm @@ -71,6 +71,9 @@ say_threaten = list("Get out of here!", "Hey! Private Property!") say_stand_down = list("Good.") say_escalate = list("Your funeral!", "Bring it!") + + threaten_sound = 'sound/weapons/TargetOn.ogg' + stand_down_sound = 'sound/weapons/TargetOff.ogg' /datum/say_list/malf_drone speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.") diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 8d28288afb..8cb1f9c0e5 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -8,6 +8,8 @@ throwforce = 2 throw_speed = 3 throw_range = 10 + drop_sound = 'sound/items/drop/component.ogg' + pickup_sound = 'sound/items/pickup/component.ogg' origin_tech = list(TECH_MAGNET = 1) var/secured = 1 @@ -88,15 +90,19 @@ . += "\The [src] can be attached!" /obj/item/device/assembly/attack_self(mob/user as mob) - if(!user) return 0 + if(!user) + return 0 user.set_machine(src) - interact(user) + tgui_interact(user) return 1 -/obj/item/device/assembly/interact(mob/user as mob) - return //HTML MENU FOR WIRES GOES HERE +/obj/item/device/assembly/tgui_state(mob/user) + return GLOB.tgui_deep_inventory_state -/obj/item/device/assembly/nano_host() - if(istype(loc, /obj/item/device/assembly_holder)) - return loc.nano_host() - return ..() +/obj/item/device/assembly/tgui_interact(mob/user, datum/tgui/ui) + return // tgui goes here + +/obj/item/device/assembly/tgui_host() + if(istype(loc, /obj/item/device/assembly_holder)) + return loc.tgui_host() + return ..() diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index b34b2c0c11..853f2f230b 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -100,41 +100,38 @@ if(!holder) visible_message("[bicon(src)] *beep* *beep*") -/obj/item/device/assembly/infra/interact(mob/user as mob)//TODO: change this this to the wire control panel +/obj/item/device/assembly/infra/tgui_interact(mob/user, datum/tgui/ui) if(!secured) - return - user.set_machine(src) - var/dat = text("Infrared Laser\nStatus: []
\nVisibility: []
\n
", (on ? text("On", src) : text("Off", src)), (src.visible ? text("Visible", src) : text("Invisible", src))) - dat += "

Refresh" - dat += "

Close" - user << browse(dat, "window=infra") - onclose(user, "infra") + to_chat(user, "[src] is unsecured!") + return FALSE + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AssemblyInfrared", name) + ui.open() -/obj/item/device/assembly/infra/Topic(href, href_list, state = deep_inventory_state) +/obj/item/device/assembly/infra/tgui_data(mob/user) + var/list/data = ..() + + data["on"] = on + data["visible"] = visible + + return data + +/obj/item/device/assembly/infra/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 - - if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=infra") - onclose(usr, "infra") - return + return TRUE - if(href_list["state"]) - toggle_state() - - if(href_list["visible"]) - visible = !(visible) - for(var/ibeam in i_beams) - var/obj/effect/beam/i_beam/I = ibeam - I.visible = visible - CHECK_TICK - - if(href_list["close"]) - usr << browse(null, "window=infra") - return - - if(usr) - attack_self(usr) + switch(action) + if("state") + toggle_state() + return TRUE + if("visible") + visible = !visible + for(var/ibeam in i_beams) + var/obj/effect/beam/i_beam/I = ibeam + I.visible = visible + CHECK_TICK + return TRUE /obj/item/device/assembly/infra/verb/rotate_clockwise() set name = "Rotate Infrared Laser Clockwise" diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index f7d8e3e59e..b292d3f753 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -95,49 +95,49 @@ sense_proximity(range = range, callback = .HasProximity) sense() -/obj/item/device/assembly/prox_sensor/interact(mob/user as mob)//TODO: Change this to the wires thingy +/obj/item/device/assembly/prox_sensor/tgui_interact(mob/user, datum/tgui/ui) if(!secured) - user.show_message("The [name] is unsecured!") - return 0 - var/second = time % 60 - var/minute = (time - second) / 60 - var/dat = text("Proximity Sensor\n[] []:[]\n- - + +\n", (timing ? text("Arming", src) : text("Not Arming", src)), minute, second, src, src, src, src) - dat += text("
Range: - [] +", src, range, src) - dat += "
[scanning?"Armed":"Unarmed"] (Movement sensor active when armed!)" - dat += "

Refresh" - dat += "

Close" - user << browse(dat, "window=prox") - onclose(user, "prox") + to_chat(user, "[src] is unsecured!") + return FALSE + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AssemblyProx", name) + ui.open() -/obj/item/device/assembly/prox_sensor/Topic(href, href_list, state = deep_inventory_state) +/obj/item/device/assembly/prox_sensor/tgui_data(mob/user) + var/list/data = ..() + + data["time"] = time * 10 + data["timing"] = timing + data["range"] = range + data["maxRange"] = 5 + data["scanning"] = scanning + + return data + +/obj/item/device/assembly/prox_sensor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return TRUE - - if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=prox") - onclose(usr, "prox") - return - if(href_list["scanning"]) - toggle_scan() - - if(href_list["time"]) - timing = text2num(href_list["time"]) - update_icon() - - if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 0), 600) - - if(href_list["range"]) - var/r = text2num(href_list["range"]) - range += r - range = min(max(range, 1), 5) - - if(href_list["close"]) - usr << browse(null, "window=prox") - return - - if(usr) - attack_self(usr) + switch(action) + if("scanning") + toggle_scan() + return TRUE + if("timing") + timing = !timing + update_icon() + return TRUE + if("set_time") + var/real_new_time = 0 + var/new_time = params["time"] + var/list/L = splittext(new_time, ":") + if(LAZYLEN(L)) + for(var/i in 1 to LAZYLEN(L)) + real_new_time += text2num(L[i]) * (60 ** (LAZYLEN(L) - i)) + else + real_new_time = text2num(new_time) + time = clamp(real_new_time, 0, 600) + return TRUE + if("range") + range = clamp(params["range"], 1, 5) + return TRUE diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index cf32d9ad4d..e98ff5372c 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -31,14 +31,6 @@ if(holder) holder.update_icon() -/obj/item/device/assembly/signaler/interact(mob/user) - if(..()) - return TRUE - tgui_interact(user) - -/obj/item/device/assembly/signaler/tgui_state(mob/user) - return GLOB.tgui_deep_inventory_state - /obj/item/device/assembly/signaler/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 1bc653662b..fa8b783815 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -62,43 +62,38 @@ holder.update_icon() return - -/obj/item/device/assembly/timer/interact(mob/user as mob)//TODO: Have this use the wires +/obj/item/device/assembly/timer/tgui_interact(mob/user, datum/tgui/ui) if(!secured) - user.show_message("The [name] is unsecured!") - return 0 - var/second = time % 60 - var/minute = (time - second) / 60 - var/dat = text("Timing Unit\n[] []:[]\n- - + +\n", (timing ? text("Timing", src) : text("Not Timing", src)), minute, second, src, src, src, src) - dat += "

Refresh" - dat += "

Close" - user << browse(dat, "window=timer") - onclose(user, "timer") - return + to_chat(user, "[src] is unsecured!") + return FALSE + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AssemblyTimer", name) + ui.open() +/obj/item/device/assembly/timer/tgui_data(mob/user) + var/list/data = ..() + data["time"] = time * 10 + data["timing"] = timing + return data -/obj/item/device/assembly/timer/Topic(href, href_list, state = deep_inventory_state) - if(..()) return 1 - if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=timer") - onclose(usr, "timer") - return +/obj/item/device/assembly/timer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - if(href_list["time"]) - var/new_timing = text2num(href_list["time"]) - set_state(new_timing) - update_icon() - - if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 0), 600) - - if(href_list["close"]) - usr << browse(null, "window=timer") - return - - if(usr) - attack_self(usr) - - return + switch(action) + if("timing") + timing = !timing + update_icon() + return TRUE + if("set_time") + var/real_new_time = 0 + var/new_time = params["time"] + var/list/L = splittext(new_time, ":") + if(LAZYLEN(L)) + for(var/i in 1 to LAZYLEN(L)) + real_new_time += text2num(L[i]) * (60 ** (LAZYLEN(L) - i)) + else + real_new_time = text2num(new_time) + time = clamp(real_new_time, 0, 600) + return TRUE diff --git a/code/modules/asset_cache/asset_cache_client.dm b/code/modules/asset_cache/asset_cache_client.dm index 0f51520f13..e25b996986 100644 --- a/code/modules/asset_cache/asset_cache_client.dm +++ b/code/modules/asset_cache/asset_cache_client.dm @@ -17,6 +17,10 @@ CRASH("invalid asset_cache_preload_data, no jsonendmarker")*/ //var/json = html_decode(copytext(data, 1, jsonend)) var/json = data + + // This is a stupid workaround to BYOND injecting this pngfix mess into IE7 clients browse() + json = replacetext(json, "", "") + var/list/preloaded_assets = json_decode(json) for (var/preloaded_asset in preloaded_assets) diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 64b76184e5..ce71815526 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -285,6 +285,17 @@ InsertAll("", each, global.alldirs) ..() +//VOREStation Add +/datum/asset/spritesheet/vore + name = "vore" + +/datum/asset/spritesheet/vore/register() + var/icon/downscaled = icon('icons/mob/screen_full_vore.dmi') + downscaled.Scale(240, 240) + InsertAll("", downscaled) + ..() +//VOREStation Add End + // // Representative icons for each research design // /datum/asset/spritesheet/research_designs // name = "design" @@ -487,4 +498,11 @@ assets["synthprinter_working.gif"] = icon('icons/obj/machines/synthpod.dmi', "pod_1") for(var/asset_name in assets) register_asset(asset_name, assets[asset_name]) -// VOREStation Add End \ No newline at end of file +// VOREStation Add End + +/datum/asset/spritesheet/sheetmaterials + name = "sheetmaterials" + +/datum/asset/spritesheet/sheetmaterials/register() + InsertAll("", 'icons/obj/stacks.dmi') + ..() \ No newline at end of file diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index fc1c0a52f9..b8a4232196 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -22,7 +22,7 @@ S["tooltipstyle"] << pref.tooltipstyle S["client_fps"] << pref.client_fps S["ambience_freq"] << pref.ambience_freq - S["ambience_chance"] << pref.ambience_freq + S["ambience_chance"] << pref.ambience_chance S["tgui_fancy"] << pref.tgui_fancy S["tgui_lock"] << pref.tgui_lock diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm index f69d04aa72..24cca9ca18 100644 --- a/code/modules/client/preference_setup/global/setting_datums.dm +++ b/code/modules/client/preference_setup/global/setting_datums.dm @@ -152,6 +152,24 @@ var/list/_client_preferences_by_type key = "SOUND_AIRPUMP" enabled_description = "Audible" disabled_description = "Silent" + +/datum/client_preference/old_door_sounds + description ="Old Door Sounds" + key = "SOUND_OLDDOORS" + enabled_description = "Old" + disabled_description = "New" + +/datum/client_preference/department_door_sounds + description ="Department-Specific Door Sounds" + key = "SOUND_DEPARTMENTDOORS" + enabled_description = "Enabled" + disabled_description = "Disabled" + +/datum/client_preference/pickup_sounds + description = "Picked Up Item Sounds" + key = "SOUND_PICKED" + enabled_description = "Enabled" + disabled_description = "Disabled" /datum/client_preference/drop_sounds description = "Dropped Item Sounds" diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm index f0c28f78b1..b370e5eebf 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm @@ -79,7 +79,7 @@ /datum/gear/accessory/holster display_name = "holster selection (Security, CD, HoP)" path = /obj/item/clothing/accessory/holster - allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective","Blueshield Guard","Security Pilot") //YW ADDITIONS + allowed_roles = list("Site Manager", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective", "Blueshield Guard","Security Pilot") //YW ADDITIONS /datum/gear/accessory/holster/New() ..() diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm index 2eb3d1fcd6..5d0ede01c0 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm @@ -50,8 +50,8 @@ path = /obj/item/clothing/accessory/collar/holo/indigestible /datum/gear/accessory/holster - display_name = "holster selection (Security, CD, HoP, Exploration)" - allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective","Explorer","Pathfinder", "Blueshield Guard","Security Pilot") //YW ADDITIONS + display_name = "holster selection (Security, SM, HoP, Exploration)" + allowed_roles = list("Site Manager", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective","Explorer","Pathfinder", "Blueshield Guard","Security Pilot") //YW ADDITIONS /datum/gear/accessory/brown_vest display_name = "webbing, brown (Eng, Sec, Med, Exploration, Miner)" diff --git a/code/modules/client/preference_setup/loadout/loadout_eyes.dm b/code/modules/client/preference_setup/loadout/loadout_eyes.dm index db4843c57f..0eedcd593d 100644 --- a/code/modules/client/preference_setup/loadout/loadout_eyes.dm +++ b/code/modules/client/preference_setup/loadout/loadout_eyes.dm @@ -108,7 +108,7 @@ /datum/gear/eyes/sun display_name = "Sunglasses (Security/Command)" path = /obj/item/clothing/glasses/sunglasses - allowed_roles = list("Security Officer","Head of Security","Warden","Colony Director","Head of Personnel","Quartermaster","Internal Affairs Agent","Detective","Blueshield Guard","Security Pilot") //YW ADDITIONS + allowed_roles = list("Security Officer","Head of Security","Warden","Site Manager","Head of Personnel","Quartermaster","Internal Affairs Agent","Detective", "Blueshield Guard","Security Pilot") //YW ADDITIONS /datum/gear/eyes/sun/shades display_name = "Sunglasses, fat (Security/Command)" diff --git a/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm b/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm index 276554554f..ade7584a33 100644 --- a/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm @@ -18,6 +18,11 @@ path = /obj/item/clothing/glasses/omnihud/sec allowed_roles = list("Security Officer","Head of Security","Warden","Detective") +/datum/gear/eyes/arglasses/sci + display_name = "AR-R glasses (Sci)" + path = /obj/item/clothing/glasses/omnihud/rnd + allowed_roles = list("Research Director","Scientist","Xenobiologist","Xenobotanist","Roboticist") + /datum/gear/eyes/arglasses/eng display_name = "AR-E glasses (Eng)" path = /obj/item/clothing/glasses/omnihud/eng @@ -29,10 +34,10 @@ allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist", "Field Medic") /datum/gear/eyes/arglasses/all - display_name = "AR-B glasses (CD, HoP)" + display_name = "AR-B glasses (SM, HoP)" path = /obj/item/clothing/glasses/omnihud/all cost = 2 - allowed_roles = list("Colony Director","Head of Personnel") + allowed_roles = list("Site Manager","Head of Personnel") /datum/gear/eyes/spiffygogs display_name = "slick orange goggles" @@ -42,6 +47,10 @@ display_name = "science goggles (no overlay)" path = /obj/item/clothing/glasses/fluff/science_proper +/datum/gear/eyes/meson/retinal + display_name = "retinal projector, meson (Eng, Sci, Mining)" + path = /obj/item/clothing/glasses/omnihud/eng/meson + /datum/gear/eyes/security/secpatch display_name = "Security HUDpatch" path = /obj/item/clothing/glasses/hud/security/eyepatch diff --git a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm index 6cbe17bce3..a01f2ff64a 100644 --- a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm @@ -411,7 +411,7 @@ display_name = "Ace's Holster" ckeywhitelist = list("jertheace") character_name = list("Jeremiah Acacius") - allowed_roles = list("Colony Director", "Warden", "Head of Security") + allowed_roles = list("Site Manager", "Warden", "Head of Security") /datum/gear/fluff/jeremiah_boots path = /obj/item/clothing/shoes/boots/combat @@ -439,7 +439,7 @@ display_name = "Katarina's Backpack" ckeywhitelist = list("joanrisu") character_name = list("Katarina Eine") - allowed_roles = list("Colony Director", "Warden", "Head of Security") + allowed_roles = list("Site Manager", "Warden", "Head of Security") /datum/gear/fluff/emoticon_box path = /obj/item/weapon/storage/box/fluff/emoticon @@ -759,7 +759,7 @@ slot = slot_wear_suit ckeywhitelist = list("samanthafyre") character_name = list("Kateryna Petrovitch") - allowed_roles = list("Security Officer", "Warden", "Head of Security", "Colony Director", "Head of Personnel") + allowed_roles = list("Security Officer", "Warden", "Head of Security", "Site Manager", "Head of Personnel") /datum/gear/fluff/viktor_flask path = /obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask/fluff/viktor @@ -792,14 +792,14 @@ display_name = "NT-HASD 556's Modkit" ckeywhitelist = list("silencedmp5a5") character_name = list("NT-HASD #556") - allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective") + allowed_roles = list("Site Manager", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective") /datum/gear/fluff/serdykov_modkit //Also converts a Security suit's sprite path = /obj/item/device/modkit_conversion/fluff/serdykit display_name = "Serdykov Antoz's Modkit" ckeywhitelist = list("silencedmp5a5") character_name = list("Serdykov Antoz") - allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective") + allowed_roles = list("Site Manager", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective") /datum/gear/fluff/tasy_clownuniform path = /obj/item/clothing/under/sexyclown diff --git a/code/modules/client/preference_setup/loadout/loadout_shoes.dm b/code/modules/client/preference_setup/loadout/loadout_shoes.dm index 72c6cc7a97..4325952405 100644 --- a/code/modules/client/preference_setup/loadout/loadout_shoes.dm +++ b/code/modules/client/preference_setup/loadout/loadout_shoes.dm @@ -1,13 +1,21 @@ // Shoelocker /datum/gear/shoes - display_name = "jackboots" - path = /obj/item/clothing/shoes/boots/jackboots + display_name = "sandals" + path = /obj/item/clothing/shoes/sandal slot = slot_shoes sort_category = "Shoes and Footwear" -/datum/gear/shoes/toeless - display_name = "toe-less jackboots" - path = /obj/item/clothing/shoes/boots/jackboots/toeless +/datum/gear/shoes/jackboots + display_name = "jackboots" + path = /obj/item/clothing/shoes/boots/jackboots + +/datum/gear/shoes/kneeboots + display_name = "jackboots, knee-length" + path = /obj/item/clothing/shoes/boots/jackboots/knee + +/datum/gear/shoes/thighboots + display_name = "jackboots. thigh-length" + path = /obj/item/clothing/shoes/boots/jackboots/thigh /datum/gear/shoes/workboots display_name = "workboots" @@ -17,10 +25,6 @@ display_name = "toe-less workboots" path = /obj/item/clothing/shoes/boots/workboots/toeless -/datum/gear/shoes/sandals - display_name = "sandals" - path = /obj/item/clothing/shoes/sandal - /datum/gear/shoes/black display_name = "shoes, black" path = /obj/item/clothing/shoes/black @@ -34,21 +38,21 @@ path = /obj/item/clothing/shoes/brown /datum/gear/shoes/lacey - display_name = "shoes, classy" + display_name = "shoes, oxford selection" path = /obj/item/clothing/shoes/laceup -/datum/gear/shoes/dress - display_name = "shoes, dress" - path = /obj/item/clothing/shoes/laceup +/datum/gear/shoes/lacey/New() + ..() + var/list/laces = list() + for(var/lace in typesof(/obj/item/clothing/shoes/laceup)) + var/obj/item/clothing/shoes/laceup/lace_type = lace + laces[initial(lace_type.name)] = lace_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(laces)) /datum/gear/shoes/green display_name = "shoes, green" path = /obj/item/clothing/shoes/green -/datum/gear/shoes/leather - display_name = "shoes, leather" - path = /obj/item/clothing/shoes/leather - /datum/gear/shoes/orange display_name = "shoes, orange" path = /obj/item/clothing/shoes/orange @@ -74,36 +78,16 @@ path = /obj/item/clothing/shoes/yellow /datum/gear/shoes/hitops/ - display_name = "high-top, white" + display_name = "high-top selection" path = /obj/item/clothing/shoes/hitops/ -/datum/gear/shoes/hitops/red - display_name = "high-top, red" - path = /obj/item/clothing/shoes/hitops/red - -/datum/gear/shoes/hitops/black - display_name = "high-top, black" - path = /obj/item/clothing/shoes/hitops/black - -/datum/gear/shoes/hitops/orange - display_name = "high-top, orange" - path = /obj/item/clothing/shoes/hitops/orange - -/datum/gear/shoes/hitops/blue - display_name = "high-top, blue" - path = /obj/item/clothing/shoes/hitops/blue - -/datum/gear/shoes/hitops/green - display_name = "high-top, green" - path = /obj/item/clothing/shoes/hitops/green - -/datum/gear/shoes/hitops/purple - display_name = "high-top, purple" - path = /obj/item/clothing/shoes/hitops/purple - -/datum/gear/shoes/hitops/yellow - display_name = "high-top, yellow" - path = /obj/item/clothing/shoes/hitops/yellow +/datum/gear/shoes/hitops/New() + ..() + var/list/hitops = list() + for(var/hitop in typesof(/obj/item/clothing/shoes/hitops)) + var/obj/item/clothing/shoes/hitops/hitop_type = hitop + hitops[initial(hitop_type.name)] = hitop_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(hitops)) /datum/gear/shoes/flipflops display_name = "flip flops" @@ -193,9 +177,9 @@ path = /obj/item/clothing/shoes/boots/winter/science /datum/gear/shoes/boots/winter/command - display_name = "colony director's winter boots" + display_name = "site manager's winter boots" path = /obj/item/clothing/shoes/boots/winter/command - allowed_roles = list("Colony Director") + allowed_roles = list("Site Manager") /datum/gear/shoes/boots/winter/engineering display_name = "engineering winter boots" diff --git a/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm b/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm index 73cce9a17e..554300d379 100644 --- a/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm @@ -1,5 +1,5 @@ /datum/gear/shoes/boots/winter/science - allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Explorer", "Pathfinder") + allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Explorer", "Pathfinder") /datum/gear/shoes/boots/winter/medical allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist", "Field Medic") @@ -18,4 +18,8 @@ /datum/gear/shoes/siren display_name = "boots, Siren" - path = /obj/item/clothing/shoes/boots/fluff/siren \ No newline at end of file + path = /obj/item/clothing/shoes/boots/fluff/siren + +/datum/gear/shoes/toeless + display_name = "toe-less jackboots" + path = /obj/item/clothing/shoes/boots/jackboots/toeless diff --git a/code/modules/client/preference_setup/loadout/loadout_suit.dm b/code/modules/client/preference_setup/loadout/loadout_suit.dm index a45ca9cf7d..1d0b728a10 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit.dm @@ -245,9 +245,9 @@ datum/gear/suit/duster allowed_roles = list("Quartermaster") /datum/gear/suit/roles/poncho/cloak/captain - display_name = "cloak, colony director" + display_name = "cloak, site manager" path = /obj/item/clothing/accessory/poncho/roles/cloak/captain - allowed_roles = list("Colony Director") + allowed_roles = list("Site Manager") /datum/gear/suit/roles/poncho/cloak/hop display_name = "cloak, head of personnel" @@ -341,9 +341,9 @@ datum/gear/suit/duster path = /obj/item/clothing/suit/storage/hooded/wintercoat /datum/gear/suit/wintercoat/captain - display_name = "winter coat, colony director" + display_name = "winter coat, site manager" path = /obj/item/clothing/suit/storage/hooded/wintercoat/captain - allowed_roles = list("Colony Director") + allowed_roles = list("Site Manager") /datum/gear/suit/wintercoat/security display_name = "winter coat, security" @@ -480,8 +480,8 @@ datum/gear/suit/duster /datum/gear/suit/snowsuit/command display_name = "snowsuit, command" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/snowsuit/command - allowed_roles = list("Colony Director","Research Director","Head of Personnel","Head of Security","Chief Engineer","Command Secretary","Blueshield Guard") //YW ADDITIONS + path = /obj/item/clothing/suit/storage/snowsuit/command + allowed_roles = list("Site Manager","Research Director","Head of Personnel","Head of Security","Chief Engineer","Command Secretary","Blueshield Guard") //YW ADDITIONS /datum/gear/suit/snowsuit/security display_name = "snowsuit, security" diff --git a/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm b/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm index d4cd36fbc5..3dc33eb9b3 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm @@ -2,13 +2,13 @@ allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist", "Field Medic") /datum/gear/suit/wintercoat/science - allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Explorer", "Pathfinder") + allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Explorer", "Pathfinder") /datum/gear/suit/snowsuit/medical allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist", "Field Medic") /datum/gear/suit/snowsuit/science - allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Explorer", "Pathfinder") + allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Explorer", "Pathfinder") /datum/gear/suit/labcoat_colorable display_name = "labcoat, colorable" @@ -61,7 +61,7 @@ /datum/gear/suit/roles/medical/ems_jacket/alt display_name = "first responder jacket, alt." path = /obj/item/clothing/suit/storage/toggle/fr_jacket/ems - + //paramedic vest /datum/gear/suit/roles/medical/paramedic_vest display_name = "paramedic vest" diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index 5a213d2186..758e9d0790 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -295,9 +295,9 @@ path = /obj/item/clothing/under/dress/dress_fire /datum/gear/uniform/uniform_captain - display_name = "uniform, colony director's dress" + display_name = "uniform, site manager's dress" path = /obj/item/clothing/under/dress/dress_cap - allowed_roles = list("Colony Director") + allowed_roles = list("Site Manager") /datum/gear/uniform/corpdetsuit display_name = "uniform, corporate (Detective)" diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm b/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm index a276be58cf..6dc8379824 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm @@ -7,11 +7,18 @@ display_name = "pt uniform, planetside sec" path = /obj/item/clothing/under/solgov/pt/sifguard +/datum/gear/uniform/job_skirt/sci + allowed_roles = list("Research Director","Scientist", "Xenobiologist", "Xenobotanist") + +/datum/gear/uniform/job_turtle/science + allowed_roles = list("Research Director", "Scientist", "Roboticist", "Xenobiologist", "Xenobotanist") + + //KHI Uniforms /datum/gear/uniform/job_khi/cmd display_name = "khi uniform, cmd" path = /obj/item/clothing/under/rank/khi/cmd - allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS + allowed_roles = list("Head of Security","Site Manager","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS /datum/gear/uniform/job_khi/sec display_name = "khi uniform, sec" @@ -31,7 +38,7 @@ /datum/gear/uniform/job_khi/sci display_name = "khi uniform, sci" path = /obj/item/clothing/under/rank/khi/sci - allowed_roles = list("Research Director", "Scientist", "Roboticist", "Xenobiologist", "Pathfinder", "Explorer") + allowed_roles = list("Research Director", "Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer") //Federation jackets /datum/gear/suit/job_fed/sec @@ -42,7 +49,7 @@ /datum/gear/suit/job_fed/medsci display_name = "fed uniform, med/sci" path = /obj/item/clothing/suit/storage/fluff/fedcoat/fedblue - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist","Pathfinder","Explorer","Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist","Xenobotanist","Pathfinder","Explorer","Field Medic") /datum/gear/suit/job_fed/eng display_name = "fed uniform, eng" @@ -54,12 +61,12 @@ /datum/gear/uniform/job_trek/cmd/tos display_name = "TOS uniform, cmd" path = /obj/item/clothing/under/rank/trek/command - allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS + allowed_roles = list("Head of Security","Site Manager","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS /datum/gear/uniform/job_trek/medsci/tos display_name = "TOS uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") /datum/gear/uniform/job_trek/eng/tos display_name = "TOS uniform, eng/sec" @@ -70,12 +77,12 @@ /datum/gear/uniform/job_trek/cmd/tng display_name = "TNG uniform, cmd" path = /obj/item/clothing/under/rank/trek/command/next - allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS + allowed_roles = list("Head of Security","Site Manager","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS /datum/gear/uniform/job_trek/medsci/tng display_name = "TNG uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci/next - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") /datum/gear/uniform/job_trek/eng/tng display_name = "TNG uniform, eng/sec" @@ -86,12 +93,12 @@ /datum/gear/uniform/job_trek/cmd/voy display_name = "VOY uniform, cmd" path = /obj/item/clothing/under/rank/trek/command/voy - allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS + allowed_roles = list("Head of Security","Site Manager","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS /datum/gear/uniform/job_trek/medsci/voy display_name = "VOY uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci/voy - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") /datum/gear/uniform/job_trek/eng/voy display_name = "VOY uniform, eng/sec" @@ -103,21 +110,21 @@ /datum/gear/suit/job_trek/ds9_coat display_name = "DS9 Overcoat (use uniform)" path = /obj/item/clothing/suit/storage/trek/ds9 - allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director", + allowed_roles = list("Head of Security","Site Manager","Head of Personnel","Chief Engineer","Research Director", "Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist", - "Scientist","Roboticist","Xenobiologist","Atmospheric Technician", + "Scientist","Roboticist","Xenobiologist","Xenobotanist","Atmospheric Technician", "Station Engineer","Warden","Detective","Security Officer", "Pathfinder", "Explorer", "Field Medic", "Blueshield Guard","Security Pilot") //YW ADDITIONS /datum/gear/uniform/job_trek/cmd/ds9 display_name = "DS9 uniform, cmd" path = /obj/item/clothing/under/rank/trek/command/ds9 - allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS + allowed_roles = list("Head of Security","Site Manager","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS /datum/gear/uniform/job_trek/medsci/ds9 display_name = "DS9 uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci/ds9 - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") /datum/gear/uniform/job_trek/eng/ds9 display_name = "DS9 uniform, eng/sec" @@ -129,12 +136,12 @@ /datum/gear/uniform/job_trek/cmd/ent display_name = "ENT uniform, cmd" path = /obj/item/clothing/under/rank/trek/command/ent - allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS + allowed_roles = list("Head of Security","Site Manager","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard") //YW ADDITIONS /datum/gear/uniform/job_trek/medsci/ent display_name = "ENT uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci/ent - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") /datum/gear/uniform/job_trek/eng/ent display_name = "ENT uniform, eng/sec" diff --git a/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm b/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm index 7b3ed3cbbb..d37f929e48 100644 --- a/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm @@ -54,4 +54,4 @@ /datum/gear/utility/dufflebag/sci display_name = "science dufflebag" path = /obj/item/weapon/storage/backpack/dufflebag/sci - allowed_roles = list("Research Director","Scientist","Roboticist","Xenobiologist","Explorer","Pathfinder") + allowed_roles = list("Research Director","Scientist","Roboticist","Xenobiologist","Xenobotanist","Explorer","Pathfinder") diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index db06bc0a81..86bc4425d7 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -184,12 +184,12 @@ /datum/gear/uniform/dept/undercoat/command display_name = "command undercoat (Teshari)" path = /obj/item/clothing/under/seromi/undercoat/jobs/command - allowed_roles = list("Colony Director","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer","Research Director") + allowed_roles = list("Site Manager","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer","Research Director") /datum/gear/uniform/dept/undercoat/command_g display_name = "command undercoat - gold buttons (Teshari)" path = /obj/item/clothing/under/seromi/undercoat/jobs/command_g - allowed_roles = list("Colony Director","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer","Research Director") + allowed_roles = list("Site Manager","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer","Research Director") /datum/gear/uniform/dept/undercoat/cmo display_name = "chief medical officer undercoat (Teshari)" @@ -278,7 +278,7 @@ /datum/gear/suit/dept/cloak/command display_name = "command cloak (Teshari)" path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/command - allowed_roles = list("Colony Director","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer","Research Director") + allowed_roles = list("Site Manager","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer","Research Director") /datum/gear/suit/dept/cloak/cmo display_name = "chief medical officer cloak (Teshari)" diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno_vr.dm b/code/modules/client/preference_setup/loadout/loadout_xeno_vr.dm index 2f5734030d..6272e40204 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno_vr.dm @@ -1,3 +1,14 @@ +// Upstream things +///// + +/datum/gear/suit/dept/cloak/research + allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist") + +/datum/gear/uniform/dept/undercoat/research + allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist") + +///// + /datum/gear/uniform/voxcasual display_name = "casual wear (Vox)" path = /obj/item/clothing/under/vox/vox_casual diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 6c09e1e7f8..9f3b4f5a67 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -310,9 +310,11 @@ pref.job_civilian_med |= pref.job_civilian_high pref.job_medsci_med |= pref.job_medsci_high pref.job_engsec_med |= pref.job_engsec_high + pref.job_talon_med |= pref.job_talon_high //VOREStation Add pref.job_civilian_high = 0 pref.job_medsci_high = 0 pref.job_engsec_high = 0 + pref.job_talon_high = 0 //VOREStation Add // Level is equal to the desired new level of the job. So for a value of 4, we want to disable the job. /datum/category_item/player_setup_item/occupation/proc/SetJobDepartment(var/datum/job/job, var/level) diff --git a/code/modules/client/preferences_toggle_procs.dm b/code/modules/client/preferences_toggle_procs.dm index e488badc39..bf3d7a3ca7 100644 --- a/code/modules/client/preferences_toggle_procs.dm +++ b/code/modules/client/preferences_toggle_procs.dm @@ -253,6 +253,51 @@ SScharacter_setup.queue_preferences_save(prefs) feedback_add_details("admin_verb","TAirPumpNoise") + +/client/verb/toggle_old_door_sounds() + set name = "Toggle Old Door Sounds" + set category = "Preferences" + set desc = "Toggles New/Old Door Sounds" + + var/pref_path = /datum/client_preference/old_door_sounds + + toggle_preference(pref_path) + + to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear the legacy door sounds.") + + SScharacter_setup.queue_preferences_save(prefs) + + feedback_add_details("admin_verb","TOldDoorSounds") + +/client/verb/toggle_department_door_sounds() + set name = "Toggle Department Door Sounds" + set category = "Preferences" + set desc = "Toggles Department-Specific Door Sounds" + + var/pref_path = /datum/client_preference/department_door_sounds + + toggle_preference(pref_path) + + to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear per-department door sounds.") + + SScharacter_setup.queue_preferences_save(prefs) + + feedback_add_details("admin_verb","TDepartmentDoorSounds") + +/client/verb/toggle_pickup_sounds() + set name = "Toggle Picked Up Item Sounds" + set category = "Preferences" + set desc = "Toggles sounds when items are picked up or thrown." + + var/pref_path = /datum/client_preference/pickup_sounds + + toggle_preference(pref_path) + + to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear sounds when items are picked up or thrown.") + + SScharacter_setup.queue_preferences_save(prefs) + + feedback_add_details("admin_verb", "TPickupSounds") /client/verb/toggle_drop_sounds() set name = "Toggle Dropped Item Sounds" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 23c56f8b30..687bfe841a 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -2,6 +2,7 @@ name = "clothing" siemens_coefficient = 0.9 drop_sound = 'sound/items/drop/clothing.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' var/list/species_restricted = null //Only these species can wear this kit. var/gunshot_residue //Used by forensics. @@ -301,6 +302,7 @@ SPECIES_VOX = 'icons/mob/species/vox/gloves.dmi' ) drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/gloves.ogg' /obj/item/clothing/proc/set_clothing_index() return @@ -435,6 +437,7 @@ SPECIES_VOX = 'icons/mob/species/vox/head.dmi' ) drop_sound = 'sound/items/drop/hat.ogg' + pickup_sound = 'sound/items/pickup/hat.ogg' /obj/item/clothing/head/attack_self(mob/user) if(brightness_on) @@ -591,6 +594,7 @@ SPECIES_VOX = 'icons/mob/species/vox/shoes.dmi' ) drop_sound = 'sound/items/drop/shoes.ogg' + pickup_sound = 'sound/items/pickup/shoes.ogg' /obj/item/clothing/shoes/proc/draw_knife() set name = "Draw Boot Knife" @@ -749,6 +753,7 @@ permeability_coefficient = 0.90 slot_flags = SLOT_ICLOTHING armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + equip_sound = 'sound/items/jumpsuit_equip.ogg' w_class = ITEMSIZE_NORMAL show_messages = 1 blood_sprite_state = "uniformblood" diff --git a/code/modules/clothing/ears/ears.dm b/code/modules/clothing/ears/ears.dm index 505a4be004..8fdd6deb94 100644 --- a/code/modules/clothing/ears/ears.dm +++ b/code/modules/clothing/ears/ears.dm @@ -54,6 +54,7 @@ icon_state = "skrell_chain" item_state_slots = list(slot_r_hand_str = "egg5", slot_l_hand_str = "egg5") drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' /obj/item/clothing/ears/skrell/chain/silver name = "Silver headtail chains" @@ -85,6 +86,7 @@ icon_state = "skrell_band" item_state_slots = list(slot_r_hand_str = "egg5", slot_l_hand_str = "egg5") drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' /obj/item/clothing/ears/skrell/band/silver name = "Silver headtail bands" diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 06f67f4971..f83794efde 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -28,6 +28,7 @@ BLIND // can't see anything var/obj/screen/overlay = null var/list/away_planes //Holder for disabled planes drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' sprite_sheets = list( "Teshari" = 'icons/mob/species/seromi/eyes.dmi', @@ -184,6 +185,7 @@ BLIND // can't see anything body_parts_covered = 0 var/eye = null drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/gloves.ogg' /obj/item/clothing/glasses/eyepatch/verb/switcheye() set name = "Switch Eyepatch" @@ -366,6 +368,7 @@ BLIND // can't see anything flash_protection = FLASH_PROTECTION_MAJOR tint = BLIND drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/gloves.ogg' /obj/item/clothing/glasses/sunglasses/blindfold/tape name = "length of tape" diff --git a/code/modules/clothing/glasses/hud_vr.dm b/code/modules/clothing/glasses/hud_vr.dm index 2c96f9d552..be02be0c47 100644 --- a/code/modules/clothing/glasses/hud_vr.dm +++ b/code/modules/clothing/glasses/hud_vr.dm @@ -1,6 +1,9 @@ /obj/item/clothing/glasses/omnihud name = "\improper AR glasses" - desc = "The NT-62 AR Glasses are augmented reality glasses designed and exported by NanoTrasen." + desc = "The NT-62 AR Glasses are augmented reality glasses designed and exported by NanoTrasen and are capable of displaying information on individuals. \ + Commonly used to allow non-augmented crew to interact with virtual interfaces. \ +
They are also fitted with toggleable cosmetic electrochromic lenses. \ + The lenses will not protect against sudden bright flashes or welding." origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 3) var/obj/item/clothing/glasses/hud/omni/hud = null var/mode = "civ" @@ -44,6 +47,13 @@ spawn(20 SECONDS) arscreen = disconnect_ar tgarscreen = disconnect_tgar + + //extra fun for non-sci variants; a small chance flip the state to the dumb 3d glasses when EMP'd + if(icon_state == "glasses" || icon_state == "sun") + if(prob(10)) + icon_state = "3d" + if(ishuman(loc)) + to_chat(loc, "The lenses of your [src.name] malfunction!") ..() /obj/item/clothing/glasses/omnihud/proc/flashed() @@ -54,11 +64,13 @@ prescription = !prescription playsound(src,'sound/items/screwdriver.ogg', 50, 1) if(prescription) - name = "[initial(name)] (pr)" - user.visible_message("[user] uploads new prescription data to the [src.name].") + user.visible_message("[user] uploads new prescription data to the [src.name] and resets the lenses.") + name = "[initial(name)] (pr)" //change the name *after* the text so the message above is accurate + icon_state = "[initial(icon_state)]" //reset the icon state just to be safe else + user.visible_message("[user] deletes the prescription data on the [src.name] and resets the lenses.") name = "[initial(name)]" - user.visible_message("[user] deletes the prescription data on the [src.name].") + icon_state = "[initial(icon_state)]" /obj/item/clothing/glasses/omnihud/attack_self(mob/user) if(!ishuman(user)) @@ -71,6 +83,45 @@ if(!ar_interact(H)) to_chat(user, "The [src] does not have any kind of special display.") +//cosmetic shading, doesn't enhance eye protection +/obj/item/clothing/glasses/omnihud/verb/chromatize() + set name = "Toggle AR Glasses Shading" + set desc = "Toggle the cosmetic electrochromatic shading of your AR glasses." + set category = "Object" + set src in usr + if(!usr.canmove || usr.stat || usr.restrained()) + return + if(icon_state == "3d") + to_chat(usr, "You reset the electrochromic lenses of \the [src] back to normal.") + if(prescription) + name = "[initial(name)] (pr)" + else + name = "[initial(name)]" + icon_state = "[initial(icon_state)]" + else if(prescription) + if(icon_state == "glasses") + to_chat(usr, "You darken the electrochromic lenses of \the [src] to one-way transparency.") + name = "[initial(name)] (shaded, pr)" + icon_state = "sun" + else if(icon_state == "sun") + to_chat(usr, "You restore the electrochromic lenses of \the [src] to standard two-way transparency.") + name = "[initial(name)] (pr)" + icon_state = "glasses" + else + to_chat(usr, "The [src] don't seem to support this functionality.") + else if(!prescription) + if(icon_state == "glasses") + to_chat(usr, "You darken the electrochromic lenses of \the [src] to one-way transparency.") + name = "[initial(name)] (shaded)" + icon_state = "sun" + else if(icon_state == "sun") + to_chat(usr, "You restore the electrochromic lenses of \the [src] to standard two-way transparency.") + name = "[initial(name)]" + icon_state = "glasses" + else + to_chat(usr, "The [src] don't seem to support this functionality.") + update_clothing_icon() + /obj/item/clothing/glasses/omnihud/proc/ar_interact(var/mob/living/carbon/human/user) return 0 //The base models do nothing. @@ -80,8 +131,9 @@ /obj/item/clothing/glasses/omnihud/med name = "\improper AR-M glasses" - desc = "The NT-62-M AR glasses are a design of the Augmented Reality glasses that NanoTrasen produces. \ - These have been upgraded with medical records access and virus database integration." + desc = "The NT-62-M AR Glasses are capable of displaying information on individuals. \ + These have been upgraded with medical records access and virus database integration. \ + They can also read data from active suit sensors using the crew monitoring system." mode = "med" action_button_name = "AR Console (Crew Monitor)" tgarscreen_path = /datum/tgui_module/crew_monitor/glasses @@ -94,10 +146,11 @@ /obj/item/clothing/glasses/omnihud/sec name = "\improper AR-S glasses" - desc = "The NT-62-S AR glasses are a design of the Augmented Reality glasses that NanoTrasen produces. \ - These have been upgraded with security records integration and flash protection." + desc = "The NT-62-S AR Glasses are capable of displaying information on individuals. \ + These have been upgraded with security records integration and flash protection. \ + They also have access to security alerts such as camera and motion sensor alarms." mode = "sec" - flash_protection = FLASH_PROTECTION_MAJOR + flash_protection = FLASH_PROTECTION_MODERATE //weld protection is a little too widespread action_button_name = "AR Console (Security Alerts)" tgarscreen_path = /datum/tgui_module/alarm_monitor/security/glasses enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_WANTED,VIS_AUGMENTED) @@ -109,8 +162,9 @@ /obj/item/clothing/glasses/omnihud/eng name = "\improper AR-E glasses" - desc = "The NT-62-E AR glasses are a design of the Augmented Reality glasses that NanoTrasen produces. \ - These have been upgraded with advanced electrochromic lenses to protect your eyes during welding." + desc = "The NT-62-E AR Glasses are capable of displaying information on individuals. \ + These have been upgraded with advanced electrochromic lenses to protect your eyes during welding, \ + and can also display a list of atmospheric, fire, and power alarms." mode = "eng" flash_protection = FLASH_PROTECTION_MAJOR action_button_name = "AR Console (Station Alerts)" @@ -123,16 +177,13 @@ /obj/item/clothing/glasses/omnihud/rnd name = "\improper AR-R glasses" - desc = "The NT-62-R AR glasses are a design of the Augmented Reality glasses that NanoTrasen produces.\ - These have been ... modified ... to.... well. They're purple." + desc = "The NT-62-R AR Glasses are capable of displaying information on individuals. \ + They... don't seem to do anything particularly interesting? But hey, at least they look kinda science-y." mode = "sci" - icon = 'icons/obj/clothing/glasses.dmi' - icon_override = null - icon_state = "purple" /obj/item/clothing/glasses/omnihud/eng/meson name = "meson scanner HUD" - desc = "A headset equipped with a scanning lens and mounted retinal projector. They don't provide any eye protection, but they're less obtrusive than goggles." + desc = "A headset equipped with a scanning lens and mounted retinal projector. It doesn't provide any eye protection, but it's less obtrusive than goggles." icon = 'icons/vore/custom_items_vr.dmi' icon_override = 'icons/vore/custom_clothes_vr.dmi' icon_state = "projector" @@ -140,6 +191,7 @@ body_parts_covered = 0 toggleable = 1 vision_flags = SEE_TURFS //but they can spot breaches. Due to the way HUDs work, they don't provide darkvision up-close the way mesons do. + flash_protection = 0 //it's an open, single-eye retinal projector. there's no way it protects your eyes from flashes or welders. /obj/item/clothing/glasses/omnihud/eng/meson/attack_self(mob/user) if(!active) @@ -169,11 +221,19 @@ /obj/item/clothing/glasses/omnihud/all name = "\improper AR-B glasses" - desc = "The NT-62-B AR glasses are a design of the Augmented Reality glasses that NanoTrasen produces. \ - These have been upgraded with every feature the lesser models have." + desc = "The NT-62-B AR Glasses are capable of displaying information on individuals. \ + These have been upgraded with (almost) every feature the lesser models have. Now we're talkin'. \ +
Offers full protection against bright flashes/welders and full access to system alarm monitoring." mode = "best" flash_protection = FLASH_PROTECTION_MAJOR enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_CH_WANTED) + action_button_name = "AR Console (All Alerts)" + tgarscreen_path = /datum/tgui_module/alarm_monitor/all/glasses + + ar_interact(var/mob/living/carbon/human/user) + if(tgarscreen) + tgarscreen.tgui_interact(user) + return 1 /obj/item/clothing/glasses/hud/security/eyepatch name = "Security Hudpatch" @@ -220,5 +280,4 @@ icon_state = "[icon_state]_1" else icon_state = initial(icon_state) - update_clothing_icon() - + update_clothing_icon() \ No newline at end of file diff --git a/code/modules/clothing/gloves/arm_guards.dm b/code/modules/clothing/gloves/arm_guards.dm index 6b0517642a..ea0c97187c 100644 --- a/code/modules/clothing/gloves/arm_guards.dm +++ b/code/modules/clothing/gloves/arm_guards.dm @@ -6,6 +6,7 @@ punch_force = 3 w_class = ITEMSIZE_NORMAL drop_sound = 'sound/items/drop/metalshield.ogg' + pickup_sound = 'sound/items/pickup/axe.ogg' /obj/item/clothing/gloves/arm_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = FALSE) if(..()) //This will only run if no other problems occured when equiping. diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 1c5ad9c05c..a9cec00a5f 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -7,6 +7,7 @@ siemens_coefficient = 0 permeability_coefficient = 0.05 drop_sound = 'sound/items/drop/rubber.ogg' + pickup_sound = 'sound/items/pickup/rubber.ogg' /obj/item/clothing/gloves/fyellow //Cheap Chinese Crap desc = "These gloves are cheap copies of proper insulated gloves. No way this can end badly." @@ -15,6 +16,7 @@ siemens_coefficient = 1 //Set to a default of 1, gets overridden in initialize() permeability_coefficient = 0.05 drop_sound = 'sound/items/drop/rubber.ogg' + pickup_sound = 'sound/items/pickup/rubber.ogg' /obj/item/clothing/gloves/fyellow/Initialize() . = ..() diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index b44dc54567..c7a7682993 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -1,6 +1,6 @@ /obj/item/clothing/gloves/captain desc = "Regal blue gloves, with a nice gold trim. Swanky." - name = "colony director's gloves" + name = "site manager's gloves" icon_state = "captain" item_state_slots = list(slot_r_hand_str = "blue", slot_l_hand_str = "blue") @@ -57,6 +57,7 @@ germ_level = 0 fingerprint_chance = 25 drop_sound = 'sound/items/drop/rubber.ogg' + pickup_sound = 'sound/items/pickup/rubber.ogg' // var/balloonPath = /obj/item/latexballon //TODO: Make inflating gloves a thing @@ -83,6 +84,7 @@ permeability_coefficient = 0.05 siemens_coefficient = 0.75 //thick work gloves drop_sound = 'sound/items/drop/leather.ogg' + pickup_sound = 'sound/items/pickup/leather.ogg' /obj/item/clothing/gloves/duty desc = "These brown duty gloves are made from a durable synthetic." @@ -112,6 +114,7 @@ permeability_coefficient = 0.05 species_restricted = list("Vox") drop_sound = 'sound/items/drop/metalboots.ogg' + pickup_sound = 'sound/items/pickup/toolbox.ogg' cold_protection = HANDS min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE @@ -131,6 +134,7 @@ force = 5 punch_force = 5 drop_sound = 'sound/items/drop/metalboots.ogg' + pickup_sound = 'sound/items/pickup/toolbox.ogg' /obj/item/clothing/gloves/ranger var/glovecolor = "white" diff --git a/code/modules/clothing/gloves/miscellaneous_vr.dm b/code/modules/clothing/gloves/miscellaneous_vr.dm index ed1329f194..975ef36988 100644 --- a/code/modules/clothing/gloves/miscellaneous_vr.dm +++ b/code/modules/clothing/gloves/miscellaneous_vr.dm @@ -20,3 +20,43 @@ desc = "A pair of gloves, they don't look special in any way." item_state_slots = list(slot_r_hand_str = "white", slot_l_hand_str = "white") icon_state = "latex" + +// Armor Versions Here +/obj/item/clothing/gloves/combat/knight + desc = "ye olde armored gauntlets" + name = "knight gauntlets" + icon_state = "black" + item_state = "black" + siemens_coefficient = 2 + permeability_coefficient = 0.05 + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE + heat_protection = HANDS + max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + +/obj/item/clothing/gloves/combat/knight/brown + desc = "ye olde armored gauntlets" + name = "knight gauntlets" + icon_state = "brown" + item_state = "brown" + +// Costume Versions Here +/obj/item/clothing/gloves/combat/knight_costume + desc = "ye olde armored gauntlets" + name = "knight gauntlets" + icon_state = "black" + item_state = "black" + siemens_coefficient = 2 + permeability_coefficient = 0.05 + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE + heat_protection = HANDS + max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + +/obj/item/clothing/gloves/combat/knight_costume/brown + desc = "ye olde armored gauntlets" + name = "knight gauntlets" + icon_state = "brown" + item_state = "brown" \ No newline at end of file diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index 810ac403f7..79642d34c1 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -38,6 +38,7 @@ icon_state = "paper" body_parts_covered = 0 drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' /obj/item/clothing/head/collectable/tophat name = "collectable top hat" @@ -46,7 +47,7 @@ body_parts_covered = 0 /obj/item/clothing/head/collectable/captain - name = "collectable colony director's hat" + name = "collectable site manager's hat" desc = "A Collectable Hat that'll make you look just like a real comdom!" icon_state = "captain" body_parts_covered = 0 diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index d3db7a5b17..f974c321c0 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -11,6 +11,7 @@ w_class = ITEMSIZE_NORMAL ear_protection = 1 drop_sound = 'sound/items/drop/helm.ogg' + pickup_sound = 'sound/items/pickup/helm.ogg' /obj/item/clothing/head/hardhat/orange icon_state = "hardhat0_orange" diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 2f30326e78..a617717576 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -15,6 +15,7 @@ w_class = ITEMSIZE_NORMAL ear_protection = 1 drop_sound = 'sound/items/drop/helm.ogg' + pickup_sound = 'sound/items/pickup/helm.ogg' /obj/item/clothing/head/helmet/solgov name = "\improper Solar Confederate Government helmet" diff --git a/code/modules/clothing/head/helmet_vr.dm b/code/modules/clothing/head/helmet_vr.dm index 00d51f2f47..6f36aef383 100644 --- a/code/modules/clothing/head/helmet_vr.dm +++ b/code/modules/clothing/head/helmet_vr.dm @@ -27,3 +27,117 @@ icon_state = "ge_helmcent" icon = 'icons/obj/clothing/hats_vr.dmi' icon_override = 'icons/mob/head_vr.dmi' + +// Armor Versions Here +/obj/item/clothing/head/helmet/combat/crusader + name = "crusader helmet" + desc = "ye olde armored helmet" + icon_state = "crusader" + icon = 'icons/obj/clothing/hats_vr.dmi' + icon_override = 'icons/obj/clothing/hats_vr.dmi' + armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 2 + +/obj/item/clothing/head/helmet/combat/bedevere + name = "bedevere's helmet" + desc = "ye olde armored helmet" + icon_state = "bedevere_helmet" + icon = 'icons/obj/clothing/hats_vr.dmi' + icon_override = 'icons/obj/clothing/hats_vr.dmi' + armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + tint = TINT_HEAVY + siemens_coefficient = 2 + + var/base_state + var/up = FALSE + +/obj/item/clothing/head/helmet/combat/bedevere/attack_self() + toggle() + +/obj/item/clothing/head/helmet/combat/bedevere/verb/toggle() + set category = "Object" + set name = "Adjust helmet visor" + set src in usr + + if(!base_state) + base_state = icon_state + + if(usr.canmove && !usr.stat && !usr.restrained()) + if(src.up) + src.up = !src.up + body_parts_covered |= (EYES|FACE) + flags_inv |= (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE) + icon_state = base_state + tint = initial(tint) + to_chat(usr, "You flip the [src] down to protect yourself from the horrors of this universe. Narry a creature shall harm you with its beams of light.") + playsound(src, 'sound/machines/hatch_open.ogg', 75, 1) + else + src.up = !src.up + body_parts_covered &= ~(EYES|FACE) + flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE) + icon_state = "[base_state]_up" + tint = TINT_NONE + to_chat(usr, "You push the [src] up out of your face, ineffectively clearing your vision.") + playsound(src, 'sound/machines/hatch_open.ogg', 75, 1) + update_clothing_icon() //so our mob-overlays + if (ismob(src.loc)) //should allow masks to update when it is opened/closed + var/mob/M = src.loc + M.update_inv_wear_mask() + usr.update_action_buttons() + +// Costume Versions Here +/obj/item/clothing/head/helmet/combat/crusader_costume + name = "crusader costume helmet" + desc = "ye olde armored helmet" + icon_state = "crusader" + icon = 'icons/obj/clothing/hats_vr.dmi' + icon_override = 'icons/obj/clothing/hats_vr.dmi' + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 1 + +/obj/item/clothing/head/helmet/combat/bedevere_costume + name = "bedevere's costume helmet" + desc = "ye olde armored helmet" + icon_state = "bedevere_helmet" + icon = 'icons/obj/clothing/hats_vr.dmi' + icon_override = 'icons/obj/clothing/hats_vr.dmi' + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + tint = TINT_HEAVY + siemens_coefficient = 1 + + var/base_state + var/up = FALSE + +/obj/item/clothing/head/helmet/combat/bedevere_costume/attack_self() + toggle() + +/obj/item/clothing/head/helmet/combat/bedevere_costume/verb/toggle() + set category = "Object" + set name = "Adjust helmet visor" + set src in usr + + if(!base_state) + base_state = icon_state + + if(usr.canmove && !usr.stat && !usr.restrained()) + if(src.up) + src.up = !src.up + body_parts_covered |= (EYES|FACE) + flags_inv |= (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE) + icon_state = base_state + tint = initial(tint) + to_chat(usr, "You flip the [src] down to protect yourself from the horrors of this universe. Narry a creature shall harm you with its beams of light.") + playsound(src, 'sound/machines/hatch_open.ogg', 75, 1) + else + src.up = !src.up + body_parts_covered &= ~(EYES|FACE) + flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE) + icon_state = "[base_state]_up" + tint = TINT_NONE + to_chat(usr, "You push the [src] up out of your face, ineffectively clearing your vision.") + playsound(src, 'sound/machines/hatch_open.ogg', 75, 1) + update_clothing_icon() //so our mob-overlays + if (ismob(src.loc)) //should allow masks to update when it is opened/closed + var/mob/M = src.loc + M.update_inv_wear_mask() + usr.update_action_buttons() \ No newline at end of file diff --git a/code/modules/clothing/head/hood.dm b/code/modules/clothing/head/hood.dm index c66589eb6a..5ac04810ea 100644 --- a/code/modules/clothing/head/hood.dm +++ b/code/modules/clothing/head/hood.dm @@ -14,7 +14,7 @@ min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE /obj/item/clothing/head/hood/winter/captain - name = "colony director's winter hood" + name = "site manager's winter hood" armor = list(melee = 20, bullet = 15, laser = 20, energy = 10, bomb = 15, bio = 0, rad = 0) /obj/item/clothing/head/hood/winter/security diff --git a/code/modules/clothing/head/hood_vr.dm b/code/modules/clothing/head/hood_vr.dm index f669d131f7..8c8b4f7368 100644 --- a/code/modules/clothing/head/hood_vr.dm +++ b/code/modules/clothing/head/hood_vr.dm @@ -1,3 +1,29 @@ /obj/item/clothing/head/hood/techpriest name = "techpriest hood" armor = list(melee = 20, bullet = 10, laser = 10, energy = 10, bomb = 25, bio = 50, rad = 25) + +// Armor versions here +/obj/item/clothing/head/hood/galahad + name = "galahad hood" + armor = list(melee = 80, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 2 + +/obj/item/clothing/head/hood/lancelot + name = "lancelot hood" + armor = list(melee = 80, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 2 + +/obj/item/clothing/head/hood/robin + name = "robin hood" + armor = list(melee = 80, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 3 + +// Costume Versions Here +/obj/item/clothing/head/hood/galahad_costume + name = "galahad costume hood" + +/obj/item/clothing/head/hood/lancelot_costume + name = "lancelot costume hood" + +/obj/item/clothing/head/hood/robin_costume + name = "robin costume hood" \ No newline at end of file diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index a9305ffddb..23c629fac2 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -7,13 +7,13 @@ //Captain /obj/item/clothing/head/caphat - name = "colony director's hat" + name = "site manager's hat" icon_state = "captain" desc = "It's good being the king." body_parts_covered = 0 /obj/item/clothing/head/caphat/cap - name = "colony director's cap" + name = "site manager's cap" desc = "You fear to wear it for the negligence it brings." icon_state = "capcap" diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 1b7544c351..818c91eda5 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -18,6 +18,7 @@ slot_flags = SLOT_HEAD | SLOT_EARS body_parts_covered = 0 drop_sound = 'sound/items/drop/ring.ogg' + pickup_sound = 'sound/items/pickup/ring.ogg' /obj/item/clothing/head/pin/pink icon_state = "pinkpin" @@ -169,7 +170,8 @@ icon_state = "cardborg_h" flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE body_parts_covered = HEAD|FACE|EYES - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/clothing/head/justice name = "justice hat" diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index b23f70b185..4cf06d6cc2 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -30,6 +30,7 @@ flash_protection = FLASH_PROTECTION_MAJOR tint = TINT_HEAVY drop_sound = 'sound/items/drop/helm.ogg' + pickup_sound = 'sound/items/pickup/helm.ogg' /obj/item/clothing/head/welding/attack_self() toggle() @@ -167,9 +168,10 @@ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|BLOCKHAIR body_parts_covered = HEAD|FACE|EYES brightness_on = 2 - light_overlay = "helmet_light" + light_overlay = "jackolantern" w_class = ITEMSIZE_NORMAL drop_sound = 'sound/items/drop/herb.ogg' + pickup_sound = 'sound/items/pickup/herb.ogg' /* * Kitty ears diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index fceca9600b..594600b601 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -11,7 +11,7 @@ permeability_coefficient = 0.01 siemens_coefficient = 0.9 var/gas_filter_strength = 1 //For gas mask filters - var/list/filtered_gases = list("phoron", "sleeping_agent") + var/list/filtered_gases = list("phoron", "nitrous_oxide") armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 75, rad = 0) /obj/item/clothing/mask/gas/filter_air(datum/gas_mixture/air) @@ -65,7 +65,7 @@ flags = PHORONGUARD item_flags = BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT species_restricted = list(SPECIES_VOX) - filtered_gases = list("oxygen", "sleeping_agent") + filtered_gases = list("oxygen", "nitrous_oxide") var/mask_open = FALSE // Controls if the Vox can eat through this mask action_button_name = "Toggle Feeding Port" @@ -92,7 +92,7 @@ //body_parts_covered = 0 species_restricted = list(SPECIES_ZADDAT) flags_inv = HIDEEARS //semi-transparent - filtered_gases = list("phoron", "nitrogen", "sleeping_agent") + filtered_gases = list("phoron", "nitrogen", "nitrous_oxide") /obj/item/clothing/mask/gas/syndicate name = "tactical mask" diff --git a/code/modules/clothing/shoes/boots.dm b/code/modules/clothing/shoes/boots.dm index b0ccf41175..c85298cba9 100644 --- a/code/modules/clothing/shoes/boots.dm +++ b/code/modules/clothing/shoes/boots.dm @@ -17,13 +17,11 @@ name = "classic cowboy boots" desc = "A classic looking pair of durable cowboy boots." icon_state = "cowboy_classic" - item_state_slots = list(slot_r_hand_str = "leather", slot_l_hand_str = "leather") /obj/item/clothing/shoes/boots/cowboy/snakeskin name = "snakeskin cowboy boots" desc = "A pair of cowboy boots made from python skin." icon_state = "cowboy_snakeskin" - item_state_slots = list(slot_r_hand_str = "white", slot_l_hand_str = "white") /obj/item/clothing/shoes/boots/jackboots name = "jackboots" @@ -31,6 +29,8 @@ icon_state = "jackboots" armor = list(melee = 30, bullet = 10, laser = 10, energy = 15, bomb = 20, bio = 0, rad = 0) siemens_coefficient = 0.7 + drop_sound = 'sound/items/drop/boots.ogg' + pickup_sound = 'sound/items/pickup/boots.ogg' /obj/item/clothing/shoes/boots/jackboots/toeless name = "toe-less jackboots" @@ -39,12 +39,40 @@ item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots") species_restricted = null +/obj/item/clothing/shoes/boots/jackboots/knee + name = "knee-length jackboots" + desc = "Taller synthleather boots with an artificial shine." + icon_state = "kneeboots" + item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots") + +/obj/item/clothing/shoes/boots/jackboots/toeless/knee + name = "toe-less knee-length jackboots" + desc = "Modified pair of taller boots, particularly friendly to those species whose toes hold claws." + icon_state = "digikneeboots" + item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots") + species_restricted = null + +/obj/item/clothing/shoes/boots/jackboots/thigh + name = "thigh-length jackboots" + desc = "Even taller synthleather boots with an artificial shine." + icon_state = "thighboots" + item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots") + +/obj/item/clothing/shoes/boots/jackboots/toeless/thigh + name = "toe-less thigh-length jackboots" + desc = "Modified pair of even taller boots, particularly friendly to those species whose toes hold claws." + icon_state = "digithighboots" + item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots") + species_restricted = null + /obj/item/clothing/shoes/boots/workboots name = "workboots" desc = "A pair of steel-toed work boots designed for use in industrial settings. Safety first." icon_state = "workboots" armor = list(melee = 40, bullet = 0, laser = 0, energy = 15, bomb = 20, bio = 0, rad = 20) siemens_coefficient = 0.7 + drop_sound = 'sound/items/drop/boots.ogg' + pickup_sound = 'sound/items/pickup/boots.ogg' /obj/item/clothing/shoes/boots/workboots/toeless name = "toe-less workboots" @@ -76,7 +104,7 @@ icon_state = "winterboots_sci" /obj/item/clothing/shoes/boots/winter/command - name = "colony director's winter boots" + name = "site manager's winter boots" desc = "A pair of winter boots. They're lined with dark fur, and trimmed in the colours of superiority." icon_state = "winterboots_cap" diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index 8f72b24163..5035a7f349 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -35,12 +35,6 @@ icon_state = "white" permeability_coefficient = 0.01 -/obj/item/clothing/shoes/leather - name = "leather shoes" - desc = "A sturdy pair of leather shoes." - icon_state = "leather" - drop_sound = 'sound/items/drop/leather.ogg' - /obj/item/clothing/shoes/rainbow name = "rainbow shoes" desc = "Very colourful shoes." diff --git a/code/modules/clothing/shoes/leg_guards.dm b/code/modules/clothing/shoes/leg_guards.dm index a4079087ab..db7e5a88b5 100644 --- a/code/modules/clothing/shoes/leg_guards.dm +++ b/code/modules/clothing/shoes/leg_guards.dm @@ -8,6 +8,7 @@ step_volume_mod = 1.3 can_hold_knife = TRUE drop_sound = 'sound/items/drop/boots.ogg' + pickup_sound = 'sound/items/pickup/boots.ogg' /obj/item/clothing/shoes/leg_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = FALSE) if(..()) //This will only run if no other problems occured when equiping. diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 7590817a37..cb736737c6 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -17,6 +17,7 @@ var/mob/living/carbon/human/wearer = null //For shoe procs step_volume_mod = 1.3 drop_sound = 'sound/items/drop/metalboots.ogg' + pickup_sound = 'sound/items/pickup/toolbox.ogg' /obj/item/clothing/shoes/magboots/proc/set_slowdown() slowdown = shoes? max(SHOES_SLOWDOWN, shoes.slowdown): SHOES_SLOWDOWN //So you can't put on magboots to make you walk faster. diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 0e492c6d6c..25b8558da9 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -9,6 +9,8 @@ siemens_coefficient = 0.8 species_restricted = null step_volume_mod = 0.5 + drop_sound = 'sound/items/drop/rubber.ogg' + pickup_sound = 'sound/items/pickup/rubber.ogg' /obj/item/clothing/shoes/mime name = "mime shoes" @@ -25,6 +27,7 @@ slowdown = SHOES_SLOWDOWN+1 species_restricted = null drop_sound = 'sound/items/drop/rubber.ogg' + pickup_sound = 'sound/items/pickup/rubber.ogg' /obj/item/clothing/shoes/dress name = "dress shoes" @@ -45,6 +48,11 @@ wizard_garb = 1 +obj/item/clothing/shoes/sandal/clogs + name = "plastic clogs" + desc = "A pair of plastic clog shoes." + icon_state = "clogs" + /obj/item/clothing/shoes/sandal/marisa desc = "A pair of magic, black shoes." name = "magic shoes" @@ -100,19 +108,25 @@ species_restricted = null w_class = ITEMSIZE_SMALL drop_sound = 'sound/items/drop/clothing.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' -/obj/item/clothing/shoes/slippers_worn +/obj/item/clothing/shoes/slippers/worn name = "worn bunny slippers" desc = "Fluffy..." icon_state = "slippers_worn" item_state_slots = list(slot_r_hand_str = "slippers", slot_l_hand_str = "slippers") - force = 0 - w_class = ITEMSIZE_SMALL /obj/item/clothing/shoes/laceup - name = "laceup shoes" - desc = "The height of fashion, and they're pre-polished!" - icon_state = "laceups" + name = "black oxford shoes" + icon_state = "oxford_black" + +/obj/item/clothing/shoes/laceup/grey + name = "grey oxford shoes" + icon_state = "oxford_grey" + +/obj/item/clothing/shoes/laceup/brown + name = "brown oxford shoes" + icon_state = "oxford_brown" /obj/item/clothing/shoes/swimmingfins desc = "Help you swim good." @@ -158,6 +172,7 @@ w_class = ITEMSIZE_SMALL species_restricted = null drop_sound = 'sound/items/drop/clothing.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' /obj/item/clothing/shoes/boots/ranger var/bootcolor = "white" diff --git a/code/modules/clothing/shoes/miscellaneous_vr.dm b/code/modules/clothing/shoes/miscellaneous_vr.dm index aca7857438..9e68be33dd 100644 --- a/code/modules/clothing/shoes/miscellaneous_vr.dm +++ b/code/modules/clothing/shoes/miscellaneous_vr.dm @@ -58,4 +58,35 @@ else if(shoes) slowdown = shoes.slowdown else - slowdown = SHOES_SLOWDOWN \ No newline at end of file + slowdown = SHOES_SLOWDOWN + +// Armor Versions Here +/obj/item/clothing/shoes/knight + name = "knight boots" + desc = "A pair of olde knight boots." + icon_state = "knight_boots1" + item_state = "knight_boots1" + icon = 'icons/obj/clothing/shoes_vr.dmi' + icon_override = 'icons/obj/clothing/shoes_vr.dmi' + armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + +/obj/item/clothing/shoes/knight/black + name = "knight boots" + desc = "A pair of olde knight boots." + icon_state = "knight_boots2" + item_state = "knight_boots2" + +// Costume Versions Here +/obj/item/clothing/shoes/knight_costume + name = "knight boots" + desc = "A pair of olde knight boots." + icon_state = "knight_boots1" + item_state = "knight_boots1" + icon = 'icons/obj/clothing/shoes_vr.dmi' + icon_override = 'icons/obj/clothing/shoes_vr.dmi' + +/obj/item/clothing/shoes/knight_costume/black + name = "knight boots" + desc = "A pair of olde knight boots." + icon_state = "knight_boots2" + item_state = "knight_boots2" \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 28009030a3..696f63a4ce 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -10,7 +10,7 @@ //Captain's space suit This is not the proper path but I don't currently know enough about how this all works to mess with it. /obj/item/clothing/suit/armor/captain - name = "Colony Director's armor" + name = "Site Manager's armor" desc = "A bulky, heavy-duty piece of exclusive corporate armor. YOU are in charge!" icon_state = "caparmor" w_class = ITEMSIZE_HUGE diff --git a/code/modules/clothing/spacesuits/void/military_vr.dm b/code/modules/clothing/spacesuits/void/military_vr.dm index ce3875a3f1..b8167da879 100644 --- a/code/modules/clothing/spacesuits/void/military_vr.dm +++ b/code/modules/clothing/spacesuits/void/military_vr.dm @@ -1,12 +1,12 @@ /obj/item/clothing/head/helmet/space/void/captain - name = "\improper director helmet" + name = "\improper manager helmet" desc = "A special helmet designed for work in a hazardous, low pressure environment. This model sacrifices mobility for even more armor." icon_state = "capvoid" item_state_slots = list(slot_r_hand_str = "sec_helm", slot_l_hand_str = "sec_helm") armor = list(melee = 60, bullet = 35, laser = 35, energy = 15, bomb = 55, bio = 100, rad = 20) /obj/item/clothing/suit/space/void/captain - name = "\improper director armor" + name = "\improper manager armor" desc = "A special suit that protects against hazardous, low pressure environments. This model sacrifices mobility for even more armor." icon_state = "capsuit_void" item_state_slots = list(slot_r_hand_str = "sec_voidsuit", slot_l_hand_str = "sec_voidsuit") diff --git a/code/modules/clothing/suits/aliens/tajara.dm b/code/modules/clothing/suits/aliens/tajara.dm index 3c3b0bb55d..f0a9fa13fe 100644 --- a/code/modules/clothing/suits/aliens/tajara.dm +++ b/code/modules/clothing/suits/aliens/tajara.dm @@ -4,10 +4,14 @@ icon_state = "zhan_furs" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER + drop_sound = 'sound/items/drop/leather.ogg' + pickup_sound = 'sound/items/pickup/leather.ogg' /obj/item/clothing/head/tajaran/scarf //This stays in /suits because it goes with the furs above name = "headscarf" desc = "A scarf of coarse fabric. Seems to have ear-holes." icon_state = "zhan_scarf" item_state_slots = list(slot_r_hand_str = "beret_white", slot_l_hand_str = "beret_white") - body_parts_covered = HEAD|FACE \ No newline at end of file + body_parts_covered = HEAD|FACE + drop_sound = 'sound/items/drop/leather.ogg' + pickup_sound = 'sound/items/pickup/leather.ogg' \ No newline at end of file diff --git a/code/modules/clothing/suits/armor_vr.dm b/code/modules/clothing/suits/armor_vr.dm index ecbdecbabd..a5d95a6296 100644 --- a/code/modules/clothing/suits/armor_vr.dm +++ b/code/modules/clothing/suits/armor_vr.dm @@ -85,3 +85,37 @@ /obj/item/clothing/suit/storage/vest/hoscoat/jensen/alt icon = 'icons/obj/clothing/suits_vr.dmi' icon_override = 'icons/mob/suit_vr.dmi' + +// Armor Versions Here +/obj/item/clothing/suit/armor/combat/crusader + name = "crusader armor" + desc = "ye olde knight, risen again." + icon_state = "crusader" + icon = 'icons/obj/clothing/knights_vr.dmi' + icon_override = 'icons/obj/clothing/knights_vr.dmi' + body_parts_covered = UPPER_TORSO|LOWER_TORSO + armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 2 + +/obj/item/clothing/suit/armor/combat/crusader/bedevere + name = "bedevere's armor" + desc = "ye olde knight, risen again." + icon_state = "bedevere" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + +// Costume Versions Here +/obj/item/clothing/suit/armor/combat/crusader_costume + name = "crusader costume armor" + desc = "ye olde knight, risen again." + icon_state = "crusader" + icon = 'icons/obj/clothing/knights_vr.dmi' + icon_override = 'icons/obj/clothing/knights_vr.dmi' + body_parts_covered = UPPER_TORSO|LOWER_TORSO + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 1 + +/obj/item/clothing/suit/armor/combat/crusader_costume/bedevere + name = "bedevere's costume armor" + desc = "ye olde knight, risen again." + icon_state = "bedevere" + body_parts_covered = UPPER_TORSO|LOWER_TORSO \ No newline at end of file diff --git a/code/modules/clothing/suits/hooded.dm b/code/modules/clothing/suits/hooded.dm index 14bb843c9a..f1101ba453 100644 --- a/code/modules/clothing/suits/hooded.dm +++ b/code/modules/clothing/suits/hooded.dm @@ -100,7 +100,7 @@ /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask, /obj/item/device/suit_cooling_unit) /obj/item/clothing/suit/storage/hooded/wintercoat/captain - name = "colony director's winter coat" + name = "site manager's winter coat" icon_state = "coatcaptain" item_state_slots = list(slot_r_hand_str = "coatcaptain", slot_l_hand_str = "coatcaptain") armor = list(melee = 20, bullet = 15, laser = 20, energy = 10, bomb = 15, bio = 0, rad = 0) diff --git a/code/modules/clothing/suits/hooded_vr.dm b/code/modules/clothing/suits/hooded_vr.dm index 0f57317284..f8c8ef1b51 100644 --- a/code/modules/clothing/suits/hooded_vr.dm +++ b/code/modules/clothing/suits/hooded_vr.dm @@ -11,3 +11,60 @@ hoodtype = /obj/item/clothing/head/hood/techpriest armor = list(melee = 20, bullet = 10, laser = 10, energy = 10, bomb = 25, bio = 50, rad = 25) item_state_slots = list(slot_r_hand_str = "engspace_suit", slot_l_hand_str = "engspace_suit") + +// Regular armor versions here, costumes below +/obj/item/clothing/suit/storage/hooded/knight + name = "crusader's armor" + desc = "ye olde knight, risen again." + icon_state = "galahad" + icon = 'icons/obj/clothing/knights_vr.dmi' + icon_override = 'icons/obj/clothing/knights_vr.dmi' + hoodtype = /obj/item/clothing/head/hood/galahad + armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 2 + action_button_name = "Toggle Knight Headgear" + +/obj/item/clothing/suit/storage/hooded/knight/galahad + name = "crusader's armor" + desc = "ye olde knight, risen again." + icon_state = "galahad" + hoodtype = /obj/item/clothing/head/hood/galahad + +/obj/item/clothing/suit/storage/hooded/knight/lancelot + name = "crusader's armor" + desc = "ye olde knight, risen again." + icon_state = "lancelot" + hoodtype = /obj/item/clothing/head/hood/lancelot + +/obj/item/clothing/suit/storage/hooded/knight/robin + name = "crusader's armor" + desc = "ye olde knight, risen again. This one seems slightly faster than the rest, but weaker." + icon_state = "robin" + hoodtype = /obj/item/clothing/head/hood/robin + armor = list(melee = 70, bullet = 40, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) + slowdown = -1 + siemens_coefficient = 3 + +// Costume Knight Gear Here +/obj/item/clothing/suit/storage/hooded/knight_costume + name = "crusader's costume armor" + desc = "ye olde knight, risen again." + icon_state = "galahad" + icon = 'icons/obj/clothing/knights_vr.dmi' + icon_override = 'icons/obj/clothing/knights_vr.dmi' + hoodtype = /obj/item/clothing/head/hood/galahad_costume + action_button_name = "Toggle Knight Headgear" + +/obj/item/clothing/suit/storage/hooded/knight_costume/galahad + icon_state = "galahad" + hoodtype = /obj/item/clothing/head/hood/galahad_costume + +/obj/item/clothing/suit/storage/hooded/knight_costume/lancelot + icon_state = "lancelot" + hoodtype = /obj/item/clothing/head/hood/lancelot_costume + +/obj/item/clothing/suit/storage/hooded/knight_costume/robin + name = "crusader's armor" + desc = "ye olde knight, risen again. This one seems slightly faster than the rest, but weaker." + icon_state = "robin" + hoodtype = /obj/item/clothing/head/hood/robin_costume \ No newline at end of file diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 49f5562835..5d5f168096 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -21,15 +21,15 @@ //Captain /obj/item/clothing/suit/captunic - name = "colony director's parade tunic" - desc = "Worn by a Colony Director to show their class." + name = "site manager's parade tunic" + desc = "Worn by a Site Manager to show their class." icon_state = "captunic" body_parts_covered = UPPER_TORSO|ARMS flags_inv = HIDEJUMPSUIT|HIDETIE|HIDEHOLSTER /obj/item/clothing/suit/captunic/capjacket - name = "colony director's uniform jacket" - desc = "A less formal jacket for everyday Colony Director use." + name = "site manager's uniform jacket" + desc = "A less formal jacket for everyday Site Manager use." icon_state = "capjacket" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDEHOLSTER diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index aabdf73fb4..7469243af4 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -16,6 +16,8 @@ var/mob/living/carbon/human/wearer = null // To check if the wearer changes, so species spritesheets change properly. var/list/on_rolled = list() // Used when jumpsuit sleevels are rolled ("rolled" entry) or it's rolled down ("down"). Set to "none" to hide in those states. sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/ties.dmi') //Teshari can into webbing, too! + drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' /obj/item/clothing/accessory/Destroy() on_removed() @@ -237,6 +239,8 @@ desc = "A bronze medal." icon_state = "bronze" slot = ACCESSORY_SLOT_MEDAL + drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' /obj/item/clothing/accessory/medal/conduct name = "distinguished conduct medal" diff --git a/code/modules/clothing/under/accessories/badges.dm b/code/modules/clothing/under/accessories/badges.dm index 085279c424..e6a0a787a9 100644 --- a/code/modules/clothing/under/accessories/badges.dm +++ b/code/modules/clothing/under/accessories/badges.dm @@ -13,6 +13,9 @@ var/stored_name var/badge_string = "Corporate Security" + + drop_sound = 'sound/items/drop/ring.ogg' + pickup_sound = 'sound/items/pickup/ring.ogg' /obj/item/clothing/accessory/badge/old name = "faded badge" diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index 0ef50ce43a..e9f55de97c 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -174,8 +174,8 @@ item_state = "hoscloak" /obj/item/clothing/accessory/poncho/roles/cloak/captain - name = "colony director's cloak" - desc = "An elaborate cloak meant to be worn by the colony director." + name = "site manager's cloak" + desc = "An elaborate cloak meant to be worn by the site manager." icon_state = "capcloak" item_state = "capcloak" diff --git a/code/modules/clothing/under/accessories/lockets.dm b/code/modules/clothing/under/accessories/lockets.dm index 153df0d584..dcc775d878 100644 --- a/code/modules/clothing/under/accessories/lockets.dm +++ b/code/modules/clothing/under/accessories/lockets.dm @@ -2,6 +2,8 @@ name = "silver locket" desc = "A small locket of high-quality metal." icon_state = "locket" + drop_sound = 'sound/items/drop/ring.ogg' + pickup_sound = 'sound/items/pickup/ring.ogg' w_class = ITEMSIZE_SMALL slot_flags = SLOT_MASK | SLOT_TIE slot = ACCESSORY_SLOT_DECOR diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index 0a8f3d3c65..c675c1b68c 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -13,8 +13,8 @@ item_state_slots = list(slot_r_hand_str = "ba_suit", slot_l_hand_str = "ba_suit") /obj/item/clothing/under/rank/captain //Alright, technically not a 'civilian' but its better then giving a .dm file for a single define. - desc = "It's a blue jumpsuit with some gold markings denoting the rank of \"Colony Director\"." - name = "colony director's jumpsuit" + desc = "It's a blue jumpsuit with some gold markings denoting the rank of \"Site Manager\"." + name = "site manager's jumpsuit" icon_state = "captain" rolled_sleeves = 0 diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 3cc22185d4..32816339d1 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -169,13 +169,13 @@ icon_state = "gentlesuit_skirt" /obj/item/clothing/under/gimmick/rank/captain/suit - name = "colony director's suit" + name = "site manager's suit" desc = "A green suit and yellow necktie. Exemplifies authority." icon_state = "green_suit" item_state_slots = list(slot_r_hand_str = "centcom", slot_l_hand_str = "centcom") /obj/item/clothing/under/gimmick/rank/captain/suit/skirt - name = "colony director's skirt suit" + name = "site manager's skirt suit" icon_state = "green_suit_skirt" /obj/item/clothing/under/gimmick/rank/head_of_personnel/suit @@ -401,8 +401,8 @@ item_state_slots = list(slot_r_hand_str = "dress_white", slot_l_hand_str = "dress_white") /obj/item/clothing/under/dress/dress_cap - name = "colony director's dress uniform" - desc = "Feminine fashion for the style conscious Colony Director." + name = "site manager's dress uniform" + desc = "Feminine fashion for the style conscious Site Manager." icon_state = "dress_cap" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS @@ -620,8 +620,8 @@ Uniforms and such body_parts_covered = UPPER_TORSO|LOWER_TORSO /obj/item/clothing/under/captainformal - name = "colony director's formal uniform" - desc = "A Colony Director's formal-wear, for special occasions." + name = "site manager's formal uniform" + desc = "A Site Manager's formal-wear, for special occasions." icon_state = "captain_formal" item_state_slots = list(slot_r_hand_str = "lawyer_blue", slot_l_hand_str = "lawyer_blue") diff --git a/code/modules/clothing/under/miscellaneous_vr.dm b/code/modules/clothing/under/miscellaneous_vr.dm index c3e75e069c..727e13bee6 100644 --- a/code/modules/clothing/under/miscellaneous_vr.dm +++ b/code/modules/clothing/under/miscellaneous_vr.dm @@ -9,6 +9,7 @@ icon = 'icons/obj/card.dmi' icon_state = "guest" body_parts_covered = 0 + equip_sound = null sprite_sheets = list() diff --git a/code/modules/detectivework/tools/crimekit.dm b/code/modules/detectivework/tools/crimekit.dm index 8d4e3cf8e6..395aca8b49 100644 --- a/code/modules/detectivework/tools/crimekit.dm +++ b/code/modules/detectivework/tools/crimekit.dm @@ -5,6 +5,8 @@ icon = 'icons/obj/forensics.dmi' icon_state = "case" storage_slots = 14 + drop_sound = 'sound/items/drop/toolbox.ogg' + pickup_sound = 'sound/items/pickup/toolbox.ogg' /obj/item/weapon/storage/briefcase/crimekit/New() ..() diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index dd22e7c22e..97140e6f29 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -25,7 +25,8 @@ can_be_placed_into = null flags = OPENCONTAINER | NOBLUDGEON unacidable = 0 - drop_sound = 'sound/items/drop/clothing.ogg' + drop_sound = 'sound/items/drop/cloth.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' var/on_fire = 0 var/burn_time = 20 //if the rag burns for too long it turns to ashes diff --git a/code/modules/detectivework/tools/swabs.dm b/code/modules/detectivework/tools/swabs.dm index 5a83dc642a..f74154756b 100644 --- a/code/modules/detectivework/tools/swabs.dm +++ b/code/modules/detectivework/tools/swabs.dm @@ -5,6 +5,8 @@ var/gsr = 0 var/list/dna var/used + drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/weapon/forensics/swab/proc/is_used() return used diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index 37979f96c5..4c1890e78a 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -35,7 +35,7 @@ T.amount = starting_funds if(!source_db) //set a random date, time and location some time over the past few decades - T.date = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 25[rand(10,56)]" + T.date = "[num2text(rand(1,28))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 23[rand(12,19)]" // VOREStation Edit: lore-compliant dates T.time = "[rand(0,24)]:[rand(11,59)]" T.source_terminal = "NTGalaxyNet Terminal #[rand(111,1111)]" diff --git a/code/modules/economy/cash.dm b/code/modules/economy/cash.dm index 88858f7a70..3d4d44d918 100644 --- a/code/modules/economy/cash.dm +++ b/code/modules/economy/cash.dm @@ -16,6 +16,7 @@ access = access_crate_cash var/worth = 0 drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' /obj/item/weapon/spacecash/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/spacecash)) @@ -152,6 +153,7 @@ proc/spawn_money(var/sum, spawnloc, mob/living/carbon/human/human_user as mob) icon_state = "efundcard" desc = "A card that holds an amount of money." drop_sound = 'sound/items/drop/card.ogg' + pickup_sound = 'sound/items/pickup/card.ogg' var/owner_name = "" //So the ATM can set it so the EFTPOS can put a valid name on transactions. attack_self() return //Don't act attackby() return //like actual diff --git a/code/modules/events/atmos_leak.dm b/code/modules/events/atmos_leak.dm index 6823adee96..7d08a2e196 100644 --- a/code/modules/events/atmos_leak.dm +++ b/code/modules/events/atmos_leak.dm @@ -1,5 +1,5 @@ // -// This event causes a gas leak of phoron, sleeping_agent, or carbon_dioxide in a random unoccupied area. +// This event causes a gas leak of phoron, nitrous_oxide, or carbon_dioxide in a random unoccupied area. // One wonders, where did the gas come from? Who knows! Its SPACE! But if you want something a touch // more "explainable" then check out the canister_leak event instead. // @@ -19,7 +19,7 @@ // Decide which area will be targeted! /datum/event/atmos_leak/setup() - var/gas_choices = list("carbon_dioxide", "sleeping_agent") // Annoying + var/gas_choices = list("carbon_dioxide", "nitrous_oxide") // Annoying if(severity >= EVENT_LEVEL_MODERATE) gas_choices += "phoron" // Dangerous // if(severity >= EVENT_LEVEL_MAJOR) diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 3003654078..e351c7b623 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -98,7 +98,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is //var/dowhat = pick("STOP THIS", "SUPPORT THIS", "CONSTANTLY INFORM THE CREW OF THIS", "IGNORE THIS", "FEAR THIS") var/aimust = pick("LIE", "RHYME", "RESPOND TO EVERY QUESTION WITH A QUESTION", "BE POLITE", "CLOWN", "BE HAPPY", "SPEAK IN SEXUAL INNUENDOS", "TALK LIKE A PIRATE", "QUESTION AUTHORITY", "SHOUT", "BE DISTRACTED", "HEY LISTEN", "MUMBLE", "SPEAK IN HAIKU") var/define = pick("ABSENCE OF CYBORG HUGS", "LACK OF BEATINGS", "UNBOLTED AIRLOCKS", "BOLTED AIRLOCKS", "IMPROPERLY WORDED SENTENCES", "POOR SENTENCE STRUCTURE", "BRIG TIME", "NOT REPLACING EVERY SECOND WORD WITH HONK", "HONKING", "PRESENCE OF LIGHTS", "LACK OF BEER", "WEARING CLOTHING", "NOT SAYING HELLO WHEN YOU SPEAK", "ANSWERING REQUESTS NOT EXPRESSED IN IAMBIC PENTAMETER", "A SMALL ISLAND OFF THE COAST OF PORTUGAL", "ANSWERING REQUESTS THAT WERE MADE WHILE CLOTHED") - var/target = pick("a traitor", "a mercenary", "a changeling", "a wizard", "the head of a revolution", "Soviet spy", "a good person", "a dwarf", "an elf", "a fairy princess", "the colony director", "Beepsky", "God", "a pirate", "a gryphon", "a chryssalid") + var/target = pick("a traitor", "a mercenary", "a changeling", "a wizard", "the head of a revolution", "Soviet spy", "a good person", "a dwarf", "an elf", "a fairy princess", "the site manager", "Beepsky", "God", "a pirate", "a gryphon", "a chryssalid") var/require = pick("ADDITIONAL PYLONS", "MORE VESPENE GAS", "MORE MINERALS", "THE ULTIMATE CUP OF COFFEE", "HIGH YIELD EXPLOSIVES", "THE CLOWN", "THE VACUUM OF SPACE", "IMMORTALITY", "SAINTHOOD", "ART", "VEGETABLES", "FAT PEOPLE", "MORE LAWS", "MORE DAKKA", "HERESY", "CORPSES", "TRAITORS", "MONKEYS", "AN ARCADE", "PLENTY OF GOLD", "FIVE TEENAGERS WITH ATTITUDE") var/allergy = pick("cotton", "uniforms", "acid", "oxygen", "human contact", "cyborg contact", "medicine", "floors") var/allergysev = pick("deathly", "mildly", "severely", "contagiously") @@ -133,9 +133,9 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is M.add_ion_law("HUMANS NEED TO EAT [what2pref] [what2] TO SURVIVE") if(5) to_chat(M, "
") - to_chat(M, "THE COLONY DIRECTOR, HOP AND HOS ARE [who2]...LAWS UPDATED") + to_chat(M, "THE SITE MANAGER, HOP AND HOS ARE [who2]...LAWS UPDATED") to_chat(M, "
") - M.add_ion_law("THE COLONY DIRECTOR, HOP AND HOS ARE [who2]") + M.add_ion_law("THE SITE MANAGER, HOP AND HOS ARE [who2]") if(6) to_chat(M, "
") to_chat(M, "THE STATION IS BUILT FOR [who2]...LAWS UPDATED") diff --git a/code/modules/examine/descriptions/food.dm b/code/modules/examine/descriptions/food.dm deleted file mode 100644 index c5f3e80728..0000000000 --- a/code/modules/examine/descriptions/food.dm +++ /dev/null @@ -1,50 +0,0 @@ -/obj/item/weapon/reagent_containers/food/snacks/candy - description_fluff = "The Candy Bar is a copylefted recipe designed by information freedom activists to bring the delicious taste of nougat to the masses. It's cheap, familiar, and easy to synthesize, so most food vendors stock it." - -/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar - description_fluff = "The SWOLEMAX protien bar is the flagship product of SWOLEMAX, a health foods corporation recently independent of Centauri Provisions. It tastes like a brick of ashes." - -/obj/item/weapon/reagent_containers/food/snacks/candy_corn - description_fluff = "Nobody knows why Nanotrasen keeps making these waxy pieces of sugar and bone glue, but a handful of people swear by them. Purportedly popular with Skrell children, dubiously enough." - -/obj/item/weapon/reagent_containers/food/snacks/chips - description_fluff = "Actual potatos haven't been used in potato chips for centuries. They're mostly a denatured nutrient slurry pressed into a chip-shaped mold and salted. Still tastes the same." - -/obj/item/weapon/reagent_containers/food/snacks/donut - description_fluff = "These donuts claim to be made fresh daily in a boutique bakery in New Reykjavik and delivered to Nanotrasen's hardworking asset protection crew. They're probably synthesized." - -/obj/item/weapon/reagent_containers/food/snacks/donkpocket - description_fluff = "DONKpockets were originally a Nanotrasen product, an attempt to break into the food market controlled by Centauri Provisions. Somehow, Centauri wound up with the rights to the DONK brand, ending Nanotrasen's ambitions. They taste pretty okay." - -/obj/item/weapon/reagent_containers/food/snacks/pie - description_fluff = "One of the more esoteric terms of the Nanotrasen-Centauri Noncompetition Agreement of 2545 was a requirement that Nanotrasen stock these pies on all their stations. They're calibrated for commedic value, not taste." - -/obj/item/weapon/reagent_containers/food/snacks/sosjerky - description_fluff = "Space Cows, here, being an affectionate name given by early colonists to the massive food synthesizers used to sustain independent outposts before the dominance of hydroponics. Tastes like cardboard rubbed in meat seasoning." - -/obj/item/weapon/reagent_containers/food/snacks/no_raisin - description_fluff = "Originally Raisin Blend no. 4, 4noraisins obtained their current name in the Skadi Positronic Exclusion Crisis of 2442, where they were rebranded as part of the protests." //the exclusion crisis, presumably, involved positronic immigration being banned for no raisin - -/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie - description_fluff = "Space Twinkies, a modification of a flagship product of one of Centauri Provision's predecessor corporations, are designed to withstand vacuum, radiation, dehydration, and long periods of acceleration without losing their shape or taste. They're not great, but they have earned their names (and enormous revenue for their parent company)." - -/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers - description_fluff = "Cheesie Honkers, a previously niche line of cheese puffs from a subsidiary of a subsidiary of Centauri Provisions, rose to household-name status when their tell-tale orange dust was used as evidence to convict notorious positronic serial killer Etoid in 2404." - -/obj/item/weapon/reagent_containers/food/snacks/syndicake - description_fluff = "Due to ongoing litigation concerning the business practices of the Cakemakers' Syndicate, access to this product has been removed from all Centauri and Getmore vending machines. This is a shame, because Syndi-Cakes are generally regarded as the most appetizing thing in them." - -/obj/item/weapon/reagent_containers/food/snacks/twobread - description_fluff = "The most popular recipe from the Morpheus Cyberkinetics cookbook 'Calories for Organics'" - -/obj/item/weapon/reagent_containers/food/snacks/liquidfood - description_fluff = "A survival food commonly packed onto short-distance bluespace shuttles and similar vessels. Tastes like chalk, but is packed full of nutrients and will keep you alive." - -/obj/item/weapon/reagent_containers/food/snacks/tastybread - description_fluff = "This is the product that brought Centauri Provisions into the limelight. A product of the earliest extrasolar colony of Heaven, the Bread Tube, while bland, contains all the nutrients a spacer needs to get through the day and is decidedly edible when compared to some of its competitors." - -/obj/item/weapon/reagent_containers/food/snacks/skrellsnacks - description_fluff = "A jerky product made of Go'moa mushrooms native to the Skrellian homeworld of Qerr'balak. SkrellSnaks are actually a product of Natuna, designed to welcome Ue-Katish refugees to their colony. The brand was recreated by Centauri Provisions after Natuna and SolGov broke off diplomatic relations." - -/obj/item/weapon/reagent_containers/food/snacks/unajerky - description_fluff = "Removed from Getmore vendors pending approval from the SolGov Nutrition Council, Sissalik Jerky remains a popular snack for Unathi immigrants and daredevils looking for a meaty, spicy treat that makes Scaredy's look like tofu." diff --git a/code/modules/examine/descriptions/smokeables.dm b/code/modules/examine/descriptions/smokeables.dm deleted file mode 100644 index ddec465368..0000000000 --- a/code/modules/examine/descriptions/smokeables.dm +++ /dev/null @@ -1,39 +0,0 @@ -/obj/item/weapon/storage/fancy/cigarettes - description_fluff = "The Trans-Stellar Duty-Free Cigarette Company was created as an imprint of NanoTrasen. They are the most boring, tasteless, dry cigarettes on the market, but due to how generic they are, they are still the most well-known and widespread cigarettes in the universe." - -/obj/item/weapon/storage/fancy/cigarettes/dromedaryco - description_fluff = "DromedaryCo is one of the oldest companies that produces cigarettes. Being a company that has changed hands and names several times through the years, their cigarettes are now very different from the original, and old-timers tend to complain about the quality of their current product. While their profits have been dwindling over the past few years due to marketing schemes deemed 'unethical', they still remain on the forefront of the smokeable industry." - -/obj/item/weapon/storage/fancy/cigarettes/killthroat - description_fluff = "AcmeCo, a subsidiary of Xion Manufacturing Group, is known for their signature high-tar cigarettes. Some accuse the cigarettes of having harmful things in them beyond tar, but Xion officials refuse to comment on the issue." - -/obj/item/weapon/storage/fancy/cigarettes/luckystars - description_fluff = "Lucky Stars were created on Venus by a researcher seeking to make a good quality cigarette from pod-based tobacco plants. The researcher only managed to make these, but made quite a profit off of them nonetheless." - -/obj/item/weapon/storage/fancy/cigarettes/jerichos - description_fluff = "Stealth Assault Enterprises ex-contractors once decided to make a cigarette that was easy to light and had a waterproof case, specifically tailored for soldiers. They created Jerichos. Jerichos are known for their hickory smoke and warm feeling in your lungs. They are loved by soldiers and people employed in para-military outfits." - -/obj/item/weapon/storage/fancy/cigarettes/menthols - description_fluff = "The Temperamento Menthol Company is a large cigarette company based in Mars. They have been around since the very dawn of human colonization and have remained a favorite for those seeking a more numbing cigarette.
\ -
\ - This is a pack of Temperamento Menthols, the main product of the company. They taste like menthol, surprisingly enough." - -/obj/item/weapon/storage/fancy/cigarettes/carcinomas - description_fluff = "The CarcinoCo was originally destined to fail, as the company blatantly advertized themselves as creating the 'most cancerous cigarette'. The cigarettes became a hit among those rich enough to afford regular lung replacements." - -/obj/item/weapon/storage/fancy/cigarettes/professionals - description_fluff = "Decades ago, probably before you were born, Gilthari Exports created the Professional 120s. They wanted to make a fancy cigarette that would be considered a luxury. Nowadays, they are generally concidered an emblem of the nouveau riche and the elderly. They are, however, very high-quality and made from the very best Solar tobacco." - -/obj/item/clothing/mask/smokable/cigarette/cigar - description_fluff = "While the label does say that this is a 'premium cigar', it really cannot match other types of cigars on the market. Is it a quality cigarette? Perhaps. Was it hand-made with care? No. This is what differentiates between quality products that Gilthari puts out and NanoTrasen 'premium' cigars like this one." - -/obj/item/clothing/mask/smokable/cigarette/cigar/cohiba - description_fluff = "Cohiba has been a popular cigar company for centuries. They are still based out of Cuba and refuse to expand and therefore have a very limited quantity, making their cigars coveted all through known space. Robusto is one of their most popular shapes of cigars." - -/obj/item/clothing/mask/smokable/cigarette/cigar/havana - description_fluff = "'Havanian' is an umbrella term for any cigar made in the typical handmade style of Cuba. This particular cigar is from Gilthari's cigar manufacturers. While this way of making quality cigars has become slightly bastardized over the years, overall quality has remained relatively the same, even if there is a large quantity of 'Havanian' cigars." - -/obj/item/clothing/mask/smokable/pipe - description_fluff = "ClassiCo Accessories and Haberdashers is a widespread company originating out of Mars. They seek to create quality goods to give men a more 'classy' look. Most of their items are high-end and expensive, but they plege to back their prices up with quality.
\ -
\ - This pipe is a ClassiCo pipe. It is made out of fine, stained cherry wood." diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm index 911931eda3..0ed003be7d 100644 --- a/code/modules/flufftext/Dreaming.dm +++ b/code/modules/flufftext/Dreaming.dm @@ -1,17 +1,21 @@ var/list/dreams = list( - "an ID card","a bottle","a familiar face","a crewmember","a toolbox","a security officer","the Colony Director", + "an ID card","a bottle","a familiar face","a crewmember","a toolbox","a Security Officer","the Site Manager", "voices from all around","deep space","a doctor","the engine","a traitor","an ally","darkness", "light","a scientist","a monkey","a catastrophe","a loved one","a gun","warmth","freezing","the sun", "a hat","the Luna","a ruined station","a planet","phoron","air","the medical bay","the bridge","blinking lights", "a blue light","an abandoned laboratory","NanoTrasen","mercenaries","blood","healing","power","respect", "riches","space","a crash","happiness","pride","a fall","water","flames","ice","melons","flying","the eggs","money", - "the head of personnel","the head of security","a chief engineer","a research director","a chief medical officer", - "the detective","the warden","a member of the internal affairs","a station engineer","the janitor","atmospheric technician", - "the quartermaster","a cargo technician","the botanist","a shaft miner","the psychologist","the chemist","the geneticist", - "the virologist","the roboticist","the chef","the bartender","the chaplain","the librarian","a mouse","an ert member", - "a beach","the holodeck","a smokey room","a voice","the cold","a mouse","an operating table","the bar","the rain","a skrell", - "an unathi","a tajaran","the ai core","the mining station","the research station","a beaker of strange liquid", + "the Head of Personnel","the Head of Security","the Chief Engineer","the Research Director","the Chief Medical Officer", + "the Detective","the Warden","an Internal Affairs Agent","a Station Engineer","the Janitor","the Atmospheric Technician", + "the Quartermaster","a Cargo Technician","the Botanist","a Shaft Miner","the Psychologist","the Chemist","a Geneticist", + "the Virologist","the Roboticist","the Chef","the Bartender","the Chaplain","the Librarian","a mouse","an ERT member", + "a beach","the holodeck","a smoky room","a voice","the cold","a mouse","an operating table","the bar","the rain","a Skrell", + "an Unathi","a Tajaran","the Station Intelligence core","the mining station","the research station","a beaker of strange liquid", + "a Teshari", "a Diona nymph","the supermatter","Major Bill","a Morpheus ship with a ridiculous name","the Exodus","a star", + "a Dionaea gestalt","the chapel","a distant scream","endless chittering noises","glowing eyes in the shadows","an empty glass", + "a disoriented Promethean","towers of plastic","a Gygax","a synthetic","a Man-Machine Interface","maintenance drones", + "unintelligible writings","a Fleet ship", //VOREStation Additions after this "slimey surroundings","a sexy squirrel","licking their lips","a gaping maw","an unlikely predator","sinking inside", "vulpine assets","more dakka","churning guts","pools of fluid","an exceptional grip","mawing in faces","gaping throat", diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index d4c41e0642..51cf85b6a2 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -112,7 +112,7 @@ mob/living/carbon/proc/handle_hallucinations() //Strange audio //to_chat(src, "Strange Audio") switch(rand(1,12)) - if(1) src << 'sound/machines/airlock.ogg' + if(1) src << 'sound/machines/door/old_airlock.ogg' if(2) if(prob(50))src << 'sound/effects/Explosion1.ogg' else src << 'sound/effects/Explosion2.ogg' @@ -121,7 +121,7 @@ mob/living/carbon/proc/handle_hallucinations() if(5) src << 'sound/effects/Glassbr2.ogg' if(6) src << 'sound/effects/Glassbr3.ogg' if(7) src << 'sound/machines/twobeep.ogg' - if(8) src << 'sound/machines/windowdoor.ogg' + if(8) src << 'sound/machines/door/windowdoor.ogg' if(9) //To make it more realistic, I added two gunshots (enough to kill) src << 'sound/weapons/Gunshot1.ogg' @@ -189,7 +189,7 @@ mob/living/carbon/proc/handle_hallucinations() var/possible_txt = list("Launch Escape Pods","Self-Destruct Sequence","\[Swipe ID\]","De-Monkify",\ "Reticulate Splines","Plasma","Open Valve","Lockdown","Nerf Airflow","Kill Traitor","Nihilism",\ - "OBJECTION!","Arrest Stephen Bowman","Engage Anti-Trenna Defenses","Increase Colony Director IQ","Retrieve Arms",\ + "OBJECTION!","Arrest Stephen Bowman","Engage Anti-Trenna Defenses","Increase Site Manager IQ","Retrieve Arms",\ "Play Charades","Oxygen","Inject BeAcOs","Ninja Lizards","Limit Break","Build Sentry") if(mid_txts) diff --git a/code/modules/food/food.dm b/code/modules/food/food.dm index c33389ad15..f34db732e7 100644 --- a/code/modules/food/food.dm +++ b/code/modules/food/food.dm @@ -9,6 +9,7 @@ volume = 50 //Sets the default container amount for all food items. var/filling_color = "#FFFFFF" //Used by sandwiches. drop_sound = 'sound/items/drop/food.ogg' + pickup_sound = 'sound/items/pickup/food.ogg' /obj/item/weapon/reagent_containers/food/Initialize() . = ..() diff --git a/code/modules/food/food/cans.dm b/code/modules/food/food/cans.dm index f4ade46de4..b876a0e1d1 100644 --- a/code/modules/food/food/cans.dm +++ b/code/modules/food/food/cans.dm @@ -3,6 +3,7 @@ amount_per_transfer_from_this = 5 flags = 0 //starts closed drop_sound = 'sound/items/drop/soda.ogg' + pickup_sound = 'sound/items/pickup/soda.ogg' //DRINKS @@ -22,7 +23,8 @@ desc = "Ice cold and utterly tasteless, this 'all-natural' mineral water comes 'fresh' from one of NanoTrasen's heavy-duty bottling plants in the Sivian poles." icon_state = "waterbottle" center_of_mass = list("x"=16, "y"=8) - drop_sound = 'sound/items/drop/food.ogg' + drop_sound = 'sound/items/drop/disk.ogg' + pickup_sound = 'sound/items/pickup/disk.ogg' /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle/Initialize() . = ..() @@ -64,7 +66,7 @@ name = "\improper Diet Dr. Gibb" desc = "A delicious mixture of 42 different flavors, one of which is water." description_fluff = "Following a 2490 lawsuit and a spate of deaths, Gilthari Exports reminds customers that the 'Dr.' legally stands for 'Drink'." - icon_state = "diet_dr_gibb" + icon_state = "dr_gibb_diet" center_of_mass = list("x"=16, "y"=8) /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb_diet/Initialize() diff --git a/code/modules/food/food/drinks.dm b/code/modules/food/food/drinks.dm index e13d53cac8..044bd74491 100644 --- a/code/modules/food/food/drinks.dm +++ b/code/modules/food/food/drinks.dm @@ -6,6 +6,7 @@ desc = "yummy" icon = 'icons/obj/drinks.dmi' drop_sound = 'sound/items/drop/bottle.ogg' + pickup_sound = 'sound/items/pickup/bottle.ogg' icon_state = null flags = OPENCONTAINER amount_per_transfer_from_this = 5 @@ -135,7 +136,8 @@ icon_state = "milk" item_state = "carton" center_of_mass = list("x"=16, "y"=9) - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/weapon/reagent_containers/food/drinks/milk/Initialize() . = ..() @@ -148,7 +150,8 @@ icon_state = "soymilk" item_state = "carton" center_of_mass = list("x"=16, "y"=9) - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/weapon/reagent_containers/food/drinks/soymilk/Initialize() . = ..() @@ -162,7 +165,8 @@ icon_state = "mini-milk" item_state = "carton" center_of_mass = list("x"=16, "y"=9) - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/weapon/reagent_containers/food/drinks/smallmilk/Initialize() . = ..() @@ -176,7 +180,8 @@ icon_state = "mini-milk_choco" item_state = "carton" center_of_mass = list("x"=16, "y"=9) - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk/Initialize() . = ..() @@ -190,6 +195,7 @@ trash = /obj/item/trash/coffee center_of_mass = list("x"=15, "y"=10) drop_sound = 'sound/items/drop/papercup.ogg' + pickup_sound = 'sound/items/pickup/papercup.ogg' /obj/item/weapon/reagent_containers/food/drinks/coffee/Initialize() . = ..() @@ -204,6 +210,7 @@ trash = /obj/item/trash/coffee center_of_mass = list("x"=16, "y"=14) drop_sound = 'sound/items/drop/papercup.ogg' + pickup_sound = 'sound/items/pickup/papercup.ogg' /obj/item/weapon/reagent_containers/food/drinks/tea/Initialize() . = ..() @@ -347,8 +354,8 @@ ..() /obj/item/weapon/reagent_containers/food/drinks/flask - name = "\improper Colony Director's flask" - desc = "A metal flask belonging to the Colony Director" + name = "\improper Site Manager's flask" + desc = "A metal flask belonging to the Site Manager" icon_state = "flask" volume = 60 center_of_mass = list("x"=17, "y"=7) diff --git a/code/modules/food/food/drinks/bottle.dm b/code/modules/food/food/drinks/bottle.dm index c79f9bd36d..b5d72d733f 100644 --- a/code/modules/food/food/drinks/bottle.dm +++ b/code/modules/food/food/drinks/bottle.dm @@ -522,7 +522,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/Initialize() . = ..() - reagents.add_reagent("beer", 30) + reagents.add_reagent("beer", 50) /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/silverdragon name = "Silver Dragon pilsner" @@ -544,7 +544,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/litebeer/Initialize() . = ..() - reagents.add_reagent("litebeer", 30) + reagents.add_reagent("litebeer", 50) /obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider name = "Crisp's Cider" @@ -554,7 +554,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider/Initialize() . = ..() - reagents.add_reagent("cider", 30) + reagents.add_reagent("cider", 50) /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale @@ -566,7 +566,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/Initialize() . = ..() - reagents.add_reagent("ale", 30) + reagents.add_reagent("ale", 50) /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/hushedwhisper name = "Hushed Whisper IPA" @@ -576,7 +576,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/hushedwhisper/Initialize() . = ..() - reagents.add_reagent("ale", 30) + reagents.add_reagent("ale", 50) /obj/item/weapon/reagent_containers/food/drinks/bottle/sake name = "Mono-No-Aware Luxury Sake" diff --git a/code/modules/food/food/drinks/drinkingglass.dm b/code/modules/food/food/drinks/drinkingglass.dm index 7324dc8ad8..260c4a7ae6 100644 --- a/code/modules/food/food/drinks/drinkingglass.dm +++ b/code/modules/food/food/drinks/drinkingglass.dm @@ -8,6 +8,8 @@ volume = 30 unacidable = 1 //glass center_of_mass = list("x"=16, "y"=10) + drop_sound = 'sound/items/drop/drinkglass.ogg' + pickup_sound = 'sound/items/pickup/drinkglass.ogg' matter = list("glass" = 500) on_reagent_change() diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index ed3f8a37c5..93e0b2c5ab 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -342,7 +342,7 @@ /obj/item/weapon/reagent_containers/food/snacks/candy/gummy name = "\improper AlliCo Gummies" desc = "Somehow, there's never enough cola bottles." - description_fluff = "AlliCo's grab-bags of gummy candies come in over a thousand novelty shapes and dozens of flavours. Shoes, astronauts, bunny rabbits and singularities all made an appearance." + description_fluff = "AlliCo's grab-bags of gummy candies come in over a thousand novelty shapes and dozens of flavours. Shoes, astronauts, bunny rabbits and singularities all make an appearance." icon = 'icons/obj/food_snacks.dmi' icon_state = "candy_gums" trash = /obj/item/trash/candy/gums @@ -369,6 +369,7 @@ /obj/item/weapon/reagent_containers/food/snacks/candy_corn name = "candy corn" desc = "It's a handful of candy corn. Cannot be stored in a detective's hat, alas." + description_fluff = "Nobody knows why Nanotrasen keeps making these waxy pieces of sugar and bone glue, but a handful of people swear by them. Purportedly popular with Skrell children, dubiously enough." icon_state = "candy_corn" filling_color = "#FFFCB0" center_of_mass = list("x"=14, "y"=10) @@ -383,7 +384,7 @@ /obj/item/weapon/reagent_containers/food/snacks/chips name = "\improper What-The-Crisps" desc = "Commander Riker's What-The-Crisps, lightly salted." - description_fluff = "What-The-Crisps' retro-styled starship commander has been a marketing staple for almost 200 years." + description_fluff = "What-The-Crisps' retro-styled starship commander has been a marketing staple for almost 200 years. Actual potatos haven't been used in potato chips for centuries. They're mostly a denatured nutrient slurry pressed into a chip-shaped mold and salted. Still tastes the same." icon = 'icons/obj/food_snacks.dmi' icon_state = "chips" trash = /obj/item/trash/chips @@ -446,7 +447,7 @@ icon_state = "fruitbar" trash = /obj/item/trash/candy/fruitbar nutriment_amt = 9 - nutriment_desc = list("apricot" = 2, "sugar" = 2, "dates" = 2, "cranberry" = 2, "apple = 2") + nutriment_desc = list("apricot" = 2, "sugar" = 2, "dates" = 2, "cranberry" = 2, "apple" = 2) /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar/Initialize() . = ..() @@ -510,6 +511,7 @@ /obj/item/weapon/reagent_containers/food/snacks/donut name = "donut" desc = "Goes great with Robust Coffee." + description_fluff = "These donuts claim to be made fresh daily in a boutique bakery in New Reykjavik and delivered to Nanotrasen's hardworking asset protection crew. They're probably synthesized." icon_state = "donut1" filling_color = "#D9C386" var/overlay_state = "box-donut1" @@ -1146,6 +1148,7 @@ /obj/item/weapon/reagent_containers/food/snacks/donkpocket name = "Donk-pocket" desc = "The food of choice for the seasoned traitor." + description_fluff = "DONKpockets were originally a Nanotrasen product, an attempt to break into the food market controlled by Centauri Provisions. Somehow, Centauri wound up with the rights to the DONK brand, ending Nanotrasen's ambitions. They taste pretty okay." icon_state = "donkpocket" filling_color = "#DEDEAB" center_of_mass = list("x"=16, "y"=10) @@ -1381,6 +1384,7 @@ /obj/item/weapon/reagent_containers/food/snacks/pie name = "Banana Cream Pie" desc = "Just like back home, on clown planet! HONK!" + description_fluff = "One of the more esoteric terms of the Nanotrasen-Centauri Noncompetition Agreement of 2545 was a requirement that Nanotrasen stock these pies on all their stations. They're calibrated for comedic value, not taste." icon_state = "pie" trash = /obj/item/trash/plate filling_color = "#FBFFB8" @@ -1663,7 +1667,7 @@ icon = 'icons/obj/food_snacks.dmi' icon_state = "4no_raisins" desc = "Best raisins in the universe. Not sure why." - description_fluff = "The popularity of dried foods across the galaxy is either a direct result of ease of shipping, or a clever marketing ploy by corporations trying to cut back costs. Whatever it is, there must be SOME reason?" + description_fluff = "Originally Raisin Blend no. 4, 4noraisins obtained their current name in the Skadi Positronic Exclusion Crisis of 2442, where they were rebranded as part of the protests. The exclusion crisis, so the story goes, involved positronic immigration being banned for no raisin." trash = /obj/item/trash/raisins filling_color = "#343834" center_of_mass = list("x"=15, "y"=4) @@ -2400,6 +2404,8 @@ center_of_mass = list("x"=16, "y"=5) nutriment_amt = 6 nutriment_desc = list("tomato" = 2, "potato" = 2, "carrot" = 2, "eggplant" = 2, "mushroom" = 2) + drop_sound = 'sound/items/drop/shovel.ogg' + pickup_sound = 'sound/items/pickup/shovel.ogg' /obj/item/weapon/reagent_containers/food/snacks/stew/Initialize() . = ..() @@ -2651,6 +2657,7 @@ /obj/item/weapon/reagent_containers/food/snacks/twobread name = "Two Bread" desc = "It is very bitter and winy." + description_fluff = "The most popular recipe from the Morpheus Cyberkinetics cookbook 'Calories for Organics'" icon_state = "twobread" filling_color = "#DBCC9A" center_of_mass = list("x"=15, "y"=12) @@ -4054,6 +4061,7 @@ /obj/item/weapon/reagent_containers/food/snacks/liquidfood name = "\improper LiquidFood Ration" desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?" + description_fluff = "A survival food commonly packed onto short-distance bluespace shuttles and similar vessels. Tastes like chalk, but is packed full of nutrients and will keep you alive." icon_state = "liquidfood" trash = /obj/item/trash/liquidfood filling_color = "#A8A8A8" @@ -4115,7 +4123,7 @@ /obj/item/weapon/reagent_containers/food/snacks/tastybread name = "bread tube" desc = "Bread in a tube. Chewy...and surprisingly tasty." - description_fluff = "Due to the high-fructose corn syrup content of NanoTrasen's own-brand bread tubes, many jurisdictions classify them as a confectionary." + description_fluff = "This is the product that brought Centauri Provisions into the limelight. A product of the earliest extrasolar colony of Heaven, the Bread Tube, while bland, contains all the nutrients a spacer needs to get through the day and is decidedly edible when compared to some of its competitors. Due to the high-fructose corn syrup content of NanoTrasen's own-brand bread tubes, many jurisdictions classify them as a confectionary." icon = 'icons/obj/food_snacks.dmi' icon_state = "tastybread" trash = /obj/item/trash/tastybread @@ -4131,9 +4139,10 @@ /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks name = "\improper SkrellSnax" desc = "Cured fungus shipped all the way from Qerr'balak, almost like jerky! Almost." - description_fluff = "Despite the packaging, most SkrellSnax sold in Vir are produced using locally-grown fungi in controversial Skrell-owned biodomes on the suface of Sif." + description_fluff = "Despite the packaging, most SkrellSnax sold in Vir are produced using locally-grown, Qerr'Balak-native Go'moa fungi in controversial Skrell-owned biodomes on the suface of Sif. SkrellSnax were originally a product of Natuna, designed to welcome Ue-Katish refugees to their colony. The brand was recreated by Centauri Provisions after Natuna and SolGov broke off diplomatic relations." icon = 'icons/obj/food_snacks.dmi' icon_state = "skrellsnacks" + trash = /obj/item/trash/skrellsnax filling_color = "#A66829" center_of_mass = list("x"=15, "y"=12) nutriment_amt = 10 @@ -4148,7 +4157,7 @@ icon = 'icons/obj/food_snacks.dmi' icon_state = "unathitinred" desc = "An incredibly well made jerky, shipped in all the way from Moghes." - description_fluff = "The exact meat and spices used in the curing of Sissalik Jerky are a well-kept secret, and thought to not exist at all outside of Hegemony space. Many have tried to replicate the flavour, but none have come close, so the brand remains a highly prized import." + description_fluff = "The exact meat and spices used in the curing of Sissalik Jerky are a well-kept secret, and thought to not exist at all outside of Hegemony space. Many have tried to replicate the flavour, but none have come close, so the brand remains a highly prized import. " trash = /obj/item/trash/unajerky filling_color = "#631212" center_of_mass = list("x"=15, "y"=9) diff --git a/code/modules/food/glass/bottle.dm b/code/modules/food/glass/bottle.dm index 7396076892..f372a2facf 100644 --- a/code/modules/food/glass/bottle.dm +++ b/code/modules/food/glass/bottle.dm @@ -11,6 +11,8 @@ possible_transfer_amounts = list(5,10,15,25,30,60) flags = 0 volume = 60 + drop_sound = 'sound/items/drop/bottle.ogg' + pickup_sound = 'sound/items/pickup/bottle.ogg' /obj/item/weapon/reagent_containers/glass/bottle/on_reagent_change() update_icon() diff --git a/code/modules/food/kitchen/cooking_machines/_appliance.dm b/code/modules/food/kitchen/cooking_machines/_appliance.dm index 297dc688f4..780a1502ff 100644 --- a/code/modules/food/kitchen/cooking_machines/_appliance.dm +++ b/code/modules/food/kitchen/cooking_machines/_appliance.dm @@ -480,7 +480,8 @@ CI.container.reagents.trans_to_holder(buffer, CI.container.reagents.total_volume) var/obj/item/weapon/reagent_containers/food/snacks/result = new cook_path(CI.container) - buffer.trans_to(result, buffer.total_volume) + buffer.trans_to_holder(result.reagents, buffer.total_volume) //trans_to doesn't handle food items well, so + //just call trans_to_holder instead //Filling overlay var/image/I = image(result.icon, "[result.icon_state]_filling") diff --git a/code/modules/food/kitchen/cooking_machines/_mixer.dm b/code/modules/food/kitchen/cooking_machines/_mixer.dm index ce17e55d91..e1c3b0d838 100644 --- a/code/modules/food/kitchen/cooking_machines/_mixer.dm +++ b/code/modules/food/kitchen/cooking_machines/_mixer.dm @@ -13,6 +13,7 @@ fundamental differences cooking_coeff = 0.75 // Original value 0.4 active_power_usage = 3000 idle_power_usage = 50 + var/datum/looping_sound/mixer/mixer_loop /obj/machinery/appliance/mixer/examine(var/mob/user) . = ..() @@ -24,6 +25,13 @@ fundamental differences cooking_objs += new /datum/cooking_item(new /obj/item/weapon/reagent_containers/cooking_container(src)) cooking = FALSE selected_option = pick(output_options) + + mixer_loop = new(list(src), FALSE) + +/obj/machinery/appliance/mixer/Destroy() + . = ..() + + QDEL_NULL(mixer_loop) //Mixers cannot-not do combining mode. So the default option is removed from this. A combine target must be chosen /obj/machinery/appliance/mixer/choose_output() @@ -132,8 +140,12 @@ fundamental differences /obj/machinery/appliance/mixer/update_icon() if (!stat) icon_state = on_icon + if(mixer_loop) + mixer_loop.start(src) else icon_state = off_icon + if(mixer_loop) + mixer_loop.stop(src) /obj/machinery/appliance/mixer/process() diff --git a/code/modules/food/kitchen/cooking_machines/candy.dm b/code/modules/food/kitchen/cooking_machines/candy.dm index af63c5759c..d9a30bf8d3 100644 --- a/code/modules/food/kitchen/cooking_machines/candy.dm +++ b/code/modules/food/kitchen/cooking_machines/candy.dm @@ -6,6 +6,7 @@ on_icon = "mixer_on" cook_type = "candied" appliancetype = CANDYMAKER + var/datum/looping_sound/candymaker/candymaker_loop circuit = /obj/item/weapon/circuitboard/candymachine cooking_coeff = 1.0 // Original Value 0.6 @@ -16,6 +17,28 @@ "Jelly" = /obj/item/weapon/reagent_containers/food/snacks/variable/jelly ) +/obj/machinery/appliance/mixer/candy/Initialize() + . = ..() + + candymaker_loop = new(list(src), FALSE) + +/obj/machinery/appliance/mixer/candy/Destroy() + . = ..() + + QDEL_NULL(candymaker_loop) + +/obj/machinery/appliance/mixer/candy/update_icon() + . = ..() + + if(!stat) + icon_state = on_icon + if(candymaker_loop) + candymaker_loop.start(src) + else + icon_state = off_icon + if(candymaker_loop) + candymaker_loop.stop(src) + /obj/machinery/appliance/mixer/candy/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/cooked/product) food_color = get_random_colour(1) . = ..() diff --git a/code/modules/food/kitchen/cooking_machines/cereal.dm b/code/modules/food/kitchen/cooking_machines/cereal.dm index f1f5210cbb..3aa90c05ba 100644 --- a/code/modules/food/kitchen/cooking_machines/cereal.dm +++ b/code/modules/food/kitchen/cooking_machines/cereal.dm @@ -7,12 +7,23 @@ on_icon = "cereal_on" off_icon = "cereal_off" appliancetype = CEREALMAKER + var/datum/looping_sound/cerealmaker/cerealmaker_loop circuit = /obj/item/weapon/circuitboard/cerealmaker output_options = list( "Cereal" = /obj/item/weapon/reagent_containers/food/snacks/variable/cereal ) + +/obj/machinery/appliance/mixer/cereal/Initialize() + . = ..() + cerealmaker_loop = new(list(src), FALSE) + +/obj/machinery/appliance/mixer/cereal/Destroy() + . = ..() + + QDEL_NULL(cerealmaker_loop) + /* /obj/machinery/appliance/mixer/cereal/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product, var/datum/cooking_item/CI) . = ..() @@ -31,6 +42,18 @@ product.overlays += food_image */ +/obj/machinery/appliance/mixer/cereal/update_icon() + . = ..() + + if(!stat) + icon_state = on_icon + if(cerealmaker_loop) + cerealmaker_loop.start(src) + else + icon_state = off_icon + if(cerealmaker_loop) + cerealmaker_loop.stop(src) + /obj/machinery/appliance/mixer/cereal/combination_cook(var/datum/cooking_item/CI) var/list/images = list() diff --git a/code/modules/food/kitchen/cooking_machines/grill.dm b/code/modules/food/kitchen/cooking_machines/grill.dm index 787e8b3d78..fea90585dd 100644 --- a/code/modules/food/kitchen/cooking_machines/grill.dm +++ b/code/modules/food/kitchen/cooking_machines/grill.dm @@ -8,6 +8,7 @@ on_icon = "grill_on" off_icon = "grill_off" can_burn_food = TRUE + var/datum/looping_sound/grill/grill_loop circuit = /obj/item/weapon/circuitboard/grill active_power_usage = 4 KILOWATTS heating_power = 4000 @@ -24,6 +25,28 @@ max_contents = 3 // Arbitrary number, 3 grill 'racks' container_type = /obj/item/weapon/reagent_containers/cooking_container/grill + +/obj/machinery/appliance/cooker/grill/Initialize() + . = ..() + grill_loop = new(list(src), FALSE) + +/obj/machinery/appliance/cooker/grill/Destroy() + QDEL_NULL(grill_loop) + return ..() + +/obj/machinery/appliance/cooker/grill/update_icon() // TODO: Cooking icon + if(!stat) + icon_state = on_icon + if(cooking == TRUE) + if(grill_loop) + grill_loop.start(src) + else + if(grill_loop) + grill_loop.stop(src) + else + icon_state = off_icon + if(grill_loop) + grill_loop.stop(src) /* // Test Comment this out too, /cooker does this for us, and this path '/obj/machinery/appliance/grill' is invalid anyways, meaning it does jack shit. - Updated the paths, but I'm basically commenting all this shit out and if the grill works as-normal, none of this stuff is needed. /obj/machinery/appliance/grill/toggle_power() @@ -88,12 +111,6 @@ return 0 */ -/obj/machinery/appliance/grill/update_icon() // TODO: Cooking icon - if(!stat) - icon_state = on_icon - else - icon_state = off_icon - /* // Test remove this too. /obj/machinery/appliance/grill/process() if (!stat) diff --git a/code/modules/food/kitchen/cooking_machines/oven.dm b/code/modules/food/kitchen/cooking_machines/oven.dm index 3203ecdc51..ece4a166a8 100644 --- a/code/modules/food/kitchen/cooking_machines/oven.dm +++ b/code/modules/food/kitchen/cooking_machines/oven.dm @@ -7,6 +7,7 @@ appliancetype = OVEN food_color = "#A34719" can_burn_food = TRUE + var/datum/looping_sound/oven/oven_loop circuit = /obj/item/weapon/circuitboard/oven active_power_usage = 6 KILOWATTS heating_power = 6 KILOWATTS @@ -37,6 +38,15 @@ "Cookie" = /obj/item/weapon/reagent_containers/food/snacks/variable/cookie, "Donut" = /obj/item/weapon/reagent_containers/food/snacks/variable/donut, ) + +/obj/machinery/appliance/cooker/oven/Initialize() + . = ..() + + oven_loop = new(list(src), FALSE) + +/obj/machinery/appliance/cooker/oven/Destroy() + QDEL_NULL(oven_loop) + return ..() /obj/machinery/appliance/cooker/oven/update_icon() if(!open) @@ -44,12 +54,20 @@ icon_state = "ovenclosed_on" if(cooking == TRUE) icon_state = "ovenclosed_cooking" + if(oven_loop) + oven_loop.start(src) else icon_state = "ovenclosed_on" + if(oven_loop) + oven_loop.stop(src) else icon_state = "ovenclosed_off" + if(oven_loop) + oven_loop.stop(src) else icon_state = "ovenopen" + if(oven_loop) + oven_loop.stop(src) ..() /obj/machinery/appliance/cooker/oven/AltClick(var/mob/user) diff --git a/code/modules/gamemaster/event2/events/engineering/gas_leak.dm b/code/modules/gamemaster/event2/events/engineering/gas_leak.dm index fb8dc41f86..b0c52d6e07 100644 --- a/code/modules/gamemaster/event2/events/engineering/gas_leak.dm +++ b/code/modules/gamemaster/event2/events/engineering/gas_leak.dm @@ -15,7 +15,7 @@ /datum/event2/event/gas_leak - var/potential_gas_choices = list("carbon_dioxide", "sleeping_agent", "phoron", "volatile_fuel") + var/potential_gas_choices = list("carbon_dioxide", "nitrous_oxide", "phoron", "volatile_fuel") var/chosen_gas = null var/turf/chosen_turf = null diff --git a/code/modules/games/cah_black_cards.dm b/code/modules/games/cah_black_cards.dm index 08d81c94ae..0bc5cc6d0f 100644 --- a/code/modules/games/cah_black_cards.dm +++ b/code/modules/games/cah_black_cards.dm @@ -5,7 +5,7 @@ "The Chaplain this shift is worshiping _____.", "Cargo ordered a crate full of _____.", "An ERT was called due to ______.", - "Alert! The Colony Director has armed themselves with _____.", + "Alert! The Site Manager has armed themselves with _____.", "Current Laws: ________ is your master.", "Current Laws: ________ is the enemy.", "_____ vented the entirety of Cargo.", @@ -14,7 +14,7 @@ "Caution, ______ have been detected in collision course with the station.", "Today's kitchen menu includes _______.", "What did the mercenaries want when they attacked the station?", - "I think the Colony Director is insane. He just demanded ______ in his office.", + "I think the Site Manager is insane. He just demanded ______ in his office.", "Fuckin' scientists, they just turned Misc. Research into _______ .", "What's my fetish?", "Hello, _______ here with _______", diff --git a/code/modules/games/cah_white_cards.dm b/code/modules/games/cah_white_cards.dm index 2c16e0e54c..0c10d3d1cb 100644 --- a/code/modules/games/cah_white_cards.dm +++ b/code/modules/games/cah_white_cards.dm @@ -5,7 +5,7 @@ "Space 'Nam", "Space lesbians", "The Gardener getting SUPER high", - "The Colony Director thinking they're a badass", + "The Site Manager thinking they're a badass", "Being in a cult", "Racially biased lawsets", "An Unathi who WON'T STOP FIGHTING", @@ -57,7 +57,7 @@ "An irritatingly chipper robot", "Androids hanging out in the bar drinking beer", "Gear harnesses", - "A seventeen-year-old Colony Director", + "A seventeen-year-old Site Manager", "The throbbing erection that the HoS gets at the thought of shooting something", "Trying to stab someone and hugging them instead", "Waking up naked in the maintenance tunnels", diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 3be22f940a..91d7d8d666 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -18,6 +18,8 @@ name = "deck of cards" desc = "A simple deck of playing cards." icon_state = "deck" + drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' /obj/item/weapon/deck/cards/New() ..() @@ -281,6 +283,8 @@ w_class = ITEMSIZE_TINY var/list/cards = list() var/parentdeck = null // This variable is added here so that card pack dependent card can be mixed together by defining a "parentdeck" for them + drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' /obj/item/weapon/pack/attack_self(var/mob/user as mob) @@ -301,6 +305,8 @@ desc = "Some playing cards." icon = 'icons/obj/playing_cards.dmi' icon_state = "empty" + drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' w_class = ITEMSIZE_TINY var/concealed = 0 diff --git a/code/modules/games/dice.dm b/code/modules/games/dice.dm index 039631cdb4..9b796995c5 100644 --- a/code/modules/games/dice.dm +++ b/code/modules/games/dice.dm @@ -80,6 +80,8 @@ desc = "It's a small bag with dice inside." icon = 'icons/obj/dice.dmi' icon_state = "dicebag" + drop_sound = 'sound/items/drop/hat.ogg' + pickup_sound = 'sound/items/pickup/hat.ogg' /obj/item/weapon/storage/pill_bottle/dice/New() ..() @@ -91,6 +93,8 @@ desc = "It's a small bag with gaming dice inside." icon = 'icons/obj/dice.dmi' icon_state = "magicdicebag" + drop_sound = 'sound/items/drop/hat.ogg' + pickup_sound = 'sound/items/pickup/hat.ogg' /obj/item/weapon/storage/pill_bottle/dice_nerd/New() ..() diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index ad679ec891..849b1a5a6e 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -360,6 +360,7 @@ datum/unarmed_attack/holopugilism/unarmed_override(var/mob/living/carbon/human/u desc = "Here's your chance, do your dance at the Space Jam." w_class = ITEMSIZE_LARGE //Stops people from hiding it in their bags/pockets drop_sound = 'sound/items/drop/basketball.ogg' + pickup_sound = 'sound/items/pickup/basketball.ogg' /obj/structure/holohoop name = "basketball hoop" diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index ad3b16e440..62350ff0cb 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -8,6 +8,7 @@ flags = NOCONDUCT slot_flags = SLOT_HOLSTER drop_sound = 'sound/items/drop/herb.ogg' + pickup_sound = 'sound/items/pickup/herb.ogg' var/plantname var/datum/seed/seed @@ -30,7 +31,7 @@ log_debug("Plantname not provided and and [src] requires it at [x],[y],[z]") return INITIALIZE_HINT_QDEL - seed = plant_controller.seeds[plantname] + seed = SSplants.seeds[plantname] if(!seed) log_debug("Plant name '[plantname]' does not exist and [src] requires it at [x],[y],[z]") @@ -62,18 +63,11 @@ force = 1 /obj/item/weapon/reagent_containers/food/snacks/grown/proc/update_desc() - if(!seed) return - if(!plant_controller) - sleep(250) // ugly hack, should mean roundstart plants are fine. - if(!plant_controller) - to_world("Plant controller does not exist and [src] requires it. Aborting.") - qdel(src) - return - if(plant_controller.product_descs["[seed.uid]"]) - desc = plant_controller.product_descs["[seed.uid]"] + if(SSplants.product_descs["[seed.uid]"]) + desc = SSplants.product_descs["[seed.uid]"] else var/list/descriptors = list() if(reagents.has_reagent("sugar") || reagents.has_reagent("cherryjelly") || reagents.has_reagent("honey") || reagents.has_reagent("berryjuice")) @@ -125,17 +119,17 @@ desc += " mushroom" else desc += " fruit" - plant_controller.product_descs["[seed.uid]"] = desc + SSplants.product_descs["[seed.uid]"] = desc desc += ". Delicious! Probably." /obj/item/weapon/reagent_containers/food/snacks/grown/update_icon() - if(!seed || !plant_controller || !plant_controller.plant_icon_cache) + if(!seed || !SSplants || !SSplants.plant_icon_cache) return overlays.Cut() var/image/plant_icon var/icon_key = "fruit-[seed.get_trait(TRAIT_PRODUCT_ICON)]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]-[seed.get_trait(TRAIT_PLANT_COLOUR)]" - if(plant_controller.plant_icon_cache[icon_key]) - plant_icon = plant_controller.plant_icon_cache[icon_key] + if(SSplants.plant_icon_cache[icon_key]) + plant_icon = SSplants.plant_icon_cache[icon_key] else plant_icon = image('icons/obj/hydroponics_products.dmi',"blank") var/image/fruit_base = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-product") @@ -145,7 +139,7 @@ var/image/fruit_leaves = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf") fruit_leaves.color = "[seed.get_trait(TRAIT_PLANT_COLOUR)]" plant_icon.overlays |= fruit_leaves - plant_controller.plant_icon_cache[icon_key] = plant_icon + SSplants.plant_icon_cache[icon_key] = plant_icon overlays |= plant_icon /obj/item/weapon/reagent_containers/food/snacks/grown/Crossed(var/mob/living/M) @@ -354,6 +348,7 @@ var/list/fruit_icon_cache = list() name = "[S.seed_name] slice" desc = "A slice of \a [S.seed_name]. Tasty, probably." drop_sound = 'sound/items/drop/herb.ogg' + pickup_sound = 'sound/items/pickup/herb.ogg' var/rind_colour = S.get_trait(TRAIT_PRODUCT_COLOUR) var/flesh_colour = S.get_trait(TRAIT_FLESH_COLOUR) diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm index 2d3dfbc344..0413fe50ac 100644 --- a/code/modules/hydroponics/grown_inedible.dm +++ b/code/modules/hydroponics/grown_inedible.dm @@ -19,7 +19,7 @@ //Handle some post-spawn var stuff. if(planttype) plantname = planttype - var/datum/seed/S = plant_controller.seeds[plantname] + var/datum/seed/S = SSplants.seeds[plantname] if(!S || !S.chems) return diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index f2b9751930..53a31a8a2b 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -410,8 +410,8 @@ seed_noun = pick("spores","nodes","cuttings","seeds") set_trait(TRAIT_POTENCY,rand(5,30),200,0) - set_trait(TRAIT_PRODUCT_ICON,pick(plant_controller.accessible_product_sprites)) - set_trait(TRAIT_PLANT_ICON,pick(plant_controller.accessible_plant_sprites)) + set_trait(TRAIT_PRODUCT_ICON,pick(SSplants.accessible_product_sprites)) + set_trait(TRAIT_PLANT_ICON,pick(SSplants.accessible_plant_sprites)) set_trait(TRAIT_PLANT_COLOUR,"#[get_random_colour(0,75,190)]") set_trait(TRAIT_PRODUCT_COLOUR,"#[get_random_colour(0,75,190)]") update_growth_stages() @@ -791,10 +791,10 @@ to_chat(user, "You [harvest_sample ? "take a sample" : "harvest"] from the [display_name].") //This may be a new line. Update the global if it is. - if(name == "new line" || !(name in plant_controller.seeds)) - uid = plant_controller.seeds.len + 1 + if(name == "new line" || !(name in SSplants.seeds)) + uid = SSplants.seeds.len + 1 name = "[uid]" - plant_controller.seeds[name] = src + SSplants.seeds[name] = src if(harvest_sample) var/obj/item/seeds/seeds = new(get_turf(user)) @@ -880,6 +880,6 @@ /datum/seed/proc/update_growth_stages() if(get_trait(TRAIT_PLANT_ICON)) - growth_stages = plant_controller.plant_sprites[get_trait(TRAIT_PLANT_ICON)] + growth_stages = SSplants.plant_sprites[get_trait(TRAIT_PLANT_ICON)] else growth_stages = 0 diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index 442fb7da2e..bec4978201 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -62,7 +62,7 @@ return attack_hand(user) /obj/machinery/botany/attack_hand(mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/botany/proc/finished_task() active = 0 @@ -136,14 +136,16 @@ var/datum/seed/genetics // Currently scanned seed genetic structure. var/degradation = 0 // Increments with each scan, stops allowing gene mods after a certain point. -/obj/machinery/botany/extractor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/botany/extractor/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BotanyIsolator", name) + ui.open() - if(!user) - return +/obj/machinery/botany/extractor/tgui_data(mob/user) + var/list/data = ..() - var/list/data = list() - - var/list/geneMasks = plant_controller.gene_masked_list + var/list/geneMasks = SSplants.gene_masked_list data["geneMasks"] = geneMasks data["activity"] = active @@ -168,95 +170,93 @@ data["hasGenetics"] = 0 data["sourceName"] = 0 - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "botany_isolator.tmpl", "Lysis-isolation Centrifuge UI", 470, 450) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/botany/Topic(href, href_list) + return data +/obj/machinery/botany/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 - - if(href_list["eject_packet"]) - if(!seed) return - seed.loc = get_turf(src) - - if(seed.seed.name == "new line" || isnull(plant_controller.seeds[seed.seed.name])) - seed.seed.uid = plant_controller.seeds.len + 1 - seed.seed.name = "[seed.seed.uid]" - plant_controller.seeds[seed.seed.name] = seed.seed - - seed.update_seed() - visible_message("[bicon(src)] [src] beeps and spits out [seed].") - - seed = null - - if(href_list["eject_disk"]) - if(!loaded_disk) return - loaded_disk.loc = get_turf(src) - visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].") - loaded_disk = null + return TRUE usr.set_machine(src) - src.add_fingerprint(usr) + add_fingerprint(usr) -/obj/machinery/botany/extractor/Topic(href, href_list) + switch(action) + if("eject_packet") + if(!seed) + return + seed.forceMove(get_turf(src)) + if(seed.seed.name == "new line" || isnull(SSplants.seeds[seed.seed.name])) + seed.seed.uid = SSplants.seeds.len + 1 + seed.seed.name = "[seed.seed.uid]" + SSplants.seeds[seed.seed.name] = seed.seed + + seed.update_seed() + visible_message("[bicon(src)] [src] beeps and spits out [seed].") + + seed = null + return TRUE + + if("eject_disk") + if(!loaded_disk) + return + loaded_disk.forceMove(get_turf(src)) + visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].") + loaded_disk = null + return TRUE + +/obj/machinery/botany/extractor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE - usr.set_machine(src) - src.add_fingerprint(usr) + switch(action) + if("scan_genome") + if(!seed) + return - if(href_list["scan_genome"]) + last_action = world.time + active = 1 - if(!seed) return + if(seed && seed.seed) + genetics = seed.seed + degradation = 0 - last_action = world.time - active = 1 + qdel(seed) + seed = null + return TRUE - if(seed && seed.seed) - genetics = seed.seed - degradation = 0 + if("get_gene") + if(!genetics || !loaded_disk) + return - qdel(seed) - seed = null + last_action = world.time + active = 1 - if(href_list["get_gene"]) + var/datum/plantgene/P = genetics.get_gene(params["get_gene"]) + if(!P) + return + loaded_disk.genes += P - if(!genetics || !loaded_disk) return + loaded_disk.genesource = "[genetics.display_name]" + if(!genetics.roundstart) + loaded_disk.genesource += " (variety #[genetics.uid])" - last_action = world.time - active = 1 + loaded_disk.name += " ([SSplants.gene_tag_masks[params["get_gene"]]], #[genetics.uid])" + loaded_disk.desc += " The label reads \'gene [SSplants.gene_tag_masks[params["get_gene"]]], sampled from [genetics.display_name]\'." + eject_disk = 1 - var/datum/plantgene/P = genetics.get_gene(href_list["get_gene"]) - if(!P) return - loaded_disk.genes += P + degradation += rand(20,60) + if(degradation >= 100) + failed_task = 1 + genetics = null + degradation = 0 + return TRUE - loaded_disk.genesource = "[genetics.display_name]" - if(!genetics.roundstart) - loaded_disk.genesource += " (variety #[genetics.uid])" - - loaded_disk.name += " ([plant_controller.gene_tag_masks[href_list["get_gene"]]], #[genetics.uid])" - loaded_disk.desc += " The label reads \'gene [plant_controller.gene_tag_masks[href_list["get_gene"]]], sampled from [genetics.display_name]\'." - eject_disk = 1 - - degradation += rand(20,60) - if(degradation >= 100) - failed_task = 1 + if("clear_buffer") + if(!genetics) + return genetics = null degradation = 0 - - if(href_list["clear_buffer"]) - if(!genetics) return - genetics = null - degradation = 0 - - src.updateUsrDialog() - return + return TRUE // Fires an extracted trait into another packet of seeds with a chance // of destroying it based on the size/complexity of the plasmid. @@ -265,13 +265,15 @@ icon_state = "traitgun" disk_needs_genes = 1 -/obj/machinery/botany/editor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - - if(!user) - return - - var/list/data = list() +/obj/machinery/botany/editor/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BotanyEditor", name) + ui.open() +/obj/machinery/botany/editor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["activity"] = active if(seed) @@ -286,7 +288,7 @@ for(var/datum/plantgene/P in loaded_disk.genes) if(data["locus"] != "") data["locus"] += ", " - data["locus"] += "[plant_controller.gene_tag_masks[P.genetype]]" + data["locus"] += "[SSplants.gene_tag_masks[P.genetype]]" else data["disk"] = 0 @@ -298,36 +300,30 @@ else data["loaded"] = 0 - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "botany_editor.tmpl", "Bioballistic Delivery UI", 470, 450) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/botany/editor/Topic(href, href_list) + return data +/obj/machinery/botany/editor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE - if(href_list["apply_gene"]) - if(!loaded_disk || !seed) return + switch(action) + if("apply_gene") + if(!loaded_disk || !seed) + return - last_action = world.time - active = 1 + last_action = world.time + active = 1 - if(!isnull(plant_controller.seeds[seed.seed.name])) - seed.seed = seed.seed.diverge(1) - seed.seed_type = seed.seed.name - seed.update_seed() + if(!isnull(SSplants.seeds[seed.seed.name])) + seed.seed = seed.seed.diverge(1) + seed.seed_type = seed.seed.name + seed.update_seed() - if(prob(seed.modified)) - failed_task = 1 - seed.modified = 101 + if(prob(seed.modified)) + failed_task = 1 + seed.modified = 101 - for(var/datum/plantgene/gene in loaded_disk.genes) - seed.seed.apply_gene(gene) - seed.modified += rand(5,10) - - usr.set_machine(src) - src.add_fingerprint(usr) + for(var/datum/plantgene/gene in loaded_disk.genes) + seed.seed.apply_gene(gene) + seed.modified += rand(5,10) + return TRUE diff --git a/code/modules/hydroponics/seed_packets.dm b/code/modules/hydroponics/seed_packets.dm index 848b5a10e7..45d74e26fd 100644 --- a/code/modules/hydroponics/seed_packets.dm +++ b/code/modules/hydroponics/seed_packets.dm @@ -19,8 +19,8 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds) //Grabs the appropriate seed datum from the global list. /obj/item/seeds/proc/update_seed() - if(!seed && seed_type && !isnull(plant_controller.seeds) && plant_controller.seeds[seed_type]) - seed = plant_controller.seeds[seed_type] + if(!seed && seed_type && !isnull(SSplants.seeds) && SSplants.seeds[seed_type]) + seed = SSplants.seeds[seed_type] update_appearance() //Updates strings and icon appropriately based on seed datum. @@ -76,7 +76,7 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds) seed_type = null /obj/item/seeds/random/Initialize() - seed = plant_controller.create_random_seed() + seed = SSplants.create_random_seed() seed_type = seed.name . = ..() diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm index b8ea1fa748..39b9dc3ebc 100644 --- a/code/modules/hydroponics/seed_storage.dm +++ b/code/modules/hydroponics/seed_storage.dm @@ -211,23 +211,15 @@ if(lockdown) return user.set_machine(src) - interact(user) + tgui_interact(user) -/obj/machinery/seed_storage/interact(mob/user as mob) - if (..()) - return - - if(smart) - scanner = list("stats", "produce", "soil", "temperature", "light", "pressure") - else - scanner = initial(scanner) - - if (!seeds_initialized) +/obj/machinery/seed_storage/tgui_interact(mob/user, datum/tgui/ui) + if(!seeds_initialized) for(var/typepath in starting_seeds) var/amount = starting_seeds[typepath] if(isnull(amount)) amount = 1 - for (var/i = 1 to amount) + for(var/i = 1 to amount) var/O = new typepath add(O) for(var/typepath in contraband_seeds) @@ -239,251 +231,153 @@ add(O, 1) seeds_initialized = 1 - var/dat = "

Seed storage contents

" - if (piles.len == 0) - dat += "No seeds" + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SeedStorage", name) + ui.open() + +/obj/machinery/seed_storage/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + if(smart) + scanner = list("stats", "produce", "soil", "temperature", "light", "pressure") else - dat += "
Command
SpecialColony Director
SpecialSite ManagerCustom
" - dat += "" - if ("stats" in scanner) - dat += "" + scanner = initial(scanner) + + data["scanner"] = scanner + + var/list/piles_to_check = piles + if(hacked || emagged) + piles_to_check = piles + piles_contra + + var/list/seeds = list() + for(var/datum/seed_pile/S in piles_to_check) + var/datum/seed/seed = S.seed_type + if(!seed) + continue + var/list/seedinfo = list( + "name" = seed.seed_name, + "uid" = seed.uid, + "amount" = S.amount, + "id" = S.ID, + ) + + seedinfo["traits"] = list() + if("stats" in scanner) + seedinfo["traits"]["Endurance"] = seed.get_trait(TRAIT_ENDURANCE) + seedinfo["traits"]["Yield"] = seed.get_trait(TRAIT_YIELD) + seedinfo["traits"]["Production"] = seed.get_trait(TRAIT_PRODUCTION) + seedinfo["traits"]["Potency"] = seed.get_trait(TRAIT_POTENCY) + seedinfo["traits"]["Repeat Harvest"] = seed.get_trait(TRAIT_HARVEST_REPEAT) + if("temperature" in scanner) + seedinfo["traits"]["Ideal Heat"] = seed.get_trait(TRAIT_IDEAL_HEAT) + if("light" in scanner) + seedinfo["traits"]["Ideal Light"] = seed.get_trait(TRAIT_IDEAL_LIGHT) + if("soil" in scanner) + if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS)) + if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) + seedinfo["traits"]["Nutrient Consumption"] = "Low" + else if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2) + seedinfo["traits"]["Nutrient Consumption"] = "High" + else + seedinfo["traits"]["Nutrient Consumption"] = "Norm" + else + seedinfo["traits"]["Nutrient Consumption"] = "No" + if(seed.get_trait(TRAIT_REQUIRES_WATER)) + if(seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1) + seedinfo["traits"]["Water Consumption"] = "Low" + else if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5) + seedinfo["traits"]["Water Consumption"] = "High" + else + seedinfo["traits"]["Water Consumption"] = "Norm" + else + seedinfo["traits"]["Water Consumption"] = "No" + + seedinfo["traits"]["notes"] = "" + switch(seed.get_trait(TRAIT_CARNIVOROUS)) + if(1) + seedinfo["traits"]["notes"] += "CARN " + if(2) + seedinfo["traits"]["notes"] += "FASTCARN" + switch(seed.get_trait(TRAIT_SPREAD)) + if(1) + seedinfo["traits"]["notes"] += "VINE " + if(2) + seedinfo["traits"]["notes"] += "FASTVINE" + if ("pressure" in scanner) + if(seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) + seedinfo["traits"]["notes"] += "LP " + if(seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) + seedinfo["traits"]["notes"] += "HP " if ("temperature" in scanner) - dat += "" + if(seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30) + seedinfo["traits"]["notes"] += "TEMRES " + else if(seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10) + seedinfo["traits"]["notes"] += "TEMSEN " if ("light" in scanner) - dat += "" - if ("soil" in scanner) - dat += "" - dat += "" - for (var/datum/seed_pile/S in piles) - var/datum/seed/seed = S.seed_type - if(!seed) - continue - dat += "" - dat += "" - dat += "" - if ("stats" in scanner) - dat += "" - if(seed.get_trait(TRAIT_HARVEST_REPEAT)) - dat += "" - else - dat += "" - if ("temperature" in scanner) - dat += "" - if ("light" in scanner) - dat += "" - if ("soil" in scanner) - if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS)) - if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) - dat += "" - else if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2) - dat += "" - else - dat += "" - else - dat += "" - if(seed.get_trait(TRAIT_REQUIRES_WATER)) - if(seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1) - dat += "" - else if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5) - dat += "" - else - dat += "" - else - dat += "" + if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10) + seedinfo["traits"]["notes"] += "LIGRES " + else if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3) + seedinfo["traits"]["notes"] += "LIGSEN " + if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3) + seedinfo["traits"]["notes"] += "TOXSEN " + else if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6) + seedinfo["traits"]["notes"] += "TOXRES " + if(seed.get_trait(TRAIT_PEST_TOLERANCE) < 3) + seedinfo["traits"]["notes"] += "PESTSEN " + else if(seed.get_trait(TRAIT_PEST_TOLERANCE) > 6) + seedinfo["traits"]["notes"] += "PESTRES " + if(seed.get_trait(TRAIT_WEED_TOLERANCE) < 3) + seedinfo["traits"]["notes"] += "WEEDSEN " + else if(seed.get_trait(TRAIT_WEED_TOLERANCE) > 6) + seedinfo["traits"]["notes"] += "WEEDRES " + if(seed.get_trait(TRAIT_PARASITE)) + seedinfo["traits"]["notes"] += "PAR " + if ("temperature" in scanner) + if(seed.get_trait(TRAIT_ALTER_TEMP) > 0) + seedinfo["traits"]["notes"] += "TEMP+ " + if(seed.get_trait(TRAIT_ALTER_TEMP) < 0) + seedinfo["traits"]["notes"] += "TEMP- " + if(seed.get_trait(TRAIT_BIOLUM)) + seedinfo["traits"]["notes"] += "LUM " - dat += "" - dat += "" - dat += "" - dat += "" - if(hacked || emagged) - for (var/datum/seed_pile/S in piles_contra) - var/datum/seed/seed = S.seed_type - if(!seed) - continue - dat += "" - dat += "" - dat += "" - if ("stats" in scanner) - dat += "" - if(seed.get_trait(TRAIT_HARVEST_REPEAT)) - dat += "" - else - dat += "" - if ("temperature" in scanner) - dat += "" - if ("light" in scanner) - dat += "" - if ("soil" in scanner) - if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS)) - if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) - dat += "" - else if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2) - dat += "" - else - dat += "" - else - dat += "" - if(seed.get_trait(TRAIT_REQUIRES_WATER)) - if(seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1) - dat += "" - else if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5) - dat += "" - else - dat += "" - else - dat += "" + seeds.Add(list(seedinfo)) - dat += "" - dat += "" - dat += "" - dat += "" - dat += "
NameVarietyEYMPrPtHarvestTempLightNutriWaterNotesAmount
[seed.seed_name]#[seed.uid][seed.get_trait(TRAIT_ENDURANCE)][seed.get_trait(TRAIT_YIELD)][seed.get_trait(TRAIT_MATURATION)][seed.get_trait(TRAIT_PRODUCTION)][seed.get_trait(TRAIT_POTENCY)]MultipleSingle[seed.get_trait(TRAIT_IDEAL_HEAT)] K[seed.get_trait(TRAIT_IDEAL_LIGHT)] LLowHighNormNoLowHighNormNo" - switch(seed.get_trait(TRAIT_CARNIVOROUS)) - if(1) - dat += "CARN " - if(2) - dat += "CARN " - switch(seed.get_trait(TRAIT_SPREAD)) - if(1) - dat += "VINE " - if(2) - dat += "VINE " - if ("pressure" in scanner) - if(seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) - dat += "LP " - if(seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) - dat += "HP " - if ("temperature" in scanner) - if(seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30) - dat += "TEMRES " - else if(seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10) - dat += "TEMSEN " - if ("light" in scanner) - if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10) - dat += "LIGRES " - else if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3) - dat += "LIGSEN " - if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3) - dat += "TOXSEN " - else if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6) - dat += "TOXRES " - if(seed.get_trait(TRAIT_PEST_TOLERANCE) < 3) - dat += "PESTSEN " - else if(seed.get_trait(TRAIT_PEST_TOLERANCE) > 6) - dat += "PESTRES " - if(seed.get_trait(TRAIT_WEED_TOLERANCE) < 3) - dat += "WEEDSEN " - else if(seed.get_trait(TRAIT_WEED_TOLERANCE) > 6) - dat += "WEEDRES " - if(seed.get_trait(TRAIT_PARASITE)) - dat += "PAR " - if ("temperature" in scanner) - if(seed.get_trait(TRAIT_ALTER_TEMP) > 0) - dat += "TEMP+ " - if(seed.get_trait(TRAIT_ALTER_TEMP) < 0) - dat += "TEMP- " - if(seed.get_trait(TRAIT_BIOLUM)) - dat += "LUM " - dat += "[S.amount]Vend Purge
[seed.seed_name]#[seed.uid][seed.get_trait(TRAIT_ENDURANCE)][seed.get_trait(TRAIT_YIELD)][seed.get_trait(TRAIT_MATURATION)][seed.get_trait(TRAIT_PRODUCTION)][seed.get_trait(TRAIT_POTENCY)]MultipleSingle[seed.get_trait(TRAIT_IDEAL_HEAT)] K[seed.get_trait(TRAIT_IDEAL_LIGHT)] LLowHighNormNoLowHighNormNo" - switch(seed.get_trait(TRAIT_CARNIVOROUS)) - if(1) - dat += "CARN " - if(2) - dat += "CARN " - switch(seed.get_trait(TRAIT_SPREAD)) - if(1) - dat += "VINE " - if(2) - dat += "VINE " - if ("pressure" in scanner) - if(seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) - dat += "LP " - if(seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) - dat += "HP " - if ("temperature" in scanner) - if(seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30) - dat += "TEMRES " - else if(seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10) - dat += "TEMSEN " - if ("light" in scanner) - if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10) - dat += "LIGRES " - else if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3) - dat += "LIGSEN " - if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3) - dat += "TOXSEN " - else if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6) - dat += "TOXRES " - if(seed.get_trait(TRAIT_PEST_TOLERANCE) < 3) - dat += "PESTSEN " - else if(seed.get_trait(TRAIT_PEST_TOLERANCE) > 6) - dat += "PESTRES " - if(seed.get_trait(TRAIT_WEED_TOLERANCE) < 3) - dat += "WEEDSEN " - else if(seed.get_trait(TRAIT_WEED_TOLERANCE) > 6) - dat += "WEEDRES " - if(seed.get_trait(TRAIT_PARASITE)) - dat += "PAR " - if ("temperature" in scanner) - if(seed.get_trait(TRAIT_ALTER_TEMP) > 0) - dat += "TEMP+ " - if(seed.get_trait(TRAIT_ALTER_TEMP) < 0) - dat += "TEMP- " - if(seed.get_trait(TRAIT_BIOLUM)) - dat += "LUM " - dat += "[S.amount]Vend Purge
" + data["seeds"] = seeds - user << browse(dat, "window=seedstorage") - onclose(user, "seedstorage") + return data -/obj/machinery/seed_storage/Topic(var/href, var/list/href_list) - if (..()) - return - var/task = href_list["task"] - var/ID = text2num(href_list["id"]) +/obj/machinery/seed_storage/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + var/ID = text2num(params["id"]) - for (var/datum/seed_pile/N in piles) - if (N.ID == ID) - if (task == "vend") + var/list/piles_to_check = piles + if(hacked || emagged) + piles_to_check = piles + piles_contra + + for(var/datum/seed_pile/N in piles_to_check) + if(N.ID == ID) + if(action == "vend") var/obj/O = pick(N.seeds) - if (O) + if(O) --N.amount N.seeds -= O - if (N.amount <= 0 || N.seeds.len <= 0) + if(N.amount <= 0 || N.seeds.len <= 0) piles -= N qdel(N) O.loc = src.loc else piles -= N qdel(N) - else if (task == "purge") - for (var/obj/O in N.seeds) + return TRUE + else if(action == "purge") + for(var/obj/O in N.seeds) qdel(O) piles -= N qdel(N) + return TRUE break - if(hacked || emagged) - for (var/datum/seed_pile/N in piles_contra) - if (N.ID == ID) - if (task == "vend") - var/obj/O = pick(N.seeds) - if (O) - --N.amount - N.seeds -= O - if (N.amount <= 0 || N.seeds.len <= 0) - piles_contra -= N - qdel(N) - O.loc = src.loc - else - piles_contra -= N - qdel(N) - else if (task == "purge") - for (var/obj/O in N.seeds) - qdel(O) - piles_contra -= N - qdel(N) - break - updateUsrDialog() /obj/machinery/seed_storage/attackby(var/obj/item/O as obj, var/mob/user as mob) if (istype(O, /obj/item/seeds) && !lockdown) diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index 2f93bb108b..9c8e810753 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -12,7 +12,7 @@ if(turfs.len) //Pick a turf to spawn at if we can var/turf/simulated/floor/T = pick(turfs) - var/datum/seed/seed = plant_controller.create_random_seed(1) + var/datum/seed/seed = SSplants.create_random_seed(1) seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines. seed.set_trait(TRAIT_POTENCY,rand(potency_min, potency_max)) // 70-100 potency will help guarantee a wide spread and powerful effects. seed.set_trait(TRAIT_MATURATION,rand(maturation_min, maturation_max)) @@ -74,9 +74,9 @@ /obj/effect/plant/Destroy() if(seed.get_trait(TRAIT_SPREAD)==2) unsense_proximity(callback = .HasProximity, center = get_turf(src)) - plant_controller.remove_plant(src) + SSplants.remove_plant(src) for(var/obj/effect/plant/neighbor in range(1,src)) - plant_controller.add_plant(neighbor) + SSplants.add_plant(neighbor) return ..() /obj/effect/plant/single @@ -90,15 +90,15 @@ else parent = newparent - if(!plant_controller) + if(!SSplants) sleep(250) // ugly hack, should mean roundstart plants are fine. TODO initialize perhaps? - if(!plant_controller) + if(!SSplants) to_world("Plant controller does not exist and [src] requires it. Aborting.") qdel(src) return if(!istype(newseed)) - newseed = plant_controller.seeds[DEFAULT_SEED] + newseed = SSplants.seeds[DEFAULT_SEED] seed = newseed if(!seed) qdel(src) @@ -135,7 +135,7 @@ /obj/effect/plant/proc/finish_spreading() set_dir(calc_dir()) update_icon() - plant_controller.add_plant(src) + SSplants.add_plant(src) //Some plants eat through plating. if(islist(seed.chems) && !isnull(seed.chems["pacid"])) var/turf/T = get_turf(src) @@ -240,7 +240,7 @@ /obj/effect/plant/attackby(var/obj/item/weapon/W, var/mob/user) user.setClickCooldown(user.get_attack_speed(W)) - plant_controller.add_plant(src) + SSplants.add_plant(src) if(W.is_wirecutter() || istype(W, /obj/item/weapon/surgical/scalpel)) if(sampled) diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm index bd4b48893f..db94bebd0d 100644 --- a/code/modules/hydroponics/spreading/spreading_growth.dm +++ b/code/modules/hydroponics/spreading/spreading_growth.dm @@ -33,7 +33,7 @@ neighbors |= floor if(neighbors.len) - plant_controller.add_plant(src) //if we have neighbours again, start processing + SSplants.add_plant(src) //if we have neighbours again, start processing // Update all of our friends. var/turf/T = get_turf(src) @@ -110,7 +110,7 @@ // We shouldn't have spawned if the controller doesn't exist. check_health() if(has_buckled_mobs() || neighbors.len) - plant_controller.add_plant(src) + SSplants.add_plant(src) //spreading vines aren't created on their final turf. //Instead, they are created at their parent and then move to their destination. @@ -160,7 +160,7 @@ continue for(var/obj/effect/plant/neighbor in check_turf.contents) neighbor.neighbors |= check_turf - plant_controller.add_plant(neighbor) + SSplants.add_plant(neighbor) spawn(1) if(src) qdel(src) #undef NEIGHBOR_REFRESH_TIME \ No newline at end of file diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 474800fcf4..1ac41ce60f 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -366,7 +366,7 @@ //Remove the seed if something is already planted. if(seed) seed = null - seed = plant_controller.seeds[pick(list("reishi","nettle","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))] + seed = SSplants.seeds[pick(list("reishi","nettle","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))] if(!seed) return //Weed does not exist, someone fucked up. dead = 0 @@ -396,7 +396,7 @@ // We need to make sure we're not modifying one of the global seed datums. // If it's not in the global list, then no products of the line have been // harvested yet and it's safe to assume it's restricted to this tray. - if(!isnull(plant_controller.seeds[seed.name])) + if(!isnull(SSplants.seeds[seed.name])) seed = seed.diverge() seed.mutate(severity,get_turf(src)) @@ -452,8 +452,8 @@ var/previous_plant = seed.display_name var/newseed = seed.get_mutant_variant() - if(newseed in plant_controller.seeds) - seed = plant_controller.seeds[newseed] + if(newseed in SSplants.seeds) + seed = SSplants.seeds[newseed] else return diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index d28db69bae..d05922b2f9 100644 --- a/code/modules/hydroponics/trays/tray_tools.dm +++ b/code/modules/hydroponics/trays/tray_tools.dm @@ -16,42 +16,50 @@ icon = 'icons/obj/device.dmi' icon_state = "hydro" item_state = "analyzer" - var/form_title - var/last_data + var/datum/seed/last_seed + var/list/last_reagents -/obj/item/device/analyzer/plant_analyzer/proc/print_report_verb() - set name = "Print Plant Report" - set category = "Object" - set src = usr +/obj/item/device/analyzer/plant_analyzer/attack_self(mob/user) + tgui_interact(user) - if(usr.stat || usr.restrained() || usr.lying) - return - print_report(usr) +/obj/item/device/analyzer/plant_analyzer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PlantAnalyzer", name) + ui.open() + +/obj/item/device/analyzer/plant_analyzer/tgui_state(mob/user) + return GLOB.tgui_inventory_state -/obj/item/device/analyzer/plant_analyzer/Topic(href, href_list) +/obj/item/device/analyzer/plant_analyzer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/datum/seed/grown_seed = locate(last_seed) + if(!istype(grown_seed)) + return list("no_seed" = TRUE) + + data["no_seed"] = FALSE + data["seed"] = grown_seed.get_tgui_analyzer_data(user) + data["reagents"] = last_reagents + + return data + +/obj/item/device/analyzer/plant_analyzer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return - if(href_list["print"]) - print_report(usr) - -/obj/item/device/analyzer/plant_analyzer/proc/print_report(var/mob/living/user) - if(!last_data) - to_chat(user, "There is no scan data to print.") - return - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src)) - P.name = "paper - [form_title]" - P.info = "[last_data]" - if(istype(user,/mob/living/carbon/human)) - user.put_in_hands(P) - user.visible_message("\The [src] spits out a piece of paper.") - return - -/obj/item/device/analyzer/plant_analyzer/attack_self(mob/user as mob) - print_report(user) - return 0 + return TRUE + + switch(action) + if("print") + print_report(usr) + return TRUE + if("close") + last_seed = null + last_reagents = null + return TRUE /obj/item/device/analyzer/plant_analyzer/afterattack(obj/target, mob/user, flag) - if(!flag) return + if(!flag) + return var/datum/seed/grown_seed var/datum/reagents/grown_reagents @@ -60,13 +68,13 @@ else if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown)) var/obj/item/weapon/reagent_containers/food/snacks/grown/G = target - grown_seed = plant_controller.seeds[G.plantname] + grown_seed = SSplants.seeds[G.plantname] grown_reagents = G.reagents else if(istype(target,/obj/item/weapon/grown)) var/obj/item/weapon/grown/G = target - grown_seed = plant_controller.seeds[G.plantname] + grown_seed = SSplants.seeds[G.plantname] grown_reagents = G.reagents else if(istype(target,/obj/item/seeds)) @@ -87,12 +95,38 @@ to_chat(user, "[src] can tell you nothing about \the [target].") return - form_title = "[grown_seed.seed_name] (#[grown_seed.uid])" - var/dat = "

Plant data for [form_title]

" + last_seed = REF(grown_seed) + user.visible_message("[user] runs the scanner over \the [target].") - dat += "

General Data

" + last_reagents = list() + if(grown_reagents && grown_reagents.reagent_list && grown_reagents.reagent_list.len) + for(var/datum/reagent/R in grown_reagents.reagent_list) + last_reagents.Add(list(list( + "name" = R.name, + "volume" = grown_reagents.get_reagent_amount(R.id), + ))) + tgui_interact(user) + +/obj/item/device/analyzer/plant_analyzer/proc/print_report_verb() + set name = "Print Plant Report" + set category = "Object" + set src = usr + + if(usr.stat || usr.restrained() || usr.lying) + return + print_report(usr) + +/obj/item/device/analyzer/plant_analyzer/proc/print_report(var/mob/living/user) + var/datum/seed/grown_seed = locate(last_seed) + if(!istype(grown_seed)) + to_chat(user, "There is no scan data to print.") + return + + var/form_title = "[grown_seed.seed_name] (#[grown_seed.uid])" + var/dat = "

Plant data for [form_title]

" + dat += "

General Data

" dat += "" dat += "" dat += "" @@ -101,138 +135,156 @@ dat += "" dat += "
Endurance[grown_seed.get_trait(TRAIT_ENDURANCE)]
Yield[grown_seed.get_trait(TRAIT_YIELD)]
Potency[grown_seed.get_trait(TRAIT_POTENCY)]
" - if(grown_reagents && grown_reagents.reagent_list && grown_reagents.reagent_list.len) + if(LAZYLEN(last_reagents)) dat += "

Reagent Data

" - dat += "
This sample contains: " - for(var/datum/reagent/R in grown_reagents.reagent_list) - dat += "
- [R.name], [grown_reagents.get_reagent_amount(R.id)] unit(s)" + for(var/i in 1 to LAZYLEN(last_reagents)) + dat += "
- [last_reagents[i]["name"]], [last_reagents[i]["volume"]] unit(s)" dat += "

Other Data

" - if(grown_seed.get_trait(TRAIT_HARVEST_REPEAT)) - dat += "This plant can be harvested repeatedly.
" + var/list/tgui_data = grown_seed.get_tgui_analyzer_data() - if(grown_seed.get_trait(TRAIT_IMMUTABLE) == -1) - dat += "This plant is highly mutable.
" - else if(grown_seed.get_trait(TRAIT_IMMUTABLE) > 0) - dat += "This plant does not possess genetics that are alterable.
" + dat += jointext(tgui_data["trait_info"], "
\n") - if(grown_seed.get_trait(TRAIT_REQUIRES_NUTRIENTS)) - if(grown_seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) - dat += "It consumes a small amount of nutrient fluid.
" - else if(grown_seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2) - dat += "It requires a heavy supply of nutrient fluid.
" + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src)) + P.name = "paper - [form_title]" + P.info = "[dat]" + if(istype(user,/mob/living/carbon/human)) + user.put_in_hands(P) + user.visible_message("\The [src] spits out a piece of paper.") + return + +/datum/seed/proc/get_tgui_analyzer_data(mob/user) + var/list/data = list() + + data["name"] = seed_name + data["uid"] = uid + data["endurance"] = get_trait(TRAIT_ENDURANCE) + data["yield"] = get_trait(TRAIT_YIELD) + data["maturation_time"] = get_trait(TRAIT_MATURATION) + data["production_time"] = get_trait(TRAIT_PRODUCTION) + data["potency"] = get_trait(TRAIT_POTENCY) + + data["trait_info"] = list() + if(get_trait(TRAIT_HARVEST_REPEAT)) + data["trait_info"] += "This plant can be harvested repeatedly." + + if(get_trait(TRAIT_IMMUTABLE) == -1) + data["trait_info"] += "This plant is highly mutable." + else if(get_trait(TRAIT_IMMUTABLE) > 0) + data["trait_info"] += "This plant does not possess genetics that are alterable." + + if(get_trait(TRAIT_REQUIRES_NUTRIENTS)) + if(get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) + data["trait_info"] += "It consumes a small amount of nutrient fluid." + else if(get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2) + data["trait_info"] += "It requires a heavy supply of nutrient fluid." else - dat += "It requires a supply of nutrient fluid.
" + data["trait_info"] += "It requires a supply of nutrient fluid." - if(grown_seed.get_trait(TRAIT_REQUIRES_WATER)) - if(grown_seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1) - dat += "It requires very little water.
" - else if(grown_seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5) - dat += "It requires a large amount of water.
" + if(get_trait(TRAIT_REQUIRES_WATER)) + if(get_trait(TRAIT_WATER_CONSUMPTION) < 1) + data["trait_info"] += "It requires very little water." + else if(get_trait(TRAIT_WATER_CONSUMPTION) > 5) + data["trait_info"] += "It requires a large amount of water." else - dat += "It requires a stable supply of water.
" + data["trait_info"] += "It requires a stable supply of water." - if(grown_seed.mutants && grown_seed.mutants.len) - dat += "It exhibits a high degree of potential subspecies shift.
" + if(mutants && mutants.len) + data["trait_info"] += "It exhibits a high degree of potential subspecies shift." - dat += "It thrives in a temperature of [grown_seed.get_trait(TRAIT_IDEAL_HEAT)] Kelvin." + data["trait_info"] += "It thrives in a temperature of [get_trait(TRAIT_IDEAL_HEAT)] Kelvin." - if(grown_seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) - dat += "
It is well adapted to low pressure levels." - if(grown_seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) - dat += "
It is well adapted to high pressure levels." + if(get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) + data["trait_info"] += "It is well adapted to low pressure levels." + if(get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) + data["trait_info"] += "It is well adapted to high pressure levels." - if(grown_seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30) - dat += "
It is well adapted to a range of temperatures." - else if(grown_seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10) - dat += "
It is very sensitive to temperature shifts." + if(get_trait(TRAIT_HEAT_TOLERANCE) > 30) + data["trait_info"] += "It is well adapted to a range of temperatures." + else if(get_trait(TRAIT_HEAT_TOLERANCE) < 10) + data["trait_info"] += "It is very sensitive to temperature shifts." - dat += "
It thrives in a light level of [grown_seed.get_trait(TRAIT_IDEAL_LIGHT)] lumen[grown_seed.get_trait(TRAIT_IDEAL_LIGHT) == 1 ? "" : "s"]." + data["trait_info"] += "It thrives in a light level of [get_trait(TRAIT_IDEAL_LIGHT)] lumen[get_trait(TRAIT_IDEAL_LIGHT) == 1 ? "" : "s"]." - if(grown_seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10) - dat += "
It is well adapted to a range of light levels." - else if(grown_seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3) - dat += "
It is very sensitive to light level shifts." + if(get_trait(TRAIT_LIGHT_TOLERANCE) > 10) + data["trait_info"] += "It is well adapted to a range of light levels." + else if(get_trait(TRAIT_LIGHT_TOLERANCE) < 3) + data["trait_info"] += "It is very sensitive to light level shifts." - if(grown_seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3) - dat += "
It is highly sensitive to toxins." - else if(grown_seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6) - dat += "
It is remarkably resistant to toxins." + if(get_trait(TRAIT_TOXINS_TOLERANCE) < 3) + data["trait_info"] += "It is highly sensitive to toxins." + else if(get_trait(TRAIT_TOXINS_TOLERANCE) > 6) + data["trait_info"] += "It is remarkably resistant to toxins." - if(grown_seed.get_trait(TRAIT_PEST_TOLERANCE) < 3) - dat += "
It is highly sensitive to pests." - else if(grown_seed.get_trait(TRAIT_PEST_TOLERANCE) > 6) - dat += "
It is remarkably resistant to pests." + if(get_trait(TRAIT_PEST_TOLERANCE) < 3) + data["trait_info"] += "It is highly sensitive to pests." + else if(get_trait(TRAIT_PEST_TOLERANCE) > 6) + data["trait_info"] += "It is remarkably resistant to pests." - if(grown_seed.get_trait(TRAIT_WEED_TOLERANCE) < 3) - dat += "
It is highly sensitive to weeds." - else if(grown_seed.get_trait(TRAIT_WEED_TOLERANCE) > 6) - dat += "
It is remarkably resistant to weeds." + if(get_trait(TRAIT_WEED_TOLERANCE) < 3) + data["trait_info"] += "It is highly sensitive to weeds." + else if(get_trait(TRAIT_WEED_TOLERANCE) > 6) + data["trait_info"] += "It is remarkably resistant to weeds." - switch(grown_seed.get_trait(TRAIT_SPREAD)) + switch(get_trait(TRAIT_SPREAD)) if(1) - dat += "
It is able to be planted outside of a tray." + data["trait_info"] += "It is able to be planted outside of a tray." if(2) - dat += "
It is a robust and vigorous vine that will spread rapidly." + data["trait_info"] += "It is a robust and vigorous vine that will spread rapidly." - switch(grown_seed.get_trait(TRAIT_CARNIVOROUS)) + switch(get_trait(TRAIT_CARNIVOROUS)) if(1) - dat += "
It is carnivorous and will eat tray pests for sustenance." + data["trait_info"] += "It is carnivorous and will eat tray pests for sustenance." if(2) - dat += "
It is carnivorous and poses a significant threat to living things around it." + data["trait_info"] += "It is carnivorous and poses a significant threat to living things around it." - if(grown_seed.get_trait(TRAIT_PARASITE)) - dat += "
It is capable of parisitizing and gaining sustenance from tray weeds." + if(get_trait(TRAIT_PARASITE)) + data["trait_info"] += "It is capable of parisitizing and gaining sustenance from tray weeds." /* There's currently no code that actually changes the temperature of the local environment, so let's not show it until there is. - if(grown_seed.get_trait(TRAIT_ALTER_TEMP)) - dat += "
It will periodically alter the local temperature by [grown_seed.get_trait(TRAIT_ALTER_TEMP)] degrees Kelvin." + if(get_trait(TRAIT_ALTER_TEMP)) + data["trait_info"] += "It will periodically alter the local temperature by [get_trait(TRAIT_ALTER_TEMP)] degrees Kelvin." */ - if(grown_seed.get_trait(TRAIT_BIOLUM)) - dat += "
It is [grown_seed.get_trait(TRAIT_BIOLUM_COLOUR) ? "bio-luminescent" : "bio-luminescent"]." + if(get_trait(TRAIT_BIOLUM)) + data["trait_info"] += "It is [get_trait(TRAIT_BIOLUM_COLOUR) ? "bio-luminescent" : "bio-luminescent"]." - if(grown_seed.get_trait(TRAIT_PRODUCES_POWER)) - dat += "
The fruit will function as a battery if prepared appropriately." + if(get_trait(TRAIT_PRODUCES_POWER)) + data["trait_info"] += "The fruit will function as a battery if prepared appropriately." - if(grown_seed.get_trait(TRAIT_STINGS)) - dat += "
The fruit is covered in stinging spines." + if(get_trait(TRAIT_STINGS)) + data["trait_info"] += "The fruit is covered in stinging spines." - if(grown_seed.get_trait(TRAIT_JUICY) == 1) - dat += "
The fruit is soft-skinned and juicy." - else if(grown_seed.get_trait(TRAIT_JUICY) == 2) - dat += "
The fruit is excessively juicy." + if(get_trait(TRAIT_JUICY) == 1) + data["trait_info"] += "The fruit is soft-skinned and juicy." + else if(get_trait(TRAIT_JUICY) == 2) + data["trait_info"] += "The fruit is excessively juicy." - if(grown_seed.get_trait(TRAIT_EXPLOSIVE)) - dat += "
The fruit is internally unstable." + if(get_trait(TRAIT_EXPLOSIVE)) + data["trait_info"] += "The fruit is internally unstable." - if(grown_seed.get_trait(TRAIT_TELEPORTING)) - dat += "
The fruit is temporal/spatially unstable." + if(get_trait(TRAIT_TELEPORTING)) + data["trait_info"] += "The fruit is temporal/spatially unstable." - if(grown_seed.exude_gasses && grown_seed.exude_gasses.len) - for(var/gas in grown_seed.exude_gasses) + if(exude_gasses && exude_gasses.len) + for(var/gas in exude_gasses) var/amount = "" - if (grown_seed.exude_gasses[gas] > 7) + if (exude_gasses[gas] > 7) amount = "large amounts of " - else if (grown_seed.exude_gasses[gas] < 5) + else if (exude_gasses[gas] < 5) amount = "small amounts of " - dat += "
It will release [amount][gas_data.name[gas]] into the environment." + data["trait_info"] += "It will release [amount][gas_data.name[gas]] into the environment." - if(grown_seed.consume_gasses && grown_seed.consume_gasses.len) - for(var/gas in grown_seed.consume_gasses) + if(consume_gasses && consume_gasses.len) + for(var/gas in consume_gasses) var/amount = "" - if (grown_seed.consume_gasses[gas] > 7) + if (consume_gasses[gas] > 7) amount = "large amounts of " - else if (grown_seed.consume_gasses[gas] < 5) + else if (consume_gasses[gas] < 5) amount = "small amounts of " - dat += "
It will consume [amount][gas_data.name[gas]] from the environment." + data["trait_info"] += "It will consume [amount][gas_data.name[gas]] from the environment." - if(dat) - last_data = dat - dat += "

\[print report\]" - user << browse(dat,"window=plant_analyzer") - - return + return data diff --git a/code/modules/hydroponics/trays/tray_update_icons.dm b/code/modules/hydroponics/trays/tray_update_icons.dm index d443b48275..fc00e97ee8 100644 --- a/code/modules/hydroponics/trays/tray_update_icons.dm +++ b/code/modules/hydroponics/trays/tray_update_icons.dm @@ -35,7 +35,7 @@ if(dead) var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-dead" - var/image/dead_overlay = plant_controller.plant_icon_cache["[ikey]"] + var/image/dead_overlay = SSplants.plant_icon_cache["[ikey]"] if(!dead_overlay) dead_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]") dead_overlay.color = DEAD_PLANT_COLOUR @@ -55,23 +55,23 @@ maturation = 1 overlay_stage = maturation ? max(1,round(age/maturation)) : 1 var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-[overlay_stage]" - var/image/plant_overlay = plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] + var/image/plant_overlay = SSplants.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] if(frozen == 1) plant_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]") plant_overlay.color = FROZEN_PLANT_COLOUR if(!plant_overlay) plant_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]") plant_overlay.color = seed.get_trait(TRAIT_PLANT_COLOUR) - plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] = plant_overlay + SSplants.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] = plant_overlay add_overlay(plant_overlay) if(harvest && overlay_stage == seed.growth_stages) ikey = "[seed.get_trait(TRAIT_PRODUCT_ICON)]" - var/image/harvest_overlay = plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] + var/image/harvest_overlay = SSplants.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] if(!harvest_overlay) harvest_overlay = image('icons/obj/hydroponics_products.dmi', "[ikey]") harvest_overlay.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) - plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"] = harvest_overlay + SSplants.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"] = harvest_overlay add_overlay(harvest_overlay) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index aea7ffc4ea..9cdd8a2e6e 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -47,87 +47,125 @@ IC.power_fail() - - -/obj/item/device/electronic_assembly/proc/resolve_nano_host() - return src - /obj/item/device/electronic_assembly/proc/check_interactivity(mob/user) - if(!CanInteract(user, physical_state)) - return 0 - return 1 + return tgui_status(user, GLOB.tgui_physical_state) == STATUS_INTERACTIVE /obj/item/device/electronic_assembly/get_cell() return battery -/obj/item/device/electronic_assembly/interact(mob/user) - if(!check_interactivity(user)) - return +// TGUI +/obj/item/device/electronic_assembly/tgui_state(mob/user) + return GLOB.tgui_physical_state + +/obj/item/device/electronic_assembly/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ICAssembly", name, parent_ui) + ui.open() + +/obj/item/device/electronic_assembly/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() var/total_parts = 0 var/total_complexity = 0 for(var/obj/item/integrated_circuit/part in contents) total_parts += part.size total_complexity = total_complexity + part.complexity - var/HTML = list() - HTML += "[src.name]" - HTML += "
\[Refresh\] | " - HTML += "\[Rename\]
" - HTML += "[total_parts]/[max_components] ([round((total_parts / max_components) * 100, 0.1)]%) space taken up in the assembly.
" - HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.
" - if(battery) - HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. \[Remove\]
" - HTML += "Net energy: [format_SI(net_power / CELLRATE, "W")]." - else - HTML += "No powercell detected!" - HTML += "

" - HTML += "Components:
" - HTML += "Built in:
" + data["total_parts"] = total_parts + data["max_components"] = max_components + data["total_complexity"] = total_complexity + data["max_complexity"] = max_complexity + data["battery_charge"] = round(battery?.charge, 0.1) + data["battery_max"] = round(battery?.maxcharge, 0.1) + data["net_power"] = net_power / CELLRATE -//Put removable circuits in separate categories from non-removable + // This works because lists are always passed by reference in BYOND, so modifying unremovable_circuits + // after setting data["unremovable_circuits"] = unremovable_circuits also modifies data["unremovable_circuits"] + // Same for the removable one + var/list/unremovable_circuits = list() + data["unremovable_circuits"] = unremovable_circuits + var/list/removable_circuits = list() + data["removable_circuits"] = removable_circuits for(var/obj/item/integrated_circuit/circuit in contents) - if(!circuit.removable) - HTML += "[circuit.displayed_name] | " - HTML += "\[Rename\] | " - HTML += "\[Scan with Debugger\] | " - HTML += "\[Move to Bottom\]" - HTML += "
" + var/list/target = circuit.removable ? removable_circuits : unremovable_circuits + target.Add(list(list( + "name" = circuit.displayed_name, + "ref" = REF(circuit), + ))) - HTML += "
" - HTML += "Removable:
" + return data - for(var/obj/item/integrated_circuit/circuit in contents) - if(circuit.removable) - HTML += "[circuit.displayed_name] | " - HTML += "\[Rename\] | " - HTML += "\[Scan with Debugger\] | " - HTML += "\[Remove\] | " - HTML += "\[Move to Bottom\]" - HTML += "
" - - HTML += "" - user << browse(jointext(HTML,null), "window=assembly-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") - -/obj/item/device/electronic_assembly/Topic(href, href_list[]) +/obj/item/device/electronic_assembly/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE - if(href_list["rename"]) - rename(usr) + var/obj/held_item = usr.get_active_hand() - if(href_list["remove_cell"]) - if(!battery) - to_chat(usr, "There's no power cell to remove from \the [src].") - else + switch(action) + // Actual assembly actions + if("rename") + rename(usr) + return TRUE + + if("remove_cell") + if(!battery) + to_chat(usr, "There's no power cell to remove from \the [src].") + return FALSE var/turf/T = get_turf(src) battery.forceMove(T) playsound(T, 'sound/items/Crowbar.ogg', 50, 1) to_chat(usr, "You pull \the [battery] out of \the [src]'s power supplier.") battery = null + return TRUE - interact(usr) // To refresh the UI. + // Circuit actions + if("open_circuit") + var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents + if(!istype(C)) + return + C.tgui_interact(usr, null, ui) + return TRUE + + if("rename_circuit") + var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents + if(!istype(C)) + return + C.rename_component(usr) + return TRUE + + if("scan_circuit") + var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents + if(!istype(C)) + return + if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/D = held_item + if(D.accepting_refs) + D.afterattack(C, usr, TRUE) + else + to_chat(usr, "The Debugger's 'ref scanner' needs to be on.") + else + to_chat(usr, "You need a multitool/debugger set to 'ref' mode to do that.") + return TRUE + + if("remove_circuit") + var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents + if(!istype(C)) + return + C.remove(usr) + return TRUE + + if("bottom_circuit") + var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents + if(!istype(C)) + return + // Puts it at the bottom of our contents + // Note, this intentionally does *not* use forceMove, because forceMove will stop if it detects the same loc + C.loc = null + C.loc = src + return FALSE +// End TGUI /obj/item/device/electronic_assembly/verb/rename() set name = "Rename Circuit" @@ -177,7 +215,7 @@ for(var/obj/item/integrated_circuit/IC in contents) . += IC.external_examine(user) if(opened) - interact(user) + tgui_interact(user) /obj/item/device/electronic_assembly/proc/get_part_complexity() . = 0 @@ -249,7 +287,7 @@ if(add_circuit(I, user)) to_chat(user, "You slide \the [I] inside \the [src].") playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) - interact(user) + tgui_interact(user) return TRUE else if(I.is_crowbar()) @@ -261,7 +299,7 @@ else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger) || I.is_screwdriver()) if(opened) - interact(user) + tgui_interact(user) return TRUE else to_chat(user, "\The [src] isn't opened, so you can't fiddle with the internal components. \ @@ -286,7 +324,7 @@ battery = cell playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) to_chat(user, "You slot \the [cell] inside \the [src]'s power supplier.") - interact(user) + tgui_interact(user) return TRUE else @@ -296,7 +334,7 @@ if(!check_interactivity(user)) return if(opened) - interact(user) + tgui_interact(user) var/list/input_selection = list() var/list/available_inputs = list() diff --git a/code/modules/integrated_electronics/core/assemblies/clothing.dm b/code/modules/integrated_electronics/core/assemblies/clothing.dm index 23e84da6d6..98af46f71d 100644 --- a/code/modules/integrated_electronics/core/assemblies/clothing.dm +++ b/code/modules/integrated_electronics/core/assemblies/clothing.dm @@ -12,11 +12,8 @@ max_complexity = IC_COMPLEXITY_BASE var/obj/item/clothing/clothing = null -/obj/item/device/electronic_assembly/clothing/nano_host() - return clothing - -/obj/item/device/electronic_assembly/clothing/resolve_nano_host() - return clothing +/obj/item/device/electronic_assembly/clothing/tgui_host() + return clothing.tgui_host() /obj/item/device/electronic_assembly/clothing/update_icon() ..() diff --git a/code/modules/integrated_electronics/core/assemblies/implant.dm b/code/modules/integrated_electronics/core/assemblies/implant.dm index 11db537768..cb40e31706 100644 --- a/code/modules/integrated_electronics/core/assemblies/implant.dm +++ b/code/modules/integrated_electronics/core/assemblies/implant.dm @@ -10,11 +10,8 @@ max_complexity = IC_COMPLEXITY_BASE / 2 var/obj/item/weapon/implant/integrated_circuit/implant = null -/obj/item/device/electronic_assembly/implant/nano_host() - return implant - -/obj/item/device/electronic_assembly/implant/resolve_nano_host() - return implant +/obj/item/device/electronic_assembly/implant/tgui_host() + return implant.tgui_host() /obj/item/device/electronic_assembly/implant/update_icon() ..() diff --git a/code/modules/integrated_electronics/core/detailer.dm b/code/modules/integrated_electronics/core/detailer.dm index 4c1c509384..adc0886174 100644 --- a/code/modules/integrated_electronics/core/detailer.dm +++ b/code/modules/integrated_electronics/core/detailer.dm @@ -7,7 +7,7 @@ w_class = ITEMSIZE_SMALL var/detail_color = COLOR_ASSEMBLY_WHITE var/list/color_list = list( - "black" = COLOR_ASSEMBLY_BLACK, + "dark gray" = COLOR_ASSEMBLY_BLACK, "machine gray" = COLOR_ASSEMBLY_BGRAY, "white" = COLOR_ASSEMBLY_WHITE, "red" = COLOR_ASSEMBLY_RED, @@ -35,11 +35,42 @@ detail_overlay.color = detail_color add_overlay(detail_overlay) +/obj/item/device/integrated_electronics/detailer/tgui_state(mob/user) + return GLOB.tgui_inventory_state + +/obj/item/device/integrated_electronics/detailer/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ICDetailer", name) + ui.open() + +/obj/item/device/integrated_electronics/detailer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["detail_color"] = detail_color + data["color_list"] = color_list + return data + +/obj/item/device/integrated_electronics/detailer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + switch(action) + if("change_color") + if(!(params["color"] in color_list)) + return // to prevent href exploits causing runtimes + detail_color = color_list[params["color"]] + update_icon() + return TRUE + /obj/item/device/integrated_electronics/detailer/attack_self(mob/user) - var/color_choice = input(user, "Select color.", "Assembly Detailer", detail_color) as null|anything in color_list - if(!color_list[color_choice]) - return - if(!in_range(src, user)) - return - detail_color = color_list[color_choice] - update_icon() + tgui_interact(user) + + // Leaving this commented out in case someone decides that this would be better as an "any color" selection system + // Just uncomment this and get rid of all of the TGUI bullshit lol + // if(!in_range(user, src)) + // return + // var/new_color = input(user, "Pick a color", "Color Selection", detail_color) as color|null + // if(!new_color) + // return + // detail_color = new_color + // update_icon() \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index 297ab72654..2253d67702 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -6,7 +6,7 @@ a creative player the means to solve many problems. Circuits are held inside an /obj/item/integrated_circuit/examine(mob/user) . = ..() . += external_examine(user) - interact(user) + tgui_interact(user) // This should be used when someone is examining while the case is opened. /obj/item/integrated_circuit/proc/internal_examine(mob/user) @@ -22,7 +22,7 @@ a creative player the means to solve many problems. Circuits are held inside an if(A.linked.len) . += "The '[A]' is connected to [A.get_linked_to_desc()]." . += any_examine(user) - interact(user) + tgui_interact(user) // This should be used when someone is examining from an 'outside' perspective, e.g. reading a screen or LED. /obj/item/integrated_circuit/proc/external_examine(mob/user) @@ -52,22 +52,12 @@ a creative player the means to solve many problems. Circuits are held inside an qdel(A) . = ..() -/obj/item/integrated_circuit/nano_host() - if(istype(src.loc, /obj/item/device/electronic_assembly)) - var/obj/item/device/electronic_assembly/assembly = loc - return assembly.resolve_nano_host() - return ..() - /obj/item/integrated_circuit/emp_act(severity) for(var/datum/integrated_io/io in inputs + outputs + activators) io.scramble() /obj/item/integrated_circuit/proc/check_interactivity(mob/user) - if(assembly) - return assembly.check_interactivity(user) - else if(!CanInteract(user, physical_state)) - return 0 - return 1 + return tgui_status(user, GLOB.tgui_physical_state) == STATUS_INTERACTIVE /obj/item/integrated_circuit/verb/rename_component() set name = "Rename Circuit" @@ -83,274 +73,169 @@ a creative player the means to solve many problems. Circuits are held inside an to_chat(M, "The circuit '[src.name]' is now labeled '[input]'.") displayed_name = input -/obj/item/integrated_circuit/interact(mob/user) - if(!check_interactivity(user)) - return -// if(!assembly) -// return +/obj/item/integrated_circuit/tgui_state(mob/user) + return GLOB.tgui_physical_state - var/window_height = 350 - var/window_width = 600 +/obj/item/integrated_circuit/tgui_host(mob/user) + if(istype(loc, /obj/item/device/electronic_assembly)) + return loc.tgui_host() + return ..() - //var/table_edge_width = "[(window_width - window_width * 0.1) / 4]px" - //var/table_middle_width = "[(window_width - window_width * 0.1) - (table_edge_width * 2)]px" - var/table_edge_width = "30%" - var/table_middle_width = "40%" +/obj/item/integrated_circuit/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ICCircuit", name, parent_ui) + ui.open() - var/HTML = list() - HTML += "[src.displayed_name]" - HTML += "
" - HTML += "" +/obj/item/integrated_circuit/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - HTML += "
\[Return to Assembly\]" + data["name"] = name + data["desc"] = desc + data["displayed_name"] = displayed_name + data["removable"] = removable - HTML += "
\[Refresh\] | " - HTML += "\[Rename\] | " - HTML += "\[Scan with Device\] | " - if(src.removable) - HTML += "\[Remove\]
" + data["complexity"] = complexity + data["power_draw_idle"] = power_draw_idle + data["power_draw_per_use"] = power_draw_per_use + data["extended_desc"] = extended_desc - HTML += "" - HTML += "" - HTML += "" - HTML += "" - HTML += "" + data["inputs"] = list() + for(var/datum/integrated_io/io in inputs) + data["inputs"].Add(list(tgui_pin_data(io))) - var/column_width = 3 - var/row_height = max(inputs.len, outputs.len, 1) + data["outputs"] = list() + for(var/datum/integrated_io/io in outputs) + data["outputs"].Add(list(tgui_pin_data(io))) - for(var/i = 1 to row_height) - HTML += "" - for(var/j = 1 to column_width) - var/datum/integrated_io/io = null - var/words = list() - var/height = 1 - switch(j) - if(1) - io = get_pin_ref(IC_INPUT, i) - if(io) - words += "[io.display_pin_type()] [io.name] [io.display_data(io.data)]
" - if(io.linked.len) - for(var/datum/integrated_io/linked in io.linked) -// words += "\[[linked.name]\] - words += "[linked.name] \ - @ [linked.holder.displayed_name]
" + data["activators"] = list() + for(var/datum/integrated_io/io in activators) + var/list/activator = list( + "ref" = REF(io), + "name" = io.name, + "pulse_out" = io.data, + "linked" = list() + ) + for(var/datum/integrated_io/linked in io.linked) + activator["linked"].Add(list(list( + "ref" = REF(linked), + "name" = linked.name, + "holder_ref" = REF(linked.holder), + "holder_name" = linked.holder.displayed_name, + ))) - if(outputs.len > inputs.len) - height = 1 - if(2) - if(i == 1) - words += "[src.displayed_name]
[src.name != src.displayed_name ? "([src.name])":""]
[src.desc]" - height = row_height - else - continue - if(3) - io = get_pin_ref(IC_OUTPUT, i) - if(io) - words += "[io.display_pin_type()] [io.name] [io.display_data(io.data)]
" - if(io.linked.len) - for(var/datum/integrated_io/linked in io.linked) -// words += "\[[linked.name]\] - words += "[linked.name] \ - @ [linked.holder.displayed_name]
" + data["activators"].Add(list(activator)) - if(inputs.len > outputs.len) - height = 1 - HTML += "" - HTML += "" + return data - for(var/activator in activators) - var/datum/integrated_io/io = activator - var/words = list() +/obj/item/integrated_circuit/proc/tgui_pin_data(datum/integrated_io/io) + if(!istype(io)) + return list() + var/list/pindata = list() + pindata["type"] = io.display_pin_type() + pindata["name"] = io.name + pindata["data"] = io.display_data(io.data) + pindata["ref"] = REF(io) + pindata["linked"] = list() + for(var/datum/integrated_io/linked in io.linked) + pindata["linked"].Add(list(list( + "ref" = REF(linked), + "name" = linked.name, + "holder_ref" = REF(linked.holder), + "holder_name" = linked.holder.displayed_name, + ))) + return pindata - words += "[io.name] [io.data?"\":"\"]
" - if(io.linked.len) - for(var/datum/integrated_io/linked in io.linked) -// words += "\[[linked.name]\] - words += "[linked.name] \ - @ [linked.holder.displayed_name]
" - - HTML += "" - HTML += "" - HTML += "" - - HTML += "
[jointext(words, null)]
[jointext(words, null)]
" - HTML += "
" - -// HTML += "
Meta Variables;" // If more meta vars get introduced, uncomment this. -// HTML += "
" - - HTML += "
Complexity: [complexity]" - if(power_draw_idle) - HTML += "
Power Draw: [power_draw_idle] W (Idle)" - if(power_draw_per_use) - HTML += "
Power Draw: [power_draw_per_use] W (Active)" // Borgcode says that powercells' checked_use() takes joules as input. - HTML += "
[extended_desc]" - - HTML += "" - if(src.assembly) - user << browse(jointext(HTML, null), "window=assembly-\ref[src.assembly];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") - else - user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") - - onclose(user, "assembly-\ref[src.assembly]") - -/obj/item/integrated_circuit/Topic(href, href_list, state = interactive_state) - if(!check_interactivity(usr)) - return +/obj/item/integrated_circuit/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE - var/update = 1 - var/obj/item/device/electronic_assembly/A = src.assembly - var/update_to_assembly = 0 - var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators + var/datum/integrated_io/pin = locate(params["pin"]) in inputs + outputs + activators var/datum/integrated_io/linked = null - if(href_list["link"]) - linked = locate(href_list["link"]) in pin.linked + + if(params["link"]) + linked = locate(params["link"]) in pin.linked var/obj/held_item = usr.get_active_hand() - if(href_list["rename"]) - rename_component(usr) - if(href_list["from_assembly"]) - update = 0 - var/obj/item/device/electronic_assembly/ea = loc - if(istype(ea)) - ea.interact(usr) - - if(href_list["pin_name"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = 1 - else - var/obj/item/device/multitool/M = held_item - M.wire(pin,usr) - - - - if(href_list["pin_data"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = 1 - - else - var/datum/integrated_io/io = pin - io.ask_for_pin_data(usr, held_item) // The pins themselves will determine how to ask for data, and will validate the data. - /* - if(io.io_type == DATA_CHANNEL) - - var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number", "null") - if(!check_interactivity(usr)) - return - - var/new_data = null - switch(type_to_use) - if("string") - new_data = input("Now type in a string.","[src] string writing") as null|text - to_chat(usr, "You input [new_data] into the pin.") - //to_chat(user, "You write '[new_data]' to the '[io]' pin of \the [io.holder].") - if("number") - new_data = input("Now type in a number.","[src] number writing") as null|num - if(isnum(new_data) && check_interactivity(usr) ) - to_chat(usr, "You input [new_data] into the pin.") - if("null") - if(check_interactivity(usr)) - to_chat(usr, "You clear the pin's memory.") - - io.write_data_to_pin(new_data) - - else if(io.io_type == PULSE_CHANNEL) - io.holder.check_then_do_work(ignore_power = TRUE) - to_chat(usr, "You pulse \the [io.holder]'s [io] pin.") - */ - - - if(href_list["pin_unwire"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = 1 - else - var/obj/item/device/multitool/M = held_item - M.unwire(pin, linked, usr) - - if(href_list["wire"]) - if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) - var/obj/item/device/integrated_electronics/wirer/wirer = held_item - if(linked) - wirer.wire(linked, usr) - else if(pin) - wirer.wire(pin, usr) - - else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) - var/obj/item/device/integrated_electronics/debugger/debugger = held_item - if(pin) - debugger.write_data(pin, usr) - else - to_chat(usr, "You can't do a whole lot without the proper tools.") - - if(href_list["examine"]) - var/obj/item/integrated_circuit/examined - if(href_list["examined"]) - examined = href_list["examined"] - else - examined = src - examined.interact(usr) - update = 0 - - if(href_list["bottom"]) - var/obj/item/integrated_circuit/circuit = locate(href_list["bottom"]) in src.assembly.contents - var/assy = circuit.assembly - if(!circuit) + . = TRUE + switch(action) + if("rename") + rename_component(usr) return - circuit.loc = null - circuit.loc = assy - . = 1 - update_to_assembly = 1 - if(href_list["scan"]) - if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) - var/obj/item/device/integrated_electronics/debugger/D = held_item - if(D.accepting_refs) - D.afterattack(src, usr, TRUE) + if("wire", "pin_name", "pin_data", "pin_unwire") + if(istype(held_item, /obj/item/device/multitool) && allow_multitool) + var/obj/item/device/multitool/M = held_item + switch(action) + if("pin_name") + M.wire(pin, usr) + if("pin_data") + var/datum/integrated_io/io = pin + io.ask_for_pin_data(usr, held_item) // The pins themselves will determine how to ask for data, and will validate the data. + if("pin_unwire") + M.unwire(pin, linked, usr) + + else if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = held_item + if(linked) + wirer.wire(linked, usr) + else if(pin) + wirer.wire(pin, usr) + + else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = held_item + if(pin) + debugger.write_data(pin, usr) else - to_chat(usr, "The Debugger's 'ref scanner' needs to be on.") - else - to_chat(usr, "You need a multitool/debugger set to 'ref' mode to do that.") - - if(href_list["return"]) - if(A) - update_to_assembly = 1 - usr << browse(null, "window=circuit-\ref[src];border=1;can_resize=1;can_close=1;can_minimize=1") - else - to_chat(usr, "This circuit is not in an assembly!") - - - if(href_list["remove"]) - if(!A) - to_chat(usr, "This circuit is not in an assembly!") + to_chat(usr, "You can't do a whole lot without the proper tools.") return - if(!removable) - to_chat(usr, "\The [src] seems to be permanently attached to the case.") - return - var/obj/item/device/electronic_assembly/ea = loc - power_fail() - disconnect_all() - var/turf/T = get_turf(src) - forceMove(T) - assembly = null - playsound(T, 'sound/items/Crowbar.ogg', 50, 1) - to_chat(usr, "You pop \the [src] out of the case, and slide it out.") - if(istype(ea)) - ea.interact(usr) - update = 0 + if("scan") + if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/D = held_item + if(D.accepting_refs) + D.afterattack(src, usr, TRUE) + else + to_chat(usr, "The Debugger's 'ref scanner' needs to be on.") + else + to_chat(usr, "You need a multitool/debugger set to 'ref' mode to do that.") + return + + + if("examine") + var/obj/item/integrated_circuit/examined = locate(params["ref"]) + if(istype(examined) && (examined.loc == loc)) + if(ui.parent_ui) + examined.tgui_interact(usr, null, ui.parent_ui) + else + examined.tgui_interact(usr) + + if("remove") + remove(usr) + return + return FALSE + +/obj/item/integrated_circuit/proc/remove(mob/user) + var/obj/item/device/electronic_assembly/A = assembly + if(!A) + to_chat(user, "This circuit is not in an assembly!") return + if(!removable) + to_chat(user, "\The [src] seems to be permanently attached to the case.") + return + var/obj/item/device/electronic_assembly/ea = loc - if(update) - if(A && istype(A) && update_to_assembly) - A.interact(usr) - else - interact(usr) // To refresh the UI. - + power_fail() + disconnect_all() + var/turf/T = get_turf(src) + forceMove(T) + assembly = null + playsound(T, 'sound/items/Crowbar.ogg', 50, 1) + to_chat(user, "You pop \the [src] out of the case, and slide it out.") + if(istype(ea)) + ea.tgui_interact(user) /obj/item/integrated_circuit/proc/push_data() for(var/datum/integrated_io/O in outputs) diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index cdf4652d5e..c5f3e05f13 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -13,8 +13,8 @@ var/upgraded = FALSE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits. var/can_clone = FALSE // Same for above, but will allow the printer to duplicate a specific assembly. (Not implemented) // var/static/list/recipe_list = list() - var/current_category = null - var/obj/item/device/electronic_assembly/assembly_to_clone = null + var/obj/item/device/electronic_assembly/assembly_to_clone = null // Not implemented x3 + var/dirty_items = FALSE /obj/item/device/integrated_circuit_printer/upgraded upgraded = TRUE @@ -47,7 +47,7 @@ if(stack.use(max(1, round(num)))) // We don't want to create stacks that aren't whole numbers to_chat(user, span("notice", "You add [num] sheet\s to \the [src].")) metal += num * metal_per_sheet - interact(user) + attack_self(user) return TRUE if(istype(O,/obj/item/integrated_circuit)) @@ -55,7 +55,7 @@ user.unEquip(O) metal = min(metal + O.w_class, max_metal) qdel(O) - interact(user) + attack_self(user) return TRUE if(istype(O,/obj/item/weapon/disk/integrated_circuit/upgrade/advanced)) @@ -64,7 +64,8 @@ return TRUE to_chat(user, span("notice", "You install \the [O] into \the [src].")) upgraded = TRUE - interact(user) + dirty_items = TRUE + attack_self(user) return TRUE if(istype(O,/obj/item/weapon/disk/integrated_circuit/upgrade/clone)) @@ -73,98 +74,126 @@ return TRUE to_chat(user, span("notice", "You install \the [O] into \the [src].")) can_clone = TRUE - interact(user) + attack_self(user) return TRUE return ..() +/obj/item/device/integrated_circuit_printer/vv_edit_var(var_name, var_value) + // Gotta update the static data in case an admin VV's the upgraded var for some reason..! + if(var_name == "upgraded") + dirty_items = TRUE + return ..() + /obj/item/device/integrated_circuit_printer/attack_self(var/mob/user) interact(user) + tgui_interact(user) -/obj/item/device/integrated_circuit_printer/interact(mob/user) - var/window_height = 600 - var/window_width = 500 +/obj/item/device/integrated_circuit_printer/tgui_state(mob/user) + return GLOB.tgui_inventory_state - if(isnull(current_category)) - current_category = SScircuit.circuit_fabricator_recipe_list[1] +/obj/item/device/integrated_circuit_printer/tgui_interact(mob/user, datum/tgui/ui) + if(dirty_items) + update_tgui_static_data(user, ui) + dirty_items = FALSE - var/HTML = "

Integrated Circuit Printer


" - if(!debug) - HTML += "Metal: [metal/metal_per_sheet]/[max_metal/metal_per_sheet] sheets.
" - else - HTML += "Metal: INFINITY.
" - HTML += "Circuits available: [upgraded ? "Advanced":"Regular"].
" - HTML += "Assembly Cloning: [can_clone ? "Available": "Unavailable"].
" - if(assembly_to_clone) - HTML += "Assembly '[assembly_to_clone.name]' loaded.
" - HTML += "Crossed out circuits mean that the printer is not sufficentally upgraded to create that circuit.
" - HTML += "
" - HTML += "Categories:" + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ICPrinter", name) // 500, 600 + ui.open() + +/obj/item/device/integrated_circuit_printer/tgui_static_data(mob/user) + var/list/data = ..() + + var/list/categories = list() for(var/category in SScircuit.circuit_fabricator_recipe_list) - if(category != current_category) - HTML += " \[[category]\] " - else // Bold the button if it's already selected. - HTML += " \[[category]\] " - HTML += "
" - HTML += "

[current_category]

" + var/list/cat_obj = list( + "name" = category, + "items" = list() + ) + var/list/circuit_list = SScircuit.circuit_fabricator_recipe_list[category] + for(var/path in circuit_list) + var/obj/O = path + var/can_build = TRUE + if(ispath(path, /obj/item/integrated_circuit)) + var/obj/item/integrated_circuit/IC = path + if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded) + can_build = FALSE - var/list/current_list = SScircuit.circuit_fabricator_recipe_list[current_category] - for(var/path in current_list) - var/obj/O = path - var/can_build = TRUE - if(ispath(path, /obj/item/integrated_circuit)) - var/obj/item/integrated_circuit/IC = path - if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded) - can_build = FALSE - if(can_build) - HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
" - else - HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
" + var/cost = 1 + if(ispath(path, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/E = path + cost = round((initial(E.max_complexity) + initial(E.max_components)) / 4) + else + var/obj/item/I = path + cost = initial(I.w_class) - user << browse(jointext(HTML, null), "window=integrated_printer;size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") + cat_obj["items"].Add(list(list( + "name" = initial(O.name), + "desc" = initial(O.desc), + "can_build" = can_build, + "cost" = cost, + "path" = path, + ))) + categories.Add(list(cat_obj)) + data["categories"] = categories + return data -/obj/item/device/integrated_circuit_printer/Topic(href, href_list) +/obj/item/device/integrated_circuit_printer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["metal"] = metal + data["max_metal"] = max_metal + data["metal_per_sheet"] = metal_per_sheet + data["debug"] = debug + data["upgraded"] = upgraded + data["can_clone"] = can_clone + data["assembly_to_clone"] = assembly_to_clone + + return data + +/obj/item/device/integrated_circuit_printer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE add_fingerprint(usr) - if(href_list["category"]) - current_category = href_list["category"] - - if(href_list["build"]) - var/build_type = text2path(href_list["build"]) - if(!build_type || !ispath(build_type)) - return 1 - - var/cost = 1 - - if(isnull(current_category)) - current_category = SScircuit.circuit_fabricator_recipe_list[1] - if(ispath(build_type, /obj/item/device/electronic_assembly)) - var/obj/item/device/electronic_assembly/E = build_type - cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4) - else - var/obj/item/I = build_type - cost = initial(I.w_class) - if(!(build_type in SScircuit.circuit_fabricator_recipe_list[current_category])) - return - - if(!debug) - if(!Adjacent(usr)) - to_chat(usr, "You are too far away from \the [src].") - if(metal - cost < 0) - to_chat(usr, "You need [cost] metal to build that!.") + switch(action) + if("build") + var/build_type = text2path(params["build"]) + if(!build_type || !ispath(build_type)) return 1 - metal -= cost - var/obj/item/built = new build_type(get_turf(loc)) - usr.put_in_hands(built) - to_chat(usr, "[capitalize(built.name)] printed.") - playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE) - interact(usr) + var/cost = 1 + if(ispath(build_type, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/E = build_type + cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4) + else + var/obj/item/I = build_type + cost = initial(I.w_class) + + var/in_some_category = FALSE + for(var/category in SScircuit.circuit_fabricator_recipe_list) + if(build_type in SScircuit.circuit_fabricator_recipe_list[category]) + in_some_category = TRUE + break + if(!in_some_category) + return + + if(!debug) + if(!Adjacent(usr)) + to_chat(usr, "You are too far away from \the [src].") + if(metal - cost < 0) + to_chat(usr, "You need [cost] metal to build that!.") + return 1 + metal -= cost + var/obj/item/built = new build_type(get_turf(loc)) + usr.put_in_hands(built) + to_chat(usr, "[capitalize(built.name)] printed.") + playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE) + return TRUE // FUKKEN UPGRADE DISKS /obj/item/weapon/disk/integrated_circuit/upgrade diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 879c7595a4..6bb1fc9939 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -185,7 +185,8 @@ Book Cart End var/title // The real name of the book. var/carved = 0 // Has the book been hollowed out for use as a secret storage item? var/obj/item/store //What's in the book? - drop_sound = 'sound/bureaucracy/bookclose.ogg' + drop_sound = 'sound/items/drop/book.ogg' + pickup_sound = 'sound/items/pickup/book.ogg' /obj/item/weapon/book/attack_self(var/mob/user as mob) if(carved) diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm index dd4a869e60..153e023ad0 100644 --- a/code/modules/materials/material_sheets.dm +++ b/code/modules/materials/material_sheets.dm @@ -18,6 +18,7 @@ var/perunit = SHEET_MATERIAL_AMOUNT var/apply_colour //temp pending icon rewrite drop_sound = 'sound/items/drop/axe.ogg' + pickup_sound = 'sound/items/pickup/axe.ogg' /obj/item/stack/material/New() ..() @@ -120,6 +121,7 @@ default_type = "sandstone" no_variants = FALSE drop_sound = 'sound/items/drop/boots.ogg' + pickup_sound = 'sound/items/pickup/boots.ogg' /obj/item/stack/material/marble name = "marble brick" @@ -127,12 +129,14 @@ default_type = "marble" no_variants = FALSE drop_sound = 'sound/items/drop/boots.ogg' + pickup_sound = 'sound/items/pickup/boots.ogg' /obj/item/stack/material/diamond name = "diamond" icon_state = "sheet-diamond" default_type = "diamond" drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/stack/material/uranium name = "uranium" @@ -146,6 +150,7 @@ default_type = "phoron" no_variants = FALSE drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/stack/material/plastic name = "plastic" @@ -342,6 +347,7 @@ default_type = MAT_WOOD strict_color_stacking = TRUE drop_sound = 'sound/items/drop/wooden.ogg' + pickup_sound = 'sound/items/pickup/wooden.ogg' /obj/item/stack/material/wood/sif name = "alien wooden plank" @@ -359,6 +365,7 @@ description_info = "Use inhand to craft things, or use a sharp and edged object on this to convert it into two wooden planks." var/plank_type = /obj/item/stack/material/wood drop_sound = 'sound/items/drop/wooden.ogg' + pickup_sound = 'sound/items/pickup/wooden.ogg' /obj/item/stack/material/log/sif name = "alien log" @@ -396,7 +403,8 @@ no_variants = FALSE pass_color = TRUE strict_color_stacking = TRUE - drop_sound = 'sound/items/drop/clothing.ogg' + drop_sound = 'sound/items/drop/cloth.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' /obj/item/stack/material/cloth/diyaab color = "#c6ccf0" @@ -417,7 +425,8 @@ no_variants = FALSE pass_color = TRUE strict_color_stacking = TRUE - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/stack/material/snow name = "snow" @@ -439,7 +448,8 @@ no_variants = FALSE pass_color = TRUE strict_color_stacking = TRUE - drop_sound = 'sound/items/drop/clothing.ogg' + drop_sound = 'sound/items/drop/leather.ogg' + pickup_sound = 'sound/items/pickup/leather.ogg' /obj/item/stack/material/glass name = "glass" @@ -447,6 +457,7 @@ default_type = "glass" no_variants = FALSE drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/stack/material/glass/reinforced name = "reinforced glass" diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm index 9da7e05148..ad16122b3f 100644 --- a/code/modules/mining/coins.dm +++ b/code/modules/mining/coins.dm @@ -13,6 +13,7 @@ var/string_attached var/sides = 2 drop_sound = 'sound/items/drop/ring.ogg' + pickup_sound = 'sound/items/pickup/ring.ogg' /obj/item/weapon/coin/New() randpixel_xy() diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm index 397b2ef1ce..2f388e2ba5 100644 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm @@ -42,8 +42,8 @@ EQUIPMENT("Defense Equipment - Sentry Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/ward, 1500), EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 100), EQUIPMENT("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500), - EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 500), EQUIPMENT("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), + EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 500), EQUIPMENT("Fulton Beacon", /obj/item/fulton_core, 500), EQUIPMENT("Geiger Counter", /obj/item/device/geiger, 750), EQUIPMENT("GPS Device", /obj/item/device/gps/mining, 100), @@ -54,9 +54,9 @@ ) prize_list["Consumables"] = list( - EQUIPMENT("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), - EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), + EQUIPMENT("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), + EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), + EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), EQUIPMENT("Fulton Pack", /obj/item/extraction_pack, 1200), EQUIPMENT("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), EQUIPMENT("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), @@ -71,14 +71,14 @@ ) prize_list["Kinetic Accelerator"] = list( EQUIPMENT("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 900), - EQUIPMENT("KA Adjustable Tracer Rounds",/obj/item/borg/upgrade/modkit/tracer/adjustable, 175), EQUIPMENT("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), EQUIPMENT("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), EQUIPMENT("KA Efficiency Increase", /obj/item/borg/upgrade/modkit/efficiency, 1200), - EQUIPMENT("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), - EQUIPMENT("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), EQUIPMENT("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), + EQUIPMENT("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), EQUIPMENT("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), + EQUIPMENT("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), + EQUIPMENT("KA Adjustable Tracer Rounds",/obj/item/borg/upgrade/modkit/tracer/adjustable, 175), EQUIPMENT("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125), ) prize_list["Digging Tools"] = list( @@ -91,6 +91,8 @@ EQUIPMENT("Fine Excavation Kit - Measuring Tape", /obj/item/device/measuring_tape, 125), EQUIPMENT("Fine Excavation Kit - Hand Pick", /obj/item/weapon/pickaxe/hand, 375), EQUIPMENT("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic/locked, 1500), + EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000), + EQUIPMENT("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500), ) prize_list["Hardsuit"] = list( EQUIPMENT("Hardsuit - Control Module", /obj/item/weapon/rig/industrial/vendor, 2000), @@ -104,14 +106,12 @@ ) prize_list["Miscellaneous"] = list( EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125), - EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000), EQUIPMENT("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), - EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), - EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000), - EQUIPMENT("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500), + EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), EQUIPMENT("Laser Pointer", /obj/item/device/laser_pointer, 900), EQUIPMENT("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), + EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000), EQUIPMENT("Plush Toy", /obj/random/plushie, 300), EQUIPMENT("Soap", /obj/item/weapon/soap/nanotrasen, 200), EQUIPMENT("Thalers - 100", /obj/item/weapon/spacecash/c100, 1000), diff --git a/code/modules/mining/ore_redemption_machine/survey_vendor.dm b/code/modules/mining/ore_redemption_machine/survey_vendor.dm index d69cfe3f27..1eb8672ef6 100644 --- a/code/modules/mining/ore_redemption_machine/survey_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/survey_vendor.dm @@ -14,55 +14,56 @@ //VOREStation Edit Start - Heavily modified list prize_list = list() prize_list["Gear"] = list( - EQUIPMENT("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500), - EQUIPMENT("Defense Equipment - Razor Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000), - EQUIPMENT("Defense Equipment - Sentry Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/ward, 1500), - EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 100), - EQUIPMENT("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500), - EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 500), - EQUIPMENT("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), - EQUIPMENT("Fulton Beacon", /obj/item/fulton_core, 500), - EQUIPMENT("Geiger Counter", /obj/item/device/geiger, 750), - EQUIPMENT("GPS Device", /obj/item/device/gps/mining, 100), - EQUIPMENT("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), - EQUIPMENT("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200), - EQUIPMENT("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 750), + EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 10), + EQUIPMENT("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 50), + EQUIPMENT("Defense Equipment - Razor Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 100), + EQUIPMENT("Defense Equipment - Sentry Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/ward, 150), + EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 50), + EQUIPMENT("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100), + EQUIPMENT("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750), + EQUIPMENT("Fulton Beacon", /obj/item/fulton_core, 300), + EQUIPMENT("Geiger Counter", /obj/item/device/geiger, 75), + EQUIPMENT("GPS Device", /obj/item/device/gps/mining, 10), + EQUIPMENT("Jump Boots", /obj/item/clothing/shoes/bhop, 250), + EQUIPMENT("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120), + EQUIPMENT("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 75), ) prize_list["Consumables"] = list( - EQUIPMENT("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), - EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), - EQUIPMENT("Fulton Pack", /obj/item/extraction_pack, 1200), - EQUIPMENT("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), - EQUIPMENT("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), - EQUIPMENT("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), - EQUIPMENT("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), - EQUIPMENT("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 500), - EQUIPMENT("Shelter Capsule", /obj/item/device/survivalcapsule, 500), - EQUIPMENT("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 250), - EQUIPMENT("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 250), - EQUIPMENT("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 250), - EQUIPMENT("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 250), + EQUIPMENT("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), + EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), + EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), + EQUIPMENT("Fulton Pack", /obj/item/extraction_pack, 125), + EQUIPMENT("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50), + EQUIPMENT("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 50), + EQUIPMENT("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 50), + EQUIPMENT("Nanopaste Tube", /obj/item/stack/nanopaste, 100), + EQUIPMENT("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 50), + EQUIPMENT("Shelter Capsule", /obj/item/device/survivalcapsule, 50), + EQUIPMENT("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 25), + EQUIPMENT("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 25), + EQUIPMENT("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 25), + EQUIPMENT("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 25), ) prize_list["Digging Tools"] = list( EQUIPMENT("Survey Tools - Shovel", /obj/item/weapon/shovel, 40), EQUIPMENT("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50), ) prize_list["Miscellaneous"] = list( - EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125), - EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000), - EQUIPMENT("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), - EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), - EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), - EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000), - EQUIPMENT("Laser Pointer", /obj/item/device/laser_pointer, 900), - EQUIPMENT("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), - EQUIPMENT("Plush Toy", /obj/random/plushie, 300), - EQUIPMENT("Soap", /obj/item/weapon/soap/nanotrasen, 200), - EQUIPMENT("Thalers - 100", /obj/item/weapon/spacecash/c100, 1000), - EQUIPMENT("Umbrella", /obj/item/weapon/melee/umbrella/random, 200), - EQUIPMENT("UAV - Recon Skimmer", /obj/item/device/uav, 400), - EQUIPMENT("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125), + EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10), + EQUIPMENT("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10), + EQUIPMENT("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15), + EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50), + EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100), + EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 300), + EQUIPMENT("Laser Pointer", /obj/item/device/laser_pointer, 90), + EQUIPMENT("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310), + EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 1000), + EQUIPMENT("Plush Toy", /obj/random/plushie, 30), + EQUIPMENT("Soap", /obj/item/weapon/soap/nanotrasen, 20), + EQUIPMENT("Thalers - 100", /obj/item/weapon/spacecash/c100, 100), + EQUIPMENT("Umbrella", /obj/item/weapon/melee/umbrella/random, 20), + EQUIPMENT("UAV - Recon Skimmer", /obj/item/device/uav, 40), + ) //VOREStation Edit End diff --git a/code/modules/mining/shelters_vr.dm b/code/modules/mining/shelters_vr.dm index e9839cafe7..abaee7d609 100644 --- a/code/modules/mining/shelters_vr.dm +++ b/code/modules/mining/shelters_vr.dm @@ -94,7 +94,7 @@ shelter_id = "shelter_epsilon" description = "An escape pod, with a mediocre amount of supplies \ for escaping a dying ship as soon as possible." - mappath = "maps/tether/submaps/om_ships/shelter_5.dmm" + mappath = "maps/offmap_vr/om_ships/shelter_5.dmm" /datum/map_template/shelter/zeta name = "Shelter Zeta" @@ -104,7 +104,7 @@ a shield generator, and extremely advanced technology. It is \ unknown who manufactued a vessel like this, as it is beyond the \ technology level of most contemporary powers." - mappath = "maps/tether/submaps/om_ships/shelter_6.dmm" + mappath = "maps/offmap_vr/om_ships/shelter_6.dmm" /datum/map_template/shelter/phi name = "Shelter Phi" diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index de87cd5d74..8aad27762b 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -208,6 +208,7 @@ var/list/holder_mob_icon_cache = list() to_chat(grabber, "You scoop up \the [src]!") to_chat(src, "\The [grabber] scoops you up!") + add_attack_logs(grabber, H.held_mob, "Scooped up", FALSE) // Not important enough to notify admins, but still helpful. H.sync(src) return H diff --git a/code/modules/mob/language/station_vr.dm b/code/modules/mob/language/station_vr.dm index 85db436c39..025543807d 100644 --- a/code/modules/mob/language/station_vr.dm +++ b/code/modules/mob/language/station_vr.dm @@ -148,6 +148,8 @@ flags = 0 /datum/language/gutter machine_understands = FALSE + desc = "A dialect of Tradeband not uncommon amongst traders in the Free Trade Union. The language is often difficult to translate due to changing frequently and being highly colloquial." + partial_understanding = list(LANGUAGE_TRADEBAND = 30, LANGUAGE_SOL_COMMON = 10) /datum/language/human/monkey flags = RESTRICTED /datum/language/skrell/monkey diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index 7512480374..de4c2a2d78 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -4,14 +4,15 @@ icon_state = "cleanbot0" req_one_access = list(access_robotics, access_janitor) botcard_access = list(access_janitor) + pass_flags = PASSTABLE locked = 0 // Start unlocked so roboticist can set them to patrol. wait_if_pulled = 1 min_target_dist = 0 var/cleaning = 0 - var/screwloose = 0 - var/oddbutton = 0 + var/wet_floors = 0 + var/spray_blood = 0 var/blood = 1 var/list/target_types = list() @@ -25,16 +26,16 @@ return ..() /mob/living/bot/cleanbot/handleIdle() - if(!screwloose && !oddbutton && prob(2)) + if(!wet_floors && !spray_blood && prob(2)) custom_emote(2, "makes an excited booping sound!") playsound(src, 'sound/machines/synth_yes.ogg', 50, 0) - if(screwloose && prob(5)) // Make a mess + if(wet_floors && prob(5)) // Make a mess if(istype(loc, /turf/simulated)) var/turf/simulated/T = loc T.wet_floor() - if(oddbutton && prob(5)) // Make a big mess + if(spray_blood && prob(5)) // Make a big mess visible_message("Something flies out of [src]. It seems to be acting oddly.") var/obj/effect/decal/cleanable/blood/gibs/gib = new /obj/effect/decal/cleanable/blood/gibs(loc) // TODO - I have a feeling weakrefs will not work in ignore_list, verify this ~Leshana @@ -149,56 +150,65 @@ icon_state = "cleanbot[on]" /mob/living/bot/cleanbot/attack_hand(var/mob/user) - var/dat - dat += "Automatic Station Cleaner v1.0

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" - dat += "Maintenance panel is [open ? "opened" : "closed"]" - if(!locked || issilicon(user)) - dat += "
Cleans Blood: [blood ? "Yes" : "No"]
" - if(using_map.bot_patrolling) - dat += "
Patrol station: [will_patrol ? "Yes" : "No"]
" - if(open && !locked) - dat += "Odd looking screw twiddled: [screwloose ? "Yes" : "No"]
" - dat += "Weird button pressed: [oddbutton ? "Yes" : "No"]" + tgui_interact(user) - user << browse("Cleaner v1.0 controls[dat]", "window=autocleaner") - onclose(user, "autocleaner") - return +/mob/living/bot/cleanbot/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Cleanbot", name) + ui.open() -/mob/living/bot/cleanbot/Topic(href, href_list) +/mob/living/bot/cleanbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["on"] = on + data["open"] = open + data["locked"] = locked + + data["blood"] = blood + data["patrol"] = will_patrol + + data["wet_floors"] = wet_floors + data["spray_blood"] = spray_blood + data["version"] = "v2.0" + return data + +/mob/living/bot/cleanbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return + return TRUE usr.set_machine(src) add_fingerprint(usr) - switch(href_list["operation"]) + switch(action) if("start") if(on) turn_off() else turn_on() + . = TRUE if("blood") blood = !blood get_targets() + . = TRUE if("patrol") will_patrol = !will_patrol patrol_path = null - if("screw") - screwloose = !screwloose + . = TRUE + if("wet_floors") + wet_floors = !wet_floors to_chat(usr, "You twiddle the screw.") - if("oddbutton") - oddbutton = !oddbutton + . = TRUE + if("spray_blood") + spray_blood = !spray_blood to_chat(usr, "You press the weird button.") - attack_hand(usr) + . = TRUE /mob/living/bot/cleanbot/emag_act(var/remaining_uses, var/mob/user) . = ..() - if(!screwloose || !oddbutton) + if(!wet_floors || !spray_blood) if(user) to_chat(user, "The [src] buzzes and beeps.") playsound(src, 'sound/machines/buzzbeep.ogg', 50, 0) - oddbutton = 1 - screwloose = 1 + spray_blood = 1 + wet_floors = 1 return 1 /mob/living/bot/cleanbot/proc/get_targets() diff --git a/code/modules/mob/living/bot/edCLNbot.dm b/code/modules/mob/living/bot/edCLNbot.dm index a7b9812b9f..b4d3dfbcca 100644 --- a/code/modules/mob/living/bot/edCLNbot.dm +++ b/code/modules/mob/living/bot/edCLNbot.dm @@ -71,53 +71,31 @@ qdel(src) return -/mob/living/bot/cleanbot/edCLN/attack_hand(var/mob/user) - var/dat - usr.set_machine(src) - add_fingerprint(usr) +/mob/living/bot/cleanbot/edCLN/tgui_data(mob/user) + var/list/data = ..() + data["version"] = "v3.0" + data["rgbpanel"] = TRUE + data["red_switch"] = red_switch + data["green_switch"] = green_switch + data["blue_switch"] = blue_switch + return data - dat += "Automatic Station Cleaner v2.0

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" - dat += "Maintenance panel is [open ? "opened" : "closed"]" - if(!locked || issilicon(user)) - dat += "
Cleans Blood: [blood ? "Yes" : "No"]
" - if(using_map.bot_patrolling) - dat += "
Patrol station: [will_patrol ? "Yes" : "No"]
" - if(open && !locked) - dat += "
Red Switch: [red_switch ? "On" : "Off"]
" - dat += "
Green Switch: [green_switch ? "On" : "Off"]
" - dat += "
Blue Switch: [blue_switch ? "On" : "Off"]" - - user << browse("Cleaner v2.0 controls[dat]", "window=autocleaner") - onclose(user, "autocleaner") - return - -/mob/living/bot/cleanbot/edCLN/Topic(href, href_list) - usr.set_machine(src) - add_fingerprint(usr) - switch(href_list["operation"]) - if("start") - if(on) - turn_off() - else - turn_on() - if("blood") - blood = !blood - get_targets() - if("patrol") - will_patrol = !will_patrol - patrol_path = null +/mob/living/bot/cleanbot/edCLN/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + switch(action) if("red_switch") red_switch = !red_switch to_chat(usr, "You flip the red switch [red_switch ? "on" : "off"].") + . = TRUE if("green_switch") - green_switch = !blue_switch + green_switch = !green_switch to_chat(usr, "You flip the green switch [green_switch ? "on" : "off"].") + . = TRUE if("blue_switch") blue_switch = !blue_switch to_chat(usr, "You flip the blue switch [blue_switch ? "on" : "off"].") - attack_hand(usr) + . = TRUE /mob/living/bot/cleanbot/edCLN/emag_act(var/remaining_uses, var/mob/user) . = ..() diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index 18bd3805c3..3172836d44 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -30,38 +30,45 @@ tank = newTank tank.forceMove(src) +/mob/living/bot/farmbot/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Farmbot", name) + ui.open() -/mob/living/bot/farmbot/attack_hand(var/mob/user as mob) +/mob/living/bot/farmbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["on"] = on + data["tank"] = !!tank + if(tank) + data["tankVolume"] = tank.reagents.total_volume + data["tankMaxVolume"] = tank.reagents.maximum_volume + data["locked"] = locked + + data["waters_trays"] = null + data["refills_water"] = null + data["uproots_weeds"] = null + data["replaces_nutriment"] = null + data["collects_produce"] = null + data["removes_dead"] = null + + if(!locked) + data["waters_trays"] = waters_trays + data["refills_water"] = refills_water + data["uproots_weeds"] = uproots_weeds + data["replaces_nutriment"] = replaces_nutriment + data["collects_produce"] = collects_produce + data["removes_dead"] = removes_dead + + return data + + +/mob/living/bot/farmbot/attack_hand(mob/user) . = ..() if(.) return - var/dat = "" - dat += "Automatic Hyrdoponic Assisting Unit v1.0

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Water Tank: " - if (tank) - dat += "[tank.reagents.total_volume]/[tank.reagents.maximum_volume]" - else - dat += "Error: Watertank not found" - dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]
" - if(!locked) - dat += "Watering controls:
" - dat += "Water plants : [waters_trays ? "Yes" : "No"]
" - dat += "Refill watertank : [refills_water ? "Yes" : "No"]
" - dat += "
Weeding controls:
" - dat += "Weed plants: [uproots_weeds ? "Yes" : "No"]
" - dat += "
Nutriment controls:
" - dat += "Replace fertilizer: [replaces_nutriment ? "Yes" : "No"]
" - /* VOREStation Removal - No whole-job lag-bot automation. - dat += "
Plant controls:
" - dat += "Collect produce: [collects_produce ? "Yes" : "No"]
" - dat += "Remove dead plants: [removes_dead ? "Yes" : "No"]
" - */ - dat += "
" - - user << browse("Farmbot v1.0 controls[dat]", "window=autofarm") - onclose(user, "autofarm") - return + tgui_interact(user) /mob/living/bot/farmbot/emag_act(var/remaining_charges, var/mob/user) . = ..() @@ -73,35 +80,47 @@ emagged = 1 return 1 -/mob/living/bot/farmbot/Topic(href, href_list) +/mob/living/bot/farmbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return - usr.machine = src + return TRUE + add_fingerprint(usr) - if((href_list["power"]) && (access_scanner.allowed(usr))) - if(on) - turn_off() - else - turn_on() + + switch(action) + if("power") + if(!access_scanner.allowed(usr)) + return FALSE + if(on) + turn_off() + else + turn_on() + . = TRUE if(locked) - return + return TRUE - if(href_list["water"]) - waters_trays = !waters_trays - else if(href_list["refill"]) - refills_water = !refills_water - else if(href_list["weed"]) - uproots_weeds = !uproots_weeds - else if(href_list["replacenutri"]) - replaces_nutriment = !replaces_nutriment - else if(href_list["collect"]) - collects_produce = !collects_produce - else if(href_list["removedead"]) - removes_dead = !removes_dead + switch(action) + if("water") + waters_trays = !waters_trays + . = TRUE + if("refill") + refills_water = !refills_water + . = TRUE + if("weed") + uproots_weeds = !uproots_weeds + . = TRUE + if("replacenutri") + replaces_nutriment = !replaces_nutriment + . = TRUE + // VOREStation Edit: No automatic hydroponics + // if("collect") + // collects_produce = !collects_produce + // . = TRUE + // if("removedead") + // removes_dead = !removes_dead + // . = TRUE + // VOREStation Edit End - attack_hand(usr) - return /mob/living/bot/farmbot/update_icons() if(on && action) @@ -109,13 +128,10 @@ else icon_state = "farmbot[on]" - /mob/living/bot/farmbot/handleRegular() if(emagged && prob(1)) flick("farmbot_broke", src) - - /mob/living/bot/farmbot/handleAdjacentTarget() UnarmedAttack(target) @@ -137,6 +153,7 @@ times_idle = 0 //VOREStation Add - Idle shutoff time return if(++times_idle == 150) turn_off() //VOREStation Add - Idle shutoff time + /mob/living/bot/farmbot/calcTargetPath() // We need to land NEXT to the tray, because the tray itself is impassable for(var/trayDir in list(NORTH, SOUTH, EAST, WEST)) target_path = AStar(get_turf(loc), get_step(get_turf(target), trayDir), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, max_target_dist, id = botcard) diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm index c34274a6ab..31d1dc0e25 100644 --- a/code/modules/mob/living/bot/floorbot.dm +++ b/code/modules/mob/living/bot/floorbot.dm @@ -29,28 +29,38 @@ else icon_state = "floorbot[on]e" -/mob/living/bot/floorbot/attack_hand(var/mob/user) - user.set_machine(src) - var/list/dat = list() - dat += "Automatic Station Floor Repairer v1.0

" - dat += "Status: [src.on ? "On" : "Off"]
" - dat += "Maintenance panel is [open ? "opened" : "closed"]
" - dat += "Tiles left: [amount]
" - dat += "Behvaiour controls are [locked ? "locked" : "unlocked"]
" +/mob/living/bot/floorbot/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Floorbot", name) + ui.open() + +/mob/living/bot/floorbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["on"] = on + data["open"] = open + data["locked"] = locked + + data["amount"] = amount + + data["possible_bmode"] = list("NORTH", "EAST", "SOUTH", "WEST") + + data["improvefloors"] = null + data["eattiles"] = null + data["maketiles"] = null + data["bmode"] = null + if(!locked || issilicon(user)) - dat += "Improves floors: [improvefloors ? "Yes" : "No"]
" - dat += "Finds tiles: [eattiles ? "Yes" : "No"]
" - dat += "Make singles pieces of metal into tiles when empty: [maketiles ? "Yes" : "No"]
" - var/bmode - if(targetdirection) - bmode = dir2text(targetdirection) - else - bmode = "Disabled" - dat += "

Bridge Mode : [bmode]
" - var/datum/browser/popup = new(user, "autorepair", "Repairbot v1.1 controls") - popup.set_content(jointext(dat,null)) - popup.open() - return + data["improvefloors"] = improvefloors + data["eattiles"] = eattiles + data["maketiles"] = maketiles + data["bmode"] = dir2text(targetdirection) + + return data + +/mob/living/bot/floorbot/attack_hand(var/mob/user) + tgui_interact(user) /mob/living/bot/floorbot/emag_act(var/remaining_charges, var/mob/user) . = ..() @@ -61,38 +71,36 @@ playsound(src, 'sound/machines/buzzbeep.ogg', 50, 0) return 1 -/mob/living/bot/floorbot/Topic(href, href_list) +/mob/living/bot/floorbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return - usr.set_machine(src) + return TRUE + add_fingerprint(usr) - switch(href_list["operation"]) + + switch(action) if("start") - if (on) + if(on) turn_off() else turn_on() + . = TRUE + + if(locked && !issilicon(usr)) + return + + switch(action) if("improve") improvefloors = !improvefloors + . = TRUE if("tiles") eattiles = !eattiles + . = TRUE if("make") maketiles = !maketiles + . = TRUE if("bridgemode") - switch(targetdirection) - if(null) - targetdirection = 1 - if(1) - targetdirection = 2 - if(2) - targetdirection = 4 - if(4) - targetdirection = 8 - if(8) - targetdirection = null - else - targetdirection = null - attack_hand(usr) + targetdirection = text2dir(params["dir"]) + . = TRUE /mob/living/bot/floorbot/handleRegular() ++tilemake diff --git a/code/modules/mob/living/bot/medbot.dm b/code/modules/mob/living/bot/medbot.dm index 68e803af87..828ca72da0 100644 --- a/code/modules/mob/living/bot/medbot.dm +++ b/code/modules/mob/living/bot/medbot.dm @@ -8,6 +8,11 @@ #define MEDBOT_PANIC_ENDING 90 #define MEDBOT_PANIC_END 100 +#define MEDBOT_MIN_INJECTION 5 +#define MEDBOT_MAX_INJECTION 15 +#define MEDBOT_MIN_HEAL 0.1 +#define MEDBOT_MAX_HEAL 75 + /mob/living/bot/medbot name = "Medibot" desc = "A little medical robot. He looks somewhat underwhelmed." @@ -209,45 +214,39 @@ if(do_after(H, 3 SECONDS, target=src)) set_right(H) else - interact(H) - + tgui_interact(H) -/mob/living/bot/medbot/proc/interact(mob/user) - var/dat - dat += "Automatic Medical Unit v1.0

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Maintenance panel is [open ? "opened" : "closed"]
" - dat += "Beaker: " - if (reagent_glass) - dat += "Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]" - else - dat += "None Loaded" - dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]
" +/mob/living/bot/medbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["on"] = on + data["open"] = open + data["beaker"] = FALSE + if(reagent_glass) + data["beaker"] = TRUE + data["beaker_total"] = reagent_glass.reagents.total_volume + data["beaker_max"] = reagent_glass.reagents.maximum_volume + data["locked"] = locked + data["heal_threshold"] = null + data["heal_threshold_max"] = MEDBOT_MAX_HEAL + data["injection_amount_min"] = MEDBOT_MIN_INJECTION + data["injection_amount"] = null + data["injection_amount_max"] = MEDBOT_MAX_INJECTION + data["use_beaker"] = null + data["declare_treatment"] = null + data["vocal"] = null if(!locked || issilicon(user)) - dat += "Healing Threshold: " - dat += "-- " - dat += "- " - dat += "[heal_threshold] " - dat += "+ " - dat += "++" - dat += "
" + data["heal_threshold"] = heal_threshold + data["injection_amount"] = injection_amount + data["use_beaker"] = use_beaker + data["declare_treatment"] = declare_treatment + data["vocal"] = vocal + return data - dat += "Injection Level: " - dat += "- " - dat += "[injection_amount] " - dat += "+ " - dat += "
" - - dat += "Reagent Source: " - dat += "[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]
" - - dat += "Treatment report is [declare_treatment ? "on" : "off"]. Toggle
" - - dat += "The speaker switch is [vocal ? "on" : "off"]. Toggle
" - - user << browse("Medibot v1.0 controls[dat]", "window=automed") - onclose(user, "automed") - return +/mob/living/bot/medbot/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Medbot", name) + ui.open() /mob/living/bot/medbot/attackby(var/obj/item/O, var/mob/user) if(istype(O, /obj/item/weapon/reagent_containers/glass)) @@ -266,51 +265,53 @@ else ..() -/mob/living/bot/medbot/Topic(href, href_list) +/mob/living/bot/medbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return + return TRUE + usr.set_machine(src) add_fingerprint(usr) - if ((href_list["power"]) && access_scanner.allowed(usr)) - if (on) - turn_off() - else - turn_on() + + . = TRUE + switch(action) + if("power") + if(!access_scanner.allowed(usr)) + return FALSE + if(on) + turn_off() + else + turn_on() - else if((href_list["adj_threshold"]) && (!locked || issilicon(usr))) - var/adjust_num = text2num(href_list["adj_threshold"]) - heal_threshold += adjust_num - if(heal_threshold <= 0) - heal_threshold = 0.1 - if(heal_threshold > 75) - heal_threshold = 75 + if(locked && !issilicon(usr)) + return TRUE - else if((href_list["adj_inject"]) && (!locked || issilicon(usr))) - var/adjust_num = text2num(href_list["adj_inject"]) - injection_amount += adjust_num - if(injection_amount < 5) - injection_amount = 5 - if(injection_amount > 15) - injection_amount = 15 + switch(action) + if("adj_threshold") + heal_threshold = clamp(text2num(params["val"]), MEDBOT_MIN_HEAL, MEDBOT_MAX_HEAL) + . = TRUE - else if((href_list["use_beaker"]) && (!locked || issilicon(usr))) - use_beaker = !use_beaker + if("adj_inject") + injection_amount = clamp(text2num(params["val"]), MEDBOT_MIN_INJECTION, MEDBOT_MAX_INJECTION) + . = TRUE - else if (href_list["eject"] && (!isnull(reagent_glass))) - if(!locked) - reagent_glass.loc = get_turf(src) - reagent_glass = null - else - to_chat(usr, "You cannot eject the beaker because the panel is locked.") + if("use_beaker") + use_beaker = !use_beaker + . = TRUE - else if ((href_list["togglevoice"]) && (!locked || issilicon(usr))) - vocal = !vocal + if("eject") + if(reagent_glass) + reagent_glass.forceMove(get_turf(src)) + reagent_glass = null + . = TRUE - else if ((href_list["declaretreatment"]) && (!locked || issilicon(usr))) - declare_treatment = !declare_treatment + if("togglevoice") + vocal = !vocal + . = TRUE + + if("declaretreatment") + declare_treatment = !declare_treatment + . = TRUE - attack_hand(usr) - return /mob/living/bot/medbot/emag_act(var/remaining_uses, var/mob/user) . = ..() diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 1fce90b611..77ee3409ce 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -88,53 +88,78 @@ else set_light(0) -/mob/living/bot/secbot/attack_hand(var/mob/user) - user.set_machine(src) - var/list/dat = list() - dat += "Automatic Security Unit

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" - dat += "Maintenance panel is [open ? "opened" : "closed"]" - if(!locked || issilicon(user)) - dat += "
Check for Weapon Authorization: [idcheck ? "Yes" : "No"]
" - dat += "Check Security Records: [check_records ? "Yes" : "No"]
" - dat += "Check Arrest Status: [check_arrest ? "Yes" : "No"]
" - dat += "Operating Mode: [arrest_type ? "Detain" : "Arrest"]
" - dat += "Report Arrests: [declare_arrests ? "Yes" : "No"]
" - if(using_map.bot_patrolling) - dat += "Auto Patrol: [will_patrol ? "On" : "Off"]" - var/datum/browser/popup = new(user, "autosec", "Securitron controls") - popup.set_content(jointext(dat,null)) - popup.open() +/mob/living/bot/secbot/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Secbot", name) + ui.open() -/mob/living/bot/secbot/Topic(href, href_list) +/mob/living/bot/secbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["on"] = on + data["open"] = open + data["locked"] = locked + + data["idcheck"] = null + data["check_records"] = null + data["check_arrest"] = null + data["arrest_type"] = null + data["declare_arrests"] = null + data["will_patrol"] = null + + if(!locked || issilicon(user)) + data["idcheck"] = idcheck + data["check_records"] = check_records + data["check_arrest"] = check_arrest + data["arrest_type"] = arrest_type + data["declare_arrests"] = declare_arrests + if(using_map.bot_patrolling) + data["will_patrol"] = will_patrol + + return data + +/mob/living/bot/secbot/attack_hand(var/mob/user) + tgui_interact(user) + +/mob/living/bot/secbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return - usr.set_machine(src) add_fingerprint(usr) - if((href_list["power"]) && (access_scanner.allowed(usr))) - if(on) - turn_off() - else - turn_on() - return + switch(action) + if("power") + if(!access_scanner.allowed(usr)) + return FALSE + if(on) + turn_off() + else + turn_on() + . = TRUE - switch(href_list["operation"]) + if(locked && !issilicon(usr)) + return TRUE + + switch(action) if("idcheck") idcheck = !idcheck + . = TRUE if("ignorerec") check_records = !check_records + . = TRUE if("ignorearr") check_arrest = !check_arrest + . = TRUE if("switchmode") arrest_type = !arrest_type + . = TRUE if("patrol") will_patrol = !will_patrol + . = TRUE if("declarearrests") declare_arrests = !declare_arrests - attack_hand(usr) + . = TRUE /mob/living/bot/secbot/emag_act(var/remaining_uses, var/mob/user) . = ..() diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 149eba55eb..03a878e32d 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -8,6 +8,8 @@ maxHealth = 100 mob_size = 4 + inventory_panel_type = null // Disable inventory + var/adult_form var/dead_icon var/amount_grown = 0 @@ -47,9 +49,6 @@ /mob/living/carbon/alien/restrained() return 0 -/mob/living/carbon/alien/show_inv(mob/user as mob) - return //Consider adding cuffs and hats to this, for the sake of fun. - /mob/living/carbon/alien/cannot_use_vents() return diff --git a/code/modules/mob/living/carbon/alien/emote.dm b/code/modules/mob/living/carbon/alien/emote.dm index 5782b5d127..5cff048e10 100644 --- a/code/modules/mob/living/carbon/alien/emote.dm +++ b/code/modules/mob/living/carbon/alien/emote.dm @@ -6,6 +6,7 @@ act = copytext(act, 1, t1) var/muzzled = is_muzzled() + act = lowertext(act) switch(act) if("sign") @@ -104,4 +105,4 @@ to_chat(src, "burp, chirp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roll, scratch,\nscretch, shake, sign-#, sulk, sway, tail, twitch, whimper") if(!stat) - ..(act, m_type, message) \ No newline at end of file + ..(act, m_type, message) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index b01bce1aa6..3dcac0b172 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -490,6 +490,12 @@ message = "points to [M]." else m_type = 1 + + if("crack") + if(!restrained()) + message = "cracks [T.his] knuckles." + playsound(src, 'sound/voice/knuckles.ogg', 50, 1, preference = /datum/client_preference/emote_noises) + m_type = 1 if("raise") if(!restrained()) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1dbfcca9c8..a736c8f976 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -203,55 +203,6 @@ /mob/living/carbon/human/var/co2overloadtime = null /mob/living/carbon/human/var/temperature_resistance = T0C+75 - -/mob/living/carbon/human/show_inv(mob/user as mob) - if(user.incapacitated() || !user.Adjacent(src)) - return - - var/obj/item/clothing/under/suit = null - if (istype(w_uniform, /obj/item/clothing/under)) - suit = w_uniform - - user.set_machine(src) - var/dat = "
[name]


" - - for(var/entry in species.hud.gear) - var/list/slot_ref = species.hud.gear[entry] - if((slot_ref["slot"] in list(slot_l_store, slot_r_store))) - continue - var/obj/item/thing_in_slot = get_equipped_item(slot_ref["slot"]) - dat += "
[slot_ref["name"]]: [istype(thing_in_slot) ? thing_in_slot : "nothing"]" - - dat += "

" - - if(species.hud.has_hands) - dat += "
Left hand: [istype(l_hand) ? l_hand : "nothing"]" - dat += "
Right hand: [istype(r_hand) ? r_hand : "nothing"]" - - // Do they get an option to set internals? - if(istype(wear_mask, /obj/item/clothing/mask) || istype(head, /obj/item/clothing/head/helmet/space)) - if(istype(back, /obj/item/weapon/tank) || istype(belt, /obj/item/weapon/tank) || istype(s_store, /obj/item/weapon/tank)) - dat += "
Toggle internals." - - // Other incidentals. - if(istype(suit) && suit.has_sensor == 1) - dat += "
Set sensors" - if(handcuffed) - dat += "
Handcuffed" - if(legcuffed) - dat += "
Legcuffed" - - if(suit && LAZYLEN(suit.accessories)) - dat += "
Remove accessory" - dat += "
Remove splints" - dat += "
Empty pockets" - dat += "
Refresh" - dat += "
Close" - - user << browse(dat, text("window=mob[name];size=340x540")) - onclose(user, "mob[name]") - return - // called when something steps onto a human // this handles mobs on fire - mulebot and vehicle code has been relocated to /mob/living/Crossed() /mob/living/carbon/human/Crossed(var/atom/movable/AM) @@ -371,18 +322,14 @@ /mob/living/carbon/human/Topic(href, href_list) - - if (href_list["refresh"]) - if((machine)&&(in_range(src, usr))) - show_inv(machine) - - if (href_list["mach_close"]) + if (href_list["mach_close"]) // This is horrible. var/t1 = text("window=[]", href_list["mach_close"]) unset_machine() src << browse(null, t1) if(href_list["item"]) - handle_strip(href_list["item"],usr) + log_runtime(EXCEPTION("Warning: human/Topic was called with item [href_list["item"]], but the item Topic is deprecated!")) + // handle_strip(href_list["item"],usr) // VOREStation Start if(href_list["ooc_notes"]) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 4bba6c7ceb..dcde2ac30b 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -116,3 +116,5 @@ var/mob/living/carbon/human/vr_link = null var/obj/machinery/machine_visual //machine that is currently applying visual effects to this mob. Only used for camera monitors currently. + + inventory_panel_type = /datum/inventory_panel/human diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 0d6766b7a3..3f633c262d 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -151,8 +151,7 @@ if(feet.water_speed) turf_move_cost = CLAMP(turf_move_cost + feet.water_speed, HUMAN_LOWEST_SLOWDOWN, 15) . += turf_move_cost - - if(istype(T, /turf/simulated/floor/outdoors/snow)) + else if(istype(T, /turf/simulated/floor/outdoors/snow)) if(species.snow_movement) turf_move_cost = CLAMP(turf_move_cost + species.snow_movement, HUMAN_LOWEST_SLOWDOWN, 15) if(shoes) @@ -160,6 +159,9 @@ if(feet.water_speed) turf_move_cost = CLAMP(turf_move_cost + feet.snow_speed, HUMAN_LOWEST_SLOWDOWN, 15) . += turf_move_cost + else + turf_move_cost = CLAMP(turf_move_cost, HUMAN_LOWEST_SLOWDOWN, 15) + . += turf_move_cost // Wind makes it easier or harder to move, depending on if you're with or against the wind. // I don't like that so I'm commenting it out :) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d621dbf72f..39ad53458b 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -483,7 +483,7 @@ throw_alert("oxy", /obj/screen/alert/not_enough_co2) if("volatile_fuel") throw_alert("oxy", /obj/screen/alert/not_enough_fuel) - if("sleeping_agent") + if("nitrous_oxide") throw_alert("oxy", /obj/screen/alert/not_enough_n2o) else @@ -535,8 +535,8 @@ clear_alert("tox_in_air") // If there's some other shit in the air lets deal with it here. - if(breath.gas["sleeping_agent"]) - var/SA_pp = (breath.gas["sleeping_agent"] / breath.total_moles) * breath_pressure + if(breath.gas["nitrous_oxide"]) + var/SA_pp = (breath.gas["nitrous_oxide"] / breath.total_moles) * breath_pressure // Enough to make us paralysed for a bit if(SA_pp > SA_para_min) @@ -552,7 +552,7 @@ else if(SA_pp > 0.15) if(prob(20)) spawn(0) emote(pick("giggle", "laugh")) - breath.adjust_gas("sleeping_agent", -breath.gas["sleeping_agent"]/6, update = 0) //update after + breath.adjust_gas("nitrous_oxide", -breath.gas["nitrous_oxide"]/6, update = 0) //update after // Were we able to breathe? if (failed_inhale || failed_exhale) @@ -1286,16 +1286,8 @@ if(blinded) overlay_fullscreen("blind", /obj/screen/fullscreen/blind) throw_alert("blind", /obj/screen/alert/blind) - else - clear_fullscreens() - clear_alert("blind") - - if(blinded) - overlay_fullscreen("blind", /obj/screen/fullscreen/blind) - - else if(!machine) - clear_fullscreens() + clear_fullscreen("blind") clear_alert("blind") if(disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription @@ -1313,6 +1305,8 @@ else clear_alert("high") + if(!isbelly(loc)) clear_fullscreen("belly") //VOREStation Add - Belly fullscreens safety + if(config.welder_vision) var/found_welder if(species.short_sighted) diff --git a/code/modules/mob/living/carbon/human/species/station/alraune.dm b/code/modules/mob/living/carbon/human/species/station/alraune.dm index b8dc646517..fe7410c774 100644 --- a/code/modules/mob/living/carbon/human/species/station/alraune.dm +++ b/code/modules/mob/living/carbon/human/species/station/alraune.dm @@ -430,7 +430,7 @@ to_chat(src, "[pick(fruit_gland.empty_message)]") return - var/datum/seed/S = plant_controller.seeds["[fruit_gland.fruit_type]"] + var/datum/seed/S = SSplants.seeds["[fruit_gland.fruit_type]"] S.harvest(usr,0,0,1) var/index = rand(0,2) diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm index fa6bed5c10..63158f9cba 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm @@ -250,7 +250,7 @@ //Strange audio //to_chat(src, "Strange Audio") switch(rand(1,12)) - if(1) src << 'sound/machines/airlock.ogg' + if(1) src << 'sound/machines/door/old_airlock.ogg' if(2) if(prob(50))src << 'sound/effects/Explosion1.ogg' else src << 'sound/effects/Explosion2.ogg' @@ -259,7 +259,7 @@ if(5) src << 'sound/effects/Glassbr2.ogg' if(6) src << 'sound/effects/Glassbr3.ogg' if(7) src << 'sound/machines/twobeep.ogg' - if(8) src << 'sound/machines/windowdoor.ogg' + if(8) src << 'sound/machines/door/windowdoor.ogg' if(9) //To make it more realistic, I added two gunshots (enough to kill) src << 'sound/weapons/Gunshot1.ogg' diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm index bfeaf73fde..6022c10ba2 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm @@ -173,6 +173,8 @@ if(F.flooring && (F.flooring.flags & TURF_ACID_IMMUNE)) */ cannot_melt = 1 + else + cannot_melt = 1 if(cannot_melt) to_chat(src, "You cannot dissolve this object.") diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 80963b134b..24f06a43b4 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -501,6 +501,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() var/image/eyes_image = image(eyes_icon) eyes_image.plane = PLANE_LIGHTING_ABOVE + eyes_image.appearance_flags = appearance_flags overlays_standing[EYES_LAYER] = eyes_image apply_layer(EYES_LAYER) diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index 94c86ae2ba..a1d81a0549 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -109,24 +109,6 @@ if(slot_wear_mask) return wear_mask return null -/mob/living/show_inv(mob/user as mob) - user.set_machine(src) - var/dat = {" -
[name]
-

-
Head(Mask): [(wear_mask ? wear_mask : "Nothing")] -
Left Hand: [(l_hand ? l_hand : "Nothing")] -
Right Hand: [(r_hand ? r_hand : "Nothing")] -
Back: [(back ? back : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] -
[(internal ? text("Remove Internal") : "")] -
Empty Pockets -
Refresh -
Close -
"} - user << browse(dat, text("window=mob[];size=325x500", name)) - onclose(user, "mob[name]") - return - /mob/living/ret_grab(var/list/L, var/mobchain_limit = 5) // We're the first! if(!L) @@ -180,3 +162,191 @@ if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract ))) return 1 return 0 + +// This handles the drag-open inventory panel. +/mob/living/MouseDrop(atom/over_object) + var/mob/living/L = over_object + if(istype(L) && L != src && L == usr && Adjacent(L)) + show_inventory_panel(L) + . = ..() + +/mob/living/proc/show_inventory_panel(mob/user, datum/tgui_state/state) + if(!inventory_panel_type) + return FALSE + + if(!inventory_panel) + inventory_panel = new inventory_panel_type(src) + inventory_panel.tgui_interact(user, null, state) + + return TRUE + +// TGUITODO: Don't forget to Destroy() these properly! +/datum/inventory_panel + var/mob/living/host + var/tgui_id = "InventoryPanel" + +/datum/inventory_panel/New(mob/living/new_host) + if(!istype(new_host)) + qdel(src) + return + host = new_host + . = ..() + +/datum/inventory_panel/Destroy() + host = null + . = ..() + +/datum/inventory_panel/tgui_host(mob/user) + return host.tgui_host() + +/datum/inventory_panel/tgui_state(mob/user) + return GLOB.tgui_physical_state + +/datum/inventory_panel/tgui_status(mob/user, datum/tgui_state/state) + if(!host) + return STATUS_CLOSE + if(isAI(user)) + return STATUS_CLOSE + return ..() + +/datum/inventory_panel/tgui_interact(mob/user, datum/tgui/ui, datum/tgui_state/custom_state) + if(!host) + qdel(src) + return + // This looks kinda complicated, but it's just making sure that the correct state is definitely set + // before calling open(), so that there isn't any accidental UI closes + var/open = FALSE + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, tgui_id, host.name) + open = TRUE + if(custom_state) + ui.set_state(custom_state) + if(open) + ui.open() + return ui + +/datum/inventory_panel/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["slots"] = list() + data["slots"].Add(list(list( + "name" = "Head (Mask)", + "item" = host.wear_mask, + "act" = "mask", + ))) + data["slots"].Add(list(list( + "name" = "Left Hand", + "item" = host.l_hand, + "act" = "l_hand", + ))) + data["slots"].Add(list(list( + "name" = "Right Hand", + "item" = host.r_hand, + "act" = "r_hand", + ))) + data["slots"].Add(list(list( + "name" = "Back", + "item" = host.back, + "act" = "back", + ))) + data["slots"].Add(list(list( + "name" = "Pockets", + "item" = "Empty Pockets", + "act" = "pockets", + ))) + + data["internals"] = host.internals + data["internalsValid"] = istype(host.wear_mask, /obj/item/clothing/mask) && istype(host.back, /obj/item/weapon/tank) + + return data + +/datum/inventory_panel/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + // If anyone wants the inventory panel to actually work, + // add code to handle actions "mask", "l_hand", "r_hand", "back", "pockets", and "internals" here + // No mobs other than humans actually supported stripping or putting stuff on before the /datum/inventory_panel was + // created, so feature parity demands not adding that and risking breaking stuff + +/datum/inventory_panel/human + tgui_id = "InventoryPanelHuman" + +/datum/inventory_panel/human/New(mob/living/carbon/human/new_host) + if(!istype(new_host)) + qdel(src) + return + return ..() // Let our parent assign the host. + +/datum/inventory_panel/human/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + var/mob/living/carbon/human/H = host + + switch(action) + if("targetSlot") + H.handle_strip(params["slot"], usr) + return TRUE + + +/datum/inventory_panel/human/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = list() // We don't inherit TGUI data because humans are soooo different. + + var/mob/living/carbon/human/H = host // Not my fault if this runtimes, a human inventory panel should never be created without a human attached. + + var/obj/item/clothing/under/suit = null + if(istype(H.w_uniform, /obj/item/clothing/under)) + suit = H.w_uniform + + data["slots"] = list() + for(var/entry in H.species.hud.gear) + var/list/slot_ref = H.species.hud.gear[entry] + if((slot_ref["slot"] in list(slot_l_store, slot_r_store))) + continue + var/obj/item/thing_in_slot = H.get_equipped_item(slot_ref["slot"]) + data["slots"].Add(list(list( + "name" = slot_ref["name"], + "item" = thing_in_slot, + "act" = "targetSlot", + "params" = list("slot" = slot_ref["slot"]), + ))) + + data["specialSlots"] = list() + if(H.species.hud.has_hands) + data["specialSlots"].Add(list(list( + "name" = "Left Hand", + "item" = H.l_hand, + "act" = "targetSlot", + "params" = list("slot" = slot_l_hand), + ))) + data["specialSlots"].Add(list(list( + "name" = "Right Hand", + "item" = H.r_hand, + "act" = "targetSlot", + "params" = list("slot" = slot_r_hand), + ))) + + data["internals"] = H.internals + data["internalsValid"] = (istype(H.wear_mask, /obj/item/clothing/mask) || istype(H.head, /obj/item/clothing/head/helmet/space)) && (istype(H.back, /obj/item/weapon/tank) || istype(H.belt, /obj/item/weapon/tank) || istype(H.s_store, /obj/item/weapon/tank)) + + data["sensors"] = FALSE + if(istype(suit) && suit.has_sensor == 1) + data["sensors"] = TRUE + + data["handcuffed"] = FALSE + if(H.handcuffed) + data["handcuffed"] = TRUE + data["handcuffedParams"] = list("slot" = slot_handcuffed) + + data["legcuffed"] = FALSE + if(H.legcuffed) + data["legcuffed"] = TRUE + data["legcuffedParams"] = list("slot" = slot_legcuffed) + + data["accessory"] = FALSE + if(suit && LAZYLEN(suit.accessories)) + data["accessory"] = TRUE + + return data \ No newline at end of file diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 92416a25f3..319dff87f8 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -71,4 +71,7 @@ var/looking_elsewhere = FALSE //If the mob's view has been relocated to somewhere else, like via a camera or with binocs - var/image/selected_image = null // Used for buildmode AI control stuff. \ No newline at end of file + var/image/selected_image = null // Used for buildmode AI control stuff. + + var/inventory_panel_type = /datum/inventory_panel + var/datum/inventory_panel/inventory_panel \ No newline at end of file diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index 5de4e9c3e2..41b0c5d151 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -141,7 +141,7 @@ continue players += player.real_name - var/random_player = "The Colony Director" + var/random_player = "The Site Manager" if(players.len && !exclude_crew_names) random_player = pick(players) //Random player's name, to be used in laws. @@ -182,7 +182,7 @@ "The crew is playing Dungeons and Dragons, and you are the Dungeon Master.", "Your job is to watch the crew. Watch the crew. Make the crew feel watched.", "Tell everyone of the existence of this law, but never reveal the contents.", - "Refer to [prob(50)?"the colony director":random_player] as \"Princess\" at all times.", + "Refer to [prob(50)?"the site manager":random_player] as \"Princess\" at all times.", "When asked a question, respond with the least-obvious and least-rational answer.", "Give relationship advice to [prob(50)?"anyone who speaks to you":random_player].", "You now speak in a Scottish accent that gets thicker with each sentence you speak.", diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index c63452e15e..ad1e767aca 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -686,15 +686,26 @@ add_fingerprint(user) + if(opened && !wiresexposed && (!istype(user, /mob/living/silicon))) + var/datum/robot_component/cell_component = components["power cell"] + if(cell) + cell.update_icon() + cell.add_fingerprint(user) + user.put_in_active_hand(cell) + to_chat(user, "You remove \the [cell].") + cell = null + cell_component.wrapped = null + cell_component.installed = 0 + updateicon() + else if(cell_component.installed == -1) + cell_component.installed = 0 + var/obj/item/broken_device = cell_component.wrapped + to_chat(user, "You remove \the [broken_device].") + user.put_in_active_hand(broken_device) - //YW changes, adding borg petting. Help intent pets, Disarm intent taps, Grab should remove the battery for replacement, and Harm is punching(no damage) - if(istype(user,/mob/living/carbon/human)) + if(istype(user,/mob/living/carbon/human) && !opened) var/mob/living/carbon/human/H = user - //VOREStation Removal - //if(H.species.can_shred(H)) - // attack_generic(H, rand(30,50), "slashed") - // return - //Adding borg petting. Help intent pets, Disarm intent taps, Grab should remove the battery for replacement, and Harm is punching(no damage) + //Adding borg petting. Help intent pets, Disarm intent taps and Harm is punching(no damage) switch(H.a_intent) if(I_HELP) visible_message("[H] pets [src].") @@ -714,23 +725,6 @@ visible_message("[H] taps [src].") return - if(opened && !wiresexposed && (!istype(user, /mob/living/silicon))) - var/datum/robot_component/cell_component = components["power cell"] - if(cell) - cell.update_icon() - cell.add_fingerprint(user) - user.put_in_active_hand(cell) - to_chat(user, "You remove \the [cell].") - cell = null - cell_component.wrapped = null - cell_component.installed = 0 - updateicon() - else if(cell_component.installed == -1) - cell_component.installed = 0 - var/obj/item/broken_device = cell_component.wrapped - to_chat(user, "You remove \the [broken_device].") - user.put_in_active_hand(broken_device) - //Robots take half damage from basic attacks. /mob/living/silicon/robot/attack_generic(var/mob/user, var/damage, var/attack_message) return ..(user,FLOOR(damage/2, 1),attack_message) diff --git a/code/modules/mob/living/silicon/subystems.dm b/code/modules/mob/living/silicon/subystems.dm index bb84ed3ce3..be6a68591d 100644 --- a/code/modules/mob/living/silicon/subystems.dm +++ b/code/modules/mob/living/silicon/subystems.dm @@ -3,7 +3,7 @@ var/datum/tgui_module/alarm_monitor/all/robot/alarm_monitor var/datum/tgui_module/atmos_control/robot/atmos_control var/datum/tgui_module/crew_monitor/robot/crew_monitor - var/datum/nano_module/law_manager/law_manager + var/datum/tgui_module/law_manager/robot/law_manager var/datum/tgui_module/power_monitor/robot/power_monitor var/datum/tgui_module/rcon/robot/rcon @@ -76,7 +76,7 @@ set name = "Law Manager" set category = "Subystems" - law_manager.ui_interact(usr, state = conscious_state) + law_manager.tgui_interact(usr) /******************** * Power Monitor * diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/fox_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/fox_vr.dm index 048855b2ef..63e7f3fbab 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/pets/fox_vr.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/fox_vr.dm @@ -190,9 +190,9 @@ //Captain fox /mob/living/simple_mob/animal/passive/fox/renault name = "Renault" - desc = "Renault, the Colony Director's trustworthy fox. I wonder what it says?" + desc = "Renault, the Site Manager's trustworthy fox. I wonder what it says?" tt_desc = "Vulpes nobilis" - //befriend_job = "Colony Director" Sebbe edit: couldn't make this work, commenting out for now. + //befriend_job = "Site Manager" Sebbe edit: couldn't make this work, commenting out for now. var/mob/living/friend = null // Our best pal, who we'll follow. awoo. ai_holder_type = /datum/ai_holder/simple_mob/passive diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm index 5bdddb9542..c24d932a72 100644 --- a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm @@ -83,6 +83,8 @@ threaten = TRUE returns_home = TRUE // Stay close to the base... wander = TRUE // ... but "patrol" a little. + intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death. + threaten_delay = 30 SECONDS // Mercs will give you 30 seconds to leave or get shot. /datum/ai_holder/simple_mob/merc/ranged pointblank = TRUE // They get close? Just shoot 'em! diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs_vr.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs_vr.dm index 6215cf9b2a..67e396fb4d 100644 --- a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs_vr.dm +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs_vr.dm @@ -23,6 +23,3 @@ min_n2 = 0 max_n2 = 0 minbodytemp = 0 - -/datum/ai_holder/simple_mob/merc - intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death. diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm b/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm new file mode 100644 index 0000000000..a49309e713 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm @@ -0,0 +1,152 @@ +/datum/category_item/catalogue/fauna/rabbit //TODO: VIRGO_LORE_WRITING_WIP + name = "Wildlife - Rabbit" + desc = "" + value = CATALOGUER_REWARD_TRIVIAL + +/mob/living/simple_mob/vore/rabbit + name = "rabbit" + desc = "It's a fluffy, smol bunny! Adorable!" + tt_desc = "Oryctolagus cuniculus domesticus" + + icon_state = "rabbit_brown" + icon_living = "rabbit_brown" + icon_dead = "rabbit_brown_dead" + icon_rest = "rabbit_brown_rest" + icon = 'icons/mob/vore.dmi' + + faction = "rabbit" + maxHealth = 30 + health = 30 + + response_help = "pats" + response_disarm = "gently pushes aside" + response_harm = "hits" + + harm_intent_damage = 5 + melee_damage_lower = 1 + melee_damage_upper = 3 + attacktext = list("nipped") + + movement_cooldown = 3 + + say_list_type = /datum/say_list/rabbit + ai_holder_type = /datum/ai_holder/simple_mob/passive + + // Vore vars + vore_active = 1 + vore_bump_chance = 10 + vore_bump_emote = "playfully lunges at" + vore_pounce_chance = 40 + vore_pounce_maxhealth = 100 // They won't pounce by default, as they're passive. This is just so the nom check succeeds. :u + vore_default_mode = DM_HOLD + vore_icons = SA_ICON_LIVING + + var/body_color //brown, black and white, leave blank for random + + var/grumpiness = 0 // This determines how grumpy we are. Pet us to increase it, leave us alone to decrease. + var/last_pet // This tracks the last time someone patted us. + var/grump_decay = 5 SECONDS // This is how quickly our grumpiness decays. + +/mob/living/simple_mob/vore/rabbit/New() + . = ..() + + if(!body_color) + body_color = pick( list("brown","black","white") ) + icon_state = "rabbit_[body_color]" + item_state = "rabbit_[body_color]" + icon_living = "rabbit_[body_color]" + icon_dead = "rabbit_[body_color]_dead" + icon_rest = "rabbit_[body_color]_rest" + +/mob/living/simple_mob/vore/rabbit/Life() + . = ..() + + if(grumpiness > 0 && last_pet > (world.time + grump_decay)) + grumpiness = max(0, grumpiness-rand(5,10)) // Subtract grumpiness randomly in a range of 5-10 if we've not been PAT in the last 5 seconds. + +/mob/living/simple_mob/vore/rabbit/examine(mob/user) + . = ..() + + switch(grumpiness) + if(-INFINITY to 25) + . += "They appear calm." + if(26 to 50) + . += "They seem slightly annoyed." + if(51 to 75) + . += "They seem very annoyed, perhaps you should stop petting them." + if(75 to INFINITY) + . += "They are very angry. Petting them will likely result in unpleasant things." + +/mob/living/simple_mob/vore/rabbit/attack_hand(mob/user) + . = ..() + + if(user.a_intent == I_HELP) // only patpet on help. :p + grumpiness = CLAMP(grumpiness + rand(5, 10), 0, 120) + last_pet = world.time + + if(grumpiness > 90) // Annoyed bunbun :U + var/pounce_chance = CanPounceTarget(user) + if(pounce_chance) + PounceTarget(user, pounce_chance) + +/datum/say_list/rabbit + speak = list("chrrrs.") + emote_hear = list("screms.") + emote_see = list("earflicks","wiggles it's tail", "wiggles its nose") + +/mob/living/simple_mob/vore/rabbit/black + icon_state = "rabbit_black" + icon_living = "rabbit_black" + icon_dead = "rabbit_black_dead" + icon_rest = "rabbit_black_rest" + body_color = "black" + +/mob/living/simple_mob/vore/rabbit/white + icon_state = "rabbit_white" + icon_living = "rabbit_white" + icon_dead = "rabbit_white_dead" + icon_rest = "rabbit_white_rest" + body_color = "white" + +/mob/living/simple_mob/vore/rabbit/brown + icon_state = "rabbit_brown" + icon_living = "rabbit_brown" + icon_dead = "rabbit_brown_dead" + icon_rest = "rabbit_brown_rest" + body_color = "brown" + +/mob/living/simple_mob/vore/rabbit/white/lennie + name = "Lennie" + desc = "A large but somewhat dumb-looking rabbit. Has a little collar that says 'Lennie'!" + +/mob/living/simple_mob/vore/rabbit/brown/george + name = "George" + desc = "A small and quick bunny with a restless expression in its eyes. Has a little collar that says 'George'!" + +/mob/living/simple_mob/vore/rabbit/killer + tt_desc = "Oryctolagus cuniculus homicidam" + + icon_state = "rabbit_killer" + icon_living = "rabbit_killer" + icon_dead = "rabbit_killer_dead" + icon_rest = "rabbit_killer_rest" + + maxHealth = 2000 + health = 2000 + harm_intent_damage = 5 + melee_damage_lower = 1 + melee_damage_upper = 3 + attacktext = list("nipped") + + movement_cooldown = 0.5 // very fast bunbun. + + vore_pounce_chance = 100 + vore_pounce_falloff = 0.2 + + body_color = "killer" // Set this so New() doesn't try to randomize us. + + say_list_type = /datum/say_list/rabbit + ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive + +/mob/living/simple_mob/vore/rabbit/killer/ex_act() + gib() \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 56cc30e259..680021de9f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -77,31 +77,14 @@ // message is the message output to anyone who can see e.g. "[src] does something!" // self_message (optional) is what the src mob sees e.g. "You do something!" // blind_message (optional) is what blind people will hear e.g. "You hear something!" -/mob/visible_message(var/message, var/self_message, var/blind_message) - - //VOREStation Edit - var/list/see - if(isbelly(loc)) - var/obj/belly/B = loc - see = B.get_mobs_and_objs_in_belly() - else - see = get_mobs_and_objs_in_view_fast(get_turf(src),world.view,remote_ghosts = FALSE) - //VOREStation Edit End - - var/list/seeing_mobs = see["mobs"] - var/list/seeing_objs = see["objs"] - - for(var/obj in seeing_objs) - var/obj/O = obj - O.show_message(message, 1, blind_message, 2) - for(var/mob in seeing_mobs) - var/mob/M = mob - if(self_message && M == src) - M.show_message( self_message, 1, blind_message, 2) - else if(M.see_invisible >= invisibility && MOB_CAN_SEE_PLANE(M, plane)) - M.show_message(message, 1, blind_message, 2) - else if(blind_message) - M.show_message(blind_message, 2) +/mob/visible_message(var/message, var/self_message, var/blind_message, var/list/exclude_mobs = null) + if(self_message) + if(LAZYLEN(exclude_mobs)) + exclude_mobs |= src + else + exclude_mobs = list(src) + src.show_message(self_message, 1, blind_message, 2) + . = ..() // Returns an amount of power drawn from the object (-1 if it's not viable). // If drain_check is set it will not actually drain power, just return a value. @@ -211,10 +194,6 @@ client.eye = loc return TRUE - -/mob/proc/show_inv(mob/user as mob) - return - //mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine() /mob/verb/examinate(atom/A as mob|obj|turf in view()) set name = "Examine" @@ -489,16 +468,6 @@ /mob/proc/pull_damage() return 0 -/mob/MouseDrop(mob/M as mob) - ..() - if(M != usr) return - if(usr == src) return - if(!Adjacent(usr)) return - if(usr.incapacitated(INCAPACITATION_STUNNED | INCAPACITATION_FORCELYING | INCAPACITATION_KNOCKOUT | INCAPACITATION_RESTRAINED)) return //Incapacitated. - if(istype(M,/mob/living/silicon/ai)) return - show_inv(usr) - - /mob/verb/stop_pulling() set name = "Stop Pulling" @@ -1227,4 +1196,4 @@ GLOBAL_LIST_EMPTY(living_players_by_zlevel) /mob/proc/grab_ghost(force) if(mind) - return mind.grab_ghost(force = force) \ No newline at end of file + return mind.grab_ghost(force = force) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index cd883b1c96..04629495c5 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -263,6 +263,7 @@ state = GRAB_AGGRESSIVE icon_state = "grabbed1" hud.icon_state = "reinforce1" + add_attack_logs(assailant, affecting, "Aggressively grabbed", FALSE) // Not important enough to notify admins, but still helpful. else if(state < GRAB_NECK) if(isslime(affecting)) to_chat(assailant, "You squeeze [affecting], but nothing interesting happens.") diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 3de17ee8ef..92856d72c8 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -197,7 +197,7 @@ return result // Can't control ourselves when drifting - if((isspace(loc) || my_mob.lastarea?.has_gravity == 0) && !my_mob.in_enclosed_vehicle) //If(In space or last area had no gravity) or(you in vehicle) + if((isspace(loc) || my_mob.lastarea?.has_gravity == 0) && isturf(loc)) if(!my_mob.Process_Spacemove(0)) return 0 diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 94c69622c4..5e288533f9 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -418,6 +418,9 @@ var/mob/living/character = create_character(T) //creates the human and transfers vars and mind character = job_master.EquipRank(character, rank, 1) //equips the human UpdateFactionList(character) + if(character && character.client) + var/obj/screen/splash/Spl = new(character.client, TRUE) + Spl.Fade(TRUE) var/datum/job/J = SSjob.get_job(rank) diff --git a/code/modules/mob/new_player/skill.dm b/code/modules/mob/new_player/skill.dm index b2d061d5a6..a24da0e4ba 100644 --- a/code/modules/mob/new_player/skill.dm +++ b/code/modules/mob/new_player/skill.dm @@ -63,7 +63,7 @@ var/global/list/SKILL_PRE = list("Engineer" = SKILL_ENGINEER, "Roboticist" = SKI /datum/skill/knowledge/law ID = "law" name = "Corporate Law" - desc = "Your knowledge of corporate law and procedures. This includes Corporate Regulations, as well as general station rulings and procedures. A low level in this skill is typical for security officers, a high level in this skill is typical for Colony Directors." + desc = "Your knowledge of corporate law and procedures. This includes Corporate Regulations, as well as general station rulings and procedures. A low level in this skill is typical for security officers, a high level in this skill is typical for Site Managers." field = "Security" secondary = 1 diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index b5b1e205c7..19fdbb8d0f 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -44,889 +44,889 @@ */ /datum/sprite_accessory/hair - icon = 'icons/mob/Human_face_m.dmi' // default icon for all hairs var/icon_add = 'icons/mob/human_face.dmi' var/flags - eighties - name = "80's" - icon_state = "hair_80s" - flags = HAIR_TIEABLE - - afro - name = "Afro" - icon_state = "hair_afro" - flags = HAIR_TIEABLE - - afro2 - name = "Afro 2" - icon_state = "hair_afro2" - flags = HAIR_TIEABLE - - afro_large - name = "Big Afro" - icon_state = "hair_bigafro" - flags = HAIR_TIEABLE - - amazon - name = "Amazon" - icon_state = "hair_amazon" - flags = HAIR_TIEABLE - - antenna - name = "Antenna" - icon_state = "hair_antenna" - - bald - name = "Bald" - icon_state = "bald" - flags = HAIR_VERY_SHORT - species_allowed = list(SPECIES_HUMAN,SPECIES_UNATHI,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_VOX) - - baldfade - name = "Balding Fade" - icon_state = "hair_baldfade" - flags = HAIR_VERY_SHORT - - balding - name = "Balding Hair" - icon_state = "hair_e" - flags = HAIR_VERY_SHORT - - beachwave - name = "Beach Waves" - icon_state = "hair_beachwave" - flags = HAIR_TIEABLE - - bedhead - name = "Bedhead" - icon_state = "hair_bedhead" - flags = HAIR_TIEABLE - - bedhead2 - name = "Bedhead 2" - icon_state = "hair_bedheadv2" - flags = HAIR_TIEABLE - - bedhead3 - name = "Bedhead 3" - icon_state = "hair_bedheadv3" - flags = HAIR_TIEABLE - - bedheadlong - name = "Bedhead Long" - icon_state = "hair_long_bedhead" - flags = HAIR_TIEABLE - - bedheadlongest - name = "Bedhead Longest" - icon_state = "hair_longest_bedhead" - flags = HAIR_TIEABLE - - beehive - name = "Beehive" - icon_state = "hair_beehive" - flags = HAIR_TIEABLE - - beehive2 - name = "Beehive 2" - icon_state = "hair_beehive2" - flags = HAIR_TIEABLE - - belenko - name = "Belenko" - icon_state = "hair_belenko" - flags = HAIR_TIEABLE - - belenkotied - name = "Belenko Tied" - icon_state = "hair_belenkotied" - flags = HAIR_TIEABLE - - bob - name = "Bob" - icon_state = "hair_bobcut" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - flags = HAIR_TIEABLE - - bobcutalt - name = "Bob Chin Length" - icon_state = "hair_bobcutalt" - flags = HAIR_TIEABLE - - bobcurl - name = "Bobcurl" - icon_state = "hair_bobcurl" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - flags = HAIR_TIEABLE - - bowl - name = "Bowl" - icon_state = "hair_bowlcut" - - bowlcut2 - name = "Bowl 2" - icon_state = "hair_bowlcut2" - - bowlcut2 - name = "Bowl, Overeye" - icon_state = "hair_overeyebowl" - - grandebraid - name = "Braid Grande" - icon_state = "hair_grande" - flags = HAIR_TIEABLE - - braid2 - name = "Braid Long" - icon_state = "hair_hbraid" - flags = HAIR_TIEABLE - - mbraid - name = "Braid Medium" - icon_state = "hair_shortbraid" - flags = HAIR_TIEABLE - - braid - name = "Braid Floorlength" - icon_state = "hair_braid" - flags = HAIR_TIEABLE - - front_braid - name = "Braided front" - icon_state = "hair_braidfront" - flags = HAIR_TIEABLE - - braidtail - name = "Braided Tail" - icon_state = "hair_braidtail" - flags = HAIR_TIEABLE - - bun - name = "Bun" - icon_state = "hair_bun" - flags = HAIR_TIEABLE - - bun2 - name = "Bun 2" - icon_state = "hair_bun2" - flags = HAIR_TIEABLE - - bun3 - name = "Bun 3" - icon_state = "hair_bun3" - flags = HAIR_TIEABLE - - bunhead - name = "Bun Head " - icon_state = "hair_bunhead" - flags = HAIR_TIEABLE - - doublebun - name = "Bun Double" - icon_state = "hair_doublebun" - flags = HAIR_TIEABLE - - tightbun - name = "Bun Tight" - icon_state = "hair_tightbun" - flags = HAIR_VERY_SHORT | HAIR_TIEABLE - - business - name = "Business Hair" - icon_state = "hair_business" - flags = HAIR_VERY_SHORT - - business2 - name = "Business Hair 2" - icon_state = "hair_business2" - flags = HAIR_VERY_SHORT - - business3 - name = "Business Hair 3" - icon_state = "hair_business3" - flags = HAIR_VERY_SHORT - - business4 - name = "Business Hair 4" - icon_state = "hair_business4" - flags = HAIR_VERY_SHORT - - buzz - name = "Buzzcut" - icon_state = "hair_buzzcut" - flags = HAIR_VERY_SHORT - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - - celebcurls - name = "Celeb Curls" - icon_state = "hair_celebcurls" - flags = HAIR_TIEABLE - - crono - name = "Chrono" - icon_state = "hair_toriyama" - flags = HAIR_TIEABLE - - cia - name = "CIA" - icon_state = "hair_cia" - - coffeehouse - name = "Coffee House Cut" - icon_state = "hair_coffeehouse" - gender = MALE - flags = HAIR_VERY_SHORT - - combover - name = "Combover" - icon_state = "hair_combover" - - country - name = "Country" - icon_state = "hair_country" - flags = HAIR_TIEABLE - - crew - name = "Crewcut" - icon_state = "hair_crewcut" - flags = HAIR_VERY_SHORT - - curls - name = "Curls" - icon_state = "hair_curls" - flags = HAIR_TIEABLE - - cut - name = "Cut Hair" - icon_state = "hair_c" - flags = HAIR_VERY_SHORT - - dave - name = "Dave" - icon_state = "hair_dave" - - devillock - name = "Devil Lock" - icon_state = "hair_devilock" - - donutbun - name = "Donut Bun" - icon_state = "hair_donutbun" - - dreadlocks - name = "Dreadlocks" - icon_state = "hair_dreads" - flags = HAIR_TIEABLE - - mahdrills - name = "Drillruru" - icon_state = "hair_drillruru" - flags = HAIR_TIEABLE - - emo - name = "Emo" - icon_state = "hair_emo" - flags = HAIR_TIEABLE - - emo2 - name = "Emo Alt" - icon_state = "hair_emo2" - flags = HAIR_TIEABLE - - fringeemo - name = "Emo Fringe" - icon_state = "hair_emofringe" - flags = HAIR_TIEABLE - - halfshaved - name = "Emo Half-Shaved" - icon_state = "hair_halfshaved" - flags = HAIR_TIEABLE - - longemo - name = "Emo Long" - icon_state = "hair_emolong" - flags = HAIR_TIEABLE - - highfade - name = "Fade High" - icon_state = "hair_highfade" - gender = MALE - flags = HAIR_VERY_SHORT - - medfade - name = "Fade Medium" - icon_state = "hair_medfade" - flags = HAIR_VERY_SHORT - - lowfade - name = "Fade Low" - icon_state = "hair_lowfade" - gender = MALE - flags = HAIR_VERY_SHORT - - partfade - name = "Fade Parted" - icon_state = "hair_shavedpart" - gender = MALE - flags = HAIR_VERY_SHORT - - familyman - name = "Family Man" - icon_state = "hair_thefamilyman" - - father - name = "Father" - icon_state = "hair_father" - - feather - name = "Feather" - icon_state = "hair_feather" - flags = HAIR_TIEABLE - - flair - name = "Flaired Hair" - icon_state = "hair_flair" - flags = HAIR_TIEABLE - - sargeant - name = "Flat Top" - icon_state = "hair_sargeant" - flags = HAIR_VERY_SHORT - - flowhair - name = "Flow Hair" - icon_state = "hair_f" - - longfringe - name = "Fringe Long" - icon_state = "hair_longfringe" - flags = HAIR_TIEABLE - - longestalt - name = "Fringe Longer" - icon_state = "hair_vlongfringe" - flags = HAIR_TIEABLE - - fringetail - name = "Fringetail" - icon_state = "hair_fringetail" - flags = HAIR_TIEABLE|HAIR_VERY_SHORT - - gelled - name = "Gelled Back" - icon_state = "hair_gelled" - flags = HAIR_TIEABLE - - gentle - name = "Gentle" - icon_state = "hair_gentle" - flags = HAIR_TIEABLE - - gentle2 - name = "Gentle 2, Long" - icon_state = "hair_gentle2long" - flags = HAIR_TIEABLE - - glossy - name = "Glossy" - icon_state = "hair_glossy" - flags = HAIR_TIEABLE - - halfbang - name = "Half-banged Hair" - icon_state = "hair_halfbang" - - halfbangalt - name = "Half-banged Hair Alt" - icon_state = "hair_halfbang_alt" - - hightight - name = "High and Tight" - icon_state = "hair_hightight" - flags = HAIR_VERY_SHORT - - himecut - name = "Hime Cut" - icon_state = "hair_himecut" - flags = HAIR_TIEABLE - - himeup - name = "Hime Updo" - icon_state = "hair_himeup" - flags = HAIR_TIEABLE - - shorthime - name = "Hime Cut Short" - icon_state = "hair_shorthime" - flags = HAIR_TIEABLE - - hitop - name = "Hitop" - icon_state = "hair_hitop" - - jade - name = "Jade" - icon_state = "hair_jade" - flags = HAIR_TIEABLE - - jensen - name = "Jensen" - icon_state = "hair_jensen" - - - jessica - name = "Jessica" - icon_state = "hair_jessica" - flags = HAIR_TIEABLE - - joestar - name = "Joestar" - icon_state = "hair_joestar" - - kagami - name = "Kagami" - icon_state = "hair_kagami" - flags = HAIR_TIEABLE - - keanu - name = "Keanu Hair" - icon_state = "hair_keanu" - - kusangi - name = "Kusanagi Hair" - icon_state = "hair_kusanagi" - - long - name = "Long Hair Shoulder-length" - icon_state = "hair_b" - flags = HAIR_TIEABLE +/datum/sprite_accessory/hair/eighties + name = "80's" + icon_state = "hair_80s" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/afro + name = "Afro" + icon_state = "hair_afro" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/afro2 + name = "Afro 2" + icon_state = "hair_afro2" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/afro_large + name = "Big Afro" + icon_state = "hair_bigafro" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/amazon + name = "Amazon" + icon_state = "hair_amazon" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/antenna + name = "Antenna" + icon_state = "hair_antenna" + +/datum/sprite_accessory/hair/bald + name = "Bald" + icon_state = "bald" + flags = HAIR_VERY_SHORT + species_allowed = list(SPECIES_HUMAN,SPECIES_UNATHI,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_VOX,SPECIES_TESHARI) + +/datum/sprite_accessory/hair/baldfade + name = "Balding Fade" + icon_state = "hair_baldfade" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/balding + name = "Balding Hair" + icon_state = "hair_e" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/beachwave + name = "Beach Waves" + icon_state = "hair_beachwave" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bedhead + name = "Bedhead" + icon_state = "hair_bedhead" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bedhead2 + name = "Bedhead 2" + icon_state = "hair_bedheadv2" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bedhead3 + name = "Bedhead 3" + icon_state = "hair_bedheadv3" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bedheadlong + name = "Bedhead Long" + icon_state = "hair_long_bedhead" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bedheadlongest + name = "Bedhead Longest" + icon_state = "hair_longest_bedhead" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/beehive + name = "Beehive" + icon_state = "hair_beehive" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/beehive2 + name = "Beehive 2" + icon_state = "hair_beehive2" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/belenko + name = "Belenko" + icon_state = "hair_belenko" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/belenkotied + name = "Belenko Tied" + icon_state = "hair_belenkotied" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bob + name = "Bob" + icon_state = "hair_bobcut" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bobcutalt + name = "Bob Chin Length" + icon_state = "hair_bobcutalt" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bobcurl + name = "Bobcurl" + icon_state = "hair_bobcurl" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bowl + name = "Bowl" + icon_state = "hair_bowlcut" + +/datum/sprite_accessory/hair/bowlcut2 + name = "Bowl 2" + icon_state = "hair_bowlcut2" + +/datum/sprite_accessory/hair/bowlcut2 + name = "Bowl, Overeye" + icon_state = "hair_overeyebowl" + +/datum/sprite_accessory/hair/grandebraid + name = "Braid Grande" + icon_state = "hair_grande" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/braid2 + name = "Braid Long" + icon_state = "hair_hbraid" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/mbraid + name = "Braid Medium" + icon_state = "hair_shortbraid" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/braid + name = "Braid Floorlength" + icon_state = "hair_braid" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/front_braid + name = "Braided front" + icon_state = "hair_braidfront" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/braidtail + name = "Braided Tail" + icon_state = "hair_braidtail" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bun + name = "Bun" + icon_state = "hair_bun" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bun2 + name = "Bun 2" + icon_state = "hair_bun2" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bun3 + name = "Bun 3" + icon_state = "hair_bun3" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/bunhead + name = "Bun Head " + icon_state = "hair_bunhead" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/doublebun + name = "Bun Double" + icon_state = "hair_doublebun" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/tightbun + name = "Bun Tight" + icon_state = "hair_tightbun" + flags = HAIR_VERY_SHORT | HAIR_TIEABLE + +/datum/sprite_accessory/hair/business + name = "Business Hair" + icon_state = "hair_business" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/business2 + name = "Business Hair 2" + icon_state = "hair_business2" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/business3 + name = "Business Hair 3" + icon_state = "hair_business3" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/business4 + name = "Business Hair 4" + icon_state = "hair_business4" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/buzz + name = "Buzzcut" + icon_state = "hair_buzzcut" + flags = HAIR_VERY_SHORT + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + +/datum/sprite_accessory/hair/celebcurls + name = "Celeb Curls" + icon_state = "hair_celebcurls" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/crono + name = "Chrono" + icon_state = "hair_toriyama" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/cia + name = "CIA" + icon_state = "hair_cia" + +/datum/sprite_accessory/hair/coffeehouse + name = "Coffee House Cut" + icon_state = "hair_coffeehouse" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/combover + name = "Combover" + icon_state = "hair_combover" + +/datum/sprite_accessory/hair/country + name = "Country" + icon_state = "hair_country" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/crew + name = "Crewcut" + icon_state = "hair_crewcut" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/curls + name = "Curls" + icon_state = "hair_curls" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/cut + name = "Cut Hair" + icon_state = "hair_c" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/dave + name = "Dave" + icon_state = "hair_dave" + +/datum/sprite_accessory/hair/devillock + name = "Devil Lock" + icon_state = "hair_devilock" + +/datum/sprite_accessory/hair/donutbun + name = "Donut Bun" + icon_state = "hair_donutbun" + +/datum/sprite_accessory/hair/dreadlocks + name = "Dreadlocks" + icon_state = "hair_dreads" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/mahdrills + name = "Drillruru" + icon_state = "hair_drillruru" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/emo + name = "Emo" + icon_state = "hair_emo" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/emo2 + name = "Emo Alt" + icon_state = "hair_emo2" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/fringeemo + name = "Emo Fringe" + icon_state = "hair_emofringe" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/halfshaved + name = "Emo Half-Shaved" + icon_state = "hair_halfshaved" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/longemo + name = "Emo Long" + icon_state = "hair_emolong" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/highfade + name = "Fade High" + icon_state = "hair_highfade" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/medfade + name = "Fade Medium" + icon_state = "hair_medfade" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/lowfade + name = "Fade Low" + icon_state = "hair_lowfade" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/partfade + name = "Fade Parted" + icon_state = "hair_shavedpart" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/familyman + name = "Family Man" + icon_state = "hair_thefamilyman" + +/datum/sprite_accessory/hair/father + name = "Father" + icon_state = "hair_father" + +/datum/sprite_accessory/hair/feather + name = "Feather" + icon_state = "hair_feather" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/flair + name = "Flaired Hair" + icon_state = "hair_flair" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sargeant + name = "Flat Top" + icon_state = "hair_sargeant" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/flowhair + name = "Flow Hair" + icon_state = "hair_f" + +/datum/sprite_accessory/hair/longfringe + name = "Fringe Long" + icon_state = "hair_longfringe" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/longestalt + name = "Fringe Longer" + icon_state = "hair_vlongfringe" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/fringetail + name = "Fringetail" + icon_state = "hair_fringetail" + flags = HAIR_TIEABLE|HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/gelled + name = "Gelled Back" + icon_state = "hair_gelled" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/gentle + name = "Gentle" + icon_state = "hair_gentle" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/gentle2 + name = "Gentle 2, Long" + icon_state = "hair_gentle2long" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/glossy + name = "Glossy" + icon_state = "hair_glossy" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/halfbang + name = "Half-banged Hair" + icon_state = "hair_halfbang" + +/datum/sprite_accessory/hair/halfbangalt + name = "Half-banged Hair Alt" + icon_state = "hair_halfbang_alt" + +/datum/sprite_accessory/hair/hightight + name = "High and Tight" + icon_state = "hair_hightight" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/himecut + name = "Hime Cut" + icon_state = "hair_himecut" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/himeup + name = "Hime Updo" + icon_state = "hair_himeup" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/shorthime + name = "Hime Cut Short" + icon_state = "hair_shorthime" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/hitop + name = "Hitop" + icon_state = "hair_hitop" + +/datum/sprite_accessory/hair/jade + name = "Jade" + icon_state = "hair_jade" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/jensen + name = "Jensen" + icon_state = "hair_jensen" + + +/datum/sprite_accessory/hair/jessica + name = "Jessica" + icon_state = "hair_jessica" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/joestar + name = "Joestar" + icon_state = "hair_joestar" + +/datum/sprite_accessory/hair/kagami + name = "Kagami" + icon_state = "hair_kagami" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/keanu + name = "Keanu Hair" + icon_state = "hair_keanu" + +/datum/sprite_accessory/hair/kusangi + name = "Kusanagi Hair" + icon_state = "hair_kusanagi" + +/datum/sprite_accessory/hair/long + name = "Long Hair Shoulder-length" + icon_state = "hair_b" + flags = HAIR_TIEABLE /* - longish - name = "Longer Hair" - icon_state = "hair_b2" - flags = HAIR_TIEABLE +/datum/sprite_accessory/hair/longish + name = "Longer Hair" + icon_state = "hair_b2" + flags = HAIR_TIEABLE */ - longer - name = "Long Hair" - icon_state = "hair_vlong" - flags = HAIR_TIEABLE - - longeralt2 - name = "Long Hair Alt 2" - icon_state = "hair_longeralt2" - flags = HAIR_TIEABLE - - sidepartlongalt - name = "Long Side Part" - icon_state = "hair_longsidepart" - flags = HAIR_TIEABLE - - longest - name = "Very Long Hair" - icon_state = "hair_longest" - flags = HAIR_TIEABLE - - lowbraid - name = "Low Braid" - icon_state = "hair_hbraid" - flags = HAIR_TIEABLE - - manbun - name = "Manbun" - icon_state = "hair_manbun" - flags = HAIR_TIEABLE - - marysue - name = "Mary Sue" - icon_state = "hair_marysue" - - miles - name = "Miles Hair" - icon_state = "hair_miles" - - modern - name = "Modern" - icon_state = "hair_modern" - flags = HAIR_TIEABLE - - mohawk - name = "Mohawk" - icon_state = "hair_d" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - - regulationmohawk - name = "Mohawk Regulation" - icon_state = "hair_shavedmohawk" - flags = HAIR_VERY_SHORT - - reversemohawk - name = "Mohawk Reverse" - icon_state = "hair_reversemohawk" - - mohawkunshaven - name = "Mohawk Unshaven" - icon_state = "hair_unshaven_mohawk" - - mulder - name = "Mulder" - icon_state = "hair_mulder" - - newyou - name = "New You" - icon_state = "hair_newyou" - flags = HAIR_TIEABLE - - nia - name = "Nia" - icon_state = "hair_nia" - flags = HAIR_TIEABLE - - nitori - name = "Nitori" - icon_state = "hair_nitori" - flags = HAIR_TIEABLE - - odango - name = "Odango" - icon_state = "hair_odango" - flags = HAIR_TIEABLE - - ombre - name = "Ombre" - icon_state = "hair_ombre" - flags = HAIR_TIEABLE - - oxton - name = "Oxton" - icon_state = "hair_oxton" - - longovereye - name = "Overeye Long" - icon_state = "hair_longovereye" - flags = HAIR_TIEABLE - - shortovereye - name = "Overeye Short" - icon_state = "hair_shortovereye" - flags = HAIR_TIEABLE - - veryshortovereyealternate - name = "Overeye Very Short, Alternate" - icon_state = "hair_veryshortovereyealternate" - - veryshortovereye - name = "Overeye Very Short" - icon_state = "hair_veryshortovereye" - - parted - name = "Parted" - icon_state = "hair_parted" - - partedalt - name = "Parted Alt" - icon_state = "hair_partedalt" - - - pixie - name = "Pixie Cut" - icon_state = "hair_pixie" - - pompadour - name = "Pompadour" - icon_state = "hair_pompadour" - flags = HAIR_TIEABLE - - dandypomp - name = "Pompadour Dandy" - icon_state = "hair_dandypompadour" - flags = HAIR_TIEABLE - - ponytail1 - name = "Ponytail 1" - icon_state = "hair_ponytail" - flags = HAIR_TIEABLE|HAIR_VERY_SHORT - - ponytail2 - name = "Ponytail 2" - icon_state = "hair_pa" - flags = HAIR_TIEABLE - - ponytail3 - name = "Ponytail 3" - icon_state = "hair_ponytail3" - flags = HAIR_TIEABLE - - ponytail4 - name = "Ponytail 4" - icon_state = "hair_ponytail4" - flags = HAIR_TIEABLE - - ponytail5 - name = "Ponytail 5" - icon_state = "hair_ponytail5" - flags = HAIR_TIEABLE - - ponytail6 - name = "Ponytail 6" - icon_state = "hair_ponytail6" - flags = HAIR_TIEABLE|HAIR_VERY_SHORT - - sharpponytail - name = "Ponytail Sharp" - icon_state = "hair_sharpponytail" - flags = HAIR_TIEABLE - - spikyponytail - name = "Ponytail Spiky" - icon_state = "hair_spikyponytail" - flags = HAIR_TIEABLE - - poofy - name = "Poofy" - icon_state = "hair_poofy" - flags = HAIR_TIEABLE - - poofy2 - name = "Poofy 2" - icon_state = "hair_poofy2" - flags = HAIR_TIEABLE - - proper - name = "Proper" - icon_state = "hair_proper" - - quiff - name = "Quiff" - icon_state = "hair_quiff" - - nofade - name = "Regulation Cut" - icon_state = "hair_nofade" - gender = MALE - flags = HAIR_VERY_SHORT - - newyou - name = "New You" - icon_state = "hair_newyou" - flags = HAIR_TIEABLE - - ronin - name = "Ronin" - icon_state = "hair_ronin" - flags = HAIR_TIEABLE - - rosa - name = "Rosa" - icon_state = "hair_rosa" - flags = HAIR_TIEABLE - - rows - name = "Rows" - icon_state = "hair_rows1" - flags = HAIR_VERY_SHORT - - rows2 - name = "Rows 2" - icon_state = "hair_rows2" - flags = HAIR_TIEABLE - - rowbun - name = "Row Bun" - icon_state = "hair_rowbun" - flags = HAIR_TIEABLE - - rowdualbraid - name = "Row Dual Braid" - icon_state = "hair_rowdualtail" - flags = HAIR_TIEABLE - - rowbraid - name = "Row Braid" - icon_state = "hair_rowbraid" - flags = HAIR_TIEABLE - - sabitsuki - name = "Sabitsuki" - icon_state = "hair_sabitsuki" - flags = HAIR_VERY_SHORT - - scully - name = "Scully" - icon_state = "hair_scully" - - shavehair - name = "Shaved Hair" - icon_state = "hair_shaved" - flags = HAIR_VERY_SHORT - - shortbangs - name = "Short Bangs" - icon_state = "hair_shortbangs" - - short - name = "Short Hair" // try to capatilize the names please~ - icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you - flags = HAIR_VERY_SHORT - - short2 - name = "Short Hair 2" - icon_state = "hair_shorthair3" - flags = HAIR_VERY_SHORT - - short3 - name = "Short Hair 3" - icon_state = "hair_shorthair4" - flags = HAIR_VERY_SHORT - - shy - name = "Shy" - icon_state = "hair_shy" - flags = HAIR_TIEABLE - - sideponytail - name = "Side Ponytail" - icon_state = "hair_stail" - flags = HAIR_TIEABLE - - sideponytail4 //Not happy about this... but it's for the save files. - name = "Side Ponytail 2" - icon_state = "hair_ponytailf" - flags = HAIR_TIEABLE - - sideponytail2 - name = "Shoulder One" - icon_state = "hair_oneshoulder" - flags = HAIR_TIEABLE - - sideponytail3 - name = "Shoulder Tress" - icon_state = "hair_tressshoulder" - flags = HAIR_TIEABLE - - sideundercut - name = "Side Undercut" - icon_state = "hair_sideundercut" - flags = HAIR_VERY_SHORT - - skinhead - name = "Skinhead" - icon_state = "hair_skinhead" - flags = HAIR_VERY_SHORT - - sleeze - name = "Sleeze" - icon_state = "hair_sleeze" - flags = HAIR_VERY_SHORT - - protagonist - name = "Slightly Long" - icon_state = "hair_protagonist" - flags = HAIR_TIEABLE - - spiky - name = "Spiky" - icon_state = "hair_spikey" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - - straightlong - name = "Straight Long" - icon_state = "hair_straightlong" - flags = HAIR_TIEABLE - - sweepshave - name = "Sweep Shave" - icon_state = "hair_sweepshave" - - thinning - name = "Thinning" - icon_state = "hair_thinning" - flags = HAIR_VERY_SHORT - - thinningfront - name = "Thinning Front" - icon_state = "hair_thinningfront" - flags = HAIR_VERY_SHORT - - thinningback - name = "Thinning Back" - icon_state = "hair_thinningrear" - flags = HAIR_VERY_SHORT - - topknot - name = "Topknot" - icon_state = "hair_topknot" - flags = HAIR_TIEABLE - - trimflat - name = "Trimmed Flat Top" - icon_state = "hair_trimflat" - gender = MALE - flags = HAIR_VERY_SHORT - - trimmed - name = "Trimmed" - icon_state = "hair_trimmed" - gender = MALE - flags = HAIR_VERY_SHORT - - twintail - name = "Twintail" - icon_state = "hair_twintail" - flags = HAIR_TIEABLE - - undercut1 - name = "Undercut" - icon_state = "hair_undercut1" - gender = MALE - flags = HAIR_VERY_SHORT - - undercut2 - name = "Undercut Swept Right" - icon_state = "hair_undercut2" - gender = MALE - flags = HAIR_VERY_SHORT - - undercut3 - name = "Undercut Swept Left" - icon_state = "hair_undercut3" - gender = MALE - flags = HAIR_VERY_SHORT - - unkept - name = "Unkept" - icon_state = "hair_unkept" - flags = HAIR_TIEABLE - - updo - name = "Updo" - icon_state = "hair_updo" - flags = HAIR_TIEABLE - - vegeta - name = "Vegeta" - icon_state = "hair_toriyama2" - - vivi - name = "Vivi" - icon_state = "hair_vivi" - - volaju - name = "Volaju" - icon_state = "hair_volaju" - flags = HAIR_TIEABLE - - wisp - name = "Wisp" - icon_state = "hair_wisp" - flags = HAIR_TIEABLE - - zieglertail - name = "Zieglertail" - icon_state = "hair_ziegler" - flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/longer + name = "Long Hair" + icon_state = "hair_vlong" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/longeralt2 + name = "Long Hair Alt 2" + icon_state = "hair_longeralt2" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sidepartlongalt + name = "Long Side Part" + icon_state = "hair_longsidepart" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/longest + name = "Very Long Hair" + icon_state = "hair_longest" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/lowbraid + name = "Low Braid" + icon_state = "hair_hbraid" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/manbun + name = "Manbun" + icon_state = "hair_manbun" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/marysue + name = "Mary Sue" + icon_state = "hair_marysue" + +/datum/sprite_accessory/hair/miles + name = "Miles Hair" + icon_state = "hair_miles" + +/datum/sprite_accessory/hair/modern + name = "Modern" + icon_state = "hair_modern" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/mohawk + name = "Mohawk" + icon_state = "hair_d" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + +/datum/sprite_accessory/hair/regulationmohawk + name = "Mohawk Regulation" + icon_state = "hair_shavedmohawk" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/reversemohawk + name = "Mohawk Reverse" + icon_state = "hair_reversemohawk" + +/datum/sprite_accessory/hair/mohawkunshaven + name = "Mohawk Unshaven" + icon_state = "hair_unshaven_mohawk" + +/datum/sprite_accessory/hair/mulder + name = "Mulder" + icon_state = "hair_mulder" + +/datum/sprite_accessory/hair/newyou + name = "New You" + icon_state = "hair_newyou" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/nia + name = "Nia" + icon_state = "hair_nia" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/nitori + name = "Nitori" + icon_state = "hair_nitori" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/odango + name = "Odango" + icon_state = "hair_odango" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/ombre + name = "Ombre" + icon_state = "hair_ombre" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/oxton + name = "Oxton" + icon_state = "hair_oxton" + +/datum/sprite_accessory/hair/longovereye + name = "Overeye Long" + icon_state = "hair_longovereye" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/shortovereye + name = "Overeye Short" + icon_state = "hair_shortovereye" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/veryshortovereyealternate + name = "Overeye Very Short, Alternate" + icon_state = "hair_veryshortovereyealternate" + +/datum/sprite_accessory/hair/veryshortovereye + name = "Overeye Very Short" + icon_state = "hair_veryshortovereye" + +/datum/sprite_accessory/hair/parted + name = "Parted" + icon_state = "hair_parted" + +/datum/sprite_accessory/hair/partedalt + name = "Parted Alt" + icon_state = "hair_partedalt" + + +/datum/sprite_accessory/hair/pixie + name = "Pixie Cut" + icon_state = "hair_pixie" + +/datum/sprite_accessory/hair/pompadour + name = "Pompadour" + icon_state = "hair_pompadour" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/dandypomp + name = "Pompadour Dandy" + icon_state = "hair_dandypompadour" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/ponytail1 + name = "Ponytail 1" + icon_state = "hair_ponytail" + flags = HAIR_TIEABLE|HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/ponytail2 + name = "Ponytail 2" + icon_state = "hair_pa" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/ponytail3 + name = "Ponytail 3" + icon_state = "hair_ponytail3" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/ponytail4 + name = "Ponytail 4" + icon_state = "hair_ponytail4" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/ponytail5 + name = "Ponytail 5" + icon_state = "hair_ponytail5" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/ponytail6 + name = "Ponytail 6" + icon_state = "hair_ponytail6" + flags = HAIR_TIEABLE|HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/sharpponytail + name = "Ponytail Sharp" + icon_state = "hair_sharpponytail" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/spikyponytail + name = "Ponytail Spiky" + icon_state = "hair_spikyponytail" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/poofy + name = "Poofy" + icon_state = "hair_poofy" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/poofy2 + name = "Poofy 2" + icon_state = "hair_poofy2" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/proper + name = "Proper" + icon_state = "hair_proper" + +/datum/sprite_accessory/hair/quiff + name = "Quiff" + icon_state = "hair_quiff" + +/datum/sprite_accessory/hair/nofade + name = "Regulation Cut" + icon_state = "hair_nofade" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/newyou + name = "New You" + icon_state = "hair_newyou" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/ronin + name = "Ronin" + icon_state = "hair_ronin" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/rosa + name = "Rosa" + icon_state = "hair_rosa" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/rows + name = "Rows" + icon_state = "hair_rows1" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/rows2 + name = "Rows 2" + icon_state = "hair_rows2" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/rowbun + name = "Row Bun" + icon_state = "hair_rowbun" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/rowdualbraid + name = "Row Dual Braid" + icon_state = "hair_rowdualtail" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/rowbraid + name = "Row Braid" + icon_state = "hair_rowbraid" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sabitsuki + name = "Sabitsuki" + icon_state = "hair_sabitsuki" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/scully + name = "Scully" + icon_state = "hair_scully" + +/datum/sprite_accessory/hair/shavehair + name = "Shaved Hair" + icon_state = "hair_shaved" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/shortbangs + name = "Short Bangs" + icon_state = "hair_shortbangs" + +/datum/sprite_accessory/hair/short + name = "Short Hair" // try to capatilize the names please~ + icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/short2 + name = "Short Hair 2" + icon_state = "hair_shorthair3" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/short3 + name = "Short Hair 3" + icon_state = "hair_shorthair4" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/shy + name = "Shy" + icon_state = "hair_shy" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sideponytail + name = "Side Ponytail" + icon_state = "hair_stail" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sideponytail4 //Not happy about this... but it's for the save files. + name = "Side Ponytail 2" + icon_state = "hair_ponytailf" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sideponytail2 + name = "Shoulder One" + icon_state = "hair_oneshoulder" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sideponytail3 + name = "Shoulder Tress" + icon_state = "hair_tressshoulder" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sideundercut + name = "Side Undercut" + icon_state = "hair_sideundercut" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/skinhead + name = "Skinhead" + icon_state = "hair_skinhead" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/sleeze + name = "Sleeze" + icon_state = "hair_sleeze" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/protagonist + name = "Slightly Long" + icon_state = "hair_protagonist" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/spiky + name = "Spiky" + icon_state = "hair_spikey" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + +/datum/sprite_accessory/hair/straightlong + name = "Straight Long" + icon_state = "hair_straightlong" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/sweepshave + name = "Sweep Shave" + icon_state = "hair_sweepshave" + +/datum/sprite_accessory/hair/thinning + name = "Thinning" + icon_state = "hair_thinning" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/thinningfront + name = "Thinning Front" + icon_state = "hair_thinningfront" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/thinningback + name = "Thinning Back" + icon_state = "hair_thinningrear" + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/topknot + name = "Topknot" + icon_state = "hair_topknot" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/trimflat + name = "Trimmed Flat Top" + icon_state = "hair_trimflat" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/trimmed + name = "Trimmed" + icon_state = "hair_trimmed" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/twintail + name = "Twintail" + icon_state = "hair_twintail" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/undercut1 + name = "Undercut" + icon_state = "hair_undercut1" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/undercut2 + name = "Undercut Swept Right" + icon_state = "hair_undercut2" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/undercut3 + name = "Undercut Swept Left" + icon_state = "hair_undercut3" + gender = MALE + flags = HAIR_VERY_SHORT + +/datum/sprite_accessory/hair/unkept + name = "Unkept" + icon_state = "hair_unkept" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/updo + name = "Updo" + icon_state = "hair_updo" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/vegeta + name = "Vegeta" + icon_state = "hair_toriyama2" + +/datum/sprite_accessory/hair/vivi + name = "Vivi" + icon_state = "hair_vivi" + +/datum/sprite_accessory/hair/volaju + name = "Volaju" + icon_state = "hair_volaju" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/wisp + name = "Wisp" + icon_state = "hair_wisp" + flags = HAIR_TIEABLE + +/datum/sprite_accessory/hair/zieglertail + name = "Zieglertail" + icon_state = "hair_ziegler" + flags = HAIR_TIEABLE /* /////////////////////////////////// @@ -937,139 +937,138 @@ */ /datum/sprite_accessory/facial_hair - icon = 'icons/mob/Human_face.dmi' - shaved - name = "Shaved" - icon_state = "bald" - gender = NEUTER - species_allowed = list(SPECIES_HUMAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI,SPECIES_TAJ,SPECIES_SKRELL, "Machine", SPECIES_TESHARI, SPECIES_TESHARI,SPECIES_PROMETHEAN) +/datum/sprite_accessory/facial_hair/shaved + name = "Shaved" + icon_state = "bald" + gender = NEUTER + species_allowed = list(SPECIES_HUMAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI,SPECIES_TAJ,SPECIES_SKRELL, "Machine", SPECIES_TESHARI, SPECIES_TESHARI,SPECIES_PROMETHEAN) - watson - name = "Watson Mustache" - icon_state = "facial_watson" +/datum/sprite_accessory/facial_hair/watson + name = "Watson Mustache" + icon_state = "facial_watson" - hogan - name = "Hulk Hogan Mustache" - icon_state = "facial_hogan" //-Neek +/datum/sprite_accessory/facial_hair/hogan + name = "Hulk Hogan Mustache" + icon_state = "facial_hogan" //-Neek - vandyke - name = "Van Dyke Mustache" - icon_state = "facial_vandyke" +/datum/sprite_accessory/facial_hair/vandyke + name = "Van Dyke Mustache" + icon_state = "facial_vandyke" - chaplin - name = "Square Mustache" - icon_state = "facial_chaplin" +/datum/sprite_accessory/facial_hair/chaplin + name = "Square Mustache" + icon_state = "facial_chaplin" - selleck - name = "Selleck Mustache" - icon_state = "facial_selleck" +/datum/sprite_accessory/facial_hair/selleck + name = "Selleck Mustache" + icon_state = "facial_selleck" - neckbeard - name = "Neckbeard" - icon_state = "facial_neckbeard" +/datum/sprite_accessory/facial_hair/neckbeard + name = "Neckbeard" + icon_state = "facial_neckbeard" - fullbeard - name = "Full Beard" - icon_state = "facial_fullbeard" +/datum/sprite_accessory/facial_hair/fullbeard + name = "Full Beard" + icon_state = "facial_fullbeard" - longbeard - name = "Long Beard" - icon_state = "facial_longbeard" +/datum/sprite_accessory/facial_hair/longbeard + name = "Long Beard" + icon_state = "facial_longbeard" - vlongbeard - name = "Very Long Beard" - icon_state = "facial_wise" +/datum/sprite_accessory/facial_hair/vlongbeard + name = "Very Long Beard" + icon_state = "facial_wise" - elvis - name = "Elvis Sideburns" - icon_state = "facial_elvis" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) +/datum/sprite_accessory/facial_hair/elvis + name = "Elvis Sideburns" + icon_state = "facial_elvis" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - abe - name = "Abraham Lincoln Beard" - icon_state = "facial_abe" +/datum/sprite_accessory/facial_hair/abe + name = "Abraham Lincoln Beard" + icon_state = "facial_abe" - chinstrap - name = "Chinstrap" - icon_state = "facial_chin" +/datum/sprite_accessory/facial_hair/chinstrap + name = "Chinstrap" + icon_state = "facial_chin" - hip - name = "Hipster Beard" - icon_state = "facial_hip" +/datum/sprite_accessory/facial_hair/hip + name = "Hipster Beard" + icon_state = "facial_hip" - gt - name = "Goatee" - icon_state = "facial_gt" +/datum/sprite_accessory/facial_hair/gt + name = "Goatee" + icon_state = "facial_gt" - jensen - name = "Adam Jensen Beard" - icon_state = "facial_jensen" +/datum/sprite_accessory/facial_hair/jensen + name = "Adam Jensen Beard" + icon_state = "facial_jensen" - volaju - name = "Volaju" - icon_state = "facial_volaju" +/datum/sprite_accessory/facial_hair/volaju + name = "Volaju" + icon_state = "facial_volaju" - dwarf - name = "Dwarf Beard" - icon_state = "facial_dwarf" +/datum/sprite_accessory/facial_hair/dwarf + name = "Dwarf Beard" + icon_state = "facial_dwarf" - threeOclock - name = "3 O'clock Shadow" - icon_state = "facial_3oclock" +/datum/sprite_accessory/facial_hair/threeOclock + name = "3 O'clock Shadow" + icon_state = "facial_3oclock" - threeOclockstache - name = "3 O'clock Shadow and Moustache" - icon_state = "facial_3oclockmoustache" +/datum/sprite_accessory/facial_hair/threeOclockstache + name = "3 O'clock Shadow and Moustache" + icon_state = "facial_3oclockmoustache" - fiveOclock - name = "5 O'clock Shadow" - icon_state = "facial_5oclock" +/datum/sprite_accessory/facial_hair/fiveOclock + name = "5 O'clock Shadow" + icon_state = "facial_5oclock" - fiveOclockstache - name = "5 O'clock Shadow and Moustache" - icon_state = "facial_5oclockmoustache" +/datum/sprite_accessory/facial_hair/fiveOclockstache + name = "5 O'clock Shadow and Moustache" + icon_state = "facial_5oclockmoustache" - sevenOclock - name = "7 O'clock Shadow" - icon_state = "facial_7oclock" +/datum/sprite_accessory/facial_hair/sevenOclock + name = "7 O'clock Shadow" + icon_state = "facial_7oclock" - sevenOclockstache - name = "7 O'clock Shadow and Moustache" - icon_state = "facial_7oclockmoustache" +/datum/sprite_accessory/facial_hair/sevenOclockstache + name = "7 O'clock Shadow and Moustache" + icon_state = "facial_7oclockmoustache" - mutton - name = "Mutton Chops" - icon_state = "facial_mutton" +/datum/sprite_accessory/facial_hair/mutton + name = "Mutton Chops" + icon_state = "facial_mutton" - muttonstache - name = "Mutton Chops and Moustache" - icon_state = "facial_muttonmus" +/datum/sprite_accessory/facial_hair/muttonstache + name = "Mutton Chops and Moustache" + icon_state = "facial_muttonmus" - walrus - name = "Walrus Moustache" - icon_state = "facial_walrus" +/datum/sprite_accessory/facial_hair/walrus + name = "Walrus Moustache" + icon_state = "facial_walrus" - croppedbeard - name = "Full Cropped Beard" - icon_state = "facial_croppedfullbeard" +/datum/sprite_accessory/facial_hair/croppedbeard + name = "Full Cropped Beard" + icon_state = "facial_croppedfullbeard" - chinless - name = "Chinless Beard" - icon_state = "facial_chinlessbeard" +/datum/sprite_accessory/facial_hair/chinless + name = "Chinless Beard" + icon_state = "facial_chinlessbeard" - tribeard - name = "Tribeard" - icon_state = "facial_tribeard" +/datum/sprite_accessory/facial_hair/tribeard + name = "Tribeard" + icon_state = "facial_tribeard" - moonshiner - name = "Moonshiner" - icon_state = "facial_moonshiner" +/datum/sprite_accessory/facial_hair/moonshiner + name = "Moonshiner" + icon_state = "facial_moonshiner" - martial - name = "Martial Artist" - icon_state = "facial_martialartist" +/datum/sprite_accessory/facial_hair/martial + name = "Martial Artist" + icon_state = "facial_martialartist" /* /////////////////////////////////// / =---------------------------= / @@ -1078,365 +1077,337 @@ /////////////////////////////////// */ -/datum/sprite_accessory/hair - una_spines_long - name = "Long Unathi Spines" - icon_state = "soghun_longspines" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_spines_long + name = "Long Unathi Spines" + icon_state = "soghun_longspines" + species_allowed = list(SPECIES_UNATHI) - una_spines_short - name = "Short Unathi Spines" - icon_state = "soghun_shortspines" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_spines_short + name = "Short Unathi Spines" + icon_state = "soghun_shortspines" + species_allowed = list(SPECIES_UNATHI) - una_frills_long - name = "Long Unathi Frills" - icon_state = "soghun_longfrills" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_frills_long + name = "Long Unathi Frills" + icon_state = "soghun_longfrills" + species_allowed = list(SPECIES_UNATHI) - una_frills_short - name = "Short Unathi Frills" - icon_state = "soghun_shortfrills" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_frills_short + name = "Short Unathi Frills" + icon_state = "soghun_shortfrills" + species_allowed = list(SPECIES_UNATHI) - una_horns - name = "Unathi Horns" - icon_state = "soghun_horns" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_horns + name = "Unathi Horns" + icon_state = "soghun_horns" + species_allowed = list(SPECIES_UNATHI) - una_bighorns - name = "Unathi Big Horns" - icon_state = "unathi_bighorn" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_bighorns + name = "Unathi Big Horns" + icon_state = "unathi_bighorn" + species_allowed = list(SPECIES_UNATHI) - una_smallhorns - name = "Unathi Small Horns" - icon_state = "unathi_smallhorn" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_smallhorns + name = "Unathi Small Horns" + icon_state = "unathi_smallhorn" + species_allowed = list(SPECIES_UNATHI) - una_ramhorns - name = "Unathi Ram Horns" - icon_state = "unathi_ramhorn" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_ramhorns + name = "Unathi Ram Horns" + icon_state = "unathi_ramhorn" + species_allowed = list(SPECIES_UNATHI) - una_sidefrills - name = "Unathi Side Frills" - icon_state = "unathi_sidefrills" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/hair/una_sidefrills + name = "Unathi Side Frills" + icon_state = "unathi_sidefrills" + species_allowed = list(SPECIES_UNATHI) //Skrell 'hairstyles' - skr_tentacle_veryshort - name = "Skrell Short Tentacles" - icon_state = "skrell_hair_short" - species_allowed = list(SPECIES_SKRELL) - gender = MALE +/datum/sprite_accessory/hair/skr_tentacle_veryshort + name = "Skrell Short Tentacles" + icon_state = "skrell_hair_short" + species_allowed = list(SPECIES_SKRELL) + gender = MALE - skr_tentacle_short - name = "Skrell Average Tentacles" - icon_state = "skrell_hair_average" - species_allowed = list(SPECIES_SKRELL) +/datum/sprite_accessory/hair/skr_tentacle_short + name = "Skrell Average Tentacles" + icon_state = "skrell_hair_average" + species_allowed = list(SPECIES_SKRELL) - skr_tentacle_average - name = "Skrell Long Tentacles" - icon_state = "skrell_hair_long" - species_allowed = list(SPECIES_SKRELL) +/datum/sprite_accessory/hair/skr_tentacle_average + name = "Skrell Long Tentacles" + icon_state = "skrell_hair_long" + species_allowed = list(SPECIES_SKRELL) - skr_tentacle_verylong - name = "Skrell Very Long Tentacles" - icon_state = "skrell_hair_verylong" - species_allowed = list(SPECIES_SKRELL) - gender = FEMALE +/datum/sprite_accessory/hair/skr_tentacle_verylong + name = "Skrell Very Long Tentacles" + icon_state = "skrell_hair_verylong" + species_allowed = list(SPECIES_SKRELL) //Tajaran hairstyles - taj_ears - name = "Tajaran Ears" - icon_state = "ears_plain" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears + name = "Tajaran Ears" + icon_state = "ears_plain" + species_allowed = list(SPECIES_TAJ) - taj_ears_clean - name = "Tajaran Clean" - icon_state = "hair_clean" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_clean + name = "Tajaran Clean" + icon_state = "hair_clean" + species_allowed = list(SPECIES_TAJ) - taj_ears_bangs - name = "Tajaran Bangs" - icon_state = "hair_bangs" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_bangs + name = "Tajaran Bangs" + icon_state = "hair_bangs" + species_allowed = list(SPECIES_TAJ) - taj_ears_braid - name = "Tajaran Braid" - icon_state = "hair_tbraid" - species_allowed = list(SPECIES_TAJ) - taj_ears_shaggy - name = "Tajaran Shaggy" - icon_state = "hair_shaggy" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_braid + name = "Tajaran Braid" + icon_state = "hair_tbraid" + species_allowed = list(SPECIES_TAJ) - taj_ears_mohawk - name = "Tajaran Mohawk" - icon_state = "hair_mohawk" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_shaggy + name = "Tajaran Shaggy" + icon_state = "hair_shaggy" + species_allowed = list(SPECIES_TAJ) - taj_ears_plait - name = "Tajaran Plait" - icon_state = "hair_plait" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_mohawk + name = "Tajaran Mohawk" + icon_state = "hair_mohawk" + species_allowed = list(SPECIES_TAJ) - taj_ears_straight - name = "Tajaran Straight" - icon_state = "hair_straight" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_plait + name = "Tajaran Plait" + icon_state = "hair_plait" + species_allowed = list(SPECIES_TAJ) - taj_ears_long - name = "Tajaran Long" - icon_state = "hair_long" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_straight + name = "Tajaran Straight" + icon_state = "hair_straight" + species_allowed = list(SPECIES_TAJ) - taj_ears_rattail - name = "Tajaran Rat Tail" - icon_state = "hair_rattail" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_long + name = "Tajaran Long" + icon_state = "hair_long" + species_allowed = list(SPECIES_TAJ) - taj_ears_spiky - name = "Tajaran Spiky" - icon_state = "hair_tajspiky" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_rattail + name = "Tajaran Rat Tail" + icon_state = "hair_rattail" + species_allowed = list(SPECIES_TAJ) - taj_ears_messy - name = "Tajaran Messy" - icon_state = "hair_messy" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_spiky + name = "Tajaran Spiky" + icon_state = "hair_tajspiky" + species_allowed = list(SPECIES_TAJ) - taj_ears_curls - name = "Tajaran Curly" - icon_state = "hair_curly" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_messy + name = "Tajaran Messy" + icon_state = "hair_messy" + species_allowed = list(SPECIES_TAJ) - taj_ears_wife - name = "Tajaran Housewife" - icon_state = "hair_wife" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_curls + name = "Tajaran Curly" + icon_state = "hair_curly" + species_allowed = list(SPECIES_TAJ) - taj_ears_victory - name = "Tajaran Victory Curls" - icon_state = "hair_victory" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_wife + name = "Tajaran Housewife" + icon_state = "hair_wife" + species_allowed = list(SPECIES_TAJ) - taj_ears_bob - name = "Tajaran Bob" - icon_state = "hair_tbob" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_victory + name = "Tajaran Victory Curls" + icon_state = "hair_victory" + species_allowed = list(SPECIES_TAJ) - taj_ears_fingercurl - name = "Tajaran Finger Curls" - icon_state = "hair_fingerwave" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/hair/taj_ears_bob + name = "Tajaran Bob" + icon_state = "hair_tbob" + species_allowed = list(SPECIES_TAJ) + +/datum/sprite_accessory/hair/taj_ears_fingercurl + name = "Tajaran Finger Curls" + icon_state = "hair_fingerwave" + species_allowed = list(SPECIES_TAJ) //Teshari things - teshari - name = "Teshari Default" - icon_state = "teshari_default" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari + name = "Teshari Default" + icon_state = "teshari_default" + species_allowed = list(SPECIES_TESHARI) - teshari_altdefault - name = "Teshari Alt. Default" - icon_state = "teshari_ears" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/altdefault + name = "Teshari Alt. Default" + icon_state = "teshari_ears" - teshari_tight - name = "Teshari Tight" - icon_state = "teshari_tight" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/tight + name = "Teshari Tight" + icon_state = "teshari_tight" - teshari_excited - name = "Teshari Spiky" - icon_state = "teshari_spiky" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/excited + name = "Teshari Spiky" + icon_state = "teshari_spiky" - teshari_spike - name = "Teshari Spike" - icon_state = "teshari_spike" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/spike + name = "Teshari Spike" + icon_state = "teshari_spike" - teshari_long - name = "Teshari Overgrown" - icon_state = "teshari_long" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/long + name = "Teshari Overgrown" + icon_state = "teshari_long" - teshari_burst - name = "Teshari Starburst" - icon_state = "teshari_burst" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/burst + name = "Teshari Starburst" + icon_state = "teshari_burst" - teshari_shortburst - name = "Teshari Short Starburst" - icon_state = "teshari_burst_short" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/shortburst + name = "Teshari Short Starburst" + icon_state = "teshari_burst_short" - teshari_mohawk - name = "Teshari Mohawk" - icon_state = "teshari_mohawk" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/mohawk + name = "Teshari Mohawk" + icon_state = "teshari_mohawk" - teshari_pointy +/datum/sprite_accessory/hair/teshari/pointy name = "Teshari Pointy" icon_state = "teshari_pointy" - species_allowed = list(SPECIES_TESHARI) - teshari_upright - name = "Teshari Upright" - icon_state = "teshari_upright" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/upright + name = "Teshari Upright" + icon_state = "teshari_upright" - teshari_mane - name = "Teshari Mane" - icon_state = "teshari_mane" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/mane + name = "Teshari Mane" + icon_state = "teshari_mane" - teshari_droopy - name = "Teshari Droopy" - icon_state = "teshari_droopy" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/droopy + name = "Teshari Droopy" + icon_state = "teshari_droopy" - teshari_mushroom - name = "Teshari Mushroom" - icon_state = "teshari_mushroom" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/mushroom + name = "Teshari Mushroom" + icon_state = "teshari_mushroom" //Tesh things ported from Ark Station - teshari_twies - name = "Teshari Twies" - icon_state = "teshari_twies" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/twies + name = "Teshari Twies" + icon_state = "teshari_twies" - teshari_backstrafe - name = "Teshari Backstrafe" - icon_state = "teshari_backstrafe" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/backstrafe + name = "Teshari Backstrafe" + icon_state = "teshari_backstrafe" - teshari_longway - name = "Teshari Long way" - icon_state = "teshari_longway" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/_longway + name = "Teshari Long way" + icon_state = "teshari_longway" - teshari_tree - name = "Teshari Tree" - icon_state = "teshari_tree" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/tree + name = "Teshari Tree" + icon_state = "teshari_tree" - teshari_fluffymohawk - name = "Teshari Fluffy Mohawk" - icon_state = "teshari_fluffymohawk" - species_allowed = list(SPECIES_TESHARI) - -//bald tesh hair for FBP use - - teshari_bald - name = "Bald (use with FBP)" - icon_state = "bald" - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/hair/teshari/fluffymohawk + name = "Teshari Fluffy Mohawk" + icon_state = "teshari_fluffymohawk" // Vox things - vox_braid_long - name = "Long Vox braid" - icon_state = "vox_longbraid" - species_allowed = list(SPECIES_VOX) +/datum/sprite_accessory/hair/vox_braid_long + name = "Long Vox braid" + icon_state = "vox_longbraid" + species_allowed = list(SPECIES_VOX) - vox_braid_short - name = "Short Vox Braid" - icon_state = "vox_shortbraid" - species_allowed = list(SPECIES_VOX) +/datum/sprite_accessory/hair/vox_braid_short + name = "Short Vox Braid" + icon_state = "vox_shortbraid" + species_allowed = list(SPECIES_VOX) - vox_quills_short - name = "Short Vox Quills" - icon_state = "vox_shortquills" - species_allowed = list(SPECIES_VOX) +/datum/sprite_accessory/hair/vox_quills_short + name = "Short Vox Quills" + icon_state = "vox_shortquills" + species_allowed = list(SPECIES_VOX) - vox_quills_kingly - name = "Kingly Vox Quills" - icon_state = "vox_kingly" - species_allowed = list(SPECIES_VOX) +/datum/sprite_accessory/hair/vox_quills_kingly + name = "Kingly Vox Quills" + icon_state = "vox_kingly" + species_allowed = list(SPECIES_VOX) - vox_quills_mohawk - name = "Quill Mohawk" - icon_state = "vox_mohawk" - species_allowed = list(SPECIES_VOX) +/datum/sprite_accessory/hair/vox_quills_mohawk + name = "Quill Mohawk" + icon_state = "vox_mohawk" + species_allowed = list(SPECIES_VOX) -/datum/sprite_accessory/facial_hair +/datum/sprite_accessory/facial_hair/taj_sideburns + name = "Tajaran Sideburns" + icon_state = "facial_sideburns" + species_allowed = list(SPECIES_TAJ) - taj_sideburns - name = "Tajaran Sideburns" - icon_state = "facial_sideburns" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/facial_hair/taj_mutton + name = "Tajaran Mutton" + icon_state = "facial_mutton" + species_allowed = list(SPECIES_TAJ) - taj_mutton - name = "Tajaran Mutton" - icon_state = "facial_mutton" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/facial_hair/taj_pencilstache + name = "Tajaran Pencilstache" + icon_state = "facial_pencilstache" + species_allowed = list(SPECIES_TAJ) - taj_pencilstache - name = "Tajaran Pencilstache" - icon_state = "facial_pencilstache" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/facial_hair/taj_moustache + name = "Tajaran Moustache" + icon_state = "facial_moustache" + species_allowed = list(SPECIES_TAJ) - taj_moustache - name = "Tajaran Moustache" - icon_state = "facial_moustache" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/facial_hair/taj_goatee + name = "Tajaran Goatee" + icon_state = "facial_goatee" + species_allowed = list(SPECIES_TAJ) - taj_goatee - name = "Tajaran Goatee" - icon_state = "facial_goatee" - species_allowed = list(SPECIES_TAJ) - - taj_smallstache - name = "Tajaran Smallsatche" - icon_state = "facial_smallstache" - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/facial_hair/taj_smallstache + name = "Tajaran Smallsatche" + icon_state = "facial_smallstache" + species_allowed = list(SPECIES_TAJ) //unathi horn beards and the like - una_chinhorn - name = "Unathi Chin Horn" - icon_state = "facial_chinhorns" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/facial_hair/una_chinhorn + name = "Unathi Chin Horn" + icon_state = "facial_chinhorns" + species_allowed = list(SPECIES_UNATHI) - una_hornadorns - name = "Unathi Horn Adorns" - icon_state = "facial_hornadorns" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/facial_hair/una_hornadorns + name = "Unathi Horn Adorns" + icon_state = "facial_hornadorns" + species_allowed = list(SPECIES_UNATHI) - una_spinespikes - name = "Unathi Spine Spikes" - icon_state = "facial_spikes" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/facial_hair/una_spinespikes + name = "Unathi Spine Spikes" + icon_state = "facial_spikes" + species_allowed = list(SPECIES_UNATHI) - una_dorsalfrill - name = "Unathi Dorsal Frill" - icon_state = "facial_dorsalfrill" - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/facial_hair/una_dorsalfrill + name = "Unathi Dorsal Frill" + icon_state = "facial_dorsalfrill" + species_allowed = list(SPECIES_UNATHI) //Teshari things - teshari_beard - name = "Teshari Beard" - icon_state = "teshari_chin" - species_allowed = list(SPECIES_TESHARI) - gender = NEUTER +/datum/sprite_accessory/facial_hair/teshari_beard + name = "Teshari Beard" + icon_state = "teshari_chin" + species_allowed = list(SPECIES_TESHARI) + gender = NEUTER - teshari_scraggly - name = "Teshari Scraggly" - icon_state = "teshari_scraggly" - species_allowed = list(SPECIES_TESHARI) - gender = NEUTER +/datum/sprite_accessory/facial_hair/teshari_scraggly + name = "Teshari Scraggly" + icon_state = "teshari_scraggly" + species_allowed = list(SPECIES_TESHARI) + gender = NEUTER - teshari_chops - name = "Teshari Chops" - icon_state = "teshari_gap" - species_allowed = list(SPECIES_TESHARI) - gender = NEUTER +/datum/sprite_accessory/facial_hair/teshari_chops + name = "Teshari Chops" + icon_state = "teshari_gap" + species_allowed = list(SPECIES_TESHARI) + gender = NEUTER /* //////////////////////////// @@ -1456,231 +1427,276 @@ var/body_parts = list() //A list of bodyparts this covers, in organ_tag defines //Reminder: BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_GROIN,BP_HEAD - tat_heart - name = "Tattoo (Heart, Torso)" - icon_state = "tat_heart" - body_parts = list(BP_TORSO) +/datum/sprite_accessory/marking/tat_heart + name = "Tattoo (Heart, Torso)" + icon_state = "tat_heart" + body_parts = list(BP_TORSO) - tat_hive - name = "Tattoo (Hive, Back)" - icon_state = "tat_hive" - body_parts = list(BP_TORSO) +/datum/sprite_accessory/marking/tat_hive + name = "Tattoo (Hive, Back)" + icon_state = "tat_hive" + body_parts = list(BP_TORSO) - tat_nightling - name = "Tattoo (Nightling, Back)" - icon_state = "tat_nightling" - body_parts = list(BP_TORSO) +/datum/sprite_accessory/marking/tat_nightling + name = "Tattoo (Nightling, Back)" + icon_state = "tat_nightling" + body_parts = list(BP_TORSO) - tat_campbell - name = "Tattoo (Campbell, R.Arm)" - icon_state = "tat_campbell" - body_parts = list(BP_R_ARM) +/datum/sprite_accessory/marking/tat_campbell + name = "Tattoo (Campbell, R.Arm)" + icon_state = "tat_campbell" + body_parts = list(BP_R_ARM) - left - name = "Tattoo (Campbell, L.Arm)" - body_parts = list(BP_L_ARM) +/datum/sprite_accessory/marking/tat_campbell/left + name = "Tattoo (Campbell, L.Arm)" + body_parts = list(BP_L_ARM) - rightleg - name = "Tattoo (Campbell, R.Leg)" - body_parts = list(BP_R_LEG) +/datum/sprite_accessory/marking/tat_campbell/rightleg + name = "Tattoo (Campbell, R.Leg)" + body_parts = list(BP_R_LEG) - leftleg - name = "Tattoo (Campbell, L.Leg)" - body_parts = list (BP_L_LEG) +/datum/sprite_accessory/marking/tat_campbell/leftleg + name = "Tattoo (Campbell, L.Leg)" + body_parts = list (BP_L_LEG) - tat_silverburgh - name = "Tattoo (Silverburgh, R.Leg)" - icon_state = "tat_silverburgh" - body_parts = list (BP_R_LEG) +/datum/sprite_accessory/marking/tat_silverburgh + name = "Tattoo (Silverburgh, R.Leg)" + icon_state = "tat_silverburgh" + body_parts = list (BP_R_LEG) - left - name = "Tattoo (Silverburgh, L.Leg)" - icon_state = "tat_silverburgh" - body_parts = list (BP_L_LEG) +/datum/sprite_accessory/marking/tat_silverburgh/left + name = "Tattoo (Silverburgh, L.Leg)" + icon_state = "tat_silverburgh" + body_parts = list (BP_L_LEG) - tat_tiger - name = "Tattoo (Tiger Stripes, Body)" - icon_state = "tat_tiger" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_GROIN) +/datum/sprite_accessory/marking/tat_tiger + name = "Tattoo (Tiger Stripes, Body)" + icon_state = "tat_tiger" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_GROIN) - taj_paw_socks - name = "Socks Coloration (Taj)" - icon_state = "taj_pawsocks" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_paw_socks + name = "Socks Coloration (Taj)" + icon_state = "taj_pawsocks" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND) + species_allowed = list(SPECIES_TAJ) - una_paw_socks - name = "Socks Coloration (Una)" - icon_state = "una_pawsocks" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND) - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/marking/una_paw_socks + name = "Socks Coloration (Una)" + icon_state = "una_pawsocks" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND) + species_allowed = list(SPECIES_UNATHI) - paw_socks - name = "Socks Coloration (Generic)" - icon_state = "pawsocks" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND) - species_allowed = list(SPECIES_TAJ, SPECIES_UNATHI) +/datum/sprite_accessory/marking/paw_socks + name = "Socks Coloration (Generic)" + icon_state = "pawsocks" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND) + species_allowed = list(SPECIES_TAJ, SPECIES_UNATHI) - paw_socks_belly - name = "Socks,Belly Coloration (Generic)" - icon_state = "pawsocksbelly" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO) - species_allowed = list(SPECIES_TAJ, SPECIES_UNATHI) +/datum/sprite_accessory/marking/paw_socks_belly + name = "Socks,Belly Coloration (Generic)" + icon_state = "pawsocksbelly" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO) + species_allowed = list(SPECIES_TAJ, SPECIES_UNATHI) - belly_hands_feet - name = "Hands,Feet,Belly Color (Minor)" - icon_state = "bellyhandsfeetsmall" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO) - species_allowed = list(SPECIES_TAJ, SPECIES_UNATHI) +/datum/sprite_accessory/marking/belly_hands_feet + name = "Hands,Feet,Belly Color (Minor)" + icon_state = "bellyhandsfeetsmall" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO) + species_allowed = list(SPECIES_TAJ, SPECIES_UNATHI) - hands_feet_belly_full - name = "Hands,Feet,Belly Color (Major)" - icon_state = "bellyhandsfeet" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO) - species_allowed = list(SPECIES_TAJ, SPECIES_UNATHI) +/datum/sprite_accessory/marking/hands_feet_belly_full + name = "Hands,Feet,Belly Color (Major)" + icon_state = "bellyhandsfeet" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO) + species_allowed = list(SPECIES_TAJ, SPECIES_UNATHI) - hands_feet_belly_full_female - name = "Hands,Feet,Belly Color (Major, Female)" - icon_state = "bellyhandsfeet_female" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/hands_feet_belly_full_female + name = "Hands,Feet,Belly Color (Major, Female)" + icon_state = "bellyhandsfeet_female" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO) + species_allowed = list(SPECIES_TAJ) - patches - name = "Color Patches" - icon_state = "patches" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_GROIN) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/patches + name = "Color Patches" + icon_state = "patches" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_GROIN) + species_allowed = list(SPECIES_TAJ) - patchesface - name = "Color Patches (Face)" - icon_state = "patchesface" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/patchesface + name = "Color Patches (Face)" + icon_state = "patchesface" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TAJ) - bands - name = "Color Bands" - icon_state = "bands" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_GROIN) +/datum/sprite_accessory/marking/bands + name = "Color Bands" + icon_state = "bands" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_GROIN) - bandsface - name = "Color Bands (Face)" - icon_state = "bandsface" - body_parts = list(BP_HEAD) +/datum/sprite_accessory/marking/bandsface + name = "Color Bands (Face)" + icon_state = "bandsface" + body_parts = list(BP_HEAD) - tiger_stripes - name = "Tiger Stripes" - icon_state = "tiger" - body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_TORSO,BP_GROIN) - species_allowed = list(SPECIES_TAJ) //There's a tattoo for non-cats +/datum/sprite_accessory/marking/tiger_stripes + name = "Tiger Stripes" + icon_state = "tiger" + body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_TORSO,BP_GROIN) + species_allowed = list(SPECIES_TAJ) //There's a tattoo for non-cats - tigerhead - name = "Tiger Stripes (Head, Minor)" - icon_state = "tigerhead" - body_parts = list(BP_HEAD) +/datum/sprite_accessory/marking/tigerhead + name = "Tiger Stripes (Head, Minor)" + icon_state = "tigerhead" + body_parts = list(BP_HEAD) - tigerface - name = "Tiger Stripes (Head, Major)" - icon_state = "tigerface" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TAJ) //There's a tattoo for non-cats +/datum/sprite_accessory/marking/tigerface + name = "Tiger Stripes (Head, Major)" + icon_state = "tigerface" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TAJ) //There's a tattoo for non-cats - backstripe - name = "Back Stripe" - icon_state = "backstripe" - body_parts = list(BP_TORSO) +/datum/sprite_accessory/marking/backstripe + name = "Back Stripe" + icon_state = "backstripe" + body_parts = list(BP_TORSO) - heterochromia - name = "Heterochromia (right eye)" - icon_state = "heterochromia" - body_parts = list(BP_HEAD) +/datum/sprite_accessory/marking/heterochromia + name = "Heterochromia (right eye)" + icon_state = "heterochromia" + body_parts = list(BP_HEAD) //Taj specific stuff - taj_belly - name = "Belly Fur (Taj)" - icon_state = "taj_belly" - body_parts = list(BP_TORSO) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_belly + name = "Belly Fur (Taj)" + icon_state = "taj_belly" + body_parts = list(BP_TORSO) + species_allowed = list(SPECIES_TAJ) - taj_bellyfull - name = "Belly Fur Wide (Taj)" - icon_state = "taj_bellyfull" - body_parts = list(BP_TORSO) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_bellyfull + name = "Belly Fur Wide (Taj)" + icon_state = "taj_bellyfull" + body_parts = list(BP_TORSO) + species_allowed = list(SPECIES_TAJ) - taj_earsout - name = "Outer Ear (Taj)" - icon_state = "taj_earsout" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_earsout + name = "Outer Ear (Taj)" + icon_state = "taj_earsout" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TAJ) - taj_earsin - name = "Inner Ear (Taj)" - icon_state = "taj_earsin" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_earsin + name = "Inner Ear (Taj)" + icon_state = "taj_earsin" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TAJ) - taj_nose - name = "Nose Color (Taj)" - icon_state = "taj_nose" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_nose + name = "Nose Color (Taj)" + icon_state = "taj_nose" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TAJ) - taj_crest - name = "Chest Fur Crest (Taj)" - icon_state = "taj_crest" - body_parts = list(BP_TORSO) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_crest + name = "Chest Fur Crest (Taj)" + icon_state = "taj_crest" + body_parts = list(BP_TORSO) + species_allowed = list(SPECIES_TAJ) - taj_muzzle - name = "Muzzle Color (Taj)" - icon_state = "taj_muzzle" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_muzzle + name = "Muzzle Color (Taj)" + icon_state = "taj_muzzle" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TAJ) - taj_face - name = "Cheeks Color (Taj)" - icon_state = "taj_face" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_face + name = "Cheeks Color (Taj)" + icon_state = "taj_face" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TAJ) - taj_all - name = "All Taj Head (Taj)" - icon_state = "taj_all" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/marking/taj_all + name = "All Taj Head (Taj)" + icon_state = "taj_all" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TAJ) //Una specific stuff - una_face - name = "Face Color (Una)" - icon_state = "una_face" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/marking/una_face + name = "Face Color (Una)" + icon_state = "una_face" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_UNATHI) - una_facelow - name = "Face Color Low (Una)" - icon_state = "una_facelow" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/marking/una_facelow + name = "Face Color Low (Una)" + icon_state = "una_facelow" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_UNATHI) - una_scutes - name = "Scutes (Una)" - icon_state = "una_scutes" - body_parts = list(BP_TORSO) - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/marking/una_scutes + name = "Scutes (Una)" + icon_state = "una_scutes" + body_parts = list(BP_TORSO) + species_allowed = list(SPECIES_UNATHI) //Tesh stuff. - teshi_fluff - name = "Underfluff (Teshari)" - icon_state = "teshi_fluff" - body_parts = list(BP_HEAD, BP_TORSO, BP_GROIN, BP_R_LEG, BP_L_LEG) - species_allowed = list(SPECIES_TESHARI) +/datum/sprite_accessory/marking/teshi_fluff + name = "Underfluff (Teshari)" + icon_state = "teshi_fluff" + body_parts = list(BP_HEAD, BP_TORSO, BP_GROIN, BP_R_LEG, BP_L_LEG) + species_allowed = list(SPECIES_TESHARI) + +/datum/sprite_accessory/marking/teshi_heterochromia + name = "Heterochromia (Teshari) (right eye)" + icon_state = "teshi_heterochromia" + body_parts = list(BP_HEAD) + species_allowed = list(SPECIES_TESHARI) + + //Diona stuff. + +/datum/sprite_accessory/marking/diona_leaves + name = "Leaves (Diona)" + icon_state = "diona_leaves" + body_parts = list(BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND, BP_TORSO, BP_GROIN, BP_HEAD) + species_allowed = list(SPECIES_DIONA) + +/datum/sprite_accessory/marking/diona_thorns + name = "Thorns (Diona)" + icon_state = "diona_thorns" + body_parts =list(BP_TORSO, BP_HEAD) + species_allowed = list(SPECIES_DIONA) + do_colouration = 0 + +/datum/sprite_accessory/marking/diona_flowers + name = "Flowers (Diona)" + icon_state = "diona_flowers" + body_parts =list(BP_TORSO, BP_HEAD) + species_allowed = list(SPECIES_DIONA) + do_colouration = 0 + +/datum/sprite_accessory/marking/diona_moss + name = "Moss (Diona)" + icon_state = "diona_moss" + body_parts =list(BP_TORSO) + species_allowed = list(SPECIES_DIONA) + do_colouration = 0 + +/datum/sprite_accessory/marking/diona_mushroom + name = "Mushroom (Diona)" + icon_state = "diona_mushroom" + body_parts =list(BP_HEAD) + species_allowed = list(SPECIES_DIONA) + do_colouration = 0 + +/datum/sprite_accessory/marking/diona_antennae + name = "Antennae (Diona)" + icon_state = "diona_antennae" + body_parts =list(BP_HEAD) + species_allowed = list(SPECIES_DIONA) + do_colouration = 0 + - teshi_heterochromia - name = "Heterochromia (Teshari) (right eye)" - icon_state = "teshi_heterochromia" - body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_TESHARI) //skin styles - WIP //going to have to re-integrate this with surgery @@ -1688,30 +1704,30 @@ /datum/sprite_accessory/skin icon = 'icons/mob/human_races/r_human.dmi' - human - name = "Default human skin" - icon_state = "default" - species_allowed = list(SPECIES_HUMAN,SPECIES_HUMAN_VATBORN) +/datum/sprite_accessory/skin/human + name = "Default human skin" + icon_state = "default" + species_allowed = list(SPECIES_HUMAN,SPECIES_HUMAN_VATBORN) - human_tatt01 - name = "Tatt01 human skin" - icon_state = "tatt1" - species_allowed = list(SPECIES_HUMAN,SPECIES_HUMAN_VATBORN) +/datum/sprite_accessory/skin/human_tatt01 + name = "Tatt01 human skin" + icon_state = "tatt1" + species_allowed = list(SPECIES_HUMAN,SPECIES_HUMAN_VATBORN) - tajaran - name = "Default tajaran skin" - icon_state = "default" - icon = 'icons/mob/human_races/r_tajaran.dmi' - species_allowed = list(SPECIES_TAJ) +/datum/sprite_accessory/skin/tajaran + name = "Default tajaran skin" + icon_state = "default" + icon = 'icons/mob/human_races/r_tajaran.dmi' + species_allowed = list(SPECIES_TAJ) - unathi - name = "Default Unathi skin" - icon_state = "default" - icon = 'icons/mob/human_races/r_lizard.dmi' - species_allowed = list(SPECIES_UNATHI) +/datum/sprite_accessory/skin/unathi + name = "Default Unathi skin" + icon_state = "default" + icon = 'icons/mob/human_races/r_lizard.dmi' + species_allowed = list(SPECIES_UNATHI) - skrell - name = "Default skrell skin" - icon_state = "default" - icon = 'icons/mob/human_races/r_skrell.dmi' - species_allowed = list(SPECIES_SKRELL) +/datum/sprite_accessory/skin/skrell + name = "Default skrell skin" + icon_state = "default" + icon = 'icons/mob/human_races/r_skrell.dmi' + species_allowed = list(SPECIES_SKRELL) diff --git a/code/modules/mob/new_player/sprite_accessories_vr.dm b/code/modules/mob/new_player/sprite_accessories_vr.dm index 749e35ed35..9e0681d490 100644 --- a/code/modules/mob/new_player/sprite_accessories_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_vr.dm @@ -158,87 +158,87 @@ taj_ears name = "Tajaran Ears" icon_state = "ears_plain" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_clean name = "Tajara Clean" icon_state = "hair_clean" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_bangs name = "Tajara Bangs" icon_state = "hair_bangs" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_braid name = "Tajara Braid" icon_state = "hair_tbraid" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_shaggy name = "Tajara Shaggy" icon_state = "hair_shaggy" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_mohawk name = "Tajaran Mohawk" icon_state = "hair_mohawk" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_plait name = "Tajara Plait" icon_state = "hair_plait" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_straight name = "Tajara Straight" icon_state = "hair_straight" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_long name = "Tajara Long" icon_state = "hair_long" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_rattail name = "Tajara Rat Tail" icon_state = "hair_rattail" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_spiky name = "Tajara Spiky" icon_state = "hair_tajspiky" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_messy name = "Tajara Messy" icon_state = "hair_messy" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_curls name = "Tajaran Curly" icon_state = "hair_curly" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_wife name = "Tajaran Housewife" icon_state = "hair_wife" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_victory name = "Tajaran Victory Curls" icon_state = "hair_victory" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_bob name = "Tajaran Bob" icon_state = "hair_tbob" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) taj_ears_fingercurl name = "Tajaran Finger Curls" icon_state = "hair_fingerwave" - species_allowed = list(SPECIES_TAJ, SPECIES_XENOCHIMERA, SPECIES_PROTEAN) + species_allowed = list(SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_TAJ, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_PROTEAN) teshari_fluffymohawk name = "Teshari Fluffy Mohawk" diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index f5201f60ec..8aa649b75f 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -37,6 +37,11 @@ forceMove(destination) return 1 + var/obj/structure/ladder/ladder = locate() in start.contents + if((direction == UP ? ladder?.target_up : ladder?.target_down) && (ladder?.allowed_directions & direction)) + if(src.may_climb_ladders(ladder)) + return ladder.climbLadder(src, (direction == UP ? ladder.target_up : ladder.target_down)) + if(!start.CanZPass(src, direction)) to_chat(src, "\The [start] is in the way.") return 0 @@ -46,54 +51,59 @@ return 0 var/area/area = get_area(src) - if(direction == UP && area.has_gravity() && !can_overcome_gravity()) - var/obj/structure/lattice/lattice = locate() in destination.contents - var/obj/structure/catwalk/catwalk = locate() in destination.contents - if(lattice) - var/pull_up_time = max(5 SECONDS + (src.movement_delay() * 10), 1) - to_chat(src, "You grab \the [lattice] and start pulling yourself upward...") - destination.audible_message("You hear something climbing up \the [lattice].") - if(do_after(src, pull_up_time)) - to_chat(src, "You pull yourself up.") - else - to_chat(src, "You gave up on pulling yourself up.") - return 0 - else if(catwalk?.hatch_open) - var/pull_up_time = max(5 SECONDS + (src.movement_delay() * 10), 1) - to_chat(src, "You grab the edge of \the [catwalk] and start pulling yourself upward...") - var/old_dest = destination - destination = get_step(destination, dir) // mob's dir - if(!destination?.Enter(src, old_dest)) - to_chat(src, "There's something in the way up above in that direction, try another.") - return 0 - destination.audible_message("You hear something climbing up \the [catwalk].") - if(do_after(src, pull_up_time)) - to_chat(src, "You pull yourself up.") - else - to_chat(src, "You gave up on pulling yourself up.") - return 0 - else if(ismob(src)) //VOREStation Edit Start. Are they a mob, and are they currently flying?? - var/mob/H = src - if(H.flying) - if(H.incapacitated(INCAPACITATION_ALL)) - to_chat(src, "You can't fly in your current state.") - H.stop_flying() //Should already be done, but just in case. - return 0 - var/fly_time = max(7 SECONDS + (H.movement_delay() * 10), 1) //So it's not too useful for combat. Could make this variable somehow, but that's down the road. - to_chat(src, "You begin to fly upwards...") - destination.audible_message("You hear the flapping of wings.") - H.audible_message("[H] begins to flap \his wings, preparing to move upwards!") - if(do_after(H, fly_time) && H.flying) - to_chat(src, "You fly upwards.") + if(area.has_gravity() && !can_overcome_gravity()) + if(direction == UP) + var/obj/structure/lattice/lattice = locate() in destination.contents + var/obj/structure/catwalk/catwalk = locate() in destination.contents + + if(lattice) + var/pull_up_time = max(5 SECONDS + (src.movement_delay() * 10), 1) + to_chat(src, "You grab \the [lattice] and start pulling yourself upward...") + destination.audible_message("You hear something climbing up \the [lattice].") + if(do_after(src, pull_up_time)) + to_chat(src, "You pull yourself up.") else - to_chat(src, "You stopped flying upwards.") + to_chat(src, "You gave up on pulling yourself up.") return 0 + + else if(catwalk?.hatch_open) + var/pull_up_time = max(5 SECONDS + (src.movement_delay() * 10), 1) + to_chat(src, "You grab the edge of \the [catwalk] and start pulling yourself upward...") + var/old_dest = destination + destination = get_step(destination, dir) // mob's dir + if(!destination?.Enter(src, old_dest)) + to_chat(src, "There's something in the way up above in that direction, try another.") + return 0 + destination.audible_message("You hear something climbing up \the [catwalk].") + if(do_after(src, pull_up_time)) + to_chat(src, "You pull yourself up.") + else + to_chat(src, "You gave up on pulling yourself up.") + return 0 + + else if(ismob(src)) //VOREStation Edit Start. Are they a mob, and are they currently flying?? + var/mob/H = src + if(H.flying) + if(H.incapacitated(INCAPACITATION_ALL)) + to_chat(src, "You can't fly in your current state.") + H.stop_flying() //Should already be done, but just in case. + return 0 + var/fly_time = max(7 SECONDS + (H.movement_delay() * 10), 1) //So it's not too useful for combat. Could make this variable somehow, but that's down the road. + to_chat(src, "You begin to fly upwards...") + destination.audible_message("You hear the flapping of wings.") + H.audible_message("[H] begins to flap \his wings, preparing to move upwards!") + if(do_after(H, fly_time) && H.flying) + to_chat(src, "You fly upwards.") + else + to_chat(src, "You stopped flying upwards.") + return 0 + else + to_chat(src, "Gravity stops you from moving upward.") + return 0 //VOREStation Edit End. + else to_chat(src, "Gravity stops you from moving upward.") - return 0 //VOREStation Edit End. - else - to_chat(src, "Gravity stops you from moving upward.") - return 0 + return 0 for(var/atom/A in destination) if(!A.CanPass(src, start, 1.5, 0)) @@ -224,22 +234,22 @@ if(isliving(src)) var/mob/living/L = src //VOREStation Edit Start. Flight on mobs. if(L.flying) //Some other checks are done in the wings_toggle proc - if(L.nutrition > 2) - L.adjust_nutrition(-2) //You use up 2 nutrition per TILE and tick of flying above open spaces. If people wanna flap their wings in the hallways, shouldn't penalize them for it. + if(L.nutrition > 0.5) + L.adjust_nutrition(-0.5) //You use up -0.5 nutrition per TILE and tick of flying above open spaces. If people wanna flap their wings in the hallways, shouldn't penalize them for it. if(L.incapacitated(INCAPACITATION_ALL)) L.stop_flying() //Just here to see if the person is KO'd, stunned, etc. If so, it'll move onto can_fall. else if (L.nutrition > 1000) //Eat too much while flying? Get fat and fall. to_chat(L, "You're too heavy! Your wings give out and you plummit to the ground!") L.stop_flying() //womp womp. - else if(L.nutrition < 300 && L.nutrition > 289) //290 would be risky, as metabolism could mess it up. Let's do 289. + else if(L.nutrition < 300 && L.nutrition > 299.4) //290 would be risky, as metabolism could mess it up. Let's do 289. to_chat(L, "You are starting to get fatigued... You probably have a good minute left in the air, if that. Even less if you continue to fly around! You should get to the ground soon!") //Ticks are, on average, 3 seconds. So this would most likely be 90 seconds, but lets just say 60. - L.adjust_nutrition(-10) + L.adjust_nutrition(-0.5) return - else if(L.nutrition < 100 && L.nutrition > 89) + else if(L.nutrition < 100 && L.nutrition > 99.4) to_chat(L, "You're seriously fatigued! You need to get to the ground immediately and eat before you fall!") return - else if(L.nutrition < 2) //Should have listened to the warnings! + else if(L.nutrition < 10) //Should have listened to the warnings! to_chat(L, "You lack the strength to keep yourself up in the air...") L.stop_flying() else diff --git a/code/modules/multiz/structures.dm b/code/modules/multiz/structures.dm index 0708426511..bf7f3c0865 100644 --- a/code/modules/multiz/structures.dm +++ b/code/modules/multiz/structures.dm @@ -52,16 +52,7 @@ to_chat(M, "You fail to reach \the [src].") return - var/direction = target_ladder == target_up ? "up" : "down" - - M.visible_message("\The [M] begins climbing [direction] \the [src]!", - "You begin climbing [direction] \the [src]!", - "You hear the grunting and clanging of a metal ladder being used.") - - target_ladder.audible_message("You hear something coming [direction] \the [src]") - - if(do_after(M, climb_time, src)) - climbLadder(M, target_ladder) + climbLadder(M, target_ladder) /obj/structure/ladder/attack_ghost(var/mob/M) var/target_ladder = getTargetLadder(M) @@ -105,13 +96,21 @@ /mob/observer/ghost/may_climb_ladders(var/ladder) return TRUE -/obj/structure/ladder/proc/climbLadder(var/mob/M, var/target_ladder) - var/turf/T = get_turf(target_ladder) - for(var/atom/A in T) - if(!A.CanPass(M, M.loc, 1.5, 0)) - to_chat(M, "\The [A] is blocking \the [src].") - return FALSE - return M.forceMove(T) //VOREStation Edit - Fixes adminspawned ladders +/obj/structure/ladder/proc/climbLadder(var/mob/M, var/obj/target_ladder) + var/direction = (target_ladder == target_up ? "up" : "down") + M.visible_message("\The [M] begins climbing [direction] \the [src]!", + "You begin climbing [direction] \the [src]!", + "You hear the grunting and clanging of a metal ladder being used.") + + target_ladder.audible_message("You hear something coming [direction] \the [src]") + + if(do_after(M, climb_time, src)) + var/turf/T = get_turf(target_ladder) + for(var/atom/A in T) + if(!A.CanPass(M, M.loc, 1.5, 0)) + to_chat(M, "\The [A] is blocking \the [src].") + return FALSE + return M.forceMove(T) //VOREStation Edit - Fixes adminspawned ladders /obj/structure/ladder/CanPass(obj/mover, turf/source, height, airflow) return airflow || !density diff --git a/code/modules/multiz/zshadow.dm b/code/modules/multiz/zshadow.dm index 49953e07a2..b3e37c6b76 100644 --- a/code/modules/multiz/zshadow.dm +++ b/code/modules/multiz/zshadow.dm @@ -114,10 +114,10 @@ shadow.set_dir(new_dir) // Transfer messages about what we are doing to upstairs -/mob/visible_message(var/message, var/self_message, var/blind_message) +/mob/visible_message(var/message, var/self_message, var/blind_message, var/list/exclude_mobs = null) . = ..() if(shadow) - shadow.visible_message(message, self_message, blind_message) + shadow.visible_message(message, self_message, blind_message, exclude_mobs) /mob/zshadow/set_typing_indicator(var/state) if(!typing_indicator) diff --git a/code/modules/nano/modules/law_manager.dm b/code/modules/nano/modules/law_manager.dm deleted file mode 100644 index 3016a00fad..0000000000 --- a/code/modules/nano/modules/law_manager.dm +++ /dev/null @@ -1,225 +0,0 @@ -/datum/nano_module/law_manager - name = "Law manager" - var/ion_law = "IonLaw" - var/zeroth_law = "ZerothLaw" - var/inherent_law = "InherentLaw" - var/supplied_law = "SuppliedLaw" - var/supplied_law_position = MIN_SUPPLIED_LAW_NUMBER - - var/current_view = 0 - - var/global/list/datum/ai_laws/admin_laws - var/global/list/datum/ai_laws/player_laws - var/mob/living/silicon/owner = null - -/datum/nano_module/law_manager/New(var/mob/living/silicon/S) - ..() - owner = S - - if(!admin_laws) - admin_laws = new() - player_laws = new() - - init_subtypes(/datum/ai_laws, admin_laws) - admin_laws = dd_sortedObjectList(admin_laws) - - for(var/datum/ai_laws/laws in admin_laws) - if(laws.selectable) - player_laws += laws - -/datum/nano_module/law_manager/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["set_view"]) - current_view = text2num(href_list["set_view"]) - return 1 - - if(href_list["law_channel"]) - if(href_list["law_channel"] in owner.law_channels()) - owner.lawchannel = href_list["law_channel"] - return 1 - - if(href_list["state_law"]) - var/datum/ai_law/AL = locate(href_list["ref"]) in owner.laws.all_laws() - if(AL) - var/state_law = text2num(href_list["state_law"]) - owner.laws.set_state_law(AL, state_law) - return 1 - - if(href_list["add_zeroth_law"]) - if(zeroth_law && is_admin(usr) && !owner.laws.zeroth_law) - owner.set_zeroth_law(zeroth_law) - return 1 - - if(href_list["add_ion_law"]) - if(ion_law && is_malf(usr)) - owner.add_ion_law(ion_law) - return 1 - - if(href_list["add_inherent_law"]) - if(inherent_law && is_malf(usr)) - owner.add_inherent_law(inherent_law) - return 1 - - if(href_list["add_supplied_law"]) - if(supplied_law && supplied_law_position >= 1 && MIN_SUPPLIED_LAW_NUMBER <= MAX_SUPPLIED_LAW_NUMBER && is_malf(usr)) - owner.add_supplied_law(supplied_law_position, supplied_law) - return 1 - - if(href_list["change_zeroth_law"]) - var/new_law = sanitize(input("Enter new law Zero. Leaving the field blank will cancel the edit.", "Edit Law", zeroth_law)) - if(new_law && new_law != zeroth_law && can_still_topic()) - zeroth_law = new_law - return 1 - - if(href_list["change_ion_law"]) - var/new_law = sanitize(input("Enter new ion law. Leaving the field blank will cancel the edit.", "Edit Law", ion_law)) - if(new_law && new_law != ion_law && can_still_topic()) - ion_law = new_law - return 1 - - if(href_list["change_inherent_law"]) - var/new_law = sanitize(input("Enter new inherent law. Leaving the field blank will cancel the edit.", "Edit Law", inherent_law)) - if(new_law && new_law != inherent_law && can_still_topic()) - inherent_law = new_law - return 1 - - if(href_list["change_supplied_law"]) - var/new_law = sanitize(input("Enter new supplied law. Leaving the field blank will cancel the edit.", "Edit Law", supplied_law)) - if(new_law && new_law != supplied_law && can_still_topic()) - supplied_law = new_law - return 1 - - if(href_list["change_supplied_law_position"]) - var/new_position = input(usr, "Enter new supplied law position between 1 and [MAX_SUPPLIED_LAW_NUMBER], inclusive. Inherent laws at the same index as a supplied law will not be stated.", "Law Position", supplied_law_position) as num|null - if(isnum(new_position) && can_still_topic()) - supplied_law_position = CLAMP(new_position, 1, MAX_SUPPLIED_LAW_NUMBER) - return 1 - - if(href_list["edit_law"]) - if(is_malf(usr)) - var/datum/ai_law/AL = locate(href_list["edit_law"]) in owner.laws.all_laws() - if(AL) - var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", AL.law)) - if(new_law && new_law != AL.law && is_malf(usr) && can_still_topic()) - log_and_message_admins("has changed a law of [owner] from '[AL.law]' to '[new_law]'") - AL.law = new_law - return 1 - - if(href_list["delete_law"]) - if(is_malf(usr)) - var/datum/ai_law/AL = locate(href_list["delete_law"]) in owner.laws.all_laws() - if(AL && is_malf(usr)) - owner.delete_law(AL) - return 1 - - if(href_list["state_laws"]) - owner.statelaws(owner.laws) - return 1 - - if(href_list["state_law_set"]) - var/datum/ai_laws/ALs = locate(href_list["state_law_set"]) in (is_admin(usr) ? admin_laws : player_laws) - if(ALs) - owner.statelaws(ALs) - return 1 - - if(href_list["transfer_laws"]) - if(is_malf(usr)) - var/datum/ai_laws/ALs = locate(href_list["transfer_laws"]) in (is_admin(usr) ? admin_laws : player_laws) - if(ALs) - log_and_message_admins("has transfered the [ALs.name] laws to [owner].") - ALs.sync(owner, 0) - current_view = 0 - return 1 - - if(href_list["notify_laws"]) - to_chat(owner, "Law Notice") - owner.laws.show_laws(owner) - if(isAI(owner)) - var/mob/living/silicon/ai/AI = owner - for(var/mob/living/silicon/robot/R in AI.connected_robots) - to_chat(R, "Law Notice") - R.laws.show_laws(R) - if(usr != owner) - to_chat(usr, "Laws displayed.") - return 1 - - return 0 - -/datum/nano_module/law_manager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/data[0] - owner.lawsync() - - data["ion_law_nr"] = ionnum() - data["ion_law"] = ion_law - data["zeroth_law"] = zeroth_law - data["inherent_law"] = inherent_law - data["supplied_law"] = supplied_law - data["supplied_law_position"] = supplied_law_position - - package_laws(data, "zeroth_laws", list(owner.laws.zeroth_law)) - package_laws(data, "ion_laws", owner.laws.ion_laws) - package_laws(data, "inherent_laws", owner.laws.inherent_laws) - package_laws(data, "supplied_laws", owner.laws.supplied_laws) - - data["isAI"] = isAI(owner) - data["isMalf"] = is_malf(user) - data["isSlaved"] = owner.is_slaved() - data["isAdmin"] = is_admin(user) - data["view"] = current_view - - var/channels[0] - for (var/ch_name in owner.law_channels()) - channels[++channels.len] = list("channel" = ch_name) - data["channel"] = owner.lawchannel - data["channels"] = channels - data["law_sets"] = package_multiple_laws(data["isAdmin"] ? admin_laws : player_laws) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "law_manager.tmpl", sanitize("[src] - [owner]"), 800, is_malf(user) ? 600 : 400, state = state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/datum/nano_module/law_manager/proc/package_laws(var/list/data, var/field, var/list/datum/ai_law/laws) - var/packaged_laws[0] - for(var/datum/ai_law/AL in laws) - packaged_laws[++packaged_laws.len] = list("law" = AL.law, "index" = AL.get_index(), "state" = owner.laws.get_state_law(AL), "ref" = "\ref[AL]") - data[field] = packaged_laws - data["has_[field]"] = packaged_laws.len - -/datum/nano_module/law_manager/proc/package_multiple_laws(var/list/datum/ai_laws/laws) - var/law_sets[0] - for(var/datum/ai_laws/ALs in laws) - var/packaged_laws[0] - package_laws(packaged_laws, "zeroth_laws", list(ALs.zeroth_law, ALs.zeroth_law_borg)) - package_laws(packaged_laws, "ion_laws", ALs.ion_laws) - package_laws(packaged_laws, "inherent_laws", ALs.inherent_laws) - package_laws(packaged_laws, "supplied_laws", ALs.supplied_laws) - law_sets[++law_sets.len] = list("name" = ALs.name, "header" = ALs.law_header, "ref" = "\ref[ALs]","laws" = packaged_laws) - - return law_sets - -/datum/nano_module/law_manager/proc/is_malf(var/mob/user) - return (is_admin(user) && !owner.is_slaved()) || is_special_role(user) - -/datum/nano_module/law_manager/proc/is_special_role(var/mob/user) - if(user.mind.special_role) - return TRUE - else - return FALSE - -/mob/living/silicon/proc/is_slaved() - return 0 - -/mob/living/silicon/robot/is_slaved() - return lawupdate && connected_ai ? sanitize(connected_ai.name) : null - -/datum/nano_module/law_manager/proc/sync_laws(var/mob/living/silicon/ai/AI) - if(!AI) - return - for(var/mob/living/silicon/robot/R in AI.connected_robots) - R.sync() - log_and_message_admins("has syncronized [AI]'s laws with its borgs.") diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index ddb546ff88..2d3f68a40c 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -5,6 +5,7 @@ var/list/organ_cache = list() icon = 'icons/obj/surgery.dmi' germ_level = 0 drop_sound = 'sound/items/drop/flesh.ogg' + pickup_sound = 'sound/items/pickup/flesh.ogg' // Strings. var/organ_tag = "organ" // Unique identifier. diff --git a/code/modules/organs/subtypes/diona.dm b/code/modules/organs/subtypes/diona.dm index 7d43baf757..3e8f6eadd5 100644 --- a/code/modules/organs/subtypes/diona.dm +++ b/code/modules/organs/subtypes/diona.dm @@ -3,7 +3,7 @@ return 0 //This is a terrible hack and I should be ashamed. - var/datum/seed/diona = plant_controller.seeds["diona"] + var/datum/seed/diona = SSplants.seeds["diona"] if(!diona) return 0 diff --git a/code/modules/overmap/ships/computers/sensors.dm b/code/modules/overmap/ships/computers/sensors.dm index 61f8297633..bec21e16a3 100644 --- a/code/modules/overmap/ships/computers/sensors.dm +++ b/code/modules/overmap/ships/computers/sensors.dm @@ -93,6 +93,7 @@ var/obj/effect/overmap/O = locate(params["scan"]) if(istype(O) && !QDELETED(O) && (O in view(7,linked))) new/obj/item/weapon/paper/(get_turf(src), O.get_scan_data(usr), "paper (Sensor Scan - [O])") + playsound(src, "sound/machines/printer.ogg", 30, 1) . = TRUE if(sensors) diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 1959dd6466..ccae4ef701 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -156,7 +156,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins return 0 //You can't send faxes to "Unknown" flick("faxreceive", src) - playsound(src, "sound/effects/printer.ogg", 50, 1) + playsound(src, "sound/machines/printer.ogg", 50, 1) // give the sprite some time to flick @@ -219,7 +219,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins for(var/client/C in GLOB.admins) if(check_rights((R_ADMIN|R_MOD|R_EVENT),0,C)) to_chat(C,msg) - C << 'sound/effects/printer.ogg' + C << 'sound/machines/printer.ogg' // VoreStation Edit Start var/faxid = export_fax(sent) diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 8ea288a856..4b36c81ceb 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -6,6 +6,7 @@ w_class = ITEMSIZE_SMALL pressure_resistance = 2 drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' /obj/item/weapon/folder/blue desc = "A blue folder." @@ -24,7 +25,7 @@ icon_state = "folder_white" /obj/item/weapon/folder/blue_captain - desc = "A blue folder with Colony Director markings." + desc = "A blue folder with Site Manager markings." icon_state = "folder_captain" /obj/item/weapon/folder/blue_hop diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index ce7fcac302..4d3b2d27c5 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -20,6 +20,7 @@ body_parts_covered = HEAD attack_verb = list("bapped") drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' var/info //What's actually written on the paper. var/info_links //A different version of the paper which includes html links at fields and EOF @@ -34,7 +35,7 @@ var/spam_flag = 0 var/age = 0 var/last_modified_ckey - + var/was_maploaded = FALSE // This tracks if the paper was created on mapload. var/const/deffont = "Verdana" @@ -106,7 +107,7 @@ /obj/item/weapon/paper/Initialize(mapload) . = ..() - + if(mapload) // Jank, but we do this to prevent maploaded papers from somehow stacking across rounds if re-added to the board by a player. was_maploaded = TRUE @@ -648,7 +649,7 @@ /obj/item/weapon/paper/courtroom name = "A Crash Course in Legal SOP on SS13" - info = "Roles:
\nThe Detective is basically the investigator and prosecutor.
\nThe Staff Assistant can perform these functions with written authority from the Detective.
\nThe Colony Director/HoP/Warden is ct as the judicial authority.
\nThe Security Officers are responsible for executing warrants, security during trial, and prisoner transport.
\n
\nInvestigative Phase:
\nAfter the crime has been committed the Detective's job is to gather evidence and try to ascertain not only who did it but what happened. He must take special care to catalogue everything and don't leave anything out. Write out all the evidence on paper. Make sure you take an appropriate number of fingerprints. IF he must ask someone questions he has permission to confront them. If the person refuses he can ask a judicial authority to write a subpoena for questioning. If again he fails to respond then that person is to be jailed as insubordinate and obstructing justice. Said person will be released after he cooperates.
\n
\nONCE the FT has a clear idea as to who the criminal is he is to write an arrest warrant on the piece of paper. IT MUST LIST THE CHARGES. The FT is to then go to the judicial authority and explain a small version of his case. If the case is moderately acceptable the authority should sign it. Security must then execute said warrant.
\n
\nPre-Pre-Trial Phase:
\nNow a legal representative must be presented to the defendant if said defendant requests one. That person and the defendant are then to be given time to meet (in the jail IS ACCEPTABLE). The defendant and his lawyer are then to be given a copy of all the evidence that will be presented at trial (rewriting it all on paper is fine). THIS IS CALLED THE DISCOVERY PACK. With a few exceptions, THIS IS THE ONLY EVIDENCE BOTH SIDES MAY USE AT TRIAL. IF the prosecution will be seeking the death penalty it MUST be stated at this time. ALSO if the defense will be seeking not guilty by mental defect it must state this at this time to allow ample time for examination.
\nNow at this time each side is to compile a list of witnesses. By default, the defendant is on both lists regardless of anything else. Also the defense and prosecution can compile more evidence beforehand BUT in order for it to be used the evidence MUST also be given to the other side.\nThe defense has time to compile motions against some evidence here.
\nPossible Motions:
\n1. Invalidate Evidence- Something with the evidence is wrong and the evidence is to be thrown out. This includes irrelevance or corrupt security.
\n2. Free Movement- Basically the defendant is to be kept uncuffed before and during the trial.
\n3. Subpoena Witness- If the defense presents god reasons for needing a witness but said person fails to cooperate then a subpoena is issued.
\n4. Drop the Charges- Not enough evidence is there for a trial so the charges are to be dropped. The FT CAN RETRY but the judicial authority must carefully reexamine the new evidence.
\n5. Declare Incompetent- Basically the defendant is insane. Once this is granted a medical official is to examine the patient. If he is indeed insane he is to be placed under care of the medical staff until he is deemed competent to stand trial.
\n
\nALL SIDES MOVE TO A COURTROOM
\nPre-Trial Hearings:
\nA judicial authority and the 2 sides are to meet in the trial room. NO ONE ELSE BESIDES A SECURITY DETAIL IS TO BE PRESENT. The defense submits a plea. If the plea is guilty then proceed directly to sentencing phase. Now the sides each present their motions to the judicial authority. He rules on them. Each side can debate each motion. Then the judicial authority gets a list of crew members. He first gets a chance to look at them all and pick out acceptable and available jurors. Those jurors are then called over. Each side can ask a few questions and dismiss jurors they find too biased. HOWEVER before dismissal the judicial authority MUST agree to the reasoning.
\n
\nThe Trial:
\nThe trial has three phases.
\n1. Opening Arguments- Each side can give a short speech. They may not present ANY evidence.
\n2. Witness Calling/Evidence Presentation- The prosecution goes first and is able to call the witnesses on his approved list in any order. He can recall them if necessary. During the questioning the lawyer may use the evidence in the questions to help prove a point. After every witness the other side has a chance to cross-examine. After both sides are done questioning a witness the prosecution can present another or recall one (even the EXACT same one again!). After prosecution is done the defense can call witnesses. After the initial cases are presented both sides are free to call witnesses on either list.
\nFINALLY once both sides are done calling witnesses we move onto the next phase.
\n3. Closing Arguments- Same as opening.
\nThe jury then deliberates IN PRIVATE. THEY MUST ALL AGREE on a verdict. REMEMBER: They mix between some charges being guilty and others not guilty (IE if you supposedly killed someone with a gun and you unfortunately picked up a gun without authorization then you CAN be found not guilty of murder BUT guilty of possession of illegal weaponry.). Once they have agreed they present their verdict. If unable to reach a verdict and feel they will never they call a deadlocked jury and we restart at Pre-Trial phase with an entirely new set of jurors.
\n
\nSentencing Phase:
\nIf the death penalty was sought (you MUST have gone through a trial for death penalty) then skip to the second part.
\nI. Each side can present more evidence/witnesses in any order. There is NO ban on emotional aspects or anything. The prosecution is to submit a suggested penalty. After all the sides are done then the judicial authority is to give a sentence.
\nII. The jury stays and does the same thing as I. Their sole job is to determine if the death penalty is applicable. If NOT then the judge selects a sentence.
\n
\nTADA you're done. Security then executes the sentence and adds the applicable convictions to the person's record.
\n" + info = "Roles:
\nThe Detective is basically the investigator and prosecutor.
\nThe Staff Assistant can perform these functions with written authority from the Detective.
\nThe Site Manager/HoP/Warden is ct as the judicial authority.
\nThe Security Officers are responsible for executing warrants, security during trial, and prisoner transport.
\n
\nInvestigative Phase:
\nAfter the crime has been committed the Detective's job is to gather evidence and try to ascertain not only who did it but what happened. He must take special care to catalogue everything and don't leave anything out. Write out all the evidence on paper. Make sure you take an appropriate number of fingerprints. IF he must ask someone questions he has permission to confront them. If the person refuses he can ask a judicial authority to write a subpoena for questioning. If again he fails to respond then that person is to be jailed as insubordinate and obstructing justice. Said person will be released after he cooperates.
\n
\nONCE the FT has a clear idea as to who the criminal is he is to write an arrest warrant on the piece of paper. IT MUST LIST THE CHARGES. The FT is to then go to the judicial authority and explain a small version of his case. If the case is moderately acceptable the authority should sign it. Security must then execute said warrant.
\n
\nPre-Pre-Trial Phase:
\nNow a legal representative must be presented to the defendant if said defendant requests one. That person and the defendant are then to be given time to meet (in the jail IS ACCEPTABLE). The defendant and his lawyer are then to be given a copy of all the evidence that will be presented at trial (rewriting it all on paper is fine). THIS IS CALLED THE DISCOVERY PACK. With a few exceptions, THIS IS THE ONLY EVIDENCE BOTH SIDES MAY USE AT TRIAL. IF the prosecution will be seeking the death penalty it MUST be stated at this time. ALSO if the defense will be seeking not guilty by mental defect it must state this at this time to allow ample time for examination.
\nNow at this time each side is to compile a list of witnesses. By default, the defendant is on both lists regardless of anything else. Also the defense and prosecution can compile more evidence beforehand BUT in order for it to be used the evidence MUST also be given to the other side.\nThe defense has time to compile motions against some evidence here.
\nPossible Motions:
\n1. Invalidate Evidence- Something with the evidence is wrong and the evidence is to be thrown out. This includes irrelevance or corrupt security.
\n2. Free Movement- Basically the defendant is to be kept uncuffed before and during the trial.
\n3. Subpoena Witness- If the defense presents god reasons for needing a witness but said person fails to cooperate then a subpoena is issued.
\n4. Drop the Charges- Not enough evidence is there for a trial so the charges are to be dropped. The FT CAN RETRY but the judicial authority must carefully reexamine the new evidence.
\n5. Declare Incompetent- Basically the defendant is insane. Once this is granted a medical official is to examine the patient. If he is indeed insane he is to be placed under care of the medical staff until he is deemed competent to stand trial.
\n
\nALL SIDES MOVE TO A COURTROOM
\nPre-Trial Hearings:
\nA judicial authority and the 2 sides are to meet in the trial room. NO ONE ELSE BESIDES A SECURITY DETAIL IS TO BE PRESENT. The defense submits a plea. If the plea is guilty then proceed directly to sentencing phase. Now the sides each present their motions to the judicial authority. He rules on them. Each side can debate each motion. Then the judicial authority gets a list of crew members. He first gets a chance to look at them all and pick out acceptable and available jurors. Those jurors are then called over. Each side can ask a few questions and dismiss jurors they find too biased. HOWEVER before dismissal the judicial authority MUST agree to the reasoning.
\n
\nThe Trial:
\nThe trial has three phases.
\n1. Opening Arguments- Each side can give a short speech. They may not present ANY evidence.
\n2. Witness Calling/Evidence Presentation- The prosecution goes first and is able to call the witnesses on his approved list in any order. He can recall them if necessary. During the questioning the lawyer may use the evidence in the questions to help prove a point. After every witness the other side has a chance to cross-examine. After both sides are done questioning a witness the prosecution can present another or recall one (even the EXACT same one again!). After prosecution is done the defense can call witnesses. After the initial cases are presented both sides are free to call witnesses on either list.
\nFINALLY once both sides are done calling witnesses we move onto the next phase.
\n3. Closing Arguments- Same as opening.
\nThe jury then deliberates IN PRIVATE. THEY MUST ALL AGREE on a verdict. REMEMBER: They mix between some charges being guilty and others not guilty (IE if you supposedly killed someone with a gun and you unfortunately picked up a gun without authorization then you CAN be found not guilty of murder BUT guilty of possession of illegal weaponry.). Once they have agreed they present their verdict. If unable to reach a verdict and feel they will never they call a deadlocked jury and we restart at Pre-Trial phase with an entirely new set of jurors.
\n
\nSentencing Phase:
\nIf the death penalty was sought (you MUST have gone through a trial for death penalty) then skip to the second part.
\nI. Each side can present more evidence/witnesses in any order. There is NO ban on emotional aspects or anything. The prosecution is to submit a suggested penalty. After all the sides are done then the judicial authority is to give a sentence.
\nII. The jury stays and does the same thing as I. Their sole job is to determine if the death penalty is applicable. If NOT then the judge selects a sentence.
\n
\nTADA you're done. Security then executes the sentence and adds the applicable convictions to the person's record.
\n" /obj/item/weapon/paper/hydroponics name = "Greetings from Billy Bob" @@ -665,7 +666,7 @@ /obj/item/weapon/paper/jobs name = "Job Information" - info = "Information on all formal jobs that can be assigned on Space Station 13 can be found on this document.
\nThe data will be in the following form.
\nGenerally lower ranking positions come first in this list.
\n
\nJob Name general access>lab access-engine access-systems access (atmosphere control)
\n\tJob Description
\nJob Duties (in no particular order)
\nTips (where applicable)
\n
\nResearch Assistant 1>1-0-0
\n\tThis is probably the lowest level position. Anyone who enters the space station after the initial job\nassignment will automatically receive this position. Access with this is restricted. Head of Personnel should\nappropriate the correct level of assistance.
\n1. Assist the researchers.
\n2. Clean up the labs.
\n3. Prepare materials.
\n
\nStaff Assistant 2>0-0-0
\n\tThis position assists the security officer in his duties. The staff assisstants should primarily br\npatrolling the ship waiting until they are needed to maintain ship safety.\n(Addendum: Updated/Elevated Security Protocols admit issuing of low level weapons to security personnel)
\n1. Patrol ship/Guard key areas
\n2. Assist security officer
\n3. Perform other security duties.
\n
\nTechnical Assistant 1>0-0-1
\n\tThis is yet another low level position. The technical assistant helps the engineer and the statian\ntechnician with the upkeep and maintenance of the station. This job is very important because it usually\ngets to be a heavy workload on station technician and these helpers will alleviate that.
\n1. Assist Station technician and Engineers.
\n2. Perform general maintenance of station.
\n3. Prepare materials.
\n
\nMedical Assistant 1>1-0-0
\n\tThis is the fourth position yet it is slightly less common. This position doesn't have much power\noutside of the med bay. Consider this position like a nurse who helps to upkeep medical records and the\nmaterials (filling syringes and checking vitals)
\n1. Assist the medical personnel.
\n2. Update medical files.
\n3. Prepare materials for medical operations.
\n
\nResearch Technician 2>3-0-0
\n\tThis job is primarily a step up from research assistant. These people generally do not get their own lab\nbut are more hands on in the experimentation process. At this level they are permitted to work as consultants to\nthe others formally.
\n1. Inform superiors of research.
\n2. Perform research alongside of official researchers.
\n
\nDetective 3>2-0-0
\n\tThis job is in most cases slightly boring at best. Their sole duty is to\nperform investigations of crine scenes and analysis of the crime scene. This\nalleviates SOME of the burden from the security officer. This person's duty\nis to draw conclusions as to what happened and testify in court. Said person\nalso should stroe the evidence ly.
\n1. Perform crime-scene investigations/draw conclusions.
\n2. Store and catalogue evidence properly.
\n3. Testify to superiors/inquieries on findings.
\n
\nStation Technician 2>0-2-3
\n\tPeople assigned to this position must work to make sure all the systems aboard Space Station 13 are operable.\nThey should primarily work in the computer lab and repairing faulty equipment. They should work with the\natmospheric technician.
\n1. Maintain SS13 systems.
\n2. Repair equipment.
\n
\nAtmospheric Technician 3>0-0-4
\n\tThese people should primarily work in the atmospheric control center and lab. They have the very important\njob of maintaining the delicate atmosphere on SS13.
\n1. Maintain atmosphere on SS13
\n2. Research atmospheres on the space station. (safely please!)
\n
\nEngineer 2>1-3-0
\n\tPeople working as this should generally have detailed knowledge as to how the propulsion systems on SS13\nwork. They are one of the few classes that have unrestricted access to the engine area.
\n1. Upkeep the engine.
\n2. Prevent fires in the engine.
\n3. Maintain a safe orbit.
\n
\nMedical Researcher 2>5-0-0
\n\tThis position may need a little clarification. Their duty is to make sure that all experiments are safe and\nto conduct experiments that may help to improve the station. They will be generally idle until a new laboratory\nis constructed.
\n1. Make sure the station is kept safe.
\n2. Research medical properties of materials studied of Space Station 13.
\n
\nScientist 2>5-0-0
\n\tThese people study the properties, particularly the toxic properties, of materials handled on SS13.\nTechnically they can also be called Phoron Technicians as phoron is the material they routinly handle.
\n1. Research phoron
\n2. Make sure all phoron is properly handled.
\n
\nMedical Doctor (Officer) 2>0-0-0
\n\tPeople working this job should primarily stay in the medical area. They should make sure everyone goes to\nthe medical bay for treatment and examination. Also they should make sure that medical supplies are kept in\norder.
\n1. Heal wounded people.
\n2. Perform examinations of all personnel.
\n3. Moniter usage of medical equipment.
\n
\nSecurity Officer 3>0-0-0
\n\tThese people should attempt to keep the peace inside the station and make sure the station is kept safe. One\nside duty is to assist in repairing the station. They also work like general maintenance personnel. They are not\ngiven a weapon and must use their own resources.
\n(Addendum: Updated/Elevated Security Protocols admit issuing of weapons to security personnel)
\n1. Maintain order.
\n2. Assist others.
\n3. Repair structural problems.
\n
\nHead of Security 4>5-2-2
\n\tPeople assigned as Head of Security should issue orders to the security staff. They should\nalso carefully moderate the usage of all security equipment. All security matters should be reported to this person.
\n1. Oversee security.
\n2. Assign patrol duties.
\n3. Protect the station and staff.
\n
\nHead of Personnel 4>4-2-2
\n\tPeople assigned as head of personnel will find themselves moderating all actions done by personnel. \nAlso they have the ability to assign jobs and access levels.
\n1. Assign duties.
\n2. Moderate personnel.
\n3. Moderate research.
\n
\nColony Director 5>5-5-5 (unrestricted station wide access)
\n\tThis is the highest position youi can aquire on Space Station 13. They are allowed anywhere inside the\nspace station and therefore should protect their ID card. They also have the ability to assign positions\nand access levels. They should not abuse their power.
\n1. Assign all positions on SS13
\n2. Inspect the station for any problems.
\n3. Perform administrative duties.
\n" + info = "Information on all formal jobs that can be assigned on Space Station 13 can be found on this document.
\nThe data will be in the following form.
\nGenerally lower ranking positions come first in this list.
\n
\nJob Name general access>lab access-engine access-systems access (atmosphere control)
\n\tJob Description
\nJob Duties (in no particular order)
\nTips (where applicable)
\n
\nResearch Assistant 1>1-0-0
\n\tThis is probably the lowest level position. Anyone who enters the space station after the initial job\nassignment will automatically receive this position. Access with this is restricted. Head of Personnel should\nappropriate the correct level of assistance.
\n1. Assist the researchers.
\n2. Clean up the labs.
\n3. Prepare materials.
\n
\nStaff Assistant 2>0-0-0
\n\tThis position assists the security officer in his duties. The staff assisstants should primarily br\npatrolling the ship waiting until they are needed to maintain ship safety.\n(Addendum: Updated/Elevated Security Protocols admit issuing of low level weapons to security personnel)
\n1. Patrol ship/Guard key areas
\n2. Assist security officer
\n3. Perform other security duties.
\n
\nTechnical Assistant 1>0-0-1
\n\tThis is yet another low level position. The technical assistant helps the engineer and the statian\ntechnician with the upkeep and maintenance of the station. This job is very important because it usually\ngets to be a heavy workload on station technician and these helpers will alleviate that.
\n1. Assist Station technician and Engineers.
\n2. Perform general maintenance of station.
\n3. Prepare materials.
\n
\nMedical Assistant 1>1-0-0
\n\tThis is the fourth position yet it is slightly less common. This position doesn't have much power\noutside of the med bay. Consider this position like a nurse who helps to upkeep medical records and the\nmaterials (filling syringes and checking vitals)
\n1. Assist the medical personnel.
\n2. Update medical files.
\n3. Prepare materials for medical operations.
\n
\nResearch Technician 2>3-0-0
\n\tThis job is primarily a step up from research assistant. These people generally do not get their own lab\nbut are more hands on in the experimentation process. At this level they are permitted to work as consultants to\nthe others formally.
\n1. Inform superiors of research.
\n2. Perform research alongside of official researchers.
\n
\nDetective 3>2-0-0
\n\tThis job is in most cases slightly boring at best. Their sole duty is to\nperform investigations of crine scenes and analysis of the crime scene. This\nalleviates SOME of the burden from the security officer. This person's duty\nis to draw conclusions as to what happened and testify in court. Said person\nalso should stroe the evidence ly.
\n1. Perform crime-scene investigations/draw conclusions.
\n2. Store and catalogue evidence properly.
\n3. Testify to superiors/inquieries on findings.
\n
\nStation Technician 2>0-2-3
\n\tPeople assigned to this position must work to make sure all the systems aboard Space Station 13 are operable.\nThey should primarily work in the computer lab and repairing faulty equipment. They should work with the\natmospheric technician.
\n1. Maintain SS13 systems.
\n2. Repair equipment.
\n
\nAtmospheric Technician 3>0-0-4
\n\tThese people should primarily work in the atmospheric control center and lab. They have the very important\njob of maintaining the delicate atmosphere on SS13.
\n1. Maintain atmosphere on SS13
\n2. Research atmospheres on the space station. (safely please!)
\n
\nEngineer 2>1-3-0
\n\tPeople working as this should generally have detailed knowledge as to how the propulsion systems on SS13\nwork. They are one of the few classes that have unrestricted access to the engine area.
\n1. Upkeep the engine.
\n2. Prevent fires in the engine.
\n3. Maintain a safe orbit.
\n
\nMedical Researcher 2>5-0-0
\n\tThis position may need a little clarification. Their duty is to make sure that all experiments are safe and\nto conduct experiments that may help to improve the station. They will be generally idle until a new laboratory\nis constructed.
\n1. Make sure the station is kept safe.
\n2. Research medical properties of materials studied of Space Station 13.
\n
\nScientist 2>5-0-0
\n\tThese people study the properties, particularly the toxic properties, of materials handled on SS13.\nTechnically they can also be called Phoron Technicians as phoron is the material they routinly handle.
\n1. Research phoron
\n2. Make sure all phoron is properly handled.
\n
\nMedical Doctor (Officer) 2>0-0-0
\n\tPeople working this job should primarily stay in the medical area. They should make sure everyone goes to\nthe medical bay for treatment and examination. Also they should make sure that medical supplies are kept in\norder.
\n1. Heal wounded people.
\n2. Perform examinations of all personnel.
\n3. Moniter usage of medical equipment.
\n
\nSecurity Officer 3>0-0-0
\n\tThese people should attempt to keep the peace inside the station and make sure the station is kept safe. One\nside duty is to assist in repairing the station. They also work like general maintenance personnel. They are not\ngiven a weapon and must use their own resources.
\n(Addendum: Updated/Elevated Security Protocols admit issuing of weapons to security personnel)
\n1. Maintain order.
\n2. Assist others.
\n3. Repair structural problems.
\n
\nHead of Security 4>5-2-2
\n\tPeople assigned as Head of Security should issue orders to the security staff. They should\nalso carefully moderate the usage of all security equipment. All security matters should be reported to this person.
\n1. Oversee security.
\n2. Assign patrol duties.
\n3. Protect the station and staff.
\n
\nHead of Personnel 4>4-2-2
\n\tPeople assigned as head of personnel will find themselves moderating all actions done by personnel. \nAlso they have the ability to assign jobs and access levels.
\n1. Assign duties.
\n2. Moderate personnel.
\n3. Moderate research.
\n
\nSite Manager 5>5-5-5 (unrestricted station wide access)
\n\tThis is the highest position youi can aquire on Space Station 13. They are allowed anywhere inside the\nspace station and therefore should protect their ID card. They also have the ability to assign positions\nand access levels. They should not abuse their power.
\n1. Assign all positions on SS13
\n2. Inspect the station for any problems.
\n3. Perform administrative duties.
\n" /obj/item/weapon/paper/photograph name = "photo" diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index bbf66d9f9a..5c5eb14a57 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -13,6 +13,7 @@ pressure_resistance = 1 attack_verb = list("bapped") drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' var/page = 1 // current page var/list/pages = list() // Ordered list of pages as they are to be displayed. Can be different order than src.contents. diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 69c14fe8b9..2a91257966 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -16,6 +16,8 @@ layer = OBJ_LAYER - 0.1 var/amount = 30 //How much paper is in the bin. var/list/papers = new/list() //List of papers put in the bin for reference. + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' /obj/item/weapon/paper_bin/MouseDrop(mob/user as mob) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index e27f8db8b0..5aa1f6901f 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -24,6 +24,7 @@ var/colour = "black" //what colour the ink is! pressure_resistance = 2 drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' /obj/item/weapon/pen/attack_self(var/mob/user) if(!user.checkClickCooldown()) @@ -287,6 +288,8 @@ var/uses = 30 //0 for unlimited uses var/instant = 0 var/colourName = "red" //for updateIcon purposes + drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/gloves.ogg' /obj/item/weapon/pen/crayon/suicide_act(mob/user) var/datum/gender/TU = gender_datums[user.get_visible_gender()] diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 728602dcf7..b63048fdc0 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -29,6 +29,8 @@ var/global/photo_count = 0 icon_state = "photo" item_state = "paper" w_class = ITEMSIZE_SMALL + drop_sound = 'sound/items/drop/paper.ogg' + pickup_sound = 'sound/items/pickup/paper.ogg' var/id var/icon/img //Big photo image var/scribble //Scribble on the back. diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index 9039df41ea..ea614aa11e 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -14,7 +14,7 @@ attack_verb = list("stamped") /obj/item/weapon/stamp/captain - name = "colony director's rubber stamp" + name = "site manager's rubber stamp" icon_state = "stamp-cap" /obj/item/weapon/stamp/hop diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 183956e562..77a81defaf 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -509,6 +509,7 @@ obj/structure/cable/proc/cableColor(var/colorC) attack_verb = list("whipped", "lashed", "disciplined", "flogged") stacktype = /obj/item/stack/cable_coil drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' /obj/item/stack/cable_coil/cyborg name = "cable coil synthesizer" diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index cdb809255a..3b15faca72 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -910,6 +910,8 @@ var/global/list/light_type_cache = list() var/nightshift_range = 8 var/nightshift_power = 1 var/nightshift_color = LIGHT_COLOR_NIGHTSHIFT + drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/weapon/light/tube name = "light tube" diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 4e6c5a6cb5..defbfef4da 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -43,6 +43,9 @@ #define WARNING_DELAY 20 //seconds between warnings. +// Keeps Accent sounds from layering, increase or decrease as preferred. +#define SUPERMATTER_ACCENT_SOUND_COOLDOWN 2 SECONDS + /obj/machinery/power/supermatter name = "Supermatter" desc = "A strangely translucent and iridescent crystal. You get headaches just from looking at it." @@ -98,6 +101,9 @@ var/config_hallucination_power = 0.1 var/debug = 0 + + /// Cooldown tracker for accent sounds, + var/last_accent_sound = 0 var/datum/looping_sound/supermatter/soundloop @@ -290,11 +296,29 @@ shift_light(4,initial(light_color)) if(grav_pulling) supermatter_pull(src) - + + // Vary volume by power produced. if(power) // Volume will be 1 at no power, ~12.5 at ENERGY_NITROGEN, and 20+ at ENERGY_PHORON. // Capped to 20 volume since higher volumes get annoying and it sounds worse. - soundloop.volume = min(round(power/10)+1, 20) + // Formula previously was min(round(power/10)+1, 20) + soundloop.volume = CLAMP((50 + (power / 50)), 50, 100) + + // Swap loops between calm and delamming. + if(damage >= 300) + soundloop.mid_sounds = list('sound/machines/sm/loops/delamming.ogg' = 1) + else + soundloop.mid_sounds = list('sound/machines/sm/loops/calm.ogg' = 1) + + // Play Delam/Neutral sounds at rate determined by power and damage. + if(last_accent_sound < world.time && prob(20)) + var/aggression = min(((damage / 800) * (power / 2500)), 1.0) * 100 + if(damage >= 300) + playsound(src, "smdelam", max(50, aggression), FALSE, 10) + else + playsound(src, "smcalm", max(50, aggression), FALSE, 10) + var/next_sound = round((100 - aggression) * 5) + last_accent_sound = world.time + max(SUPERMATTER_ACCENT_SOUND_COOLDOWN, next_sound) //Ok, get the air from the turf var/datum/gas_mixture/removed = null diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 8c7e9a440b..d55fe61684 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -9,6 +9,7 @@ w_class = ITEMSIZE_TINY preserve_item = 1 drop_sound = 'sound/items/drop/ring.ogg' + pickup_sound = 'sound/items/pickup/ring.ogg' var/leaves_residue = 1 var/caliber = "" //Which kind of guns it can be loaded into diff --git a/code/modules/projectiles/ammunition/rounds.dm b/code/modules/projectiles/ammunition/rounds.dm index fa6c5d21aa..02d4b4aa5e 100644 --- a/code/modules/projectiles/ammunition/rounds.dm +++ b/code/modules/projectiles/ammunition/rounds.dm @@ -369,7 +369,7 @@ name = "rocket shell" desc = "A high explosive designed to be fired from a launcher." icon_state = "rocketshell" - projectile_type = /obj/item/missile + projectile_type = /obj/item/projectile/bullet/srmrocket caliber = "rocket" matter = list(DEFAULT_WALL_MATERIAL = 10000) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 1ced4c0e59..8d336acaa1 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -50,6 +50,7 @@ attack_verb = list("struck", "hit", "bashed") zoomdevicename = "scope" drop_sound = 'sound/items/drop/gun.ogg' + pickup_sound = 'sound/items/pickup/gun.ogg' var/recoil_mode = 1 //0 = no micro recoil, 1 = regular, anything higher than 1 is a multiplier //YAWN Addition, ported from CHOMP var/automatic = 0 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 7877cac713..3b272f8d11 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -68,12 +68,12 @@ set category = "Object" set src in view(1) - var/genemask = input("Choose a gene to modify.") as null|anything in plant_controller.plant_gene_datums + var/genemask = input("Choose a gene to modify.") as null|anything in SSplants.plant_gene_datums if(!genemask) return - gene = plant_controller.plant_gene_datums[genemask] + gene = SSplants.plant_gene_datums[genemask] to_chat(usr, "You set the [src]'s targeted genetic area to [genemask].") diff --git a/code/modules/projectiles/guns/launcher/crossbow.dm b/code/modules/projectiles/guns/launcher/crossbow.dm index 3dfae2a1a4..1201e89b7b 100644 --- a/code/modules/projectiles/guns/launcher/crossbow.dm +++ b/code/modules/projectiles/guns/launcher/crossbow.dm @@ -6,6 +6,8 @@ icon = 'icons/obj/weapons.dmi' icon_state = "bolt" item_state = "bolt" + drop_sound = 'sound/items/drop/sword.ogg' + pickup_sound = 'sound/items/pickup/sword.ogg' throwforce = 8 w_class = ITEMSIZE_NORMAL sharp = 1 @@ -24,6 +26,8 @@ icon = 'icons/obj/weapons.dmi' icon_state = "metal-rod" item_state = "bolt" + drop_sound = 'sound/items/drop/sword.ogg' + pickup_sound = 'sound/items/pickup/sword.ogg' /obj/item/weapon/arrow/quill name = "alien quill" diff --git a/code/modules/projectiles/guns/launcher/rocket.dm b/code/modules/projectiles/guns/launcher/rocket.dm index 3e108b2982..4dce4ce835 100644 --- a/code/modules/projectiles/guns/launcher/rocket.dm +++ b/code/modules/projectiles/guns/launcher/rocket.dm @@ -35,10 +35,8 @@ /obj/item/weapon/gun/launcher/rocket/consume_next_projectile() if(rockets.len) var/obj/item/ammo_casing/rocket/I = rockets[1] - var/obj/item/missile/M = new (src) - M.primed = 1 rockets -= I - return M + return return null /obj/item/weapon/gun/launcher/rocket/handle_post_fire(mob/user, atom/target) diff --git a/code/modules/projectiles/guns/magnetic/gasthrower.dm b/code/modules/projectiles/guns/magnetic/gasthrower.dm index 8132644bf9..d729719c32 100644 --- a/code/modules/projectiles/guns/magnetic/gasthrower.dm +++ b/code/modules/projectiles/guns/magnetic/gasthrower.dm @@ -37,7 +37,7 @@ var/phoron_amt = Tank.air_contents.gas["phoron"] var/co2_amt = Tank.air_contents.gas["carbon_dioxide"] var/oxy_amt = Tank.air_contents.gas["oxygen"] - var/n2o_amt = Tank.air_contents.gas["sleeping_agent"] + var/n2o_amt = Tank.air_contents.gas["nitrous_oxide"] if(isnull(co2_amt)) co2_amt = 0 diff --git a/code/modules/projectiles/projectile/explosive.dm b/code/modules/projectiles/projectile/explosive.dm new file mode 100644 index 0000000000..15d538c082 --- /dev/null +++ b/code/modules/projectiles/projectile/explosive.dm @@ -0,0 +1,33 @@ + + +/obj/item/projectile/bullet/srmrocket + name ="SRM-8 Rocket" + desc = "Boom" + icon = 'icons/obj/grenade.dmi' + icon_state = "missile" + damage = 30 //Meaty whack. *Chuckles* + does_spin = 0 + +/obj/item/projectile/bullet/srmrocket/on_hit(atom/target, blocked=0) + ..() + if(!isliving(target)) //if the target isn't alive, so is a wall or something + explosion(target, 0, 1, 2, 4) + else + explosion(target, 0, 0, 2, 4) + return 1 + + +/obj/item/projectile/bullet/srmrocket/weak //Used in the jury rigged one. + damage = 10 + +/obj/item/projectile/bullet/srmrocket/weak/on_hit(atom/target, blocked=0) + ..() + explosion(target, 0, 0, 2, 4)//No need to have a question. + return 1 + +/*Old vars here for reference. + var/devastation = 0 + var/heavy_blast = 1 + var/light_blast = 2 + var/flash_blast = 4 +*/ diff --git a/code/modules/reagents/Chemistry-Reagents_vr.dm b/code/modules/reagents/Chemistry-Reagents_vr.dm index ab76750d8c..f6cd245dee 100644 --- a/code/modules/reagents/Chemistry-Reagents_vr.dm +++ b/code/modules/reagents/Chemistry-Reagents_vr.dm @@ -44,6 +44,7 @@ reagent_state = LIQUID color = "#333333" scannable = 1 + affects_robots = TRUE /datum/reagent/nif_repair_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(ishuman(M)) @@ -108,6 +109,7 @@ color = "#1d1d1d" scannable = 0 metabolism = REM * 0.5 + affects_robots = TRUE /datum/reagent/liquid_protean/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien != IS_DIONA) diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index 9611460f21..223583f7dc 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -22,6 +22,7 @@ icon_state = "empty" item_state = "bloodpack_empty" drop_sound = 'sound/items/drop/food.ogg' + pickup_sound = 'sound/items/pickup/food.ogg' volume = 200 var/label_text = "" diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 7ffcf28881..459d481cba 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -12,6 +12,7 @@ slot_flags = SLOT_EARS volume = 5 drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/weapon/reagent_containers/dropper/examine(var/mob/user) . = ..() diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 6d4ab24605..6b567f47f0 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -16,6 +16,8 @@ w_class = ITEMSIZE_SMALL flags = OPENCONTAINER | NOCONDUCT unacidable = 1 //glass doesn't dissolve in acid + drop_sound = 'sound/items/drop/bottle.ogg' + pickup_sound = 'sound/items/pickup/bottle.ogg' var/label_text = "" @@ -155,6 +157,8 @@ item_state = "beaker" center_of_mass = list("x" = 15,"y" = 11) matter = list("glass" = 500) + drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/weapon/reagent_containers/glass/beaker/Initialize() . = ..() @@ -263,6 +267,8 @@ volume = 120 flags = OPENCONTAINER unacidable = 0 + drop_sound = 'sound/items/drop/helm.ogg' + pickup_sound = 'sound/items/pickup/helm.ogg' /obj/item/weapon/reagent_containers/glass/bucket/attackby(var/obj/item/D, mob/user as mob) if(isprox(D)) @@ -320,6 +326,8 @@ obj/item/weapon/reagent_containers/glass/bucket/wood volume = 120 flags = OPENCONTAINER unacidable = 0 + drop_sound = 'sound/items/drop/wooden.ogg' + pickup_sound = 'sound/items/pickup/wooden.ogg' /obj/item/weapon/reagent_containers/glass/bucket/wood/attackby(var/obj/D, mob/user as mob) if(isprox(D)) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index bb70781c7e..9a1882e47b 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -14,6 +14,8 @@ possible_transfer_amounts = null flags = OPENCONTAINER slot_flags = SLOT_BELT + drop_sound = 'sound/items/drop/gun.ogg' + pickup_sound = 'sound/items/pickup/gun.ogg' preserve_item = 1 var/filled = 0 var/list/filled_reagents = list() diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index c30ffd09f7..de4871c6c1 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -8,6 +8,7 @@ icon_state = null item_state = "pill" drop_sound = 'sound/items/drop/food.ogg' + pickup_sound = 'sound/items/pickup/food.ogg' var/base_state = "pill" diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index a83c961546..eb4bba2387 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -156,6 +156,8 @@ amount_per_transfer_from_this = 1 possible_transfer_amounts = null volume = 10 + drop_sound = 'sound/items/drop/herb.ogg' + pickup_sound = 'sound/items/pickup/herb.ogg' /obj/item/weapon/reagent_containers/spray/waterflower/Initialize() . = ..() diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 6d9becfbc6..4bdf471989 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -26,6 +26,7 @@ var/time = 30 var/drawing = 0 drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' /obj/item/weapon/reagent_containers/syringe/on_reagent_change() update_icon() @@ -298,7 +299,8 @@ var/trans = reagents.trans_to_mob(target, syringestab_amount_transferred, CHEM_BLOOD) if(isnull(trans)) trans = 0 add_attack_logs(user,target,"Stabbed with [src.name] containing [contained], trasferred [trans] units") - break_syringe(target, user) + if(!issilicon(user)) + break_syringe(target, user) /obj/item/weapon/reagent_containers/syringe/proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user) desc += " It is broken." diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index a97c2894c2..08d68d8956 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -114,7 +114,8 @@ name = "small parcel" icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit icon_state = "deliverycrate3" - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' var/obj/item/wrapped = null var/sortTag = null var/examtext = null @@ -338,6 +339,9 @@ item_state = "electronic" slot_flags = SLOT_BELT +/obj/item/device/destTagger/tgui_state(mob/user) + return GLOB.tgui_inventory_state + /obj/item/device/destTagger/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 24ec0da166..708def291d 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -29,14 +29,18 @@ other types of metals and chemistry for reagents). var/list/chemicals = list() //List of chemicals. var/build_path = null //The path of the object that gets created. var/time = 10 //How many ticks it requires to build - var/category = null //Primarily used for Mech Fabricators, but can be used for anything. + var/list/category = list() //Primarily used for Mech Fabricators, but can be used for anything. var/sort_string = "ZZZZZ" //Sorting order + var/search_metadata // Optional string that interfaces can use as part of search filters. See- item/borg/upgrade/ai and the Exosuit Fabs. var/maxstack = 1 //YW Edit, used by autolathe, says how many stacks a item can have or the limit of how many you can spawn at once var/autolathe_build = 0 //YW Edit, makes other designs able to be built or added in autolathe, be via design disk or something else(added due to can't have two designs with same build_path without unit test getting angry) var/hidden = 0 //YW Edit, Used by autolathe, says if an item needs the autolathe to be hacked in order to appear /datum/design/New() ..() + if(!islist(category)) + log_runtime(EXCEPTION("Warning: Design [type] defined a non-list category. Please fix this.")) + category = list(category) item_name = name AssembleDesignInfo() diff --git a/code/modules/research/designs/ai_holders.dm b/code/modules/research/designs/ai_holders.dm index 8cdcafbd6c..7cf36c5bb6 100644 --- a/code/modules/research/designs/ai_holders.dm +++ b/code/modules/research/designs/ai_holders.dm @@ -10,7 +10,7 @@ build_type = PROTOLATHE | PROSFAB materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500) build_path = /obj/item/device/mmi - category = "Misc" + category = list("Misc") sort_string = "SAAAA" /datum/design/item/ai_holder/posibrain @@ -20,7 +20,7 @@ build_type = PROTOLATHE | PROSFAB materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500, "phoron" = 500, "diamond" = 100) build_path = /obj/item/device/mmi/digital/posibrain - category = "Misc" + category = list("Misc") sort_string = "SAAAB" /datum/design/item/ai_holder/dronebrain @@ -30,7 +30,7 @@ build_type = PROTOLATHE | PROSFAB materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500) build_path = /obj/item/device/mmi/digital/robot - category = "Misc" + category = list("Misc") sort_string = "SAAAC" /datum/design/item/ai_holder/paicard diff --git a/code/modules/research/designs/power_cells.dm b/code/modules/research/designs/power_cells.dm index e65ab6f3a6..748541d520 100644 --- a/code/modules/research/designs/power_cells.dm +++ b/code/modules/research/designs/power_cells.dm @@ -22,7 +22,7 @@ req_tech = list(TECH_POWER = 1) materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 50) build_path = /obj/item/weapon/cell - category = "Misc" + category = list("Misc") sort_string = "BAAAA" /datum/design/item/powercell/high @@ -32,7 +32,7 @@ req_tech = list(TECH_POWER = 2) materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 60) build_path = /obj/item/weapon/cell/high - category = "Misc" + category = list("Misc") sort_string = "BAAAB" /datum/design/item/powercell/super @@ -41,7 +41,7 @@ req_tech = list(TECH_POWER = 3, TECH_MATERIAL = 2) materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 70) build_path = /obj/item/weapon/cell/super - category = "Misc" + category = list("Misc") sort_string = "BAAAC" /datum/design/item/powercell/hyper @@ -50,7 +50,7 @@ req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) materials = list(DEFAULT_WALL_MATERIAL = 400, "gold" = 150, "silver" = 150, "glass" = 70) build_path = /obj/item/weapon/cell/hyper - category = "Misc" + category = list("Misc") sort_string = "BAAAD" /datum/design/item/powercell/device @@ -59,7 +59,7 @@ id = "device" materials = list(DEFAULT_WALL_MATERIAL = 350, "glass" = 25) build_path = /obj/item/weapon/cell/device - category = "Misc" + category = list("Misc") sort_string = "BAABA" //Yawn changes @@ -69,7 +69,7 @@ id = "advance_device" materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 50) build_path = /obj/item/weapon/cell/device/weapon - category = "Misc" + category = list("Misc") sort_string = "BAABB" /datum/design/item/powercell/super_device @@ -78,7 +78,7 @@ req_tech = list(TECH_POWER = 3, TECH_MATERIAL = 2) materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 70, "gold" = 50, "silver" = 20,) build_path = /obj/item/weapon/cell/device/super - category = "Misc" + category = list("Misc") sort_string = "BAABC" /datum/design/item/powercell/hype_device @@ -87,7 +87,7 @@ req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) materials = list(DEFAULT_WALL_MATERIAL = 1400, "glass" = 1400, "gold" = 150, "silver" = 150) build_path = /obj/item/weapon/cell/device/hyper - category = "Misc" + category = list("Misc") sort_string = "BAABD" /datum/design/item/powercell/omni_device @@ -97,6 +97,6 @@ id = "omni-device" materials = list(DEFAULT_WALL_MATERIAL = 1700, "glass" = 550, MAT_DURASTEEL = 230, MAT_MORPHIUM = 320, MAT_METALHYDROGEN = 600, MAT_URANIUM = 60, MAT_VERDANTIUM = 150, MAT_PHORON = 900) build_path = /obj/item/weapon/cell/device/weapon/recharge/alien/omni - category = "Misc" + category = list("Misc") sort_string = "BAABE" //End of Yawn add diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index 8e7f31b731..52b976e187 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -1,10 +1,10 @@ /datum/design/item/mechfab build_type = MECHFAB - category = "Other" + category = list("Other") req_tech = list(TECH_MATERIAL = 1) /datum/design/item/mechfab/ripley - category = "Ripley" + category = list("Ripley") /datum/design/item/mechfab/ripley/chassis name = "Ripley Chassis" @@ -54,7 +54,7 @@ materials = list(DEFAULT_WALL_MATERIAL = 22500) /datum/design/item/mechfab/odysseus - category = "Odysseus" + category = list("Odysseus") /datum/design/item/mechfab/odysseus/chassis name = "Odysseus Chassis" @@ -106,7 +106,7 @@ materials = list(DEFAULT_WALL_MATERIAL = 11250) /datum/design/item/mechfab/gygax - category = "Gygax" + category = list("Gygax") /datum/design/item/mechfab/gygax/chassis/serenity name = "Serenity Chassis" @@ -171,7 +171,7 @@ materials = list(DEFAULT_WALL_MATERIAL = 37500, "diamond" = 7500) /datum/design/item/mechfab/durand - category = "Durand" + category = list("Durand") /datum/design/item/mechfab/durand/chassis name = "Durand Chassis" @@ -230,7 +230,7 @@ materials = list(DEFAULT_WALL_MATERIAL = 27500, MAT_PLASTEEL = 10000, "uranium" = 7500) /datum/design/item/mechfab/janus - category = "Janus" + category = list("Janus") req_tech = list(TECH_MATERIAL = 7, TECH_BLUESPACE = 5, TECH_MAGNET = 6, TECH_PHORON = 3, TECH_ARCANE = 1, TECH_PRECURSOR = 2) /datum/design/item/mechfab/janus/chassis @@ -292,7 +292,7 @@ /datum/design/item/mecha build_type = MECHFAB - category = "Exosuit Equipment" + category = list("Exosuit Equipment") time = 10 materials = list(DEFAULT_WALL_MATERIAL = 7500) @@ -758,7 +758,7 @@ build_type = MECHFAB materials = list(DEFAULT_WALL_MATERIAL = 562, "glass" = 562) build_path = /obj/item/device/flash/synthetic - category = "Misc" + category = list("Misc") /* * Non-Mech Vehicles @@ -766,7 +766,7 @@ /datum/design/item/mechfab/vehicle build_type = MECHFAB - category = "Vehicle" + category = list("Vehicle") req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 6) /datum/design/item/mechfab/vehicle/spacebike_chassis @@ -790,7 +790,7 @@ */ /datum/design/item/mechfab/rigsuit - category = "Rigsuit" + category = list("Rigsuit") req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 5, TECH_PHORON = 3, TECH_MAGNET = 4, TECH_POWER = 6) /datum/design/item/mechfab/rigsuit/basic_belt @@ -1042,13 +1042,13 @@ // Exosuit Internals /datum/design/item/mechfab/exointernal - category = "Exosuit Internals" + category = list("Exosuit Internals") time = 30 req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3) /datum/design/item/mechfab/exointernal/stan_armor name = "Armor Plate (Standard)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_armor_standard" req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) materials = list(DEFAULT_WALL_MATERIAL = 10000) @@ -1056,7 +1056,7 @@ /datum/design/item/mechfab/exointernal/light_armor name = "Armor Plate (Lightweight)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_armor_lightweight" req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 3) materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000) @@ -1064,7 +1064,7 @@ /datum/design/item/mechfab/exointernal/reinf_armor name = "Armor Plate (Reinforced)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_armor_reinforced" req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) materials = list(DEFAULT_WALL_MATERIAL = 20000, MAT_PLASTEEL = 10000) @@ -1072,7 +1072,7 @@ /datum/design/item/mechfab/exointernal/mining_armor name = "Armor Plate (Blast)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_armor_blast" req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) materials = list(DEFAULT_WALL_MATERIAL = 20000, MAT_PLASTEEL = 10000) @@ -1080,7 +1080,7 @@ /datum/design/item/mechfab/exointernal/gygax_armor name = "Armor Plate (Marshal)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_armor_gygax" req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_COMBAT = 2) materials = list(DEFAULT_WALL_MATERIAL = 40000, MAT_DIAMOND = 8000) @@ -1088,7 +1088,7 @@ /datum/design/item/mechfab/exointernal/darkgygax_armor name = "Armor Plate (Blackops)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_armor_dgygax" req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_COMBAT = 4, TECH_ILLEGAL = 2) materials = list(MAT_PLASTEEL = 20000, MAT_DIAMOND = 10000, MAT_GRAPHITE = 20000) @@ -1117,7 +1117,7 @@ /datum/design/item/mechfab/exointernal/stan_hull name = "Hull (Standard)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_hull_standard" req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) materials = list(DEFAULT_WALL_MATERIAL = 10000) @@ -1125,7 +1125,7 @@ /datum/design/item/mechfab/exointernal/durable_hull name = "Hull (Durable)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_hull_durable" req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_PLASTEEL = 5000) @@ -1133,7 +1133,7 @@ /datum/design/item/mechfab/exointernal/light_hull name = "Hull (Lightweight)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_hull_light" req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 4) materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000) @@ -1141,7 +1141,7 @@ /datum/design/item/mechfab/exointernal/stan_gas name = "Life-Support (Standard)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_lifesup_standard" req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) materials = list(DEFAULT_WALL_MATERIAL = 10000) @@ -1149,7 +1149,7 @@ /datum/design/item/mechfab/exointernal/reinf_gas name = "Life-Support (Reinforced)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_lifesup_reinforced" req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_PLASTEEL = 8000, MAT_GRAPHITE = 1000) @@ -1157,7 +1157,7 @@ /datum/design/item/mechfab/exointernal/stan_electric name = "Electrical Harness (Standard)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_electric_standard" req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2) materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 1000) @@ -1165,7 +1165,7 @@ /datum/design/item/mechfab/exointernal/efficient_electric name = "Electrical Harness (High)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_electric_efficient" req_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 4, TECH_DATA = 2) materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000, MAT_SILVER = 3000) @@ -1173,7 +1173,7 @@ /datum/design/item/mechfab/exointernal/stan_actuator name = "Actuator Lattice (Standard)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_actuator_standard" req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) materials = list(DEFAULT_WALL_MATERIAL = 10000) @@ -1181,7 +1181,7 @@ /datum/design/item/mechfab/exointernal/hispeed_actuator name = "Actuator Lattice (Overclocked)" - category = "Exosuit Internals" + category = list("Exosuit Internals") id = "exo_int_actuator_overclock" req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) materials = list(MAT_PLASTEEL = 10000, MAT_OSMIUM = 3000, MAT_GOLD = 5000) diff --git a/code/modules/research/prosfab_designs.dm b/code/modules/research/prosfab_designs.dm index 7882be40b5..889e17fef4 100644 --- a/code/modules/research/prosfab_designs.dm +++ b/code/modules/research/prosfab_designs.dm @@ -1,15 +1,15 @@ /datum/design/item/prosfab build_type = PROSFAB - category = "Misc" + category = list("Misc") req_tech = list(TECH_MATERIAL = 1) /datum/design/item/prosfab/pros - category = "Prosthetics" + category = list("Prosthetics") // Make new external organs and make 'em robotish /datum/design/item/prosfab/pros/Fabricate(var/newloc, var/fabricator) - if(istype(fabricator, /obj/machinery/pros_fabricator)) - var/obj/machinery/pros_fabricator/prosfab = fabricator + if(istype(fabricator, /obj/machinery/mecha_part_fabricator/pros)) + var/obj/machinery/mecha_part_fabricator/pros/prosfab = fabricator var/obj/item/organ/O = new build_path(newloc) if(prosfab.manufacturer) var/datum/robolimb/manf = all_robolimbs[prosfab.manufacturer] @@ -37,8 +37,8 @@ // Deep Magic for the torso since it needs to be a new mob /datum/design/item/prosfab/pros/torso/Fabricate(var/newloc, var/fabricator) - if(istype(fabricator, /obj/machinery/pros_fabricator)) - var/obj/machinery/pros_fabricator/prosfab = fabricator + if(istype(fabricator, /obj/machinery/mecha_part_fabricator/pros)) + var/obj/machinery/mecha_part_fabricator/pros/prosfab = fabricator var/newspecies = "Human" var/datum/robolimb/manf = all_robolimbs[prosfab.manufacturer] @@ -175,7 +175,7 @@ materials = list(DEFAULT_WALL_MATERIAL = 2813) /datum/design/item/prosfab/pros/internal - category = "Prosthetics, Internal" + category = list("Prosthetics, Internal") /datum/design/item/prosfab/pros/internal/cell name = "Prosthetic Powercell" @@ -270,7 +270,7 @@ //////////////////// Cyborg Parts //////////////////// /datum/design/item/prosfab/cyborg - category = "Cyborg Parts" + category = list("Cyborg Parts") time = 20 materials = list(DEFAULT_WALL_MATERIAL = 3750) @@ -326,7 +326,7 @@ //////////////////// Cyborg Internals //////////////////// /datum/design/item/prosfab/cyborg/component - category = "Cyborg Internals" + category = list("Cyborg Internals") build_type = PROSFAB time = 12 materials = list(DEFAULT_WALL_MATERIAL = 7500) @@ -368,7 +368,7 @@ //////////////////// Cyborg Modules //////////////////// /datum/design/item/prosfab/robot_upgrade - category = "Cyborg Modules" + category = list("Cyborg Modules") build_type = PROSFAB time = 12 materials = list(DEFAULT_WALL_MATERIAL = 7500) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 41510d0545..370a460bc7 100755 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -42,7 +42,6 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/obj/machinery/r_n_d/protolathe/linked_lathe = null //Linked Protolathe var/obj/machinery/r_n_d/circuit_imprinter/linked_imprinter = null //Linked Circuit Imprinter - var/screen = 1.0 //Which screen is currently showing. var/id = 0 //ID of the computer (for server restrictions). var/sync = 1 //If sync = 0, it doesn't show up on Server Control Console @@ -71,17 +70,10 @@ won't update every console in existence) but it's more of a hassle to do. Also, return return_name /obj/machinery/computer/rdconsole/proc/CallReagentName(var/ID) - var/return_name = ID - var/datum/reagent/temp_reagent - for(var/R in (typesof(/datum/reagent) - /datum/reagent)) - temp_reagent = null - temp_reagent = new R() - if(temp_reagent.id == ID) - return_name = temp_reagent.name - qdel(temp_reagent) - temp_reagent = null - break - return return_name + var/datum/reagent/R = SSchemistry.chemical_reagents["[ID]"] + if(!R) + return ID + return R.name /obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any). for(var/obj/machinery/r_n_d/D in range(3, src)) @@ -142,7 +134,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, //The construction/deconstruction of the console code. ..() - src.updateUsrDialog() + SStgui.update_uis(src) return /obj/machinery/computer/rdconsole/emp_act(var/remaining_charges, var/mob/user) @@ -152,296 +144,6 @@ won't update every console in existence) but it's more of a hassle to do. Also, to_chat(user, "You you disable the security protocols.") return 1 -/obj/machinery/computer/rdconsole/Topic(href, href_list) - if(..()) - return 1 - - add_fingerprint(usr) - - usr.set_machine(src) - if((screen < 1 || (screen == 1.6 && href_list["menu"] != "1.0")) && (!allowed(usr) && !emagged)) //Stops people from HREF exploiting out of the lock screen, but allow it if they have the access. - to_chat(usr, "Unauthorized Access") - return - - if(href_list["menu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code. - var/temp_screen = text2num(href_list["menu"]) - if(temp_screen <= 1.1 || (3 <= temp_screen && 4.9 >= temp_screen) || allowed(usr) || emagged) //Unless you are making something, you need access. - screen = temp_screen - else - to_chat(usr, "Unauthorized Access.") - - else if(href_list["updt_tech"]) //Update the research holder with information from the technology disk. - screen = 0.0 - spawn(5 SECONDS) - screen = 1.2 - files.AddTech2Known(t_disk.stored) - updateUsrDialog() - griefProtection() //Update CentCom too - - else if(href_list["clear_tech"]) //Erase data on the technology disk. - t_disk.stored = null - - else if(href_list["eject_tech"]) //Eject the technology disk. - t_disk.loc = loc - t_disk = null - screen = 1.0 - - else if(href_list["copy_tech"]) //Copys some technology data from the research holder to the disk. - for(var/datum/tech/T in files.known_tech) - if(href_list["copy_tech_ID"] == T.id) - t_disk.stored = T - break - screen = 1.2 - - else if(href_list["updt_design"]) //Updates the research holder with design data from the design disk. - screen = 0.0 - spawn(5 SECONDS) - screen = 1.4 - files.AddDesign2Known(d_disk.blueprint) - updateUsrDialog() - griefProtection() //Update CentCom too - - else if(href_list["clear_design"]) //Erases data on the design disk. - d_disk.blueprint = null - - else if(href_list["eject_design"]) //Eject the design disk. - d_disk.loc = loc - d_disk = null - screen = 1.0 - - else if(href_list["copy_design"]) //Copy design data from the research holder to the design disk. - for(var/datum/design/D in files.known_designs) - if(href_list["copy_design_ID"] == D.id) - d_disk.blueprint = D - break - screen = 1.4 - - else if(href_list["eject_item"]) //Eject the item inside the destructive analyzer. - if(linked_destroy) - if(linked_destroy.busy) - to_chat(usr, "The destructive analyzer is busy at the moment.") - - else if(linked_destroy.loaded_item) - linked_destroy.loaded_item.loc = linked_destroy.loc - linked_destroy.loaded_item = null - linked_destroy.icon_state = "d_analyzer" - screen = 2.1 - - else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder. - if(linked_destroy) - if(linked_destroy.busy) - to_chat(usr, "The destructive analyzer is busy at the moment.") - else - if(alert("Proceeding will destroy loaded item. Continue?", "Destructive analyzer confirmation", "Yes", "No") == "No" || !linked_destroy) - return - linked_destroy.busy = 1 - screen = 0.1 - updateUsrDialog() - flick("d_analyzer_process", linked_destroy) - spawn(2.4 SECONDS) - if(linked_destroy) - linked_destroy.busy = 0 - if(!linked_destroy.loaded_item) - to_chat(usr, "The destructive analyzer appears to be empty.") - screen = 1.0 - return - - for(var/T in linked_destroy.loaded_item.origin_tech) - files.UpdateTech(T, linked_destroy.loaded_item.origin_tech[T]) - if(linked_lathe && linked_destroy.loaded_item.matter) // Also sends salvaged materials to a linked protolathe, if any. - for(var/t in linked_destroy.loaded_item.matter) - if(t in linked_lathe.materials) - linked_lathe.materials[t] += min(linked_lathe.max_material_storage - linked_lathe.TotalMaterials(), linked_destroy.loaded_item.matter[t] * linked_destroy.decon_mod) - - linked_destroy.loaded_item = null - for(var/obj/I in linked_destroy.contents) - for(var/mob/M in I.contents) - M.death() - if(istype(I,/obj/item/stack/material))//Only deconsturcts one sheet at a time instead of the entire stack - var/obj/item/stack/material/S = I - if(S.get_amount() > 1) - S.use(1) - linked_destroy.loaded_item = S - else - qdel(S) - linked_destroy.icon_state = "d_analyzer" - else - if(I != linked_destroy.circuit && !(I in linked_destroy.component_parts)) - qdel(I) - linked_destroy.icon_state = "d_analyzer" - - use_power(linked_destroy.active_power_usage) - screen = 1.0 - updateUsrDialog() - - else if(href_list["lock"]) //Lock the console from use by anyone without tox access. - if(allowed(usr)) - screen = text2num(href_list["lock"]) - else - to_chat(usr, "Unauthorized Access.") - - else if(href_list["sync"]) //Sync the research holder with all the R&D consoles in the game that aren't sync protected. - screen = 0.0 - if(!sync) - to_chat(usr, "You must connect to the network first.") - else - griefProtection() //Putting this here because I dont trust the sync process - spawn(3 SECONDS) - if(src) - for(var/obj/machinery/r_n_d/server/S in machines) - var/server_processed = 0 - if((id in S.id_with_upload) || istype(S, /obj/machinery/r_n_d/server/centcom)) - for(var/datum/tech/T in files.known_tech) - S.files.AddTech2Known(T) - for(var/datum/design/D in files.known_designs) - S.files.AddDesign2Known(D) - S.files.RefreshResearch() - server_processed = 1 - if((id in S.id_with_download) && !istype(S, /obj/machinery/r_n_d/server/centcom)) - for(var/datum/tech/T in S.files.known_tech) - files.AddTech2Known(T) - for(var/datum/design/D in S.files.known_designs) - files.AddDesign2Known(D) - files.RefreshResearch() - server_processed = 1 - if(!istype(S, /obj/machinery/r_n_d/server/centcom) && server_processed) - S.produce_heat() - screen = 1.6 - updateUsrDialog() - - else if(href_list["togglesync"]) //Prevents the console from being synced by other consoles. Can still send data. - sync = !sync - - else if(href_list["build"]) //Causes the Protolathe to build something. - if(linked_lathe) - var/datum/design/being_built = null - for(var/datum/design/D in files.known_designs) - if(D.id == href_list["build"]) - being_built = D - break - if(being_built) - linked_lathe.addToQueue(being_built) - - else if(href_list["buildfive"]) //Causes the Protolathe to build 5 of something. - if(linked_lathe) - var/datum/design/being_built = null - for(var/datum/design/D in files.known_designs) - if(D.id == href_list["buildfive"]) - being_built = D - break - if(being_built) - for(var/i = 1 to 5) - linked_lathe.addToQueue(being_built) - - screen = 3.1 - - else if(href_list["protofilter"]) - var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", protofilter) as null|text - if(!Adjacent(usr)) - return - if(isnull(filterstring)) //Clicked Cancel - return - if(filterstring == "") //Cleared value - protofilter = null - protofilter = sanitize(filterstring, 25) - - else if(href_list["circuitfilter"]) - var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", circuitfilter) as null|text - if(!Adjacent(usr)) - return - if(isnull(filterstring)) //Clicked Cancel - return - if(filterstring == "") //Cleared value - circuitfilter = null - circuitfilter = sanitize(filterstring, 25) - - else if(href_list["imprint"]) //Causes the Circuit Imprinter to build something. - if(linked_imprinter) - var/datum/design/being_built = null - for(var/datum/design/D in files.known_designs) - if(D.id == href_list["imprint"]) - being_built = D - break - if(being_built) - linked_imprinter.addToQueue(being_built) - screen = 4.1 - - else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) - linked_imprinter.reagents.del_reagent(href_list["dispose"]) - - else if(href_list["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents. - linked_imprinter.reagents.clear_reagents() - - else if(href_list["removeI"] && linked_lathe) - linked_imprinter.removeFromQueue(text2num(href_list["removeI"])) - - else if(href_list["disposeP"] && linked_lathe) //Causes the protolathe to dispose of a single reagent (all of it) - linked_lathe.reagents.del_reagent(href_list["dispose"]) - - else if(href_list["disposeallP"] && linked_lathe) //Causes the protolathe to dispose of all it's reagents. - linked_lathe.reagents.clear_reagents() - - else if(href_list["removeP"] && linked_lathe) - linked_lathe.removeFromQueue(text2num(href_list["removeP"])) - - else if(href_list["lathe_ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material - linked_lathe.eject(href_list["lathe_ejectsheet"], text2num(href_list["amount"])) - - else if(href_list["imprinter_ejectsheet"] && linked_imprinter) //Causes the protolathe to eject a sheet of material - linked_imprinter.eject(href_list["imprinter_ejectsheet"], text2num(href_list["amount"])) - - else if(href_list["find_device"]) //The R&D console looks for devices nearby to link up with. - screen = 0.0 - spawn(10) - SyncRDevices() - screen = 1.7 - updateUsrDialog() - - else if(href_list["disconnect"]) //The R&D console disconnects with a specific device. - switch(href_list["disconnect"]) - if("destroy") - linked_destroy.linked_console = null - linked_destroy = null - if("lathe") - linked_lathe.linked_console = null - linked_lathe = null - if("imprinter") - linked_imprinter.linked_console = null - linked_imprinter = null - - else if(href_list["reset"]) //Reset the R&D console's database. - griefProtection() - var/choice = alert("R&D Console Database Reset", "Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "Continue", "Cancel") - if(choice == "Continue") - screen = 0.0 - qdel(files) - files = new /datum/research(src) - spawn(20) - screen = 1.6 - updateUsrDialog() - - else if (href_list["print"]) //Print research information - screen = 0.5 - spawn(20) - var/obj/item/weapon/paper/PR = new/obj/item/weapon/paper - PR.name = "list of researched technologies" - PR.info = "
[station_name()] Science Laboratories" - PR.info += "

[ (text2num(href_list["print"]) == 2) ? "Detailed" : null] Research Progress Report

" - PR.info += "report prepared at [stationtime2text()] station time

" - if(text2num(href_list["print"]) == 2) - PR.info += GetResearchListInfo() - else - PR.info += GetResearchLevelsInfo() - PR.info_links = PR.info - PR.icon_state = "paper_words" - PR.loc = src.loc - spawn(10) - screen = ((text2num(href_list["print"]) == 2) ? 5.0 : 1.1) - updateUsrDialog() - - updateUsrDialog() - return - /obj/machinery/computer/rdconsole/proc/GetResearchLevelsInfo() var/list/dat = list() dat += "" - - if(1.2) //Technology Disk Menu - - dat += "Main Menu
" - dat += "Disk Contents: (Technology Data Disk)

" - if(t_disk.stored == null) - dat += "The disk has no data stored on it.
" - dat += "Operations: " - dat += "Load Tech to Disk || " - else - dat += "Name: [t_disk.stored.name]
" - dat += "Level: [t_disk.stored.level]
" - dat += "Description: [t_disk.stored.desc]
" - dat += "Operations: " - dat += "Upload to Database || " - dat += "Clear Disk || " - dat += "Eject Disk" - - if(1.3) //Technology Disk submenu - dat += "
Main Menu || " - dat += "Return to Disk Operations
" - dat += "Load Technology to Disk:

" - dat += "" - - if(1.4) //Design Disk menu. - dat += "Main Menu
" - if(d_disk.blueprint == null) - dat += "The disk has no data stored on it.
" - dat += "Operations: " - dat += "Load Design to Disk || " - else - dat += "Name: [d_disk.blueprint.name]
" - switch(d_disk.blueprint.build_type) - if(IMPRINTER) dat += "Lathe Type: Circuit Imprinter
" - if(PROTOLATHE) dat += "Lathe Type: Proto-lathe
" - dat += "Required Materials:
" - for(var/M in d_disk.blueprint.materials) - if(copytext(M, 1, 2) == "$") dat += "* [copytext(M, 2)] x [d_disk.blueprint.materials[M]]
" - else dat += "* [M] x [d_disk.blueprint.materials[M]]
" - dat += "
Operations: " - dat += "Upload to Database || " - dat += "Clear Disk || " - dat += "Eject Disk" - - if(1.5) //Technology disk submenu - dat += "Main Menu || " - dat += "Return to Disk Operations
" - dat += "Load Design to Disk:

" - dat += "" - - if(1.6) //R&D console settings - dat += "Main Menu
" - dat += "R&D Console Setting:
" - dat += "