diff --git a/code/__defines/ai.dm b/code/__defines/ai.dm new file mode 100644 index 0000000000..2f7d9db3a0 --- /dev/null +++ b/code/__defines/ai.dm @@ -0,0 +1,9 @@ + +/// Used in ai/manage_processing to indicate that the AI should be dequeued from slow and fast AI processing +#define AI_NO_PROCESS 0 + +/// Used in ai/manage_processing to indicate that the AI should be queued for slow AI processing, and for related subsystem checks +#define AI_PROCESSING (1 << 0) + +/// Used in ai/manage_processing to indicate that the AI should be queued for fast AI processing, and for related subsystem checks +#define AI_FASTPROCESSING (1 << 1) diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 39fd330f8b..589d529bee 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -442,4 +442,14 @@ #define DEATHGASP_NO_MESSAGE "no message" -#define RESIST_COOLDOWN 2 SECONDS \ No newline at end of file +#define RESIST_COOLDOWN 2 SECONDS + + +/// Used by human/get_visible_gender(user, force) to return PLURAL +#define VISIBLE_GENDER_FORCE_PLURAL 1 + +/// Used by human/get_visible_gender(user, force) to return the mob's identifying gender +#define VISIBLE_GENDER_FORCE_IDENTIFYING 2 + +/// Used by human/get_visible_gender(user, force) to return the mob's biological gender +#define VISIBLE_GENDER_FORCE_BIOLOGICAL 3 diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 8b578c760f..d9660d0195 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -53,7 +53,7 @@ GLOBAL_LIST_INIT(custom_species_bases, new) // Species that can be used for a Cu var/datum/category_collection/underwear/global_underwear = new() //Backpacks -var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt", "Messenger Bag") +var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt", "Messenger Bag", "Sports Bag") var/global/list/pdachoicelist = list("Default", "Slim", "Old", "Rugged", "Holographic", "Wrist-Bound") var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg) diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index 770881e49a..00648bfb2e 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -213,23 +213,58 @@ t = replacetext(t, char, repl_chars[char]) return t -//Adds 'u' number of zeros ahead of the text 't' -/proc/add_zero(t, u) - while (length(t) < u) - t = "0[t]" - return t -//Adds 'u' number of spaces ahead of the text 't' -/proc/add_lspace(t, u) - while(length(t) < u) - t = " [t]" - return t +/// Returns a string of hexadecimal characters of length size, uppercased if uppercase is truthy +/proc/random_hex_text(size, uppercase) + if (!ISINTEGER(size)) + return + var/list/result = list() + for (var/i = size to 1 step -1) + result += num2hex(rand(0, 0xF)) + result = jointext(result, null) + if (uppercase) + return uppertext(result) + return result -//Adds 'u' number of spaces behind the text 't' -/proc/add_tspace(t, u) - while(length(t) < u) - t = "[t] " - return t + +/// Builds a string of padding repeated until its character count meets or exceeds size +/proc/generate_padding(size, padding) + var/padding_size = length_char(padding) + if (!padding_size) + return "" + var/padding_count = CEILING(size / padding_size, 1) + var/list/result = list() + for (var/i = padding_count to 1 step -1) + result += padding // pow2 strategies could be used here at the cost of complexity + return result.Join(null) + + +/// Pads the matter of padding onto the start of text until the result length is size +/proc/pad_left(text, size, padding) + var/text_length = length_char(text) + if (text_length >= size) + return text + if (!text_length) + text = "" + var/result = "[generate_padding(size - text_length, padding)][text]" + var/length_difference = length_char(result) - size + if (!length_difference) + return result + return copytext_char(result, length_difference + 1) + + +/// Pads the matter of padding onto the start of text until the result length is size +/proc/pad_right(text, size, padding) + var/text_length = length_char(text) + if (text_length >= size) + return text + if (!text_length) + text = "" + var/result = "[text][generate_padding(size - text_length, padding)]" + var/length_difference = length_char(result) - size + if (!length_difference) + return result + return copytext_char(result, 1, -length_difference) //Returns a string with reserved characters and spaces before the first letter removed /proc/trim_left(text) diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm index 0dc857baea..212d17fcc5 100644 --- a/code/_helpers/time.dm +++ b/code/_helpers/time.dm @@ -110,8 +110,8 @@ GLOBAL_VAR_INIT(round_start_time, 0) var/mins = round((mills % 36000) / 600) var/hours = round(mills / 36000) - mins = mins < 10 ? add_zero(mins, 1) : mins - hours = hours < 10 ? add_zero(hours, 1) : hours + mins = pad_left("[mins]", 2, "0") + hours = pad_left("[hours]", 2, "0") last_round_duration = "[hours]:[mins]" next_duration_update = world.time + 1 MINUTES diff --git a/code/_helpers/turfs.dm b/code/_helpers/turfs.dm index 109f29a4f9..ad4c343d9c 100644 --- a/code/_helpers/turfs.dm +++ b/code/_helpers/turfs.dm @@ -1,10 +1,20 @@ -// Returns the atom sitting on the turf. -// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf. -/proc/get_atom_on_turf(var/atom/movable/M) - var/atom/mloc = M - while(mloc && mloc.loc && !istype(mloc.loc, /turf/)) - mloc = mloc.loc - return mloc +/** +* Returns a best attempt at the least-nested containing movable of subject, or subject. +* eg, if subject is an item in a bag on a mob in a locker in the world, returns the locker. +*/ +/proc/get_atom_on_turf(atom/movable/subject) + var/atom/parent = subject?.loc + if (!parent || !ismovable(subject) || isarea(parent)) + return subject + var/atom/current = subject + do + parent = current.loc + if (isturf(parent)) + return current + current = parent + while (current) + return subject + /proc/iswall(turf/T) return (istype(T, /turf/simulated/wall) || istype(T, /turf/unsimulated/wall) || istype(T, /turf/simulated/shuttle/wall)) diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm index 3e6c3e9854..f1fff0ff74 100644 --- a/code/_helpers/type2type.dm +++ b/code/_helpers/type2type.dm @@ -1,55 +1,3 @@ -/* - * Holds procs designed to change one type of value, into another. - * Contains: - * hex2num & num2hex - * text2list & list2text - * file2list - * angle2dir - * angle2text - * worldtime2text - */ - -// Returns an integer given a hexadecimal number string as input. -/proc/hex2num(hex) - if (!istext(hex)) - return - - var/num = 0 - var/power = 1 - var/i = length(hex) - - while (i) - var/char = text2ascii(hex, i) - switch(char) - if(48) // 0 -- do nothing - if(49 to 57) num += (char - 48) * power // 1-9 - if(97, 65) num += power * 10 // A - if(98, 66) num += power * 11 // B - if(99, 67) num += power * 12 // C - if(100, 68) num += power * 13 // D - if(101, 69) num += power * 14 // E - if(102, 70) num += power * 15 // F - else - return - power *= 16 - i-- - return num - -// Returns the hex value of a number given a value assumed to be a base-ten value -/proc/num2hex(num, padlength) - var/global/list/hexdigits = list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F") - - . = "" - while(num > 0) - var/hexdigit = hexdigits[(num & 0xF) + 1] - . = "[hexdigit][.]" - num >>= 4 //go to the next half-byte - - //pad with zeroes - var/left = padlength - length(.) - while (left-- > 0) - . = "0[.]" - /proc/text2numlist(text, delimiter="\n") var/list/num_list = list() for(var/x in splittext(text, delimiter)) @@ -151,25 +99,6 @@ if (rights & R_EVENT) . += "[seperator]+EVENT" return . -// Converts a hexadecimal color (e.g. #FF0050) to a list of numbers for red, green, and blue (e.g. list(255,0,80) ). -/proc/hex2rgb(hex) - // Strips the starting #, in case this is ever supplied without one, so everything doesn't break. - if(findtext(hex,"#",1,2)) - hex = copytext(hex, 2) - return list(hex2rgb_r(hex), hex2rgb_g(hex), hex2rgb_b(hex)) - -// The three procs below require that the '#' part of the hex be stripped, which hex2rgb() does automatically. -/proc/hex2rgb_r(hex) - var/hex_to_work_on = copytext(hex,1,3) - return hex2num(hex_to_work_on) - -/proc/hex2rgb_g(hex) - var/hex_to_work_on = copytext(hex,3,5) - return hex2num(hex_to_work_on) - -/proc/hex2rgb_b(hex) - var/hex_to_work_on = copytext(hex,5,7) - return hex2num(hex_to_work_on) // heat2color functions. Adapted from: http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ /proc/heat2color(temp) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 9884581036..91bf996be7 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -14,30 +14,6 @@ locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \ ) -//Inverts the colour of an HTML string -/proc/invertHTML(HTMLstring) - - if (!( istext(HTMLstring) )) - CRASH("Given non-text argument!") - else - if (length(HTMLstring) != 7) - CRASH("Given non-HTML argument!") - var/textr = copytext(HTMLstring, 2, 4) - var/textg = copytext(HTMLstring, 4, 6) - var/textb = copytext(HTMLstring, 6, 8) - var/r = hex2num(textr) - var/g = hex2num(textg) - var/b = hex2num(textb) - textr = num2hex(255 - r) - textg = num2hex(255 - g) - textb = num2hex(255 - b) - if (length(textr) < 2) - textr = text("0[]", textr) - if (length(textg) < 2) - textr = text("0[]", textg) - if (length(textb) < 2) - textr = text("0[]", textb) - return text("#[][][]", textr, textg, textb) //Returns the middle-most value /proc/dd_range(var/low, var/high, var/num) @@ -1279,7 +1255,7 @@ var/list/WALLITEMS = list( return colour /proc/color_square(red, green, blue, hex) - var/color = hex ? hex : "#[num2hex(red, 2)][num2hex(green, 2)][num2hex(blue, 2)]" + var/color = hex || rgb(red, green, blue) return "___" var/mob/dview/dview_mob = new diff --git a/code/_macros.dm b/code/_macros.dm index d122d9045f..a725086194 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -38,6 +38,15 @@ #define random_id(key,min_id,max_id) uniqueness_repository.Generate(/datum/uniqueness_generator/id_random, key, min_id, max_id) + +/// Given a hexadeximal text, returns the corresponding integer +#define hex2num(hex) (text2num(hex, 16) || 0) + + +/// Given an integer number, returns a hexadecimal representation +#define num2hex(num) num2text(num, 1, 16) + + #define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") } #define WORLD_ICON_SIZE 32 //Needed for the R-UST port diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index af1527eed4..806ee7ca54 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -103,6 +103,12 @@ #define ui_alien_fire "EAST-1:28,NORTH-3:25" #define ui_alien_oxygen "EAST-1:28,NORTH-4:25" +// Goes above HUD, mid-right +#define ui_ammo_hud1 "EAST-1:28,CENTER+1:25" +#define ui_ammo_hud2 "EAST-1:28,CENTER+2:27" +#define ui_ammo_hud3 "EAST-1:28,CENTER+3:29" +#define ui_ammo_hud4 "EAST-1:28,CENTER+4:31" + //Middle right (status indicators) #define ui_temp "EAST-1:28,CENTER-2:13" #define ui_health "EAST-1:28,CENTER-1:15" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 71e32197ff..a6597f9b13 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -1,3 +1,4 @@ +#define MAX_AMMO_HUD_POSSIBLE 4 // Cap the amount of HUDs at 4. /* The global hud: Uses the same visual objects for all players. @@ -182,6 +183,9 @@ var/list/global_huds = list( var/icon/ui_style var/ui_color var/ui_alpha + + // TGMC Ammo HUD Port + var/list/obj/screen/ammo_hud_list = list() var/list/minihuds = list() @@ -210,6 +214,7 @@ var/list/global_huds = list( other = null hotkeybuttons = null // item_action_list = null // ? + QDEL_LIST(ammo_hud_list) mymob = null /datum/hud/proc/hidden_inventory_update() @@ -446,4 +451,37 @@ var/list/global_huds = list( client.screen += client.void /mob/new_player/add_click_catcher() - return \ No newline at end of file + return + +/* TGMC Ammo HUD Port + * These procs call to screen_objects.dm's respective procs. + * All these do is manage the amount of huds on screen and set the HUD. +*/ +///Add an ammo hud to the user informing of the ammo count of G +/datum/hud/proc/add_ammo_hud(mob/living/user, obj/item/weapon/gun/G) + if(length(ammo_hud_list) >= MAX_AMMO_HUD_POSSIBLE) + return + var/obj/screen/ammo/ammo_hud = new + ammo_hud_list[G] = ammo_hud + ammo_hud.screen_loc = ammo_hud.ammo_screen_loc_list[length(ammo_hud_list)] + ammo_hud.add_hud(user, G) + ammo_hud.update_hud(user, G) + +///Remove the ammo hud related to the gun G from the user +/datum/hud/proc/remove_ammo_hud(mob/living/user, obj/item/weapon/gun/G) + var/obj/screen/ammo/ammo_hud = ammo_hud_list[G] + if(isnull(ammo_hud)) + return + ammo_hud.remove_hud(user, G) + qdel(ammo_hud) + ammo_hud_list -= G + var/i = 1 + for(var/key in ammo_hud_list) + ammo_hud = ammo_hud_list[key] + ammo_hud.screen_loc = ammo_hud.ammo_screen_loc_list[i] + i++ + +///Update the ammo hud related to the gun G +/datum/hud/proc/update_ammo_hud(mob/living/user, obj/item/weapon/gun/G) + var/obj/screen/ammo/ammo_hud = ammo_hud_list[G] + ammo_hud?.update_hud(user, G) \ No newline at end of file diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 2006f53adc..e8bb2bb7f4 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -833,3 +833,80 @@ icon_state = null plane = PLANE_HOLOMAP_ICONS appearance_flags = KEEP_TOGETHER + +// Begin TGMC Ammo HUD Port +/obj/screen/ammo + name = "ammo" + icon = 'icons/mob/screen_ammo.dmi' + icon_state = "ammo" + screen_loc = ui_ammo_hud1 + var/warned = FALSE + var/static/list/ammo_screen_loc_list = list(ui_ammo_hud1, ui_ammo_hud2, ui_ammo_hud3 ,ui_ammo_hud4) + +/obj/screen/ammo/proc/add_hud(var/mob/living/user, var/obj/item/weapon/gun/G) + + if(!user?.client) + return + + if(!G) + CRASH("/obj/screen/ammo/proc/add_hud() has been called from [src] without the required param of G") + + if(!G.has_ammo_counter()) + return + + user.client.screen += src + +/obj/screen/ammo/proc/remove_hud(var/mob/living/user) + user?.client?.screen -= src + +/obj/screen/ammo/proc/update_hud(var/mob/living/user, var/obj/item/weapon/gun/G) + if(!user?.client?.screen.Find(src)) + return + + if(!G || !istype(G) || !G.has_ammo_counter() || !G.get_ammo_type() || isnull(G.get_ammo_count())) + remove_hud() + return + + var/list/ammo_type = G.get_ammo_type() + var/rounds = G.get_ammo_count() + + var/hud_state = ammo_type[1] + var/hud_state_empty = ammo_type[2] + + overlays.Cut() + + var/empty = image('icons/mob/screen_ammo.dmi', src, "[hud_state_empty]") + + if(rounds == 0) + if(warned) + overlays += empty + else + warned = TRUE + var/obj/screen/ammo/F = new /obj/screen/ammo(src) + F.icon_state = "frame" + user.client.screen += F + flick("[hud_state_empty]_flash", F) + spawn(20) + user.client.screen -= F + qdel(F) + overlays += empty + else + warned = FALSE + overlays += image('icons/mob/screen_ammo.dmi', src, "[hud_state]") + + rounds = num2text(rounds) + //Handle the amount of rounds + switch(length(rounds)) + if(1) + overlays += image('icons/mob/screen_ammo.dmi', src, "o[rounds[1]]") + if(2) + overlays += image('icons/mob/screen_ammo.dmi', src, "o[rounds[2]]") + overlays += image('icons/mob/screen_ammo.dmi', src, "t[rounds[1]]") + if(3) + overlays += image('icons/mob/screen_ammo.dmi', src, "o[rounds[3]]") + overlays += image('icons/mob/screen_ammo.dmi', src, "t[rounds[2]]") + overlays += image('icons/mob/screen_ammo.dmi', src, "h[rounds[1]]") + else //"0" is still length 1 so this means it's over 999 + overlays += image('icons/mob/screen_ammo.dmi', src, "o9") + overlays += image('icons/mob/screen_ammo.dmi', src, "t9") + overlays += image('icons/mob/screen_ammo.dmi', src, "h9") \ No newline at end of file diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index fde8227376..191d4d89f5 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -228,14 +228,14 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle = new if (online()) if (shuttle.has_arrive_time()) var/timeleft = emergency_shuttle.estimate_arrival_time() - return "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]" + return "ETA-[(timeleft / 60) % 60]:[pad_left(num2text(timeleft % 60), 2, "0")]" if (waiting_to_leave()) if (shuttle.moving_status == SHUTTLE_WARMUP) return "Departing..." var/timeleft = emergency_shuttle.estimate_launch_time() - return "ETD-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]" + return "ETD-[(timeleft / 60) % 60]:[pad_left(num2text(timeleft % 60), 2, "0")]" return "" /* diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm index c92d42d82a..7e088b6449 100644 --- a/code/controllers/globals.dm +++ b/code/controllers/globals.dm @@ -43,6 +43,12 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars) return FALSE return ..() + +/datum/controller/global_vars/VV_hidden() + return list( + "vchatdb" + ) + /datum/controller/global_vars/Initialize() gvars_datum_init_order = list() gvars_datum_protected_varlist = list(NAMEOF(src, gvars_datum_protected_varlist) = TRUE) diff --git a/code/controllers/subsystems/ai.dm b/code/controllers/subsystems/ai.dm index 57bd5cc1ac..46b078cde9 100644 --- a/code/controllers/subsystems/ai.dm +++ b/code/controllers/subsystems/ai.dm @@ -1,32 +1,53 @@ SUBSYSTEM_DEF(ai) name = "AI" - init_order = INIT_ORDER_AI - priority = FIRE_PRIORITY_AI - wait = 2 SECONDS flags = SS_NO_INIT runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + priority = FIRE_PRIORITY_AI + wait = 2 SECONDS + + /// The list of AI datums to be processed. + var/static/tmp/list/queue = list() + + /// The list of AI datums currently being processed. + var/static/tmp/list/current = list() - var/list/processing = list() - var/list/currentrun = list() /datum/controller/subsystem/ai/stat_entry(msg_prefix) var/list/msg = list(msg_prefix) - msg += "P:[processing.len]" + msg += "P:[queue.len]" ..(msg.Join()) + +/datum/controller/subsystem/ai/Recover() + current.Cut() + + /datum/controller/subsystem/ai/fire(resumed, no_mc_tick) if (!resumed) - src.currentrun = processing.Copy() - - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - - while(currentrun.len) - var/datum/ai_holder/A = currentrun[currentrun.len] - --currentrun.len - if(!A || QDELETED(A) || A.busy) // Doesn't exist or won't exist soon or not doing it this tick + current = queue.Copy() + var/datum/ai_holder/subject + for (var/i = current.len to 1 step -1) + subject = current[i] + if (QDELETED(subject) || subject.busy) continue - A.handle_strategicals() - - if(MC_TICK_CHECK) + subject.handle_strategicals() + if (no_mc_tick) + CHECK_TICK + else if (MC_TICK_CHECK) + current.Cut(i) return + current.Cut() + + +/// Convenience define for safely enqueueing an AI datum for slow processing. +#define START_AIPROCESSING(DATUM) \ +if (!(DATUM.process_flags & AI_PROCESSING)) {\ + DATUM.process_flags |= AI_PROCESSING;\ + SSai.queue += DATUM;\ +} + + +/// Convenience define for safely dequeueing an AI datum from slow processing. +#define STOP_AIPROCESSING(DATUM) \ +DATUM.process_flags &= ~AI_PROCESSING; \ +SSai.queue -= DATUM; diff --git a/code/controllers/subsystems/aifast.dm b/code/controllers/subsystems/aifast.dm index 6ce841855d..d4a70a3853 100644 --- a/code/controllers/subsystems/aifast.dm +++ b/code/controllers/subsystems/aifast.dm @@ -1,32 +1,53 @@ SUBSYSTEM_DEF(aifast) - name = "AI (Fast)" - init_order = INIT_ORDER_AI_FAST - priority = FIRE_PRIORITY_AI - wait = 0.25 SECONDS + name = "AI Fast" flags = SS_NO_INIT runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + priority = FIRE_PRIORITY_AI + wait = 0.25 SECONDS + + /// The list of AI datums to be processed. + var/static/tmp/list/queue = list() + + /// The list of AI datums currently being processed. + var/static/tmp/list/current = list() - var/list/processing = list() - var/list/currentrun = list() /datum/controller/subsystem/aifast/stat_entry(msg_prefix) var/list/msg = list(msg_prefix) - msg += "P:[processing.len]" + msg += "P:[queue.len]" ..(msg.Join()) + +/datum/controller/subsystem/aifast/Recover() + current.Cut() + + /datum/controller/subsystem/aifast/fire(resumed, no_mc_tick) if (!resumed) - src.currentrun = processing.Copy() - - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - - while(currentrun.len) - var/datum/ai_holder/A = currentrun[currentrun.len] - --currentrun.len - if(!A || QDELETED(A) || A.busy) // Doesn't exist or won't exist soon or not doing it this tick + current = queue.Copy() + var/datum/ai_holder/subject + for (var/i = current.len to 1 step -1) + subject = current[i] + if (QDELETED(subject) || subject.busy) continue - A.handle_tactics() - - if(MC_TICK_CHECK) + subject.handle_tactics() + if (no_mc_tick) + CHECK_TICK + else if (MC_TICK_CHECK) + current.Cut(i) return + current.Cut() + + +/// Convenience define for safely enqueueing an AI datum for fast processing. +#define START_AIFASTPROCESSING(DATUM) \ +if (!(DATUM.process_flags & AI_FASTPROCESSING)) {\ + DATUM.process_flags |= AI_FASTPROCESSING;\ + SSaifast.queue += DATUM;\ +} + + +/// Convenience define for safely dequeueing an AI datum from fast processing. +#define STOP_AIFASTPROCESSING(DATUM) \ +DATUM.process_flags &= ~AI_FASTPROCESSING; \ +SSaifast.queue -= DATUM; diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 1aaf8d66f3..2d957ecf38 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -416,7 +416,8 @@ var/global/list/PDA_Manifest = list() return /proc/generate_record_id() - return add_zero(num2hex(rand(1, 65535)), 4) //no point generating higher numbers because of the limitations of num2hex + return "000[random_hex_text(3, TRUE)]" + /datum/datacore/proc/CreateGeneralRecord(var/mob/living/carbon/human/H, var/id, var/hidden) ResetPDAManifest() @@ -431,7 +432,7 @@ var/global/list/PDA_Manifest = list() side = icon('html/images/no_image32.png') if(!id) - id = text("[]", add_zero(num2hex(rand(1, 65536)), 4)) + id = generate_record_id() var/datum/data/record/G = new /datum/data/record() G.name = "Employee Record #[id]" G.fields["name"] = "New Record" diff --git a/code/datums/outfits/jobs/civilian.dm b/code/datums/outfits/jobs/civilian.dm index 722a3fefb6..49d7efb494 100644 --- a/code/datums/outfits/jobs/civilian.dm +++ b/code/datums/outfits/jobs/civilian.dm @@ -54,6 +54,7 @@ backpack = /obj/item/weapon/storage/backpack/hydroponics satchel_one = /obj/item/weapon/storage/backpack/satchel/hyd messenger_bag = /obj/item/weapon/storage/backpack/messenger/hyd + sports_bag = /obj/item/weapon/storage/backpack/sport/hyd id_type = /obj/item/weapon/card/id/civilian/botanist pda_type = /obj/item/device/pda/botanist diff --git a/code/datums/outfits/jobs/medical.dm b/code/datums/outfits/jobs/medical.dm index 6622d3b285..dd5cb7fbcb 100644 --- a/code/datums/outfits/jobs/medical.dm +++ b/code/datums/outfits/jobs/medical.dm @@ -65,6 +65,7 @@ suit = /obj/item/clothing/suit/storage/toggle/labcoat/chemist backpack = /obj/item/weapon/storage/backpack/chemistry satchel_one = /obj/item/weapon/storage/backpack/satchel/chem + sports_bag = /obj/item/weapon/storage/backpack/sport/chem id_type = /obj/item/weapon/card/id/medical/chemist pda_type = /obj/item/device/pda/chemist diff --git a/code/datums/outfits/jobs/science.dm b/code/datums/outfits/jobs/science.dm index 4a6392d61f..fcccfb8f8c 100644 --- a/code/datums/outfits/jobs/science.dm +++ b/code/datums/outfits/jobs/science.dm @@ -7,6 +7,7 @@ backpack = /obj/item/weapon/storage/backpack/toxins satchel_one = /obj/item/weapon/storage/backpack/satchel/tox messenger_bag = /obj/item/weapon/storage/backpack/messenger/tox + sports_bag = /obj/item/weapon/storage/backpack/sport/tox /decl/hierarchy/outfit/job/science/rd name = OUTFIT_JOB_NAME("Research Director") diff --git a/code/datums/outfits/jobs/security.dm b/code/datums/outfits/jobs/security.dm index b1976b7f04..65388a7902 100644 --- a/code/datums/outfits/jobs/security.dm +++ b/code/datums/outfits/jobs/security.dm @@ -8,6 +8,7 @@ satchel_one = /obj/item/weapon/storage/backpack/satchel/sec backpack_contents = list(/obj/item/weapon/handcuffs = 1) messenger_bag = /obj/item/weapon/storage/backpack/messenger/sec + sports_bag = /obj/item/weapon/storage/backpack/sport/sec /decl/hierarchy/outfit/job/security/hos name = OUTFIT_JOB_NAME("Head of security") diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index 8cdcf117ee..7b74bc448b 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -41,7 +41,7 @@ var/list/outfits_decls_by_type_ var/l_hand = null // In the list(path=count,otherpath=count) format var/list/uniform_accessories = list() // webbing, armbands etc - fits in slot_tie - var/list/backpack_contents = list() + var/list/backpack_contents = list() var/id_type var/id_desc @@ -56,6 +56,7 @@ var/list/outfits_decls_by_type_ var/satchel_one = /obj/item/weapon/storage/backpack/satchel/norm var/satchel_two = /obj/item/weapon/storage/backpack/satchel var/messenger_bag = /obj/item/weapon/storage/backpack/messenger + var/sports_bag = /obj/item/weapon/storage/backpack/sport var/flags // Specific flags @@ -76,6 +77,7 @@ var/list/outfits_decls_by_type_ if(3) back = satchel_one if(4) back = satchel_two if(5) back = messenger_bag + if(6) back = sports_bag else back = null /decl/hierarchy/outfit/proc/post_equip(mob/living/carbon/human/H) diff --git a/code/datums/wires/explosive.dm b/code/datums/wires/explosive.dm index 52b0150b66..234f75a9e8 100644 --- a/code/datums/wires/explosive.dm +++ b/code/datums/wires/explosive.dm @@ -31,4 +31,5 @@ /datum/wires/explosive/c4/explode() var/obj/item/weapon/plastique/P = holder - P.explode(get_turf(P)) + P.set_target(get_turf(P)) + P.detonate() diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 29632a7bfb..ea7326f51e 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -649,5 +649,5 @@ var/global/list/pre_init_created_atoms // atom creation ordering means some stuf . = ..() SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, new_loc) -/atom/proc/get_visible_gender() +/atom/proc/get_visible_gender(mob/user, force) return gender diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index 7a8d2f5d89..430145671f 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -328,8 +328,8 @@ var/global/list/datum/dna/gene/dna_genes[0] SetSEBlock(block,newBlock,defer) -/proc/EncodeDNABlock(var/value) - return add_zero2(num2hex(value,1), 3) +/proc/EncodeDNABlock(value) + return pad_left(num2hex(value), 3, "0") /datum/dna/proc/UpdateUI() src.uni_identity="" diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 2287d3477c..2b7b00f303 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -2,15 +2,6 @@ // Helpers for DNA2 ///////////////////////////// -// Pads 0s to t until length == u -/proc/add_zero2(t, u) - var/temp1 - while (length(t) < u) - t = "0[t]" - temp1 = t - if (length(t) > u) - temp1 = copytext(t,2,u+1) - return temp1 // DNA Gene activation boundaries, see dna2.dm. // Returns a list object with 4 numbers. diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index 2138298e6d..87273128c6 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -26,7 +26,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) min_age_by_species = list(SPECIES_HUMAN_VATBORN = 14) ideal_character_age = 70 // Old geezer captains ftw ideal_age_by_species = list(SPECIES_HUMAN_VATBORN = 55) /// Vatborn live shorter, no other race eligible for captain besides human/skrell - banned_job_species = list(SPECIES_UNATHI, SPECIES_TAJ, SPECIES_DIONA, SPECIES_PROMETHEAN, SPECIES_ZADDAT, "mechanical", "digital") + banned_job_species = list(SPECIES_UNATHI, SPECIES_TAJ, SPECIES_TESHARI, SPECIES_DIONA, SPECIES_PROMETHEAN, SPECIES_ZADDAT, "mechanical", "digital") outfit_type = /decl/hierarchy/outfit/job/captain job_description = "The Site Manager manages the other Command Staff, and through them the rest of the station. Though they have access to everything, \ diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index f32858d8fa..8a002dc6b4 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -224,7 +224,7 @@ if ("issue") if (giver) - var/number = add_zero("[rand(0,9999)]", 4) + var/number = pad_left("[rand(1, 9999)]", 4, "0") var/entry = "\[[stationtime2text()]\] Pass #[number] issued by [giver.registered_name] ([giver.assignment]) to [giv_name]. Reason: [reason]. Grants access to following areas: " for (var/i=1 to accesses.len) var/A = accesses[i] diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index e5074c06f0..2b408982ab 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -69,11 +69,15 @@ ..() /obj/machinery/computer/message_monitor/Initialize() + ..() + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/computer/message_monitor/LateInitialize() + . = ..() //Is the server isn't linked to a server, and there's a server available, default it to the first one in the list. if(!linkedServer) if(message_servers && message_servers.len > 0) linkedServer = message_servers[1] - return ..() /obj/machinery/computer/message_monitor/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index c7cb351e70..1d486ab5e3 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -210,7 +210,7 @@ var/timeleft = emergency_shuttle.estimate_arrival_time() if(timeleft < 0) return "" - return "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]" + return "[pad_left(num2text(timeleft / 60 % 60), 2, "0")]:[pad_left(num2text(timeleft % 60), 2, "0")]" /obj/machinery/status_display/proc/get_shuttle_timer_departure() if(!emergency_shuttle) @@ -218,7 +218,7 @@ var/timeleft = emergency_shuttle.estimate_launch_time() if(timeleft < 0) return "" - return "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]" + return "[pad_left(num2text(timeleft / 60 % 60), 2, "0")]:[pad_left(num2text(timeleft % 60), 2, "0")]" /obj/machinery/status_display/proc/get_supply_shuttle_timer() var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle @@ -229,7 +229,7 @@ var/timeleft = round((shuttle.arrive_time - world.time) / 10,1) if(timeleft < 0) return "Late" - return "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]" + return "[pad_left(num2text(timeleft / 60 % 60), 2, "0")]:[pad_left(num2text(timeleft % 60), 2, "0")]" return "" /obj/machinery/status_display/proc/remove_display() diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 4a9c8bf55f..c2b3fc1141 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -57,9 +57,12 @@ health -= Proj.get_structure_damage() healthcheck() +/obj/effect/spider/proc/die() + qdel(src) + /obj/effect/spider/proc/healthcheck() if(health <= 0) - qdel(src) + die() /obj/effect/spider/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature > 300 + T0C) @@ -141,7 +144,7 @@ layer = HIDING_LAYER health = 3 var/last_itch = 0 - var/amount_grown = -1 + var/amount_grown = 0 var/obj/machinery/atmospherics/unary/vent_pump/entry_vent var/travelling_in_vent = 0 var/list/grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/nurse, /mob/living/simple_mob/animal/giant_spider/hunter) @@ -171,16 +174,17 @@ else ..() -/obj/effect/spider/spiderling/proc/die() +/obj/effect/spider/spiderling/die() visible_message("[src] dies!") new /obj/effect/decal/cleanable/spiderling_remains(src.loc) - qdel(src) + ..() /obj/effect/spider/spiderling/healthcheck() if(health <= 0) die() /obj/effect/spider/spiderling/process() + healthcheck() if(travelling_in_vent) if(istype(src.loc, /turf)) travelling_in_vent = 0 diff --git a/code/game/objects/items/weapons/chewables.dm b/code/game/objects/items/weapons/chewables.dm index 186263897b..ef30947f5b 100644 --- a/code/game/objects/items/weapons/chewables.dm +++ b/code/game/objects/items/weapons/chewables.dm @@ -254,12 +254,12 @@ desc = "A chocolate-coated biscuit stick." icon_state = "pocky" item_state = "pocky" + filling = list("sugar" = 2, "chocolate" = 5) + type_butt = null /obj/item/clothing/mask/chewable/candy/pocky/process() chew() if(chewtime < 1) - spitout(0) - -/obj/item/clothing/mask/chewable/candy/pocky/Initialize() - . = ..() - reagents.add_reagent("chocolate", 10) \ No newline at end of file + if(ismob(loc)) + to_chat(loc, SPAN_NOTICE("There's no more of \the [name] left!")) + spitout(0) \ No newline at end of file diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 8cbd953a6b..4ecf203424 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -11,6 +11,7 @@ var/datum/wires/explosive/c4/wires = null var/timer = 10 var/atom/target = null + var/list/location = list() var/open_panel = 0 var/image_overlay = null var/blast_dev = -1 @@ -53,9 +54,9 @@ to_chat(user, "Planting explosives...") user.do_attack_animation(target) - if(do_after(user, 50) && in_range(user, target)) + if(do_after(user, 5 SECONDS) && in_range(user, target)) user.drop_item() - src.target = target + set_target(target) // Saving coordinates in case the reference becomes invalid loc = null if (ismob(target)) @@ -67,16 +68,25 @@ target.overlays += image_overlay to_chat(user, "Bomb has been planted. Timer counting down from [timer].") - spawn(timer*10) - explode(get_turf(target)) + addtimer(CALLBACK(src, .proc/detonate), timer SECONDS) -/obj/item/weapon/plastique/proc/explode(var/location) +/obj/item/weapon/plastique/proc/set_target(var/atom/T) + if(!isatom(T)) + return + target = T + location = list(T.x, T.y, T.z) + +/obj/item/weapon/plastique/proc/detonate() if(!target) target = get_atom_on_turf(src) if(!target) target = src - if(location) - explosion(location, blast_dev, blast_heavy, blast_light, blast_flash) + + var/turf/T = get_turf(target) + if (!T && length(location)) + T = locate(location[1], location[2], location[3]) + if (T) + explosion(T, blast_dev, blast_heavy, blast_light, blast_flash) if(target) if (istype(target, /turf/simulated/wall)) diff --git a/code/game/objects/items/weapons/grenades/explosive.dm b/code/game/objects/items/weapons/grenades/explosive.dm index 076a7accce..77e07e2c5f 100644 --- a/code/game/objects/items/weapons/grenades/explosive.dm +++ b/code/game/objects/items/weapons/grenades/explosive.dm @@ -12,6 +12,7 @@ //The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern var/spread_range = 7 loadable = null + hud_state = "grenade_frag" // TGMC Ammo HUD Port /obj/item/weapon/grenade/explosive/detonate() ..() diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index 209e47b253..9bdf650c64 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -13,6 +13,8 @@ var/det_time = 50 var/loadable = TRUE var/arm_sound = 'sound/weapons/armbomb.ogg' + var/hud_state = "grenade_he" // TGMC Ammo HUD Port + var/hud_state_empty = "grenade_empty" // TGMC Ammo HUD Port /obj/item/weapon/grenade/proc/clown_check(var/mob/living/user) if((CLUMSY in user.mutations) && prob(50)) diff --git a/code/game/objects/items/weapons/grenades/smokebomb.dm b/code/game/objects/items/weapons/grenades/smokebomb.dm index 51ec50d182..d3b417b6a7 100644 --- a/code/game/objects/items/weapons/grenades/smokebomb.dm +++ b/code/game/objects/items/weapons/grenades/smokebomb.dm @@ -6,6 +6,7 @@ det_time = 20 item_state = "flashbang" slot_flags = SLOT_BELT + hud_state = "grenade_smoke" var/datum/effect_system/smoke_spread/bad/smoke var/smoke_color var/smoke_strength = 8 diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index b296c58b96..38b82beb36 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -127,6 +127,18 @@ desc = "It's an orange backpack which was designed to hold beakers, pill bottles and bottles." icon_state = "chempack" +/obj/item/weapon/storage/backpack/white + name = "white backpack" + icon_state = "backpack_white" + +/obj/item/weapon/storage/backpack/fancy + name = "fancy backpack" + icon_state = "backpack_fancy" + +/obj/item/weapon/storage/backpack/military + name = "military backpack" + icon_state = "backpack_military" + /* * Duffle Types */ @@ -184,6 +196,16 @@ desc = "A large dufflebag for holding circuits and beakers." icon_state = "duffle_sci" +/obj/item/weapon/storage/backpack/dufflebag/drone + name = "drone dufflebag" + desc = "A large dufflebag for holding small robots? Or maybe it's one used by robots!" + icon_state = "duffle_drone" + +/obj/item/weapon/storage/backpack/dufflebag/cursed + name = "cursed dufflebag" + desc = "That probably shouldn't be moving..." + icon_state = "duffle_cursed" + /* * Satchel Types */ @@ -192,7 +214,6 @@ name = "leather satchel" desc = "It's a very fancy satchel made with fine leather." icon_state = "satchel" - item_state_slots = list(slot_r_hand_str = "briefcase", slot_l_hand_str = "briefcase") /obj/item/weapon/storage/backpack/satchel/withwallet starts_with = list(/obj/item/weapon/storage/wallet/random) @@ -206,43 +227,36 @@ name = "industrial satchel" desc = "A tough satchel with extra pockets." icon_state = "satchel-eng" - item_state_slots = list(slot_r_hand_str = "engiepack", slot_l_hand_str = "engiepack") /obj/item/weapon/storage/backpack/satchel/med name = "medical satchel" desc = "A sterile satchel used in medical departments." icon_state = "satchel-med" - item_state_slots = list(slot_r_hand_str = "medicalpack", slot_l_hand_str = "medicalpack") /obj/item/weapon/storage/backpack/satchel/vir name = "virologist satchel" desc = "A sterile satchel with virologist colours." icon_state = "satchel-vir" - item_state_slots = list(slot_r_hand_str = "viropack", slot_l_hand_str = "viropack") /obj/item/weapon/storage/backpack/satchel/chem name = "chemist satchel" desc = "A sterile satchel with chemist colours." icon_state = "satchel-chem" - item_state_slots = list(slot_r_hand_str = "chempack", slot_l_hand_str = "chempack") /obj/item/weapon/storage/backpack/satchel/gen name = "geneticist satchel" desc = "A sterile satchel with geneticist colours." icon_state = "satchel-gen" - item_state_slots = list(slot_r_hand_str = "genpack", slot_l_hand_str = "genpack") /obj/item/weapon/storage/backpack/satchel/tox name = "scientist satchel" desc = "Useful for holding research materials." icon_state = "satchel-tox" - item_state_slots = list(slot_r_hand_str = "toxpack", slot_l_hand_str = "toxpack") /obj/item/weapon/storage/backpack/satchel/sec name = "security satchel" desc = "A robust satchel for security related needs." icon_state = "satchel-sec" - item_state_slots = list(slot_r_hand_str = "securitypack", slot_l_hand_str = "securitypack") /obj/item/weapon/storage/backpack/satchel/hyd name = "hydroponics satchel" @@ -253,7 +267,18 @@ name = "site manager's satchel" desc = "An exclusive satchel for officers." icon_state = "satchel-cap" - item_state_slots = list(slot_r_hand_str = "captainpack", slot_l_hand_str = "captainpack") + +/obj/item/weapon/storage/backpack/satchel/white + name = "white satchel" + icon_state = "satchel_white" + +/obj/item/weapon/storage/backpack/satchel/fancy + name = "fancy satchel" + icon_state = "satchel_fancy" + +/obj/item/weapon/storage/backpack/satchel/military + name = "military satchel" + icon_state = "satchel_military" //ERT backpacks. /obj/item/weapon/storage/backpack/ert @@ -293,56 +318,104 @@ name = "messenger bag" desc = "A sturdy backpack worn over one shoulder." icon_state = "courierbag" - item_state_slots = list(slot_r_hand_str = "backpack", slot_l_hand_str = "backpack") + item_state_slots = list(slot_r_hand_str = "satchel-norm", slot_l_hand_str = "satchel-norm") /obj/item/weapon/storage/backpack/messenger/chem name = "chemistry messenger bag" desc = "A serile backpack worn over one shoulder. This one is in Chemsitry colors." icon_state = "courierbagchem" - item_state_slots = list(slot_r_hand_str = "chempack", slot_l_hand_str = "chempack") + item_state_slots = list(slot_r_hand_str = "satchel-chem", slot_l_hand_str = "satchel-chem") /obj/item/weapon/storage/backpack/messenger/med name = "medical messenger bag" desc = "A sterile backpack worn over one shoulder used in medical departments." icon_state = "courierbagmed" - item_state_slots = list(slot_r_hand_str = "medicalpack", slot_l_hand_str = "medicalpack") + item_state_slots = list(slot_r_hand_str = "satchel-med", slot_l_hand_str = "satchel-med") /obj/item/weapon/storage/backpack/messenger/viro name = "virology messenger bag" desc = "A sterile backpack worn over one shoulder. This one is in Virology colors." icon_state = "courierbagviro" - item_state_slots = list(slot_r_hand_str = "viropack", slot_l_hand_str = "viropack") + item_state_slots = list(slot_r_hand_str = "satchel-vir", slot_l_hand_str = "satchel-vir") /obj/item/weapon/storage/backpack/messenger/tox name = "research messenger bag" desc = "A backpack worn over one shoulder. Useful for holding science materials." icon_state = "courierbagtox" - item_state_slots = list(slot_r_hand_str = "toxpack", slot_l_hand_str = "toxpack") + item_state_slots = list(slot_r_hand_str = "satchel-tox", slot_l_hand_str = "satchel-tox") /obj/item/weapon/storage/backpack/messenger/com name = "command messenger bag" desc = "A special backpack worn over one shoulder. This one is made specifically for officers." icon_state = "courierbagcom" - item_state_slots = list(slot_r_hand_str = "captainpack", slot_l_hand_str = "captainpack") + item_state_slots = list(slot_r_hand_str = "satchel-cap", slot_l_hand_str = "satchel-cap") /obj/item/weapon/storage/backpack/messenger/engi name = "engineering messenger bag" icon_state = "courierbagengi" - item_state_slots = list(slot_r_hand_str = "engiepack", slot_l_hand_str = "engiepack") + item_state_slots = list(slot_r_hand_str = "satchel-eng", slot_l_hand_str = "satchel-eng") /obj/item/weapon/storage/backpack/messenger/hyd name = "hydroponics messenger bag" desc = "A backpack worn over one shoulder. This one is designed for plant-related work." icon_state = "courierbaghyd" + item_state_slots = list(slot_r_hand_str = "satchel_hyd", slot_l_hand_str = "satchel_hyd") /obj/item/weapon/storage/backpack/messenger/sec name = "security messenger bag" desc = "A tactical backpack worn over one shoulder. This one is in Security colors." icon_state = "courierbagsec" - item_state_slots = list(slot_r_hand_str = "securitypack", slot_l_hand_str = "securitypack") + item_state_slots = list(slot_r_hand_str = "satchel-sec", slot_l_hand_str = "satchel-sec") /obj/item/weapon/storage/backpack/messenger/black icon_state = "courierbagblk" + item_state_slots = list(slot_r_hand_str = "satchel-sec", slot_l_hand_str = "satchel-sec") + +/* + * Sport Bags + */ + +/obj/item/weapon/storage/backpack/sport + name = "sports backpack" + icon_state = "backsport" + +/obj/item/weapon/storage/backpack/sport/white + name = "white sports backpack" + icon_state = "backsport_white" + +/obj/item/weapon/storage/backpack/sport/fancy + name = "fancy sports backpack" + icon_state = "backsport_fancy" + +/obj/item/weapon/storage/backpack/sport/vir + name = "virologist sports backpack" + desc = "A sterile sports backpack with virologist colours." + icon_state = "backsport_green" + +/obj/item/weapon/storage/backpack/sport/chem + name = "chemist sports backpack" + desc = "A sterile sports backpack with chemist colours." + icon_state = "backsport_orange" + +/obj/item/weapon/storage/backpack/sport/gen + name = "geneticist sports backpack" + desc = "A sterile sports backpack with geneticist colours." + icon_state = "backsport_blue" + +/obj/item/weapon/storage/backpack/sport/tox + name = "scientist sports backpack" + desc = "Useful for holding research materials." + icon_state = "backsport_purple" + +/obj/item/weapon/storage/backpack/sport/sec + name = "security sports backpack" + desc = "A robust sports backpack for security related needs." + icon_state = "backsport_security" + +/obj/item/weapon/storage/backpack/sport/hyd + name = "hydroponics sports backpack" + desc = "A green sports backpack for plant related work." + icon_state = "backsport_hydro" //Purses diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index ed4d8fdbbe..a3cc27d926 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -20,4 +20,13 @@ force = 0 w_class = ITEMSIZE_NORMAL max_w_class = ITEMSIZE_SMALL - max_storage_space = ITEMSIZE_COST_SMALL * 4 \ No newline at end of file + max_storage_space = ITEMSIZE_COST_SMALL * 4 + +/obj/item/weapon/storage/briefcase/bookbag + name = "bookbag" + desc = "A small bookbag for holding... things other than books?" + icon_state = "bookbag" + force = 4.0 + w_class = ITEMSIZE_LARGE + max_w_class = ITEMSIZE_NORMAL + max_storage_space = ITEMSIZE_COST_NORMAL * 4 \ No newline at end of file diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index be833aec08..426db6b7dd 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -114,6 +114,7 @@ if(!istype(src.loc, /turf)) user.drop_from_inventory(src) src.loc = get_turf(src) + playsound(src.loc, 'sound/effects/rustle5.ogg', 50, 1) to_chat(user, "You add padding to \the [src].") add_padding(padding_type) return diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 5d1322c3c3..ffef310fdf 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -132,6 +132,42 @@ /obj/structure/bed/chair/comfy/orange/Initialize(var/ml,var/newmaterial) . = ..(ml, MAT_STEEL, "orange") +/obj/structure/bed/chair/rounded + name = "rounded chair" + desc = "It's a rounded chair. It looks comfy." + icon_state = "roundedchair" + base_icon = "roundedchair" + +/obj/structure/bed/chair/rounded/brown/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, MAT_LEATHER) + +/obj/structure/bed/chair/rounded/red/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "carpet") + +/obj/structure/bed/chair/rounded/teal/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "teal") + +/obj/structure/bed/chair/rounded/black/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "black") + +/obj/structure/bed/chair/rounded/green/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "green") + +/obj/structure/bed/chair/rounded/purple/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "purple") + +/obj/structure/bed/chair/rounded/blue/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "blue") + +/obj/structure/bed/chair/rounded/beige/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "beige") + +/obj/structure/bed/chair/rounded/lime/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "lime") + +/obj/structure/bed/chair/rounded/yellow/Initialize(var/ml,var/newmaterial) + . = ..(ml, MAT_STEEL, "yellow") + /obj/structure/bed/chair/office anchored = 0 buckle_movable = 1 diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 459d5b2bc7..c309ebdf53 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -393,11 +393,11 @@ else if (emergency_shuttle.wait_for_launch) var/timeleft = emergency_shuttle.estimate_launch_time() - dat += "ETL: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
" + dat += "ETL: [(timeleft / 60) % 60]:[pad_left(num2text(timeleft % 60), 2, "0")]
" else if (emergency_shuttle.shuttle.has_arrive_time()) var/timeleft = emergency_shuttle.estimate_arrival_time() - dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
" + dat += "ETA: [(timeleft / 60) % 60]:[pad_left(num2text(timeleft % 60), 2, "0")]
" dat += "Send Back
" if (emergency_shuttle.shuttle.moving_status == SHUTTLE_WARMUP) diff --git a/code/modules/admin/view_variables/view_variables_global.dm b/code/modules/admin/view_variables/view_variables_global.dm index 1f6f2d52d6..3d7302caf2 100644 --- a/code/modules/admin/view_variables/view_variables_global.dm +++ b/code/modules/admin/view_variables/view_variables_global.dm @@ -1,40 +1,49 @@ -/proc/readglobal(which) - . = global.vars[which] - -/proc/writeglobal(which, newval) - global.vars[which] = newval +GLOBAL_DATUM(debug_real_globals, /debug_real_globals) // :3c -/proc/getallglobals() - . = list() - for(var/some_global in global.vars) - . += some_global -/var/decl/global_vars/global_vars_ +/debug_real_globals/vv_get_header() + return list("Debug: Real Globals
") -/decl/global_vars - var/name = "Global Variables" -/decl/global_vars/get_view_variables_options() - return "" // Ensuring changes to the base proc never affect us +/debug_real_globals/get_variables() + var/static/list/cache + if (!cache) + cache = list() + var/list/hidden = VV_hidden() + for (var/name in global.vars) + if (name in hidden) + continue + cache |= name + cache = sortList(cache) + if (!usr || !check_rights(R_ADMIN|R_DEBUG, FALSE)) + var/static/list/locked + if (!locked) + locked = VV_locked() + return (cache - locked) + return cache.Copy() -/decl/global_vars/get_variables() - . = getallglobals() - VV_hidden() - if(!usr || !check_rights(R_ADMIN|R_DEBUG, FALSE)) - . -= VV_secluded() -/decl/global_vars/get_variable_value(varname) - return readglobal(varname) +/debug_real_globals/make_view_variables_variable_entry(name, value) + return {"(E) "} -/decl/global_vars/set_variable_value(varname, value) - writeglobal(varname, value) -/decl/global_vars/make_view_variables_variable_entry(varname, value) - return "(E) " +/debug_real_globals/set_variable_value(name, value) + global.vars[name] = value -/decl/global_vars/VV_locked() + +/debug_real_globals/get_variable_value(name) + return global.vars[name] + + +/debug_real_globals/get_view_variables_options() + return "" + + +/debug_real_globals/VV_locked() return vars -/decl/global_vars/VV_hidden() + +/debug_real_globals/VV_hidden() return list( "forumsqladdress", "forumsqldb", @@ -79,13 +88,14 @@ "adminlogs", "cardinal", "cardinalz", - "IClog" + "IClog", + "vchatdb" ) + /client/proc/debug_global_variables() set category = "Debug" - set name = "View Global Variables" - - if(!global_vars_) - global_vars_ = new() - debug_variables(global_vars_) \ No newline at end of file + set name = "View Real Globals" + if (!GLOB.debug_real_globals) + GLOB.debug_real_globals = new + debug_variables(GLOB.debug_real_globals) diff --git a/code/modules/ai/ai_holder.dm b/code/modules/ai/ai_holder.dm index 21d9cd8588..a285225286 100644 --- a/code/modules/ai/ai_holder.dm +++ b/code/modules/ai/ai_holder.dm @@ -1,14 +1,6 @@ // This is a datum-based artificial intelligence for simple mobs (and possibly others) to use. // The neat thing with having this here instead of on the mob is that it is independant of Life(), and that different mobs // can use a more or less complex AI by giving it a different datum. -#define AI_NO_PROCESS 0 -#define AI_PROCESSING (1<<0) -#define AI_FASTPROCESSING (1<<1) - -#define START_AIPROCESSING(Datum) if (!(Datum.process_flags & AI_PROCESSING)) {Datum.process_flags |= AI_PROCESSING;SSai.processing += Datum} -#define STOP_AIPROCESSING(Datum) Datum.process_flags &= ~AI_PROCESSING;SSai.processing -= Datum -#define START_AIFASTPROCESSING(Datum) if (!(Datum.process_flags & AI_FASTPROCESSING)) {Datum.process_flags |= AI_FASTPROCESSING;SSaifast.processing += Datum} -#define STOP_AIFASTPROCESSING(Datum) Datum.process_flags &= ~AI_FASTPROCESSING;SSaifast.processing -= Datum /mob/living var/datum/ai_holder/ai_holder = null diff --git a/code/modules/antagonist/outsider/mercenary.dm b/code/modules/antagonist/outsider/mercenary.dm index 94b362fca8..623291dde7 100644 --- a/code/modules/antagonist/outsider/mercenary.dm +++ b/code/modules/antagonist/outsider/mercenary.dm @@ -42,6 +42,7 @@ var/datum/antagonist/mercenary/mercs if(player.backbag == 3) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(player), slot_back) if(player.backbag == 4) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(player), slot_back) if(player.backbag == 5) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(player), slot_back) + if(player.backbag == 6) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/sport(player), slot_back) player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack) player.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT diff --git a/code/modules/antagonist/outsider/wizard.dm b/code/modules/antagonist/outsider/wizard.dm index f362f6b3a8..6a3aea1f9e 100644 --- a/code/modules/antagonist/outsider/wizard.dm +++ b/code/modules/antagonist/outsider/wizard.dm @@ -84,6 +84,7 @@ var/datum/antagonist/wizard/wizards if(wizard_mob.backbag == 3) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(wizard_mob), slot_back) if(wizard_mob.backbag == 4) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(wizard_mob), slot_back) if(wizard_mob.backbag == 5) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(wizard_mob), slot_back) + if(wizard_mob.backbag == 6) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/sport(wizard_mob), slot_back) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(wizard_mob), slot_in_backpack) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(wizard_mob), slot_r_hand) diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index c5a940e868..13d079c60a 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -36,8 +36,8 @@ pref.all_underwear -= underwear_category_name // TODO - Looks like this is duplicating the work of sanitize_character() if so, remove - if(pref.backbag > 5 || pref.backbag < 1) - pref.backbag = 1 //Same as above + if(pref.backbag > backbaglist.len || pref.backbag < 1) + pref.backbag = 2 //Same as above character.backbag = pref.backbag if(pref.pdachoice > 6 || pref.pdachoice < 1) diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm index 4a271fde93..e26a98cc25 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm @@ -121,6 +121,18 @@ ..() gear_tweaks += gear_tweak_free_color_choice +/datum/gear/accessory/bowtie + display_name = "bowtie selection" + path = /obj/item/clothing/accessory/bowtie + cost = 1 + +/datum/gear/accessory/bowtie/New() + ..() + var/list/bowties = list() + for(var/obj/item/clothing/accessory/bowtie_type as anything in typesof(/obj/item/clothing/accessory/bowtie)) + bowties[initial(bowtie_type.name)] = bowtie_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(bowties)) + /datum/gear/accessory/jacket display_name = "suit jacket selection" path = /obj/item/clothing/accessory/jacket @@ -306,4 +318,17 @@ for(var/pridepin in typesof(/obj/item/clothing/accessory/pride)) var/obj/item/clothing/accessory/pridepin_type = pridepin pridepins[initial(pridepin_type.name)] = pridepin_type - gear_tweaks += new/datum/gear_tweak/path(sortAssoc(pridepins)) \ No newline at end of file + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(pridepins)) + +/datum/gear/accessory/corpbadge + display_name = "investigator holobadge (IAA)" + path = /obj/item/clothing/accessory/badge/holo/investigator + allowed_roles = list("Internal affairs agent") + +/datum/gear/accessory/pressbadge + display_name = "corporate press pass" + path = /obj/item/clothing/accessory/badge/press + +/datum/gear/accessory/pressbadge + display_name = "freelance press pass" + path = /obj/item/clothing/accessory/badge/press/independent \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_gloves.dm b/code/modules/client/preference_setup/loadout/loadout_gloves.dm index fe56eea868..226006d10f 100644 --- a/code/modules/client/preference_setup/loadout/loadout_gloves.dm +++ b/code/modules/client/preference_setup/loadout/loadout_gloves.dm @@ -78,6 +78,10 @@ display_name = "fingerless gloves" path = /obj/item/clothing/gloves/fingerless +/datum/gear/gloves/fingerless/New() + ..() + gear_tweaks += gear_tweak_free_color_choice + /datum/gear/gloves/ring display_name = "ring selection" description = "Choose from a number of rings." diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 75121c608e..a6409e1d0e 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -90,4 +90,5 @@ desc = "A pair of gloves that don't actually cover the fingers." name = "fingerless gloves" icon_state = "fingerlessgloves" + addblends = "fingerlessgloves_a" fingerprint_chance = 100 \ No newline at end of file diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index f974c321c0..c78749f6f8 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -37,37 +37,3 @@ /obj/item/clothing/head/hardhat/dblue name = "blue hard hat" icon_state = "hardhat0_dblue" - -/obj/item/clothing/head/hardhat/ranger - var/hatcolor = "white" - name = "ranger helmet" - desc = "A special helmet designed for the Go Go ERT-Rangers, able to withstand a pressureless environment, filter gas and provide air. It has thermal vision and sometimes \ - mesons to find breaches, as well as an integrated radio... well, only in the show, of course. This one has none of those features- it just has a flashlight instead." - icon = 'icons/obj/clothing/ranger.dmi' - icon_state = "ranger_helmet" - light_overlay = "helmet_light" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|BLOCKHAIR - -/obj/item/clothing/head/hardhat/ranger/Initialize() - . = ..() - if(icon_state == "ranger_helmet") - name = "[hatcolor] ranger helmet" - icon_state = "[hatcolor]_ranger_helmet" - -/obj/item/clothing/head/hardhat/ranger/black - hatcolor = "black" - -/obj/item/clothing/head/hardhat/ranger/pink - hatcolor = "pink" - -/obj/item/clothing/head/hardhat/ranger/green - hatcolor = "green" - -/obj/item/clothing/head/hardhat/ranger/cyan - hatcolor = "cyan" - -/obj/item/clothing/head/hardhat/ranger/orange - hatcolor = "orange" - -/obj/item/clothing/head/hardhat/ranger/yellow - hatcolor = "yellow" \ No newline at end of file diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index ba20ceb2f5..925d6cae31 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -502,4 +502,41 @@ desc = "A marine helmet prop from the popular game 'Ruin'." icon_state = "marine" flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|BLOCKHAIR - body_parts_covered = HEAD|FACE|EYES \ No newline at end of file + body_parts_covered = HEAD|FACE|EYES + +/obj/item/clothing/head/ranger + var/hatcolor = "white" + name = "ranger helmet" + desc = "A special helmet designed for the Go Go ERT-Rangers, able to withstand a pressureless environment, filter gas and provide air. It has thermal vision and sometimes \ + mesons to find breaches, as well as an integrated radio... well, only in the show, of course." + icon = 'icons/obj/clothing/ranger.dmi' + icon_state = "ranger_helmet" + light_overlay = "helmet_light" + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|BLOCKHAIR + drop_sound = 'sound/items/drop/helm.ogg' + pickup_sound = 'sound/items/pickup/helm.ogg' + w_class = ITEMSIZE_NORMAL + +/obj/item/clothing/head/ranger/Initialize() + . = ..() + if(icon_state == "ranger_helmet") + name = "[hatcolor] ranger helmet" + icon_state = "[hatcolor]_ranger_helmet" + +/obj/item/clothing/head/ranger/black + hatcolor = "black" + +/obj/item/clothing/head/ranger/pink + hatcolor = "pink" + +/obj/item/clothing/head/ranger/green + hatcolor = "green" + +/obj/item/clothing/head/ranger/cyan + hatcolor = "cyan" + +/obj/item/clothing/head/ranger/orange + hatcolor = "orange" + +/obj/item/clothing/head/ranger/yellow + hatcolor = "yellow" \ No newline at end of file diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index b8151b7743..ef7d53d5e6 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -174,34 +174,36 @@ drop_sound = 'sound/items/drop/clothing.ogg' pickup_sound = 'sound/items/pickup/clothing.ogg' -/obj/item/clothing/shoes/boots/ranger +/obj/item/clothing/shoes/ranger var/bootcolor = "white" name = "ranger boots" desc = "The Rangers special lightweight hybrid magboots-jetboots perfect for EVA. If only these functions were so easy to copy in reality.\ These ones are just a well-made pair of boots in appropriate colours." icon = 'icons/obj/clothing/ranger.dmi' icon_state = "ranger_boots" + step_volume_mod = 1.2 + drop_sound = 'sound/items/drop/boots.ogg' -/obj/item/clothing/shoes/boots/ranger/Initialize() +/obj/item/clothing/shoes/ranger/Initialize() . = ..() if(icon_state == "ranger_boots") name = "[bootcolor] ranger boots" icon_state = "[bootcolor]_ranger_boots" -/obj/item/clothing/shoes/boots/ranger/black +/obj/item/clothing/shoes/ranger/black bootcolor = "black" -/obj/item/clothing/shoes/boots/ranger/pink +/obj/item/clothing/shoes/ranger/pink bootcolor = "pink" -/obj/item/clothing/shoes/boots/ranger/green +/obj/item/clothing/shoes/ranger/green bootcolor = "green" -/obj/item/clothing/shoes/boots/ranger/cyan +/obj/item/clothing/shoes/ranger/cyan bootcolor = "cyan" -/obj/item/clothing/shoes/boots/ranger/orange +/obj/item/clothing/shoes/ranger/orange bootcolor = "orange" -/obj/item/clothing/shoes/boots/ranger/yellow +/obj/item/clothing/shoes/ranger/yellow bootcolor = "yellow" \ No newline at end of file diff --git a/code/modules/clothing/suits/solgov.dm b/code/modules/clothing/suits/solgov.dm index aebec733a8..184d4e11ac 100644 --- a/code/modules/clothing/suits/solgov.dm +++ b/code/modules/clothing/suits/solgov.dm @@ -180,8 +180,8 @@ /obj/item/clothing/suit/storage/solgov/dress name = "dress jacket" desc = "A uniform dress jacket, fancy." - icon_state = "sgdress_xpl" - item_state = "sgdress_xpl" + icon_state = "ecdress_xpl" + item_state = "ecdress_xpl" body_parts_covered = UPPER_TORSO|ARMS armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0.9 @@ -192,39 +192,37 @@ /obj/item/clothing/suit/storage/solgov/dress/sifguard name = "\improper SifGuard dress jacket" desc = "A silver and grey dress jacket belonging to the Sif Defense Force. Fashionable, for the 25th century at least." - icon_state = "sgdress_xpl" - item_state = "sgdress_xpl" /obj/item/clothing/suit/storage/solgov/dress/sifguard/senior name = "\improper SifGuard senior's dress coat" - icon_state = "sgdress_sxpl" - item_state = "sgdress_sxpl" + icon_state = "ecdress_sxpl" + item_state = "ecdress_sxpl" /obj/item/clothing/suit/storage/solgov/dress/sifguard/chief name = "\improper SifGuard chief's dress coat" icon_state = "ecdress_cxpl" - item_state = "sgdress_cxpl" + item_state = "ecdress_cxpl" /obj/item/clothing/suit/storage/solgov/dress/sifguard/command name = "\improper SifGuard officer's dress coat" desc = "A gold and black dress peacoat belonging to the Sif Defense Force. The height of fashion." icon_state = "ecdress_ofcr" - item_state = "sgdress_ofcr" + item_state = "ecdress_ofcr" /obj/item/clothing/suit/storage/solgov/dress/sifguard/command/cdr name = "\improper SifGuard commander's dress coat" - icon_state = "sgdress_cdr" - item_state = "sgdress_cdr" + icon_state = "ecdress_cdr" + item_state = "ecdress_cdr" /obj/item/clothing/suit/storage/solgov/dress/sifguard/command/capt name = "\improper SifGuard captain's dress coat" - icon_state = "sgdress_capt" - item_state = "sgdress_capt" + icon_state = "ecdress_capt" + item_state = "ecdress_capt" /obj/item/clothing/suit/storage/solgov/dress/sifguard/command/adm name = "\improper SifGuard admiral's dress coat" - icon_state = "sgdress_adm" - item_state = "sgdress_adm" + icon_state = "ecdress_adm" + item_state = "ecdress_adm" /obj/item/clothing/suit/storage/solgov/dress/fleet name = "fleet dress jacket" @@ -273,7 +271,7 @@ name = "fleet dress overwear" desc = "A navy blue SCG Fleet dress suit. Almost looks like a school-girl outfit." icon_state = "sailordress" - item_state = "whitedress" + item_state = "sailordress" /obj/item/clothing/suit/dress/solgov/army name = "marine dress jacket" @@ -313,7 +311,7 @@ name = "clasped dress jacket" desc = "A uniform dress jacket with gold toggles." icon_state = "whitedress" - item_state = "labcoat" + item_state = "whitedress" blood_overlay_type = "coat" /obj/item/clothing/suit/storage/toggle/dress/fleet @@ -324,7 +322,7 @@ name = "fleet command dress jacket" desc = "A crisp white SCG Fleet dress jacket dripping with gold accents. So bright it's blinding." icon_state = "whitedress_com" - item_state = "labcoat" + item_state = "whitedress_com" blood_overlay_type = "coat" /obj/item/clothing/suit/storage/eio_jacket diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index c6a886d26d..29e5c57526 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -157,6 +157,20 @@ desc = "A neosilk clip-on tie. This one is disgusting." icon_state = "horribletie" +/obj/item/clothing/accessory/bowtie + name = "red bow tie" + desc = "Snazzy!" + icon_state = "redbowtie" + slot = ACCESSORY_SLOT_TIE + +/obj/item/clothing/accessory/bowtie/black + name = "black bow tie" + icon_state = "blackbowtie" + +/obj/item/clothing/accessory/bowtie/white + name = "white bow tie" + icon_state = "whitebowtie" + /obj/item/clothing/accessory/stethoscope name = "stethoscope" desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." diff --git a/code/modules/clothing/under/accessories/badges.dm b/code/modules/clothing/under/accessories/badges.dm index 75e8dc8e4d..49d66dcb6b 100644 --- a/code/modules/clothing/under/accessories/badges.dm +++ b/code/modules/clothing/under/accessories/badges.dm @@ -6,19 +6,14 @@ /obj/item/clothing/accessory/badge name = "detective's badge" - desc = "Security Department detective's badge, made from gold." - icon_state = "badge" + desc = "NanoTrasen Security Department detective's badge, made from gold." + icon_state = "marshalbadge" slot_flags = SLOT_BELT | SLOT_TIE slot = ACCESSORY_SLOT_MEDAL var/stored_name var/badge_string = "Corporate Security" -/obj/item/clothing/accessory/badge/old - name = "faded badge" - desc = "A faded badge, backed with leather. It bears the emblem of the Forensic division." - icon_state = "badge_round" - /obj/item/clothing/accessory/badge/proc/set_name(var/new_name) stored_name = new_name name = "[initial(name)] ([stored_name])" @@ -48,8 +43,8 @@ /obj/item/clothing/accessory/badge/sheriff name = "sheriff badge" desc = "This town ain't big enough for the two of us, pardner." - icon_state = "sheriff" - item_state = "goldbadge" + icon_state = "sheriff_toy" + item_state = "sheriff_toy" /obj/item/clothing/accessory/badge/sheriff/attack_self(mob/user as mob) user.visible_message("[user] shows their sheriff badge. There's a new sheriff in town!",\ @@ -61,10 +56,10 @@ user.do_attack_animation(M) user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) //to prevent spam -//.Holobadges. +//Security Holobadges /obj/item/clothing/accessory/badge/holo name = "holobadge" - desc = "This glowing blue badge marks the holder as THE LAW." + desc = "This glowing blue badge marks the holder as law enforcement." icon_state = "holobadge" var/emagged //Emagging removes Sec check. @@ -111,9 +106,16 @@ desc = "A box claiming to contain holobadges." starts_with = list( /obj/item/clothing/accessory/badge/holo = 4, + /obj/item/clothing/accessory/badge/holo/officer = 2, /obj/item/clothing/accessory/badge/holo/cord = 2 ) +/obj/item/clothing/accessory/badge/holo/officer + name = "officer's badge" + desc = "A bronze corporate security badge. Stamped with the words 'Security Officer.'" + icon_state = "bronzebadge" + slot_flags = SLOT_TIE | SLOT_BELT + /obj/item/clothing/accessory/badge/holo/warden name = "warden's holobadge" desc = "A silver corporate security badge. Stamped with the words 'Warden.'" @@ -122,7 +124,7 @@ /obj/item/clothing/accessory/badge/holo/hos name = "head of security's holobadge" - desc = "An immaculately polished gold security badge. Labeled 'Head of Security.'" + desc = "An immaculately polished gold security badge. Stamped with the words 'Head of Security.'" icon_state = "goldbadge" slot_flags = SLOT_TIE | SLOT_BELT @@ -141,9 +143,65 @@ /obj/item/clothing/accessory/badge/holo/detective = 2, /obj/item/clothing/accessory/badge/holo/hos = 1, /obj/item/clothing/accessory/badge/holo/cord = 1 - + ) +/obj/item/clothing/accessory/badge/holo/investigator + name = "\improper Internal Investigations holobadge" + desc = "This badge marks the holder as an internal affairs investigator." + icon_state = "invbadge" + badge_string = "Internal Investigations" + slot_flags = SLOT_TIE | SLOT_BELT + +/obj/item/clothing/accessory/badge/holo/sheriff + name = "sheriff badge" + desc = "A star-shaped brass badge denoting who the law is around these parts." + icon_state = "sheriff" + slot_flags = SLOT_TIE | SLOT_BELT + +//Other badges + +/obj/item/clothing/accessory/badge/old + name = "faded badge" + desc = "A faded law enforcement badge in an older design." + icon_state = "badge_round" + +/obj/item/clothing/accessory/badge/solid + name = "\improper SolGov ID badge" + desc = "A descriptive identification badge with the holder's credentials. This one indicates the holder is representing the SCG." + icon_state = "solbadge" + badge_string = null + +/obj/item/clothing/accessory/badge/ntid + name = "\improper NT ID badge" + desc = "A descriptive identification badge with the holder's credentials. This one has red marks with the NanoTrasen logo on it." + icon_state = "ntbadge" + badge_string = null + +/obj/item/clothing/accessory/badge/press + name = "corporate press pass" + desc = "A corporate reporter's pass, emblazoned with the NanoTrasen logo." + icon_state = "pressbadge" + item_state = "pbadge" + badge_string = "Corporate Reporter" + w_class = ITEMSIZE_TINY + + drop_sound = 'sound/items/drop/rubber.ogg' + pickup_sound = 'sound/items/pickup/rubber.ogg' + +/obj/item/clothing/accessory/badge/press/independent + name = "press pass" + desc = "A freelance journalist's pass, certified by Oculum Broadcast." + icon_state = "pressbadge-i" + badge_string = "Freelance Journalist" + +/obj/item/clothing/accessory/badge/press/plastic + name = "plastic press pass" + desc = "A journalist's 'pass' shaped, for whatever reason, like a security badge. It is made of plastic." + icon_state = "pbadge" + badge_string = "Sicurity Journelist" + w_class = ITEMSIZE_SMALL + // Synthmorph bag / Corporation badges. Primarily used on the robobag, but can be worn. Default is NT. /obj/item/clothing/accessory/badge/corporate_tag diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index 72cbcb91ae..e99a816e86 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -135,22 +135,34 @@ desc = "A worn-out handgun holster. Perfect for concealed carry" icon_state = "holster" +/obj/item/clothing/accessory/holster/armpit/black + icon_state = "holster_b" + /obj/item/clothing/accessory/holster/waist name = "waist holster" desc = "A handgun holster. Made of expensive leather." - icon_state = "holster" + icon_state = "holster_low" overlay_state = "holster_low" concealed_holster = 0 +/obj/item/clothing/accessory/holster/waist/black + icon_state = "holster_b_low" + /obj/item/clothing/accessory/holster/hip name = "hip holster" - desc = "A handgun holster slung low on the hip, draw pardner!" + desc = "No one dared to ask his business, no one dared to make a slip. The stranger there among them had a big iron on his hip." icon_state = "holster_hip" concealed_holster = 0 +/obj/item/clothing/accessory/holster/hip/black + icon_state = "holster_b_hip" + /obj/item/clothing/accessory/holster/leg name = "leg holster" - desc = "A tacticool handgun holster. Worn on the upper leg." + desc = "A drop leg holster worn on the upper leg." icon_state = "holster_leg" overlay_state = "holster_leg" concealed_holster = 0 + +/obj/item/clothing/accessory/holster/leg/black + icon_state = "holster_b_leg" \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index bcca912dcc..0533cbd9b4 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -1216,6 +1216,7 @@ Uniforms and such desc = "A waistline this high is just made for ripping bodices, swashing buckles, or - just occasionally - sucking blood." icon_state = "gayvampire" worn_state = "gayvampire" + index = 1 /obj/item/clothing/under/rank/psych/turtleneck/sweater desc = "A warm looking sweater and a pair of dark blue slacks." @@ -1275,34 +1276,35 @@ Uniforms and such //Ranger uniforms //On-mob sprites go in icons\mob\uniform.dmi with the format "white_ranger_uniform_s" - with 'white' replaced with green, cyan, etc... of course! Note the _s - this is not optional. //Item sprites go in icons\obj\clothing\ranger.dmi with the format "white_ranger_uniform" -/obj/item/clothing/under/color/ranger +/obj/item/clothing/under/ranger var/unicolor = "white" name = "ranger uniform" desc = "Made from a space-proof fibre and tight fitting, this uniform usually gives the agile Rangers all kinds of protection while not inhibiting their movement. \ This costume is instead made from genuine cotton fibre and is based on the season three uniform." icon = 'icons/obj/clothing/ranger.dmi' icon_state = "ranger_uniform" + rolled_sleeves = FALSE -/obj/item/clothing/under/color/ranger/Initialize() +/obj/item/clothing/under/ranger/Initialize() . = ..() if(icon_state == "ranger_uniform") //allows for custom items name = "[unicolor] ranger uniform" icon_state = "[unicolor]_ranger_uniform" -/obj/item/clothing/under/color/ranger/black +/obj/item/clothing/under/ranger/black unicolor = "black" -/obj/item/clothing/under/color/ranger/pink +/obj/item/clothing/under/ranger/pink unicolor = "pink" -/obj/item/clothing/under/color/ranger/green +/obj/item/clothing/under/ranger/green unicolor = "green" -/obj/item/clothing/under/color/ranger/cyan +/obj/item/clothing/under/ranger/cyan unicolor = "cyan" -/obj/item/clothing/under/color/ranger/orange +/obj/item/clothing/under/ranger/orange unicolor = "orange" -/obj/item/clothing/under/color/ranger/yellow +/obj/item/clothing/under/ranger/yellow unicolor = "yellow" \ No newline at end of file diff --git a/code/modules/events/money_hacker.dm b/code/modules/events/money_hacker.dm index 025bcc6901..86f7be0e49 100644 --- a/code/modules/events/money_hacker.dm +++ b/code/modules/events/money_hacker.dm @@ -52,7 +52,7 @@ GLOBAL_VAR_INIT(account_hack_attempted, 0) var/date2 = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], [rand(1000,3000)]" T.date = pick("", current_date_string, date1, date2) var/time1 = rand(0, 99999999) - var/time2 = "[round(time1 / 36000)+12]:[(time1 / 600 % 60) < 10 ? add_zero(time1 / 600 % 60, 1) : time1 / 600 % 60]" + var/time2 = "[round(time1 / 36000)+12]:[(time1 / 600 % 60) < 10 ? pad_left("[time1 / 600 % 60]", 2, "0") : time1 / 600 % 60]" T.time = pick("", stationtime2text(), time2) T.source_terminal = pick("","[pick("Biesel","New Gibson")] GalaxyNet Terminal #[rand(111,999)]","your mums place","nantrasen high CommanD") diff --git a/code/modules/gamemaster/event2/events/command/money_hacker.dm b/code/modules/gamemaster/event2/events/command/money_hacker.dm index b365fdaef2..a0831495a8 100644 --- a/code/modules/gamemaster/event2/events/command/money_hacker.dm +++ b/code/modules/gamemaster/event2/events/command/money_hacker.dm @@ -103,7 +103,7 @@ T.date = pick("", current_date_string, date1, date2,"Nowhen") var/time1 = rand(0, 99999999) - var/time2 = "[round(time1 / 36000)+12]:[(time1 / 600 % 60) < 10 ? add_zero(time1 / 600 % 60, 1) : time1 / 600 % 60]" + var/time2 = "[round(time1 / 36000)+12]:[(time1 / 600 % 60) < 10 ? pad_left("[time1 / 600 % 60]", 2, "0") : time1 / 600 % 60]" T.time = pick("", stationtime2text(), time2, "Never") T.source_terminal = pick("","[pick("Biesel","New Gibson")] GalaxyNet Terminal #[rand(111,999)]","your mums place","nantrasen high CommanD","Angessa's Pearl","Nowhere") diff --git a/code/modules/hydroponics/seed_controller.dm b/code/modules/hydroponics/seed_controller.dm index 85c6a5f51e..6a5012f514 100644 --- a/code/modules/hydroponics/seed_controller.dm +++ b/code/modules/hydroponics/seed_controller.dm @@ -97,11 +97,10 @@ var/global/datum/controller/plants/plant_controller // Set in New(). var/list/plant_traits = ALL_GENES while(plant_traits && plant_traits.len) var/gene_tag = pick(plant_traits) - var/gene_mask = "[uppertext(num2hex(rand(0,255), 2))]" - - while(gene_mask in used_masks) - gene_mask = "[uppertext(num2hex(rand(0,255), 2))]" - + var/gene_mask + do + gene_mask = random_hex_text(2, TRUE) + while (gene_mask in used_masks) var/decl/plantgene/G for(var/D in gene_datums) diff --git a/code/modules/materials/materials/metals/steel.dm b/code/modules/materials/materials/metals/steel.dm index 10560dec36..e871e03070 100644 --- a/code/modules/materials/materials/metals/steel.dm +++ b/code/modules/materials/materials/metals/steel.dm @@ -28,6 +28,18 @@ new /datum/stack_recipe("yellow comfy chair", /obj/structure/bed/chair/comfy/yellow, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), new /datum/stack_recipe("orange comfy chair", /obj/structure/bed/chair/comfy/orange, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), )), + new /datum/stack_recipe_list("rounded chairs", list( + new /datum/stack_recipe("beige rounded chair", /obj/structure/bed/chair/rounded/beige, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("black rounded chair", /obj/structure/bed/chair/rounded/black, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("brown rounded chair", /obj/structure/bed/chair/rounded/brown, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("lime rounded chair", /obj/structure/bed/chair/rounded/lime, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("teal rounded chair", /obj/structure/bed/chair/rounded/teal, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("red rounded chair", /obj/structure/bed/chair/rounded/red, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("blue rounded chair", /obj/structure/bed/chair/rounded/blue, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("purple rounded chair", /obj/structure/bed/chair/rounded/purple, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("green rounded chair", /obj/structure/bed/chair/rounded/green, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("yellow rounded chair", /obj/structure/bed/chair/rounded/yellow, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + )), new /datum/stack_recipe_list("airlock assemblies", list( new /datum/stack_recipe("standard airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), new /datum/stack_recipe("command airlock assembly", /obj/structure/door_assembly/door_assembly_com, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), diff --git a/code/modules/materials/materials/organic/leather.dm b/code/modules/materials/materials/organic/leather.dm index f5fc8cb2f9..cb564bcbd6 100644 --- a/code/modules/materials/materials/organic/leather.dm +++ b/code/modules/materials/materials/organic/leather.dm @@ -1,6 +1,6 @@ /datum/material/leather name = MAT_LEATHER - display_name = "plainleather" + display_name = "plain leather" icon_colour = "#5C4831" stack_type = /obj/item/stack/material/leather stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 2c537bd4c8..30fe22fc78 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -23,6 +23,8 @@ var/list/mining_overlay_cache = list() var/rock_side_icon_state = "rock_side" var/sand_icon_state = "asteroid" var/rock_icon_state = "rock" + var/sand_icon_path = 'icons/turf/flooring/asteroid.dmi' // Override this on a subtype turf if you want a custom icon + var/rock_icon_path = 'icons/turf/walls.dmi' // Override this on a subtype turf if you want a custom icon var/random_icon = 0 var/ore/mineral @@ -30,6 +32,7 @@ var/list/mining_overlay_cache = list() var/mined_ore = 0 var/last_act = 0 var/overlay_detail + var/overlay_detail_icon_path = 'icons/turf/flooring/decals.dmi' // Override this on a subtype turf if you want a custom icon var/datum/geosample/geologic_data var/excavation_level = 0 @@ -266,7 +269,7 @@ var/list/mining_overlay_cache = list() else name = "rock" - icon = 'icons/turf/walls.dmi' + icon = rock_icon_path icon_state = rock_icon_state //Apply overlays if we should have borders @@ -284,7 +287,7 @@ var/list/mining_overlay_cache = list() //We are a sand floor else name = floor_name - icon = 'icons/turf/flooring/asteroid.dmi' + icon = sand_icon_path icon_state = sand_icon_state if(sand_dug) @@ -299,11 +302,11 @@ var/list/mining_overlay_cache = list() else var/turf/T = get_step(src, direction) if(istype(T) && T.density) - add_overlay(get_cached_border(rock_side_icon_state,direction,'icons/turf/walls.dmi',rock_side_icon_state)) + add_overlay(get_cached_border(rock_side_icon_state,direction,rock_icon_path,rock_side_icon_state)) if(overlay_detail) if(overlay_detail in icon_states(icon)) - add_overlay('icons/turf/flooring/decals.dmi',overlay_detail) + add_overlay(overlay_detail_icon_path,overlay_detail) if(update_neighbors) for(var/direction in alldirs) diff --git a/code/modules/mob/living/autohiss.dm b/code/modules/mob/living/autohiss.dm index 7a3999ea36..a51616a56f 100644 --- a/code/modules/mob/living/autohiss.dm +++ b/code/modules/mob/living/autohiss.dm @@ -55,6 +55,18 @@ ) autohiss_exempt = list(LANGUAGE_SIIK,LANGUAGE_AKHANI) +/datum/species/zaddat + autohiss_basic_map = list( + "f" = list("v","vh"), + "ph" = list("v", "vh") + ) + autohiss_extra_map = list( + "s" = list("z", "zz", "zzz"), + "ce" = list("z", "zz"), + "ci" = list("z", "zz"), + "v" = list("vv", "vvv") + ) + autohiss_exempt = list(LANGUAGE_ZADDAT) /datum/species/proc/handle_autohiss(message, datum/language/lang, mode) if(!autohiss_basic_map) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index efa90d3116..ba0d770728 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -76,22 +76,12 @@ BP_L_LEG = skip_body & EXAMINE_SKIPLEGS, BP_R_LEG = skip_body & EXAMINE_SKIPLEGS) - var/datum/gender/T = gender_datums[get_visible_gender()] - - if((skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE)) //big suits/masks/helmets make it hard to tell their gender - T = gender_datums[PLURAL] - - else if(species && species.ambiguous_genders) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.species && !istype(species, H.species)) - T = gender_datums[PLURAL]// Species with ambiguous_genders will not show their true gender upon examine if the examiner is not also the same species. - if(!(issilicon(user) || isobserver(user))) // Ghosts and borgs are all knowing - T = gender_datums[PLURAL] - - if(!T) - // Just in case someone VVs the gender to something strange. It'll runtime anyway when it hits usages, better to CRASH() now with a helpful message. - CRASH("Gender datum was null; key was '[((skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE)) ? PLURAL : gender]'") + + var/gender_hidden = (skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE) + var/gender_key = get_visible_gender(user, gender_hidden) + var/datum/gender/T = gender_datums[gender_key] + if (!T) + CRASH({"Null gender datum on examine: mob="[src]",hidden="[gender_hidden]",key="[gender_key]",bio="[gender]",id="[identifying_gender]""}) var/name_ender = "" if(!((skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE))) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b0b2a7c8ae..20e5469e75 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -849,13 +849,27 @@ remoteview_target = null reset_view(0) -/mob/living/carbon/human/get_visible_gender() - if(wear_suit && wear_suit.flags_inv & HIDEJUMPSUIT && ((head && head.flags_inv & HIDEMASK) || wear_mask)) - return PLURAL //plural is the gender-neutral default - if(species) - if(species.ambiguous_genders) - return PLURAL // regardless of what you're wearing, your gender can't be figured out - return get_gender() + +/mob/living/carbon/human/get_visible_gender(mob/user, force) + switch (force) + if (VISIBLE_GENDER_FORCE_PLURAL) + return PLURAL + if (VISIBLE_GENDER_FORCE_IDENTIFYING) + return get_gender() + if (VISIBLE_GENDER_FORCE_BIOLOGICAL) + return gender + else + if ((wear_mask || (head?.flags_inv & HIDEMASK)) && (wear_suit?.flags_inv & HIDEJUMPSUIT)) + return PLURAL + if (species?.ambiguous_genders && user) + if (ishuman(user)) + var/mob/living/carbon/human/human = user + if (!istype(human.species, species)) + return PLURAL + else if (!isobserver(user) && !issilicon(user)) + return PLURAL + return get_gender() + /mob/living/carbon/human/proc/increase_germ_level(n) if(gloves) 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 79d19b66db..1691d87bb2 100644 --- a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm +++ b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm @@ -322,7 +322,7 @@ var/list/wrapped_species_by_ref = list() /mob/living/carbon/human/proc/shapeshifter_set_eye_color(var/new_eyes) - var/list/new_color_rgb_list = hex2rgb(new_eyes) + var/list/new_color_rgb_list = rgb2num(new_eyes) // First, update mob vars. r_eyes = new_color_rgb_list[1] g_eyes = new_color_rgb_list[2] diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b0373cbcef..67a57e4f33 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -938,7 +938,7 @@ var/B = 0 for(var/C in colors_to_blend) - var/RGB = hex2rgb(C) + var/RGB = rgb2num(C) R = between(0, R + RGB[1], 255) G = between(0, G + RGB[2], 255) B = between(0, B + RGB[3], 255) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index fcc1fd62df..dff56aef72 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -133,7 +133,7 @@ /mob/living/silicon/pai/proc/show_silenced() if(src.silence_time) var/timeleft = round((silence_time - world.timeofday)/10 ,1) - stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]") + stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[pad_left(num2text(timeleft % 60), 2, "0")]") /mob/living/silicon/pai/Stat() diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm index 915c14e9f7..6c1d5b738b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm @@ -57,14 +57,14 @@ // Used for a special grenade, to ensure they don't attack the wrong thing. /mob/living/simple_mob/mechanical/viscerator/mercenary/IIsAlly(mob/living/L) . = ..() - if(!.) // Not friendly, see if they're a baddie first. + if(!. && isliving(L)) // Not friendly, see if they're a baddie first. if(L.mind && mercs.is_antagonist(L.mind)) return TRUE // Similar to above but for raiders. /mob/living/simple_mob/mechanical/viscerator/raider/IIsAlly(mob/living/L) . = ..() - if(!.) // Not friendly, see if they're a baddie first. + if(!. && isliving(L)) // Not friendly, see if they're a baddie first. if(L.mind && raiders.is_antagonist(L.mind)) return TRUE @@ -83,7 +83,7 @@ /mob/living/simple_mob/mechanical/viscerator/station/IIsAlly(mob/living/L) . = ..() - if(!.) + if(!. && isliving(L)) if(isrobot(L)) // They ignore synths. return TRUE if(istype(L, /mob/living/simple_mob/mechanical/ward/monitor/crew)) // Also ignore friendly monitor wards @@ -97,4 +97,4 @@ movement_cooldown = 0.5 /decl/mob_organ_names/viscerator - hit_zones = list("chassis", "rotor blades", "sensor array") \ No newline at end of file + hit_zones = list("chassis", "rotor blades", "sensor array") diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index c908b7952b..2383700ed3 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -86,13 +86,6 @@ return check_rights(R_ADMIN|R_EVENT, 0, user) != 0 -/proc/hsl2rgb(h, s, l) - return //TODO: Implement - -/* - Miss Chance -*/ - /proc/check_zone(zone) if(!zone) return BP_TORSO switch(zone) diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 9ac1263238..7796c86ea1 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -29,7 +29,7 @@ all_underwear[WRC.name] = WRI.name - backbag = rand(1,5) + backbag = rand(1,6) pdachoice = rand(1,5) age = rand(current_species.min_age, current_species.max_age) b_type = RANDOM_BLOOD_TYPE diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm index e7e8c5f135..18307d69a9 100644 --- a/code/modules/organs/internal/eyes.dm +++ b/code/modules/organs/internal/eyes.dm @@ -40,7 +40,7 @@ var/new_color = input("Pick a new color for your eyes.","Eye Color", current_color) as null|color if(new_color && owner) // input() supplies us with a hex color, which we can't use, so we convert it to rbg values. - var/list/new_color_rgb_list = hex2rgb(new_color) + var/list/new_color_rgb_list = rgb2num(new_color) // First, update mob vars. owner.r_eyes = new_color_rgb_list[1] owner.g_eyes = new_color_rgb_list[2] diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 1c8af09d9e..5a988e3100 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -43,10 +43,6 @@ icon_state = "pen_red" colour = "red" -/obj/item/weapon/pen/fountain - desc = "A well made fountain pen." - icon_state = "pen_fountain" - /obj/item/weapon/pen/multi desc = "It's a pen with multiple colors of ink!" var/selectedColor = 1 @@ -75,6 +71,46 @@ icon_state = "pen" colour = "white" +//Fountain Pens + +/obj/item/weapon/pen/fountain + desc = "A well made fountain pen with a faux-wood finish." + icon_state = "pen_fountain" + +/obj/item/weapon/pen/fountain2 + desc = "A well made fountain pen, with a faux wood body. This one has golden accents." + icon_state = "pen_fountain2" + +/obj/item/weapon/pen/fountain3 + desc = "A well made expensive rosewood pen with golden accents. Very pretty." + icon_state = "red_fountain" + +/obj/item/weapon/pen/fountain4 + desc = "A well made and expensive fountain pen. This one has silver accents." + icon_state = "blues_fountain" + +/obj/item/weapon/pen/fountain5 + desc = "A well made and expensive fountain pen. This one has gold accents." + icon_state = "blueg_fountain" + +/obj/item/weapon/pen/fountain6 + desc = "A well made and expensive fountain pen. The nib is quite sharp." + icon_state = "command_fountain" + +/obj/item/weapon/pen/fountain7 + desc = "A well made and expensive fountain pen made from gold." + icon_state = "gold_fountain" + +/obj/item/weapon/pen/fountain8 + desc = "A well made and expensive fountain pen." + icon_state = "black_fountain" + +/obj/item/weapon/pen/fountain9 + desc = "A well made and expensive fountain pen made for gesturing." + icon_state = "mime_fountain" + + + /* * Reagent pens */ diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 5d554b05d3..738017e5d7 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -2,8 +2,8 @@ name = "photocopier" desc = "Copy all your important papers here!" icon = 'icons/obj/library.dmi' - icon_state = "bigscanner" - var/insert_anim = "bigscanner1" + icon_state = "photocopier" + var/insert_anim = "photocopier_scan" anchored = 1 density = 1 use_power = USE_POWER_IDLE @@ -72,12 +72,14 @@ sleep(11) copy(copyitem) audible_message("You can hear [src] whirring as it finishes printing.", runemessage = "whirr") + flick("photocopier_print", src) playsound(src, "sound/machines/buzzbeep.ogg", 30) else if (istype(copyitem, /obj/item/weapon/photo)) playsound(loc, "sound/machines/copier.ogg", 100, 1) sleep(11) photocopy(copyitem) audible_message("You can hear [src] whirring as it finishes printing.", runemessage = "whirr") + flick("photocopier_print", src) playsound(src, "sound/machines/buzzbeep.ogg", 30) else if (istype(copyitem, /obj/item/weapon/paper_bundle)) sleep(11) @@ -85,6 +87,7 @@ var/obj/item/weapon/paper_bundle/B = bundlecopy(copyitem) sleep(11*B.pages.len) audible_message("You can hear [src] whirring as it finishes printing.", runemessage = "whirr") + flick("photocopier_print", src) playsound(src, "sound/machines/buzzbeep.ogg", 30) else to_chat(user, "\The [copyitem] can't be copied by [src].") @@ -151,11 +154,15 @@ if(toner <= 10) //allow replacing when low toner is affecting the print darkness user.drop_item() to_chat(user, "You insert the toner cartridge into \the [src].") + flick("photocopier_toner", src) + playsound(loc, 'sound/machines/click.ogg', 50, 1) var/obj/item/device/toner/T = O toner += T.toner_amount qdel(O) else to_chat(user, "This cartridge is not yet ready for replacement! Use up the rest of the toner.") + flick("photocopier_notoner", src) + playsound(loc, 'sound/machines/buzz-two.ogg', 75, 1) else if(O.is_wrench()) playsound(src, O.usesound, 50, 1) anchored = !anchored diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index 449f08e723..f567cf478a 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -48,6 +48,10 @@ icon_state = "stamp-deny" attack_verb = list("DENIED") +/obj/item/weapon/stamp/accepted + name = "\improper ACCEPTED rubber stamp" + icon_state = "stamp-ok" + /obj/item/weapon/stamp/clown name = "clown's rubber stamp" icon_state = "stamp-clown" @@ -72,6 +76,21 @@ name = "\improper Sol Government rubber stamp" icon_state = "stamp-sg" +/obj/item/weapon/stamp/solgovlogo + name = "\improper Sol Government logo stamp" + icon_state = "stamp-sol" + +/obj/item/stamp/einstein + name = "\improper Einstein Engines rubber stamp" + icon_state = "stamp-einstein" + +/obj/item/stamp/hephaestus + name = "\improper Hephaestus Industries rubber stamp" + icon_state = "stamp-heph" + +/obj/item/stamp/zeng_hu + name = "\improper Zeng-Hu Pharmaceuticals rubber stamp" + icon_state = "stamp-zenghu" // Syndicate stamp to forge documents. /obj/item/weapon/stamp/chameleon/attack_self(mob/user as mob) diff --git a/code/modules/planet/sif.dm b/code/modules/planet/sif.dm index b418a42db0..867fc829f0 100644 --- a/code/modules/planet/sif.dm +++ b/code/modules/planet/sif.dm @@ -81,12 +81,12 @@ var/datum/planet/sif/planet_sif = null if(weather_holder && weather_holder.current_weather && weather_holder.current_weather.light_color) new_color = weather_holder.current_weather.light_color else - var/list/low_color_list = hex2rgb(low_color) + var/list/low_color_list = rgb2num(low_color) var/low_r = low_color_list[1] var/low_g = low_color_list[2] var/low_b = low_color_list[3] - var/list/high_color_list = hex2rgb(high_color) + var/list/high_color_list = rgb2num(high_color) var/high_r = high_color_list[1] var/high_g = high_color_list[2] var/high_b = high_color_list[3] diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index a1d31cdfa1..7fd8688a2c 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -53,6 +53,12 @@ if(self_recharge) if(world.time >= last_use + charge_delay) give(charge_amount) + // TGMC Ammo HUD - Update the HUD every time we're called to recharge. + if(istype(loc, /obj/item/weapon/gun/energy)) // Are we in a gun currently? + var/obj/item/weapon/gun/energy/gun = loc + var/mob/living/user = gun.loc + if(istype(user)) + user?.hud_used.update_ammo_hud(user, gun) // Update the HUD else return PROCESS_KILL diff --git a/code/modules/power/cells/esoteric_cells.dm b/code/modules/power/cells/esoteric_cells.dm index b9bb06bf68..346d3b3ad1 100644 --- a/code/modules/power/cells/esoteric_cells.dm +++ b/code/modules/power/cells/esoteric_cells.dm @@ -69,6 +69,7 @@ C4.visible_message("The current fries \the [C4]!") if(prob(10)) - C4.explode(get_turf(src)) + C4.set_target(src) + C4.detonate() else qdel(C4) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index d19e6d6ca9..0bb9c643bb 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -401,6 +401,8 @@ if(muzzle_flash) set_light(0) + + user.hud_used.update_ammo_hud(user, src) // Similar to the above proc, but does not require a user, which is ideal for things like turrets. /obj/item/weapon/gun/proc/Fire_userless(atom/target) @@ -493,6 +495,7 @@ /obj/item/weapon/gun/proc/handle_click_empty(mob/user) if (user) user.visible_message("*click click*", "*click*") + user.hud_used.update_ammo_hud(user, src) else src.visible_message("*click click*") playsound(src, 'sound/weapons/empty.ogg', 100, 1) @@ -724,8 +727,35 @@ var/datum/firemode/new_mode = firemodes[sel_mode] new_mode.apply_to(src) to_chat(user, "\The [src] is now set to [new_mode.name].") + user.hud_used.update_ammo_hud(user, src) return new_mode /obj/item/weapon/gun/attack_self(mob/user) switch_firemodes(user) + +/* TGMC Ammo HUD Port Begin */ +/obj/item/weapon/gun + var/hud_enabled = TRUE + +/obj/item/weapon/gun/proc/has_ammo_counter() + return FALSE + +/obj/item/weapon/gun/proc/get_ammo_type() + return FALSE + +/obj/item/weapon/gun/proc/get_ammo_count() + return FALSE + +/obj/item/weapon/gun/equipped(mob/living/user, slot) // When a gun is equipped to your hands, we'll add the HUD to the user. Pending porting over TGMC guncode where wielding is far more sensible. + if(slot == slot_l_hand || slot == slot_r_hand) + user.hud_used.add_ammo_hud(user, src) + else + user.hud_used.remove_ammo_hud(user, src) + + return ..() + +/obj/item/weapon/gun/dropped(mob/living/user) // Ditto as above, we remove the HUD. Pending porting TGMC code to clean up this fucking nightmare of spaghetti. + user.hud_used.remove_ammo_hud(user, src) + + ..() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 245aad9a95..91ca21f48e 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -90,6 +90,9 @@ power_supply.give(rechargeamt) //... to recharge 1/5th the battery update_icon() + var/mob/living/M = loc // TGMC Ammo HUD + if(istype(M)) // TGMC Ammo HUD + M?.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD else charge_tick = 0 return 1 @@ -109,6 +112,9 @@ if(!power_supply) return null if(!ispath(projectile_type)) return null if(!power_supply.checked_use(charge_cost)) return null + var/mob/living/M = loc // TGMC Ammo HUD + if(istype(M)) // TGMC Ammo HUD + M?.hud_used.update_ammo_hud(M, src) return new projectile_type(src) /obj/item/weapon/gun/energy/proc/load_ammo(var/obj/item/C, mob/user) @@ -130,6 +136,7 @@ playsound(src, 'sound/weapons/flipblade.ogg', 50, 1) update_icon() update_held_icon() + user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD else to_chat(user, "This cell is not fitted for [src].") return @@ -146,6 +153,7 @@ playsound(src, 'sound/weapons/empty.ogg', 50, 1) update_icon() update_held_icon() + user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD else to_chat(user, "[src] does not have a power cell.") @@ -231,4 +239,21 @@ results += ..() - return results \ No newline at end of file + return results + +// TGMC AMMO HUD +/obj/item/weapon/gun/energy/has_ammo_counter() + return TRUE + +/obj/item/weapon/gun/energy/get_ammo_type() + if(!projectile_type) + return list("unknown", "unknown") + else + var/obj/item/projectile/P = projectile_type + return list(initial(P.hud_state), initial(P.hud_state_empty)) + +/obj/item/weapon/gun/energy/get_ammo_count() + if(!power_supply) + return 0 + else + return FLOOR(power_supply.charge / max(charge_cost, 1), 1) \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index a8b1ab929d..8ce418b5f1 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -54,6 +54,10 @@ chambered = ammo_magazine.stored_ammo[ammo_magazine.stored_ammo.len] if(handle_casings != HOLD_CASINGS) ammo_magazine.stored_ammo -= chambered + + var/mob/living/M = loc + if(istype(M)) + M?.hud_used.update_ammo_hud(M, src) if (chambered) return chambered.BB @@ -98,6 +102,10 @@ if(handle_casings != HOLD_CASINGS) chambered = null + + var/mob/living/M = loc + if(istype(M)) + M?.hud_used.update_ammo_hud(M, src) //Attempts to load A into src, depending on the type of thing being loaded and the load_method @@ -117,6 +125,7 @@ AM.loc = src ammo_magazine = AM user.visible_message("[user] inserts [AM] into [src].", "You insert [AM] into [src].") + user.hud_used.update_ammo_hud(user, src) playsound(src, 'sound/weapons/flipblade.ogg', 50, 1) if(SPEEDLOADER) if(loaded.len >= max_shells) @@ -131,8 +140,10 @@ loaded += C AM.stored_ammo -= C //should probably go inside an ammo_magazine proc, but I guess less proc calls this way... count++ + user.hud_used.update_ammo_hud(user, src) if(count) user.visible_message("[user] reloads [src].", "You load [count] round\s into [src].") + user.hud_used.update_ammo_hud(user, src) playsound(src, 'sound/weapons/empty.ogg', 50, 1) AM.update_icon() else if(istype(A, /obj/item/ammo_casing)) @@ -168,6 +179,7 @@ sleep(1 SECOND) update_icon() + user.hud_used.update_ammo_hud(user, src) //attempts to unload src. If allow_dump is set to 0, the speedloader unloading method will be disabled /obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user, var/allow_dump=1) @@ -177,6 +189,7 @@ playsound(src, 'sound/weapons/empty.ogg', 50, 1) ammo_magazine.update_icon() ammo_magazine = null + user.hud_used.update_ammo_hud(user, src) else if(loaded.len) //presumably, if it can be speed-loaded, it can be speed-unloaded. if(allow_dump && (load_method & SPEEDLOADER)) @@ -195,9 +208,11 @@ user.put_in_hands(C) user.visible_message("[user] removes \a [C] from [src].", "You remove \a [C] from [src].") playsound(src, 'sound/weapons/empty.ogg', 50, 1) + user.hud_used.update_ammo_hud(user, src) else to_chat(user, "[src] is empty.") update_icon() + user.hud_used.update_ammo_hud(user, src) /obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob) ..() @@ -228,6 +243,7 @@ ammo_magazine.update_icon() ammo_magazine = null update_icon() //make sure to do this after unsetting ammo_magazine + user.hud_used.update_ammo_hud(user, src) /obj/item/weapon/gun/projectile/examine(mob/user) . = ..() @@ -256,3 +272,72 @@ unload_ammo(usr) */ + +// TGMC Ammo HUD Insertion +/obj/item/weapon/gun/projectile/has_ammo_counter() + return TRUE + +/obj/item/weapon/gun/projectile/get_ammo_type() + if(load_method & MAGAZINE) + if(chambered) // Do we have an ammo casing chambered + var/obj/item/ammo_casing/A = chambered + var/obj/item/projectile/P = A.projectile_type + return list(initial(P.hud_state), initial(P.hud_state_empty)) + else if(ammo_magazine && ammo_magazine.stored_ammo.len) // Do we have a mag, and have ammo in the mag, but nothing chambered? + var/obj/item/ammo_casing/A = ammo_magazine.stored_ammo[1] + var/obj/item/projectile/P = A.projectile_type + return list(initial(P.hud_state), initial(P.hud_state_empty)) + else if(src.projectile_type) // Else, we're entirely empty, and irregardless of the mag we have loaded (as it's empty, or it would've passed the length check above), return the DEFAULT projectile_type on the gun, if set. + var/obj/item/projectile/P = src.projectile_type + return list(initial(P.hud_state), initial(P.hud_state_empty)) + else + return list("unknown", "unknown") // Safety, this shouldn't happen, but just in case + else if(load_method & (SINGLE_CASING|SPEEDLOADER)) // Do we load with single casings OR speedloaders? + if(chambered) // Do we have an ammo casing loaded in the chamber? All casings still have a projectile_type var. + var/obj/item/ammo_casing/A = chambered + var/obj/item/projectile/P = A.projectile_type + return list(initial(P.hud_state), initial(P.hud_state_empty)) // Return the casing's projectile_type ammo hud state + else if(loaded.len) // Else, is the gun loaded, but no ammo casings in chamber currently? + var/obj/item/ammo_casing/A = loaded[1] + var/obj/item/projectile/P = A.projectile_type + return list(initial(P.hud_state), initial(P.hud_state_empty)) // Return the ammunition loaded in the gun's hud_state + else if(src.projectile_type) // Else, we're entirely empty, and have nothing loaded in the gun, and nothing in the chamber. Return the DEFAULT projectile_type on the gun, if set. + var/obj/item/projectile/P = src.projectile_type + return list(initial(P.hud_state), initial(P.hud_state_empty)) + else + return list("unknown", "unknown") // Safety, this shouldn't happen, but just in case + else if(src.projectile_type) // Failsafe if we somehow don't pass the above. Return the DEFAULT projectile_type on the gun, if set. + var/obj/item/projectile/P = src.projectile_type + return list(initial(P.hud_state), initial(P.hud_state_empty)) + else // Failsafe if we somehow fail all three methods + return list("unknown", "unknown") + +/obj/item/weapon/gun/projectile/get_ammo_count() + if(ammo_magazine) // Do we have a magazine loaded? + var/shots_left + if(chambered && chambered.BB) // Do we have a bullet in the currently-chambered casing, if any? + shots_left++ + for(var/obj/item/ammo_casing/bullet in ammo_magazine.stored_ammo) + if(bullet.BB) + shots_left++ + + if(shots_left > 0) + return shots_left + else + return 0 // No ammo left or failsafe. + else if(loaded) // Do we use internal ammunition + var/shots_left + if(chambered && chambered.BB) // Do we have a bullet in the currently-chambered casing, if any? + shots_left++ + for(var/obj/item/ammo_casing/bullet in loaded) + if(bullet.BB) // Only increment how many shots we have left if we're loaded. + shots_left++ + + if(shots_left > 0) + return shots_left + else + return 0 // No ammo left or failsafe. + else if(chambered) // If we don't have a magazine or internal ammunition loaded, but we have a casing in chamber, return the amount. + return chambered.BB ? 1 : 0 + else // Failsafe, or completely unloaded + return 0 diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 4f6cb0b018..161f3ea29e 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -1,3 +1,7 @@ +/* + * Shotgun + */ + /obj/item/weapon/gun/projectile/shotgun/pump name = "shotgun" desc = "The mass-produced MarsTech Meteor 29 shotgun is a favourite of police and security forces on many worlds. Uses 12g rounds." @@ -39,12 +43,14 @@ else chambered.loc = get_turf(src) // Eject casing chambered = null + M.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD Port // Load next shell if(loaded.len) var/obj/item/ammo_casing/AC = loaded[1] // load next casing. loaded -= AC // Remove casing from loaded list. chambered = AC + M.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD Port if(pump_animation) // This affects all bolt action and shotguns. flick("[pump_animation]", src) // This plays any pumping @@ -125,6 +131,7 @@ burst = 2 user.visible_message("The shotgun goes off!", "The shotgun goes off in your face!") Fire_userless(user) + user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD Port burst = burstsetting return if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index b06e33db76..1686a6e6e1 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -135,6 +135,10 @@ var/impact_effect_type = null var/list/impacted_mobs = list() + + // TGMC Ammo HUD Port + var/hud_state = "unknown" // What HUD state we use when we have ammunition. + var/hud_state_empty = "unknown" // The empty state. DON'T USE _FLASH IN THE NAME OF THE EMPTY STATE STRING, THAT IS ADDED BY THE CODE. /obj/item/projectile/proc/Range() range-- diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 559fb2a12b..829d660c81 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -23,6 +23,9 @@ tracer_type = /obj/effect/projectile/tracer/laser impact_type = /obj/effect/projectile/impact/laser + hud_state = "laser" + hud_state_empty = "battery_empty" + /obj/item/projectile/beam/practice name = "laser" icon_state = "laser" @@ -31,23 +34,28 @@ damage_type = BURN check_armour = "laser" eyeblur = 2 + hud_state = "laser" /obj/item/projectile/beam/weaklaser name = "weak laser" icon_state = "laser" damage = 15 + hud_state = "laser" /obj/item/projectile/beam/smalllaser damage = 25 + hud_state = "laser" /obj/item/projectile/beam/burstlaser damage = 30 armor_penetration = 10 + hud_state = "laser" /obj/item/projectile/beam/midlaser damage = 40 armor_penetration = 10 + hud_state = "laser" /obj/item/projectile/beam/mininglaser name = "pulsating laser" @@ -74,6 +82,7 @@ muzzle_type = /obj/effect/projectile/muzzle/laser_heavy tracer_type = /obj/effect/projectile/tracer/laser_heavy impact_type = /obj/effect/projectile/impact/laser_heavy + hud_state = "laser_overcharge" /obj/item/projectile/beam/heavylaser/fakeemitter name = "emitter beam" @@ -81,6 +90,7 @@ fire_sound = 'sound/weapons/emitter.ogg' light_color = "#00CC33" excavation_amount = 140 // 2 shots to dig a standard rock turf. Superior due to being a mounted tool beam, to make it actually viable. + hud_state = "laser_overcharge" muzzle_type = /obj/effect/projectile/muzzle/emitter tracer_type = /obj/effect/projectile/tracer/emitter @@ -90,6 +100,7 @@ damage = 80 armor_penetration = 50 light_color = "#FF0D00" + hud_state = "laser_overcharge" /obj/item/projectile/beam/xray name = "xray beam" @@ -98,6 +109,7 @@ damage = 25 armor_penetration = 50 light_color = "#00CC33" + hud_state = "laser_sniper" muzzle_type = /obj/effect/projectile/muzzle/xray tracer_type = /obj/effect/projectile/tracer/xray @@ -111,6 +123,7 @@ armor_penetration = 90 irradiate = 20 light_color = "#00CC33" + hud_state = "laser_sniper" muzzle_type = /obj/effect/projectile/muzzle/xray tracer_type = /obj/effect/projectile/tracer/xray @@ -122,6 +135,7 @@ fire_sound = 'sound/weapons/eluger.ogg' damage = 40 light_color = "#00C6FF" + hud_state = "laser_disabler" muzzle_type = /obj/effect/projectile/muzzle/laser_omni tracer_type = /obj/effect/projectile/tracer/laser_omni @@ -134,6 +148,7 @@ damage = 100 //Badmin toy, don't care armor_penetration = 100 light_color = "#0066FF" + hud_state = "pulse" muzzle_type = /obj/effect/projectile/muzzle/laser_pulse tracer_type = /obj/effect/projectile/tracer/laser_pulse @@ -151,6 +166,7 @@ damage = 0 // The actual damage is computed in /code/modules/power/singularity/emitter.dm light_color = "#00CC33" excavation_amount = 70 // 3 shots to mine a turf + hud_state = "laser_overcharge" muzzle_type = /obj/effect/projectile/muzzle/emitter tracer_type = /obj/effect/projectile/tracer/emitter @@ -164,13 +180,14 @@ no_attack_log = 1 damage_type = BURN check_armour = "laser" + hud_state = "monkey" combustion = FALSE /obj/item/projectile/beam/lasertag/blue icon_state = "bluelaser" light_color = "#0066FF" - + hud_state = "monkey" muzzle_type = /obj/effect/projectile/muzzle/laser_blue tracer_type = /obj/effect/projectile/tracer/laser_blue impact_type = /obj/effect/projectile/impact/laser_blue @@ -185,6 +202,7 @@ /obj/item/projectile/beam/lasertag/red icon_state = "laser" light_color = "#FF0D00" + hud_state = "monkey" /obj/item/projectile/beam/lasertag/red/on_hit(var/atom/target, var/blocked = 0) if(ishuman(target)) @@ -196,6 +214,7 @@ /obj/item/projectile/beam/lasertag/omni//A laser tag bolt that stuns EVERYONE icon_state = "omnilaser" light_color = "#00C6FF" + hud_state = "monkey" muzzle_type = /obj/effect/projectile/muzzle/laser_omni tracer_type = /obj/effect/projectile/tracer/laser_omni @@ -215,6 +234,7 @@ damage = 50 armor_penetration = 10 light_color = "#00CC33" + hud_state = "laser_sniper" muzzle_type = /obj/effect/projectile/muzzle/xray tracer_type = /obj/effect/projectile/tracer/xray @@ -231,12 +251,15 @@ light_color = "#FFFFFF" hitsound = 'sound/weapons/zapbang.ogg' + combustion = FALSE muzzle_type = /obj/effect/projectile/muzzle/stun tracer_type = /obj/effect/projectile/tracer/stun impact_type = /obj/effect/projectile/impact/stun + hud_state = "taser" // TGMC Ammo HUD port + /obj/item/projectile/beam/stun/weak name = "weak stun beam" icon_state = "stun" @@ -277,6 +300,7 @@ agony = 15 eyeblur = 2 hitsound = 'sound/weapons/zapbang.ogg' + hud_state = "taser" /obj/item/projectile/beam/shock/weak damage = 5 @@ -294,7 +318,7 @@ damage_type = ELECTROCUTE //You should be safe inside a voidsuit sharp = FALSE //"Wide" spectrum beam light_color = COLOR_GOLD - + hud_state = "monkey" excavation_amount = 200 // Good at shooting rocks muzzle_type = /obj/effect/projectile/muzzle/pointdefense diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 812bc8b829..113f7d7387 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -12,6 +12,8 @@ impact_effect_type = /obj/effect/temp_visual/impact_effect excavation_amount = 20 var/mob_passthrough_check = 0 + hud_state = "pistol_lightap" + hud_state_empty = "pistol_empty" // Just in case we somehow have no hud_state_empty defined muzzle_type = /obj/effect/projectile/muzzle/bullet @@ -96,30 +98,38 @@ /obj/item/projectile/bullet/pistol // 9mm pistols and most SMGs. Sacrifice power for capacity. fire_sound = 'sound/weapons/gunshot2.ogg' damage = 20 + hud_state = "pistol" + hud_state_empty = "pistol_empty" /obj/item/projectile/bullet/pistol/ap damage = 15 armor_penetration = 30 + hud_state = "pistol_light_ap" /obj/item/projectile/bullet/pistol/hp damage = 25 armor_penetration = -50 + hud_state = "pistol_ap" /obj/item/projectile/bullet/pistol/medium // .45 (and maybe .40 if it ever gets added) caliber security pistols. Balance between capacity and power. fire_sound = 'sound/weapons/gunshot3.ogg' // Snappier sound. damage = 25 + hud_state = "pistol" /obj/item/projectile/bullet/pistol/medium/ap damage = 20 armor_penetration = 15 + hud_state = "pistol_light_ap" /obj/item/projectile/bullet/pistol/medium/hp damage = 30 armor_penetration = -50 + hud_state = "pistol_ap" /obj/item/projectile/bullet/pistol/strong // .357 and .44 caliber stuff. High power pistols like the Mateba or Desert Eagle. Sacrifice capacity for power. fire_sound = 'sound/weapons/gunshot4.ogg' damage = 60 + hud_state = "pistol_heavy" /obj/item/projectile/bullet/pistol/rubber/strong // "Rubber" bullets for high power pistols. fire_sound = 'sound/weapons/gunshot3.ogg' // Rubber shots have less powder, but these still have more punch than normal rubber shot. @@ -128,6 +138,7 @@ embed_chance = 0 sharp = 0 check_armour = "melee" + hud_state = "pistol_special" /obj/item/projectile/bullet/pistol/rubber // "Rubber" bullets for all other pistols. name = "rubber bullet" @@ -136,6 +147,7 @@ embed_chance = 0 sharp = 0 check_armour = "melee" + hud_state = "pistol_special" fire_sound ='sound/weapons/Gunshot_pathetic.ogg' // Rubber shots have less powder in the casing. /* shotgun projectiles */ @@ -145,6 +157,8 @@ fire_sound = 'sound/weapons/Gunshot_shotgun.ogg' damage = 50 armor_penetration = 20 + hud_state = "shotgun_slug" + hud_state_empty = "shotgun_empty" /obj/item/projectile/bullet/shotgun/beanbag //because beanbags are not bullets name = "beanbag" @@ -153,6 +167,7 @@ embed_chance = 0 sharp = 0 check_armour = "melee" + hud_state = "shotgun_beanbag" //Should do about 80 damage at 1 tile distance (adjacent), and 50 damage at 3 tiles distance. //Overall less damage than slugs in exchange for more damage at very close range and more embedding @@ -163,12 +178,14 @@ pellets = 6 range_step = 1 spread_step = 10 + hud_state = "shotgun_buckshot" /obj/item/projectile/bullet/pellet/shotgun/flak damage = 2 //The main weapon using these fires four at a time, usually with different destinations. Usually. range_step = 2 spread_step = 30 armor_penetration = 10 + hud_state = "shotgun_flechette" //EMP shotgun 'slug', it's basically a beanbag that pops a tiny emp when it hits. //Not currently used /obj/item/projectile/bullet/shotgun/ion @@ -178,6 +195,7 @@ embed_chance = 0 sharp = 0 check_armour = "melee" + hud_state = "shotgun_ion" combustion = FALSE @@ -193,46 +211,57 @@ fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg' armor_penetration = 15 penetrating = 1 + hud_state = "rifle" + hud_state_empty = "rifle_empty" /obj/item/projectile/bullet/rifle/a762 fire_sound = 'sound/weapons/Gunshot_heavy.ogg' damage = 35 + hud_state = "rifle_heavy" /obj/item/projectile/bullet/rifle/a762/sniper // Hitscan specifically for sniper ammo; to be implimented at a later date, probably for the SVD. -Ace fire_sound = 'sound/weapons/Gunshot_sniper.ogg' hitscan = 1 //so the ammo isn't useless as a sniper weapon + hud_state = "hivelo" /obj/item/projectile/bullet/rifle/a762/ap damage = 30 armor_penetration = 50 // At 30 or more armor, this will do more damage than standard rounds. + hud_state = "rifle_ap" /obj/item/projectile/bullet/rifle/a762/hp damage = 40 armor_penetration = -50 penetrating = 0 + hud_state = "hivelo_iff" /obj/item/projectile/bullet/rifle/a762/hunter // Optimized for killing simple animals and not people, because Balance(tm) damage = 20 SA_bonus_damage = 50 // 70 total on animals. SA_vulnerability = SA_ANIMAL + hud_state = "rifle_heavy" /obj/item/projectile/bullet/rifle/a545 fire_sound = 'sound/weapons/Gunshot_light.ogg' damage = 25 + hud_state = "rifle" /obj/item/projectile/bullet/rifle/a545/ap damage = 20 armor_penetration = 50 // At 40 or more armor, this will do more damage than standard rounds. + hud_state = "rifle_ap" /obj/item/projectile/bullet/rifle/a545/hp damage = 35 armor_penetration = -50 penetrating = 0 + hud_state = "hivelo_iff" /obj/item/projectile/bullet/rifle/a545/hunter damage = 15 SA_bonus_damage = 35 // 50 total on animals. SA_vulnerability = SA_ANIMAL + hud_state = "rifle_heavy" /obj/item/projectile/bullet/rifle/a145 // 14.5�114mm is bigger than a .50 BMG round. fire_sound = 'sound/weapons/Gunshot_cannon.ogg' // This is literally an anti-tank rifle caliber. It better sound like a fucking cannon. @@ -242,6 +271,7 @@ penetrating = 5 armor_penetration = 80 hitscan = 1 //so the PTR isn't useless as a sniper weapon + hud_state = "sniper" icon_state = "bullet_alt" tracer_type = /obj/effect/projectile/tracer/cannon @@ -252,10 +282,12 @@ weaken = 0 penetrating = 15 armor_penetration = 90 + hud_state = "sniper_flak" /obj/item/projectile/bullet/rifle/a44rifle fire_sound = 'sound/weapons/gunshot4.ogg' damage = 50 + hud_state = "revolver" /* Mech rounds */ @@ -274,18 +306,21 @@ name = "co bullet" damage = 20 damage_type = OXY + hud_state = "pistol_tranq" /obj/item/projectile/bullet/cyanideround name = "poison bullet" damage = 40 damage_type = TOX + hud_state = "pistol_tranq" /obj/item/projectile/bullet/burstbullet name = "exploding bullet" fire_sound = 'sound/effects/Explosion1.ogg' damage = 20 embed_chance = 0 - edge = 1 + edge = TRUE + hud_state = "pistol_fire" /obj/item/projectile/bullet/burstbullet/on_hit(var/atom/target, var/blocked = 0) if(isturf(target)) @@ -301,6 +336,7 @@ damage_type = BURN incendiary = 0.5 flammability = 2 + hud_state = "pistol_fire" /obj/item/projectile/bullet/incendiary/flamethrower name = "ball of fire" @@ -313,12 +349,14 @@ agony = 30 range = 4 vacuum_traversal = 0 + hud_state = "flame" /obj/item/projectile/bullet/incendiary/flamethrower/large damage = 5 incendiary = 3 flammability = 2 range = 6 + hud_state = "flame" /obj/item/projectile/bullet/incendiary/flamethrower/tiny damage = 2 @@ -328,11 +366,13 @@ modifier_duration = 20 SECONDS range = 6 agony = 0 + hud_state = "flame" /* Practice rounds and blanks */ /obj/item/projectile/bullet/practice damage = 5 + hud_state = "smg_light" /obj/item/projectile/bullet/pistol/cap // Just the primer, such as a cap gun. name = "cap" @@ -341,7 +381,8 @@ damage = 0 nodamage = 1 embed_chance = 0 - sharp = 0 + sharp = FALSE + hud_state = "monkey" combustion = FALSE @@ -356,7 +397,8 @@ damage = 0 nodamage = 1 embed_chance = 0 - sharp = 0 + sharp = FALSE + hud_state = "smg_light" /obj/item/projectile/bullet/blank/cap/process() loc = null @@ -370,6 +412,7 @@ embed_chance = 0 sharp = FALSE silenced = TRUE + hud_state = "pistol_light" /obj/item/projectile/bullet/pellet/shotgun/bb // Shotgun name = "BB" diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 35e4c61ea4..3be445f264 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -8,6 +8,8 @@ impact_effect_type = /obj/effect/temp_visual/impact_effect hitsound_wall = 'sound/weapons/effects/searwall.ogg' hitsound = 'sound/weapons/zapbang.ogg' + hud_state = "plasma" + hud_state_empty = "battery_empty" var/flash_strength = 10 @@ -22,6 +24,7 @@ var/flash_range = 0 var/brightness = 7 var/light_colour = "#ffffff" + hud_state = "grenade_dummy" /obj/item/projectile/energy/flash/on_impact(var/atom/A) var/turf/T = flash_range? src.loc : get_turf(A) @@ -59,6 +62,7 @@ flash_range = 1 brightness = 15 flash_strength = 20 + hud_state = "grenade_dummy" /obj/item/projectile/energy/flash/flare/on_impact(var/atom/A) light_colour = pick("#e58775", "#ffffff", "#90ff90", "#a09030") @@ -77,15 +81,18 @@ light_range = 2 light_power = 0.5 light_color = "#FFFFFF" + hud_state = "taser" //Damage will be handled on the MOB side, to prevent window shattering. /obj/item/projectile/energy/electrode/strong agony = 55 + hud_state = "taser" /obj/item/projectile/energy/electrode/stunshot name = "stunshot" damage = 5 agony = 80 + hud_state = "taser" /obj/item/projectile/energy/declone name = "declone" @@ -100,6 +107,7 @@ impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser combustion = FALSE + hud_state = "plasma_pistol" /obj/item/projectile/energy/excavate name = "kinetic blast" @@ -113,6 +121,7 @@ vacuum_traversal = 0 combustion = FALSE + hud_state = "plasma_blast" /obj/item/projectile/energy/dart name = "dart" @@ -121,6 +130,7 @@ damage_type = TOX agony = 120 check_armour = "energy" + hud_state = "pistol_tranq" combustion = FALSE @@ -131,10 +141,12 @@ damage_type = TOX agony = 40 stutter = 10 + hud_state = "electrothermal" /obj/item/projectile/energy/bolt/large name = "largebolt" damage = 20 + hud_state = "electrothermal" /obj/item/projectile/energy/acid //Slightly up-gunned (Read: The thing does agony and checks bio resist) variant of the simple alien mob's projectile, for queens and sentinels. name = "acidic spit" @@ -155,6 +167,7 @@ agony = 80 check_armour = "bio" armor_penetration = 25 // It's acid-based + hud_state = "electrothermal" combustion = FALSE @@ -164,6 +177,7 @@ damage = 20 damage_type = BIOACID agony = 20 + hud_state = "electrothermal" check_armour = "bio" armor_penetration = 25 // It's acid-based @@ -193,6 +207,7 @@ light_power = 0.5 light_color = "#33CC00" impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser + hud_state = "plasma_rifle" combustion = FALSE @@ -206,6 +221,7 @@ agony = 55 damage_type = BURN vacuum_traversal = 0 //Projectile disappears in empty space + hud_state = "plasma_rifle_blast" /obj/item/projectile/energy/plasmastun/proc/bang(var/mob/living/carbon/M) @@ -250,6 +266,7 @@ embed_chance = 0 muzzle_type = /obj/effect/projectile/muzzle/pulse impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser + hud_state = "plasma_sphere" /obj/item/projectile/energy/phase name = "phase wave" @@ -258,17 +275,20 @@ range = 6 damage = 5 SA_bonus_damage = 45 // 50 total on animals - SA_vulnerability = SA_ANIMAL + hud_state = "laser_heat" /obj/item/projectile/energy/phase/light range = 4 SA_bonus_damage = 35 // 40 total on animals + hud_state = "laser_heat" /obj/item/projectile/energy/phase/heavy range = 8 SA_bonus_damage = 55 // 60 total on animals + hud_state = "laser_heat" /obj/item/projectile/energy/phase/heavy/cannon range = 10 damage = 15 - SA_bonus_damage = 60 // 75 total on animals \ No newline at end of file + SA_bonus_damage = 60 // 75 total on animals + hud_state = "laser_heat" \ No newline at end of file diff --git a/code/modules/projectiles/projectile/explosive.dm b/code/modules/projectiles/projectile/explosive.dm index 307febc8bc..76da8f3e3a 100644 --- a/code/modules/projectiles/projectile/explosive.dm +++ b/code/modules/projectiles/projectile/explosive.dm @@ -7,6 +7,8 @@ icon_state = "missile" damage = 30 //Meaty whack. *Chuckles* does_spin = 0 + hud_state = "rocket_he" + hud_state_empty = "rocket_empty" /obj/item/projectile/bullet/srmrocket/on_hit(atom/target, blocked=0) if(!isliving(target)) //if the target isn't alive, so is a wall or something @@ -24,6 +26,7 @@ /obj/item/projectile/bullet/srmrocket/weak //Used in the jury rigged one. damage = 10 + hud_state = "rocket_he" /obj/item/projectile/bullet/srmrocket/weak/on_hit(atom/target, blocked=0) explosion(target, 0, 0, 2, 4)//No need to have a question. diff --git a/code/modules/projectiles/projectile/magnetic.dm b/code/modules/projectiles/projectile/magnetic.dm index 12452d4618..3ccc8618da 100644 --- a/code/modules/projectiles/projectile/magnetic.dm +++ b/code/modules/projectiles/projectile/magnetic.dm @@ -8,12 +8,14 @@ weaken = 1 penetrating = 5 armor_penetration = 70 + hud_state = "alloy_spike" /obj/item/projectile/bullet/magnetic/slug name = "slug" icon_state = "gauss_silenced" damage = 75 armor_penetration = 90 + hud_state = "alloy_spike" /obj/item/projectile/bullet/magnetic/flechette name = "flechette" @@ -21,6 +23,7 @@ fire_sound = 'sound/weapons/rapidslice.ogg' damage = 20 armor_penetration = 100 + hud_state = "alloy_spike" /obj/item/projectile/bullet/magnetic/flechette/small name = "small flechette" @@ -28,12 +31,14 @@ fire_sound = 'sound/weapons/rapidslice.ogg' damage = 12 armor_penetration = 100 + hud_state = "alloy_spike" /obj/item/projectile/bullet/magnetic/flechette/hunting name = "shredder slug" armor_penetration = 30 SA_bonus_damage = 40 SA_vulnerability = SA_ANIMAL + hud_state = "alloy_spike" /obj/item/projectile/bullet/magnetic/heated name = "slug" @@ -45,6 +50,7 @@ embed_chance = 0 armor_penetration = 40 penetrating = 1 + hud_state = "alloy_spike" /obj/item/projectile/bullet/magnetic/heated/weak icon_state = "gauss_silenced" @@ -53,6 +59,7 @@ embed_chance = 0 armor_penetration = 30 penetrating = 0 + hud_state = "alloy_spike" /obj/item/projectile/bullet/magnetic/fuelrod name = "fuel rod" @@ -67,6 +74,7 @@ embed_chance = 0 armor_penetration = 40 range = 20 + hud_state = "rocket_he" var/searing = 0 //Does this fuelrod ignore shields? var/detonate_travel = 0 //Will this fuelrod explode when it reaches maximum distance? @@ -113,6 +121,7 @@ flammability = -1 armor_penetration = 50 penetrating = 3 + hud_state = "rocket_ap" /obj/item/projectile/bullet/magnetic/fuelrod/phoron name = "blazing fuel rod" @@ -124,6 +133,7 @@ penetrating = 5 irradiate = 20 detonate_mob = 1 + hud_state = "rocket_fire" /obj/item/projectile/bullet/magnetic/fuelrod/supermatter name = "painfully incandescent fuel rod" @@ -140,6 +150,7 @@ detonate_travel = 1 detonate_mob = 1 energetic_impact = 1 + hud_state = "rocket_thermobaric" /obj/item/projectile/bullet/magnetic/fuelrod/supermatter/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) //You cannot touch the supermatter without disentigrating. Assumedly, this is true for condensed rods of it flying at relativistic speeds. if(istype(target,/turf/simulated/wall) || istype(target,/mob/living)) @@ -160,6 +171,7 @@ check_armour = "melee" irradiate = 20 range = 6 + hud_state = "plasma_rifle_blast" /obj/item/projectile/bullet/magnetic/bore/Initialize(loc, range_mod) // i'm gonna be real honest i dunno how this works but it does . = ..() diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 9c06241ecf..fff673befc 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -9,6 +9,8 @@ light_range = 2 light_power = 0.5 light_color = "#55AAFF" + hud_state = "plasma_blast" + hud_state_empty = "battery_empty" combustion = FALSE impact_effect_type = /obj/effect/temp_visual/impact_effect/ion @@ -41,8 +43,9 @@ icon_state= "bolter" damage = 50 check_armour = "bullet" - sharp = 1 - edge = 1 + sharp = TRUE + edge = TRUE + hud_state = "rocket_fire" /obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0) explosion(target, -1, 0, 2) @@ -62,6 +65,7 @@ light_power = 0.5 light_color = "#55AAFF" impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser + hud_state = "water" combustion = FALSE @@ -93,6 +97,7 @@ /obj/item/projectile/temp/hot name = "heat beam" target_temperature = 1000 + hud_state = "flame" combustion = TRUE @@ -104,6 +109,7 @@ damage_type = BRUTE nodamage = 1 check_armour = "bullet" + hud_state = "monkey" /obj/item/projectile/meteor/Bump(atom/A as mob|obj|turf|area) if(A == firer) @@ -140,6 +146,7 @@ impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser combustion = FALSE + hud_state = "electrothermal" /obj/item/projectile/energy/floramut/on_hit(var/atom/target, var/blocked = 0) var/mob/living/M = target @@ -182,6 +189,7 @@ nodamage = 1 check_armour = "energy" var/decl/plantgene/gene = null + hud_state = "electrothermal" /obj/item/projectile/energy/florayield name = "beta somatoray" @@ -195,6 +203,7 @@ light_power = 0.5 light_color = "#FFFFFF" impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser + hud_state = "electrothermal" /obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0) var/mob/living/M = target @@ -212,6 +221,7 @@ name = "flayer ray" combustion = FALSE + hud_state = "electrothermal" /obj/item/projectile/beam/mindflayer/on_hit(var/atom/target, var/blocked = 0) if(ishuman(target)) @@ -227,6 +237,7 @@ nodamage = 1 damage_type = HALLOSS muzzle_type = /obj/effect/projectile/muzzle/bullet + hud_state = "monkey" /obj/item/projectile/bola name = "bola" @@ -235,6 +246,7 @@ embed_chance = 0 //Nada. damage_type = HALLOSS muzzle_type = null + hud_state = "monkey" combustion = FALSE @@ -254,7 +266,7 @@ embed_chance = 0 //Nada. damage_type = BRUTE muzzle_type = null - + hud_state = "monkey" combustion = FALSE /obj/item/projectile/webball/on_hit(var/atom/target, var/blocked = 0) @@ -276,6 +288,7 @@ light_range = 4 light_power = 3 light_color = "#3300ff" + hud_state = "alloy_spike" muzzle_type = /obj/effect/projectile/muzzle/tungsten tracer_type = /obj/effect/projectile/tracer/tungsten diff --git a/code/modules/reagents/reagents/food_drinks.dm b/code/modules/reagents/reagents/food_drinks.dm index c445659d37..a0a06d2aa1 100644 --- a/code/modules/reagents/reagents/food_drinks.dm +++ b/code/modules/reagents/reagents/food_drinks.dm @@ -401,6 +401,15 @@ nutriment_factor = 5 color = "#302000" +/datum/reagent/nutriment/chocolate + name = "Chocolate" + id = "chocolate" + description = "Great for cooking or on its own!" + taste_description = "chocolate" + color = "#582815" + nutriment_factor = 5 + taste_mult = 1.3 + /datum/reagent/nutriment/instantjuice name = "Juice Powder" id = "instantjuice" diff --git a/code/modules/shieldgen/directional_shield.dm b/code/modules/shieldgen/directional_shield.dm index 469adeb887..c383ebd2f3 100644 --- a/code/modules/shieldgen/directional_shield.dm +++ b/code/modules/shieldgen/directional_shield.dm @@ -158,12 +158,12 @@ // This is done at the projector instead of the shields themselves to avoid needing to calculate this more than once every update. var/interpolate_weight = shield_health / max_shield_health - var/list/low_color_list = hex2rgb(low_color) + var/list/low_color_list = rgb2num(low_color) var/low_r = low_color_list[1] var/low_g = low_color_list[2] var/low_b = low_color_list[3] - var/list/high_color_list = hex2rgb(high_color) + var/list/high_color_list = rgb2num(high_color) var/high_r = high_color_list[1] var/high_g = high_color_list[2] var/high_b = high_color_list[3] diff --git a/code/modules/tgui/modules/communications.dm b/code/modules/tgui/modules/communications.dm index d30f3a8a17..8ae0a48435 100644 --- a/code/modules/tgui/modules/communications.dm +++ b/code/modules/tgui/modules/communications.dm @@ -152,7 +152,7 @@ if(emergency_shuttle.has_eta()) var/timeleft = emergency_shuttle.estimate_arrival_time() data["esc_status"] = emergency_shuttle.online() ? "ETA:" : "RECALLING:" - data["esc_status"] += " [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]" + data["esc_status"] += " [timeleft / 60 % 60]:[pad_left(num2text(timeleft % 60), 2, "0")]" return data /datum/tgui_module/communications/proc/setCurrentMessage(mob/user, value) diff --git a/code/modules/virus2/disease2.dm b/code/modules/virus2/disease2.dm index 08d52b1706..c6932b4df6 100644 --- a/code/modules/virus2/disease2.dm +++ b/code/modules/virus2/disease2.dm @@ -14,7 +14,7 @@ var/resistance = 10 // % chance a disease will resist cure, up to 100 /datum/disease2/disease/New() - uniqueID = rand(0,10000) + uniqueID = rand(1, 9999) ..() /datum/disease2/disease/proc/makerandom(var/severity=1) @@ -25,7 +25,7 @@ holder.getrandomeffect(severity, excludetypes) excludetypes += holder.effect.type effects += holder - uniqueID = rand(0,10000) + uniqueID = rand(1, 9999) switch(severity) if(1) infectionchance = 1 @@ -135,13 +135,13 @@ BITSET(mob.hud_updateflag, STATUS_HUD) /datum/disease2/disease/proc/minormutate() - //uniqueID = rand(0,10000) + //uniqueID = rand(1, 9999) var/datum/disease2/effectholder/holder = pick(effects) holder.minormutate() //infectionchance = min(50,infectionchance + rand(0,10)) /datum/disease2/disease/proc/majormutate() - uniqueID = rand(0,10000) + uniqueID = rand(1, 9999) var/datum/disease2/effectholder/holder = pick(effects) var/list/exclude = list() for(var/datum/disease2/effectholder/D in effects) @@ -208,7 +208,7 @@ var/global/list/virusDB = list() /datum/disease2/disease/proc/name() - .= "stamm #[add_zero("[uniqueID]", 4)]" + .= "stamm #[pad_left(uniqueID, 8, "0")]" if ("[uniqueID]" in virusDB) var/datum/data/record/V = virusDB["[uniqueID]"] .= V.fields["name"] diff --git a/code/modules/xenobio2/controller.dm b/code/modules/xenobio2/controller.dm index 584d820cb2..22f5e70b3e 100644 --- a/code/modules/xenobio2/controller.dm +++ b/code/modules/xenobio2/controller.dm @@ -34,11 +34,10 @@ var/global/datum/controller/xenobio/xenobio_controller // Set in New(). var/list/xenobio_traits = ALL_XENO_GENES while(xenobio_traits && xenobio_traits.len) var/gene_tag = pick(xenobio_traits) - var/gene_mask = "[uppertext(num2hex(rand(0,255), 2))]" - - while(gene_mask in used_masks) - gene_mask = "[uppertext(num2hex(rand(0,255), 2))]" - + var/gene_mask + do + gene_mask = random_hex_text(2, TRUE) + while (gene_mask in used_masks) used_masks += gene_mask xenobio_traits -= gene_tag gene_tag_masks[gene_tag] = gene_mask \ No newline at end of file diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index f1b934a287..46a696e64f 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi index 32008f190b..d1e4839233 100644 Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.dmi differ diff --git a/icons/mob/items/lefthand_storage.dmi b/icons/mob/items/lefthand_storage.dmi index 6b5a4defb8..cdbd3cc252 100644 Binary files a/icons/mob/items/lefthand_storage.dmi and b/icons/mob/items/lefthand_storage.dmi differ diff --git a/icons/mob/items/righthand_storage.dmi b/icons/mob/items/righthand_storage.dmi index 783540cefc..e2f54f84e9 100644 Binary files a/icons/mob/items/righthand_storage.dmi and b/icons/mob/items/righthand_storage.dmi differ diff --git a/icons/mob/screen_ammo.dmi b/icons/mob/screen_ammo.dmi new file mode 100644 index 0000000000..57ab8e772e Binary files /dev/null and b/icons/mob/screen_ammo.dmi differ diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi index db8f1bda59..f701e0ebcd 100644 Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index e45c3d2f40..32b465fb34 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/clothing/backpack.dmi b/icons/obj/clothing/backpack.dmi index 7132925559..f5a13f5461 100644 Binary files a/icons/obj/clothing/backpack.dmi and b/icons/obj/clothing/backpack.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index d7daacb379..5902e2920d 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/ties.dmi b/icons/obj/clothing/ties.dmi index eb60fbfdf9..7aae8c7560 100644 Binary files a/icons/obj/clothing/ties.dmi and b/icons/obj/clothing/ties.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index a86db9a720..ad7bac8531 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/furniture.dmi b/icons/obj/furniture.dmi index 7e0badd1e8..f75fef6207 100644 Binary files a/icons/obj/furniture.dmi and b/icons/obj/furniture.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index c3f730e586..bc8cba2747 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/papershredder.dmi b/icons/obj/papershredder.dmi index 36764945df..5670b38553 100644 Binary files a/icons/obj/papershredder.dmi and b/icons/obj/papershredder.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 7f13fc75f1..55eee87e4b 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/polaris.dme b/polaris.dme index 00dcb611a9..9f31d34e0d 100644 --- a/polaris.dme +++ b/polaris.dme @@ -26,6 +26,7 @@ #include "code\__defines\_protect.dm" #include "code\__defines\_tick.dm" #include "code\__defines\admin.dm" +#include "code\__defines\ai.dm" #include "code\__defines\appearance.dm" #include "code\__defines\atmos.dm" #include "code\__defines\callbacks.dm"