diff --git a/.travis.yml b/.travis.yml index e2bc4a5192..2559dcab32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ addons: - libc6-i386 - libgcc1:i386 - libstdc++6:i386 + - libssl-dev:i386 before_script: - chmod +x ./install-byond.sh diff --git a/code/__defines/_compile_options.dm b/code/__defines/_compile_options.dm index 229d0b94ad..10a6485c44 100644 --- a/code/__defines/_compile_options.dm +++ b/code/__defines/_compile_options.dm @@ -7,6 +7,10 @@ 2 for preloading absolutely everything; */ +#define RUST_G "rust_g" // If uncommented, we will use the rust-g (https://github.com/tgstation/rust-g) native library for fast + // logging. This requires you to have the rust_g.dll or rust_g (renamed from librust_g.so) installed in the root folder or BYOND/bin + // The define's value should be the name of library file. + // ZAS Compile Options //#define ZASDBG // Uncomment to turn on super detailed ZAS debugging that probably won't even compile. #define MULTIZAS // Uncomment to turn on Multi-Z ZAS Support! diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index ad2962547c..3686518108 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -58,7 +58,7 @@ What is the naming convention for planes or layers? #define ATMOS_LAYER 2.4 // Pipe-like atmos machinery that goes on the floor, like filters. #define ABOVE_UTILITY 2.5 // Above stuff like pipes and wires #define TURF_PLANE -45 // Turfs themselves, most flooring - #define ABOVE_TURF_LAYER 2.1 // Snow and such + #define ABOVE_TURF_LAYER 2.1 // Snow and wallmounted/floormounted equipment #define DECAL_PLANE -44 // Permanent decals #define DIRTY_PLANE -43 // Nonpermanent decals #define BLOOD_PLANE -42 // Blood is really dirty, but we can do special stuff if we separate it @@ -74,9 +74,6 @@ What is the naming convention for planes or layers? #define DOOR_CLOSED_LAYER 3.1 // Doors when closed #define WINDOW_LAYER 3.2 // Windows #define ON_WINDOW_LAYER 3.3 // Ontop of a window - #define SHOWER_OPEN_LAYER 3.4 // Showers when open - // Obj/Mob layer boundary - #define SHOWER_CLOSED_LAYER 4.2 // Should be converted to plane swaps // Mob planes #define MOB_PLANE -25 diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm index 00e473fc2a..9304a26efe 100644 --- a/code/__defines/lighting.dm +++ b/code/__defines/lighting.dm @@ -72,4 +72,7 @@ #define LIGHT_COLOR_FLARE "#FA644B" //Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75) #define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75) #define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175) -#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250) \ No newline at end of file +#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250) + +//Fake ambient occlusion filter +#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, border=4, color="#04080FAA") diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 6058200915..eea0e7deda 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -21,6 +21,9 @@ #define SEE_INVISIBLE_MINIMUM 5 #define INVISIBILITY_MAXIMUM 100 +// For the client FPS pref and anywhere else +#define MAX_CLIENT_FPS 200 + // Some arbitrary defines to be used by self-pruning global lists. (see master_controller) #define PROCESS_KILL 26 // Used to trigger removal from a processing list. #define MAX_GEAR_COST 15 // Used in chargen for accessory loadout limit. @@ -101,7 +104,7 @@ #define WAIT_FINISH 4 // Setting this much higher than 1024 could allow spammers to DOS the server easily. -#define MAX_MESSAGE_LEN 1024 +#define MAX_MESSAGE_LEN 2048 //VOREStation Edit - I'm not sure about "easily". It can be a little longer. #define MAX_PAPER_MESSAGE_LEN 6144 #define MAX_BOOK_MESSAGE_LEN 24576 #define MAX_RECORD_LENGTH 24576 @@ -237,3 +240,17 @@ #define USE_FAIL_INCAPACITATED 5 #define USE_FAIL_NOT_IN_USER 6 #define USE_FAIL_IS_SILICON 7 + +//'Normal'ness v v v +//Various types of colorblindness R2R R2G R2B G2R G2G G2B B2R B2G B2B +#define MATRIX_Monochromia list(0.33, 0.33, 0.33, 0.59, 0.59, 0.59, 0.11, 0.11, 0.11) +#define MATRIX_Protanopia list(0.57, 0.43, 0, 0.56, 0.44, 0, 0, 0.24, 0.76) +#define MATRIX_Protanomaly list(0.82, 0.18, 0, 0.33, 0.67, 0, 0, 0.13, 0.88) +#define MATRIX_Deuteranopia list(0.63, 0.38, 0, 0.70, 0.30, 0, 0, 0.30, 0.70) +#define MATRIX_Deuteranomaly list(0.80, 0.20, 0, 0.26, 0.74, 0, 0, 0.14, 0.86) +#define MATRIX_Tritanopia list(0.95, 0.05, 0, 0, 0.43, 0.57, 0, 0.48, 0.53) +#define MATRIX_Tritanomaly list(0.97, 0.03, 0, 0, 0.73, 0.27, 0, 0.18, 0.82) +#define MATRIX_Achromatopsia list(0.30, 0.59, 0.11, 0.30, 0.59, 0.11, 0.30, 0.59, 0.11) +#define MATRIX_Achromatomaly list(0.62, 0.32, 0.06, 0.16, 0.78, 0.06, 0.16, 0.32, 0.52) +#define MATRIX_Vulp_Colorblind list(0.50, 0.40, 0.10, 0.50, 0.40, 0.10, 0, 0.20, 0.80) +#define MATRIX_Taj_Colorblind list(0.40, 0.20, 0.40, 0.40, 0.60, 0, 0.20, 0.20, 0.60) diff --git a/code/__defines/misc_vr.dm b/code/__defines/misc_vr.dm index ed2f27978a..600bf5be2b 100644 --- a/code/__defines/misc_vr.dm +++ b/code/__defines/misc_vr.dm @@ -20,6 +20,11 @@ #define STARTING_SPECIES_POINTS 1 #define MAX_SPECIES_TRAITS 5 +// Xenochimera thing mostly +#define REVIVING_NOW 1 +#define REVIVING_DONE 2 +#define REVIVING_COOLDOWN 3 + // Resleeving Mind Record Status #define MR_NORMAL 0 #define MR_UNSURE 1 @@ -33,6 +38,9 @@ //Assistant/Visitor/Whatever #define USELESS_JOB "Visitor" +//Herm Gender +#define HERM "herm" + // Bluespace shelter deploy checks #define SHELTER_DEPLOY_ALLOWED "allowed" #define SHELTER_DEPLOY_BAD_TURFS "bad turfs" diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 6d466e9930..53707c98cd 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -293,16 +293,17 @@ #define VIS_CH_SPECIAL 13 #define VIS_CH_STATUS_OOC 14 -#define VIS_D_COLORBLIND 15 -#define VIS_D_COLORBLINDI 16 +#define VIS_ADMIN1 15 +#define VIS_ADMIN2 16 +#define VIS_ADMIN3 17 -#define VIS_ADMIN1 17 -#define VIS_ADMIN2 18 -#define VIS_ADMIN3 19 +#define VIS_MESONS 18 -#define VIS_MESONS 20 +#define VIS_TURFS 19 +#define VIS_OBJS 20 +#define VIS_MOBS 21 -#define VIS_COUNT 20 //Must be highest number from above. +#define VIS_COUNT 21 //Must be highest number from above. //Some mob icon layering defines #define BODY_LAYER -100 diff --git a/code/__defines/mobs_vr.dm b/code/__defines/mobs_vr.dm index eee6220f8b..2e3f8b0760 100644 --- a/code/__defines/mobs_vr.dm +++ b/code/__defines/mobs_vr.dm @@ -1,13 +1,13 @@ #undef VIS_COUNT -#define VIS_CH_STATUS_R 21 -#define VIS_CH_HEALTH_VR 22 -#define VIS_CH_BACKUP 23 -#define VIS_CH_VANTAG 24 +#define VIS_CH_STATUS_R 22 +#define VIS_CH_HEALTH_VR 23 +#define VIS_CH_BACKUP 24 +#define VIS_CH_VANTAG 25 -#define VIS_AUGMENTED 25 +#define VIS_AUGMENTED 26 -#define VIS_COUNT 25 +#define VIS_COUNT 26 //Protean organs #define O_ORCH "orchestrator" diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 903c7d3d68..34a58f18ca 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -24,8 +24,8 @@ var/global/list/joblist = list() //list of all jobstypes, minus borg and AI var/global/list/turfs = list() //list of all turfs -#define all_genders_define_list list(MALE,FEMALE,PLURAL,NEUTER) -#define all_genders_text_list list("Male","Female","Plural","Neuter") +#define all_genders_define_list list(MALE,FEMALE,PLURAL,NEUTER,HERM) //VOREStaton Edit +#define all_genders_text_list list("Male","Female","Plural","Neuter","Herm") //VOREStation Edit //Languages/species/whitelist. var/global/list/all_species[0] diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index 492fa8ed75..d49a71d013 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -162,6 +162,215 @@ var/global/list/edible_trash = list(/obj/item/trash, /obj/item/device/mmi/digital/posibrain, /obj/item/device/aicard) +var/global/list/cont_flavors = list( + "Generic" = cont_flavors_generic, + "Acrid" = cont_flavors_acrid, + "Dirty" = cont_flavors_dirty, + "Musky" = cont_flavors_musky, + "Smelly" = cont_flavors_smelly, + "Wet" = cont_flavors_wet) + +var/global/list/cont_flavors_generic = list("acrid", + "bedraggled", + "begrimed", + "churned", + "contaminated", + "cruddy", + "damp", + "digested", + "dirty", + "disgusting", + "drenched", + "drippy", + "filthy", + "foul", + "funky", + "gloppy", + "gooey", + "grimy", + "gross", + "gruesome", + "gunky", + "icky", + "juicy", + "messy", + "mucky", + "mushy", + "nasty", + "noxious", + "oozing", + "pungent", + "putrescent", + "putrid", + "repulsive", + "saucy", + "slimy", + "sloppy", + "sloshed", + "sludgy", + "smeary", + "smelly", + "smudgy", + "smutty", + "soaked", + "soggy", + "soiled", + "sopping", + "squashy", + "squishy", + "stained", + "sticky", + "stinky", + "tainted", + "tarnished", + "unclean", + "unsanitary", + "unsavory", + "yucky") + +var/global/list/cont_flavors_wet = list("damp", + "drenched", + "drippy", + "gloppy", + "gooey", + "juicy", + "oozing", + "slimy", + "slobbery", + "sloppy", + "sloshed", + "sloughy", + "sludgy", + "slushy", + "soaked", + "soggy", + "sopping", + "squashy", + "squishy", + "sticky") + +var/global/list/cont_flavors_smelly = list("disgusting", + "filthy", + "foul", + "funky", + "gross", + "icky", + "malodorous", + "nasty", + "niffy", + "noxious", + "pungent", + "putrescent", + "putrid", + "rancid", + "reeking", + "repulsive", + "smelly", + "stenchy", + "stinky", + "unsavory", + "whiffy", + "yucky") + +var/global/list/cont_flavors_acrid = list("acrid", + "caustic", + "churned", + "chymous", + "digested", + "discolored", + "disgusting", + "drippy", + "foul", + "gloppy", + "gooey", + "grimy", + "gross", + "gruesome", + "icky", + "mucky", + "mushy", + "nasty", + "noxious", + "oozing", + "pungent", + "putrescent", + "putrid", + "repulsive", + "saucy", + "slimy", + "sloppy", + "sloshed", + "sludgy", + "slushy", + "smelly", + "smudgy", + "soupy", + "squashy", + "squishy", + "stained", + "sticky", + "tainted", + "unsavory", + "yucky") + +var/global/list/cont_flavors_dirty = list("bedraggled", + "begrimed", + "besmirched", + "blemished", + "contaminated", + "cruddy", + "dirty", + "discolored", + "filthy", + "gloppy", + "gooey", + "grimy", + "gross", + "grubby", + "gruesome", + "gunky", + "messy", + "mucky", + "mushy", + "nasty", + "saucy", + "slimy", + "sloppy", + "sludgy", + "smeary", + "smudgy", + "smutty", + "soiled", + "stained", + "sticky", + "tainted", + "tarnished", + "unclean", + "unsanitary", + "unsavory") + +var/global/list/cont_flavors_musky = list("drenched", + "drippy", + "funky", + "gooey", + "juicy", + "messy", + "musky", + "nasty", + "raunchy", + "saucy", + "slimy", + "sloppy", + "slushy", + "smeary", + "smelly", + "smutty", + "soggy", + "squashy", + "squishy", + "sticky", + "tainted") + /hook/startup/proc/init_vore_datum_ref_lists() var/paths diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index ee8949f535..c771de02ef 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -1,38 +1,51 @@ //print an error message to world.log +// Fall back to using old format if we are not using rust-g +#ifdef RUST_G + #define WRITE_LOG(log, text) call(RUST_G, "log_write")(log, text) +#else + #define WRITE_LOG(log, text) log << "\[[time_stamp()]][text]" +#endif -// On Linux/Unix systems the line endings are LF, on windows it's CRLF, admins that don't use notepad++ -// will get logs that are one big line if the system is Linux and they are using notepad. This solves it by adding CR to every line ending -// in the logs. ascii character 13 = CR - -/var/global/log_end= world.system_type == UNIX ? ascii2text(13) : "" +/* For logging round startup. */ +/proc/start_log(log) + #ifndef RUST_G + log = file(log) + #endif + WRITE_LOG(log, "START: Starting up [log_path].") + return log +/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */ +/proc/shutdown_logging() + #ifdef RUST_G + call(RUST_G, "log_close_all")() + #endif /proc/error(msg) - world.log << "## ERROR: [msg][log_end]" + world.log << "## ERROR: [msg]" #define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].") //print a warning message to world.log /proc/warning(msg) - world.log << "## WARNING: [msg][log_end]" + world.log << "## WARNING: [msg]" //print a testing-mode debug message to world.log /proc/testing(msg) - world.log << "## TESTING: [msg][log_end]" + world.log << "## TESTING: [msg]" /proc/log_admin(text) admin_log.Add(text) if (config.log_admin) - diary << "\[[time_stamp()]]ADMIN: [text][log_end]" + WRITE_LOG(diary, "ADMIN: [text]") /proc/log_adminpm(text, client/source, client/dest) admin_log.Add(text) if (config.log_admin) - diary << "\[[time_stamp()]]ADMINPM: [key_name(source)]->[key_name(dest)]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "ADMINPM: [key_name(source)]->[key_name(dest)]: [html_decode(text)]") /proc/log_debug(text) if (config.log_debug) - debug_log << "\[[time_stamp()]]DEBUG: [text][log_end]" + WRITE_LOG(debug_log, "DEBUG: [text]") for(var/client/C in admins) if(C.is_preference_enabled(/datum/client_preference/debug/show_debug_logs)) @@ -40,89 +53,97 @@ /proc/log_game(text) if (config.log_game) - diary << "\[[time_stamp()]]GAME: [text][log_end]" + WRITE_LOG(diary, "GAME: [text]") /proc/log_vote(text) if (config.log_vote) - diary << "\[[time_stamp()]]VOTE: [text][log_end]" + WRITE_LOG(diary, "VOTE: [text]") /proc/log_access_in(client/new_client) if (config.log_access) var/message = "[key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version]" - diary << "\[[time_stamp()]]ACCESS IN: [message][log_end]" + WRITE_LOG(diary, "ACCESS IN: [message]") /proc/log_access_out(mob/last_mob) if (config.log_access) var/message = "[key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:Logged Out - BYOND Logged Out" - diary << "\[[time_stamp()]]ACCESS OUT: [message][log_end]" + WRITE_LOG(diary, "ACCESS OUT: [message]") /proc/log_say(text, mob/speaker) if (config.log_say) - diary << "\[[time_stamp()]]SAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "SAY: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_ooc(text, client/user) if (config.log_ooc) - diary << "\[[time_stamp()]]OOC: [user.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "OOC: [user.simple_info_line()]: [html_decode(text)]") /proc/log_aooc(text, client/user) if (config.log_ooc) - diary << "\[[time_stamp()]]AOOC: [user.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "AOOC: [user.simple_info_line()]: [html_decode(text)]") /proc/log_looc(text, client/user) if (config.log_ooc) - diary << "\[[time_stamp()]]LOOC: [user.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "LOOC: [user.simple_info_line()]: [html_decode(text)]") /proc/log_whisper(text, mob/speaker) if (config.log_whisper) - diary << "\[[time_stamp()]]WHISPER: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_emote(text, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]EMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_attack(attacker, defender, message) if (config.log_attack) - diary << "\[[time_stamp()]]ATTACK: [attacker] against [defender]: [message][log_end]" + WRITE_LOG(diary, "ATTACK: [attacker] against [defender]: [message]") /proc/log_adminsay(text, mob/speaker) if (config.log_adminchat) - diary << "\[[time_stamp()]]ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_modsay(text, mob/speaker) if (config.log_adminchat) - diary << "\[[time_stamp()]]MODSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "MODSAY: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_eventsay(text, mob/speaker) if (config.log_adminchat) - diary << "\[[time_stamp()]]EVENTSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "EVENTSAY: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_ghostsay(text, mob/speaker) if (config.log_say) - diary << "\[[time_stamp()]]DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_ghostemote(text, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_adminwarn(text) if (config.log_adminwarn) - diary << "\[[time_stamp()]]ADMINWARN: [html_decode(text)][log_end]" + WRITE_LOG(diary, "ADMINWARN: [html_decode(text)]") /proc/log_pda(text, mob/speaker) if (config.log_pda) - diary << "\[[time_stamp()]]PDA: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "PDA: [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_to_dd(text) world.log << text //this comes before the config check because it can't possibly runtime if(config.log_world_output) - diary << "\[[time_stamp()]]DD_OUTPUT: [text][log_end]" + WRITE_LOG(diary, "DD_OUTPUT: [text]") /proc/log_error(text) world.log << text - error_log << "\[[time_stamp()]]RUNTIME: [text][log_end]" + WRITE_LOG(error_log, "RUNTIME: [text]") /proc/log_misc(text) - diary << "\[[time_stamp()]]MISC: [text][log_end]" + WRITE_LOG(diary, "MISC: [text]") + +/proc/log_topic(text) + if(Debug2) + WRITE_LOG(diary, "TOPIC: [text]") + +/proc/log_href(text) + // Configs are checked by caller + WRITE_LOG(href_logfile, "HREF: [text]") /proc/log_unit_test(text) world.log << "## UNIT_TEST: [text]" diff --git a/code/_helpers/logging_vr.dm b/code/_helpers/logging_vr.dm index 66a91e0c2e..aa117125dc 100644 --- a/code/_helpers/logging_vr.dm +++ b/code/_helpers/logging_vr.dm @@ -1,11 +1,11 @@ /proc/log_nsay(text, inside, mob/speaker) if (config.log_say) - diary << "\[[time_stamp()]]NSAY (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "NSAY (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_nme(text, inside, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]NME (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "NME (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)]") /proc/log_subtle(text, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]SUBTLE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + WRITE_LOG(diary, "SUBTLE: [speaker.simple_info_line()]: [html_decode(text)]") diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index e26724ae5b..92b8d25542 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -1467,11 +1467,21 @@ var/mob/dview/dview_mob = new if(337.5) return "North-Northwest" +//This is used to force compiletime errors if you incorrectly supply variable names. Crafty! +#define NAMEOF(datum, X) (#X || ##datum.##X) +//Creates a callback with the specific purpose of setting a variable +#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, weakref(##datum), NAMEOF(##datum, ##var), ##var_value) - - - - - - +//Helper for the above +/proc/___callbackvarset(list_or_datum, var_name, var_value) + if(isweakref(list_or_datum)) + var/weakref/wr = list_or_datum + list_or_datum = wr.resolve() + if(!list_or_datum) + return + if(length(list_or_datum)) + list_or_datum[var_name] = var_value + return + var/datum/D = list_or_datum + D.vars[var_name] = var_value diff --git a/code/controllers/Processes/scheduler.dm b/code/controllers/Processes/scheduler.dm index a2a2f5f925..c852264bb7 100644 --- a/code/controllers/Processes/scheduler.dm +++ b/code/controllers/Processes/scheduler.dm @@ -58,6 +58,9 @@ /proc/schedule_task_in(var/in_time, var/procedure, var/list/arguments = list()) return schedule_task(world.time + in_time, procedure, arguments) +/proc/schedule_callback_in(var/in_time, var/datum/callback) + return schedule_callback(world.time + in_time, callback) + /proc/schedule_task_with_source_in(var/in_time, var/source, var/procedure, var/list/arguments = list()) return schedule_task_with_source(world.time + in_time, source, procedure, arguments) @@ -66,6 +69,11 @@ scheduler.schedule(st) return st +/proc/schedule_callback(var/trigger_time, var/datum/callback) + var/datum/scheduled_task/callback/st = new/datum/scheduled_task/callback(trigger_time, callback, /proc/destroy_scheduled_task, list()) + scheduler.schedule(st) + return st + /proc/schedule_task_with_source(var/trigger_time, var/source, var/procedure, var/list/arguments) var/datum/scheduled_task/st = new/datum/scheduled_task/source(trigger_time, source, procedure, arguments, /proc/destroy_scheduled_task, list()) scheduler.schedule(st) @@ -125,6 +133,15 @@ /datum/scheduled_task/proc/trigger_task_in(var/trigger_in) src.trigger_time = world.time + trigger_in +/datum/scheduled_task/callback + var/datum/callback/callback + +/datum/scheduled_task/callback/New(var/trigger_time, var/datum/callback, var/proc/task_after_process, var/list/task_after_process_args) + ..(trigger_time = trigger_time, task_after_process = task_after_process, task_after_process_args = task_after_process_args) + +/datum/scheduled_task/callback/process() + callback.Invoke() + /datum/scheduled_task/source var/datum/source diff --git a/code/controllers/subsystems/transcore_vr.dm b/code/controllers/subsystems/transcore_vr.dm index 4958d87f3d..feae05ae91 100644 --- a/code/controllers/subsystems/transcore_vr.dm +++ b/code/controllers/subsystems/transcore_vr.dm @@ -139,10 +139,12 @@ SUBSYSTEM_DEF(transcore) var/datum/nifsoft/nifsoft = N nifsofts += nifsoft.type MR.nif_software = nifsofts + MR.nif_savedata = nif.save_data.Copy() else if(isnull(nif)) //Didn't pass anything, so no NIF MR.nif_path = null MR.nif_durability = null MR.nif_software = null + MR.nif_savedata = null else MR = new(mind, mind.current, add_to_db = TRUE, one_time = one_time) diff --git a/code/datums/supplypacks/engineering_vr.dm b/code/datums/supplypacks/engineering_vr.dm index 72b0073371..28faf96434 100644 --- a/code/datums/supplypacks/engineering_vr.dm +++ b/code/datums/supplypacks/engineering_vr.dm @@ -7,8 +7,7 @@ /datum/supply_packs/eng/radsuit contains = list( - /obj/item/clothing/suit/radiation = 2, - /obj/item/clothing/suit/radiation/taur = 1, + /obj/item/clothing/suit/radiation = 3, /obj/item/clothing/head/radiation = 3 ) diff --git a/code/datums/supplypacks/medical_vr.dm b/code/datums/supplypacks/medical_vr.dm index b5e3a6bc57..989e89297b 100644 --- a/code/datums/supplypacks/medical_vr.dm +++ b/code/datums/supplypacks/medical_vr.dm @@ -1,13 +1,10 @@ /datum/supply_packs/med/medicalbiosuits contains = list( /obj/item/clothing/head/bio_hood/scientist = 3, - /obj/item/clothing/suit/bio_suit/scientist = 2, - /obj/item/clothing/suit/bio_suit/scientist/taur = 1, - /obj/item/clothing/suit/bio_suit/virology = 2, - /obj/item/clothing/suit/bio_suit/virology/taur = 1, + /obj/item/clothing/suit/bio_suit/scientist = 3, + /obj/item/clothing/suit/bio_suit/virology = 3, /obj/item/clothing/head/bio_hood/virology = 3, /obj/item/clothing/suit/bio_suit/cmo, - /obj/item/clothing/suit/bio_suit/cmo/taur, /obj/item/clothing/head/bio_hood/cmo, /obj/item/clothing/shoes/white = 7, /obj/item/clothing/mask/gas = 7, @@ -20,8 +17,7 @@ /datum/supply_packs/med/virologybiosuits name = "Virology biohazard gear" contains = list( - /obj/item/clothing/suit/bio_suit/virology = 2, - /obj/item/clothing/suit/bio_suit/virology/taur = 1, + /obj/item/clothing/suit/bio_suit/virology = 3, /obj/item/clothing/head/bio_hood/virology = 3, /obj/item/clothing/mask/gas = 3, /obj/item/weapon/tank/oxygen = 3, diff --git a/code/datums/supplypacks/robotics_vr.dm b/code/datums/supplypacks/robotics_vr.dm new file mode 100644 index 0000000000..9ee67ebb9d --- /dev/null +++ b/code/datums/supplypacks/robotics_vr.dm @@ -0,0 +1,73 @@ +/datum/supply_packs/robotics/mecha_gopher + name = "Circuit Crate (\"Gopher\" APLU)" + contains = list( + /obj/item/weapon/circuitboard/mecha/gopher/main, + /obj/item/weapon/circuitboard/mecha/gopher/peripherals + ) + cost = 25 + containertype = /obj/structure/closet/crate/secure/science + containername = "APLU \"Gopher\" Circuit Crate" + access = access_robotics + +/datum/supply_packs/robotics/mecha_polecat + name = "Circuit Crate (\"Polecat\" APLU)" + contains = list( + /obj/item/weapon/circuitboard/mecha/polecat/main, + /obj/item/weapon/circuitboard/mecha/polecat/peripherals, + /obj/item/weapon/circuitboard/mecha/polecat/targeting + ) + cost = 25 + containertype = /obj/structure/closet/crate/secure/science + containername = "APLU \"Polecat\" Circuit Crate" + access = access_robotics + +/datum/supply_packs/robotics/mecha_weasel + name = "Circuit Crate (\"Weasel\" APLU)" + contains = list( + /obj/item/weapon/circuitboard/mecha/weasel/main, + /obj/item/weapon/circuitboard/mecha/weasel/peripherals, + /obj/item/weapon/circuitboard/mecha/weasel/targeting + ) + cost = 25 + containertype = /obj/structure/closet/crate/secure/science + containername = "APLU \"Weasel\" Circuit Crate" + access = access_robotics + +/datum/supply_packs/robotics/some_robolimbs + name = "Basic Robolimb Blueprints" + contains = list( + /obj/item/weapon/disk/limb/morpheus, + /obj/item/weapon/disk/limb/xion, + /obj/item/weapon/disk/limb/talon + ) + cost = 15 + containertype = /obj/structure/closet/crate/secure + containername = "Basic Robolimb Blueprint Crate" + access = access_robotics + +/datum/supply_packs/robotics/all_robolimbs + name = "Advanced Robolimb Blueprints" + contains = list( + /obj/item/weapon/disk/limb/bishop, + /obj/item/weapon/disk/limb/hephaestus, + /obj/item/weapon/disk/limb/morpheus, + /obj/item/weapon/disk/limb/veymed, + /obj/item/weapon/disk/limb/wardtakahashi, + /obj/item/weapon/disk/limb/xion, + /obj/item/weapon/disk/limb/zenghu, + /obj/item/weapon/disk/limb/talon, + /obj/item/weapon/disk/limb/dsi_tajaran, + /obj/item/weapon/disk/limb/dsi_lizard, + /obj/item/weapon/disk/limb/dsi_sergal, + /obj/item/weapon/disk/limb/dsi_nevrean, + /obj/item/weapon/disk/limb/dsi_vulpkanin, + /obj/item/weapon/disk/limb/dsi_akula, + /obj/item/weapon/disk/limb/dsi_spider, + /obj/item/weapon/disk/limb/dsi_teshari, + /obj/item/weapon/disk/limb/eggnerdltd, + /obj/item/weapon/disk/limb/eggnerdltdred + ) + cost = 40 + containertype = /obj/structure/closet/crate/secure + containername = "Advanced Robolimb Blueprint Crate" + access = access_robotics diff --git a/code/datums/supplypacks/science_vr.dm b/code/datums/supplypacks/science_vr.dm index 595d2eeba2..4dbb5b847e 100644 --- a/code/datums/supplypacks/science_vr.dm +++ b/code/datums/supplypacks/science_vr.dm @@ -1,41 +1,3 @@ -/datum/supply_packs/sci/some_robolimbs - name = "Basic Robolimb Blueprints" - contains = list( - /obj/item/weapon/disk/limb/morpheus, - /obj/item/weapon/disk/limb/xion, - /obj/item/weapon/disk/limb/talon - ) - cost = 15 - containertype = /obj/structure/closet/crate/secure - containername = "Basic Robolimb Blueprint Crate" - access = access_robotics - -/datum/supply_packs/sci/all_robolimbs - name = "Advanced Robolimb Blueprints" - contains = list( - /obj/item/weapon/disk/limb/bishop, - /obj/item/weapon/disk/limb/hephaestus, - /obj/item/weapon/disk/limb/morpheus, - /obj/item/weapon/disk/limb/veymed, - /obj/item/weapon/disk/limb/wardtakahashi, - /obj/item/weapon/disk/limb/xion, - /obj/item/weapon/disk/limb/zenghu, - /obj/item/weapon/disk/limb/talon, - /obj/item/weapon/disk/limb/dsi_tajaran, - /obj/item/weapon/disk/limb/dsi_lizard, - /obj/item/weapon/disk/limb/dsi_sergal, - /obj/item/weapon/disk/limb/dsi_nevrean, - /obj/item/weapon/disk/limb/dsi_vulpkanin, - /obj/item/weapon/disk/limb/dsi_akula, - /obj/item/weapon/disk/limb/dsi_spider, - /obj/item/weapon/disk/limb/dsi_teshari, - /obj/item/weapon/disk/limb/eggnerdltd, - /obj/item/weapon/disk/limb/eggnerdltdred - ) - cost = 40 - containertype = /obj/structure/closet/crate/secure - containername = "Advanced Robolimb Blueprint Crate" - access = access_robotics /* /datum/supply_packs/sci/dune_buggy name = "Exploration Dune Buggy" diff --git a/code/datums/supplypacks/security_vr.dm b/code/datums/supplypacks/security_vr.dm index 20629de0b4..4c77b42e06 100644 --- a/code/datums/supplypacks/security_vr.dm +++ b/code/datums/supplypacks/security_vr.dm @@ -20,8 +20,7 @@ contains = list( /obj/item/clothing/head/bio_hood/security = 3, /obj/item/clothing/under/rank/security = 3, - /obj/item/clothing/suit/bio_suit/security = 2, - /obj/item/clothing/suit/bio_suit/security/taur = 1, + /obj/item/clothing/suit/bio_suit/security = 3, /obj/item/clothing/shoes/white = 3, /obj/item/clothing/mask/gas = 3, /obj/item/weapon/tank/oxygen = 3, diff --git a/code/datums/supplypacks/voidsuits_vr.dm b/code/datums/supplypacks/voidsuits_vr.dm index d4b3ec9bf5..cad6438ee3 100644 --- a/code/datums/supplypacks/voidsuits_vr.dm +++ b/code/datums/supplypacks/voidsuits_vr.dm @@ -1,7 +1,6 @@ /datum/supply_packs/voidsuits/atmos contains = list( - /obj/item/clothing/suit/space/void/atmos = 2, - /obj/item/clothing/suit/space/void/atmos/taur = 1, + /obj/item/clothing/suit/space/void/atmos = 3, /obj/item/clothing/head/helmet/space/void/atmos = 3, /obj/item/clothing/mask/breath = 3, /obj/item/clothing/shoes/magboots = 3, @@ -10,8 +9,7 @@ /datum/supply_packs/voidsuits/engineering contains = list( - /obj/item/clothing/suit/space/void/engineering = 2, - /obj/item/clothing/suit/space/void/engineering/taur = 1, + /obj/item/clothing/suit/space/void/engineering = 3, /obj/item/clothing/head/helmet/space/void/engineering = 3, /obj/item/clothing/mask/breath = 3, /obj/item/clothing/shoes/magboots = 3, @@ -20,8 +18,7 @@ /datum/supply_packs/voidsuits/medical contains = list( - /obj/item/clothing/suit/space/void/medical = 2, - /obj/item/clothing/suit/space/void/medical/taur = 1, + /obj/item/clothing/suit/space/void/medical = 3, /obj/item/clothing/head/helmet/space/void/medical = 3, /obj/item/clothing/mask/breath = 3, /obj/item/clothing/shoes/magboots = 3, @@ -30,19 +27,16 @@ /datum/supply_packs/voidsuits/medical/alt contains = list( - /obj/item/clothing/suit/space/void/medical/alt = 2, - /obj/item/clothing/suit/space/void/medical/alt/taur = 1, + /obj/item/clothing/suit/space/void/medical/alt = 3, /obj/item/clothing/head/helmet/space/void/medical/alt = 3, /obj/item/clothing/mask/breath = 3, /obj/item/clothing/shoes/magboots = 3, /obj/item/weapon/tank/oxygen = 3 ) - /datum/supply_packs/voidsuits/security contains = list( - /obj/item/clothing/suit/space/void/security = 2, - /obj/item/clothing/suit/space/void/security/taur =1, + /obj/item/clothing/suit/space/void/security = 3, /obj/item/clothing/head/helmet/space/void/security = 3, /obj/item/clothing/mask/breath = 3, /obj/item/clothing/shoes/magboots = 3, @@ -51,8 +45,7 @@ /datum/supply_packs/voidsuits/security/crowd contains = list( - /obj/item/clothing/suit/space/void/security/riot = 2, - /obj/item/clothing/suit/space/void/security/riot/taur = 1, + /obj/item/clothing/suit/space/void/security/riot = 3, /obj/item/clothing/head/helmet/space/void/security/riot = 3, /obj/item/clothing/mask/breath = 3, /obj/item/clothing/shoes/magboots = 3, @@ -61,8 +54,7 @@ /datum/supply_packs/voidsuits/security/alt contains = list( - /obj/item/clothing/suit/space/void/security/alt = 2, - /obj/item/clothing/suit/space/void/security/alt/taur =1, + /obj/item/clothing/suit/space/void/security/alt = 3, /obj/item/clothing/head/helmet/space/void/security/alt = 3, /obj/item/clothing/mask/breath = 3, /obj/item/clothing/shoes/magboots = 3, @@ -72,8 +64,7 @@ /datum/supply_packs/voidsuits/supply name = "Mining voidsuits" contains = list( - /obj/item/clothing/suit/space/void/mining = 2, - /obj/item/clothing/suit/space/void/mining/taur = 1, + /obj/item/clothing/suit/space/void/mining = 3, /obj/item/clothing/head/helmet/space/void/mining = 3, /obj/item/clothing/mask/breath = 3, /obj/item/weapon/tank/oxygen = 3 diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 6a435ef388..ee0bdc05a7 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -36,6 +36,8 @@ name = "alarm" icon = 'icons/obj/monitors.dmi' icon_state = "alarm0" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER anchored = 1 use_power = 1 idle_power_usage = 80 @@ -804,6 +806,8 @@ FIRE ALARM desc = "\"Pull this in case of emergency\". Thus, keep pulling it forever." icon = 'icons/obj/monitors.dmi' icon_state = "fire0" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER var/detecting = 1.0 var/working = 1.0 var/time = 10.0 diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index d51b79ae48..cec980c54e 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -2,6 +2,8 @@ name = "button" icon = 'icons/obj/objects.dmi' icon_state = "launcherbtt" +// plane = TURF_PLANE //Can't have them under tables, oh well. +// layer = ABOVE_TURF_LAYER desc = "A remote control switch for something." var/id = null var/active = 0 diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 785abecbec..7c16309ec0 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -205,6 +205,8 @@ name = "Telescreen" desc = "Used for watching an empty arena." icon_state = "wallframe" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER icon_keyboard = null icon_screen = null light_range_on = 0 diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 3a70d57173..3345e30ab7 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -78,6 +78,8 @@ /obj/machinery/computer/guestpass name = "guest pass terminal" icon_state = "guest" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER icon_keyboard = null icon_screen = "pass" density = 0 diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index f7ab7e7a7e..6c68620644 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -197,13 +197,16 @@ var/obj/item/weapon/grab/grab = G if(!ismob(grab.affecting)) return + if(occupant) + to_chat(user,"\The [src] is already occupied by [occupant].") for(var/mob/living/simple_animal/slime/M in range(1,grab.affecting)) if(M.victim == grab.affecting) usr << "[grab.affecting.name] will not fit into the cryo because they have a slime latched onto their head." return var/mob/M = grab.affecting - if(put_mob(M)) - qdel(grab) + qdel(grab) + put_mob(M) + return /obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(var/mob/target, var/mob/user) //Allows borgs to put people into cryo without external assistance diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index ea4f8c1e69..a519394232 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -94,8 +94,8 @@ dat += "View storage log.
" if(allow_items) dat += "View objects.
" - dat += "Recover object.
" - dat += "Recover all objects.
" + //dat += "Recover object.
" //VOREStation Removal - Just log them. + //dat += "Recover all objects.
" //VOREStation Removal user << browse(dat, "window=cryopod_console") onclose(user, "cryopod_console") @@ -122,8 +122,10 @@ if(!allow_items) return var/dat = "Recently stored objects


" - for(var/obj/item/I in frozen_items) - dat += "[I.name]
" + //VOREStation Edit Start + for(var/I in frozen_items) + dat += "[I]
" + //VOREStation Edit End dat += "
" user << browse(dat, "window=cryoitems") @@ -240,7 +242,7 @@ on_store_name = "Robotic Storage Oversight" on_enter_occupant_message = "The storage unit broadcasts a sleep signal to you. Your systems start to shut down, and you enter low-power mode." allow_occupant_types = list(/mob/living/silicon/robot) - disallow_occupant_types = list(/mob/living/silicon/robot/drone) + //disallow_occupant_types = list(/mob/living/silicon/robot/drone) //VOREStation Removal - Why? How else do they leave? applies_stasis = 0 /obj/machinery/cryopod/robot/door @@ -429,12 +431,14 @@ if(!preserve) qdel(W) else + log_special_item(W,to_despawn) //VOREStation Add + /* VOREStation Removal - We do our own thing. if(control_computer && control_computer.allow_items) control_computer.frozen_items += W W.loc = control_computer //VOREStation Edit else W.forceMove(src.loc) - + VOREStation Removal End */ for(var/obj/structure/B in items) if(istype(B,/obj/structure/bed)) qdel(B) diff --git a/code/game/machinery/cryopod_vr.dm b/code/game/machinery/cryopod_vr.dm index 777574619e..d4b2f84220 100644 --- a/code/game/machinery/cryopod_vr.dm +++ b/code/game/machinery/cryopod_vr.dm @@ -31,4 +31,30 @@ /obj/machinery/computer/cryopod/dorms name = "residential oversight console" desc = "An interface between visitors and the residential oversight systems tasked with keeping track of all visitors in the residential district." -*/ \ No newline at end of file +*/ + +/obj/machinery/cryopod/proc/log_special_item(var/atom/movable/item,var/mob/to_despawn) + ASSERT(item && to_despawn) + + var/loaded_from_key + var/char_name = to_despawn.name + var/item_name = item.name + + // Best effort key aquisition + if(ishuman(to_despawn)) + var/mob/living/carbon/human/H = to_despawn + if(H.original_player) + loaded_from_key = H.original_player + + if(!loaded_from_key && to_despawn.mind && to_despawn.mind.loaded_from_ckey) + loaded_from_key = to_despawn.mind.loaded_from_ckey + + else + loaded_from_key = "INVALID" + + // Log to harrass them later + log_game("CRYO [loaded_from_key]/([to_despawn.name]) cryo'd with [item_name] ([item.type])") + qdel(item) + + if(control_computer && control_computer.allow_items) + control_computer.frozen_items += "[item_name] ([char_name])" diff --git a/code/game/machinery/doors/firedoor_vr.dm b/code/game/machinery/doors/firedoor_vr.dm index d15e435e69..2bc297a041 100644 --- a/code/game/machinery/doors/firedoor_vr.dm +++ b/code/game/machinery/doors/firedoor_vr.dm @@ -2,6 +2,15 @@ name = "\improper Emergency Shutter System" desc = "Emergency air-tight shutter, capable of sealing off breached areas. This model fits flush with the walls, and has a panel in the floor for maintenance." icon = 'icons/obj/doors/DoorHazardHidden.dmi' + plane = TURF_PLANE + +/obj/machinery/door/firedoor/glass/hidden/open() + . = ..() + plane = TURF_PLANE + +/obj/machinery/door/firedoor/glass/hidden/close() + . = ..() + plane = OBJ_PLANE /obj/machinery/door/firedoor/glass/hidden/steel name = "\improper Emergency Shutter System" diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 8c2c97f5a8..623cac6ef0 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -35,7 +35,8 @@ var/const/HOLOPAD_MODE = RANGE_BASED icon_state = "holopad0" show_messages = 1 circuit = /obj/item/weapon/circuitboard/holopad - layer = TURF_LAYER+0.1 //Preventing mice and drones from sneaking under them. + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER var/power_per_hologram = 500 //per usage per hologram idle_power_usage = 5 use_power = 1 diff --git a/code/game/machinery/kitchen/smartfridge_vr.dm b/code/game/machinery/kitchen/smartfridge_vr.dm new file mode 100644 index 0000000000..8b77e2f81d --- /dev/null +++ b/code/game/machinery/kitchen/smartfridge_vr.dm @@ -0,0 +1,32 @@ +/obj/machinery/smartfridge + var/expert_job = "Chef" +/obj/machinery/smartfridge/seeds + expert_job = "Botanist" +/obj/machinery/smartfridge/secure/extract + expert_job = "Xenobiologist" +/obj/machinery/smartfridge/secure/medbay + expert_job = "Chemist" +/obj/machinery/smartfridge/secure/virology + expert_job = "Medical Doctor" //Virologist is an alt-title unfortunately +/obj/machinery/smartfridge/chemistry + expert_job = "Chemist" //Unsure what this one is used for, actually +/obj/machinery/smartfridge/drinks + expert_job = "Bartender" + +// Allow thrown items into smartfridges +/obj/machinery/smartfridge/throw_impact(var/atom/movable/A) + . = ..() + if(accept_check(A) && A.thrower) + //Try to find what job they are via ID + var/obj/item/weapon/card/id/thrower_id + if(ismob(A.thrower)) + var/mob/T = A.thrower + thrower_id = T.GetIdCard() + + //98% chance the expert makes it + if(expert_job && thrower_id && thrower_id.rank == expert_job && prob(98)) + stock(A) + + //20% chance a non-expert makes it + else if(prob(20)) + stock(A) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index b9bd4a6855..048c1563b9 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -125,6 +125,8 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co desc = "A standard newsfeed handler for use on commercial space stations. All the news you absolutely have no use for, in one place!" icon = 'icons/obj/terminals.dmi' icon_state = "newscaster_normal" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER var/isbroken = 0 //1 if someone banged it with something heavy var/ispowered = 1 //starts powered, changes with power_change() //var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored. diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index c47d3738a0..3d2601b59d 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -249,6 +249,8 @@ obj/machinery/recharger name = "wall recharger" icon = 'icons/obj/stationobjs.dmi' icon_state = "wrecharger0" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER active_power_usage = 25000 //25 kW , It's more specialized than the standalone recharger (guns, batons, and flashlights only) so make it more powerful allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/gun/magnetic, /obj/item/weapon/melee/baton, /obj/item/device/flashlight, /obj/item/weapon/cell/device) icon_state_charged = "wrecharger2" diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 45e1a7315d..65583f3473 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -28,6 +28,8 @@ var/list/obj/machinery/requests_console/allConsoles = list() anchored = 1 icon = 'icons/obj/terminals.dmi' icon_state = "req_comp0" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER circuit = /obj/item/weapon/circuitboard/request var/department = "Unknown" //The list of all departments on the station (Determined from this variable on each unit) Set this to the same thing if you want several consoles in one department var/list/message_log = list() //List of all messages diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 9a02fddfd2..e3a00abb4d 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -12,6 +12,8 @@ /obj/machinery/status_display icon = 'icons/obj/status_display.dmi' icon_state = "frame" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER name = "status display" anchored = 1 density = 0 diff --git a/code/game/machinery/suit_storage_unit_vr.dm b/code/game/machinery/suit_storage_unit_vr.dm index abab98b8f1..964d80b258 100644 --- a/code/game/machinery/suit_storage_unit_vr.dm +++ b/code/game/machinery/suit_storage_unit_vr.dm @@ -1,2 +1,19 @@ /obj/machinery/suit_cycler - species = list("Human","Skrell","Unathi","Tajara", "Teshari", "Nevrean", "Akula", "Sergal", "Flatland Zorren", "Highlander Zorren", "Vulpkanin", "Promethean", "Xenomorph Hybrid", "Xenochimera","Vasilissan", "Rapala") //Added xenochimera while I was at it. Someone put in an issue about it. + species = list( + SPECIES_HUMAN, + SPECIES_SKRELL, + SPECIES_UNATHI, + SPECIES_TAJ, + SPECIES_TESHARI, + SPECIES_AKULA, + SPECIES_ALRAUNE, + SPECIES_NEVREAN, + SPECIES_RAPALA, + SPECIES_SERGAL, + SPECIES_VASILISSAN, + SPECIES_VULPKANIN, + SPECIES_XENOCHIMERA, + SPECIES_XENOHYBRID, + SPECIES_ZORREN_FLAT, + SPECIES_ZORREN_HIGH + ) diff --git a/code/game/mecha/micro/mecha_construction_paths_vr.dm b/code/game/mecha/micro/mecha_construction_paths_vr.dm new file mode 100644 index 0000000000..305cdfcf92 --- /dev/null +++ b/code/game/mecha/micro/mecha_construction_paths_vr.dm @@ -0,0 +1,768 @@ + +/datum/construction/mecha/polecat_chassis + steps = list(list("key"=/obj/item/mecha_parts/micro/part/polecat_torso),//1 + list("key"=/obj/item/mecha_parts/micro/part/polecat_left_arm),//2 + list("key"=/obj/item/mecha_parts/micro/part/polecat_right_arm),//3 + list("key"=/obj/item/mecha_parts/micro/part/polecat_left_leg),//4 + list("key"=/obj/item/mecha_parts/micro/part/polecat_right_leg)//5 + ) + + custom_action(step, atom/used_atom, mob/user) + user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + holder.overlays += used_atom.icon_state+"+o" + qdel(used_atom) + return 1 + + action(atom/used_atom,mob/user as mob) + return check_all_steps(used_atom,user) + + spawn_result() + var/obj/item/mecha_parts/chassis/const_holder = holder + const_holder.construct = new /datum/construction/reversible/mecha/polecat(const_holder) + const_holder.icon = 'icons/mecha/mech_construction_vr.dmi' + const_holder.icon_state = "polecat0" + const_holder.density = 1 + const_holder.overlays.len = 0 + spawn() + qdel(src) + return + + +/datum/construction/reversible/mecha/polecat + result = "/obj/mecha/micro/sec/polecat" + steps = list( + //1 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="External armor is wrenched."), + //2 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="External armor is installed."), + //3 + list("key"=/obj/item/mecha_parts/micro/part/polecat_armour, + "backkey"=/obj/item/weapon/weldingtool, + "desc"="Internal armor is welded."), + //4 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="Internal armor is wrenched"), + //5 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Internal armor is installed"), + //6 + list("key"=/obj/item/stack/material/steel, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Advanced capacitor is secured"), + //7 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Advanced capacitor is installed"), + //8 + list("key"=/obj/item/weapon/stock_parts/capacitor/adv, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Advanced scanner module is secured"), + //9 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Advanced scanner module is installed"), + //10 + list("key"=/obj/item/weapon/stock_parts/scanning_module/adv, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Targeting module is secured"), + //11 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Targeting module is installed"), + //12 + list("key"=/obj/item/weapon/circuitboard/mecha/polecat/targeting, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Peripherals control module is secured"), + //13 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Peripherals control module is installed"), + //14 + list("key"=/obj/item/weapon/circuitboard/mecha/polecat/peripherals, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Central control module is secured"), + //15 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Central control module is installed"), + //16 + list("key"=/obj/item/weapon/circuitboard/mecha/polecat/main, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is adjusted"), + //17 + list("key"=/obj/item/weapon/wirecutters, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is added"), + //18 + list("key"=/obj/item/stack/cable_coil, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The hydraulic systems are active."), + //19 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are connected."), + //20 + list("key"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are disconnected.") + ) + + + action(atom/used_atom,mob/user as mob) + return check_step(used_atom,user) + + custom_action(index, diff, atom/used_atom, mob/user) + if(!..()) + return 0 + //TODO: better messages. + switch(index) + if(20) + user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + holder.icon_state = "polecat1" + if(19) + if(diff==FORWARD) + user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + holder.icon_state = "polecat2" + else + user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + holder.icon_state = "polecat0" + if(18) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + holder.icon_state = "polecat3" + else + user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + holder.icon_state = "polecat1" + if(17) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + holder.icon_state = "polecat4" + else + user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) + coil.amount = 4 + holder.icon_state = "polecat2" + if(16) + if(diff==FORWARD) + user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + qdel(used_atom) + holder.icon_state = "polecat5" + else + user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + holder.icon_state = "polecat3" + if(15) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + holder.icon_state = "polecat6" + else + user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + new /obj/item/weapon/circuitboard/mecha/polecat/main(get_turf(holder)) + holder.icon_state = "polecat4" + if(14) + if(diff==FORWARD) + user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + qdel(used_atom) + holder.icon_state = "polecat7" + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + holder.icon_state = "polecat5" + if(13) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + holder.icon_state = "polecat8" + else + user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + new /obj/item/weapon/circuitboard/mecha/polecat/peripherals(get_turf(holder)) + holder.icon_state = "polecat6" + if(12) + if(diff==FORWARD) + user.visible_message("[user] installs the weapon control module into [holder].", "You install the weapon control module into [holder].") + qdel(used_atom) + holder.icon_state = "polecat9" + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + holder.icon_state = "polecat7" + if(11) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + holder.icon_state = "polecat10" + else + user.visible_message("[user] removes the weapon control module from [holder].", "You remove the weapon control module from [holder].") + new /obj/item/weapon/circuitboard/mecha/polecat/targeting(get_turf(holder)) + holder.icon_state = "polecat8" + if(10) + if(diff==FORWARD) + user.visible_message("[user] installs advanced scanner module to [holder].", "You install advanced scanner module to [holder].") + qdel(used_atom) + holder.icon_state = "polecat11" + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + holder.icon_state = "polecat9" + if(9) + if(diff==FORWARD) + user.visible_message("[user] secures the advanced scanner module.", "You secure the advanced scanner module.") + holder.icon_state = "polecat12" + else + user.visible_message("[user] removes the advanced scanner module from [holder].", "You remove the advanced scanner module from [holder].") + new /obj/item/weapon/stock_parts/scanning_module/adv(get_turf(holder)) + holder.icon_state = "polecat10" + if(8) + if(diff==FORWARD) + user.visible_message("[user] installs advanced capacitor to [holder].", "You install advanced capacitor to [holder].") + qdel(used_atom) + holder.icon_state = "polecat13" + else + user.visible_message("[user] unfastens the advanced scanner module.", "You unfasten the advanced scanner module.") + holder.icon_state = "polecat11" + if(7) + if(diff==FORWARD) + user.visible_message("[user] secures the advanced capacitor.", "You secure the advanced capacitor.") + holder.icon_state = "polecat14" + else + user.visible_message("[user] removes the advanced capacitor from [holder].", "You remove the advanced capacitor from [holder].") + new /obj/item/weapon/stock_parts/capacitor/adv(get_turf(holder)) + holder.icon_state = "polecat12" + if(6) + if(diff==FORWARD) + user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + holder.icon_state = "polecat15" + else + user.visible_message("[user] unfastens the advanced capacitor.", "You unfasten the advanced capacitor.") + holder.icon_state = "polecat13" + if(5) + if(diff==FORWARD) + user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + holder.icon_state = "polecat16" + else + user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].") + var/obj/item/stack/material/steel/MS = new /obj/item/stack/material/steel(get_turf(holder)) + MS.amount = 3 + holder.icon_state = "polecat14" + if(4) + if(diff==FORWARD) + user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + holder.icon_state = "polecat17" + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + holder.icon_state = "polecat15" + if(3) + if(diff==FORWARD) + user.visible_message("[user] installs external reinforced armor layer to [holder].", "You install external reinforced armor layer to [holder].") + holder.icon_state = "polecat18" + else + user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + holder.icon_state = "polecat16" + if(2) + if(diff==FORWARD) + user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.") + holder.icon_state = "polecat19" + else + user.visible_message("[user] pries external armor layer from [holder].", "You prie external armor layer from [holder].") + var/obj/item/stack/material/plasteel/MS = new /obj/item/stack/material/plasteel(get_turf(holder)) + MS.amount = 5 + holder.icon_state = "polecat17" + if(1) + if(diff==FORWARD) + user.visible_message("[user] welds external armor layer to [holder].", "You weld external armor layer to [holder].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + holder.icon_state = "polecat18" + return 1 + + spawn_result() + ..() + feedback_inc("mecha_polecat_created",1) + return + +/datum/construction/mecha/gopher_chassis + steps = list(list("key"=/obj/item/mecha_parts/micro/part/gopher_torso),//1 + list("key"=/obj/item/mecha_parts/micro/part/gopher_left_arm),//2 + list("key"=/obj/item/mecha_parts/micro/part/gopher_right_arm),//3 + list("key"=/obj/item/mecha_parts/micro/part/gopher_left_leg),//4 + list("key"=/obj/item/mecha_parts/micro/part/gopher_right_leg)//5 + ) + + custom_action(step, atom/used_atom, mob/user) + user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + holder.overlays += used_atom.icon_state+"+o" + qdel(used_atom) + return 1 + + action(atom/used_atom,mob/user as mob) + return check_all_steps(used_atom,user) + + spawn_result() + var/obj/item/mecha_parts/chassis/const_holder = holder + const_holder.construct = new /datum/construction/reversible/mecha/gopher(const_holder) + const_holder.icon = 'icons/mecha/mech_construction_vr.dmi' + const_holder.icon_state = "gopher0" + const_holder.density = 1 + const_holder.overlays.len = 0 + spawn() + qdel(src) + return + + +/datum/construction/reversible/mecha/gopher + result = "/obj/mecha/micro/utility/gopher" + steps = list( + //1 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="External armor is wrenched."), + //2 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="External armor is installed."), + //3 + list("key"=/obj/item/stack/material/plasteel, + "backkey"=/obj/item/weapon/weldingtool, + "desc"="Internal armor is welded."), + //4 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="Internal armor is wrenched"), + //5 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Internal armor is installed"), + //6 + list("key"=/obj/item/stack/material/steel, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Peripherals control module is secured"), + //7 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Peripherals control module is installed"), + //8 + list("key"=/obj/item/weapon/circuitboard/mecha/gopher/peripherals, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Central control module is secured"), + //9 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Central control module is installed"), + //10 + list("key"=/obj/item/weapon/circuitboard/mecha/gopher/main, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is adjusted"), + //11 + list("key"=/obj/item/weapon/wirecutters, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is added"), + //12 + list("key"=/obj/item/stack/cable_coil, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The hydraulic systems are active."), + //13 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are connected."), + //14 + list("key"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are disconnected.") + ) + + action(atom/used_atom,mob/user as mob) + return check_step(used_atom,user) + + custom_action(index, diff, atom/used_atom, mob/user) + if(!..()) + return 0 + + //TODO: better messages. + switch(index) + if(14) + user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + holder.icon_state = "gopher1" + if(13) + if(diff==FORWARD) + user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + holder.icon_state = "gopher2" + else + user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + holder.icon_state = "gopher0" + if(12) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + holder.icon_state = "gopher3" + else + user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + holder.icon_state = "gopher1" + if(11) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + holder.icon_state = "gopher4" + else + user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) + coil.amount = 4 + holder.icon_state = "gopher2" + if(10) + if(diff==FORWARD) + user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + qdel(used_atom) + holder.icon_state = "gopher5" + else + user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + holder.icon_state = "gopher3" + if(9) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + holder.icon_state = "gopher6" + else + user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + new /obj/item/weapon/circuitboard/mecha/gopher/main(get_turf(holder)) + holder.icon_state = "gopher4" + if(8) + if(diff==FORWARD) + user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + qdel(used_atom) + holder.icon_state = "gopher7" + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + holder.icon_state = "gopher5" + if(7) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + holder.icon_state = "gopher8" + else + user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + new /obj/item/weapon/circuitboard/mecha/gopher/peripherals(get_turf(holder)) + holder.icon_state = "gopher6" + if(6) + if(diff==FORWARD) + user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + holder.icon_state = "gopher9" + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + holder.icon_state = "gopher7" + if(5) + if(diff==FORWARD) + user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + holder.icon_state = "gopher10" + else + user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].") + var/obj/item/stack/material/steel/MS = new /obj/item/stack/material/steel(get_turf(holder)) + MS.amount = 3 + holder.icon_state = "gopher8" + if(4) + if(diff==FORWARD) + user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + holder.icon_state = "gopher11" + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + holder.icon_state = "gopher9" + if(3) + if(diff==FORWARD) + user.visible_message("[user] installs external reinforced armor layer to [holder].", "You install external reinforced armor layer to [holder].") + holder.icon_state = "gopher12" + else + user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + holder.icon_state = "gopher10" + if(2) + if(diff==FORWARD) + user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.") + holder.icon_state = "gopher13" + else + user.visible_message("[user] pries external armor layer from [holder].", "You prie external armor layer from [holder].") + var/obj/item/stack/material/plasteel/MS = new /obj/item/stack/material/plasteel(get_turf(holder)) + MS.amount = 2 + holder.icon_state = "gopher11" + if(1) + if(diff==FORWARD) + user.visible_message("[user] welds external armor layer to [holder].", "You weld external armor layer to [holder].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + holder.icon_state = "gopher12" + return 1 + + spawn_result() + ..() + feedback_inc("mecha_gopher_created",1) + return + +/datum/construction/mecha/weasel_chassis + steps = list(list("key"=/obj/item/mecha_parts/micro/part/weasel_torso),//1 + list("key"=/obj/item/mecha_parts/micro/part/weasel_head),//2 + list("key"=/obj/item/mecha_parts/micro/part/weasel_left_arm),//3 + list("key"=/obj/item/mecha_parts/micro/part/weasel_right_arm),//4 + list("key"=/obj/item/mecha_parts/micro/part/weasel_tri_leg),//5 + ) + + custom_action(step, atom/used_atom, mob/user) + user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + holder.overlays += used_atom.icon_state+"+o" + qdel(used_atom) + return 1 + + action(atom/used_atom,mob/user as mob) + return check_all_steps(used_atom,user) + + spawn_result() + var/obj/item/mecha_parts/chassis/const_holder = holder + const_holder.construct = new /datum/construction/reversible/mecha/weasel(const_holder) + const_holder.icon = 'icons/mecha/mech_construction_vr.dmi' + const_holder.icon_state = "weasel0" + const_holder.density = 1 + const_holder.overlays.len = 0 + spawn() + qdel(src) + return + + +/datum/construction/reversible/mecha/weasel + result = "/obj/mecha/micro/sec/weasel" + steps = list( + //1 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="External armor is wrenched."), + //2 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="External armor is installed."), + //3 + list("key"=/obj/item/stack/material/plasteel, + "backkey"=/obj/item/weapon/weldingtool, + "desc"="Internal armor is welded."), + //4 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="Internal armor is wrenched"), + //5 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Internal armor is installed"), + //6 + list("key"=/obj/item/stack/material/steel, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Advanced capacitor is secured"), + //7 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Advanced capacitor is installed"), + //8 + list("key"=/obj/item/weapon/stock_parts/capacitor/adv, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Advanced scanner module is secured"), + //9 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Advanced scanner module is installed"), + //10 + list("key"=/obj/item/weapon/stock_parts/scanning_module/adv, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Targeting module is secured"), + //11 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Targeting module is installed"), + //12 + list("key"=/obj/item/weapon/circuitboard/mecha/weasel/targeting, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Peripherals control module is secured"), + //13 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Peripherals control module is installed"), + //14 + list("key"=/obj/item/weapon/circuitboard/mecha/weasel/peripherals, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Central control module is secured"), + //15 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Central control module is installed"), + //16 + list("key"=/obj/item/weapon/circuitboard/mecha/weasel/main, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is adjusted"), + //17 + list("key"=/obj/item/weapon/wirecutters, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is added"), + //18 + list("key"=/obj/item/stack/cable_coil, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The hydraulic systems are active."), + //19 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are connected."), + //20 + list("key"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are disconnected.") + ) + + + action(atom/used_atom,mob/user as mob) + return check_step(used_atom,user) + + custom_action(index, diff, atom/used_atom, mob/user) + if(!..()) + return 0 + //TODO: better messages. + switch(index) + if(20) + user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + holder.icon_state = "weasel1" + if(19) + if(diff==FORWARD) + user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + holder.icon_state = "weasel2" + else + user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + holder.icon_state = "weasel0" + if(18) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + holder.icon_state = "weasel3" + else + user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + holder.icon_state = "weasel1" + if(17) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + holder.icon_state = "weasel4" + else + user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) + coil.amount = 4 + holder.icon_state = "weasel2" + if(16) + if(diff==FORWARD) + user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + qdel(used_atom) + holder.icon_state = "weasel5" + else + user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + holder.icon_state = "weasel3" + if(15) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + holder.icon_state = "weasel6" + else + user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + new /obj/item/weapon/circuitboard/mecha/weasel/main(get_turf(holder)) + holder.icon_state = "weasel4" + if(14) + if(diff==FORWARD) + user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + qdel(used_atom) + holder.icon_state = "weasel7" + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + holder.icon_state = "weasel5" + if(13) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + holder.icon_state = "weasel8" + else + user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + new /obj/item/weapon/circuitboard/mecha/weasel/peripherals(get_turf(holder)) + holder.icon_state = "weasel6" + if(12) + if(diff==FORWARD) + user.visible_message("[user] installs the weapon control module into [holder].", "You install the weapon control module into [holder].") + qdel(used_atom) + holder.icon_state = "weasel9" + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + holder.icon_state = "weasel7" + if(11) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + holder.icon_state = "weasel10" + else + user.visible_message("[user] removes the weapon control module from [holder].", "You remove the weapon control module from [holder].") + new /obj/item/weapon/circuitboard/mecha/weasel/targeting(get_turf(holder)) + holder.icon_state = "weasel8" + if(10) + if(diff==FORWARD) + user.visible_message("[user] installs advanced scanner module to [holder].", "You install advanced scanner module to [holder].") + qdel(used_atom) + holder.icon_state = "weasel11" + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + holder.icon_state = "weasel9" + if(9) + if(diff==FORWARD) + user.visible_message("[user] secures the advanced scanner module.", "You secure the advanced scanner module.") + holder.icon_state = "weasel12" + else + user.visible_message("[user] removes the advanced scanner module from [holder].", "You remove the advanced scanner module from [holder].") + new /obj/item/weapon/stock_parts/scanning_module/adv(get_turf(holder)) + holder.icon_state = "weasel10" + if(8) + if(diff==FORWARD) + user.visible_message("[user] installs advanced capacitor to [holder].", "You install advanced capacitor to [holder].") + qdel(used_atom) + holder.icon_state = "weasel13" + else + user.visible_message("[user] unfastens the advanced scanner module.", "You unfasten the advanced scanner module.") + holder.icon_state = "weasel11" + if(7) + if(diff==FORWARD) + user.visible_message("[user] secures the advanced capacitor.", "You secure the advanced capacitor.") + holder.icon_state = "weasel14" + else + user.visible_message("[user] removes the advanced capacitor from [holder].", "You remove the advanced capacitor from [holder].") + new /obj/item/weapon/stock_parts/capacitor/adv(get_turf(holder)) + holder.icon_state = "weasel12" + if(6) + if(diff==FORWARD) + user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + holder.icon_state = "weasel15" + else + user.visible_message("[user] unfastens the advanced capacitor.", "You unfasten the advanced capacitor.") + holder.icon_state = "weasel13" + if(5) + if(diff==FORWARD) + user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + holder.icon_state = "weasel16" + else + user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].") + var/obj/item/stack/material/steel/MS = new /obj/item/stack/material/steel(get_turf(holder)) + MS.amount = 3 + holder.icon_state = "weasel14" + if(4) + if(diff==FORWARD) + user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + holder.icon_state = "weasel17" + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + holder.icon_state = "weasel15" + if(3) + if(diff==FORWARD) + user.visible_message("[user] installs external reinforced armor layer to [holder].", "You install external reinforced armor layer to [holder].") + holder.icon_state = "weasel18" + else + user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + holder.icon_state = "weasel16" + if(2) + if(diff==FORWARD) + user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.") + holder.icon_state = "weasel19" + else + user.visible_message("[user] pries external armor layer from [holder].", "You prie external armor layer from [holder].") + var/obj/item/stack/material/plasteel/MS = new /obj/item/stack/material/plasteel(get_turf(holder)) + MS.amount = 3 + holder.icon_state = "weasel17" + if(1) + if(diff==FORWARD) + user.visible_message("[user] welds external armor layer to [holder].", "You weld external armor layer to [holder].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + holder.icon_state = "weasel18" + return 1 + + spawn_result() + ..() + feedback_inc("mecha_weasel_created",1) + return diff --git a/code/game/mecha/micro/mecha_parts_vr.dm b/code/game/mecha/micro/mecha_parts_vr.dm new file mode 100644 index 0000000000..f16442abf7 --- /dev/null +++ b/code/game/mecha/micro/mecha_parts_vr.dm @@ -0,0 +1,141 @@ +//new micro parts define + +/obj/item/mecha_parts/micro + name = "mecha part" + icon = 'icons/mecha/mech_construct_vr.dmi' + icon_state = "blank" + w_class = ITEMSIZE_NORMAL + + +/obj/item/mecha_parts/micro/chassis/ + name="Mecha Chassis" + icon_state = "backbone" + var/datum/construction/construct + flags = CONDUCT + + attackby(obj/item/W as obj, mob/user as mob) + if(!construct || !construct.action(W, user)) + ..() + return + + attack_hand() + return +//Gopher +/obj/item/mecha_parts/micro/chassis/gopher + name = "Gopher Chassis" + icon_state = "gopher-chassis" + + New() + ..() + construct = new /datum/construction/mecha/gopher_chassis(src) + +/obj/item/mecha_parts/micro/part/gopher_torso + name="Gopher Torso" + desc="A torso part of Gopher. Contains power unit, processing core and life support systems." + icon_state = "gopher-torso" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_ENGINEERING = 2) + +/obj/item/mecha_parts/micro/part/gopher_left_arm + name="Gopher Left Arm" + desc="A Gopher left arm. Data and power sockets are compatible with most exosuit tools." + icon_state = "gopher-arm-left" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + +/obj/item/mecha_parts/micro/part/gopher_right_arm + name="Gopher Right Arm" + desc="A Gopher right arm. Data and power sockets are compatible with most exosuit tools." + icon_state = "gopher-arm-right" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + +/obj/item/mecha_parts/micro/part/gopher_left_leg + name="Gopher Left Leg" + desc="A Gopher left leg. Contains somewhat complex servodrives and balance maintaining systems." + icon_state = "gopher-leg-left" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + +/obj/item/mecha_parts/micro/part/gopher_right_leg + name="Gopher Right Leg" + desc="A Gopher right leg. Contains somewhat complex servodrives and balance maintaining systems." + icon_state = "gopher-leg-right" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + +//polecat +/obj/item/mecha_parts/micro/chassis/polecat + name = "Polecat Chassis" + icon_state = "polecat-chassis" + New() + ..() + construct = new /datum/construction/mecha/polecat_chassis(src) + +/obj/item/mecha_parts/micro/part/polecat_torso + name="Polecat Torso" + icon_state = "polecat-torso" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_BIO = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/polecat_left_arm + name="Polecat Left Arm" + icon_state = "polecat-arm-left" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/polecat_right_arm + name="Polecat Right Arm" + icon_state = "polecat-arm-right" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/polecat_left_leg + name="Polecat Left Leg" + icon_state = "polecat-leg-left" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/polecat_right_leg + name="Polecat Right Leg" + icon_state = "polecat-leg-right" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/polecat_armour + name="Polecat Armour Plates" + icon_state = "polecat-armor" + origin_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 4, TECH_ENGINEERING = 5) + +//weasel +/obj/item/mecha_parts/micro/chassis/weasel + name = "Weasel Chassis" + icon_state = "weasel-chassis" + New() + ..() + construct = new /datum/construction/mecha/weasel_chassis(src) + +/obj/item/mecha_parts/micro/part/weasel_torso + name="Weasel Torso" + icon_state = "weasel-torso" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_BIO = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/weasel_head + name="Weasel Head" + icon_state = "weasel-head" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_MAGNET = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/weasel_left_arm + name="Weasel Left Arm" + icon_state = "weasel-arm-left" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/weasel_right_arm + name="Weasel Right Arm" + icon_state = "weasel-arm-right" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/*/obj/item/mecha_parts/micro/part/weasel_left_leg + name="Weasel Left Leg" + icon_state = "weasel-leg-left" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/obj/item/mecha_parts/micro/part/weasel_right_leg + name="Weasel Right Leg" + icon_state = "weasel-leg-right" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3)*/ + +/obj/item/mecha_parts/micro/part/weasel_tri_leg + name="Weasel Legs" + icon_state = "weasel-leg-all" + origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 3, TECH_ENGINEERING = 3) \ No newline at end of file diff --git a/code/game/mecha/micro/mecha_vr.dm b/code/game/mecha/micro/mecha_vr.dm new file mode 100644 index 0000000000..fee3afb2a6 --- /dev/null +++ b/code/game/mecha/micro/mecha_vr.dm @@ -0,0 +1,47 @@ +#ifdef T_BOARD_MICRO_MECHA +#error T_BOARD_MICRO_MECHA already defined elsewhere, we can't use it. +#endif +#define T_BOARD_MICRO_MECHA(name) "exosuit module circuit board (" + (name) + ")" + +/obj/item/weapon/circuitboard/mecha/gopher + origin_tech = list(TECH_DATA = 3) + +/obj/item/weapon/circuitboard/mecha/gopher/peripherals + name = T_BOARD_MICRO_MECHA("Gopher peripherals control") + icon_state = "mcontroller" + +/obj/item/weapon/circuitboard/mecha/gopher/main + name = T_BOARD_MICRO_MECHA("Gopher central control") + icon_state = "mainboard" + +/obj/item/weapon/circuitboard/mecha/polecat + origin_tech = list(TECH_DATA = 4) + +/obj/item/weapon/circuitboard/mecha/polecat/peripherals + name = T_BOARD_MICRO_MECHA("Polecat peripherals control") + icon_state = "mcontroller" + +/obj/item/weapon/circuitboard/mecha/polecat/targeting + name = T_BOARD_MICRO_MECHA("Polecat weapon control and targeting") + icon_state = "mcontroller" + origin_tech = list(TECH_DATA = 4, TECH_COMBAT = 4) + +/obj/item/weapon/circuitboard/mecha/polecat/main + name = T_BOARD_MICRO_MECHA("Weasel central control") + icon_state = "mainboard" + +/obj/item/weapon/circuitboard/mecha/weasel + origin_tech = list(TECH_DATA = 4) + +/obj/item/weapon/circuitboard/mecha/weasel/peripherals + name = T_BOARD_MICRO_MECHA("Weasel peripherals control") + icon_state = "mcontroller" + +/obj/item/weapon/circuitboard/mecha/weasel/targeting + name = T_BOARD_MICRO_MECHA("Weasel weapon control and targeting") + icon_state = "mcontroller" + origin_tech = list(TECH_DATA = 4, TECH_COMBAT = 4) + +/obj/item/weapon/circuitboard/mecha/weasel/main + name = T_BOARD_MICRO_MECHA("Weasel central control") + icon_state = "mainboard" diff --git a/code/game/mecha/micro/mechfab_designs_vr.dm b/code/game/mecha/micro/mechfab_designs_vr.dm new file mode 100644 index 0000000000..940d7607e3 --- /dev/null +++ b/code/game/mecha/micro/mechfab_designs_vr.dm @@ -0,0 +1,187 @@ +/datum/design/item/mechfab/gopher + category = "Gopher" + time = 5 + +/datum/design/item/mechfab/gopher/chassis + name = "Gopher Chassis" + id = "gopher_chassis" + build_path = /obj/item/mecha_parts/micro/chassis/gopher + time = 3 + materials = list(DEFAULT_WALL_MATERIAL = 7000) + +/datum/design/item/mechfab/gopher/torso + name = "Gopher Torso" + id = "gopher_torso" + build_path = /obj/item/mecha_parts/micro/part/gopher_torso + materials = list(DEFAULT_WALL_MATERIAL = 15000, "glass" = 5250) + +/datum/design/item/mechfab/gopher/left_arm + name = "Gopher Left Arm" + id = "gopher_left_arm" + build_path = /obj/item/mecha_parts/micro/part/gopher_left_arm + materials = list(DEFAULT_WALL_MATERIAL = 8750) + +/datum/design/item/mechfab/gopher/right_arm + name = "Gopher Right Arm" + id = "gopher_right_arm" + build_path = /obj/item/mecha_parts/micro/part/gopher_right_arm + + materials = list(DEFAULT_WALL_MATERIAL = 8750) + +/datum/design/item/mechfab/gopher/left_leg + name = "Gopher Left Leg" + id = "gopher_left_leg" + build_path = /obj/item/mecha_parts/micro/part/gopher_left_leg + materials = list(DEFAULT_WALL_MATERIAL = 12500) + +/datum/design/item/mechfab/gopher/right_leg + name = "Gopher Right Leg" + id = "gopher_right_leg" + build_path = /obj/item/mecha_parts/micro/part/gopher_right_leg + materials = list(DEFAULT_WALL_MATERIAL = 12500) + +/datum/design/item/mecha/drill/micro + name = "Miniature Drill" + id = "micro_drill" + build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill/micro + time = 5 + materials = list(DEFAULT_WALL_MATERIAL = 2500) + +/datum/design/item/mecha/hydraulic_clamp/micro + name = "Mounted ore box" + id = "ore_scoop" + build_path = /obj/item/mecha_parts/mecha_equipment/tool/micro/orescoop + time = 5 + materials = list(DEFAULT_WALL_MATERIAL = 2500) + +/datum/design/item/mechfab/polecat + category = "Polecat" + time = 10 + +/datum/design/item/mechfab/polecat/chassis + name = "Polecat Chassis" + id = "polecat_chassis" + build_path = /obj/item/mecha_parts/micro/chassis/polecat + time = 3 + materials = list(DEFAULT_WALL_MATERIAL = 7000) + +/datum/design/item/mechfab/polecat/torso + name = "Polecat Torso" + id = "polecat_torso" + build_path = /obj/item/mecha_parts/micro/part/polecat_torso + materials = list(DEFAULT_WALL_MATERIAL = 15000, "glass" = 5250) + +/datum/design/item/mechfab/polecat/left_arm + name = "Polecat Left Arm" + id = "polecat_left_arm" + build_path = /obj/item/mecha_parts/micro/part/polecat_left_arm + materials = list(DEFAULT_WALL_MATERIAL = 8750) + +/datum/design/item/mechfab/polecat/right_arm + name = "Polecat Right Arm" + id = "polecat_right_arm" + build_path = /obj/item/mecha_parts/micro/part/polecat_right_arm + materials = list(DEFAULT_WALL_MATERIAL = 8750) + +/datum/design/item/mechfab/polecat/left_leg + name = "Polecat Left Leg" + id = "polecat_left_leg" + build_path = /obj/item/mecha_parts/micro/part/polecat_left_leg + materials = list(DEFAULT_WALL_MATERIAL = 12500) + +/datum/design/item/mechfab/polecat/right_leg + name = "Polecat Right Leg" + id = "polecat_right_leg" + build_path = /obj/item/mecha_parts/micro/part/polecat_right_leg + materials = list(DEFAULT_WALL_MATERIAL = 12500) + +/datum/design/item/mechfab/polecat/armour + name = "Polecat Armour Plates" + id = "polecat_armour" + build_path = /obj/item/mecha_parts/micro/part/polecat_armour + time = 25 + materials = list(DEFAULT_WALL_MATERIAL = 12500, "plastic" = 7500) + +/datum/design/item/mecha/taser/micro + name = "\improper TS-12 \"Suppressor\" integrated taser" + id = "micro_taser" + build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/microtaser + +/datum/design/item/mecha/weapon/laser/micro + name = "\improper WS-19 \"Torch\" laser carbine" + id = "micro_laser" +// req_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 3) + build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/microlaser + +/datum/design/item/mecha/weapon/laser_heavy/micro + name = "\improper PC-20 \"Lance\" light laser cannon" + id = "micro_laser_heavy" + req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 1000, "diamond" = 2000) + build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/microheavy + +/datum/design/item/mecha/weapon/grenade_launcher/micro + name = "\improper FP-20 mounted grenade launcher" + id = "micro_flashbang_launcher" +// req_tech = list(TECH_COMBAT = 3) + build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/microflashbang + +/datum/design/item/mecha/weapon/scattershot/micro + name = "\improper Remington C-12 \"Boomstick\"" + desc = "A mounted combat shotgun with integrated ammo-lathe." + id = "micro_scattershot" +// req_tech = list(TECH_COMBAT = 4) + build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/microshotgun + +/datum/design/item/mechfab/weasel + category = "Weasel" + time = 5 + +/datum/design/item/mechfab/weasel/chassis + name = "Weasel Chassis" + id = "weasel_chassis" + build_path = /obj/item/mecha_parts/micro/chassis/weasel + time = 3 + materials = list(DEFAULT_WALL_MATERIAL = 7000) + +/datum/design/item/mechfab/weasel/torso + name = "Weasel Torso" + id = "weasel_torso" + build_path = /obj/item/mecha_parts/micro/part/weasel_torso + materials = list(DEFAULT_WALL_MATERIAL = 15000, "glass" = 5250) + +/datum/design/item/mechfab/weasel/left_arm + name = "Weasel Left Arm" + id = "weasel_left_arm" + build_path = /obj/item/mecha_parts/micro/part/weasel_left_arm + materials = list(DEFAULT_WALL_MATERIAL = 8750) + +/datum/design/item/mechfab/weasel/right_arm + name = "Weasel Right Arm" + id = "weasel_right_arm" + build_path = /obj/item/mecha_parts/micro/part/weasel_right_arm + materials = list(DEFAULT_WALL_MATERIAL = 8750) + +/*/datum/design/item/mechfab/weasel/left_leg + name = "Weasel Left Leg" + id = "weasel_left_leg" + build_path = /obj/item/mecha_parts/micro/part/weasel_left_leg + materials = list(DEFAULT_WALL_MATERIAL = 12500) + +/datum/design/item/mechfab/weasel/right_leg + name = "Weasel Right Leg" + id = "weasel_right_leg" + build_path = /obj/item/mecha_parts/micro/part/weasel_right_leg + materials = list(DEFAULT_WALL_MATERIAL = 12500)*/ + +/datum/design/item/mechfab/weasel/tri_leg + name = "Weasel Tri Leg" + id = "weasel_right_leg" + build_path = /obj/item/mecha_parts/micro/part/weasel_tri_leg + materials = list(DEFAULT_WALL_MATERIAL = 27500) + +/datum/design/item/mechfab/weasel/head + name = "Weasel Head" + id = "weasel_head" + build_path = /obj/item/mecha_parts/micro/part/weasel_head + materials = list(DEFAULT_WALL_MATERIAL = 7000, "glass" = 2500) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index eb3ac7cb12..5bc75ca2a0 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -3,6 +3,8 @@ desc = "Talk through this." icon = 'icons/obj/radio_vr.dmi' //VOREStation Edit - New Icon icon_state = "intercom" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER anchored = 1 w_class = ITEMSIZE_LARGE canhear_range = 2 diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm index 4a67bffe56..7a7828ef95 100644 --- a/code/game/objects/items/devices/whistle.dm +++ b/code/game/objects/items/devices/whistle.dm @@ -27,8 +27,8 @@ use_message = capitalize(copytext(sanitize(new_message), 1, MAX_MESSAGE_LEN)) usr << "You configure the hailer to shout \"[use_message]\"." -/ -obj/item/device/hailer/attack_self(mob/living/carbon/user as mob) + +/obj/item/device/hailer/attack_self(mob/living/carbon/user as mob) if (spamcheck) return diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index bbb8171b10..7248950a0f 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -29,7 +29,7 @@ icon_state = "unathiknife" attack_verb = list("ripped", "torn", "cut") can_cleave = FALSE - var hits = 0 + var/hits = 0 /obj/item/weapon/material/knife/machete/hatchet/unathiknife/attack(mob/M as mob, mob/user as mob) if(hits > 0) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 1bc9fa761d..0a1f358eb4 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -450,7 +450,7 @@ item_state_slots = list(slot_r_hand_str = "medicalpack", slot_l_hand_str = "medicalpack") foldable = null max_w_class = ITEMSIZE_NORMAL - can_hold = list(/obj/item/organ, /obj/item/weapon/reagent_containers/food, /obj/item/weapon/reagent_containers/glass) + can_hold = list(/obj/item/organ) max_storage_space = ITEMSIZE_COST_NORMAL * 5 // Formally 21. Odd numbers are bad. use_to_pickup = 1 // for picking up broken bulbs, not that most people will try diff --git a/code/game/objects/items/weapons/traps_vr.dm b/code/game/objects/items/weapons/traps_vr.dm new file mode 100644 index 0000000000..f1338f691d --- /dev/null +++ b/code/game/objects/items/weapons/traps_vr.dm @@ -0,0 +1,18 @@ +/obj/item/weapon/beartrap + slot_flags = SLOT_MASK + item_icons = list( + slot_wear_mask_str = 'icons/mob/mask_vr.dmi' + ) + +/obj/item/weapon/beartrap/equipped() + if(ishuman(src.loc)) + var/mob/living/carbon/human/H = src.loc + if(H.wear_mask == src) + H.verbs |= /mob/living/proc/shred_limb_temp + else + H.verbs -= /mob/living/proc/shred_limb_temp + ..() + +/obj/item/weapon/beartrap/dropped(var/mob/user) + user.verbs -= /mob/living/proc/shred_limb_temp + ..() \ No newline at end of file diff --git a/code/game/objects/random/guns_and_ammo.dm b/code/game/objects/random/guns_and_ammo.dm index a910881a76..62dde5a3df 100644 --- a/code/game/objects/random/guns_and_ammo.dm +++ b/code/game/objects/random/guns_and_ammo.dm @@ -1,6 +1,16 @@ +/obj/random/gun/random + name = "Random Weapon" + desc = "This is a random energy or ballistic weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "energystun100" + +/obj/random/gun/random/item_to_spawn() + return pick(prob(5);/obj/random/energy, + prob(5);/obj/random/projectile/random) + /obj/random/energy name = "Random Energy Weapon" - desc = "This is a random security weapon." + desc = "This is a random weapon." icon = 'icons/obj/gun.dmi' icon_state = "energykill100" @@ -83,6 +93,18 @@ prob(2);/obj/item/weapon/gun/projectile/automatic/wt550, prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat) +/obj/random/projectile/shotgun + name = "Random Projectile Weapon" + desc = "This is a random projectile weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "shotgun" + +/obj/random/projectile/item_to_spawn() + return pick(prob(4);/obj/item/weapon/gun/projectile/shotgun/doublebarrel, + prob(3);/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn, + prob(3);/obj/item/weapon/gun/projectile/shotgun/pump, + prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat) + /obj/random/handgun name = "Random Handgun" desc = "This is a random sidearm." @@ -126,4 +148,256 @@ prob(4);/obj/item/ammo_magazine/m45/rubber, prob(4);/obj/item/ammo_magazine/m45/flash, prob(2);/obj/item/ammo_magazine/m9mmt, - prob(6);/obj/item/ammo_magazine/m9mmt/rubber) \ No newline at end of file + prob(6);/obj/item/ammo_magazine/m9mmt/rubber) + +/obj/random/projectile/random + name = "Random Projectile Weapon" + desc = "This is a random weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "revolver" + +/obj/random/projectile/random/item_to_spawn() + return pick(prob(3);/obj/random/multiple/gun/projectile/handgun, + prob(2);/obj/random/multiple/gun/projectile/smg, + prob(2);/obj/random/multiple/gun/projectile/shotgun, + prob(1);/obj/random/multiple/gun/projectile/rifle) + +/obj/random/multiple/gun/projectile/smg + name = "random smg projectile gun" + desc = "Loot for PoIs." + icon = 'icons/obj/gun.dmi' + icon_state = "saber" + +/obj/random/multiple/gun/projectile/smg/item_to_spawn() + return pick( + prob(3);list( + /obj/item/weapon/gun/projectile/automatic/wt550, + /obj/item/ammo_magazine/m9mmt, + /obj/item/ammo_magazine/m9mmt + ), + prob(3);list( + /obj/item/weapon/gun/projectile/automatic/mini_uzi, + /obj/item/ammo_magazine/m45uzi, + /obj/item/ammo_magazine/m45uzi + ), + prob(3);list( + /obj/item/weapon/gun/projectile/automatic/tommygun, + /obj/item/ammo_magazine/m45tommy, + /obj/item/ammo_magazine/m45tommy + ), + prob(2);list( + /obj/item/weapon/gun/projectile/automatic/c20r, + /obj/item/ammo_magazine/m10mm, + /obj/item/ammo_magazine/m10mm + ), + prob(1);list( + /obj/item/weapon/gun/projectile/automatic/p90, + /obj/item/ammo_magazine/m9mmp90 + ) + ) + +/obj/random/multiple/gun/projectile/rifle + name = "random rifle projectile gun" + desc = "Loot for PoIs." + icon = 'icons/obj/gun.dmi' + icon_state = "carbine" + +//Concerns about the bullpup, but currently seems to be only a slightly stronger z8. But we shall see. + +/obj/random/multiple/gun/projectile/rifle/item_to_spawn() + return pick( + prob(2);list( + /obj/item/weapon/gun/projectile/automatic/sts35, + /obj/item/ammo_magazine/m545, + /obj/item/ammo_magazine/m545 + ), + prob(2);list( + /obj/item/weapon/gun/projectile/automatic/z8, + /obj/item/ammo_magazine/m762, + /obj/item/ammo_magazine/m762 + ), + prob(4);list( + /obj/item/weapon/gun/projectile/shotgun/pump/rifle, + /obj/item/ammo_magazine/clip/c762, + /obj/item/ammo_magazine/clip/c762 + ), + prob(3);list( + /obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever, + /obj/item/ammo_magazine/clip/c762, + /obj/item/ammo_magazine/clip/c762 + ), + prob(1);list( + /obj/item/weapon/gun/projectile/garand, + /obj/item/ammo_magazine/m762garand, + /obj/item/ammo_magazine/m762garand + ), + prob(1);list( + /obj/item/weapon/gun/projectile/automatic/bullpup, + /obj/item/ammo_magazine/m762, + /obj/item/ammo_magazine/m762 + ) + ) + +/obj/random/multiple/gun/projectile/handgun + name = "random handgun projectile gun" + desc = "Loot for PoIs." + icon = 'icons/obj/gun.dmi' + icon_state = "revolver" + +/obj/random/multiple/gun/projectile/handgun/item_to_spawn() + return pick( + prob(5);list( + /obj/item/weapon/gun/projectile/colt, + /obj/item/ammo_magazine/m45, + /obj/item/ammo_magazine/m45 + ), + prob(4);list( + /obj/item/weapon/gun/projectile/contender, + /obj/item/ammo_magazine/s357, + /obj/item/ammo_magazine/s357 + ), + prob(3);list( + /obj/item/weapon/gun/projectile/contender/tacticool, + /obj/item/ammo_magazine/s357, + /obj/item/ammo_magazine/s357 + ), + prob(2);list( + /obj/item/weapon/gun/projectile/deagle, + /obj/item/ammo_magazine/m44, + /obj/item/ammo_magazine/m44 + ), + prob(1);list( + /obj/item/weapon/gun/projectile/deagle/camo, + /obj/item/ammo_magazine/m44, + /obj/item/ammo_magazine/m44 + ), + prob(1);list( + /obj/item/weapon/gun/projectile/deagle/gold, + /obj/item/ammo_magazine/m44, + /obj/item/ammo_magazine/m44 + ), + prob(4);list( + /obj/item/weapon/gun/projectile/derringer, + /obj/item/ammo_magazine/s357, + /obj/item/ammo_magazine/s357 + ), + prob(5);list( + /obj/item/weapon/gun/projectile/luger, + /obj/item/ammo_magazine/m9mm/compact, + /obj/item/ammo_magazine/m9mm/compact + ), + prob(4);list( + /obj/item/weapon/gun/projectile/luger/brown, + /obj/item/ammo_magazine/m9mm/compact, + /obj/item/ammo_magazine/m9mm/compact + ), + prob(5);list( + /obj/item/weapon/gun/projectile/sec, + /obj/item/ammo_magazine/m45, + /obj/item/ammo_magazine/m45 + ), + prob(4);list( + /obj/item/weapon/gun/projectile/sec/wood, + /obj/item/ammo_magazine/m45, + /obj/item/ammo_magazine/m45 + ), + prob(5);list( + /obj/item/weapon/gun/projectile/p92x, + /obj/item/ammo_magazine/m9mm, + /obj/item/ammo_magazine/m9mm + ), + prob(4);list( + /obj/item/weapon/gun/projectile/p92x/brown, + /obj/item/ammo_magazine/m9mm, + /obj/item/ammo_magazine/m9mm + ), + prob(2);list( + /obj/item/weapon/gun/projectile/p92x/large, + /obj/item/ammo_magazine/m9mm/large, + /obj/item/ammo_magazine/m9mm/large + ), + prob(5);list( + /obj/item/weapon/gun/projectile/pistol, + /obj/item/ammo_magazine/m9mm/compact, + /obj/item/ammo_magazine/m9mm/compact + ), + prob(2);list( + /obj/item/weapon/gun/projectile/silenced, + /obj/item/ammo_magazine/m45, + /obj/item/ammo_magazine/m45 + ), + prob(2);list( + /obj/item/weapon/gun/projectile/revolver, + /obj/item/ammo_magazine/s357, + /obj/item/ammo_magazine/s357 + ), + prob(4);list( + /obj/item/weapon/gun/projectile/revolver/deckard, + /obj/item/ammo_magazine/s38, + /obj/item/ammo_magazine/s38 + ), + prob(4);list( + /obj/item/weapon/gun/projectile/revolver/detective, + /obj/item/ammo_magazine/s38, + /obj/item/ammo_magazine/s38 + ), + prob(2);list( + /obj/item/weapon/gun/projectile/revolver/judge, + /obj/item/ammo_magazine/clip/c12g, + /obj/item/ammo_magazine/clip/c12g, + /obj/item/ammo_magazine/clip/c12g + ), + prob(2);list( + /obj/item/weapon/gun/projectile/revolver/lemat, + /obj/item/ammo_magazine/s38, + /obj/item/ammo_magazine/s38, + /obj/item/ammo_magazine/clip/c12g + ), + prob(2);list( + /obj/item/weapon/gun/projectile/revolver/mateba, + /obj/item/ammo_magazine/s357, + /obj/item/ammo_magazine/s357 + ), + prob(2);list( + /obj/item/weapon/gun/projectile/revolver/webley, + /obj/item/ammo_magazine/s44, + /obj/item/ammo_magazine/s44 + ), + prob(1);list( + /obj/item/weapon/gun/projectile/revolver/webley/auto, + /obj/item/ammo_magazine/s44, + /obj/item/ammo_magazine/s44 + ) + ) + +/obj/random/multiple/gun/projectile/shotgun + name = "random shotgun projectile gun" + desc = "Loot for PoIs." + icon = 'icons/obj/gun.dmi' + icon_state = "shotgun" + +/obj/random/multiple/gun/projectile/shotgun/item_to_spawn() + return pick( + prob(4);list( + /obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet, + /obj/item/ammo_magazine/clip/c12g/pellet, + /obj/item/ammo_magazine/clip/c12g/pellet, + /obj/item/ammo_magazine/clip/c12g/pellet, + /obj/item/ammo_magazine/clip/c12g/pellet + ), + prob(3);list( + /obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn, + /obj/item/ammo_magazine/clip/c12g/pellet, + /obj/item/ammo_magazine/clip/c12g/pellet, + /obj/item/ammo_magazine/clip/c12g/pellet, + /obj/item/ammo_magazine/clip/c12g/pellet + ), + prob(3);list( + /obj/item/weapon/gun/projectile/shotgun/pump/slug, + /obj/item/weapon/storage/box/shotgunammo + ), + prob(1);list( + /obj/item/weapon/gun/projectile/shotgun/pump/combat, + /obj/item/weapon/storage/box/shotgunammo + ) + ) \ No newline at end of file diff --git a/code/game/objects/random/mapping.dm b/code/game/objects/random/mapping.dm index 57ff7acdcd..aba62d0806 100644 --- a/code/game/objects/random/mapping.dm +++ b/code/game/objects/random/mapping.dm @@ -92,8 +92,8 @@ /obj/random/multiple/minevault name = "random vault loot" desc = "Loot for mine vaults." - icon = 'icons/misc/mark.dmi' - icon_state = "rup" + icon = 'icons/obj/storage.dmi' + icon_state = "crate" /obj/random/multiple/minevault/item_to_spawn() return pick( diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm index 29b597d460..c918425221 100644 --- a/code/game/objects/random/misc.dm +++ b/code/game/objects/random/misc.dm @@ -159,8 +159,8 @@ /obj/random/medical name = "Random Medicine" desc = "This is a random medical item." - icon = 'icons/obj/items.dmi' - icon_state = "advfirstaid" + icon = 'icons/obj/stacks.dmi' + icon_state = "traumakit" /obj/random/medical/item_to_spawn() return pick(prob(21);/obj/random/medical/lite, diff --git a/code/game/objects/random/mob.dm b/code/game/objects/random/mob.dm index 2043ef0240..3aefa9a84c 100644 --- a/code/game/objects/random/mob.dm +++ b/code/game/objects/random/mob.dm @@ -74,6 +74,23 @@ prob(1);/mob/living/simple_animal/hostile/goose, prob(20);/mob/living/simple_animal/giant_crab) + +/obj/random/mob/sif/peaceful + name = "Random Peaceful Sif Animal" + desc = "This is a random peaceful cold weather animal." + icon_state = "penguin" + + mob_returns_home = 1 + mob_wander_distance = 12 + +/obj/random/mob/sif/peaceful/item_to_spawn() + return pick(prob(30);/mob/living/simple_animal/retaliate/diyaab, + prob(15);/mob/living/simple_animal/crab, + prob(15);/mob/living/simple_animal/penguin, + prob(15);/mob/living/simple_animal/mouse, + prob(15);/mob/living/simple_animal/corgi/tamaskan, + prob(20);/mob/living/simple_animal/giant_crab) + /obj/random/mob/sif/hostile name = "Random Hostile Sif Animal" desc = "This is a random hostile cold weather animal." @@ -97,6 +114,18 @@ prob(33);/mob/living/simple_animal/hostile/giant_spider/hunter, prob(45);/mob/living/simple_animal/hostile/giant_spider) +/obj/random/mob/spider/nurse + name = "Random Nurse Spider" + desc = "This is a random nurse spider." + icon_state = "nurse" + + mob_returns_home = 1 + mob_wander_distance = 4 + +/obj/random/mob/spider/nurse/item_to_spawn() + return pick(prob(22);/mob/living/simple_animal/hostile/giant_spider/nurse/hat, + prob(45);/mob/living/simple_animal/hostile/giant_spider/nurse) + /obj/random/mob/spider/mutant name = "Random Mutant Spider" desc = "This is a random mutated spider." diff --git a/code/game/objects/random/spacesuits.dm b/code/game/objects/random/spacesuits.dm index cb4ec6d4e9..29bd799c5c 100644 --- a/code/game/objects/random/spacesuits.dm +++ b/code/game/objects/random/spacesuits.dm @@ -97,6 +97,31 @@ ) ) +/obj/random/multiple/voidsuit/medical + name = "Random Mining Voidsuit" + desc = "This is a random mining voidsuit." + icon = 'icons/obj/clothing/suits.dmi' + icon_state = "rig-mining" + +/obj/random/multiple/voidsuit/medical/item_to_spawn() + return pick( + prob(5);list( + /obj/item/clothing/suit/space/void/medical, + /obj/item/clothing/head/helmet/space/void/medical + ), + prob(1);list( + /obj/item/clothing/suit/space/void/medical/alt, + /obj/item/clothing/head/helmet/space/void/medical/alt + ), + prob(3);list( + /obj/item/clothing/suit/space/void/medical/bio, + /obj/item/clothing/head/helmet/space/void/medical/bio + ), + prob(4);list( + /obj/item/clothing/suit/space/void/medical/emt, + /obj/item/clothing/head/helmet/space/void/medical/emt + ) + ) /obj/random/rigsuit name = "Random rigsuit" diff --git a/code/game/objects/structures/crates_lockers/closets/l3closet_vr.dm b/code/game/objects/structures/crates_lockers/closets/l3closet_vr.dm index fdc6163459..e69de29bb2 100644 --- a/code/game/objects/structures/crates_lockers/closets/l3closet_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/l3closet_vr.dm @@ -1,27 +0,0 @@ -/obj/structure/closet/l3closet/virology/New() - ..() - new /obj/item/clothing/suit/bio_suit/virology/taur(src) - new /obj/item/clothing/head/bio_hood/virology(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/weapon/tank/oxygen(src) - - -/obj/structure/closet/l3closet/security/New() - ..() - new /obj/item/clothing/suit/bio_suit/security/taur(src) - new /obj/item/clothing/head/bio_hood/security(src) - - -/obj/structure/closet/l3closet/janitor/New() - ..() - new /obj/item/clothing/suit/bio_suit/janitor/taur(src) - new /obj/item/clothing/head/bio_hood/janitor(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/weapon/tank/emergency/oxygen/engi(src) - - -/obj/structure/closet/l3closet/scientist/New() - ..() - new /obj/item/clothing/suit/bio_suit/scientist/taur(src) - new /obj/item/clothing/head/bio_hood/scientist(src) - diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 96a1b39477..66732a8209 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -313,6 +313,8 @@ icon_opened = "medical_wall_open" icon_broken = "medical_wall_spark" icon_off = "medical_wall_off" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER anchored = 1 density = 0 wall_mounted = 1 diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index 62db60456e..c2b8ff731a 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -215,6 +215,8 @@ icon_state = "hydrant" icon_closed = "hydrant" icon_opened = "hydrant_open" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER anchored = 1 density = 0 wall_mounted = 1 diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets_vr.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets_vr.dm index d9f0dcc092..c1e40dab11 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets_vr.dm @@ -1,13 +1,11 @@ /obj/structure/closet/radiation/New() ..() - new /obj/item/clothing/suit/radiation/taur(src) new /obj/item/clothing/head/radiation(src) new /obj/item/device/geiger(src) /obj/structure/closet/bombcloset/New() ..() - new /obj/item/clothing/suit/bomb_suit/taur(src) new /obj/item/clothing/under/color/black(src) new /obj/item/clothing/shoes/black(src ) new /obj/item/clothing/head/bomb_hood(src) @@ -15,7 +13,6 @@ /obj/structure/closet/bombclosetsecurity/New() ..() - new /obj/item/clothing/suit/bomb_suit/taur/security(src) new /obj/item/clothing/under/rank/security(src) new /obj/item/clothing/shoes/brown(src) new /obj/item/clothing/head/bomb_hood/security(src) diff --git a/code/game/objects/structures/crates_lockers/largecrate_vr.dm b/code/game/objects/structures/crates_lockers/largecrate_vr.dm index 014b49b522..134aad487f 100644 --- a/code/game/objects/structures/crates_lockers/largecrate_vr.dm +++ b/code/game/objects/structures/crates_lockers/largecrate_vr.dm @@ -48,13 +48,13 @@ /mob/living/simple_animal/hostile/frog, /mob/living/simple_animal/horse, /mob/living/simple_animal/hostile/panther, - /mob/living/simple_animal/hostile/snake, + /mob/living/simple_animal/hostile/giant_snake, /mob/living/simple_animal/hostile/wolf, /mob/living/simple_animal/hostile/bear;0.5, /mob/living/simple_animal/hostile/bear/brown;0.5, /mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/mimic, - /mob/living/simple_animal/hostile/rous, + /mob/living/simple_animal/hostile/rat, /mob/living/simple_animal/otie;0.5) ..() @@ -73,7 +73,7 @@ /mob/living/simple_animal/hostile/alien/sentinel, /mob/living/simple_animal/hostile/alien/queen, /mob/living/simple_animal/otie/feral, - /mob/living/simple_animal/hostile/badboi) + /mob/living/simple_animal/hostile/corrupthound) ..() /obj/structure/largecrate/animal/guardbeast diff --git a/code/game/objects/structures/curtains.dm b/code/game/objects/structures/curtains.dm index af129800b7..39c2dc43fd 100644 --- a/code/game/objects/structures/curtains.dm +++ b/code/game/objects/structures/curtains.dm @@ -2,13 +2,15 @@ name = "curtain" icon = 'icons/obj/curtain.dmi' icon_state = "closed" - layer = SHOWER_OPEN_LAYER + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER opacity = 1 density = 0 /obj/structure/curtain/open icon_state = "open" - layer = SHOWER_CLOSED_LAYER + plane = OBJ_PLANE + layer = OBJ_LAYER opacity = 0 /obj/structure/curtain/bullet_act(obj/item/projectile/P, def_zone) @@ -27,10 +29,12 @@ set_opacity(!opacity) if(opacity) icon_state = "closed" - layer = SHOWER_CLOSED_LAYER + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER else icon_state = "open" - layer = SHOWER_OPEN_LAYER + plane = OBJ_PLANE + layer = OBJ_LAYER /obj/structure/curtain/attackby(obj/item/P, mob/user) if(istype(P, /obj/item/weapon/wirecutters)) @@ -76,6 +80,3 @@ /obj/structure/curtain/open/shower/security color = "#AA0000" - -#undef SHOWER_OPEN_LAYER -#undef SHOWER_CLOSED_LAYER diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index bfbc34dcee..e93afd18f3 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -3,6 +3,8 @@ desc = "A small wall mounted cabinet designed to hold a fire extinguisher." icon = 'icons/obj/closet.dmi' icon_state = "extinguisher_closed" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER anchored = 1 density = 0 var/obj/item/weapon/extinguisher/has_extinguisher diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index 353dbe31a7..96416e0229 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -830,3 +830,42 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/mecha_parts/mecha_equipment/repair_droid, /obj/item/mecha_parts/mecha_equipment/teleporter ) + +/obj/structure/loot_pile/surface/drone + name = "drone wreckage" + desc = "The ruins of some unfortunate drone. Perhaps something is salvageable." + icon = 'icons/mob/animal.dmi' + icon_state = "drone_dead" + +// Since the actual drone loot is a bit stupid in how it is handled, this is a sparse and empty list with items I don't exactly want in it. But until we can get the proper items in . . . + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/weapon/cell, + /obj/item/weapon/material/shard + ) + + uncommon_loot = list( + /obj/item/weapon/cell/high, + /obj/item/robot_parts/robot_component/actuator, + /obj/item/robot_parts/robot_component/armour, + /obj/item/robot_parts/robot_component/binary_communication_device, + /obj/item/robot_parts/robot_component/camera, + /obj/item/robot_parts/robot_component/diagnosis_unit, + /obj/item/robot_parts/robot_component/radio + ) + + rare_loot = list( + /obj/item/weapon/cell/super, + /obj/item/borg/upgrade/restart, + /obj/item/borg/upgrade/jetpack, + /obj/item/borg/upgrade/tasercooler, + /obj/item/borg/upgrade/syndicate, + /obj/item/borg/upgrade/vtec + ) \ No newline at end of file diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index b180b88603..c1b0b6b0c5 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -3,7 +3,8 @@ anchored = 1 opacity = 0 density = 0 - layer = ABOVE_JUNK_LAYER + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER w_class = ITEMSIZE_NORMAL /obj/structure/sign/ex_act(severity) @@ -387,6 +388,18 @@ icon = 'icons/obj/christmas.dmi' icon_state = "doorwreath" +/obj/structure/sign/hostilefauna + icon = 'icons/obj/decals_vr.dmi' + name = "\improper Caution: Hostile fauna" + desc = "This sign warns of hostile life forms in the area." + icon_state = "h_fauna" + +/obj/structure/sign/graffiti/pisoff + icon = 'icons/obj/decals_vr.dmi' + name = "\improper PIS OFF" + desc = "This sign bears some rather rude looking graffiti instructing you to PIS OFF." + icon_state = "pisoff" + //Eris signs /obj/structure/sign/ironhammer diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 9882ca4507..98e0f1a41e 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -142,7 +142,8 @@ name = "mist" icon = 'icons/obj/watercloset.dmi' icon_state = "mist" - layer = MOB_LAYER + 1 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER anchored = 1 mouse_opacity = 0 diff --git a/code/game/turfs/simulated/dungeon/wall.dm b/code/game/turfs/simulated/dungeon/wall.dm index 156fddac6a..176c10142c 100644 --- a/code/game/turfs/simulated/dungeon/wall.dm +++ b/code/game/turfs/simulated/dungeon/wall.dm @@ -13,6 +13,9 @@ return /turf/simulated/wall/solidrock //for more stylish anti-cheese. + name = "solid rock" + desc = "This rock seems dense, impossible to drill." + description_info = "Probably not going to be able to drill or bomb your way through this, best to try and find a way around." icon_state = "bedrock" var/base_state = "bedrock" block_tele = TRUE diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 2b0158b5fc..8d26d11543 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -137,6 +137,8 @@ turf/attackby(obj/item/weapon/W as obj, mob/user as mob) animate(O, transform = turn(O.transform, -40), time = 4) sleep(4) animate(O, transform = turn(O.transform, 20), time = 2) + sleep(2) + O.update_transform() /turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area) if(movement_disabled && usr.ckey != movement_disabled_exception) diff --git a/code/modules/admin/admin_secrets.dm b/code/modules/admin/admin_secrets.dm index 473770ac2b..5f04582ace 100644 --- a/code/modules/admin/admin_secrets.dm +++ b/code/modules/admin/admin_secrets.dm @@ -31,7 +31,6 @@ var/datum/admin_secrets/admin_secrets = new() var/list/datum/admin_secret_item/items /datum/admin_secret_category - ..() items = list() /datum/admin_secret_category/proc/can_view(var/mob/user) diff --git a/code/modules/awaymissions/loot_vr.dm b/code/modules/awaymissions/loot_vr.dm index 0506d647be..9c88e740a7 100644 --- a/code/modules/awaymissions/loot_vr.dm +++ b/code/modules/awaymissions/loot_vr.dm @@ -365,7 +365,7 @@ icon_state = "da" /obj/structure/symbol/em - desc = "It looks like the letter 'Y' with an underline." + desc = "It looks kind of like a cup. Specifically, a martini glass." icon_state = "em" /obj/structure/symbol/es @@ -381,7 +381,7 @@ icon_state = "gu" /obj/structure/symbol/lo - desc = "It looks kind of like a cup. Specifically, a martini glass." + desc = "It looks like the letter 'Y' with an underline." icon_state = "lo" /obj/structure/symbol/pr diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index fe37d19f4b..e430894b90 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -64,7 +64,7 @@ //Logs all hrefs if(config && config.log_hrefs && href_logfile) - href_logfile << "[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]
" + href_logfile << "[src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]" switch(href_list["_src_"]) if("holder") hsrc = holder diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index 29502ec985..5b1314d05f 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -8,6 +8,7 @@ S["UI_style_alpha"] >> pref.UI_style_alpha S["ooccolor"] >> pref.ooccolor S["tooltipstyle"] >> pref.tooltipstyle + S["client_fps"] >> pref.client_fps /datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S) S["UI_style"] << pref.UI_style @@ -15,6 +16,7 @@ S["UI_style_alpha"] << pref.UI_style_alpha S["ooccolor"] << pref.ooccolor S["tooltipstyle"] << pref.tooltipstyle + S["client_fps"] << pref.client_fps /datum/category_item/player_setup_item/player_global/ui/sanitize_preferences() pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style)) @@ -22,6 +24,7 @@ pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha)) pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor)) pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, initial(pref.tooltipstyle)) + pref.client_fps = sanitize_integer(pref.client_fps, 0, MAX_CLIENT_FPS, initial(pref.client_fps)) /datum/category_item/player_setup_item/player_global/ui/content(var/mob/user) . = "UI Style: [pref.UI_style]
" @@ -29,6 +32,7 @@ . += "-Color: [pref.UI_style_color] 
__
 reset
" . += "-Alpha(transparency): [pref.UI_style_alpha] reset
" . += "Tooltip Style: [pref.tooltipstyle]
" + . += "Client FPS: [pref.client_fps]
" if(can_select_ooc_color(user)) . += "OOC Color: " if(pref.ooccolor == initial(pref.ooccolor)) @@ -62,11 +66,20 @@ return TOPIC_REFRESH else if(href_list["select_tooltip_style"]) - var/tooltip_style_new = input(user, "Choose tooltip style.", "Character Preference", pref.tooltipstyle) as null|anything in all_tooltip_styles + var/tooltip_style_new = input(user, "Choose tooltip style.", "Global Preference", pref.tooltipstyle) as null|anything in all_tooltip_styles if(!tooltip_style_new || !CanUseTopic(user)) return TOPIC_NOACTION pref.tooltipstyle = tooltip_style_new return TOPIC_REFRESH + else if(href_list["select_client_fps"]) + var/fps_new = input(user, "Input Client FPS (1-200, 0 uses server FPS)", "Global Preference", pref.client_fps) as null|num + if(isnull(fps_new) || !CanUseTopic(user)) return TOPIC_NOACTION + if(fps_new < 0 || fps_new > MAX_CLIENT_FPS) return TOPIC_NOACTION + pref.client_fps = fps_new + if(pref.client) + pref.client.fps = fps_new + return TOPIC_REFRESH + else if(href_list["reset"]) switch(href_list["reset"]) if("ui") diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm index 5260193848..393ac5841c 100644 --- a/code/modules/client/preference_setup/global/setting_datums.dm +++ b/code/modules/client/preference_setup/global/setting_datums.dm @@ -193,6 +193,20 @@ var/list/_client_preferences_by_type enabled_description = "Fancy" disabled_description = "Plain" +/datum/client_preference/ambient_occlusion + description = "Fake Ambient Occlusion" + key = "AMBIENT_OCCLUSION_PREF" + enabled_by_default = FALSE + enabled_description = "On" + disabled_description = "Off" + +/datum/client_preference/ambient_occlusion/toggled(var/mob/preference_mob, var/enabled) + . = ..() + if(preference_mob && preference_mob.plane_holder) + var/datum/plane_holder/PH = preference_mob.plane_holder + PH.set_ao(VIS_OBJS, enabled) + PH.set_ao(VIS_MOBS, enabled) + /******************** * Staff Preferences * ********************/ diff --git a/code/modules/client/preference_setup/loadout/loadout_suit.dm b/code/modules/client/preference_setup/loadout/loadout_suit.dm index 6b32034b31..9276384602 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit.dm @@ -455,4 +455,4 @@ datum/gear/suit/duster /datum/gear/suit/snowsuit/cargo display_name = "snowsuit, supply" path = /obj/item/clothing/suit/storage/snowsuit/cargo - allowed_roles = list("Quartermaster","shaft Miner","Cargo Technician","Head of Personnel") \ No newline at end of file + allowed_roles = list("Quartermaster","Shaft Miner","Cargo Technician","Head of Personnel") \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 22d04295ad..d0aefa286f 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -22,6 +22,7 @@ datum/preferences var/UI_style_color = "#ffffff" var/UI_style_alpha = 255 var/tooltipstyle = "Midnight" //Style for popup tooltips + var/client_fps = 0 //character preferences var/real_name //our character's name diff --git a/code/modules/clothing/clothing_vr.dm b/code/modules/clothing/clothing_vr.dm index fd0beeddf3..e0472d23b9 100644 --- a/code/modules/clothing/clothing_vr.dm +++ b/code/modules/clothing/clothing_vr.dm @@ -99,11 +99,33 @@ ) //"Spider" = 'icons/mob/species/spider/mask_vr.dmi' Add this later when they have custom mask sprites and everything. +//Switch to taur sprites if a taur equips +/obj/item/clothing/suit + var/taurized = FALSE //Easier than trying to 'compare icons' to see if it's a taur suit + +/obj/item/clothing/suit/equipped(var/mob/user, var/slot) + var/normalize = TRUE + + //Pyramid of doom-y. Improve somehow? + if(!taurized && slot == slot_wear_suit && ishuman(user)) + var/mob/living/carbon/human/H = user + if(isTaurTail(H.tail_style)) + var/datum/sprite_accessory/tail/taur/taurtail = H.tail_style + if(taurtail.suit_sprites && (get_worn_icon_state(slot_wear_suit_str) in icon_states(taurtail.suit_sprites))) + icon_override = taurtail.suit_sprites + normalize = FALSE + taurized = TRUE + + if(normalize && taurized) + icon_override = initial(icon_override) + taurized = FALSE + + return ..() + // Taur suits need to be shifted so its centered on their taur half. -// TODO - Instead of just assuming this junk, shift some of the data onto the taur tail datum. /obj/item/clothing/suit/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0) var/image/standing = ..() - if(icon_override && icon_override == 'icons/mob/taursuits_vr.dmi') + if(taurized) //Special snowflake var on suits standing.pixel_x = -16 standing.layer = BODY_LAYER + 15 // 15 is above tail layer, so will not be covered by taurbody. return standing diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index ac82df4ddc..9a2d3868dd 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -99,7 +99,7 @@ slot_l_hand_str = "engiewelding", slot_r_hand_str = "engiewelding", ) -. + /* * Cakehat @@ -272,4 +272,4 @@ /obj/item/clothing/head/psy_crown/wrath/activate_ability(var/mob/living/wearer) ..() - wearer.add_modifier(/datum/modifier/berserk, 30 SECONDS) \ No newline at end of file + wearer.add_modifier(/datum/modifier/berserk, 30 SECONDS) diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm b/code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm index 494c54d05a..d71d7cd6fa 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm @@ -32,300 +32,6 @@ SPECIES_VOX = 'icons/mob/species/vox/suit.dmi' ) -/obj/item/clothing/suit/space/rig - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(icon_state == "security_rig_sealed") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "breacher_rig_cheap-horse_sealed" //They have to toggle the chest piece off then on again for this to show up. - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "breacher_rig_cheap-wolf_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "breacher_rig_cheap-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "security_rig_sealed" - pixel_x = 0 - update_icon() - return 1 - else if(icon_state == "engineering_rig_sealed") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "industrial_rig-horse_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "industrial_rig-wolf_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "industrial_rig-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "engineering_rig_sealed" - pixel_x = 0 - update_icon() - return 1 - else if(icon_state == "science_rig_sealed") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "science_rig-horse_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "science_rig-wolf_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "science_rig-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "science_rig_sealed" - pixel_x = 0 - update_icon() - return 1 - else if(icon_state == "medical_rig_sealed") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical_rig-horse_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical_rig-wolf_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical_rig-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "medical_rig_sealed" - pixel_x = 0 - update_icon() - return 1 - else if(icon_state == "security_rig") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "breacher_rig_cheap-horse_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "breacher_rig_cheap-wolf_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "breacher_rig_cheap-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "security_rig" - pixel_x = 0 - update_icon() - return 1 - else if(icon_state == "engineering_rig") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "industrial_rig-horse_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "industrial_rig-wolf_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "industrial_rig-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "engineering_rig" - pixel_x = 0 - update_icon() - return 1 - else if(icon_state == "science_rig") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "science_rig-horse_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "science_rig-wolf_sealed" - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "science_rig-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "science_rig" - pixel_x = 0 - update_icon() - return 1 - else if(icon_state == "medical_rig") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical_rig-horse_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical_rig-wolf_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical_rig-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "medical_rig" - pixel_x = 0 - update_icon() - return 1 - else - return 1 - - - -/obj/item/clothing/suit/space/rig/ce - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(icon_state == "ce_rig") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "ce_rig-horse" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "ce_rig-wolf" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "ce_rig-naga" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "ce_rig" - pixel_x = 0 - update_icon() - return 1 - else if(icon_state == "ce_rig_sealed") - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "ce_rig-horse_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "ce_rig-wolf_sealed" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "ce_rig-naga_sealed" - pixel_x = -16 - update_icon() - return 1 - else - icon = 'icons/obj/clothing/suits.dmi' - icon_override = null - icon_state = "ce_rig_sealed" - pixel_x = 0 - update_icon() - return 1 - else - return 1 - /obj/item/clothing/head/helmet/space/rig phoronproof = 1 /obj/item/clothing/gloves/gauntlets/rig diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm index 0dd98de966..85c2004058 100644 --- a/code/modules/clothing/spacesuits/rig/suits/light.dm +++ b/code/modules/clothing/spacesuits/rig/suits/light.dm @@ -103,7 +103,6 @@ /obj/item/rig_module/self_destruct ) - ..() /obj/item/clothing/gloves/gauntlets/rig/light/ninja name = "insulated gloves" diff --git a/code/modules/clothing/spacesuits/void/void_vr.dm b/code/modules/clothing/spacesuits/void/void_vr.dm index 51f29be19a..b0842df24f 100644 --- a/code/modules/clothing/spacesuits/void/void_vr.dm +++ b/code/modules/clothing/spacesuits/void/void_vr.dm @@ -74,297 +74,50 @@ // however the species spritesheet now means we no longer need that anyway! sprite_sheets_refit = list() +/obj/item/clothing/suit/space/void/explorer + desc = "A classy red voidsuit for the needs of any semi-retro-futuristic spaceperson! This one is rather loose fitting." + species_restricted = list( + SPECIES_HUMAN, + SPECIES_SKRELL, + SPECIES_UNATHI, + SPECIES_TAJ, + SPECIES_TESHARI, + SPECIES_AKULA, + SPECIES_ALRAUNE, + SPECIES_NEVREAN, + SPECIES_RAPALA, + SPECIES_SERGAL, + SPECIES_VASILISSAN, + SPECIES_VULPKANIN, + SPECIES_XENOCHIMERA, + SPECIES_XENOHYBRID, + SPECIES_ZORREN_FLAT, + SPECIES_ZORREN_HIGH + ) +/obj/item/clothing/suit/space/void/explorer/initialize() + . = ..() + sprite_sheets += sprite_sheets_refit - -/obj/item/clothing/suit/space/void/merc/taur - name = "taur specific blood-red voidsuit" - desc = "A high-tech space suit. It says has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - species_restricted = null //Species restricted since all it cares about is a taur half - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "syndie-horse" - item_state = "syndie-horse" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "syndie-wolf" - item_state = "syndie-wolf" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "syndie-naga" - item_state = "syndie-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -/obj/item/clothing/suit/space/void/medical/taur - name = "taur specific medical voidsuit" - desc = "A high-tech space suit. It says has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical-horse" - item_state = "medical-horse" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical-wolf" - item_state = "medical-wolf" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medical-naga" - item_state = "medical-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -/obj/item/clothing/suit/space/void/medical/alt/taur - name = "taur specific streamlined medical voidsuit" - desc = "A more recent model of Vey-Med voidsuit, featuring the latest in radiation shielding technology. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medicalalt-horse" - item_state = "medicalalt-horse" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medicalalt-wolf" - item_state = "medicalalt-wolf" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "medicalalt-naga" - item_state = "medicalalt-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -/obj/item/clothing/suit/space/void/engineering/taur - name = "taur specific engineering voidsuit" - desc = "A high-tech space suit. It says has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "engineering-horse" - item_state = "engineering-horse" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "engineering-wolf" - item_state = "engineering-wolf" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "engineering-naga" - item_state = "engineering-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - - -/obj/item/clothing/suit/space/void/security/taur - name = "taur specific security voidsuit" - desc = "A high-tech space suit. It says has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "security-horse" - item_state = "security-horse" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "security-wolf" - item_state = "security-wolf" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "security-naga" - item_state = "security-naga" - pixel_x = -16 - update_icon() - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -/obj/item/clothing/suit/space/void/security/alt/taur - name = "taur specific riot security voidsuit" - desc = "A heavily armored voidsuit. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - armor = list(melee = 70, bullet = 20, laser = 30, energy = 5, bomb = 35, bio = 100, rad = 10) - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "securityalt-horse" - item_state = "securityalt-horse" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "securityalt-wolf" - item_state = "securityalt-wolf" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "securityalt-naga" - item_state = "securityalt-naga" - pixel_x = -16 - update_icon() - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -/obj/item/clothing/suit/space/void/security/riot/taur - name = "taur specific crowd control voidsuit" - desc = "A high-tech space suit. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "securityriot-horse" - item_state = "securityriot-horse" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "securityriot-wolf" - item_state = "securityriot-wolf" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "securityriot-naga" - item_state = "securityriot-naga" - pixel_x = -16 - update_icon() - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -/obj/item/clothing/suit/space/void/atmos/taur - name = "taur specific atmospherics voidsuit" - desc = "A high-tech space suit. It says has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "atmos-horse" - item_state = "atmos-horse" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "atmos-wolf" - item_state = "atmos-wolf" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "atmos-naga" - item_state = "atmos-naga" - pixel_x = -16 - update_icon() - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -/obj/item/clothing/suit/space/void/mining/taur - name = "taur specific mining voidsuit" - desc = "A high-tech space suit. It says has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "mining-horse" - item_state = "mining-horse" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "mining-wolf" - item_state = "mining-wolf" - pixel_x = -16 - update_icon() - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "mining-naga" - item_state = "mining-naga" - pixel_x = -16 - update_icon() - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 +/obj/item/clothing/head/helmet/space/void/explorer + desc = "A helmet that matches a red voidsuit! So classy." + species_restricted = list( + SPECIES_HUMAN, + SPECIES_SKRELL, + SPECIES_UNATHI, + SPECIES_TAJ, + SPECIES_TESHARI, + SPECIES_AKULA, + SPECIES_ALRAUNE, + SPECIES_NEVREAN, + SPECIES_RAPALA, + SPECIES_SERGAL, + SPECIES_VASILISSAN, + SPECIES_VULPKANIN, + SPECIES_XENOCHIMERA, + SPECIES_XENOHYBRID, + SPECIES_ZORREN_FLAT, + SPECIES_ZORREN_HIGH + ) +/obj/item/clothing/head/helmet/space/void/explorer/initialize() + . = ..() + sprite_sheets += sprite_sheets_refit diff --git a/code/modules/clothing/suits/armor_vr.dm b/code/modules/clothing/suits/armor_vr.dm index a70a33f872..349b0e01e7 100644 --- a/code/modules/clothing/suits/armor_vr.dm +++ b/code/modules/clothing/suits/armor_vr.dm @@ -16,20 +16,15 @@ name = "wolf-taur armor vest" desc = "An armored vest that protects against some damage. It appears to be created for a wolf-taur." species_restricted = null //Species restricted since all it cares about is a taur half - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' + icon = 'icons/mob/taursuits_wolf_vr.dmi' icon_state = "heavy_wolf_armor" + item_state = "heavy_wolf_armor" mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) if(..()) if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - if(icon_state == "serdy_armor") //This is to prevent Serdy's custom armor from turning into heavy_wolf_armor - return ..() - icon_override = 'icons/mob/taursuits_vr.dmi' //Just in case - icon_state = "heavy_wolf_armor" //Just in case - pixel_x = -16 return ..() else - H << "You need to have a wolf-taur half to wear this." + to_chat(H,"You need to have a wolf-taur half to wear this.") return 0 // HoS armor improved by Vorestation to be slightly better than normal security stuff. diff --git a/code/modules/clothing/suits/bio_vr.dm b/code/modules/clothing/suits/bio_vr.dm index 799ea429da..e69de29bb2 100644 --- a/code/modules/clothing/suits/bio_vr.dm +++ b/code/modules/clothing/suits/bio_vr.dm @@ -1,101 +0,0 @@ -//Biosuits for use with taurs (Currently only nagas) - -//Virology biosuit, green stripe -/obj/item/clothing/suit/bio_suit/virology/taur - name = "taur specific bio suit" - desc = "A suit that protects against biological contamination. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER - species_restricted = null //Species restricted since all it cares about is a taur half - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "bioviro-naga" - item_state = "bioviro-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -//Security biosuit, grey with red stripe across the chest -/obj/item/clothing/suit/bio_suit/security/taur - name = "taur specific bio suit" - desc = "A suit that protects against biological contamination. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER - species_restricted = null //Species restricted since all it cares about is a taur half - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "biosec-naga" - item_state = "biosec-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -//Janitor's biosuit, grey with purple arms -/obj/item/clothing/suit/bio_suit/janitor/taur - name = "taur specific bio suit" - desc = "A suit that protects against biological contamination. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER - species_restricted = null //Species restricted since all it cares about is a taur half - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "biojan-naga" - item_state = "biojan-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -//Scientist's biosuit, white with a pink-ish hue -/obj/item/clothing/suit/bio_suit/scientist/taur - name = "taur specific bio suit" - desc = "A suit that protects against biological contamination. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER - species_restricted = null //Species restricted since all it cares about is a taur half - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "biosci-naga" - item_state = "biosci-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -//CMO's biosuit, blue stripe -/obj/item/clothing/suit/bio_suit/cmo/taur - name = "taur specific bio suit" - desc = "A suit that protects against biological contamination. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER - species_restricted = null //Species restricted since all it cares about is a taur half - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "biocmo-naga" - item_state = "biocmo-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 \ No newline at end of file diff --git a/code/modules/clothing/suits/utility_vr.dm b/code/modules/clothing/suits/utility_vr.dm index be67b06bf2..c1982a58ce 100644 --- a/code/modules/clothing/suits/utility_vr.dm +++ b/code/modules/clothing/suits/utility_vr.dm @@ -1,130 +1,3 @@ -/* - * Contains: - * Bomb protection - * Radiation protection - */ - -/* - * Bomb protection - */ - -/obj/item/clothing/suit/bomb_suit/taur - name = "taur specific bomb suit" - desc = "A suit designed for safety when handling explosives. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - w_class = ITEMSIZE_LARGE//bulky item - gas_transfer_coefficient = 0.01 - permeability_coefficient = 0.01 - slowdown = 2 - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 100, bio = 0, rad = 0) - flags_inv = HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER - heat_protection = UPPER_TORSO|LOWER_TORSO - max_heat_protection_temperature = ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE - siemens_coefficient = 0 - - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "bombsuit-horse" - item_state = "bombsuit-horse" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "bombsuit-wolf" - item_state = "bombsuit-wolf" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "bombsuit-naga" - item_state = "bombsuit-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - - /obj/item/clothing/head/bomb_hood/security icon_state = "bombsuitsec" body_parts_covered = HEAD - -/obj/item/clothing/suit/bomb_suit/taur/security - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "bombsuit-horse" - item_state = "bombsuit-horse" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "bombsuit-wolf" - item_state = "bombsuit-wolf" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "bombsuit-naga" - item_state = "bombsuit-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 - -/* - * Radiation protection - */ - -/obj/item/clothing/suit/radiation/taur - name = "taur specific radiation suit" - desc = "A suit that protects against radiation. Label: Made with lead, do not eat insulation. It has a sticker saying one size fits all taurs on it. Below the sticker, it states that it only fits horses, wolves, and naga taurs." - w_class = ITEMSIZE_LARGE//bulky item - gas_transfer_coefficient = 0.90 - permeability_coefficient = 0.50 - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS|FEET - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency/oxygen,/obj/item/clothing/head/radiation,/obj/item/clothing/mask/gas) - slowdown = 1.5 - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100) - flags_inv = HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER - - species_restricted = null - mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/horse)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "radsuit-horse" - item_state = "radsuit-horse" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "radsuit-wolf" - item_state = "radsuit-wolf" - pixel_x = -16 - return 1 - else if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/naga)) - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "radsuit-naga" - item_state = "radsuit-naga" - pixel_x = -16 - return 1 - else - H << "You need to have a horse, wolf, or naga half to wear this." - return 0 \ No newline at end of file diff --git a/code/modules/economy/cash_register.dm b/code/modules/economy/cash_register.dm index c9332fb72f..febb412879 100644 --- a/code/modules/economy/cash_register.dm +++ b/code/modules/economy/cash_register.dm @@ -519,28 +519,21 @@ /obj/machinery/cash_register/command account_to_connect = "Command" - ..() /obj/machinery/cash_register/medical account_to_connect = "Medical" - ..() /obj/machinery/cash_register/engineering account_to_connect = "Engineering" - ..() /obj/machinery/cash_register/science account_to_connect = "Science" - ..() /obj/machinery/cash_register/security account_to_connect = "Security" - ..() /obj/machinery/cash_register/cargo account_to_connect = "Cargo" - ..() /obj/machinery/cash_register/civilian account_to_connect = "Civilian" - ..() \ No newline at end of file diff --git a/code/modules/economy/retail_scanner.dm b/code/modules/economy/retail_scanner.dm index 7117172af8..af1d87177a 100644 --- a/code/modules/economy/retail_scanner.dm +++ b/code/modules/economy/retail_scanner.dm @@ -401,28 +401,21 @@ /obj/item/device/retail_scanner/command account_to_connect = "Command" - ..() /obj/item/device/retail_scanner/medical account_to_connect = "Medical" - ..() /obj/item/device/retail_scanner/engineering account_to_connect = "Engineering" - ..() /obj/item/device/retail_scanner/science account_to_connect = "Science" - ..() /obj/item/device/retail_scanner/security account_to_connect = "Security" - ..() /obj/item/device/retail_scanner/cargo account_to_connect = "Cargo" - ..() /obj/item/device/retail_scanner/civilian account_to_connect = "Civilian" - ..() \ No newline at end of file diff --git a/code/modules/holomap/station_holomap.dm b/code/modules/holomap/station_holomap.dm index eb2ea9d53f..b704872abb 100644 --- a/code/modules/holomap/station_holomap.dm +++ b/code/modules/holomap/station_holomap.dm @@ -19,7 +19,8 @@ var/light_range_on = 2 light_color = "#64C864" - layer = ABOVE_WINDOW_LAYER + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER var/mob/watching_mob = null var/image/small_station_map = null diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 3ef22e0a5c..ac9a0e13f9 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -20,7 +20,7 @@ /obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. - to_chat(user, "You press the button labeled '[src.name]'.") + to_chat(user, "You press the button labeled '[src.displayed_name]'.") activate_pin(1) /obj/item/integrated_circuit/input/toggle_button @@ -38,7 +38,7 @@ set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1)) push_data() activate_pin(1) - to_chat(user, "You toggle the button labeled '[src.name]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].") + to_chat(user, "You toggle the button labeled '[src.displayed_name]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].") /obj/item/integrated_circuit/input/numberpad name = "number pad" diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index b59909376f..ef068381c8 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -563,7 +563,7 @@ var/list/mining_overlay_cache = list() new /obj/item/stack/material/uranium(src, rand(5,25)) /turf/simulated/mineral/proc/make_ore(var/rare_ore) - if(mineral) + if(mineral || ignore_mapgen) //VOREStation Edit - Makes sense, doesn't it? return var/mineral_name diff --git a/code/modules/mining/shelter_atoms.dm b/code/modules/mining/shelter_atoms.dm index 656f8f7ad1..8f6f43319f 100644 --- a/code/modules/mining/shelter_atoms.dm +++ b/code/modules/mining/shelter_atoms.dm @@ -15,12 +15,14 @@ w_class = ITEMSIZE_TINY var/template_id = "shelter_alpha" var/datum/map_template/shelter/template + var/datum/map_template/shelter/template_roof var/used = FALSE /obj/item/device/survivalcapsule/proc/get_template() if(template) return template = SSmapping.shelter_templates[template_id] + template_roof = SSmapping.shelter_templates[template.roof] if(!template) throw EXCEPTION("Shelter template ([template_id]) not found!") qdel(src) @@ -41,19 +43,26 @@ if(!used) loc.visible_message("\The [src] begins to shake. Stand back!") used = TRUE - + sleep(5 SECONDS) - + var/turf/deploy_location = get_turf(src) var/status = template.check_deploy(deploy_location) + var/turf/above_location = GetAbove(deploy_location) + if(above_location && status == SHELTER_DEPLOY_ALLOWED) + status = template.check_deploy(above_location) + switch(status) + //Not allowed due to /area technical reasons if(SHELTER_DEPLOY_BAD_AREA) src.loc.visible_message("\The [src] will not function in this area.") + + //Anchored objects or no space if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS) var/width = template.width var/height = template.height src.loc.visible_message("\The [src] doesn't have room to deploy! You need to clear a [width]x[height] area!") - + if(status != SHELTER_DEPLOY_ALLOWED) used = FALSE return @@ -68,6 +77,8 @@ playsound(get_turf(src), 'sound/effects/phasein.ogg', 100, 1) log_and_message_admins("[key_name_admin(usr)] activated a bluespace capsule at [get_area(T)]!") + if(above_location && template_roof) + template_roof.load(above_location, centered = TRUE) template.load(deploy_location, centered = TRUE) qdel(src) @@ -87,6 +98,23 @@ name = "survival airlock" block_air_zones = 1 +//Door access setter button +/obj/machinery/button/remote/airlock/survival_pod + name = "shelter privacy control" + desc = "You can secure yourself inside the shelter here." + specialfunctions = 4 // 4 is bolts + id = "placeholder_id_do_not_use" //This has to be this way, otherwise it will control ALL doors if left blank. + var/obj/machinery/door/airlock/voidcraft/survival_pod/door + +/obj/machinery/button/remote/airlock/survival_pod/attack_hand(obj/item/weapon/W, mob/user as mob) + if(..()) return 1 //1 is failure on machines (for whatever reason) + if(!door) + var/turf/dT = get_step(src,dir) + door = locate() in dT + if(door) + door.glass = !door.glass + door.opacity = !door.opacity + //Windows /obj/structure/window/reinforced/survival_pod name = "pod window" @@ -112,12 +140,25 @@ name = "table" icon = 'icons/obj/survival_pod.dmi' icon_state = "table" + can_reinforce = FALSE + can_plate = FALSE /obj/structure/table/survival_pod/update_icon() icon_state = "table" +/obj/structure/table/survival_pod/New() + material = get_material_by_name(DEFAULT_WALL_MATERIAL) + verbs -= /obj/structure/table/verb/do_flip + verbs -= /obj/structure/table/proc/do_put + ..() + +/obj/structure/table/survival_pod/dismantle(obj/item/weapon/wrench/W, mob/user) + to_chat(user, "You cannot dismantle \the [src].") + return + //Sleeper /obj/machinery/sleeper/survival_pod + desc = "A limited functionality sleeper, all it can do is put patients into stasis. It lacks the medication and configuration of the larger units." icon = 'icons/obj/survival_pod.dmi' icon_state = "sleeper" stasis_level = 100 //Just one setting @@ -178,6 +219,9 @@ for(var/i in 1 to 5) var/obj/item/weapon/reagent_containers/food/snacks/liquidfood/W = new(src) stock(W) + for(var/i in 1 to 2) + var/obj/item/device/fbp_backup_cell/W = new(src) + stock(W) if(prob(50)) var/obj/item/weapon/storage/pill_bottle/dice/D = new(src) stock(D) diff --git a/code/modules/mining/shelters.dm b/code/modules/mining/shelters.dm index 19ad55f966..5ac1a7f6cd 100644 --- a/code/modules/mining/shelters.dm +++ b/code/modules/mining/shelters.dm @@ -5,6 +5,7 @@ var/whitelisted_turfs var/banned_areas var/banned_objects + var/roof /datum/map_template/shelter/New() . = ..() @@ -38,6 +39,11 @@ sleeping area! Order now, and we'll throw in a TINY FAN, \ absolutely free!" mappath = "maps/submaps/shelters/shelter_1.dmm" + roof = "roof_alpha" + +/datum/map_template/shelter/alpha_roof + shelter_id = "roof_alpha" + mappath = "maps/submaps/shelters/shelter_1_roof.dmm" /datum/map_template/shelter/alpha/New() . = ..() @@ -53,8 +59,14 @@ and a deluxe companion to keep you from getting lonely during \ an ash storm." mappath = "maps/submaps/shelters/shelter_2.dmm" + roof = "roof_beta" + +/datum/map_template/shelter/beta_roof + shelter_id = "roof_beta" + mappath = "maps/submaps/shelters/shelter_2_roof.dmm" /datum/map_template/shelter/beta/New() . = ..() whitelisted_turfs = typecacheof(/turf/simulated/mineral) banned_objects = list() + diff --git a/code/modules/mob/_modifiers/traits.dm b/code/modules/mob/_modifiers/traits.dm index 453c17f321..e510798001 100644 --- a/code/modules/mob/_modifiers/traits.dm +++ b/code/modules/mob/_modifiers/traits.dm @@ -82,4 +82,22 @@ name = "Smaller" desc = "Your body is smaller than average." - icon_scale_percent = 0.9 \ No newline at end of file + icon_scale_percent = 0.9 + +/datum/modifier/trait/colorblind_taj + name = "Colorblind - B+R" + desc = "You are colorblind. You have a minor issue with blue colors and have difficulty recognizing them from red colors." + + client_color = MATRIX_Taj_Colorblind + +/datum/modifier/trait/colorblind_vulp + name = "Colorblind - G+R" + desc = "You are colorblind. You have a severe issue with green colors and have difficulty recognizing them from red colors." + + client_color = MATRIX_Vulp_Colorblind + +/datum/modifier/trait/colorblind_mono + name = "Colorblind - Mono" + desc = "You are colorblind. Your condition is rare, but you can see no colors at all." + + client_color = MATRIX_Monochromia diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index f1ccde0a17..0ecdb2fc20 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -11,7 +11,7 @@ var/input if(!message) - input = sanitize(input(src,"Choose an emote to display.") as text|null) + input = sanitize_or_reflect(input(src,"Choose an emote to display.") as text|null, src) //VOREStation Edit - Reflect too long messages, within reason else input = message if(input) @@ -70,7 +70,7 @@ var/input if(!message) - input = sanitize(input(src, "Choose an emote to display.") as text|null) + input = sanitize_or_reflect(input(src, "Choose an emote to display.") as text|null, src) //VOREStation Edit - Reflect too long messages, within reason else input = message diff --git a/code/modules/mob/gender_vr.dm b/code/modules/mob/gender_vr.dm new file mode 100644 index 0000000000..8312458d08 --- /dev/null +++ b/code/modules/mob/gender_vr.dm @@ -0,0 +1,14 @@ +/datum/gender/herm + key = "herm" + + He = "Shi" + he = "shi" + His = "Hir" + his = "hir" + him = "hir" + has = "has" + is = "is" + does = "does" + himself = "hirself" + s = "s" + hes = "shi's" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/emote_vr.dm b/code/modules/mob/living/carbon/human/emote_vr.dm index 46a12d0d8c..a637dff787 100644 --- a/code/modules/mob/living/carbon/human/emote_vr.dm +++ b/code/modules/mob/living/carbon/human/emote_vr.dm @@ -99,7 +99,7 @@ set name = "Set Gender Identity" set desc = "Sets the pronouns when examined and performing an emote." set category = "IC" - var/new_gender_identity = input("Please select a gender Identity.") as null|anything in list(FEMALE, MALE, NEUTER, PLURAL) + var/new_gender_identity = input("Please select a gender Identity.") as null|anything in list(FEMALE, MALE, NEUTER, PLURAL, HERM) if(!new_gender_identity) return 0 change_gender_identity(new_gender_identity) @@ -110,4 +110,4 @@ set category = "IC" set desc = "Switch tail layer on top." tail_alt = !tail_alt - update_tail_showing() \ No newline at end of file + update_tail_showing() diff --git a/code/modules/mob/living/carbon/human/examine_vr.dm b/code/modules/mob/living/carbon/human/examine_vr.dm index d976dc50b1..44488ae319 100644 --- a/code/modules/mob/living/carbon/human/examine_vr.dm +++ b/code/modules/mob/living/carbon/human/examine_vr.dm @@ -35,6 +35,12 @@ t_he = "it" t_His = "Its" t_his = "its" + if(HERM) + t_He = "Shi" + t_he = "shi" + t_His = "Hir" + t_his = "hir" + t_heavy = "curvy" switch(weight_examine) if(0 to 74) @@ -88,6 +94,10 @@ t_He = "It" t_his = "its" t_His = "Its" + if(HERM) + t_He = "Shi" + t_his = "hir" + t_His = "Hir" switch(nutrition_examine) if(0 to 49) message = "[t_He] [t_is] starving! You can hear [t_his] stomach snarling from across the room!\n" diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index a0276a15ac..d42c26880b 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -3,7 +3,7 @@ if(name != GetVoice()) alt_name = "(as [get_id_name("Unknown")])" - message = sanitize(message) + message = sanitize_or_reflect(message,src) //VOREStation Edit - Reflect too-long messages, within reason ..(message, alt_name = alt_name, whispering = whispering) /mob/living/carbon/human/proc/forcesay(list/append) diff --git a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm index c5b13db327..fd167fc2da 100644 --- a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm +++ b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm @@ -130,7 +130,7 @@ var/list/wrapped_species_by_ref = list() if(!new_gender) return - var/new_gender_identity = input("Please select a gender Identity.", "Shapeshifter Gender Identity") as null|anything in list(FEMALE, MALE, NEUTER, PLURAL) + var/new_gender_identity = input("Please select a gender Identity.", "Shapeshifter Gender Identity") as null|anything in list(FEMALE, MALE, NEUTER, PLURAL, HERM) //VOREStation Edit if(!new_gender_identity) return diff --git a/code/modules/mob/living/carbon/human/species/species_vr.dm b/code/modules/mob/living/carbon/human/species/species_vr.dm index c6a69369fa..fa3bb9762d 100644 --- a/code/modules/mob/living/carbon/human/species/species_vr.dm +++ b/code/modules/mob/living/carbon/human/species/species_vr.dm @@ -33,9 +33,10 @@ var/type = H.nif.type var/durability = H.nif.durability var/list/nifsofts = H.nif.nifsofts + var/list/nif_savedata = H.nif.save_data.Copy() ..() - var/obj/item/device/nif/nif = new type(H,durability) + var/obj/item/device/nif/nif = new type(H,durability,nif_savedata) nif.nifsofts = nifsofts else ..() diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm index 740d72987f..a6047c94c8 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -184,6 +184,8 @@ VOREStation Removal End */ t_she = "They are" else if(H.identifying_gender == NEUTER) t_she = "It is" + else if(H.identifying_gender == HERM) //VOREStation Edit + t_she = "Shi is" switch(stored_shock_by_ref["\ref[H]"]) if(1 to 10) 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 3e6592fd6e..59dfcdf015 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 @@ -1,137 +1,151 @@ -/mob/living/carbon/human/proc/begin_reconstitute_form() //Scree's race ability.in exchange for: No cloning. +/mob/living/carbon/human/proc/reconstitute_form() //Scree's race ability.in exchange for: No cloning. set name = "Reconstitute Form" set category = "Abilities" - if(world.time < last_special) - return - - last_special = world.time + 50 //To prevent button spam. - + // Sanity is mostly handled in chimera_regenerate() + var/confirm = alert(usr, "Are you sure you want to completely reconstruct your form? This process can take up to twenty minutes, depending on how hungry you are, and you will be unable to move.", "Confirm Regeneration", "Yes", "No") if(confirm == "Yes") chimera_regenerate() /mob/living/carbon/human/proc/chimera_regenerate() - var/nutrition_used = nutrition/2 - - if(reviving == TRUE) //If they're already unable to - to_chat(src, "You are already reconstructing, or your body is currently recovering from the intense process of your previous reconstitution.") - return - - if(stat == DEAD) //Uh oh, you died! - if(hasnutriment()) //Let's hope you have nutriment in you.... If not - var/time = (240+960/(1 + nutrition_used/75)) - reviving = TRUE - to_chat(src, "You begin to reconstruct your form. You will not be able to move during this time. It should take aproximately [round(time)] seconds.") - //don't need all the weakened, does_not_breathe, canmove, heal IB crap here like you do for live ones'cause they're DEAD. - - spawn(time SECONDS) - if(src) //Runtime prevention. - if (stat == DEAD) // let's make sure they've not been defibbed or whatever - to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch.") - verbs += /mob/living/carbon/human/proc/hatch - return - else // their revive got aborted by being made not-dead. Remove their cooldown. - to_chat(src, "Your body has recovered from its ordeal, ready to regenerate itself again.") - reviving = FALSE - return - else - return //Something went wrong. - else //Dead until nutrition injected. - to_chat(src, "Your body is too damaged to regenerate without additional nutrients to feed what few living cells remain.") + //If they're already regenerating + switch(reviving) + if(REVIVING_NOW) + to_chat(src, "You are already reconstructing, just wait for the reconstruction to finish!") + return + if(REVIVING_DONE) + to_chat(src, "Your reconstruction is done, but you need to hatch now.") + return + if(REVIVING_COOLDOWN) + to_chat(src, "You can't use that ability again so soon!") return - else if(stat != DEAD) //If they're alive at the time of regenerating. - var/time = (240+960/(1 + nutrition_used/75)) - weakened = 10000 //Since it takes 1 tick to lose one weaken. Due to prior rounding errors, you'd sometimes unweaken before regenning. This fixes that. - reviving = TRUE - canmove = 0 //Make them unable to move. In case they somehow get up before the delay. - to_chat(src, "You begin to reconstruct your form. You will not be able to move during this time. It should take aproximately [round(time)] seconds.") - does_not_breathe = 1 //effectively makes them spaceworthy while regenning + var/nutrition_used = nutrition * 0.5 + var/time = (240+960/(1 + nutrition_used/75)) - spawn(time SECONDS) - if(stat != DEAD) //If they're still alive after regenning. - to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch..") - verbs += /mob/living/carbon/human/proc/hatch - return - else if(stat == DEAD) - if(hasnutriment()) //Let's hope you have nutriment in you.... If not - to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch..") - verbs += /mob/living/carbon/human/proc/hatch - return - else //Dead until nutrition injected. - to_chat(src, "Your body was unable to regenerate, what few living cells remain require additional nutrients to complete the process.") - reviving = FALSE // so they can try again when they're given a kickstart - return - else - return //Something went wrong + //Clicked regen while dead. + if(stat == DEAD) + + //Has nutrition and dead, allow regen. + if(hasnutriment()) + to_chat(src, "You begin to reconstruct your form. You will not be able to move during this time. It should take aproximately [round(time)] seconds.") + + //Scary spawnerization. + reviving = REVIVING_NOW + spawn(time SECONDS) + // Was dead, now not dead. + if(stat != DEAD) + to_chat(src, "Your body has recovered from its ordeal, ready to regenerate itself again.") + reviving = 0 //Not bool + + // Was dead, still dead. + else + to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch.") + verbs |= /mob/living/carbon/human/proc/hatch + reviving = REVIVING_DONE + + //Dead until nutrition injected. + else + to_chat(src, "Your body is too damaged to regenerate without additional nutrients to feed what few living cells remain.") + + //Clicked regen while NOT dead else - return //Something went wrong + to_chat(src, "You begin to reconstruct your form. You will not be able to move during this time. It should take aproximately [round(time)] seconds.") + + //Waiting for regen after being alive + reviving = REVIVING_NOW + spawn(time SECONDS) + + //If they're still alive after regenning. + if(stat != DEAD) + to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch..") + verbs |= /mob/living/carbon/human/proc/hatch + reviving = REVIVING_DONE + + //Was alive, now dead + else if(hasnutriment()) + to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch..") + verbs |= /mob/living/carbon/human/proc/hatch + reviving = REVIVING_DONE + + //Dead until nutrition injected. + else + to_chat(src, "Your body was unable to regenerate, what few living cells remain require additional nutrients to complete the process.") + reviving = 0 //Not boolean /mob/living/carbon/human/proc/hasnutriment() if (bloodstr.has_reagent("nutriment", 30) || src.bloodstr.has_reagent("protein", 15)) //protein needs half as much. For reference, a steak contains 9u protein. - return 1 + return TRUE else if (ingested.has_reagent("nutriment", 60) || src.ingested.has_reagent("protein", 30)) //try forcefeeding them, why not. Less effective. - return 1 - else return 0 + return TRUE + else return FALSE /mob/living/carbon/human/proc/hatch() set name = "Hatch" set category = "Abilities" - if(world.time < last_special) + if(reviving != REVIVING_DONE) + //Hwhat? + verbs -= /mob/living/carbon/human/proc/hatch return - last_special = world.time + 50 //To prevent button spam. - var/confirm = alert(usr, "Are you sure you want to hatch right now? This will be very obvious to anyone in view.", "Confirm Regeneration", "Yes", "No") if(confirm == "Yes") - if(stat == DEAD) //Uh oh, you died! - if(hasnutriment()) //Let's hope you have nutriment in you.... If not - if(src) //Runtime prevention. - chimera_hatch() - visible_message("

The lifeless husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.

") //Bloody hell... - brainloss += 10 //Reviving from dead means you take a lil' brainloss on top of whatever was healed in the revive. - return - else - return //Runtime prevention - else //don't have nutriment to hatch! Or you somehow died in between completing your revive and hitting hatch. - to_chat(src, "Your body was unable to regenerate, what few living cells remain require additional nutrients to complete the process.") - reviving = FALSE // so they can try again when they're given a kickstart + + //Dead when hatching + if(stat == DEAD) + //Check again for nutriment (necessary?) + if(hasnutriment()) + chimera_hatch() + adjustBrainLoss(10) // if they're reviving from dead, they come back with 10 brainloss on top of whatever's unhealed. + visible_message("

The lifeless husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.

") //Bloody hell... return - else if(stat != DEAD) //If they're alive at the time of regenerating. + //Don't have nutriment to hatch! Or you somehow died in between completing your revive and hitting hatch. + else + to_chat(src, "Your body was unable to regenerate, what few living cells remain require additional nutrients to complete the process.") + verbs -= /mob/living/carbon/human/proc/hatch + reviving = 0 //So they can try again when they're given a kickstart + + //Alive when hatching + else chimera_hatch() visible_message("

The dormant husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.

") //Bloody hell... - return - else - return //Runtime prevention. /mob/living/carbon/human/proc/chimera_hatch() - nutrition -= nutrition/2 //Cut their nutrition in half. - var/old_nutrition = nutrition //Since the game is being annoying. + verbs -= /mob/living/carbon/human/proc/hatch to_chat(src, "Your new body awakens, bursting free from your old skin.") - var/T = get_turf(src) - new /obj/effect/gibspawner/human/scree(T) - var/braindamage = brainloss/2 //If you have 100 brainloss, it gives you 50. - does_not_breathe = 0 //start breathing again - revive() // I did have special snowflake code, but this is easier. - weakened = 2 //Not going to let you get up immediately. 2 ticks before you get up. Overrides the above 10000 weaken. + + //Modify and record values (half nutrition and braindamage) + var/old_nutrition = nutrition * 0.5 + var/braindamage = (brainloss * 0.5) //Can only heal half brain damage. + + //I did have special snowflake code, but this is easier. + revive() mutations.Remove(HUSK) nutrition = old_nutrition - brainloss = braindamage //Gives them half their prior brain damage. - update_canmove() + setBrainLoss(braindamage) + + //Drop everything for(var/obj/item/W in src) drop_from_inventory(W) - spawn(3600 SECONDS) //1 hour wait until you can revive. - reviving = FALSE - to_chat(src, "Your body has recovered from the strenuous effort of rebuilding itself.") - verbs -= /mob/living/carbon/human/proc/hatch - return -/obj/effect/gibspawner/human/scree - fleshcolor = "#14AD8B" //Scree blood. + //Unfreeze some things + does_not_breathe = FALSE + update_canmove() + weakened = 2 + + //Visual effects + var/T = get_turf(src) + new /obj/effect/gibspawner/human/xenochimera(T) + + reviving = REVIVING_COOLDOWN + schedule_callback_in(1 HOUR, VARSET_CALLBACK(src, reviving, 0)) + +/obj/effect/gibspawner/human/xenochimera + fleshcolor = "#14AD8B" bloodcolor = "#14AD8B" /mob/living/carbon/human/proc/getlightlevel() //easier than having the same code in like three places @@ -141,7 +155,7 @@ else return 0 /mob/living/carbon/human/proc/handle_feral() - if(handling_hal) return //avoid conflict with actual hallucinations + if(handling_hal) return handling_hal = 1 if(client && feral >= 10) // largely a copy of handle_hallucinations() without the fake attackers. Unlike hallucinations, only fires once - if they're still feral they'll get hit again anyway. @@ -734,6 +748,12 @@ add_attack_logs(src,T,"Shredded (hardvore)") +/mob/living/proc/shred_limb_temp() + set name = "Damage/Remove Prey's Organ (beartrap)" + set desc = "Severely damages prey's organ. If the limb is already severely damaged, it will be torn off." + set category = "Abilities" + shred_limb() + /mob/living/proc/flying_toggle() set name = "Toggle Flight" set desc = "While flying over open spaces, you will use up some nutrition. If you run out nutrition, you will fall. Additionally, you can't fly if you are too heavy." diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm index 56a35acc96..aa8af0e273 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm @@ -22,7 +22,7 @@ tail = "tail" //Scree's tail. Can be disabled in the vore tab by choosing "hide species specific tail sprite" icobase_tail = 1 inherent_verbs = list( - /mob/living/carbon/human/proc/begin_reconstitute_form, + /mob/living/carbon/human/proc/reconstitute_form, /mob/living/carbon/human/proc/sonar_ping, /mob/living/carbon/human/proc/succubus_drain, /mob/living/carbon/human/proc/succubus_drain_finalize, @@ -40,9 +40,9 @@ Most, if not all chimeras possess the ability to undergo some type of regeneration process, at the cost of energy." hazard_low_pressure = -1 //Prevents them from dying normally in space. Special code handled below. - cold_level_1 = -5000 // All cold debuffs are handled below in handle_environment_special - cold_level_2 = -5000 - cold_level_3 = -5000 + cold_level_1 = -1 // All cold debuffs are handled below in handle_environment_special + cold_level_2 = -1 + cold_level_3 = -1 //primitive_form = "Farwa" @@ -56,142 +56,198 @@ /datum/species/xenochimera/handle_environment_special(var/mob/living/carbon/human/H) - if(H.stat == 2) // If they're dead they won't think about being all feral and won't need all the code below. - return + //If they're KO'd/dead, they're probably not thinking a lot about much of anything. + if(!H.stat) + handle_feralness(H) -//handle feral triggers - - if(H.nutrition <= 200||H.traumatic_shock > min(60, H.nutrition/10)) // Stress factors are in play - // If they're hungry, give nag messages. - if (!istype(H.loc, /mob)) // if they're in a mob, skip the hunger stuff so it doesn't mess with drain/absorption modes. - if(H.nutrition < 200 && H.nutrition > 150) - if(prob(0.5)) //A bit of an issue, not too bad. - H << "You feel rather hungry. It might be a good idea to find some some food..." - - else if(H.nutrition <= 150 && H.nutrition > 100) - if(prob(0.5)) //Getting closer, should probably eat some food about now... - H << "You feel like you're going to snap and give in to your hunger soon... It would be for the best to find some [pick("food","prey")] to eat..." - - else if(H.nutrition <= 100) //Should've eaten sooner! - if(H.feral == 0) - H << "Something in your mind flips, your instincts taking over, no longer able to fully comprehend your surroundings as survival becomes your primary concern - you must feed, survive, there is nothing else. Hunt. Eat. Hide. Repeat." - log_and_message_admins("has gone feral due to hunger.", H) - H.feral += 5 //just put them over the threshold by a decent amount for the first chunk. - if(H.stat == CONSCIOUS) - H.emote("twitch") - if(H.feral + H.nutrition < 150) //Feralness increases while this hungry, capped at 50-150 depending on hunger. - H.feral += 1 - - // If they're hurt, chance of snapping. Not if they're straight-up KO'd though. - if (H.stat == CONSCIOUS && H.traumatic_shock >=min(60, H.nutrition/10)) //at 360 nutrition, this is 30 brute/burn, or 18 halloss. Capped at 50 brute/30 halloss - if they take THAT much, no amount of satiation will help them. Also they're fat. - if (2.5*H.halloss >= H.traumatic_shock) //If the majority of their shock is due to halloss, greater chance of snapping. - if(prob(min(10,(0.2 * H.traumatic_shock)))) - if(H.feral == 0) - H << "The pain! It stings! Got to get away! Your instincts take over, urging you to flee, to hide, to go to ground, get away from here..." - log_and_message_admins("has gone feral due to halloss.", H) - H.feral = max(H.feral, H.halloss) //if already more feral than their halloss justifies, don't increase it. - H.emote("twitch") - else if(prob(min(10,(0.1 * H.traumatic_shock)))) - H.emote("twitch") - if(H.feral == 0) - H << "Your fight-or-flight response kicks in, your injuries too much to simply ignore - you need to flee, to hide, survive at all costs - or destroy whatever is threatening you." - H.feral = 2*H.traumatic_shock //Make 'em snap. - log_and_message_admins("has gone feral due to injury.", H) - else - H.feral = max(H.feral, H.traumatic_shock * 2) //keep feralness up to match the current injury state. - - else if (H.jitteriness >= 100) //No stress factors, but there's coffee. Keeps them mildly feral while they're all jittery. - if(H.feral == 0) - H << "Suddenly, something flips - everything that moves is... potential prey. A plaything. This is great! Time to hunt!" - log_and_message_admins("has gone feral due to jitteriness.", H) - if(H.stat == CONSCIOUS) - H.emote("twitch") - H.feral = max(H.feral, H.jitteriness-100) //they'll be twitchy and pouncy while they're under the influence, and feralness won't wear off until they're calm. + //While regenerating + if(H.reviving && H.reviving != REVIVING_COOLDOWN) + H.weakened = 5 + H.canmove = 0 + H.does_not_breathe = TRUE + //Cold/pressure effects when not regenerating else - if (H.feral > 0) //still feral, but all stress factors are gone. Calm them down. - H.feral -= 1 - if (H.feral <=0) //check if they're unferalled - H.feral = 0 - H << "Your thoughts start clearing, your feral urges having passed - for the time being, at least." - log_and_message_admins("is no longer feral.", H) + var/datum/gas_mixture/environment = H.loc.return_air() + var/pressure2 = environment.return_pressure() + var/adjusted_pressure2 = H.calculate_affecting_pressure(pressure2) -// handle what happens while feral + //Very low pressure damage + if(adjusted_pressure2 <= 20) + H.take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") - if(H.feral > 0) //do the following if feral, otherwise no effects. - var/light_amount = H.getlightlevel() //how much light there is in the place + //Cold hurts and gives them pain messages, eventually weakening and paralysing, but doesn't damage or trigger feral. + //NB: 'body_temperature' used here is the 'setpoint' species var + var/temp_diff = body_temperature - H.bodytemperature + if(temp_diff >= 50) + H.shock_stage = min(H.shock_stage + (temp_diff/20), 160) // Divided by 20 is the same as previous numbers, but a full scale + H.eye_blurry = max(5,H.eye_blurry) - H.shock_stage = max(H.shock_stage-(H.feral/20), 0) //if they lose enough health to hit softcrit, handle_shock() will keep resetting this. Otherwise, pissed off critters will lose shock faster than they gain it. - if(light_amount <= 0.5) // in the darkness. No need for custom scene-protection checks as it's just an occational infomessage. - if(prob(2)) //periodic nagmessages just to remind 'em they're still feral - if (H.traumatic_shock >=min(60, H.nutrition/10)) // if hurt, tell 'em to heal up - H << " This place seems safe, secure, hidden, a place to lick your wounds and recover..." - else if(H.nutrition <= 100) //If hungry, nag them to go and find someone or something to eat. - H << " Secure in your hiding place, your hunger still gnaws at you. You need to catch some food..." - else if(H.jitteriness >= 100) - H << " sneakysneakyyesyesyescleverhidingfindthingsyessssss" - else //otherwise, just tell them to keep hiding. - H << " ...safe..." - else // must be in a lit area - var/list/nearby = oviewers(H) - if (nearby.len) // someone's nearby - if(prob(1)) // 1 in 100 chance of doing something so as not to interrupt scenes - var/mob/M = pick(nearby) - if (H.traumatic_shock >=min(60, H.nutrition/10)) //tell 'em to be wary of a random person - H << " You're hurt, in danger, exposed, and [M] looks to be a little too close for comfort..." - else if(H.nutrition <= 250 || H.jitteriness > 0) //tell them a random person in view looks like food. It CAN happen when you're not hungry enough to be feral, especially if coffee is involved. - H << " Every movement, every flick, every sight and sound has your full attention, your hunting instincts on high alert... In fact, [M] looks extremely appetizing..." - if(H.stat == CONSCIOUS) +/datum/species/xenochimera/proc/handle_feralness(var/mob/living/carbon/human/H) + + //Low-ish nutrition has messages and eventually feral + var/hungry = H.nutrition <= 200 + + //At 360 nutrition, this is 30 brute/burn, or 18 halloss. Capped at 50 brute/30 halloss - if they take THAT much, no amount of satiation will help them. Also they're fat. + var/shock = H.traumatic_shock > min(60, H.nutrition/10) + + //Caffeinated xenochimera can become feral and have special messages + var/jittery = H.jitteriness >= 100 + + //To reduce distant object references + var/feral = H.feral + +//Handle feral triggers and pre-feral messages + if(!feral && (hungry || shock || jittery)) + + // If they're hungry, give nag messages (when not bellied) + if(H.nutrition >= 100 && prob(0.5) && !isbelly(H.loc)) + switch(H.nutrition) + if(150 to 200) + to_chat(H,"You feel rather hungry. It might be a good idea to find some some food...") + if(100 to 150) + to_chat(H,"You feel like you're going to snap and give in to your hunger soon... It would be for the best to find some [pick("food","prey")] to eat...") + + // Going feral due to hunger + else if(H.nutrition < 100 && !isbelly(H.loc)) + to_chat(H,"Something in your mind flips, your instincts taking over, no longer able to fully comprehend your surroundings as survival becomes your primary concern - you must feed, survive, there is nothing else. Hunt. Eat. Hide. Repeat.") + log_and_message_admins("has gone feral due to hunger.", H) + feral = 5 + if(!H.stat) + H.emote("twitch") + + // If they're hurt, chance of snapping. + else if(shock) + + //If the majority of their shock is due to halloss, greater chance of snapping. + if(2.5*H.halloss >= H.traumatic_shock) + if(prob(min(10,(0.2 * H.traumatic_shock)))) + to_chat(H,"The pain! It stings! Got to get away! Your instincts take over, urging you to flee, to hide, to go to ground, get away from here...") + log_and_message_admins("has gone feral due to halloss.", H) + feral = 5 + if(!H.stat) H.emote("twitch") + + //Majority due to other damage sources + else if(prob(min(10,(0.1 * H.traumatic_shock)))) + to_chat(H,"Your fight-or-flight response kicks in, your injuries too much to simply ignore - you need to flee, to hide, survive at all costs - or destroy whatever is threatening you.") + feral = 5 + log_and_message_admins("has gone feral due to injury.", H) + if(!H.stat) + H.emote("twitch") + + //No hungry or shock, but jittery + else if(jittery) + to_chat(H,"Suddenly, something flips - everything that moves is... potential prey. A plaything. This is great! Time to hunt!") + feral = 5 + log_and_message_admins("has gone feral due to jitteriness.", H) + if(!H.stat) + H.emote("twitch") + +// Handle being feral + if(feral) + + //Shock due to mostly halloss. More feral. + if(shock && 2.5*H.halloss >= H.traumatic_shock) + feral = max(feral, H.halloss) + + //Shock due to mostly injury. More feral. + else if(shock) + feral = max(feral, H.traumatic_shock * 2) + + //Still jittery? More feral. + if(jittery) + feral = max(feral, H.jitteriness-100) + + //Still hungry? More feral. + if(H.feral + H.nutrition < 150) + feral++ + else + feral = max(0,--feral) + + //Set our real mob's var to our temp var + H.feral = feral + + //Did we just finish being feral? + if(!feral) + to_chat(H,"Your thoughts start clearing, your feral urges having passed - for the time being, at least.") + log_and_message_admins("is no longer feral.", H) + return + + //If they lose enough health to hit softcrit, handle_shock() will keep resetting this. Otherwise, pissed off critters will lose shock faster than they gain it. + H.shock_stage = max(H.shock_stage-(feral/20), 0) + + //Handle light/dark areas + var/turf/T = get_turf(H) + if(!T) + return //Nullspace + var/darkish = T.get_lumcount() <= 0.1 + + //Don't bother doing heavy lifting if we weren't going to give emotes anyway. + if(!prob(1)) + + //This is basically the 'lite' version of the below block. + var/list/nearby = H.living_mobs(world.view) + + //Not in the dark and out in the open. + if(!darkish && isturf(H.loc)) + + //Always handle feral if nobody's around and not in the dark. + if(!nearby.len) H.handle_feral() - else // nobody around - H.handle_feral() - if(prob(2)) //periodic nagmessages - if(H.nutrition <= 100) //If hungry, nag them to go and find someone or something to eat. - H << " Confusing sights and sounds and smells surround you - scary and disorienting it may be, but the drive to hunt, to feed, to survive, compels you." - if(H.stat == CONSCIOUS) - H.emote("twitch") - else if(H.jitteriness >= 100) - H << " yesyesyesyesyesyesgetthethingGETTHETHINGfindfoodsfindpreypounceyesyesyes" - if(H.stat == CONSCIOUS) - H.emote("twitch") - else //otherwise, just tell them to hide. - H << " Confusing sights and sounds and smells surround you, this place is wrong, confusing, frightening. You need to hide, go to ground..." - if(H.stat == CONSCIOUS) - H.emote("twitch") + //Rarely handle feral if someone is around + else if(prob(1)) + H.handle_feral() -////////////////////////////////////////////////////////////////////////////////////////// -///////////WIP CODE TO MAKE XENOCHIMERAS NOT DIE IN SPACE WHILE REGENNING BELOW/////////// //I put WIP, but what I really meant to put was "Finished" -////////////////////////////////////////////////////////////////////////////////////////// + //And bail + return - var/datum/gas_mixture/environment = H.loc.return_air() - var/pressure2 = environment.return_pressure() - var/adjusted_pressure2 = H.calculate_affecting_pressure(pressure2) + // In the darkness or "hidden". No need for custom scene-protection checks as it's just an occational infomessage. + if(darkish || !isturf(H.loc)) + // If hurt, tell 'em to heal up + if (shock) + to_chat(H,"This place seems safe, secure, hidden, a place to lick your wounds and recover...") - if(adjusted_pressure2 <= 20 && H.does_not_breathe) //If they're in a enviroment with no pressure and are not breathing (See: regenerating), don't kill them. - //This is just to prevent them from taking damage if they're in stasis. + //If hungry, nag them to go and find someone or something to eat. + else if(hungry) + to_chat(H,"Secure in your hiding place, your hunger still gnaws at you. You need to catch some food...") - else if(adjusted_pressure2 <= 20) //If they're in an enviroment with no pressure and are NOT in stasis, damage them. - H.take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") + //If jittery, etc + else if(jittery) + to_chat(H,"sneakysneakyyesyesyescleverhidingfindthingsyessssss") - if(H.bodytemperature <= 260 && H.does_not_breathe) //If they're regenerating, don't give them them the negative cold effects - //This is just here to prevent them from getting cold effects + //Otherwise, just tell them to keep hiding. + else + to_chat(H,"...safe...") + + // NOT in the darkness + else + + //Twitch twitch + if(!H.stat) + H.emote("twitch") + + var/list/nearby = H.living_mobs(world.view) + + // Someone/something nearby + if(nearby.len) + var/M = pick(nearby) + if(shock) + to_chat(H,"You're hurt, in danger, exposed, and [M] looks to be a little too close for comfort...") + else if(hungry || jittery) + to_chat(H,"Every movement, every flick, every sight and sound has your full attention, your hunting instincts on high alert... In fact, [M] looks extremely appetizing...") + + // Nobody around + else + if(hungry) + to_chat(H,"Confusing sights and sounds and smells surround you - scary and disorienting it may be, but the drive to hunt, to feed, to survive, compels you.") + else if(jittery) + to_chat(H,"yesyesyesyesyesyesgetthethingGETTHETHINGfindfoodsfindpreypounceyesyesyes") + else + to_chat(H,"Confusing sights and sounds and smells surround you, this place is wrong, confusing, frightening. You need to hide, go to ground...") - else if(H.bodytemperature <= 260) //If they're not in stasis and are cold. Don't really have to add in an exception to cryo cells, as the effects aren't anything /too/ horrible. - var/coldshock = 0 - if(H.bodytemperature <= 260 && H.bodytemperature >= 200) //Chilly. - coldshock = 4 //This will begin to knock them out until they run out of oxygen and suffocate or until someone finds them. - H.eye_blurry = 5 //Blurry vision in the cold. - if(H.bodytemperature <= 199 && H.bodytemperature >= 100) //Extremely cold. Even in somewhere like the server room it takes a while for bodytemp to drop this low. - coldshock = 8 - H.eye_blurry = 5 - if(H.bodytemperature <= 99) //Insanely cold. - coldshock = 16 - H.eye_blurry = 5 - H.shock_stage = min(H.shock_stage + coldshock, 160) //cold hurts and gives them pain messages, eventually weakening and paralysing, but doesn't damage or trigger feral. - return /datum/species/xenochimera/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H) ASSERT(to_copy) @@ -272,10 +328,10 @@ Before they were found they built great cities out of their silk, being united and subjugated in warring factions under great “Star Queens” \ Who forced the working class to build huge, towering cities to attempt to reach the stars, which they worship as gems of great spiritual and magical significance." - hazard_low_pressure = -1 //Prevents them from dying normally in space. Special code handled below. - cold_level_1 = -5000 // All cold debuffs are handled below in handle_environment_special - cold_level_2 = -5000 - cold_level_3 = -5000 + hazard_low_pressure = 20 //Prevents them from dying normally in space. Special code handled below. + cold_level_1 = -1 // All cold debuffs are handled below in handle_environment_special + cold_level_2 = -1 + cold_level_3 = -1 //primitive_form = "Monkey" //I dunno. Replace this in the future. @@ -288,16 +344,9 @@ blood_color = "#0952EF" //Spiders have blue blood. /datum/species/spider/handle_environment_special(var/mob/living/carbon/human/H) - if(H.stat == 2) // If they're dead they won't need anything. + if(H.stat == DEAD) // If they're dead they won't need anything. return - var/datum/gas_mixture/environment = H.loc.return_air() - var/pressure2 = environment.return_pressure() - var/adjusted_pressure2 = H.calculate_affecting_pressure(pressure2) - - if(adjusted_pressure2 <= 20) //If they're in an enviroment with no pressure and are NOT in stasis, like a stasis bodybag, damage them. - H.take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") - if(H.bodytemperature <= 260) //If they're really cold, they go into stasis. var/coldshock = 0 if(H.bodytemperature <= 260 && H.bodytemperature >= 200) //Chilly. diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm index 4f5b839f5d..45a1fe9198 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm @@ -118,11 +118,13 @@ desc = "You simply can't see colors at all, period. You are 100% colorblind." cost = -1 +/datum/modifier/colorblindness_mono + name = "Colorblindness (Monochromancy)" + desc = "You simply can't see colors at all, period. You are 100% colorblind." + /datum/trait/colorblind/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) - if(!H.plane_holder) - H.plane_holder = new(H) - H.plane_holder.set_vis(VIS_D_COLORBLIND,TRUE) //The default is monocrhomia, no need to set values + H.add_modifier(/datum/modifier/trait/colorblind_mono) /datum/trait/colorblind/para_vulp name = "Colorblindness (Para Vulp)" @@ -131,7 +133,7 @@ /datum/trait/colorblind/para_vulp/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) - H.plane_holder.alter_values(VIS_D_COLORBLIND,list("variety" = "Paradise Vulp")) + H.add_modifier(/datum/modifier/trait/colorblind_vulp) /datum/trait/colorblind/para_taj name = "Colorblindness (Para Taj)" @@ -140,4 +142,4 @@ /datum/trait/colorblind/para_taj/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) - H.plane_holder.alter_values(VIS_D_COLORBLIND,list("variety" = "Paradise Taj")) + H.add_modifier(/datum/modifier/trait/colorblind_taj) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e18a498246..266b8ed1f5 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1124,6 +1124,9 @@ default behaviour is: var/list/colors_to_blend = list() for(var/datum/modifier/M in modifiers) if(!isnull(M.client_color)) + if(islist(M.client_color)) //It's a color matrix! Forget it. Just use that one. + animate(client, color = M.client_color, time = 10) + return colors_to_blend += M.client_color if(colors_to_blend.len) diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm index c18041e1a6..5f9d93bb72 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm @@ -23,6 +23,8 @@ var/startdrain = 500 var/max_item_count = 1 var/gulpsound = 'sound/vore/gulp.ogg' + var/digest_brute = 2 + var/digest_burn = 3 /obj/item/device/dogborg/sleeper/New() ..() @@ -504,9 +506,14 @@ if((T.status_flags & GODMODE) || !T.digestable) items_preserved += T else - T.adjustBruteLoss(2) - T.adjustFireLoss(3) - drain(-100) //20*total loss as with voreorgan stats. + var/old_brute = T.getBruteLoss() + var/old_burn = T.getFireLoss() + T.adjustBruteLoss(digest_brute) + T.adjustFireLoss(digest_burn) + var/actual_brute = T.getBruteLoss() - old_brute + var/actual_burn = T.getFireLoss() - old_burn + var/damage_gain = actual_brute + actual_burn + drain(-25 * damage_gain) //25*total loss as with voreorgan stats. update_patient() //Pick a random item to deal with (if there are any) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_vr.dm b/code/modules/mob/living/silicon/robot/drone/drone_vr.dm deleted file mode 100644 index 77e2a4ed41..0000000000 --- a/code/modules/mob/living/silicon/robot/drone/drone_vr.dm +++ /dev/null @@ -1,9 +0,0 @@ -/mob/living/silicon/robot/drone - can_enter_vent_with = list( - /obj/item/device/radio/borg, - /obj/machinery/camera, - /obj/item/device/camera/siliconcam/drone_camera, - /obj/item/weapon/robot_module/drone, - /obj/item/weapon/cell, - /obj/screen/movable/ability_master, - /obj/item/weapon/card/id/synthetic) diff --git a/code/modules/mob/living/simple_animal/aliens/mimic.dm b/code/modules/mob/living/simple_animal/aliens/mimic.dm index c13e1721ce..fff75ecbe7 100644 --- a/code/modules/mob/living/simple_animal/aliens/mimic.dm +++ b/code/modules/mob/living/simple_animal/aliens/mimic.dm @@ -49,10 +49,7 @@ qdel(src) /mob/living/simple_animal/hostile/mimic/MouseEntered(location, control, params) - ..() - closeToolTip(usr) - // ideally, we'd remove the code in ..() that opens the tooltip, - // but then we'd need to duplicate all the other code in ..() + return // Do not call parent: Mimics shouldn't have tooltips! // // Crate Mimic diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider.dm b/code/modules/mob/living/simple_animal/animals/giant_spider.dm index defdfb9644..50b6300c7b 100644 --- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/animals/giant_spider.dm @@ -84,13 +84,16 @@ Nurse Family var/atom/cocoon_target var/egg_inject_chance = 5 -// VOREStation Edit - Keep Nurse Hat Spiders -/mob/living/simple_animal/hostile/giant_spider/nurse/medical +/mob/living/simple_animal/hostile/giant_spider/nurse/hat desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes and a tiny nurse hat." icon_state = "nursemed" icon_living = "nursemed" icon_dead = "nursemed_dead" + maxHealth = 50 + health = 50 + +// VOREStation Edit melee_damage_lower = 8 melee_damage_upper = 16 poison_type = "tramadol" diff --git a/code/modules/mob/living/simple_animal/vore/badboi.dm b/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm similarity index 82% rename from code/modules/mob/living/simple_animal/vore/badboi.dm rename to code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm index 7a48eed575..a7ee0bcd7d 100644 --- a/code/modules/mob/living/simple_animal/vore/badboi.dm +++ b/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/badboi +/mob/living/simple_animal/hostile/corrupthound name = "corrupt hound" desc = "Good boy machine broke. This is definitely no good news for the organic lifeforms in vicinity." icon = 'icons/mob/vore64x32.dmi' @@ -48,6 +48,9 @@ minbodytemp = 150 maxbodytemp = 900 + var/image/eye_layer = null + + vore_active = TRUE vore_capacity = 1 vore_pounce_chance = 15 @@ -57,7 +60,7 @@ loot_list = list(/obj/item/borg/upgrade/syndicate = 6, /obj/item/borg/upgrade/vtec = 6, /obj/item/weapon/material/knife/ritual = 6, /obj/item/weapon/disk/nifsoft/compliance = 6) -/mob/living/simple_animal/hostile/badboi/prettyboi +/mob/living/simple_animal/hostile/corrupthound/prettyboi name = "corrupt corrupt hound" desc = "Bad boy machine broke as well. Seems an attempt was made to achieve a less threatening look, and this one is definitely having some conflicting feelings about it." icon_state = "prettyboi" @@ -76,18 +79,37 @@ say_got_target = list("HERE COMES BIG MEAN HUG MACHINE!", "I'LL BE GENTLE!", "FUEL ME FRIEND!", "I*M SO SORRY!", "YUMMY TREAT DETECTED!", "LOVE ME!", "Not again. NOT AGAIN!") -/mob/living/simple_animal/hostile/badboi/isSynthetic() +/mob/living/simple_animal/hostile/corrupthound/isSynthetic() return TRUE -/mob/living/simple_animal/hostile/badboi/speech_bubble_appearance() +/mob/living/simple_animal/hostile/corrupthound/speech_bubble_appearance() return "synthetic_evil" -/mob/living/simple_animal/hostile/badboi/PunchTarget() +/mob/living/simple_animal/hostile/corrupthound/PunchTarget() if(istype(target_mob,/mob/living/simple_animal/mouse)) return EatTarget() else ..() -/mob/living/simple_animal/hostile/badboi/death(gibbed, deathmessage = "shudders and collapses!") +/mob/living/simple_animal/hostile/corrupthound/proc/add_eyes() + if(!eye_layer) + eye_layer = image(icon, "badboi-eyes") + eye_layer.plane = PLANE_LIGHTING_ABOVE + add_overlay(eye_layer) + +/mob/living/simple_animal/hostile/corrupthound/proc/remove_eyes() + cut_overlay(eye_layer) + +/mob/living/simple_animal/hostile/corrupthound/New() + add_eyes() + ..() + +/mob/living/simple_animal/hostile/corrupthound/death(gibbed, deathmessage = "shudders and collapses!") .=..() resting = 0 icon_state = icon_dead + +/mob/living/simple_animal/hostile/corrupthound/update_icon() + . = ..() + remove_eyes() + if(stat == CONSCIOUS && !resting) + add_eyes() diff --git a/code/modules/mob/living/simple_animal/vore/otie.dm b/code/modules/mob/living/simple_animal/vore/otie.dm index 988855cac2..649e064e85 100644 --- a/code/modules/mob/living/simple_animal/vore/otie.dm +++ b/code/modules/mob/living/simple_animal/vore/otie.dm @@ -46,6 +46,9 @@ pixel_x = -16 pixel_y = 0 + var/glowyeyes = FALSE + var/image/eye_layer = null + var/eyetype var/mob/living/carbon/human/friend var/tamed = 0 var/tame_chance = 50 //It's a fiddy-fiddy default you may get a buddy pal or you may get mauled and ate. Win-win! @@ -78,6 +81,8 @@ max_co2 = 0 min_n2 = 0 max_n2 = 0 + glowyeyes = TRUE + eyetype = "photie" /mob/living/simple_animal/otie/friendly //gets the pet2tame feature and doesn't kill you right away name = "otie" @@ -116,6 +121,8 @@ max_co2 = 0 min_n2 = 0 max_n2 = 0 + glowyeyes = TRUE + eyetype = "photie" /mob/living/simple_animal/otie/security //tame by default unless you're a marked crimester. can be befriended to follow with pets tho. name = "guard otie" @@ -128,6 +135,8 @@ maxHealth = 200 //armored or something health = 200 tamed = 1 + glowyeyes = TRUE + eyetype = "sotie" loot_list = list(/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/suit/armor/vest/alt) vore_pounce_chance = 60 // Good boys don't do too much police brutality. @@ -151,6 +160,8 @@ max_co2 = 0 min_n2 = 0 max_n2 = 0 + glowyeyes = TRUE + eyetype = "sotie" /mob/living/simple_animal/otie/PunchTarget() if(istype(target_mob,/mob/living/simple_animal/mouse)) @@ -322,8 +333,27 @@ else ..() -/mob/living/simple_animal/otie/death(gibbed, deathmessage = "dies!") - resting = 0 - icon_state = icon_dead - update_icon() +/mob/living/simple_animal/otie/proc/add_eyes() + if(!eye_layer) + eye_layer = image(icon, "[eyetype]-eyes") + eye_layer.plane = PLANE_LIGHTING_ABOVE + add_overlay(eye_layer) + +/mob/living/simple_animal/otie/proc/remove_eyes() + cut_overlay(eye_layer) + +/mob/living/simple_animal/otie/New() + if(glowyeyes) + add_eyes() ..() + +/mob/living/simple_animal/otie/update_icon() + . = ..() + remove_eyes() + if(glowyeyes && stat == CONSCIOUS && !resting) + add_eyes() + +/mob/living/simple_animal/otie/death(gibbed, deathmessage = "dies!") + .=..() + resting = 0 + icon_state = icon_dead \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/vore/rous.dm b/code/modules/mob/living/simple_animal/vore/rat.dm similarity index 93% rename from code/modules/mob/living/simple_animal/vore/rous.dm rename to code/modules/mob/living/simple_animal/vore/rat.dm index 9b47810f36..804e5b107c 100644 --- a/code/modules/mob/living/simple_animal/vore/rous.dm +++ b/code/modules/mob/living/simple_animal/vore/rat.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/rous +/mob/living/simple_animal/hostile/rat name = "giant rat" desc = "In what passes for a hierarchy among verminous rodents, this one is king." tt_desc = "Mus muscular" @@ -41,6 +41,6 @@ vore_pounce_chance = 45 vore_icons = SA_ICON_LIVING | SA_ICON_REST -/mob/living/simple_animal/hostile/rous/death() +/mob/living/simple_animal/hostile/rat/death() playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 50, 1) ..() diff --git a/code/modules/mob/living/simple_animal/vore/wah.dm b/code/modules/mob/living/simple_animal/vore/redpanda.dm similarity index 92% rename from code/modules/mob/living/simple_animal/vore/wah.dm rename to code/modules/mob/living/simple_animal/vore/redpanda.dm index 316441edd7..6047425f18 100644 --- a/code/modules/mob/living/simple_animal/vore/wah.dm +++ b/code/modules/mob/living/simple_animal/vore/redpanda.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/wah +/mob/living/simple_animal/redpanda name = "red panda" desc = "It's a wah! Beware of doom pounce!" tt_desc = "Ailurus fulgens" @@ -29,7 +29,7 @@ emote_see = list("trundles around","rears up onto their hind legs and pounces a bug") // Activate Noms! -/mob/living/simple_animal/wah +/mob/living/simple_animal/redpanda vore_active = 1 vore_bump_chance = 10 vore_bump_emote = "playfully lunges at" @@ -37,7 +37,7 @@ vore_default_mode = DM_HOLD // above will only matter if someone toggles it anyway vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/wah/fae +/mob/living/simple_animal/redpanda/fae name = "dark wah" desc = "Ominous, but still cute!" tt_desc = "Ailurus brattus" diff --git a/code/modules/mob/living/simple_animal/vore/snake.dm b/code/modules/mob/living/simple_animal/vore/snake.dm index 7f753bc92f..8d60989478 100644 --- a/code/modules/mob/living/simple_animal/vore/snake.dm +++ b/code/modules/mob/living/simple_animal/vore/snake.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/snake +/mob/living/simple_animal/hostile/giant_snake name = "giant snake" desc = "Snakes. Why did it have to be snakes?" icon = 'icons/mob/vore64x64.dmi' @@ -21,7 +21,7 @@ pixel_y = -16 // Activate Noms! -/mob/living/simple_animal/hostile/snake +/mob/living/simple_animal/hostile/giant_snake vore_active = 1 vore_pounce_chance = 25 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 9f316ba184..8471dd8307 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -34,6 +34,11 @@ if(hud_used) qdel(hud_used) //remove the hud objects hud_used = new /datum/hud(src) + if(client.prefs && client.prefs.client_fps) + client.fps = client.prefs.client_fps + else + client.fps = 0 // Results in using the server FPS + next_move = 1 disconnect_time = null //clear the disconnect time sight |= SEE_SELF @@ -56,6 +61,11 @@ client.screen += plane_holder.plane_masters recalculate_vis() + // AO support + var/ao_enabled = client.is_preference_enabled(/datum/client_preference/ambient_occlusion) + plane_holder.set_ao(VIS_OBJS, ao_enabled) + plane_holder.set_ao(VIS_MOBS, ao_enabled) + //set macro to normal incase it was overriden (like cyborg currently does) client.set_hotkeys_macro("macro", "hotkeymode") diff --git a/code/modules/mob/mob_planes.dm b/code/modules/mob/mob_planes.dm index 8ffc15bc9f..7534ca176c 100644 --- a/code/modules/mob/mob_planes.dm +++ b/code/modules/mob/mob_planes.dm @@ -11,6 +11,8 @@ my_mob = this_guy //It'd be nice to lazy init these but some of them are important to just EXIST. Like without ghost planemaster, you can see ghosts. Go figure. + + // 'Utility' planes plane_masters[VIS_FULLBRIGHT] = new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects) plane_masters[VIS_LIGHTING] = new /obj/screen/plane_master/lighting //Lighting system (but different!) plane_masters[VIS_GHOSTS] = new /obj/screen/plane_master/ghosts //Ghosts! @@ -31,11 +33,13 @@ plane_masters[VIS_ADMIN2] = new /obj/screen/plane_master{plane = PLANE_ADMIN2} //For admin use plane_masters[VIS_ADMIN3] = new /obj/screen/plane_master{plane = PLANE_ADMIN3} //For admin use - plane_masters[VIS_D_COLORBLIND] = new /obj/screen/plane_master/colorblindness //Colorblindness (affects world) - plane_masters[VIS_D_COLORBLINDI]= new /obj/screen/plane_master/colorblindness/items //Colorblindness (items in HUD, subplane of above, don't toggle) - plane_masters[VIS_MESONS] = new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings. + // Real tangible stuff planes + plane_masters[VIS_TURFS] = new /obj/screen/plane_master/main{plane = TURF_PLANE} + plane_masters[VIS_OBJS] = new /obj/screen/plane_master/main{plane = OBJ_PLANE} + plane_masters[VIS_MOBS] = new /obj/screen/plane_master/main{plane = MOB_PLANE} + ..() /datum/plane_holder/Destroy() @@ -70,6 +74,17 @@ for(var/SP in subplanes) set_vis(which = SP, new_alpha = new_alpha) +/datum/plane_holder/proc/set_ao(var/which = null, var/enabled = FALSE) + ASSERT(which) + var/obj/screen/plane_master/PM = plane_masters[which] + if(!PM) + crash_with("Tried to set_ao [which] in plane_holder on [my_mob]!") + PM.set_ambient_occlusion(enabled) + if(PM.sub_planes) + var/list/subplanes = PM.sub_planes + for(var/SP in subplanes) + set_ao(SP, enabled) + /datum/plane_holder/proc/alter_values(var/which = null, var/list/values = null) ASSERT(which) var/obj/screen/plane_master/PM = plane_masters[which] @@ -124,6 +139,11 @@ new_alpha = sanitize_integer(new_alpha, 0, 255, 255) alpha = new_alpha +/obj/screen/plane_master/proc/set_ambient_occlusion(var/enabled = FALSE) + filters -= AMBIENT_OCCLUSION + if(enabled) + filters += AMBIENT_OCCLUSION + /obj/screen/plane_master/proc/alter_plane_values() return //Stub @@ -152,55 +172,8 @@ plane = PLANE_GHOSTS desired_alpha = 127 //When enabled, they're like half-transparent -//'Normal'ness v v v -//Various types of colorblindness R2R R2G R2B G2R G2G G2B B2R B2G B2B -#define MATRIX_Monochromia list(0.33, 0.33, 0.33, 0.59, 0.59, 0.59, 0.11, 0.11, 0.11) -#define MATRIX_Protanopia list(0.57, 0.43, 0, 0.56, 0.44, 0, 0, 0.24, 0.76) -#define MATRIX_Protanomaly list(0.82, 0.18, 0, 0.33, 0.67, 0, 0, 0.13, 0.88) -#define MATRIX_Deuteranopia list(0.63, 0.38, 0, 0.70, 0.30, 0, 0, 0.30, 0.70) -#define MATRIX_Deuteranomaly list(0.80, 0.20, 0, 0.26, 0.74, 0, 0, 0.14, 0.86) -#define MATRIX_Tritanopia list(0.95, 0.05, 0, 0, 0.43, 0.57, 0, 0.48, 0.53) -#define MATRIX_Tritanomaly list(0.97, 0.03, 0, 0, 0.73, 0.27, 0, 0.18, 0.82) -#define MATRIX_Achromatopsia list(0.30, 0.59, 0.11, 0.30, 0.59, 0.11, 0.30, 0.59, 0.11) -#define MATRIX_Achromatomaly list(0.62, 0.32, 0.06, 0.16, 0.78, 0.06, 0.16, 0.32, 0.52) -#define MATRIX_Vulp_Colorblind list(0.50, 0.40, 0.10, 0.50, 0.40, 0.10, 0, 0.20, 0.80) -#define MATRIX_Taj_Colorblind list(0.40, 0.20, 0.40, 0.40, 0.60, 0, 0.20, 0.20, 0.60) - ///////////////// -//Colorblindness uses special color shenanigans -/obj/screen/plane_master/colorblindness - plane = PLANE_WORLD //Affects the main game world - color = MATRIX_Monochromia - alpha = 255 //Starts out nice and opaque - invisibility = 101 //Can't see it usually - mouse_opacity = 1 //Don't make entire world not visible pls - invis_toggle = TRUE - sub_planes = list(VIS_D_COLORBLINDI) - var/list/varieties = list( - "Monochromia" = MATRIX_Monochromia, - "Protanopia" = MATRIX_Protanopia, - "Protanomaly" = MATRIX_Protanomaly, - "Deuteranopia" = MATRIX_Deuteranopia, - "Deuteranomaly" = MATRIX_Deuteranomaly, - "Tritanopia" = MATRIX_Tritanopia, - "Tritanomaly" = MATRIX_Tritanomaly, - "Achromatopsia" = MATRIX_Achromatopsia, - "Achromatomaly" = MATRIX_Achromatomaly, - "Paradise Vulp" = MATRIX_Vulp_Colorblind, - "Paradise Taj" = MATRIX_Taj_Colorblind - ) - -/obj/screen/plane_master/colorblindness/alter_plane_values(var/variety = null) - var/new_matrix = varieties[variety] - if(!new_matrix) return - - color = new_matrix - -/obj/screen/plane_master/colorblindness/proc/debug_variety() - var/choice = input(usr,"Pick a type of colorblindness","Which?") as null|anything in varieties - if(choice) - color = varieties[choice] - -/obj/screen/plane_master/colorblindness/items - plane = PLANE_PLAYER_HUD_ITEMS - sub_planes = null +//The main game planes start normal and visible +/obj/screen/plane_master/main + alpha = 255 + mouse_opacity = 1 diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 665f95f694..5691cf3ebc 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -2,9 +2,10 @@ /mob/new_player var/ready = 0 - var/spawning = 0//Referenced when you want to delete the new_player later on in the code. - var/totalPlayers = 0 //Player counts for the Lobby tab + var/spawning = 0 //Referenced when you want to delete the new_player later on in the code. + var/totalPlayers = 0 //Player counts for the Lobby tab var/totalPlayersReady = 0 + var/show_hidden_jobs = 0 //Show jobs that are set to "Never" in preferences var/datum/browser/panel universal_speak = 1 @@ -115,7 +116,7 @@ if(alert(src,"Are you sure you wish to observe? You will have to wait 1 minute before being able to respawn!","Player Setup","Yes","No") == "Yes") if(!client) return 1 - + //Make a new mannequin quickly, and allow the observer to take the appearance var/mob/living/carbon/human/dummy/mannequin = new() client.prefs.dress_preview_mob(mannequin) @@ -291,6 +292,10 @@ handle_server_news() return + if(href_list["hidden_jobs"]) + show_hidden_jobs = !show_hidden_jobs + LateChoices() + /mob/new_player/proc/handle_server_news() if(!client) return @@ -421,10 +426,18 @@ dat += "The station is currently undergoing crew transfer procedures.
" dat += "Choose from the following open/valid positions:
" + dat += "[show_hidden_jobs ? "Hide":"Show"] Hidden Jobs.
" for(var/datum/job/job in job_master.occupations) if(job && IsJobAvailable(job.title)) + // Checks for jobs with minimum age requirements if(job.minimum_character_age && (client.prefs.age < job.minimum_character_age)) continue + // Checks for jobs set to "Never" in preferences //TODO: Figure out a better way to check for this + if(!(client.prefs.GetJobDepartment(job, 1) & job.flag)) + if(!(client.prefs.GetJobDepartment(job, 2) & job.flag)) + if(!(client.prefs.GetJobDepartment(job, 3) & job.flag)) + if(!show_hidden_jobs && job.title != "Assistant") // Assistant is always an option + continue var/active = 0 // Only players with the job assigned and AFK for less than 10 minutes count as active for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 * 60 * 10) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 206450c909..0b20c6cb7f 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -21,8 +21,8 @@ if(say_disabled) //This is here to try to identify lag problems usr << "Speech is currently admin-disabled." return - - message = sanitize(message) + + message = sanitize_or_reflect(message,src) //VOREStation Edit - Reflect too-long messages (within reason) set_typing_indicator(FALSE) if(use_me) diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index f38c20bb82..fbf9a9febb 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -11,7 +11,7 @@ usr << "Speech is currently admin-disabled." return - message = sanitize(message) + message = sanitize_or_reflect(message,src) //VOREStation Edit - Reflect too-long messages (within reason) if(!message) return @@ -31,7 +31,7 @@ var/input if(!message) - input = sanitize(input(src,"Choose an emote to display.") as text|null) + input = sanitize_or_reflect(input(src,"Choose an emote to display.") as text|null, src) else input = message @@ -42,6 +42,8 @@ return if (message) + message = say_emphasis(message) + var/list/vis = get_mobs_and_objs_in_view_fast(get_turf(src),1,2) //Turf, Range, and type 2 is emote var/list/vis_mobs = vis["mobs"] var/list/vis_objs = vis["objs"] @@ -59,3 +61,31 @@ /mob/proc/emote_vr(var/act, var/type, var/message) //This would normally go in say.dm if(act == "me") return custom_emote_vr(type, message) + +#define MAX_HUGE_MESSAGE_LEN 8192 +#define POST_DELIMITER_STR "\<\>" +/proc/sanitize_or_reflect(message,user) + //Way too long to send + if(length(message) > MAX_HUGE_MESSAGE_LEN) + fail_to_chat(user) + return + + message = sanitize(message, max_length = MAX_HUGE_MESSAGE_LEN) + + //Came back still too long to send + if(length(message) > MAX_MESSAGE_LEN) + fail_to_chat(user,message) + return null + else + return message + +/proc/fail_to_chat(user,message) + if(!message) + to_chat(user,"Your message was NOT SENT, either because it was FAR too long, or sanitized to nothing at all.") + return + + var/length = length(message) + var/posts = Ceiling(length/MAX_MESSAGE_LEN) + to_chat(user,message) + to_chat(user,"^ This message was NOT SENT ^ -- It was [length] characters, and the limit is [MAX_MESSAGE_LEN]. It would fit in [posts] separate messages.") +#undef MAX_HUGE_MESSAGE_LEN diff --git a/code/modules/nifsoft/software/13_soulcatcher.dm b/code/modules/nifsoft/software/13_soulcatcher.dm index 672710a07c..4399a31f3a 100644 --- a/code/modules/nifsoft/software/13_soulcatcher.dm +++ b/code/modules/nifsoft/software/13_soulcatcher.dm @@ -230,6 +230,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M brainmob.dna = H.dna + brainmob.ooc_notes = H.ooc_notes brainmob.timeofhostdeath = H.timeofdeath SStranscore.m_backup(brainmob.mind,0) //It does ONE, so medical will hear about it. @@ -356,12 +357,10 @@ return ..(direction) /mob/living/carbon/brain/caught_soul/say(var/message) - if(parent_mob) return ..() if(silent) return FALSE soulcatcher.say_into(message,src,eyeobj) /mob/living/carbon/brain/caught_soul/emote(var/act,var/m_type=1,var/message = null) - if(parent_mob) return ..() if(silent) return FALSE if (act == "me") if(silent) diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index d10ed6e755..92e102d921 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -42,7 +42,7 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ var/lifelike // If set, appears organic. var/skin_tone // If set, applies skin tone rather than part color var/blood_color = "#030303" - var/list/species_cannot_use = list(SPECIES_TESHARI, SPECIES_PROMETHEAN) //VOREStation Edit + var/list/species_cannot_use = list(SPECIES_TESHARI, SPECIES_PROMETHEAN, SPECIES_XENOCHIMERA) //VOREStation Edit var/list/monitor_styles //If empty, the model of limbs offers a head compatible with monitors. var/parts = BP_ALL //Defines what parts said brand can replace on a body. var/health_hud_intensity = 1 // Intensity modifier for the health GUI indicator. diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm index 32242e9669..7eb9843cc3 100644 --- a/code/modules/paperwork/carbonpaper.dm +++ b/code/modules/paperwork/carbonpaper.dm @@ -2,8 +2,8 @@ name = "paper" icon_state = "paper_stack" item_state = "paper" - var copied = 0 - var iscopy = 0 + var/copied = 0 + var/iscopy = 0 /obj/item/weapon/paper/carbon/update_icon() @@ -48,4 +48,4 @@ copy.update_icon() c.update_icon() else - usr << "There are no more carbon copies attached to this paper!" \ No newline at end of file + usr << "There are no more carbon copies attached to this paper!" diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 4c0f6bed0e..488bb7c8b6 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -131,7 +131,7 @@ var/global/photo_count = 0 var/icon_on = "camera" var/icon_off = "camera_off" var/size = 3 - var/picture_planes = list(PLANE_WORLD) + var/picture_planes = list() /obj/item/device/camera/verb/change_size() set name = "Set Photo Focus" @@ -182,7 +182,7 @@ var/global/photo_count = 0 // As well as anything that isn't invisible. for(var/atom/A in the_turf) if(A.invisibility) continue - if(!(A.plane in picture_planes)) continue + if(A.plane > 0 && !(A.plane in picture_planes)) continue atoms.Add(A) // Sort the atoms into their layers diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 2de88c942d..8478aac50c 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -64,6 +64,8 @@ desc = "A control terminal for the area electrical systems." icon = 'icons/obj/power_vr.dmi' //VOREStation Edit - New Icon icon_state = "apc0" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER anchored = 1 use_power = 0 req_access = list(access_engine_equip) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index b3d861d4db..4b611e990f 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -161,7 +161,7 @@ layer = ABOVE_MOB_LAYER use_power = 2 idle_power_usage = 2 - active_power_usage = 20 + active_power_usage = 20 // VOREStation Edit - Keep lights at 20 power power_channel = LIGHT //Lights are calc'd via area so they dont need to be in the machine list var/on = 0 // 1 if on, 0 if off var/brightness_range = 10 // luminosity when on, also used in power calculation // VOREStation Edit - Put light range back how it was for now. diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 9dbec38fe9..7354faea9e 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -56,7 +56,6 @@ var/global/list/rad_collectors = list() else user << "The controls are locked!" return -..() /obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user) diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 94cf0ab21e..0c3c76caaf 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -472,7 +472,7 @@ /obj/item/ammo_magazine/m44 name = "magazine (.44)" - icon_state = "44" + icon_state = "m44" origin_tech = list(TECH_COMBAT = 2) mag_type = MAGAZINE caliber = ".44" diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 087543091d..183ead39d1 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -41,6 +41,9 @@ update_icon() +/obj/item/weapon/gun/projectile/shotgun/pump/slug + ammo_type = /obj/item/ammo_casing/a12g + /obj/item/weapon/gun/projectile/shotgun/pump/combat name = "combat shotgun" desc = "Built for close quarters combat, the Hephaestus Industries KS-40 is widely regarded as a weapon of choice for repelling boarders. Uses 12g rounds." diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 3587e2f36a..60179e895f 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -327,6 +327,12 @@ if(default_deconstruction_crowbar(user, O)) return + //vorestation edit start - for solargrubs + if (istype(O, /obj/item/device/multitool)) + return ..() + //vorestation edit end + + if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ istype(O,/obj/item/weapon/reagent_containers/food/drinks/glass2) || \ istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) diff --git a/code/modules/reagents/Chemistry-Recipes_vr.dm b/code/modules/reagents/Chemistry-Recipes_vr.dm index fe8731a0a1..58f49f3fc7 100644 --- a/code/modules/reagents/Chemistry-Recipes_vr.dm +++ b/code/modules/reagents/Chemistry-Recipes_vr.dm @@ -56,7 +56,7 @@ /datum/chemical_reaction/xenolazarus/on_reaction(var/datum/reagents/holder, var/created_volume) //literally all this does is mash the regenerate button if(ishuman(holder.my_atom)) var/mob/living/carbon/human/H = holder.my_atom - if(H.stat == DEAD && (/mob/living/carbon/human/proc/begin_reconstitute_form in H.verbs)) //no magical regen for non-regenners, and can't force the reaction on live ones + if(H.stat == DEAD && (/mob/living/carbon/human/proc/reconstitute_form in H.verbs)) //no magical regen for non-regenners, and can't force the reaction on live ones if(H.hasnutriment()) // make sure it actually has the conditions to revive if(!H.reviving) // if it's not reviving, start doing so H.visible_message("[H] shudders briefly, then relaxes, faint movements stirring within.") @@ -320,7 +320,8 @@ var/mob_path = /mob/living/simple_animal var/blocked = list( /mob/living/simple_animal/hostile/mimic, - /mob/living/simple_animal/hostile/alien/queen + /mob/living/simple_animal/hostile/alien/queen, + /mob/living/simple_animal/shadekin )//exclusion list for things you don't want the reaction to create. var/list/voremobs = typesof(mob_path) - mob_path - blocked // list of possible hostile mobs diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 5ec7aae23a..45af53eb87 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -5,6 +5,8 @@ desc = "..." icon = 'icons/obj/objects.dmi' icon_state = "watertank" + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER density = 1 anchored = 0 pressure_resistance = 2*ONE_ATMOSPHERE diff --git a/code/modules/research/designs_vr.dm b/code/modules/research/designs_vr.dm index 02b71645da..e074323cbd 100644 --- a/code/modules/research/designs_vr.dm +++ b/code/modules/research/designs_vr.dm @@ -180,6 +180,61 @@ build_path = /obj/item/weapon/circuitboard/quantumpad sort_string = "HABAH" +//////Micro mech stuff +/datum/design/circuit/mecha/gopher_main + name = "'Gopher' central control" + id = "gopher_main" + build_path = /obj/item/weapon/circuitboard/mecha/gopher/main + sort_string = "NAAEA" + +/datum/design/circuit/mecha/gopher_peri + name = "'Gopher' peripherals control" + id = "gopher_peri" + build_path = /obj/item/weapon/circuitboard/mecha/gopher/peripherals + sort_string = "NAAEB" + +/datum/design/circuit/mecha/polecat_main + name = "'Polecat' central control" + id = "polecat_main" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/mecha/polecat/main + sort_string = "NAAFA" + +/datum/design/circuit/mecha/polecat_peri + name = "'Polecat' peripherals control" + id = "polecat_peri" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/mecha/polecat/peripherals + sort_string = "NAAFB" + +/datum/design/circuit/mecha/polecat_targ + name = "'Polecat' weapon control and targeting" + id = "polecat_targ" + req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) + build_path = /obj/item/weapon/circuitboard/mecha/polecat/targeting + sort_string = "NAAFC" + +/datum/design/circuit/mecha/weasel_main + name = "'Weasel' central control" + id = "weasel_main" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/mecha/weasel/main + sort_string = "NAAGA" + +/datum/design/circuit/mecha/weasel_peri + name = "'Weasel' peripherals control" + id = "weasel_peri" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/mecha/weasel/peripherals + sort_string = "NAAGB" + +/datum/design/circuit/mecha/weasel_targ + name = "'Weasel' weapon control and targeting" + id = "weasel_targ" + req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) + build_path = /obj/item/weapon/circuitboard/mecha/weasel/targeting + sort_string = "NAAGC" + ////// RIGSuit Stuff /* /datum/design/item/rig diff --git a/code/modules/resleeving/infocore_records.dm b/code/modules/resleeving/infocore_records.dm index caa1e61540..834b067e9d 100644 --- a/code/modules/resleeving/infocore_records.dm +++ b/code/modules/resleeving/infocore_records.dm @@ -26,6 +26,7 @@ var/nif_path var/nif_durability var/list/nif_software + var/list/nif_savedata = list() var/one_time = FALSE @@ -42,7 +43,7 @@ cryo_at = 0 //Mental stuff the game doesn't keep mentally - if(istype(M)) + if(istype(M) || istype(M,/mob/living/carbon/brain/caught_soul)) id_gender = M.identifying_gender languages = M.languages.Copy() mind_oocnotes = M.ooc_notes @@ -55,6 +56,7 @@ var/datum/nifsoft/nifsoft = N nifsofts += nifsoft.type nif_software = nifsofts + nif_savedata = M.nif.save_data.Copy() last_update = world.time @@ -76,6 +78,7 @@ var/body_oocnotes var/list/limb_data = 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) var/list/organ_data = list(O_HEART, O_EYES, O_LUNGS, O_BRAIN) + var/list/genetic_modifiers = list() var/toocomplex var/sizemult var/weight @@ -174,6 +177,12 @@ //Just set the data to this. 0:normal, 1:assisted, 2:mechanical, 3:digital organ_data[org] = I.robotic + //Genetic modifiers + for(var/modifier in M.modifiers) + var/datum/modifier/mod = modifier + if(mod.flags & MODIFIER_GENETIC) + genetic_modifiers.Add(mod.type) + if(add_to_db) SStranscore.add_body(src) @@ -204,6 +213,7 @@ src.body_oocnotes = orig.body_oocnotes src.limb_data = orig.limb_data.Copy() src.organ_data = orig.organ_data.Copy() + src.genetic_modifiers = orig.genetic_modifiers.Copy() src.toocomplex = orig.toocomplex src.sizemult = orig.sizemult src.aflags = orig.aflags diff --git a/code/modules/resleeving/machines.dm b/code/modules/resleeving/machines.dm index 08bdc863cd..4cb6793734 100644 --- a/code/modules/resleeving/machines.dm +++ b/code/modules/resleeving/machines.dm @@ -69,6 +69,10 @@ H.dna = R.dna.Clone() H.original_player = current_project.ckey + //Apply genetic modifiers + for(var/modifier_type in R.genetic_modifiers) + H.add_modifier(modifier_type) + //Apply damage H.adjustCloneLoss((H.getMaxHealth() - config.health_threshold_dead)*0.75) H.Paralyse(4) @@ -522,9 +526,10 @@ //Re-supply a NIF if one was backed up with them. if(MR.nif_path) - var/obj/item/device/nif/nif = new MR.nif_path(occupant,MR.nif_durability) + var/obj/item/device/nif/nif = new MR.nif_path(occupant,null,MR.nif_savedata) for(var/path in MR.nif_software) new path(nif) + nif.durability = MR.nif_durability //Restore backed up durability after restoring the softs. // If it was a custom sleeve (not owned by anyone), update namification sequences if(!occupant.original_player) diff --git a/code/modules/shieldgen/shield_diffuser.dm b/code/modules/shieldgen/shield_diffuser.dm index 1d2edb43cb..c30f8a7351 100644 --- a/code/modules/shieldgen/shield_diffuser.dm +++ b/code/modules/shieldgen/shield_diffuser.dm @@ -5,8 +5,8 @@ icon = 'icons/obj/machines/shielding.dmi' icon_state = "fdiffuser_on" use_power = 2 - idle_power_usage = 100 - active_power_usage = 2000 + idle_power_usage = 25 // Previously 100. + active_power_usage = 500 // Previously 2000 anchored = 1 density = 0 level = 1 diff --git a/code/modules/telesci/construction.dm b/code/modules/telesci/construction.dm index 5143733a47..9fc487f058 100644 --- a/code/modules/telesci/construction.dm +++ b/code/modules/telesci/construction.dm @@ -47,7 +47,7 @@ req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_PHORON = 4, TECH_BLUESPACE = 5) build_path = /obj/item/weapon/circuitboard/telesci_pad sort_string = "HAAEB" - +/* Normal GPS has all the fancy features now /datum/design/item/telesci_gps name = "GPS device" id = "telesci_gps" @@ -55,7 +55,7 @@ materials = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 1000) build_path = /obj/item/device/gps/advanced sort_string = "HAAEB" - +*/ /datum/design/circuit/quantum_pad name = "Quantum Pad" id = "quantum_pad" diff --git a/code/modules/telesci/gps_advanced.dm b/code/modules/telesci/gps_advanced.dm index fb1d8e16b6..59711deced 100644 --- a/code/modules/telesci/gps_advanced.dm +++ b/code/modules/telesci/gps_advanced.dm @@ -1,3 +1,6 @@ + +// DEPRECATED - The normal GPS has the advanced features, now. This is obsolete. + // These are distinguished from the ordinary "Relay Position Devices" that just print your location // In that they are also all networked with each other to show each other's locations. /obj/item/device/gps/advanced diff --git a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm index 107af3d080..eec5c192b7 100644 --- a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm @@ -28,9 +28,9 @@ /datum/riding/taur/get_offsets(pass_index) // list(dir = x, y, layer) var/mob/living/L = ridden var/scale = L.size_multiplier - + var/list/values = list( - "[NORTH]" = list(0, 8*scale, ABOVE_MOB_LAYER), + "[NORTH]" = list(0, 8*scale, ABOVE_MOB_LAYER), "[SOUTH]" = list(0, 8*scale, BELOW_MOB_LAYER), "[EAST]" = list(-10*scale, 8*scale, BELOW_MOB_LAYER), "[WEST]" = list(10*scale, 8*scale, BELOW_MOB_LAYER)) @@ -53,6 +53,10 @@ return ..() // Skip our checks if(!isTaurTail(tail_style)) return FALSE + else + var/datum/sprite_accessory/tail/taur/taurtype = tail_style + if(!taurtype.can_ride) + return FALSE if(lying) return FALSE if(!ishuman(M)) @@ -60,13 +64,13 @@ if(M.size_multiplier > size_multiplier) to_chat(M,"This isn't a pony show! They need to be bigger to ride.") return FALSE - + var/mob/living/carbon/human/H = M if(isTaurTail(H.tail_style)) to_chat(H,"Too many legs. TOO MANY LEGS!!") return FALSE - + . = ..() if(.) buckled_mobs[M] = "riding" @@ -105,6 +109,9 @@ do_colouration = 1 // Yes color, using tail color color_blend_mode = ICON_MULTIPLY // The sprites for taurs are designed for ICON_MULTIPLY + var/icon/suit_sprites = null //File for suit sprites, if any. + + var/can_ride = 1 //whether we're real rideable taur or just in that category //Could do nested lists but it started becoming a nightmare. It'd be more fun for lookups of a_intent and m_intent, but then subtypes need to //duplicate all the messages, and it starts getting awkward. These are singletons, anyway! @@ -142,6 +149,7 @@ /datum/sprite_accessory/tail/taur/wolf name = "Wolf (Taur)" icon_state = "wolf_s" + suit_sprites = 'icons/mob/taursuits_wolf_vr.dmi' /datum/sprite_accessory/tail/taur/wolf/wolf_2c name = "Wolf dual-color (Taur)" @@ -156,6 +164,7 @@ /datum/sprite_accessory/tail/taur/naga name = "Naga (Taur)" icon_state = "naga_s" + suit_sprites = 'icons/mob/taursuits_naga_vr.dmi' msg_owner_help_walk = "You carefully slither around %prey." msg_prey_help_walk = "%owner's huge tail slithers past beside you!" @@ -192,6 +201,7 @@ /datum/sprite_accessory/tail/taur/horse name = "Horse (Taur)" icon_state = "horse_s" + suit_sprites = 'icons/mob/taursuits_horse_vr.dmi' msg_owner_disarm_run = "You quickly push %prey to the ground with your hoof!" msg_prey_disarm_run = "%owner pushes you down to the ground with their hoof!" @@ -216,6 +226,7 @@ /datum/sprite_accessory/tail/taur/cow name = "Cow (Taur)" icon_state = "cow_s" + suit_sprites = 'icons/mob/taursuits_cow_vr.dmi' msg_owner_disarm_run = "You quickly push %prey to the ground with your hoof!" msg_prey_disarm_run = "%owner pushes you down to the ground with their hoof!" @@ -255,6 +266,7 @@ /datum/sprite_accessory/tail/taur/lizard name = "Lizard (Taur)" icon_state = "lizard_s" + suit_sprites = 'icons/mob/taursuits_lizard_vr.dmi' /datum/sprite_accessory/tail/taur/lizard/lizard_2c name = "Lizard dual-color (Taur)" @@ -288,6 +300,7 @@ /datum/sprite_accessory/tail/taur/tents name = "Tentacles (Taur)" icon_state = "tent_s" + can_ride = 0 msg_prey_stepunder = "You run between %prey's tentacles." msg_owner_stepunder = "%owner runs between your tentacles." @@ -410,18 +423,26 @@ ani_state = "alraune_closed_s" ckeys_allowed = list("natje") do_colouration = 0 + can_ride = 0 - msg_owner_disarm_run = "You quickly push %prey to the ground with your leg!" - msg_prey_disarm_run = "%owner pushes you down to the ground with their leg!" - msg_owner_disarm_walk = "You firmly push your leg down on %prey, painfully but harmlessly pinning them to the ground!" - msg_prey_disarm_walk = "%owner firmly pushes their leg down on you, quite painfully but harmlessly pinning you to the ground!" + msg_prey_stepunder = "You run between %prey's vines." + msg_owner_stepunder = "%owner runs between your vines." - msg_owner_harm_walk = "You methodically place your leg down upon %prey's body, slowly applying pressure, crushing them against the floor below!" - msg_prey_harm_walk = "%owner methodically places their leg upon your body, slowly applying pressure, crushing you against the floor below!" + msg_owner_disarm_run = "You quickly push %prey to the ground with some of your vines!" + msg_prey_disarm_run = "%owner pushes you down to the ground with some of their vines!" - msg_owner_grab_success = "You pin %prey down on the ground with your front leg before using your other leg to pick them up, trapping them between two of your front legs!" - msg_prey_grab_success = "%owner pins you down on the ground with their front leg before using their other leg to pick you up, trapping you between two of their front legs!" + msg_owner_disarm_walk = "You push down on %prey with some of your vines, pinning them down firmly under you!" + msg_prey_disarm_walk = "%owner pushes down on you with some of their vines, pinning you down firmly below them!" - msg_owner_grab_fail = "You step down onto %prey, squishing them and forcing them down to the ground!" - msg_prey_grab_fail = "%owner steps down and squishes you with their leg, forcing you down to the ground!" + msg_owner_harm_run = "Your vines carelessly slide past %prey, crushing them!" + msg_prey_harm_run = "%owner quickly goes over your body, carelessly crushing you with their vines!" + + msg_owner_harm_walk = "Your vines methodically apply pressure on %prey's body, crushing them against the floor below!" + msg_prey_harm_walk = "%owner's thick vines methodically apply pressure on your body, crushing you into the floor below!" + + msg_owner_grab_success = "You slide over %prey with your vines, smushing them against the ground before wrapping one up around them, trapping them within the tight confines of your vines!" + msg_prey_grab_success = "%owner slides over you with their vines, smushing you against the ground before wrapping one up around you, trapping you within the tight confines of their vines!" + + msg_owner_grab_fail = "You step down onto %prey with one of your vines, forcing them onto the ground!" + msg_prey_grab_fail = "%owner steps down onto you with one of their vines, squishing you and forcing you onto the ground!" diff --git a/code/modules/vore/appearance/sprite_accessories_vr.dm b/code/modules/vore/appearance/sprite_accessories_vr.dm index 0ab05c0677..c8f6635b5f 100644 --- a/code/modules/vore/appearance/sprite_accessories_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_vr.dm @@ -1,6 +1,6 @@ /* Hello and welcome to VOREStation sprite_accessories: For a more general overview - please read sprite_accessories.dm. This file is for ears, tails, and taur bodies! + please read sprite_accessories.dm. This file is for ears and tails. This is intended to be friendly for people with little to no actual coding experience. !!WARNING!!: changing existing accessory information can be VERY hazardous to savefiles, to the point where you may completely corrupt a server's savefiles. Please refrain @@ -815,6 +815,13 @@ icon_state = "tigresstail" ckeys_allowed = list("hoodoo") +/datum/sprite_accessory/tail/satyr + name = "goat legs, colorable" + desc = "" + icon_state = "satyr" + color_blend_mode = ICON_MULTIPLY + do_colouration = 1 + /datum/sprite_accessory/tail/tailmaw name = "tailmaw, colorable" desc = "" diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm index 35f59c4e06..d5c6987d65 100644 --- a/code/modules/vore/eating/belly_obj_vr.dm +++ b/code/modules/vore/eating/belly_obj_vr.dm @@ -32,7 +32,8 @@ var/shrink_grow_size = 1 // This horribly named variable determines the minimum/maximum size it will shrink/grow prey to. var/transferlocation // Location that the prey is released if they struggle and get dropped off. var/release_sound = TRUE // Boolean for now, maybe replace with something else later - var/mode_flags = DM_FLAG_ITEMWEAK // Stripping, numbing, etc. + var/mode_flags = DM_FLAG_ITEMWEAK // Stripping, numbing, etc. + var/cont_flavor = "Generic" // Selected contamination mode. //I don't think we've ever altered these lists. making them static until someone actually overrides them somewhere. //Actual full digest modes @@ -41,7 +42,7 @@ var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Itemweak" = DM_FLAG_ITEMWEAK, "Stripping" = DM_FLAG_STRIPPING) //Transformation modes var/tmp/static/list/transform_modes = list(DM_TRANSFORM_MALE,DM_TRANSFORM_FEMALE,DM_TRANSFORM_KEEP_GENDER,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG,DM_TRANSFORM_REPLICA,DM_TRANSFORM_REPLICA_EGG,DM_TRANSFORM_KEEP_GENDER_EGG,DM_TRANSFORM_MALE_EGG,DM_TRANSFORM_FEMALE_EGG, DM_EGG) - + //List of slots that stripping handles strips var/tmp/static/list/slots = list(slot_back,slot_handcuffed,slot_l_store,slot_r_store,slot_wear_mask,slot_l_hand,slot_r_hand,slot_wear_id,slot_glasses,slot_gloves,slot_head,slot_shoes,slot_belt,slot_wear_suit,slot_w_uniform,slot_s_store,slot_l_ear,slot_r_ear) @@ -136,7 +137,8 @@ "digest_messages_prey", "examine_messages", "emote_lists", - "mode_flags" + "mode_flags", + "cont_flavor" ) /obj/belly/New(var/newloc) @@ -371,7 +373,7 @@ var/obj/item/I = M.get_equipped_item(slot = slot) if(I) M.unEquip(I,force = TRUE) - I.gurgle_contaminate(contents, owner) //We do an initial contamination pass to get stuff like IDs wet. + I.gurgle_contaminate(contents, cont_flavor) //We do an initial contamination pass to get stuff like IDs wet. if(mode_flags & DM_FLAG_ITEMWEAK) items_preserved |= I @@ -576,6 +578,7 @@ if(!(content in src) || !istype(target)) return content.forceMove(target) + items_preserved -= content if(!silent && target.vore_sound && !recent_sound) var/soundfile = vore_sounds[target.vore_sound] if(soundfile) @@ -611,6 +614,7 @@ dupe.bulge_size = bulge_size dupe.shrink_grow_size = shrink_grow_size dupe.mode_flags = mode_flags + dupe.cont_flavor = cont_flavor //// Object-holding variables //struggle_messages_outside - strings diff --git a/code/modules/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes_vr.dm index 1dff971638..62fc770e49 100644 --- a/code/modules/vore/eating/bellymodes_vr.dm +++ b/code/modules/vore/eating/bellymodes_vr.dm @@ -38,8 +38,9 @@ if(isitem(A) && !did_an_item) var/obj/item/I = A if(mode_flags & DM_FLAG_ITEMWEAK) - I.gurgle_contaminate(contents, owner) + I.gurgle_contaminate(contents, cont_flavor) items_preserved |= I + to_update = TRUE else digest_item(I) to_update = TRUE @@ -52,11 +53,11 @@ if(L.absorbed) L.Weaken(5) - + //Handle 'human' if(ishuman(L)) var/mob/living/carbon/human/H = L - + //Numbing flag if(mode_flags & DM_FLAG_NUMBING) if(H.bloodstr.get_reagent_amount("numbenzyme") < 2) @@ -69,7 +70,7 @@ if(I) H.unEquip(I,force = TRUE) if(mode_flags & DM_FLAG_ITEMWEAK) - I.gurgle_contaminate(contents, owner) + I.gurgle_contaminate(contents, cont_flavor) items_preserved |= I else digest_item(I) @@ -96,6 +97,7 @@ if(M.stat == DEAD) var/digest_alert_owner = pick(digest_messages_owner) var/digest_alert_prey = pick(digest_messages_prey) + var/compensation = M.getOxyLoss() //How much of the prey's damage was caused by passive crit oxyloss to compensate the lost nutrition. //Replace placeholder vars digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner) @@ -113,22 +115,35 @@ play_sound = pick(death_sounds) digestion_death(M) owner.update_icons() + if(compensation > 0) + if(isrobot(owner)) + var/mob/living/silicon/robot/R = owner + R.cell.charge += 25*compensation + else + owner.nutrition += 4.5*compensation to_update = TRUE + continue // Deal digestion damage (and feed the pred) + var/old_brute = M.getBruteLoss() + var/old_burn = M.getFireLoss() M.adjustBruteLoss(digest_brute) M.adjustFireLoss(digest_burn) + var/actual_brute = M.getBruteLoss() - old_brute + var/actual_burn = M.getFireLoss() - old_burn + var/damage_gain = actual_brute + actual_burn var/offset = (1 + ((M.weight - 137) / 137)) // 130 pounds = .95 140 pounds = 1.02 var/difference = owner.size_multiplier / M.size_multiplier if(isrobot(owner)) var/mob/living/silicon/robot/R = owner - R.cell.charge += 20*(digest_brute+digest_burn) + R.cell.charge += 25*damage_gain if(offset) // If any different than default weight, multiply the % of offset. - owner.nutrition += offset*(2*(digest_brute+digest_burn)/difference) // 9.5 nutrition per digestion tick if they're 130 pounds and it's same size. 10.2 per digestion tick if they're 140 and it's same size. Etc etc. + owner.nutrition += offset*(4.5*(damage_gain)/difference) //4.5 nutrition points per health point. Normal same size 100+100 health prey with average weight would give 900 points if the digestion was instant. With all the size/weight offset taxes plus over time oxyloss+hunger taxes deducted with non-instant digestion, this should be enough to not leave the pred starved. else - owner.nutrition += 2*(digest_brute+digest_burn)/difference + owner.nutrition += 4.5*(damage_gain)/difference + //////////////////////////// DM_ABSORB //////////////////////////// else if(digest_mode == DM_ABSORB) @@ -154,7 +169,7 @@ for (var/target in touchable_mobs) var/mob/living/M = target - + if(M.absorbed && owner.nutrition >= 100) M.absorbed = 0 to_chat(M,"You suddenly feel solid again ") @@ -167,7 +182,7 @@ for (var/target in touchable_mobs) var/mob/living/M = target - + if(prob(10)) //Less often than gurgles. People might leave this on forever. play_sound = pick(digestion_sounds) @@ -181,13 +196,13 @@ for (var/target in touchable_mobs) var/mob/living/M = target - + if(prob(10)) //Infinite gurgles! play_sound = pick(digestion_sounds) if(M.size_multiplier > shrink_grow_size) //Shrink until smol. M.resize(M.size_multiplier-0.01) //Shrink by 1% per tick. - + if(M.nutrition >= 100) //Absorbing bodymass results in nutrition if possible. var/oldnutrition = (M.nutrition * 0.05) M.nutrition = (M.nutrition * 0.95) @@ -198,7 +213,7 @@ for (var/target in touchable_mobs) var/mob/living/M = target - + if(prob(10)) play_sound = pick(digestion_sounds) @@ -212,14 +227,14 @@ for (var/target in touchable_mobs) var/mob/living/M = target - + if(prob(10)) play_sound = pick(digestion_sounds) if(M.size_multiplier > shrink_grow_size && owner.size_multiplier < 2) //Grow until either pred is large or prey is small. owner.resize(owner.size_multiplier+0.01) //Grow by 1% per tick. M.resize(M.size_multiplier-0.01) //Shrink by 1% per tick - + if(M.nutrition >= 100) var/oldnutrition = (M.nutrition * 0.05) M.nutrition = (M.nutrition * 0.95) @@ -227,7 +242,7 @@ ///////////////////////////// DM_HEAL ///////////////////////////// else if(digest_mode == DM_HEAL) - + if(prob(50)) //Wet heals! The secret is you can leave this on for gurgle noises for fun. play_sound = pick(digestion_sounds) @@ -260,5 +275,5 @@ M.updateVRPanel() if(owner.client) owner.updateVRPanel() - + return SSBELLIES_PROCESSED diff --git a/code/modules/vore/eating/contaminate_vr.dm b/code/modules/vore/eating/contaminate_vr.dm index bf51ca9d59..e1d6a0f6c1 100644 --- a/code/modules/vore/eating/contaminate_vr.dm +++ b/code/modules/vore/eating/contaminate_vr.dm @@ -5,20 +5,21 @@ var/image/gurgled_overlay = image('icons/effects/sludgeoverlay_vr.dmi') var/cleanname var/cleandesc -/obj/item/proc/gurgle_contaminate(var/atom/movable/item_storage = null) +/obj/item/proc/gurgle_contaminate(var/atom/movable/item_storage = null, var/cont_flavor = "Generic") if(!can_gurgle()) return FALSE if(!gurgled) gurgled = TRUE overlays += gurgled_overlay - var/gurgleflavor = pick("soggy","soaked","dirty","nasty","slimy","drenched","sloppy","grimy","sludgy","stinky","mucky","stained","soiled","filthy","saucy","foul","icky","tarnished","unsanitary","messy","begrimed","cruddy","funky","disgusting","repulsive","noxious","gruesome","gross","putrid","yucky","tainted","putrescent","unsavory","smelly","smutty","acrid","pungent","unclean","contaminated","gunky","gooey","sticky","drippy","oozing","sloshed","digested","sopping","damp","gloppy","begraggled","churned") + var/list/pickfrom = cont_flavors[cont_flavor] + var/gurgleflavor = pick(pickfrom) cleanname = src.name cleandesc = src.desc name = "[gurgleflavor] [cleanname]" desc = "[cleandesc] It seems to be covered in ominously foul residue and needs a wash." for(var/obj/item/O in contents) - O.gurgle_contaminate(item_storage) + O.gurgle_contaminate(item_storage, cont_flavor) return TRUE /obj/item/proc/can_gurgle() @@ -102,8 +103,10 @@ var/image/gurgled_overlay = image('icons/effects/sludgeoverlay_vr.dmi') return TRUE /obj/item/weapon/holder/gurgle_contaminate(var/atom/movable/item_storage = null) - digest_act(item_storage) - return TRUE + if(isbelly(loc)) + digest_act(item_storage) + return TRUE + return FALSE /obj/item/organ/gurgle_contaminate(var/atom/movable/item_storage = null) digest_act(item_storage) diff --git a/code/modules/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore_vr.dm index 2205e54432..d6939e9c95 100644 --- a/code/modules/vore/eating/vore_vr.dm +++ b/code/modules/vore/eating/vore_vr.dm @@ -111,7 +111,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE allowmobvore = json_from_file["allowmobvore"] vore_taste = json_from_file["vore_taste"] can_be_drop_prey = json_from_file["can_be_drop_prey"] - can_be_drop_prey = json_from_file["can_be_drop_pred"] + can_be_drop_pred = json_from_file["can_be_drop_pred"] belly_prefs = json_from_file["belly_prefs"] //Quick sanitize diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm index 31a9e7e476..b7ee064846 100644 --- a/code/modules/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -204,6 +204,9 @@ dat += " [english_list(flag_list)]" else dat += " None" + if(selected.mode_flags & DM_FLAG_ITEMWEAK) + dat += "
Contamination Mode:" + dat += "[selected.cont_flavor]" //Belly verb dat += "
Vore Verb:" @@ -514,14 +517,14 @@ var/new_mode = input("Choose Mode (currently [selected.digest_mode])") as null|anything in menu_list if(!new_mode) return 0 - + if(new_mode == DM_TRANSFORM) //Snowflek submenu var/list/tf_list = selected.transform_modes var/new_tf_mode = input("Choose TF Mode (currently [selected.tf_mode])") as null|anything in tf_list if(!new_tf_mode) return 0 selected.tf_mode = new_tf_mode - + selected.digest_mode = new_mode selected.items_preserved.Cut() //Re-evaltuate all items in belly on belly-mode change @@ -533,6 +536,13 @@ selected.mode_flags ^= selected.mode_flag_list[toggle_addon] selected.items_preserved.Cut() //Re-evaltuate all items in belly on addon toggle + if(href_list["b_cont_flavor"]) + var/list/menu_list = cont_flavors.Copy() + var/new_flavor = input("Choose Contamination Mode (currently [selected.cont_flavor])") as null|anything in menu_list + if(!new_flavor) + return 0 + selected.cont_flavor = new_flavor + if(href_list["b_desc"]) var/new_desc = html_encode(input(usr,"Belly Description ([BELLIES_DESC_MAX] char limit):","New Description",selected.desc) as message|null) diff --git a/code/modules/vore/fluffstuff/custom_clothes_vr.dm b/code/modules/vore/fluffstuff/custom_clothes_vr.dm index 96391786a6..bb60c1fab3 100644 --- a/code/modules/vore/fluffstuff/custom_clothes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_clothes_vr.dm @@ -1313,18 +1313,13 @@ Departamental Swimsuits, for general use /obj/item/clothing/suit/storage/hooded/wintercoat/jessie name = "Handmade Winter Suit" desc = "A durable, but somewhat ragged lower portion of a snow suit fitted for a wolftaur." - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' + icon = 'icons/mob/taursuits_wolf_vr.dmi' icon_state = "jessiecoat" + item_state = "jessiecoat" /obj/item/clothing/suit/storage/hooded/wintercoat/jessie/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) if(..()) if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - if(icon_state == "jessiecoat") - return ..() - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "jessiecoat" - pixel_x = -16 return ..() else to_chat(H, "You need to have a wolf-taur half to wear this.") @@ -1335,19 +1330,13 @@ Departamental Swimsuits, for general use name = "Kat's Fox Taur Armor" desc = "A set of security armor, light weight and easy to run in for a Taur, this item protects the \ entire body." - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' + icon = 'icons/mob/taursuits_wolf_vr.dmi' icon_state = "katesuit" item_state_slots = null /obj/item/clothing/suit/armor/vest/wolftaur/kate/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) if(..()) if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - if(icon_state == "katesuit") - return ..() - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "katesuit" - pixel_x = -16 return ..() else to_chat(H, "You need to have a wolf-taur half to wear this.") @@ -1359,25 +1348,12 @@ Departamental Swimsuits, for general use desc = "Taur engineering voidsuit. Recolored navy blue and white. Slightly tweaked as well to \ get close to having security voidsuit protection as possible with a slight reduction in movement \ speed to compensate for custom padding and armor Kateryna made herself." - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' + icon = 'icons/mob/taursuits_wolf_vr.dmi' icon_state = "lilithsuit" + item_state = "lilithsuit" species_restricted = null armor = list(melee = 40, bullet = 20, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20) -/obj/item/clothing/suit/space/void/engineering/kate/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..()) - if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - if(icon_state == "lilithsuit") - return ..() - icon_override = 'icons/mob/taursuits_vr.dmi' - icon_state = "lilithsuit" - pixel_x = -16 - return ..() - else - to_chat(H, "You need to have a wolf-taur half to wear this.") - return 0 - //samanthafyre:Kateryna Petrovitch /obj/item/clothing/head/helmet/space/fluff/kate name = "Kat's Navy Engineer Helmet" @@ -1807,17 +1783,16 @@ Departamental Swimsuits, for general use armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) desc = "A series of armor plates painted black, deployed from a back-mounted module. They fit smoothly over the unit's armor plates and projects a skintight bubble shield over the unit's uncovered parts. Faceplate and coolant unit not included." species_restricted = null - icon = 'icons/mob/taursuits_vr.dmi' - icon_override = 'icons/mob/taursuits_vr.dmi' + icon = 'icons/mob/taursuits_lizard_vr.dmi' icon_state = "hasd_suit" item_state = "hasd_suit" pixel_x = -16 mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) - if(..() && istype(H) && H.ckey == "silencedmp5a5" && istype(H.tail_style, /datum/sprite_accessory/tail/taur/lizard/synthlizard)) + if(..() && istype(H) && H.ckey == "silencedmp5a5") return 1 else - H << "This suit is not designed for you." + to_chat(H,"This suit is not designed for you.") return 0 //Zigfe:Zaoozaoo Xrimxuqmqixzix diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index d25b8f7d2c..a8e4410272 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -355,15 +355,13 @@ name = "KSS-8 security armor" desc = "A set of armor made from pieces of many other armors. There are two orange holobadges on it, one on the chestplate, one on the steel flank plates. The holobadges appear to be russian in origin. 'Kosmicheskaya Stantsiya-8' is printed in faded white letters on one side, along the spine. It smells strongly of dog." species_restricted = null //Species restricted since all it cares about is a taur half - icon_override = 'icons/mob/taursuits_vr.dmi' //Needs to be this since it's 64*32 + icon = 'icons/mob/taursuits_wolf_vr.dmi' icon_state = "serdy_armor" + item_state = "serdy_armor" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS //It's a full body suit, minus hands and feet. Arms and legs should be protected, not just the torso. Retains normal security armor values still. /obj/item/clothing/suit/armor/vest/wolftaur/serdy/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) if(istype(H) && istype(H.tail_style, /datum/sprite_accessory/tail/taur/wolf)) - icon_override = 'icons/mob/taursuits_vr.dmi' //Just in case - icon_state = "serdy_armor" //Just in case - pixel_x = -16 return ..() else to_chat(H, "You need to have a wolf-taur half to wear this.") @@ -1995,7 +1993,26 @@ icon_state = "modkit" from_helmet = /obj/item/clothing/head/helmet/space/void/security - from_suit = /obj/item/clothing/suit/space/void/security/taur + from_suit = /obj/item/clothing/suit/space/void/security to_helmet = /obj/item/clothing/head/helmet/space/void/security/hasd to_suit = /obj/item/clothing/suit/space/void/security/hasd +//InterroLouis - Kai Highlands +/obj/item/borg/upgrade/modkit/chassis_mod/kai + name = "kai chassis" + desc = "Makes your KA green. All the fun of having a more powerful KA without actually having a more powerful KA." + cost = 0 + denied_type = /obj/item/borg/upgrade/modkit/chassis_mod + chassis_icon = "kineticgun_K" + chassis_name = "Kai-netic Accelerator" + var/chassis_desc = "A self recharging, ranged mining tool that does increased damage in low temperature. Capable of holding up to six slots worth of mod kits. It seems to have been painted an ugly green, and has a small image of a bird scratched crudely into the stock." + var/chassis_icon_file = 'icons/vore/custom_guns_vr.dmi' + +/obj/item/borg/upgrade/modkit/chassis_mod/kai/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user) + KA.desc = chassis_desc + KA.icon = chassis_icon_file + ..() +/obj/item/borg/upgrade/modkit/chassis_mod/kai/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA) + KA.desc = initial(KA.desc) + KA.icon = initial(KA.icon) + ..() diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index 9e957955b8..23987a3fed 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -242,14 +242,14 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 //Not a human, or not a taur, generic message only if(!H || !isTaurTail(H.tail_style)) - to_chat(src,"You quickly push [tmob] to the ground with your foot!") - to_chat(tmob,"[src] pushes you down to the ground with their foot!") + to_chat(src,"You quickly push [tmob] to the ground with your foot!") + to_chat(tmob,"[src] pushes you down to the ground with their foot!") //Human with taur tail, special messages are sent else var/datum/sprite_accessory/tail/taur/tail = H.tail_style - to_chat(src,STEP_TEXT_OWNER(tail.msg_owner_disarm_run)) - to_chat(tmob,STEP_TEXT_PREY(tail.msg_prey_disarm_run)) + to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_disarm_run]")) + to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_disarm_run]")) //Walking on I_DISARM else @@ -264,14 +264,14 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 //Not a human, or not a taur, generic message only if(!H || !isTaurTail(H.tail_style)) - to_chat(src,"You firmly push your foot down on [tmob], painfully but harmlessly pinning them to the ground!") - to_chat(tmob,"[src] firmly pushes their foot down on you, quite painfully but harmlessly pinning you to the ground!") + to_chat(src,"You firmly push your foot down on [tmob], painfully but harmlessly pinning them to the ground!") + to_chat(tmob,"[src] firmly pushes their foot down on you, quite painfully but harmlessly pinning you to the ground!") //Human with taur tail, special messages are sent else var/datum/sprite_accessory/tail/taur/tail = H.tail_style - to_chat(src,STEP_TEXT_OWNER(tail.msg_owner_disarm_walk)) - to_chat(tmob,STEP_TEXT_PREY(tail.msg_prey_disarm_walk)) + to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_disarm_walk]")) + to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_disarm_walk]")) //Return true, the sizediff was enough that we handled it. return TRUE @@ -297,14 +297,14 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 //Not a human, or not a taur, generic message only if(!H || !isTaurTail(H.tail_style)) - to_chat(src,"You carelessly step down onto [tmob], crushing them!") - to_chat(tmob,"[src] steps carelessly on your body, crushing you!") + to_chat(src,"You carelessly step down onto [tmob], crushing them!") + to_chat(tmob,"[src] steps carelessly on your body, crushing you!") //Human with taur tail, special messages are sent else var/datum/sprite_accessory/tail/taur/tail = H.tail_style - to_chat(src,STEP_TEXT_OWNER(tail.msg_owner_harm_run)) - to_chat(tmob,STEP_TEXT_PREY(tail.msg_prey_harm_run)) + to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_harm_run]")) + to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_harm_run]")) //If they are a human, do damage (doesn't hurt other mobs...?) if(Ht) @@ -327,14 +327,14 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 //Not a human, or not a taur, generic message only if(!H || !isTaurTail(H.tail_style)) - to_chat(src,"You methodically place your foot down upon [tmob]'s body, slowly applying pressure, crushing them against the floor below!") - to_chat(tmob,"[src] methodically places their foot upon your body, slowly applying pressure, crushing you against the floor below!") + to_chat(src,"You methodically place your foot down upon [tmob]'s body, slowly applying pressure, crushing them against the floor below!") + to_chat(tmob,"[src] methodically places their foot upon your body, slowly applying pressure, crushing you against the floor below!") //Human with taur tail, special messages are sent else var/datum/sprite_accessory/tail/taur/tail = H.tail_style - to_chat(src,STEP_TEXT_OWNER(tail.msg_owner_harm_walk)) - to_chat(tmob,STEP_TEXT_PREY(tail.msg_prey_harm_walk)) + to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_harm_walk]")) + to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_harm_walk]")) //Return true, the sizediff was enough that we handled it. return TRUE @@ -353,29 +353,29 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 //Not a human, or not a taur while wearing shoes = no grab if(!H || (!isTaurTail(H.tail_style) && H.shoes)) - to_chat(src,"You step down onto [tmob], squishing them and forcing them down to the ground!") - to_chat(tmob,"[src] steps down and squishes you with their foot, forcing you down to the ground!") + to_chat(src,"You step down onto [tmob], squishing them and forcing them down to the ground!") + to_chat(tmob,"[src] steps down and squishes you with their foot, forcing you down to the ground!") add_attack_logs(src,tmob,"Grabbed underfoot (nontaur, shoes)") //Human, not a taur, but not wearing shoes = yes grab else if(H && (!isTaurTail(H.tail_style) && !H.shoes)) - to_chat(src,"You pin [tmob] down onto the floor with your foot and curl your toes up around their body, trapping them inbetween them!") - to_chat(tmob,"[src] pins you down to the floor with their foot and curls their toes up around your body, trapping you inbetween them!") + to_chat(src,"You pin [tmob] down onto the floor with your foot and curl your toes up around their body, trapping them inbetween them!") + to_chat(tmob,"[src] pins you down to the floor with their foot and curls their toes up around your body, trapping you inbetween them!") equip_to_slot_if_possible(tmob.get_scooped(H), slot_shoes, 0, 1) add_attack_logs(src,tmob,"Grabbed underfoot (nontaur, no shoes)") //Human, taur, shoes = no grab, special message else if(H.shoes) var/datum/sprite_accessory/tail/taur/tail = H.tail_style - to_chat(src,STEP_TEXT_OWNER(tail.msg_owner_grab_fail)) - to_chat(tmob,STEP_TEXT_PREY(tail.msg_prey_grab_fail)) + to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_grab_fail]")) + to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_grab_fail]")) add_attack_logs(src,tmob,"Grabbed underfoot (taur, shoes)") //Human, taur, no shoes = yes grab, special message else var/datum/sprite_accessory/tail/taur/tail = H.tail_style - to_chat(src,STEP_TEXT_OWNER(tail.msg_owner_grab_success)) - to_chat(tmob,STEP_TEXT_PREY(tail.msg_prey_grab_success)) + to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_grab_success]")) + to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_grab_success]")) equip_to_slot_if_possible(tmob.get_scooped(H), slot_shoes, 0, 1) add_attack_logs(src,tmob,"Grabbed underfoot (taur, no shoes)") diff --git a/code/modules/xenoarcheaology/finds/misc.dm b/code/modules/xenoarcheaology/finds/misc.dm index 129033bf6e..cc02a7f41b 100644 --- a/code/modules/xenoarcheaology/finds/misc.dm +++ b/code/modules/xenoarcheaology/finds/misc.dm @@ -19,6 +19,20 @@ else set_light(3, 3, "#33CC33") +/obj/machinery/crystal/alt + name = "Crystal" + icon = 'icons/obj/mining.dmi' + icon_state = "crystal" + density = TRUE + anchored = TRUE + +/obj/machinery/crystal/alt/New() + if(prob(50)) + icon_state = "crystal2" + set_light(3, 3, "#CC00CC") + else + set_light(3, 3, "#33CC33") + /obj/machinery/crystal/ice //slightly more thematic crystals name = "ice crystal" desc = "A large crystalline ice formation." diff --git a/code/world.dm b/code/world.dm index 765fc2b266..b437ac46f6 100644 --- a/code/world.dm +++ b/code/world.dm @@ -43,11 +43,11 @@ var/global/datum/global_init/init = new () world.log << "Map Loading Complete" //logs log_path += time2text(world.realtime, "YYYY/MM-Month/DD-Day/round-hh-mm-ss") - diary = file("[log_path].log") - href_logfile = file("[log_path]-hrefs.htm") - error_log = file("[log_path]-error.log") - debug_log = file("[log_path]-debug.log") - debug_log << "[log_end]\n[log_end]\nStarting up. [time_stamp()][log_end]\n---------------------[log_end]" + diary = start_log("[log_path].log") + href_logfile = start_log("[log_path]-hrefs.htm") + error_log = start_log("[log_path]-error.log") + debug_log = start_log("[log_path]-debug.log") + changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently if(byond_version < RECOMMENDED_VERSION) @@ -57,8 +57,9 @@ var/global/datum/global_init/init = new () // dumb and hardcoded but I don't care~ config.server_name += " #[(world.port % 1000) / 100]" - if(config && config.log_runtime) - log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log") + // TODO - Figure out what this is. Can you assign to world.log? + // if(config && config.log_runtime) + // log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log") callHook("startup") //Emergency Fix @@ -145,7 +146,7 @@ var/world_topic_spam_protect_ip = "0.0.0.0" var/world_topic_spam_protect_time = world.timeofday /world/Topic(T, addr, master, key) - debug_log << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]" + log_topic("\"[T]\", from:[addr], master:[master], key:[key]") if (T == "ping") var/x = 1 @@ -448,6 +449,7 @@ var/world_topic_spam_protect_time = world.timeofday if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite C << link("byond://[config.server]") + shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. ..(reason) /hook/startup/proc/loadMode() diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt index c55764b518..d05b428b1e 100644 --- a/config/alienwhitelist.txt +++ b/config/alienwhitelist.txt @@ -5,12 +5,13 @@ billybob11432 - Vox bikky - Xenomorph Hybrid bothnevarbackwards - Diona cameron653 - Xenomorph Hybrid -sharkmare - Protean drakewyrmsilverwing - Xenomorph Hybrid +funnyman2003 - Xenochimera hawkerthegreat - Vox jemli - Gutter kotetsuredwood - Xenochimera kovis- Xenochimera +ktccd - Diona mewchild - Diona mewchild - Vox natje - Xenochimera @@ -24,6 +25,7 @@ rixunie - Gutter seiga - Vox sepulchre - Vox sepulchre - Xenomorph Hybrid +sharkmare - Protean silverTalismen - Diona silvertalismen - Xenochimera singo - Gutter diff --git a/config/custom_items.txt b/config/custom_items.txt index 5ac1381ff2..f5f54aec55 100644 --- a/config/custom_items.txt +++ b/config/custom_items.txt @@ -207,6 +207,19 @@ item_path: /obj/item/weapon/storage/box/fluff/drake } # ######## E CKEYS +{ +ckey: draycu +character_name: Theseus +item_path: /obj/item/weapon/coin/diamond +item_name: theseus' diamond coin +item_desc: An engraved coin made of diamond. On the side for heads is printed the year 2541, along with the letter T. On the side for tails, the letter Y can be seen. +} + +{ +ckey: draycu +character_name: Schae Yonra +item_path: /obj/item/weapon/melee/fluff/holochain/mass +} { ckey: erikthedog @@ -283,19 +296,19 @@ item_path: /obj/item/weapon/implanter/reagent_generator/belle { ckey: hzdonut character_name: Jesse Soemmer -item_path:/obj/item/weapon/gun/projectile/revolver/fluff/jesselemat +item_path: /obj/item/weapon/gun/projectile/revolver/fluff/jesselemat } { ckey: hzdonut character_name: Jesse Soemmer -item_path:/obj/item/clothing/accessory/permit/gun/fluff/JesseSoemmer +item_path: /obj/item/clothing/accessory/permit/gun/fluff/JesseSoemmer } { ckey: hzdonut character_name: Jesse Soemmer -item_path:/obj/item/clothing/accessory/holster/hip +item_path: /obj/item/clothing/accessory/holster/hip } # ######## I CKEYS @@ -316,7 +329,13 @@ item_path:/obj/item/clothing/accessory/collar/fluff/Kellyscollar { ckey: interrolouis character_name: Ruda Lizden -item_path:/obj/item/clothing/accessory/badge/holo/detective/ruda +item_path: /obj/item/clothing/accessory/badge/holo/detective/ruda +} + +{ +ckey: interrolouis +character_name: Kai Highlands +item_path: /obj/item/borg/upgrade/modkit/chassis_mod/kai } { diff --git a/html/changelog.html b/html/changelog.html index a23c76ae66..00465f2f13 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,31 @@

22 March 2018

Chaoko99 updated:

01 April 2018

+

28 April 2018

+

Anewbe updated:

+ +

Arokha updated:

+ +

Atermonera updated:

+ +

Cerebulon updated:

+ +

schnayy updated:

+ +

19 April 2018

Anewbe updated: