diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 1ef76788eb..0562f3c77f 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -2282,7 +2282,6 @@ }, /obj/docking_port/mobile/emergency{ name = "Box emergency shuttle"; - timid = 0 }, /obj/docking_port/stationary{ dir = 4; diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 14282b7ebf..2badff3bb5 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -16885,7 +16885,6 @@ dwidth = 5; height = 11; name = "Omega emergency shuttle"; - timid = 0; width = 19 }, /obj/docking_port/stationary{ diff --git a/_maps/shuttles/emergency_box.dmm b/_maps/shuttles/emergency_box.dmm index 1645d971c2..5d09eb9614 100644 --- a/_maps/shuttles/emergency_box.dmm +++ b/_maps/shuttles/emergency_box.dmm @@ -224,7 +224,7 @@ }, /obj/docking_port/mobile/emergency{ name = "Box emergency shuttle"; - timid = 0 + timid = 1 }, /turf/open/floor/plating, /area/shuttle/escape) diff --git a/_maps/shuttles/whiteship_box.dmm b/_maps/shuttles/whiteship_box.dmm index 338212e727..49d9d76a77 100644 --- a/_maps/shuttles/whiteship_box.dmm +++ b/_maps/shuttles/whiteship_box.dmm @@ -21,7 +21,7 @@ port_direction = 8; preferred_direction = 4; roundstart_move = "whiteship_away"; - timid = null; + timid = 1; width = 35 }, /turf/open/floor/mineral/titanium, diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index a79850b04f..c6ca2cf0ec 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -174,3 +174,5 @@ #define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland #define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300" + +#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) \ No newline at end of file diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 4376ba9c03..1de917d5e1 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -140,6 +140,8 @@ #define isstructure(A) (istype(A, /obj/structure)) +#define ismachinery(A) (istype(A, /obj/machinery)) + #define ismecha(A) (istype(A, /obj/mecha)) #define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index c5d917ece4..bdb9ad35a9 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -288,6 +288,12 @@ GLOBAL_LIST_INIT(ghost_accs_options, list(GHOST_ACCS_NONE, GHOST_ACCS_DIR, GHOST GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DEFAULT_SPRITE, GHOST_OTHERS_THEIR_SETTING)) //Same as ghost_accs_options. +//pda fonts +#define MONO "Monospaced" +#define VT "VT323" +#define ORBITRON "Orbitron" +#define SHARE "Share Tech Mono" + //Color Defines #define OOC_COLOR "#002eb8" diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 46d6c2ce5c..75985f9c2e 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -1,544 +1,547 @@ -/* - * Holds procs designed to change one type of value, into another. - * Contains: - * hex2num & num2hex - * file2list - * angle2dir - * angle2text - * worldtime2text - * text2dir_extended & dir2text_short - */ - -//Returns an integer given a hex input, supports negative values "-ff" -//skips preceding invalid characters -//breaks when hittin invalid characters thereafter -/proc/hex2num(hex) - . = 0 - if(istext(hex)) - var/negative = 0 - var/len = length(hex) - for(var/i=1, i<=len, i++) - var/num = text2ascii(hex,i) - switch(num) - if(48 to 57) - num -= 48 //0-9 - if(97 to 102) - num -= 87 //a-f - if(65 to 70) - num -= 55 //A-F - if(45) - negative = 1//- - else - if(num) - break - else - continue - . *= 16 - . += num - if(negative) - . *= -1 - return . - -//Returns the hex value of a decimal number -//len == length of returned string -//if len < 0 then the returned string will be as long as it needs to be to contain the data -//Only supports positive numbers -//if an invalid number is provided, it assumes num==0 -//Note, unlike previous versions, this one works from low to high <-- that way -/proc/num2hex(num, len=2) - if(!isnum(num)) - num = 0 - num = round(abs(num)) - . = "" - var/i=0 - while(1) - if(len<=0) - if(!num) - break - else - if(i>=len) - break - var/remainder = num/16 - num = round(remainder) - remainder = (remainder - num) * 16 - switch(remainder) - if(9,8,7,6,5,4,3,2,1) - . = "[remainder]" + . - if(10,11,12,13,14,15) - . = ascii2text(remainder+87) + . - else - . = "0" + . - i++ - return . - -//Splits the text of a file at seperator and returns them in a list. +/* + * Holds procs designed to change one type of value, into another. + * Contains: + * hex2num & num2hex + * file2list + * angle2dir + * angle2text + * worldtime2text + * text2dir_extended & dir2text_short + */ + +//Returns an integer given a hex input, supports negative values "-ff" +//skips preceding invalid characters +//breaks when hittin invalid characters thereafter +/proc/hex2num(hex) + . = 0 + if(istext(hex)) + var/negative = 0 + var/len = length(hex) + for(var/i=1, i<=len, i++) + var/num = text2ascii(hex,i) + switch(num) + if(48 to 57) + num -= 48 //0-9 + if(97 to 102) + num -= 87 //a-f + if(65 to 70) + num -= 55 //A-F + if(45) + negative = 1//- + else + if(num) + break + else + continue + . *= 16 + . += num + if(negative) + . *= -1 + return . + +//Returns the hex value of a decimal number +//len == length of returned string +//if len < 0 then the returned string will be as long as it needs to be to contain the data +//Only supports positive numbers +//if an invalid number is provided, it assumes num==0 +//Note, unlike previous versions, this one works from low to high <-- that way +/proc/num2hex(num, len=2) + if(!isnum(num)) + num = 0 + num = round(abs(num)) + . = "" + var/i=0 + while(1) + if(len<=0) + if(!num) + break + else + if(i>=len) + break + var/remainder = num/16 + num = round(remainder) + remainder = (remainder - num) * 16 + switch(remainder) + if(9,8,7,6,5,4,3,2,1) + . = "[remainder]" + . + if(10,11,12,13,14,15) + . = ascii2text(remainder+87) + . + else + . = "0" + . + i++ + return . + +//Splits the text of a file at seperator and returns them in a list. /world/proc/file2list(filename, seperator="\n", trim = TRUE) if (trim) return splittext(trim(file2text(filename)),seperator) - return splittext(file2text(filename),seperator) - -//Turns a direction into text -/proc/dir2text(direction) - switch(direction) - if(1) - return "north" - if(2) - return "south" - if(4) - return "east" - if(8) - return "west" - if(5) - return "northeast" - if(6) - return "southeast" - if(9) - return "northwest" - if(10) - return "southwest" - else - return - -//Turns text into proper directions -/proc/text2dir(direction) - switch(uppertext(direction)) - if("NORTH") - return 1 - if("SOUTH") - return 2 - if("EAST") - return 4 - if("WEST") - return 8 - if("NORTHEAST") - return 5 - if("NORTHWEST") - return 9 - if("SOUTHEAST") - return 6 - if("SOUTHWEST") - return 10 - else - return - -//Converts an angle (degrees) into an ss13 direction -/proc/angle2dir(degree) - - degree = SimplifyDegrees(degree) - - if(degree < 45) - return NORTH - if(degree < 90) - return NORTHEAST - if(degree < 135) - return EAST - if(degree < 180) - return SOUTHEAST - if(degree < 225) - return SOUTH - if(degree < 270) - return SOUTHWEST - if(degree < 315) - return WEST - return NORTH|WEST - -//returns the north-zero clockwise angle in degrees, given a direction - -/proc/dir2angle(D) - switch(D) - if(NORTH) - return 0 - if(SOUTH) - return 180 - if(EAST) - return 90 - if(WEST) - return 270 - if(NORTHEAST) - return 45 - if(SOUTHEAST) - return 135 - if(NORTHWEST) - return 315 - if(SOUTHWEST) - return 225 - else - return null - -//Returns the angle in english -/proc/angle2text(degree) - return dir2text(angle2dir(degree)) - -//Converts a blend_mode constant to one acceptable to icon.Blend() -/proc/blendMode2iconMode(blend_mode) - switch(blend_mode) - if(BLEND_MULTIPLY) - return ICON_MULTIPLY - if(BLEND_ADD) - return ICON_ADD - if(BLEND_SUBTRACT) - return ICON_SUBTRACT - else - return ICON_OVERLAY - -//Converts a rights bitfield into a string -/proc/rights2text(rights, seperator="", list/adds, list/subs) - if(rights & R_BUILDMODE) - . += "[seperator]+BUILDMODE" - if(rights & R_ADMIN) - . += "[seperator]+ADMIN" - if(rights & R_BAN) - . += "[seperator]+BAN" - if(rights & R_FUN) - . += "[seperator]+FUN" - if(rights & R_SERVER) - . += "[seperator]+SERVER" - if(rights & R_DEBUG) - . += "[seperator]+DEBUG" - if(rights & R_POSSESS) - . += "[seperator]+POSSESS" - if(rights & R_PERMISSIONS) - . += "[seperator]+PERMISSIONS" - if(rights & R_STEALTH) - . += "[seperator]+STEALTH" - if(rights & R_POLL) - . += "[seperator]+POLL" - if(rights & R_VAREDIT) - . += "[seperator]+VAREDIT" - if(rights & R_SOUNDS) - . += "[seperator]+SOUND" - if(rights & R_SPAWN) - . += "[seperator]+SPAWN" - - for(var/verbpath in adds) - . += "[seperator]+[verbpath]" - for(var/verbpath in subs) - . += "[seperator]-[verbpath]" - return . - -/proc/ui_style2icon(ui_style) - switch(ui_style) - if("Retro") - return 'icons/mob/screen_retro.dmi' - if("Plasmafire") - return 'icons/mob/screen_plasmafire.dmi' - if("Slimecore") - return 'icons/mob/screen_slimecore.dmi' - if("Operative") - return 'icons/mob/screen_operative.dmi' - if("Clockwork") - return 'icons/mob/screen_clockwork.dmi' - else - return 'icons/mob/screen_midnight.dmi' - -//colour formats -/proc/rgb2hsl(red, green, blue) - red /= 255;green /= 255;blue /= 255; - var/max = max(red,green,blue) - var/min = min(red,green,blue) - var/range = max-min - - var/hue=0;var/saturation=0;var/lightness=0; - lightness = (max + min)/2 - if(range != 0) - if(lightness < 0.5) - saturation = range/(max+min) - else - saturation = range/(2-max-min) - - var/dred = ((max-red)/(6*max)) + 0.5 - var/dgreen = ((max-green)/(6*max)) + 0.5 - var/dblue = ((max-blue)/(6*max)) + 0.5 - - if(max==red) - hue = dblue - dgreen - else if(max==green) - hue = dred - dblue + (1/3) - else - hue = dgreen - dred + (2/3) - if(hue < 0) - hue++ - else if(hue > 1) - hue-- - - return list(hue, saturation, lightness) - -/proc/hsl2rgb(hue, saturation, lightness) - var/red;var/green;var/blue; - if(saturation == 0) - red = lightness * 255 - green = red - blue = red - else - var/a;var/b; - if(lightness < 0.5) - b = lightness*(1+saturation) - else - b = (lightness+saturation) - (saturation*lightness) - a = 2*lightness - b - - red = round(255 * hue2rgb(a, b, hue+(1/3))) - green = round(255 * hue2rgb(a, b, hue)) - blue = round(255 * hue2rgb(a, b, hue-(1/3))) - - return list(red, green, blue) - -/proc/hue2rgb(a, b, hue) - if(hue < 0) - hue++ - else if(hue > 1) - hue-- - if(6*hue < 1) - return (a+(b-a)*6*hue) - if(2*hue < 1) - return b - if(3*hue < 2) - return (a+(b-a)*((2/3)-hue)*6) - return a - -// Very ugly, BYOND doesn't support unix time and rounding errors make it really hard to convert it to BYOND time. -// returns "YYYY-MM-DD" by default -/proc/unix2date(timestamp, seperator = "-") - - if(timestamp < 0) - return 0 //Do not accept negative values - - var/year = 1970 //Unix Epoc begins 1970-01-01 - var/dayInSeconds = 86400 //60secs*60mins*24hours - var/daysInYear = 365 //Non Leap Year - var/daysInLYear = daysInYear + 1//Leap year - var/days = round(timestamp / dayInSeconds) //Days passed since UNIX Epoc - var/tmpDays = days + 1 //If passed (timestamp < dayInSeconds), it will return 0, so add 1 - var/monthsInDays = list() //Months will be in here ***Taken from the PHP source code*** - var/month = 1 //This will be the returned MONTH NUMBER. - var/day //This will be the returned day number. - - while(tmpDays > daysInYear) //Start adding years to 1970 - year++ - if(isLeap(year)) - tmpDays -= daysInLYear - else - tmpDays -= daysInYear - - if(isLeap(year)) //The year is a leap year - monthsInDays = list(-1,30,59,90,120,151,181,212,243,273,304,334) - else - monthsInDays = list(0,31,59,90,120,151,181,212,243,273,304,334) - - var/mDays = 0; - var/monthIndex = 0; - - for(var/m in monthsInDays) - monthIndex++ - if(tmpDays > m) - mDays = m - month = monthIndex - - day = tmpDays - mDays //Setup the date - - return "[year][seperator][((month < 10) ? "0[month]" : month)][seperator][((day < 10) ? "0[day]" : day)]" - -/proc/isLeap(y) - return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) - - - -//Turns a Body_parts_covered bitfield into a list of organ/limb names. -//(I challenge you to find a use for this) -/proc/body_parts_covered2organ_names(bpc) - var/list/covered_parts = list() - - if(!bpc) - return 0 - - if(bpc & FULL_BODY) - covered_parts |= list("l_arm","r_arm","head","chest","l_leg","r_leg") - - else - if(bpc & HEAD) - covered_parts |= list("head") - if(bpc & CHEST) - covered_parts |= list("chest") - if(bpc & GROIN) - covered_parts |= list("chest") - - if(bpc & ARMS) - covered_parts |= list("l_arm","r_arm") - else - if(bpc & ARM_LEFT) - covered_parts |= list("l_arm") - if(bpc & ARM_RIGHT) - covered_parts |= list("r_arm") - - if(bpc & HANDS) - covered_parts |= list("l_arm","r_arm") - else - if(bpc & HAND_LEFT) - covered_parts |= list("l_arm") - if(bpc & HAND_RIGHT) - covered_parts |= list("r_arm") - - if(bpc & LEGS) - covered_parts |= list("l_leg","r_leg") - else - if(bpc & LEG_LEFT) - covered_parts |= list("l_leg") - if(bpc & LEG_RIGHT) - covered_parts |= list("r_leg") - - if(bpc & FEET) - covered_parts |= list("l_leg","r_leg") - else - if(bpc & FOOT_LEFT) - covered_parts |= list("l_leg") - if(bpc & FOOT_RIGHT) - covered_parts |= list("r_leg") - - return covered_parts - - - -//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ -/proc/heat2colour(temp) - return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp)) - - -/proc/heat2colour_r(temp) - temp /= 100 - if(temp <= 66) - . = 255 - else - . = max(0, min(255, 329.698727446 * (temp - 60) ** -0.1332047592)) - - -/proc/heat2colour_g(temp) - temp /= 100 - if(temp <= 66) - . = max(0, min(255, 99.4708025861 * log(temp) - 161.1195681661)) - else - . = max(0, min(255, 288.1221685293 * ((temp - 60) ** -0.075148492))) - - -/proc/heat2colour_b(temp) - temp /= 100 - if(temp >= 66) - . = 255 - else - if(temp <= 16) - . = 0 - else - . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) - -/proc/color2hex(color) //web colors - if(!color) - return "#000000" - - switch(color) - if("white") - return "#FFFFFF" - if("black") - return "#000000" - if("gray") - return "#808080" - if("brown") - return "#A52A2A" - if("red") - return "#FF0000" - if("darkred") - return "#8B0000" - if("crimson") - return "#DC143C" - if("orange") - return "#FFA500" - if("yellow") - return "#FFFF00" - if("green") - return "#008000" - if("lime") - return "#00FF00" - if("darkgreen") - return "#006400" - if("cyan") - return "#00FFFF" - if("blue") - return "#0000FF" - if("navy") - return "#000080" - if("teal") - return "#008080" - if("purple") - return "#800080" - if("indigo") - return "#4B0082" - else - return "#FFFFFF" - - -//This is a weird one: -//It returns a list of all var names found in the string -//These vars must be in the [var_name] format -//It's only a proc because it's used in more than one place - -//Takes a string and a datum -//The string is well, obviously the string being checked -//The datum is used as a source for var names, to check validity -//Otherwise every single word could technically be a variable! -/proc/string2listofvars(var/t_string, var/datum/var_source) - if(!t_string || !var_source) - return list() - - . = list() - - var/var_found = findtext(t_string,"\[") //Not the actual variables, just a generic "should we even bother" check - if(var_found) - //Find var names - - // "A dog said hi [name]!" - // splittext() --> list("A dog said hi ","name]!" - // jointext() --> "A dog said hi name]!" - // splittext() --> list("A","dog","said","hi","name]!") - - t_string = replacetext(t_string,"\[","\[ ")//Necessary to resolve "word[var_name]" scenarios - var/list/list_value = splittext(t_string,"\[") - var/intermediate_stage = jointext(list_value, null) - - list_value = splittext(intermediate_stage," ") - for(var/value in list_value) - if(findtext(value,"]")) - value = splittext(value,"]") //"name]!" --> list("name","!") - for(var/A in value) - if(var_source.vars.Find(A)) - . += A - -//assumes format #RRGGBB #rrggbb -/proc/color_hex2num(A) - if(!A) - return 0 - var/R = hex2num(copytext(A,2,4)) - var/G = hex2num(copytext(A,4,6)) - var/B = hex2num(copytext(A,6,0)) - return R+G+B - -//word of warning: using a matrix like this as a color value will simplify it back to a string after being set -/proc/color_hex2color_matrix(string) - var/length = length(string) - if(length != 7 && length != 9) - return color_matrix_identity() - var/r = hex2num(copytext(string, 2, 4))/255 - var/g = hex2num(copytext(string, 4, 6))/255 - var/b = hex2num(copytext(string, 6, 8))/255 - var/a = 1 - if(length == 9) - a = hex2num(copytext(string, 8, 10))/255 - if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a)) - return color_matrix_identity() - return list(r,0,0,0, 0,g,0,0, 0,0,b,0, 0,0,0,a, 0,0,0,0) - -//will drop all values not on the diagonal -/proc/color_matrix2color_hex(list/the_matrix) - if(!istype(the_matrix) || the_matrix.len != 20) - return "#ffffffff" - return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) + return splittext(file2text(filename),seperator) + +//Turns a direction into text +/proc/dir2text(direction) + switch(direction) + if(1) + return "north" + if(2) + return "south" + if(4) + return "east" + if(8) + return "west" + if(5) + return "northeast" + if(6) + return "southeast" + if(9) + return "northwest" + if(10) + return "southwest" + else + return + +//Turns text into proper directions +/proc/text2dir(direction) + switch(uppertext(direction)) + if("NORTH") + return 1 + if("SOUTH") + return 2 + if("EAST") + return 4 + if("WEST") + return 8 + if("NORTHEAST") + return 5 + if("NORTHWEST") + return 9 + if("SOUTHEAST") + return 6 + if("SOUTHWEST") + return 10 + else + return + +//Converts an angle (degrees) into an ss13 direction +/proc/angle2dir(degree) + + degree = SimplifyDegrees(degree) + switch(degree) + if(0 to 22.5) //north requires two angle ranges + return NORTH + if(22.5 to 67.5) //each range covers 45 degrees + return NORTHEAST + if(67.5 to 112.5) + return EAST + if(112.5 to 157.5) + return SOUTHEAST + if(157.5 to 202.5) + return SOUTH + if(202.5 to 247.5) + return SOUTHWEST + if(247.5 to 292.5) + return WEST + if(292.5 to 337.5) + return NORTHWEST + if(337.5 to 360) + return NORTH + +//returns the north-zero clockwise angle in degrees, given a direction + +/proc/dir2angle(D) + switch(D) + if(NORTH) + return 0 + if(SOUTH) + return 180 + if(EAST) + return 90 + if(WEST) + return 270 + if(NORTHEAST) + return 45 + if(SOUTHEAST) + return 135 + if(NORTHWEST) + return 315 + if(SOUTHWEST) + return 225 + else + return null + +//Returns the angle in english +/proc/angle2text(degree) + return dir2text(angle2dir(degree)) + +//Converts a blend_mode constant to one acceptable to icon.Blend() +/proc/blendMode2iconMode(blend_mode) + switch(blend_mode) + if(BLEND_MULTIPLY) + return ICON_MULTIPLY + if(BLEND_ADD) + return ICON_ADD + if(BLEND_SUBTRACT) + return ICON_SUBTRACT + else + return ICON_OVERLAY + +//Converts a rights bitfield into a string +/proc/rights2text(rights, seperator="", list/adds, list/subs) + if(rights & R_BUILDMODE) + . += "[seperator]+BUILDMODE" + if(rights & R_ADMIN) + . += "[seperator]+ADMIN" + if(rights & R_BAN) + . += "[seperator]+BAN" + if(rights & R_FUN) + . += "[seperator]+FUN" + if(rights & R_SERVER) + . += "[seperator]+SERVER" + if(rights & R_DEBUG) + . += "[seperator]+DEBUG" + if(rights & R_POSSESS) + . += "[seperator]+POSSESS" + if(rights & R_PERMISSIONS) + . += "[seperator]+PERMISSIONS" + if(rights & R_STEALTH) + . += "[seperator]+STEALTH" + if(rights & R_POLL) + . += "[seperator]+POLL" + if(rights & R_VAREDIT) + . += "[seperator]+VAREDIT" + if(rights & R_SOUNDS) + . += "[seperator]+SOUND" + if(rights & R_SPAWN) + . += "[seperator]+SPAWN" + + for(var/verbpath in adds) + . += "[seperator]+[verbpath]" + for(var/verbpath in subs) + . += "[seperator]-[verbpath]" + return . + +/proc/ui_style2icon(ui_style) + switch(ui_style) + if("Retro") + return 'icons/mob/screen_retro.dmi' + if("Plasmafire") + return 'icons/mob/screen_plasmafire.dmi' + if("Slimecore") + return 'icons/mob/screen_slimecore.dmi' + if("Operative") + return 'icons/mob/screen_operative.dmi' + if("Clockwork") + return 'icons/mob/screen_clockwork.dmi' + else + return 'icons/mob/screen_midnight.dmi' + +//colour formats +/proc/rgb2hsl(red, green, blue) + red /= 255;green /= 255;blue /= 255; + var/max = max(red,green,blue) + var/min = min(red,green,blue) + var/range = max-min + + var/hue=0;var/saturation=0;var/lightness=0; + lightness = (max + min)/2 + if(range != 0) + if(lightness < 0.5) + saturation = range/(max+min) + else + saturation = range/(2-max-min) + + var/dred = ((max-red)/(6*max)) + 0.5 + var/dgreen = ((max-green)/(6*max)) + 0.5 + var/dblue = ((max-blue)/(6*max)) + 0.5 + + if(max==red) + hue = dblue - dgreen + else if(max==green) + hue = dred - dblue + (1/3) + else + hue = dgreen - dred + (2/3) + if(hue < 0) + hue++ + else if(hue > 1) + hue-- + + return list(hue, saturation, lightness) + +/proc/hsl2rgb(hue, saturation, lightness) + var/red;var/green;var/blue; + if(saturation == 0) + red = lightness * 255 + green = red + blue = red + else + var/a;var/b; + if(lightness < 0.5) + b = lightness*(1+saturation) + else + b = (lightness+saturation) - (saturation*lightness) + a = 2*lightness - b + + red = round(255 * hue2rgb(a, b, hue+(1/3))) + green = round(255 * hue2rgb(a, b, hue)) + blue = round(255 * hue2rgb(a, b, hue-(1/3))) + + return list(red, green, blue) + +/proc/hue2rgb(a, b, hue) + if(hue < 0) + hue++ + else if(hue > 1) + hue-- + if(6*hue < 1) + return (a+(b-a)*6*hue) + if(2*hue < 1) + return b + if(3*hue < 2) + return (a+(b-a)*((2/3)-hue)*6) + return a + +// Very ugly, BYOND doesn't support unix time and rounding errors make it really hard to convert it to BYOND time. +// returns "YYYY-MM-DD" by default +/proc/unix2date(timestamp, seperator = "-") + + if(timestamp < 0) + return 0 //Do not accept negative values + + var/year = 1970 //Unix Epoc begins 1970-01-01 + var/dayInSeconds = 86400 //60secs*60mins*24hours + var/daysInYear = 365 //Non Leap Year + var/daysInLYear = daysInYear + 1//Leap year + var/days = round(timestamp / dayInSeconds) //Days passed since UNIX Epoc + var/tmpDays = days + 1 //If passed (timestamp < dayInSeconds), it will return 0, so add 1 + var/monthsInDays = list() //Months will be in here ***Taken from the PHP source code*** + var/month = 1 //This will be the returned MONTH NUMBER. + var/day //This will be the returned day number. + + while(tmpDays > daysInYear) //Start adding years to 1970 + year++ + if(isLeap(year)) + tmpDays -= daysInLYear + else + tmpDays -= daysInYear + + if(isLeap(year)) //The year is a leap year + monthsInDays = list(-1,30,59,90,120,151,181,212,243,273,304,334) + else + monthsInDays = list(0,31,59,90,120,151,181,212,243,273,304,334) + + var/mDays = 0; + var/monthIndex = 0; + + for(var/m in monthsInDays) + monthIndex++ + if(tmpDays > m) + mDays = m + month = monthIndex + + day = tmpDays - mDays //Setup the date + + return "[year][seperator][((month < 10) ? "0[month]" : month)][seperator][((day < 10) ? "0[day]" : day)]" + +/proc/isLeap(y) + return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) + + + +//Turns a Body_parts_covered bitfield into a list of organ/limb names. +//(I challenge you to find a use for this) +/proc/body_parts_covered2organ_names(bpc) + var/list/covered_parts = list() + + if(!bpc) + return 0 + + if(bpc & FULL_BODY) + covered_parts |= list("l_arm","r_arm","head","chest","l_leg","r_leg") + + else + if(bpc & HEAD) + covered_parts |= list("head") + if(bpc & CHEST) + covered_parts |= list("chest") + if(bpc & GROIN) + covered_parts |= list("chest") + + if(bpc & ARMS) + covered_parts |= list("l_arm","r_arm") + else + if(bpc & ARM_LEFT) + covered_parts |= list("l_arm") + if(bpc & ARM_RIGHT) + covered_parts |= list("r_arm") + + if(bpc & HANDS) + covered_parts |= list("l_arm","r_arm") + else + if(bpc & HAND_LEFT) + covered_parts |= list("l_arm") + if(bpc & HAND_RIGHT) + covered_parts |= list("r_arm") + + if(bpc & LEGS) + covered_parts |= list("l_leg","r_leg") + else + if(bpc & LEG_LEFT) + covered_parts |= list("l_leg") + if(bpc & LEG_RIGHT) + covered_parts |= list("r_leg") + + if(bpc & FEET) + covered_parts |= list("l_leg","r_leg") + else + if(bpc & FOOT_LEFT) + covered_parts |= list("l_leg") + if(bpc & FOOT_RIGHT) + covered_parts |= list("r_leg") + + return covered_parts + + + +//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ +/proc/heat2colour(temp) + return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp)) + + +/proc/heat2colour_r(temp) + temp /= 100 + if(temp <= 66) + . = 255 + else + . = max(0, min(255, 329.698727446 * (temp - 60) ** -0.1332047592)) + + +/proc/heat2colour_g(temp) + temp /= 100 + if(temp <= 66) + . = max(0, min(255, 99.4708025861 * log(temp) - 161.1195681661)) + else + . = max(0, min(255, 288.1221685293 * ((temp - 60) ** -0.075148492))) + + +/proc/heat2colour_b(temp) + temp /= 100 + if(temp >= 66) + . = 255 + else + if(temp <= 16) + . = 0 + else + . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) + +/proc/color2hex(color) //web colors + if(!color) + return "#000000" + + switch(color) + if("white") + return "#FFFFFF" + if("black") + return "#000000" + if("gray") + return "#808080" + if("brown") + return "#A52A2A" + if("red") + return "#FF0000" + if("darkred") + return "#8B0000" + if("crimson") + return "#DC143C" + if("orange") + return "#FFA500" + if("yellow") + return "#FFFF00" + if("green") + return "#008000" + if("lime") + return "#00FF00" + if("darkgreen") + return "#006400" + if("cyan") + return "#00FFFF" + if("blue") + return "#0000FF" + if("navy") + return "#000080" + if("teal") + return "#008080" + if("purple") + return "#800080" + if("indigo") + return "#4B0082" + else + return "#FFFFFF" + + +//This is a weird one: +//It returns a list of all var names found in the string +//These vars must be in the [var_name] format +//It's only a proc because it's used in more than one place + +//Takes a string and a datum +//The string is well, obviously the string being checked +//The datum is used as a source for var names, to check validity +//Otherwise every single word could technically be a variable! +/proc/string2listofvars(var/t_string, var/datum/var_source) + if(!t_string || !var_source) + return list() + + . = list() + + var/var_found = findtext(t_string,"\[") //Not the actual variables, just a generic "should we even bother" check + if(var_found) + //Find var names + + // "A dog said hi [name]!" + // splittext() --> list("A dog said hi ","name]!" + // jointext() --> "A dog said hi name]!" + // splittext() --> list("A","dog","said","hi","name]!") + + t_string = replacetext(t_string,"\[","\[ ")//Necessary to resolve "word[var_name]" scenarios + var/list/list_value = splittext(t_string,"\[") + var/intermediate_stage = jointext(list_value, null) + + list_value = splittext(intermediate_stage," ") + for(var/value in list_value) + if(findtext(value,"]")) + value = splittext(value,"]") //"name]!" --> list("name","!") + for(var/A in value) + if(var_source.vars.Find(A)) + . += A + +//assumes format #RRGGBB #rrggbb +/proc/color_hex2num(A) + if(!A) + return 0 + var/R = hex2num(copytext(A,2,4)) + var/G = hex2num(copytext(A,4,6)) + var/B = hex2num(copytext(A,6,0)) + return R+G+B + +//word of warning: using a matrix like this as a color value will simplify it back to a string after being set +/proc/color_hex2color_matrix(string) + var/length = length(string) + if(length != 7 && length != 9) + return color_matrix_identity() + var/r = hex2num(copytext(string, 2, 4))/255 + var/g = hex2num(copytext(string, 4, 6))/255 + var/b = hex2num(copytext(string, 6, 8))/255 + var/a = 1 + if(length == 9) + a = hex2num(copytext(string, 8, 10))/255 + if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a)) + return color_matrix_identity() + return list(r,0,0,0, 0,g,0,0, 0,0,b,0, 0,0,0,a, 0,0,0,0) + +//will drop all values not on the diagonal +/proc/color_matrix2color_hex(list/the_matrix) + if(!istype(the_matrix) || the_matrix.len != 20) + return "#ffffffff" + return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) /proc/type2parent(child) var/string_type = "[child]" diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 987818924f..4c0eeccf1d 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -20,7 +20,7 @@ return SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params) /obj/attackby(obj/item/I, mob/living/user, params) - return ..() || I.attack_obj(src, user) + return ..() || (can_be_hit && I.attack_obj(src, user)) /mob/living/attackby(obj/item/I, mob/living/user, params) user.changeNext_move(CLICK_CD_MELEE) diff --git a/code/datums/action.dm b/code/datums/action.dm index cf1046ca8f..60a0722f0f 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -592,49 +592,3 @@ var/datum/language_holder/H = M.get_language_holder() H.open_language_menu(usr) -/datum/action/innate/dash - name = "Dash" - desc = "Teleport to the targeted location." - icon_icon = 'icons/mob/actions/actions_items.dmi' - button_icon_state = "jetboot" - var/charged = TRUE - var/charge_rate = 250 - var/mob/living/carbon/human/holder - var/obj/item/dashing_item - var/dash_sound = 'sound/magic/blink.ogg' - var/recharge_sound = 'sound/magic/charge.ogg' - var/beam_effect = "blur" - var/phasein = /obj/effect/temp_visual/dir_setting/ninja/phase - var/phaseout = /obj/effect/temp_visual/dir_setting/ninja/phase/out - -/datum/action/innate/dash/Grant(mob/user, obj/dasher) - . = ..() - dashing_item = dasher - holder = user - -/datum/action/innate/dash/IsAvailable() - if(charged) - return TRUE - else - return FALSE - -/datum/action/innate/dash/Activate() - dashing_item.attack_self(holder) //Used to toggle dash behavior in the dashing item - -/datum/action/innate/dash/proc/Teleport(mob/user, atom/target) - var/turf/T = get_turf(target) - if(target in view(user.client.view, get_turf(user))) - var/obj/spot1 = new phaseout(get_turf(user), user.dir) - user.forceMove(T) - playsound(T, dash_sound, 25, 1) - var/obj/spot2 = new phasein(get_turf(user), user.dir) - spot1.Beam(spot2,beam_effect,time=20) - charged = FALSE - holder.update_action_buttons_icon() - addtimer(CALLBACK(src, .proc/charge), charge_rate) - -/datum/action/innate/dash/proc/charge() - charged = TRUE - holder.update_action_buttons_icon() - playsound(dashing_item, recharge_sound, 50, 1) - to_chat(holder, "[dashing_item] is ready for another jaunt.") \ No newline at end of file diff --git a/code/datums/antagonists/datum_abductor.dm b/code/datums/antagonists/datum_abductor.dm index 6d08d61b8a..81329928b3 100644 --- a/code/datums/antagonists/datum_abductor.dm +++ b/code/datums/antagonists/datum_abductor.dm @@ -58,3 +58,9 @@ break SSticker.mode.update_abductor_icons_added(owner) + +/datum/antagonist/abductor/scientist/finalize_abductor() + ..() + var/mob/living/carbon/human/H = owner.current + var/datum/species/abductor/A = H.dna.species + A.scientist = TRUE diff --git a/code/datums/components/paintable.dm b/code/datums/components/paintable.dm new file mode 100644 index 0000000000..2ea94334d0 --- /dev/null +++ b/code/datums/components/paintable.dm @@ -0,0 +1,29 @@ +/datum/component/spraycan_paintable + var/current_paint + +/datum/component/spraycan_paintable/Initialize() + RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/Repaint) + +/datum/component/spraycan_paintable/Destroy() + RemoveCurrentCoat() + return ..() + +/datum/component/spraycan_paintable/proc/RemoveCurrentCoat() + var/atom/A = parent + A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint) + +/datum/component/spraycan_paintable/proc/Repaint(obj/item/toy/crayon/spraycan/spraycan, mob/living/user) + if(!istype(spraycan) || user.a_intent == INTENT_HARM) + return FALSE + . = TRUE + if(spraycan.is_capped) + to_chat(user, "Take the cap off first!") + return + RemoveCurrentCoat() + if(spraycan.use_charges(user, 2)) + var/colour = spraycan.paint_color + current_paint = colour + var/atom/A = parent + A.add_atom_colour(colour, FIXED_COLOUR_PRIORITY) + playsound(spraycan, 'sound/effects/spray.ogg', 5, 1, 5) + to_chat(user, "You spray [spraycan] on [A], painting it.") diff --git a/code/datums/dash_weapon.dm b/code/datums/dash_weapon.dm new file mode 100644 index 0000000000..1637655d18 --- /dev/null +++ b/code/datums/dash_weapon.dm @@ -0,0 +1,50 @@ +/datum/action/innate/dash + name = "Dash" + desc = "Teleport to the targeted location." + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "jetboot" + var/current_charges = 1 + var/max_charges = 1 + var/charge_rate = 250 + var/mob/living/carbon/human/holder + var/obj/item/dashing_item + var/dash_sound = 'sound/magic/blink.ogg' + var/recharge_sound = 'sound/magic/charge.ogg' + var/beam_effect = "blur" + var/phasein = /obj/effect/temp_visual/dir_setting/ninja/phase + var/phaseout = /obj/effect/temp_visual/dir_setting/ninja/phase/out + +/datum/action/innate/dash/Grant(mob/user, obj/dasher) + . = ..() + dashing_item = dasher + holder = user + +/datum/action/innate/dash/IsAvailable() + if(current_charges > 0) + return TRUE + else + return FALSE + +/datum/action/innate/dash/Activate() + dashing_item.attack_self(holder) //Used to toggle dash behavior in the dashing item + +/datum/action/innate/dash/proc/Teleport(mob/user, atom/target) + if(!IsAvailable()) + return + var/turf/T = get_turf(target) + if(target in view(user.client.view, get_turf(user))) + var/obj/spot1 = new phaseout(get_turf(user), user.dir) + user.forceMove(T) + playsound(T, dash_sound, 25, 1) + var/obj/spot2 = new phasein(get_turf(user), user.dir) + spot1.Beam(spot2,beam_effect,time=20) + current_charges-- + holder.update_action_buttons_icon() + addtimer(CALLBACK(src, .proc/charge), charge_rate) + +/datum/action/innate/dash/proc/charge() + current_charges = Clamp(current_charges + 1, 0, max_charges) + holder.update_action_buttons_icon() + if(recharge_sound) + playsound(dashing_item, recharge_sound, 50, 1) + to_chat(holder, "[src] now has [current_charges]/[max_charges] charges.") \ No newline at end of file diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index 455ec0f62a..88e6148c5f 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -42,7 +42,7 @@ I.trigger(key, L) if(!msg) - return FALSE + return user.log_message(msg, INDIVIDUAL_EMOTE_LOG) msg = "[user] " + msg @@ -91,21 +91,22 @@ /datum/emote/proc/select_param(mob/user, params) return replacetext(message_param, "%t", params) -/datum/emote/proc/can_run_emote(mob/user, help_check) +/datum/emote/proc/can_run_emote(mob/user, status_check = TRUE) . = TRUE if(!is_type_in_typecache(user, mob_type_allowed_typecache)) return FALSE if(is_type_in_typecache(user, mob_type_blacklist_typecache)) return FALSE - if(!help_check) + if(status_check) if(user.stat > stat_allowed || (user.status_flags & FAKEDEATH)) + to_chat(user, "You cannot [key] while unconscious.") return FALSE - if(restraint_check && user.restrained()) + if(restraint_check && (user.restrained() || user.buckled)) + to_chat(user, "You cannot [key] while restrained.") return FALSE if(user.reagents && user.reagents.has_reagent("mimesbane")) return FALSE - /datum/emote/sound var/sound //Sound to play when emote is called var/vary = FALSE //used for the honk borg emote diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 093e828452..0e1b754fc9 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1119,7 +1119,7 @@ message_admins("[key_name_admin(usr)] has nuke op'ed [current].") log_admin("[key_name(usr)] has nuke op'ed [current].") if("lair") - current.forceMove(get_turf(locate("landmark*Syndicate-Spawn"))) + current.forceMove(pick(GLOB.nukeop_start)) if("dressup") var/mob/living/carbon/human/H = current qdel(H.belt) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index b062b8f054..222ce73f92 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -449,10 +449,11 @@ GLOBAL_LIST_EMPTY(teleportlocs) if(!L.client.played) SEND_SOUND(L, sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE)) - L.client.played = 1 - sleep(600) //ewww - this is very very bad - if(L.&& L.client) - L.client.played = 0 + L.client.played = TRUE + addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 600) + +/client/proc/ResetAmbiencePlayed() + played = FALSE /atom/proc/has_gravity(turf/T) if(!T || !isturf(T)) diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm index e90626485a..519fc2e296 100644 --- a/code/game/gamemodes/blob/blob_report.dm +++ b/code/game/gamemodes/blob/blob_report.dm @@ -85,7 +85,7 @@ src.grille += 1 else if(istype(O, /obj/machinery/door)) src.door += 1 - else if(istype(O, /obj/machinery)) + else if(ismachinery(O)) src.mach += 1 if(count_territories) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 7d6f9bcdd1..261a258101 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -163,7 +163,6 @@ Credit where due: if(!M || !ishuman(M)) return FALSE var/mob/living/carbon/human/L = M - L.set_species(/datum/species/human) L.equipOutfit(/datum/outfit/servant_of_ratvar) var/obj/item/clockwork/slab/S = new var/slot = "At your feet" @@ -239,6 +238,7 @@ Credit where due: //Servant of Ratvar outfit /datum/outfit/servant_of_ratvar + name = "Servant of Ratvar" uniform = /obj/item/clothing/under/chameleon/ratvar shoes = /obj/item/clothing/shoes/workboots back = /obj/item/storage/backpack @@ -248,6 +248,15 @@ Credit where due: backpack_contents = list(/obj/item/storage/box/engineer = 1, \ /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1) id = /obj/item/card/id + var/plasmaman //We use this to determine if we should activate internals in post_equip() + +/datum/outfit/servant_of_ratvar/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + if(H.dna.species.id == "plasmaman") //Plasmamen get additional equipment because of how they work + head = /obj/item/clothing/head/helmet/space/plasmaman + uniform = /obj/item/clothing/under/plasmaman //Plasmamen generally shouldn't need chameleon suits anyways, since everyone expects them to wear their fire suit + r_hand = /obj/item/tank/internals/plasmaman/belt/full + mask = /obj/item/clothing/mask/breath + plasmaman = TRUE /datum/outfit/servant_of_ratvar/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) var/obj/item/card/id/W = H.wear_id @@ -255,6 +264,9 @@ Credit where due: W.access += ACCESS_MAINT_TUNNELS W.registered_name = H.real_name W.update_label() + if(plasmaman && !visualsOnly) //If we need to breathe from the plasma tank, we should probably start doing that + H.internal = H.get_item_for_held_index(2) + H.update_internals_hud_icon(1) /obj/item/paper/servant_primer name = "The Ark And You: A Primer On Servitude" diff --git a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm index cdff486eea..364c967ae9 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm @@ -11,7 +11,7 @@ break_message = "The warden's eye gives a glare of utter hate before falling dark!" debris = list(/obj/item/clockwork/component/belligerent_eye/blind_eye = 1) resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - var/damage_per_tick = 2.5 + var/damage_per_tick = 3 var/sight_range = 3 var/atom/movable/target var/list/idle_messages = list(" sulkily glares around.", " lazily drifts from side to side.", " looks around for something to burn.", " slowly turns in circles.") @@ -141,8 +141,12 @@ . = 1 if(target) for(var/turf/T in getline(src, target)) + if(T.density) + . -= 0.1 + continue for(var/obj/structure/O in T) - if(O.density) - . -= 0.15 + if(O != src && O.density) + . -= 0.1 + break . -= (get_dist(src, target) * 0.05) . = max(., 0.1) //The lowest damage a warden can do is 10% of its normal amount (0.25 by default) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 876cace14d..a3da1c6cbe 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -98,7 +98,6 @@ var/datum/action/innate/cult/spin2win/linked_action var/spinning = FALSE var/spin_cooldown = 250 - var/list/shards = list() var/dash_toggled = TRUE /obj/item/twohanded/required/cult_bastard/Initialize() @@ -174,11 +173,12 @@ if(H.stat != CONSCIOUS) var/obj/item/device/soulstone/SS = new /obj/item/device/soulstone(src) SS.attack(H, user) - shards += SS - return + if(!LAZYLEN(SS.contents)) + qdel(SS) if(istype(target, /obj/structure/constructshell) && contents.len) var/obj/item/device/soulstone/SS = contents[1] - if(istype(SS) && SS.transfer_soul("CONSTRUCT",target,user)) + if(istype(SS)) + SS.transfer_soul("CONSTRUCT",target,user) qdel(SS) /datum/action/innate/dash/cult @@ -193,7 +193,7 @@ phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out /datum/action/innate/dash/cult/IsAvailable() - if(iscultist(holder) && charged) + if(iscultist(holder) && current_charges) return TRUE else return FALSE diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 0144872c17..8140dffe53 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -112,7 +112,7 @@ pickedtype = /obj/item/twohanded/required/cult_bastard else cooldowntime = 12000 - (world.time - SSticker.round_start_time) - to_chat(user, "The forge fires are not yet hot enough for this weapon, give it another [DisplayTimeText(cooldowntime - world.time)].") + to_chat(user, "The forge fires are not yet hot enough for this weapon, give it another [DisplayTimeText(cooldowntime)].") cooldowntime = 0 return if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time) diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 8256d0aaf0..d25c7613bc 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -111,10 +111,7 @@ if (!newname) newname = randomname - wizard_mob.real_name = newname - wizard_mob.name = newname - if(wizard_mob.mind) - wizard_mob.mind.name = newname + wizard_mob.fully_replace_character_name(wizard_mob.real_name, newname) /* Wizards by nature cannot be too young. */ if(wizard_mob.age < WIZARD_AGE_MIN) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index b3a7f99758..d4a06d0580 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1009,8 +1009,9 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/item/clothing/mask/joy = 1, /obj/item/clothing/head/cueball = 1, /obj/item/clothing/under/scratch = 1, - /obj/item/clothing/under/sailor = 1, - /obj/item/clothing/ears/headphones = 2) + /obj/item/clothing/under/sailor = 1, + /obj/item/clothing/ears/headphones = 2, + /obj/item/clothing/head/wig/random = 3) contraband = list(/obj/item/clothing/suit/judgerobe = 1, /obj/item/clothing/head/powdered_wig = 1, /obj/item/gun/magic/wand = 2, /obj/item/clothing/glasses/sunglasses/garb = 2, /obj/item/clothing/glasses/sunglasses/blindfold = 1, /obj/item/clothing/mask/muzzle = 2) premium = list(/obj/item/clothing/suit/pirate/captain = 2, /obj/item/clothing/head/pirate/captain = 2, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/shield/riot/roman = 1, /obj/item/skub = 1) refill_canister = /obj/item/vending_refill/autodrobe diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 4406c32fbd..d5f8e28d2a 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -4,9 +4,7 @@ /obj/effect icon = 'icons/effects/effects.dmi' resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF - -/obj/effect/attackby(obj/item/I, mob/living/user, params) - return + can_be_hit = FALSE /obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) return @@ -57,4 +55,4 @@ return /obj/effect/abstract/singularity_act() - return \ No newline at end of file + return diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 072896ac01..362148c801 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -26,6 +26,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) max_integrity = 200 + can_be_hit = FALSE + var/hitsound = null var/usesound = null var/throwhitsound = null @@ -322,6 +324,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // Due to storage type consolidation this should get used more now. // I have cleaned it up a little, but it could probably use more. -Sayu // The lack of ..() is intentional, do not add one +// added one, fuck the police /obj/item/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/storage)) var/obj/item/storage/S = W @@ -346,9 +349,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) qdel(progress) to_chat(user, "You put everything you could [S.preposition] [S].") + return else if(S.can_be_inserted(src)) S.handle_item_insertion(src) + return + return ..() /obj/item/proc/handle_mass_pickup(obj/item/storage/S, list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) for(var/obj/item/I in things) diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 23905200e9..882335d5e7 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -107,20 +107,19 @@ var/amount = weight * units_per_weight reagents.add_reagent(reagent, amount) -/obj/item/toy/crayon/proc/use_charges(amount) +/obj/item/toy/crayon/proc/use_charges(mob/user, amount = 1, requires_full = TRUE) // Returns number of charges actually used - switch(paint_mode) - if(PAINT_LARGE_HORIZONTAL) - amount *= 3 - if(charges == -1) . = amount refill() else - . = min(charges_left, amount) - charges_left -= . + if(check_empty(user, amount, requires_full)) + return 0 + else + . = min(charges_left, amount) + charges_left -= . -/obj/item/toy/crayon/proc/check_empty(mob/user) +/obj/item/toy/crayon/proc/check_empty(mob/user, amount = 1, requires_full = TRUE) // When eating a crayon, check_empty() can be called twice producing // two messages unless we check for being deleted first if(QDELETED(src)) @@ -131,10 +130,13 @@ if(charges == -1) . = FALSE else if(!charges_left) - to_chat(user, "There is no more of \the [src.name] left!") + to_chat(user, "There is no more of [src] left!") if(self_contained) qdel(src) . = TRUE + else if(charges_left < amount && requires_full) + to_chat(user, "There is not enough of [src] left!") + . = TRUE /obj/item/toy/crayon/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) // tgui is a plague upon this codebase @@ -298,7 +300,7 @@ var/takes_time = !instant var/wait_time = 50 - if(PAINT_LARGE_HORIZONTAL) + if(paint_mode == PAINT_LARGE_HORIZONTAL) wait_time *= 3 if(takes_time) @@ -343,7 +345,7 @@ var/cost = 1 if(paint_mode == PAINT_LARGE_HORIZONTAL) cost = 5 - . = use_charges(cost) + . = use_charges(user, cost) var/fraction = min(1, . / reagents.maximum_volume) if(affected_turfs.len) fraction /= affected_turfs.len @@ -355,7 +357,7 @@ /obj/item/toy/crayon/attack(mob/M, mob/user) if(edible && (M == user)) to_chat(user, "You take a bite of the [src.name]. Delicious!") - var/eaten = use_charges(5) + var/eaten = use_charges(user, 5, FALSE) if(check_empty(user)) //Prevents divsion by zero return var/fraction = min(eaten / reagents.total_volume, 1) @@ -527,7 +529,7 @@ H.lip_style = "spray_face" H.lip_color = paint_color H.update_body() - var/used = use_charges(10) + var/used = use_charges(user, 10, FALSE) var/fraction = min(1, used / reagents.maximum_volume) reagents.reaction(user, VAPOR, fraction * volume_multiplier) reagents.trans_to(user, used, volume_multiplier) @@ -583,7 +585,7 @@ H.update_body() // Caution, spray cans contain inflammable substances - . = use_charges(10) + . = use_charges(user, 10, FALSE) var/fraction = min(1, . / reagents.maximum_volume) reagents.reaction(C, VAPOR, fraction * volume_multiplier) @@ -596,7 +598,7 @@ target.set_opacity(255) else target.set_opacity(initial(target.opacity)) - . = use_charges(2) + . = use_charges(user, 2) var/fraction = min(1, . / reagents.maximum_volume) reagents.reaction(target, TOUCH, fraction * volume_multiplier) reagents.trans_to(target, ., volume_multiplier) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index ccfe70e662..a5ed03919a 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -27,13 +27,17 @@ GLOBAL_LIST_EMPTY(PDAs) var/mode = 0 //Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge. var/icon_alert = "pda-r" //Icon to be overlayed for message alerts. Taken from the pda icon file. var/font_index = 0 //This int tells DM which font is currently selected and lets DM know when the last font has been selected so that it can cycle back to the first font when "toggle font" is pressed again. - var/font_mode = "font-family:\"VT323\", monospace;letter-spacing:1px;" //The currently selected font. + var/font_mode = "font-family:monospace;" //The currently selected font. var/background_color = "#808000" //The currently selected background color. - #define FONT_VT 0 - #define FONT_SHARE 1 - #define FONT_ORBITRON 2 - #define FONT_MONO 3 + #define FONT_MONO "font-family:monospace;" + #define FONT_SHARE "font-family:\"Share Tech Mono\", monospace;letter-spacing:0px;" + #define FONT_ORBITRON "font-family:\"Orbitron\", monospace;letter-spacing:0px; font-size:15px" + #define FONT_VT "font-family:\"VT323\", monospace;letter-spacing:1px;" + #define MODE_MONO 0 + #define MODE_SHARE 1 + #define MODE_ORBITRON 2 + #define MODE_VT 3 //Secondary variables var/scanmode = 0 //1 is medical scanner, 2 is forensics, 3 is reagent scanner. @@ -54,6 +58,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/detonatable = TRUE // Can the PDA be blown up? var/hidden = 0 // Is the PDA hidden from the PDA list? var/emped = 0 + var/equipped = FALSE //used here to determine if this is the first time its been picked up var/obj/item/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. var/ownjob = null //related to above @@ -87,6 +92,27 @@ GLOBAL_LIST_EMPTY(PDAs) inserted_item = new /obj/item/pen(src) update_icon() +/obj/item/device/pda/equipped(mob/user, slot) + if(!equipped) + if(user.client) + switch(user.client.prefs.pda_style) + if(MONO) + font_index = MODE_MONO + font_mode = FONT_MONO + if(SHARE) + font_index = MODE_SHARE + font_mode = FONT_SHARE + if(ORBITRON) + font_index = MODE_ORBITRON + font_mode = FONT_ORBITRON + if(VT) + font_index = MODE_VT + font_mode = FONT_VT + else + font_index = MODE_MONO + font_mode = FONT_MONO + equipped = TRUE + /obj/item/device/pda/proc/update_label() name = "PDA-[owner] ([ownjob])" //Name generalisation @@ -335,14 +361,14 @@ GLOBAL_LIST_EMPTY(PDAs) font_index = (font_index + 1) % 4 switch(font_index) - if (FONT_VT) - font_mode = "font-family:\"VT323\", monospace;letter-spacing:1px;" - if (FONT_SHARE) - font_mode = "font-family:\"Share Tech Mono\", monospace;letter-spacing:0px;" - if (FONT_ORBITRON) - font_mode = "font-family:\"Orbitron\", monospace;letter-spacing:0px; font-size:15px" - if (FONT_MONO) - font_mode = "font-family:monospace;" + if (MODE_MONO) + font_mode = FONT_MONO + if (MODE_SHARE) + font_mode = FONT_SHARE + if (MODE_ORBITRON) + font_mode = FONT_ORBITRON + if (MODE_VT) + font_mode = FONT_VT if ("Change_Color") var/new_color = input("Please enter a color name or hex value (Default is \'#808000\').")as color background_color = new_color diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 02d835da16..6c073f4b69 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -1,7 +1,7 @@ /obj/item/stack/medical name = "medical pack" singular_name = "medical pack" - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/stack_objects.dmi' amount = 6 max_amount = 6 w_class = WEIGHT_CLASS_TINY diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 8056674074..2bb5d110fc 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -63,7 +63,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ /obj/item/stack/sheet/mineral/sandbags name = "sandbags" - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/stack_objects.dmi' icon_state = "sandbags" singular_name = "sandbag" layer = LOW_ITEM_LAYER diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 3a79ce23db..7cef6094ea 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -8,6 +8,7 @@ * Stacks */ /obj/item/stack + icon = 'icons/obj/stack_objects.dmi' origin_tech = "materials=1" gender = PLURAL var/list/datum/stack_recipe/recipes @@ -150,7 +151,11 @@ if(!building_checks(R, multiplier)) return - var/obj/O = new R.result_type() + var/obj/O + if(R.max_res_amount > 1) //Is it a stack? + O = new R.result_type(usr.drop_location(), R.res_amount * multiplier) + else + O = new R.result_type(usr.drop_location()) O.setDir(usr.dir) use(R.req_amount * multiplier) @@ -163,16 +168,11 @@ W.ini_dir = W.dir //END: oh fuck i'm so sorry - //is it a stack ? - if (R.max_res_amount > 1) - var/obj/item/stack/new_item = O - new_item.amount = R.res_amount*multiplier - new_item.update_icon() + if (QDELETED(O)) + return //It's a stack and has already been merged if (isitem(O)) usr.put_in_hands(O) - else - O.forceMove(usr.drop_location()) O.add_fingerprint(usr) //BubbleWrap - so newly formed boxes are empty diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 28856e17d8..c0c861f4c4 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -162,7 +162,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1) if(do_after(user, 40, target = sword)) playsound(src,'sound/effects/pray_chaplain.ogg',60,1) - for(var/obj/item/device/soulstone/SS in sword.shards) + for(var/obj/item/device/soulstone/SS in sword.contents) SS.usability = TRUE for(var/mob/living/simple_animal/shade/EX in SS) SSticker.mode.remove_cultist(EX.mind, 1, 0) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm deleted file mode 100644 index f8a020b677..0000000000 --- a/code/game/objects/items/weapons/storage/belt.dm +++ /dev/null @@ -1,531 +0,0 @@ -/obj/item/weapon/storage/belt - name = "belt" - desc = "Can hold various things." - icon = 'icons/obj/clothing/belts.dmi' - icon_state = "utilitybelt" - item_state = "utility" - slot_flags = SLOT_BELT - attack_verb = list("whipped", "lashed", "disciplined") - max_integrity = 300 - var/content_overlays = FALSE //If this is true, the belt will gain overlays based on what it's holding - -/obj/item/weapon/storage/belt/update_icon() - cut_overlays() - if(content_overlays) - for(var/obj/item/I in contents) - var/mutable_appearance/M = I.get_belt_overlay() - add_overlay(M) - ..() - -/obj/item/weapon/storage/belt/Initialize() - . = ..() - update_icon() - -/obj/item/weapon/storage/belt/utility - name = "toolbelt" //Carn: utility belt is nicer, but it bamboozles the text parsing. - desc = "Holds tools." - icon_state = "utilitybelt" - item_state = "utility" - can_hold = list( - /obj/item/weapon/crowbar, - /obj/item/weapon/screwdriver, - /obj/item/weapon/weldingtool, - /obj/item/weapon/wirecutters, - /obj/item/weapon/wrench, - /obj/item/device/multitool, - /obj/item/device/flashlight, - /obj/item/stack/cable_coil, - /obj/item/device/t_scanner, - /obj/item/device/analyzer, - /obj/item/weapon/extinguisher/mini, - /obj/item/device/radio, - /obj/item/clothing/gloves - ) - content_overlays = TRUE - -/obj/item/weapon/storage/belt/utility/chief - name = "\improper Chief Engineer's toolbelt" //"the Chief Engineer's toolbelt", because "Chief Engineer's toolbelt" is not a proper noun - desc = "Holds tools, looks snazzy." - icon_state = "utilitybelt_ce" - item_state = "utility_ce" - -/obj/item/weapon/storage/belt/utility/chief/full/PopulateContents() - new /obj/item/weapon/screwdriver/power(src) - new /obj/item/weapon/crowbar/power(src) - new /obj/item/weapon/weldingtool/experimental(src)//This can be changed if this is too much - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) - new /obj/item/weapon/extinguisher/mini(src) - new /obj/item/device/analyzer(src) - //much roomier now that we've managed to remove two tools - - -/obj/item/weapon/storage/belt/utility/full/PopulateContents() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) - -/obj/item/weapon/storage/belt/utility/full/engi/PopulateContents() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool/largetank(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) - - -/obj/item/weapon/storage/belt/utility/atmostech/PopulateContents() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/t_scanner(src) - new /obj/item/weapon/extinguisher/mini(src) - - -/obj/item/weapon/storage/belt/utility/servant/PopulateContents() - new /obj/item/weapon/screwdriver/brass(src) - new /obj/item/weapon/wirecutters/brass(src) - new /obj/item/weapon/wrench/brass(src) - new /obj/item/weapon/crowbar/brass(src) - new /obj/item/weapon/weldingtool/experimental/brass(src) - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src, 30, "yellow") - - -/obj/item/weapon/storage/belt/medical - name = "medical belt" - desc = "Can hold various medical equipment." - icon_state = "medicalbelt" - item_state = "medical" - max_w_class = WEIGHT_CLASS_BULKY - can_hold = list( - /obj/item/device/healthanalyzer, - /obj/item/weapon/dnainjector, - /obj/item/weapon/reagent_containers/dropper, - /obj/item/weapon/reagent_containers/glass/beaker, - /obj/item/weapon/reagent_containers/glass/bottle, - /obj/item/weapon/reagent_containers/pill, - /obj/item/weapon/reagent_containers/syringe, - /obj/item/weapon/lighter, - /obj/item/weapon/storage/fancy/cigarettes, - /obj/item/weapon/storage/pill_bottle, - /obj/item/stack/medical, - /obj/item/device/flashlight/pen, - /obj/item/weapon/extinguisher/mini, - /obj/item/weapon/reagent_containers/hypospray, - /obj/item/device/sensor_device, - /obj/item/device/radio, - /obj/item/clothing/gloves/, - /obj/item/weapon/lazarus_injector, - /obj/item/weapon/bikehorn/rubberducky, - /obj/item/clothing/mask/surgical, - /obj/item/clothing/mask/breath, - /obj/item/clothing/mask/breath/medical, - /obj/item/weapon/surgical_drapes, //for true paramedics - /obj/item/weapon/scalpel, - /obj/item/weapon/circular_saw, - /obj/item/weapon/surgicaldrill, - /obj/item/weapon/retractor, - /obj/item/weapon/cautery, - /obj/item/weapon/hemostat, - /obj/item/device/geiger_counter, - /obj/item/clothing/neck/stethoscope, - /obj/item/weapon/stamp, - /obj/item/clothing/glasses, - /obj/item/weapon/wrench/medical, - /obj/item/clothing/mask/muzzle, - /obj/item/weapon/storage/bag/chemistry, - /obj/item/weapon/storage/bag/bio, - /obj/item/weapon/reagent_containers/blood, - /obj/item/weapon/tank/internals/emergency_oxygen - ) - - -/obj/item/weapon/storage/belt/security - name = "security belt" - desc = "Can hold security gear like handcuffs and flashes." - icon_state = "securitybelt" - item_state = "security"//Could likely use a better one. - storage_slots = 5 - max_w_class = WEIGHT_CLASS_NORMAL //Because the baton wouldn't fit otherwise. - Neerti - can_hold = list( - /obj/item/weapon/melee/baton, - /obj/item/weapon/melee/classic_baton, - /obj/item/weapon/grenade, - /obj/item/weapon/reagent_containers/spray/pepper, - /obj/item/weapon/restraints/handcuffs, - /obj/item/device/assembly/flash/handheld, - /obj/item/clothing/glasses, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_box, - /obj/item/weapon/reagent_containers/food/snacks/donut, - /obj/item/weapon/reagent_containers/food/snacks/donut/jelly, - /obj/item/weapon/kitchen/knife/combat, - /obj/item/device/flashlight/seclite, - /obj/item/weapon/melee/classic_baton/telescopic, - /obj/item/device/radio, - /obj/item/clothing/gloves/, - /obj/item/weapon/restraints/legcuffs/bola - ) - content_overlays = TRUE - -/obj/item/weapon/storage/belt/security/full/PopulateContents() - new /obj/item/weapon/reagent_containers/spray/pepper(src) - new /obj/item/weapon/restraints/handcuffs(src) - new /obj/item/weapon/grenade/flashbang(src) - new /obj/item/device/assembly/flash/handheld(src) - new /obj/item/weapon/melee/baton/loaded(src) - update_icon() - - -/obj/item/weapon/storage/belt/mining - name = "explorer's webbing" - desc = "A versatile chest rig, cherished by miners and hunters alike." - icon_state = "explorer1" - item_state = "explorer1" - storage_slots = 6 - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_BULKY //Pickaxes are big. - max_combined_w_class = 20 //Not an issue with this whitelist, probably. - can_hold = list( - /obj/item/weapon/crowbar, - /obj/item/weapon/screwdriver, - /obj/item/weapon/weldingtool, - /obj/item/weapon/wirecutters, - /obj/item/weapon/wrench, - /obj/item/device/flashlight, - /obj/item/stack/cable_coil, - /obj/item/device/analyzer, - /obj/item/weapon/extinguisher/mini, - /obj/item/device/radio, - /obj/item/clothing/gloves, - /obj/item/weapon/resonator, - /obj/item/device/mining_scanner, - /obj/item/weapon/pickaxe, - /obj/item/stack/sheet/animalhide, - /obj/item/stack/sheet/sinew, - /obj/item/stack/sheet/bone, - /obj/item/weapon/lighter, - /obj/item/weapon/storage/fancy/cigarettes, - /obj/item/weapon/reagent_containers/food/drinks/bottle, - /obj/item/stack/medical, - /obj/item/weapon/kitchen/knife, - /obj/item/weapon/reagent_containers/hypospray, - /obj/item/device/gps, - /obj/item/weapon/storage/bag/ore, - /obj/item/weapon/survivalcapsule, - /obj/item/device/t_scanner/adv_mining_scanner, - /obj/item/weapon/reagent_containers/pill, - /obj/item/weapon/storage/pill_bottle, - /obj/item/weapon/ore, - /obj/item/weapon/reagent_containers/food/drinks, - /obj/item/organ/regenerative_core, - /obj/item/device/wormhole_jaunter, - /obj/item/weapon/storage/bag/plants, - /obj/item/stack/marker_beacon - ) - - -/obj/item/weapon/storage/belt/mining/vendor - contents = newlist(/obj/item/weapon/survivalcapsule) - -/obj/item/weapon/storage/belt/mining/alt - icon_state = "explorer2" - item_state = "explorer2" - -/obj/item/weapon/storage/belt/mining/primitive - name = "hunter's belt" - desc = "A versatile belt, woven from sinew." - storage_slots = 5 - icon_state = "ebelt" - item_state = "ebelt" - -/obj/item/weapon/storage/belt/soulstone - name = "soul stone belt" - desc = "Designed for ease of access to the shards during a fight, as to not let a single enemy spirit slip away" - icon_state = "soulstonebelt" - item_state = "soulstonebelt" - storage_slots = 6 - can_hold = list( - /obj/item/device/soulstone - ) - -/obj/item/weapon/storage/belt/soulstone/full/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/device/soulstone(src) - -/obj/item/weapon/storage/belt/champion - name = "championship belt" - desc = "Proves to the world that you are the strongest!" - icon_state = "championbelt" - item_state = "champion" - materials = list(MAT_GOLD=400) - storage_slots = 1 - can_hold = list( - /obj/item/clothing/mask/luchador - ) - -/obj/item/weapon/storage/belt/military - name = "chest rig" - desc = "A set of tactical webbing worn by Syndicate boarding parties." - icon_state = "militarywebbing" - item_state = "militarywebbing" - max_w_class = WEIGHT_CLASS_SMALL - -/obj/item/weapon/storage/belt/military/abductor - name = "agent belt" - desc = "A belt used by abductor agents." - icon = 'icons/obj/abductor.dmi' - icon_state = "belt" - item_state = "security" - -/obj/item/weapon/storage/belt/military/abductor/full/PopulateContents() - new /obj/item/weapon/screwdriver/abductor(src) - new /obj/item/weapon/wrench/abductor(src) - new /obj/item/weapon/weldingtool/abductor(src) - new /obj/item/weapon/crowbar/abductor(src) - new /obj/item/weapon/wirecutters/abductor(src) - new /obj/item/device/multitool/abductor(src) - new /obj/item/stack/cable_coil(src,30,"white") - - -/obj/item/weapon/storage/belt/military/army - name = "army belt" - desc = "A belt used by military forces." - icon_state = "grenadebeltold" - item_state = "security" - -/obj/item/weapon/storage/belt/military/assault - name = "assault belt" - desc = "A tactical assault belt." - icon_state = "assaultbelt" - item_state = "security" - storage_slots = 6 - -/obj/item/weapon/storage/belt/grenade - name = "grenadier belt" - desc = "A belt for holding grenades." - icon_state = "grenadebeltnew" - item_state = "security" - max_w_class = WEIGHT_CLASS_BULKY - display_contents_with_number = TRUE - storage_slots = 30 - max_combined_w_class = 60 //needs to be this high - can_hold = list( - /obj/item/weapon/grenade, - /obj/item/weapon/screwdriver, - /obj/item/weapon/lighter, - /obj/item/device/multitool, - /obj/item/weapon/reagent_containers/food/drinks/bottle/molotov, - /obj/item/weapon/grenade/plastic/c4, - ) -/obj/item/weapon/storage/belt/grenade/full/PopulateContents() - new /obj/item/weapon/grenade/flashbang(src) - new /obj/item/weapon/grenade/smokebomb(src) - new /obj/item/weapon/grenade/smokebomb(src) - new /obj/item/weapon/grenade/smokebomb(src) - new /obj/item/weapon/grenade/smokebomb(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/gluon(src) - new /obj/item/weapon/grenade/gluon(src) - new /obj/item/weapon/grenade/gluon(src) - new /obj/item/weapon/grenade/gluon(src) - new /obj/item/weapon/grenade/chem_grenade/incendiary(src) - new /obj/item/weapon/grenade/chem_grenade/incendiary(src) - new /obj/item/weapon/grenade/chem_grenade/facid(src) - new /obj/item/weapon/grenade/syndieminibomb(src) - new /obj/item/weapon/grenade/syndieminibomb(src) - new /obj/item/weapon/screwdriver(src) - new /obj/item/device/multitool(src) - -/obj/item/weapon/storage/belt/wands - name = "wand belt" - desc = "A belt designed to hold various rods of power. A veritable fanny pack of exotic magic." - icon_state = "soulstonebelt" - item_state = "soulstonebelt" - storage_slots = 6 - can_hold = list( - /obj/item/weapon/gun/magic/wand - ) - -/obj/item/weapon/storage/belt/wands/full/PopulateContents() - new /obj/item/weapon/gun/magic/wand/death(src) - new /obj/item/weapon/gun/magic/wand/resurrection(src) - new /obj/item/weapon/gun/magic/wand/polymorph(src) - new /obj/item/weapon/gun/magic/wand/teleport(src) - new /obj/item/weapon/gun/magic/wand/door(src) - new /obj/item/weapon/gun/magic/wand/fireball(src) - - for(var/obj/item/weapon/gun/magic/wand/W in contents) //All wands in this pack come in the best possible condition - W.max_charges = initial(W.max_charges) - W.charges = W.max_charges - -/obj/item/weapon/storage/belt/janitor - name = "janibelt" - desc = "A belt used to hold most janitorial supplies." - icon_state = "janibelt" - item_state = "janibelt" - storage_slots = 6 - max_w_class = WEIGHT_CLASS_BULKY // Set to this so the light replacer can fit. - can_hold = list( - /obj/item/weapon/grenade/chem_grenade, - /obj/item/device/lightreplacer, - /obj/item/device/flashlight, - /obj/item/weapon/reagent_containers/spray, - /obj/item/weapon/soap, - /obj/item/weapon/holosign_creator, - /obj/item/key/janitor, - /obj/item/clothing/gloves - ) - -/obj/item/weapon/storage/belt/bandolier - name = "bandolier" - desc = "A bandolier for holding shotgun ammunition." - icon_state = "bandolier" - item_state = "bandolier" - storage_slots = 18 - display_contents_with_number = TRUE - can_hold = list( - /obj/item/ammo_casing/shotgun - ) - -/obj/item/weapon/storage/belt/holster - name = "shoulder holster" - desc = "A holster to carry a handgun and ammo. WARNING: Badasses only." - icon_state = "holster" - item_state = "holster" - storage_slots = 3 - max_w_class = WEIGHT_CLASS_NORMAL - can_hold = list( - /obj/item/weapon/gun/ballistic/automatic/pistol, - /obj/item/weapon/gun/ballistic/revolver, - /obj/item/ammo_box, - ) - alternate_worn_layer = UNDER_SUIT_LAYER - -/obj/item/weapon/storage/belt/holster/full/PopulateContents() - new /obj/item/weapon/gun/ballistic/revolver/detective(src) - new /obj/item/ammo_box/c38(src) - new /obj/item/ammo_box/c38(src) - -/obj/item/weapon/storage/belt/fannypack - name = "fannypack" - desc = "A dorky fannypack for keeping small items in." - icon_state = "fannypack_leather" - item_state = "fannypack_leather" - storage_slots = 3 - max_w_class = WEIGHT_CLASS_SMALL - -/obj/item/weapon/storage/belt/fannypack/black - name = "black fannypack" - icon_state = "fannypack_black" - item_state = "fannypack_black" - -/obj/item/weapon/storage/belt/fannypack/red - name = "red fannypack" - icon_state = "fannypack_red" - item_state = "fannypack_red" - -/obj/item/weapon/storage/belt/fannypack/purple - name = "purple fannypack" - icon_state = "fannypack_purple" - item_state = "fannypack_purple" - -/obj/item/weapon/storage/belt/fannypack/blue - name = "blue fannypack" - icon_state = "fannypack_blue" - item_state = "fannypack_blue" - -/obj/item/weapon/storage/belt/fannypack/orange - name = "orange fannypack" - icon_state = "fannypack_orange" - item_state = "fannypack_orange" - -/obj/item/weapon/storage/belt/fannypack/white - name = "white fannypack" - icon_state = "fannypack_white" - item_state = "fannypack_white" - -/obj/item/weapon/storage/belt/fannypack/green - name = "green fannypack" - icon_state = "fannypack_green" - item_state = "fannypack_green" - -/obj/item/weapon/storage/belt/fannypack/pink - name = "pink fannypack" - icon_state = "fannypack_pink" - item_state = "fannypack_pink" - -/obj/item/weapon/storage/belt/fannypack/cyan - name = "cyan fannypack" - icon_state = "fannypack_cyan" - item_state = "fannypack_cyan" - -/obj/item/weapon/storage/belt/fannypack/yellow - name = "yellow fannypack" - icon_state = "fannypack_yellow" - item_state = "fannypack_yellow" - -/obj/item/weapon/storage/belt/sabre - name = "sabre sheath" - desc = "An ornate sheath designed to hold an officer's blade." - icon_state = "sheath" - item_state = "sheath" - storage_slots = 1 - rustle_jimmies = FALSE - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_BULKY - can_hold = list( - /obj/item/weapon/melee/sabre - ) - -/obj/item/weapon/storage/belt/sabre/examine(mob/user) - ..() - if(contents.len) - to_chat(user, "Alt-click it to quickly draw the blade.") - -/obj/item/weapon/storage/belt/sabre/AltClick(mob/user) - if(!ishuman(user) || !user.canUseTopic(src, be_close=TRUE)) - return - if(contents.len) - var/obj/item/I = contents[1] - user.visible_message("[user] takes [I] out of [src].", "You take [I] out of [src].",\ - ) - user.put_in_hands(I) - update_icon() - else - to_chat(user, "[src] is empty.") - -/obj/item/weapon/storage/belt/sabre/update_icon() - icon_state = "sheath" - item_state = "sheath" - if(contents.len) - icon_state += "-sabre" - item_state += "-sabre" - if(loc && isliving(loc)) - var/mob/living/L = loc - L.regenerate_icons() - ..() - - -/obj/item/weapon/storage/belt/sabre/PopulateContents() - new /obj/item/weapon/melee/sabre(src) - update_icon() diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index dffa22670c..fb5a4344f0 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -13,6 +13,7 @@ var/integrity_failure = 0 //0 if we have no special broken behavior var/resistance_flags = 0 // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF + var/can_be_hit = TRUE //can this be bludgeoned by items? var/acid_level = 0 //how much acid is on that obj @@ -51,7 +52,7 @@ T.add_blueprints_preround(src) /obj/Destroy(force=FALSE) - if(!istype(src, /obj/machinery)) + if(!ismachinery(src)) STOP_PROCESSING(SSobj, src) // TODO: Have a processing bitflag to reduce on unnecessary loops through the processing lists SStgui.close_uis(src) . = ..() diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index a597022448..1a5d0b78ec 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -38,10 +38,6 @@ if(istype(T, /turf/closed/mineral/random)) Spread(T) -/turf/closed/mineral/shuttleRotate(rotation) - setDir(angle2dir(rotation+dir2angle(dir))) - queue_smooth(src) - /turf/closed/mineral/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) if(turf_type) underlay_appearance.icon = initial(turf_type.icon) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index e354d26ab0..e81ab011e4 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -381,13 +381,10 @@ Traitors and the like can also be revived with the previous role mostly intact. switch(new_character.mind.special_role) if("Wizard") - new_character.loc = pick(GLOB.wizardstart) - //SSticker.mode.learn_basic_spells(new_character) + new_character.forceMove(pick(GLOB.wizardstart)) SSticker.mode.equip_wizard(new_character) if("Syndicate") - var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn") - if(synd_spawn) - new_character.loc = get_turf(synd_spawn) + new_character.forceMove(pick(GLOB.nukeop_start)) call(/datum/game_mode/proc/equip_syndicate)(new_character) if("Space Ninja") var/list/ninja_spawn = list() @@ -396,8 +393,7 @@ Traitors and the like can also be revived with the previous role mostly intact. var/datum/antagonist/ninja/ninjadatum = new_character.mind.has_antag_datum(ANTAG_DATUM_NINJA) ninjadatum.equip_space_ninja() if(ninja_spawn.len) - var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn) - new_character.loc = ninja_spawn_here.loc + new_character.forceMove(pick(ninja_spawn)) else//They may also be a cyborg or AI. switch(new_character.mind.assigned_role) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index ad1ba46d86..ac8349f5f7 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -119,9 +119,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) /datum/gas_mixture/proc/return_volume() //liters return max(0, volume) -/datum/gas_mixture/proc/thermal_energy() //joules - return temperature * heat_capacity() - /datum/gas_mixture/proc/archive() //Update archived versions of variables //Returns: 1 in all cases @@ -424,7 +421,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) var/list/cached_gases = gases var/temp = temperature - var/ener = thermal_energy() + var/ener = THERMAL_ENERGY(src) reaction_loop: for(var/r in SSair.gas_reactions) diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index a37e4d61c4..abbfcf8924 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -199,13 +199,13 @@ var/old_heat_capacity = air.heat_capacity() var/carbon_efficency = min(cached_gases["plasma"][MOLES]/cached_gases["co2"][MOLES],MAX_CARBON_EFFICENCY) - var/reaction_energy = air.thermal_energy() + var/reaction_energy = THERMAL_ENERGY(air) var/moles_impurities = air.total_moles()-(cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES]) var/plasma_fused = (PLASMA_FUSED_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY) var/carbon_catalyzed = (CARBON_CATALYST_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY) var/oxygen_added = carbon_catalyzed - var/nitrogen_added = (plasma_fused-oxygen_added)-(air.thermal_energy()/PLASMA_BINDING_ENERGY) + var/nitrogen_added = (plasma_fused-oxygen_added)-(THERMAL_ENERGY(air)/PLASMA_BINDING_ENERGY) reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0) diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index 11a7881a98..ad7fdb921a 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -232,7 +232,7 @@ total_gas_mixture.merge(G) - total_thermal_energy += G.thermal_energy() + total_thermal_energy += THERMAL_ENERGY(G) total_heat_capacity += G.heat_capacity() total_gas_mixture.temperature = total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0 diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 12f99f3c50..a46b32f853 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -60,10 +60,6 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation) return icon_state = "off" -//prevents shuttles attempting to rotate this since it messes up sprites -/obj/machinery/gateway/shuttleRotate() - return - /obj/machinery/gateway/attack_hand(mob/user) if(!detect()) return diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 38e0b0bd90..bcbeb55dd2 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -44,7 +44,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/inquisitive_ghost = 1 var/allow_midround_antag = 1 var/preferred_map = null - + var/pda_style = MONO + var/uses_glasses_colour = 0 var/screenshake = 100 @@ -446,6 +447,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Default"]
" dat += "Action Buttons: [(buttons_locked) ? "Locked In Place" : "Unlocked"]
" dat += "tgui Style: [(tgui_fancy) ? "Fancy" : "No Frills"]
" + dat += "PDA Style: [pda_style]
" dat += "tgui Monitors: [(tgui_lock) ? "Primary" : "All"]
" dat += "Window Flashing: [(windowflashing) ? "Yes" : "No"]
" dat += "Play admin midis: [(toggles & SOUND_MIDI) ? "Yes" : "No"]
" @@ -1449,6 +1451,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/pickedui = input(user, "Choose your UI style.", "Character Preference") as null|anything in list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative", "Clockwork") if(pickedui) UI_style = pickedui + if("PDA") + var/pickedPDA = input(user, "Choose your PDA style.", "Character Preference") as null|anything in list(MONO, SHARE, ORBITRON, VT) + if(pickedPDA) + pda_style = pickedPDA //citadel code if("cock_color") diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index d58d1cec77..dddac1e506 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -139,6 +139,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car features["vag_color"] = sanitize_hexcolor(features["vag_color"], 3, 0) //womb features features["has_womb"] = sanitize_integer(features["has_womb"], 0, 1, 0) + if(current_version < 19) + pda_style = "mono" /datum/preferences/proc/load_path(ckey,filename="preferences.sav") if(!ckey) @@ -193,6 +195,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["arousable"] >> arousable S["screenshake"] >> screenshake S["damagescreenshake"] >> damagescreenshake + S["pda_style"] >> pda_style //try to fix any outdated data if necessary if(needs_update >= 0) @@ -219,7 +222,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car be_special = SANITIZE_LIST(be_special) screenshake = sanitize_integer(screenshake, 0, 200, initial(screenshake)) damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) - + pda_style = sanitize_inlist(MONO, VT, SHARE, ORBITRON) return 1 @@ -263,6 +266,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["screenshake"], screenshake) WRITE_FILE(S["damagescreenshake"], damagescreenshake) WRITE_FILE(S["arousable"], arousable) + WRITE_FILE(S["pda_style"], pda_style) return 1 diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index d89671d06d..da4fe1cf5c 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -17,13 +17,25 @@ dog_fashion = /datum/dog_fashion/head/helmet - -/obj/item/clothing/head/helmet/Initialize() - . = ..() - /obj/item/clothing/head/helmet/sec can_flashlight = 1 +/obj/item/clothing/head/helmet/sec/attackby(obj/item/I, mob/user, params) + if(issignaler(I)) + var/obj/item/device/assembly/signaler/S = I + if(F) //Has a flashlight. Player must remove it, else it will be lost forever. + to_chat(user, "The mounted flashlight is in the way, remove it first!") + return + + if(S.secured) + qdel(S) + var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly + user.put_in_hands(A) + to_chat(user, "You add the signaler to the helmet.") + qdel(src) + return + return ..() + /obj/item/clothing/head/helmet/alt name = "bulletproof helmet" desc = "A bulletproof combat helmet that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent." @@ -281,7 +293,7 @@ qdel(THL) return - ..() + return ..() /obj/item/clothing/head/helmet/proc/toggle_helmlight() set name = "Toggle Helmetlight" diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 314f39f48b..4a86008ad2 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -1,179 +1,221 @@ -/* - * Contents: - * Welding mask - * Cakehat - * Ushanka - * Pumpkin head - * Kitty ears - * Cardborg disguise - */ - -/* - * Welding mask - */ -/obj/item/clothing/head/welding - name = "welding helmet" - desc = "A head-mounted face cover designed to protect the wearer completely from space-arc eye." - icon_state = "welding" - flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH - item_state = "welding" - materials = list(MAT_METAL=1750, MAT_GLASS=400) -// var/up = 0 - flash_protect = 2 - tint = 2 - armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 60) - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE - actions_types = list(/datum/action/item_action/toggle) - visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE - visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH - resistance_flags = FIRE_PROOF - -/obj/item/clothing/head/welding/attack_self(mob/user) - weldingvisortoggle(user) - - -/* - * Cakehat - */ -/obj/item/clothing/head/hardhat/cakehat - name = "cakehat" - desc = "You put the cake on your head. Brilliant." - icon_state = "hardhat0_cakehat" - item_state = "hardhat0_cakehat" - item_color = "cakehat" - hitsound = 'sound/weapons/tap.ogg' - flags_inv = HIDEEARS|HIDEHAIR - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) - brightness_on = 2 //luminosity when on - flags_cover = HEADCOVERSEYES - heat = 100 - -/obj/item/clothing/head/hardhat/cakehat/process() - var/turf/location = src.loc - if(ishuman(location)) - var/mob/living/carbon/human/M = location - if(M.is_holding(src) || M.head == src) - location = M.loc - - if(isturf(location)) - location.hotspot_expose(700, 1) - -/obj/item/clothing/head/hardhat/cakehat/turn_on() - ..() - force = 2 - throwforce = 2 - damtype = BURN - hitsound = 'sound/items/welder.ogg' - START_PROCESSING(SSobj, src) - -/obj/item/clothing/head/hardhat/cakehat/turn_off() - ..() - force = 0 - throwforce = 0 - damtype = BRUTE - hitsound = 'sound/weapons/tap.ogg' - STOP_PROCESSING(SSobj, src) - -/obj/item/clothing/head/hardhat/cakehat/is_hot() - return on * heat -/* - * Ushanka - */ -/obj/item/clothing/head/ushanka - name = "ushanka" - desc = "Perfect for winter in Siberia, da?" - icon_state = "ushankadown" - item_state = "ushankadown" - flags_inv = HIDEEARS|HIDEHAIR - var/earflaps = 1 - cold_protection = HEAD - min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT - - dog_fashion = /datum/dog_fashion/head/ushanka - -/obj/item/clothing/head/ushanka/attack_self(mob/user) - if(earflaps) - src.icon_state = "ushankaup" - src.item_state = "ushankaup" - earflaps = 0 - to_chat(user, "You raise the ear flaps on the ushanka.") - else - src.icon_state = "ushankadown" - src.item_state = "ushankadown" - earflaps = 1 - to_chat(user, "You lower the ear flaps on the ushanka.") - -/* - * Pumpkin head - */ -/obj/item/clothing/head/hardhat/pumpkinhead - name = "carved pumpkin" - desc = "A jack o' lantern! Believed to ward off evil spirits." - icon_state = "hardhat0_pumpkin" - item_state = "hardhat0_pumpkin" - item_color = "pumpkin" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) - brightness_on = 2 //luminosity when on - flags_cover = HEADCOVERSEYES - -/* - * Kitty ears - */ -/obj/item/clothing/head/kitty - name = "kitty ears" - desc = "A pair of kitty ears. Meow!" - icon_state = "kitty" - color = "#999999" - dynamic_hair_suffix = "" - - dog_fashion = /datum/dog_fashion/head/kitty - -/obj/item/clothing/head/kitty/equipped(mob/living/carbon/human/user, slot) - if(ishuman(user) && slot == slot_head) - update_icon(user) - user.update_inv_head() //Color might have been changed by update_icon. - ..() - -/obj/item/clothing/head/kitty/update_icon(mob/living/carbon/human/user) - if(ishuman(user)) - add_atom_colour("#[user.hair_color]", FIXED_COLOUR_PRIORITY) - -/obj/item/clothing/head/kitty/genuine - desc = "A pair of kitty ears. A tag on the inside says \"Hand made from real cats.\"" - - -/obj/item/clothing/head/hardhat/reindeer - name = "novelty reindeer hat" - desc = "Some fake antlers and a very fake red nose." - icon_state = "hardhat0_reindeer" - item_state = "hardhat0_reindeer" - item_color = "reindeer" - flags_inv = 0 - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) - brightness_on = 1 //luminosity when on - dynamic_hair_suffix = "" - - dog_fashion = /datum/dog_fashion/head/reindeer - -/obj/item/clothing/head/cardborg - name = "cardborg helmet" - desc = "A helmet made out of a box." - icon_state = "cardborg_h" - item_state = "cardborg_h" - flags_cover = HEADCOVERSEYES - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - - dog_fashion = /datum/dog_fashion/head/cardborg - -/obj/item/clothing/head/cardborg/equipped(mob/living/user, slot) - ..() - if(ishuman(user) && slot == slot_head) - var/mob/living/carbon/human/H = user - if(istype(H.wear_suit, /obj/item/clothing/suit/cardborg)) - var/obj/item/clothing/suit/cardborg/CB = H.wear_suit - CB.disguise(user, src) - -/obj/item/clothing/head/cardborg/dropped(mob/living/user) - ..() - user.remove_alt_appearance("standard_borg_disguise") +/* + * Contents: + * Welding mask + * Cakehat + * Ushanka + * Pumpkin head + * Kitty ears + * Cardborg disguise + */ + +/* + * Welding mask + */ +/obj/item/clothing/head/welding + name = "welding helmet" + desc = "A head-mounted face cover designed to protect the wearer completely from space-arc eye." + icon_state = "welding" + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + item_state = "welding" + materials = list(MAT_METAL=1750, MAT_GLASS=400) +// var/up = 0 + flash_protect = 2 + tint = 2 + armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 60) + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + actions_types = list(/datum/action/item_action/toggle) + visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + resistance_flags = FIRE_PROOF + +/obj/item/clothing/head/welding/attack_self(mob/user) + weldingvisortoggle(user) + + +/* + * Cakehat + */ +/obj/item/clothing/head/hardhat/cakehat + name = "cakehat" + desc = "You put the cake on your head. Brilliant." + icon_state = "hardhat0_cakehat" + item_state = "hardhat0_cakehat" + item_color = "cakehat" + hitsound = 'sound/weapons/tap.ogg' + flags_inv = HIDEEARS|HIDEHAIR + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + brightness_on = 2 //luminosity when on + flags_cover = HEADCOVERSEYES + heat = 1000 + +/obj/item/clothing/head/hardhat/cakehat/process() + var/turf/location = src.loc + if(ishuman(location)) + var/mob/living/carbon/human/M = location + if(M.is_holding(src) || M.head == src) + location = M.loc + + if(isturf(location)) + location.hotspot_expose(700, 1) + +/obj/item/clothing/head/hardhat/cakehat/turn_on() + ..() + force = 15 + throwforce = 15 + damtype = BURN + hitsound = 'sound/items/welder.ogg' + START_PROCESSING(SSobj, src) + +/obj/item/clothing/head/hardhat/cakehat/turn_off() + ..() + force = 0 + throwforce = 0 + damtype = BRUTE + hitsound = 'sound/weapons/tap.ogg' + STOP_PROCESSING(SSobj, src) + +/obj/item/clothing/head/hardhat/cakehat/is_hot() + return on * heat +/* + * Ushanka + */ +/obj/item/clothing/head/ushanka + name = "ushanka" + desc = "Perfect for winter in Siberia, da?" + icon_state = "ushankadown" + item_state = "ushankadown" + flags_inv = HIDEEARS|HIDEHAIR + var/earflaps = 1 + cold_protection = HEAD + min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + + dog_fashion = /datum/dog_fashion/head/ushanka + +/obj/item/clothing/head/ushanka/attack_self(mob/user) + if(earflaps) + src.icon_state = "ushankaup" + src.item_state = "ushankaup" + earflaps = 0 + to_chat(user, "You raise the ear flaps on the ushanka.") + else + src.icon_state = "ushankadown" + src.item_state = "ushankadown" + earflaps = 1 + to_chat(user, "You lower the ear flaps on the ushanka.") + +/* + * Pumpkin head + */ +/obj/item/clothing/head/hardhat/pumpkinhead + name = "carved pumpkin" + desc = "A jack o' lantern! Believed to ward off evil spirits." + icon_state = "hardhat0_pumpkin" + item_state = "hardhat0_pumpkin" + item_color = "pumpkin" + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + brightness_on = 2 //luminosity when on + flags_cover = HEADCOVERSEYES + +/* + * Kitty ears + */ +/obj/item/clothing/head/kitty + name = "kitty ears" + desc = "A pair of kitty ears. Meow!" + icon_state = "kitty" + color = "#999999" + dynamic_hair_suffix = "" + + dog_fashion = /datum/dog_fashion/head/kitty + +/obj/item/clothing/head/kitty/equipped(mob/living/carbon/human/user, slot) + if(ishuman(user) && slot == slot_head) + update_icon(user) + user.update_inv_head() //Color might have been changed by update_icon. + ..() + +/obj/item/clothing/head/kitty/update_icon(mob/living/carbon/human/user) + if(ishuman(user)) + add_atom_colour("#[user.hair_color]", FIXED_COLOUR_PRIORITY) + +/obj/item/clothing/head/kitty/genuine + desc = "A pair of kitty ears. A tag on the inside says \"Hand made from real cats.\"" + + +/obj/item/clothing/head/hardhat/reindeer + name = "novelty reindeer hat" + desc = "Some fake antlers and a very fake red nose." + icon_state = "hardhat0_reindeer" + item_state = "hardhat0_reindeer" + item_color = "reindeer" + flags_inv = 0 + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + brightness_on = 1 //luminosity when on + dynamic_hair_suffix = "" + + dog_fashion = /datum/dog_fashion/head/reindeer + +/obj/item/clothing/head/cardborg + name = "cardborg helmet" + desc = "A helmet made out of a box." + icon_state = "cardborg_h" + item_state = "cardborg_h" + flags_cover = HEADCOVERSEYES + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + + dog_fashion = /datum/dog_fashion/head/cardborg + +/obj/item/clothing/head/cardborg/equipped(mob/living/user, slot) + ..() + if(ishuman(user) && slot == slot_head) + var/mob/living/carbon/human/H = user + if(istype(H.wear_suit, /obj/item/clothing/suit/cardborg)) + var/obj/item/clothing/suit/cardborg/CB = H.wear_suit + CB.disguise(user, src) + +/obj/item/clothing/head/cardborg/dropped(mob/living/user) + ..() + user.remove_alt_appearance("standard_borg_disguise") + + + +/obj/item/clothing/head/wig + name = "wig" + desc = "A bunch of hair without a head attached." + icon_state = "" + item_state = "pwig" + flags_inv = HIDEHAIR + var/hair_style = "Very Long Hair" + var/hair_color = "#000" + +/obj/item/clothing/head/wig/Initialize(mapload) + . = ..() + update_icon() + +/obj/item/clothing/head/wig/update_icon() + cut_overlays() + var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style] + if(!S) + icon_state = "pwig" + else + var/mutable_appearance/M = mutable_appearance(S.icon,S.icon_state) + M.appearance_flags |= RESET_COLOR + M.color = hair_color + add_overlay(M) + +/obj/item/clothing/head/wig/worn_overlays(isinhands = FALSE, file2use) + . = list() + if(!isinhands) + var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style] + if(!S) + return + var/mutable_appearance/M = mutable_appearance(S.icon, S.icon_state,layer = -HAIR_LAYER) + M.appearance_flags |= RESET_COLOR + M.color = hair_color + . += M + +/obj/item/clothing/head/wig/random/Initialize(mapload) + hair_style = pick(GLOB.hair_styles_list - "Bald") //Don't want invisible wig + hair_color = "#[random_short_color()]" + . = ..() diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index dfc2421add..e15f54a500 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -4,7 +4,7 @@ icon_state = "chronohelmet" item_state = "chronohelmet" slowdown = 1 - armor = list(melee = 60, bullet = 30/*bullet through the visor*/, laser = 60, energy = 60, bomb = 30, bio = 90, rad = 90, fire = 100, acid = 100) + armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 30, bio = 90, rad = 90, fire = 100, acid = 100) resistance_flags = FIRE_PROOF | ACID_PROOF var/obj/item/clothing/suit/space/chronos/suit = null diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index c5af37506c..1136be711f 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -173,7 +173,7 @@ Contains: item_state = "ert_command" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list(melee = 30, bullet = 50, laser = 30, energy = 50, bomb = 50, bio = 100, rad = 100, fire = 0, acid = 95) + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100, fire = 80, acid = 80) slowdown = 0 strip_delay = 130 diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm index 11426a4e04..f5a5857fea 100644 --- a/code/modules/food_and_drinks/food/snacks_meat.dm +++ b/code/modules/food_and_drinks/food/snacks_meat.dm @@ -25,8 +25,8 @@ tastes = list("fish" = 1) foodtype = MEAT -/obj/item/reagent_containers/food/snacks/carpmeat/New() - ..() +/obj/item/reagent_containers/food/snacks/carpmeat/Initialize() + . = ..() eatverb = pick("bite","chew","choke down","gnaw","swallow","chomp") /obj/item/reagent_containers/food/snacks/carpmeat/imitation @@ -114,8 +114,8 @@ tastes = list("meat" = 1) foodtype = MEAT -/obj/item/reagent_containers/food/snacks/sausage/New() - ..() +/obj/item/reagent_containers/food/snacks/sausage/Initialize() + . = ..() eatverb = pick("bite","chew","nibble","deep throat","gobble","chomp") /obj/item/reagent_containers/food/snacks/kebab @@ -185,8 +185,8 @@ /obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand() visible_message("[src] expands!") - var/mob/spammer = get_mob_by_key(src.fingerprintslast) - var/mob/living/carbon/monkey/bananas = new(get_turf(src)) + var/mob/spammer = get_mob_by_key(fingerprintslast) + var/mob/living/carbon/monkey/bananas = new(drop_location()) bananas.log_message("Spawned via [src] at [COORD(src)], Last attached mob: [key_name(spammer)].", INDIVIDUAL_ATTACK_LOG) qdel(src) @@ -212,8 +212,8 @@ tastes = list("soy" = 1, "vegetables" = 1) foodtype = VEGETABLES -/obj/item/reagent_containers/food/snacks/stewedsoymeat/New() - ..() +/obj/item/reagent_containers/food/snacks/stewedsoymeat/Initialize() + . = ..() eatverb = pick("slurp","sip","suck","inhale","drink") /obj/item/reagent_containers/food/snacks/boiledspiderleg @@ -257,8 +257,8 @@ tastes = list("\"chicken\"" = 1) foodtype = MEAT -/obj/item/reagent_containers/food/snacks/nugget/New() - ..() +/obj/item/reagent_containers/food/snacks/nugget/Initialize() + . = ..() var/shape = pick("lump", "star", "lizard", "corgi") desc = "A 'chicken' nugget vaguely shaped like a [shape]." icon_state = "nugget_[shape]" diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index f6810d0b05..153444c0ed 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -83,7 +83,7 @@ a.popt {text-decoration: none;} #ping { position: fixed; top: 0; - right: 40px; + right: 80px; width: 45px; background: #ddd; height: 30px; @@ -96,12 +96,12 @@ a.popt {text-decoration: none;} font-size: 8pt; padding-top: 2px; } -#options { +#userBar { position: fixed; top: 0; right: 0; } -#options .optionsCell { +#userBar .subCell { background: #ddd; height: 30px; padding: 5px 0; @@ -111,23 +111,23 @@ a.popt {text-decoration: none;} line-height: 28px; border-top: 1px solid #b4b4b4; } -#options .optionsCell:hover {background: #ccc;} -#options .toggle { +#userBar .subCell:hover {background: #ccc;} +#userBar .toggle { width: 40px; background: #ccc; border-top: 0; float: right; text-align: center; } -#options .sub {clear: both; display: none; width: 160px;} -#options .sub.scroll {overflow-y: scroll;} -#options .sub.optionsCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} -#options .sub span { +#userBar .sub {clear: both; display: none; width: 160px;} +#userBar .sub.scroll {overflow-y: scroll;} +#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} +#userBar .sub span { display: block; line-height: 30px; float: left; } -#options .sub i { +#userBar .sub i { display: block; padding: 0 5px; font-size: 1.1em; @@ -136,14 +136,14 @@ a.popt {text-decoration: none;} line-height: 30px; float: right; } -#options .sub input { +#userBar .sub input { position: absolute; padding: 7px 5px; width: 121px; line-height: 30px; float: left; } -#options .decreaseFont {border-top: 0;} +#userBar .topCell {border-top: 0;} /* POPUPS */ .popup { diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index a9e30b6b51..7b2d3ecfe0 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -27,17 +27,22 @@ --ms +
+ +
- -
- Decrease font size - - Increase font size + - Toggle ping display - Highlight string - Save chat log - Clear all messages - Admin music volume -
+ +
+
+ Decrease font size - + Increase font size + + Toggle ping display + Highlight string + Save chat log + Clear all messages +
+
+ Admin music volume
diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index bb555982cc..f027b523aa 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -22,7 +22,7 @@ window.onerror = function(msg, url, line, col, error) { //Globals window.status = 'Output'; -var $messages, $subOptions, $contextMenu, $filterMessages; +var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages; var opts = { //General 'messageCount': 0, //A count...of messages... @@ -37,8 +37,8 @@ var opts = { 'restarting': false, //Is the round restarting? //Options menu - 'subOptionsLoop': null, //Contains the interval loop for closing the options menu - 'suppressOptionsClose': false, //Whether or not we should be hiding the suboptions menu + 'selectedSubLoop': null, //Contains the interval loop for closing the selected sub menu + 'suppressSubClose': false, //Whether or not we should be hiding the selected sub menu 'highlightTerms': [], 'highlightLimit': 5, 'highlightColor': '#FFFF00', //The color of the highlighted message @@ -483,6 +483,46 @@ function sendVolumeUpdate() { } } +function subSlideUp() { + $(this).removeClass('scroll'); + $(this).css('height', ''); +} + +function startSubLoop() { + if (opts.selectedSubLoop) { + clearInterval(opts.selectedSubLoop); + } + return setInterval(function() { + if (!opts.suppressSubClose && $selectedSub.is(':visible')) { + $selectedSub.slideUp('fast', subSlideUp); + clearInterval(opts.selectedSubLoop); + } + }, 5000); //every 5 seconds +} + +function handleToggleClick($sub, $toggle) { + if ($selectedSub !== $sub && $selectedSub.is(':visible')) { + $selectedSub.slideUp('fast', subSlideUp); + } + $selectedSub = $sub + if ($selectedSub.is(':visible')) { + $selectedSub.slideUp('fast', subSlideUp); + clearInterval(opts.selectedSubLoop); + } else { + $selectedSub.slideDown('fast', function() { + var windowHeight = $(window).height(); + var toggleHeight = $toggle.outerHeight(); + var priorSubHeight = $selectedSub.outerHeight(); + var newSubHeight = windowHeight - toggleHeight; + $(this).height(newSubHeight); + if (priorSubHeight > (windowHeight - toggleHeight)) { + $(this).addClass('scroll'); + } + }); + opts.selectedSubLoop = startSubLoop(); + } +} + /***************************************** * * DOM READY @@ -497,6 +537,8 @@ if (typeof $ === 'undefined') { $(function() { $messages = $('#messages'); $subOptions = $('#subOptions'); + $subAudio = $('#subAudio'); + $selectedSub = $subOptions; //Hey look it's a controller loop! setInterval(function() { @@ -607,12 +649,9 @@ $(function() { }); $messages.on('mousedown', function(e) { - if ($subOptions && $subOptions.is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); + if ($selectedSub && $selectedSub.is(':visible')) { + $selectedSub.slideUp('fast', subSlideUp); + clearInterval(opts.selectedSubLoop); } }); @@ -731,41 +770,19 @@ $(function() { }); $('#toggleOptions').click(function(e) { - if ($subOptions.is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); - } else { - $subOptions.slideDown('fast', function() { - var windowHeight = $(window).height(); - var toggleHeight = $('#toggleOptions').outerHeight(); - var priorSubHeight = $subOptions.outerHeight(); - var newSubHeight = windowHeight - toggleHeight; - $(this).height(newSubHeight); - if (priorSubHeight > (windowHeight - toggleHeight)) { - $(this).addClass('scroll'); - } - }); - opts.subOptionsLoop = setInterval(function() { - if (!opts.suppressOptionsClose && $('#subOptions').is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); - } - }, 5000); //Every 5 seconds - } + handleToggleClick($subOptions, $(this)); }); - $('#subOptions, #toggleOptions').mouseenter(function() { - opts.suppressOptionsClose = true; + $('#toggleAudio').click(function(e) { + handleToggleClick($subAudio, $(this)); }); - $('#subOptions, #toggleOptions').mouseleave(function() { - opts.suppressOptionsClose = false; + $('.sub, .toggle').mouseenter(function() { + opts.suppressSubClose = true; + }); + + $('.sub, .toggle').mouseleave(function() { + opts.suppressSubClose = false; }); $('#decreaseFont').click(function(e) { diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm index 272fb1c536..9da772eaee 100644 --- a/code/modules/holodeck/area_copy.dm +++ b/code/modules/holodeck/area_copy.dm @@ -31,7 +31,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list("tag","area","type","loc","locs", I.damtype = STAMINA // thou shalt not N.update_icon() - if(istype(O, /obj/machinery)) + if(ismachinery(O)) var/obj/machinery/M = O M.power_change() diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 1b21b88447..f2cdefa9a4 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -46,3 +46,64 @@ /obj/item/clothing/mask/gas/explorer/folded/New() ..() adjustmask() + +/obj/item/clothing/suit/space/hostile_environment + name = "H.E.C.K. suit" + desc = "Hostile Environiment Cross-Kinetic Suit: A suit designed to withstand the wide variety of hazards from Lavaland. It wasn't enough for its last owner." + icon_state = "hostile_env" + item_state = "hostile_env" + flags_1 = THICKMATERIAL_1 //not spaceproof + max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + resistance_flags = FIRE_PROOF | LAVA_PROOF + slowdown = 0 + armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/device/mining_scanner, /obj/item/device/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) + +/obj/item/clothing/suit/space/hostile_environment/Initialize() + . = ..() + AddComponent(/datum/component/spraycan_paintable) + START_PROCESSING(SSobj, src) + +/obj/item/clothing/suit/space/hostile_environment/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/clothing/suit/space/hostile_environment/process() + var/mob/living/carbon/C = loc + if(istype(C) && prob(2)) //cursed by bubblegum + if(prob(15)) + new /datum/hallucination/oh_yeah(C) + to_chat(C, "[pick("I AM IMMORTAL.","I SHALL TAKE BACK WHAT'S MINE.","I SEE YOU.","YOU CANNOT ESCAPE ME FOREVER.","DEATH CANNOT HOLD ME.")]") + else + to_chat(C, "[pick("You hear faint whispers.","You smell ash.","You feel hot.","You hear a roar in the distance.")]") + +/obj/item/clothing/head/helmet/space/hostile_environment + name = "H.E.C.K. helmet" + desc = "Hostile Environiment Cross-Kinetic Helmet: A helmet designed to withstand the wide variety of hazards from Lavaland. It wasn't enough for its last owner." + icon_state = "hostile_env" + item_state = "hostile_env" + w_class = WEIGHT_CLASS_NORMAL + max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + flags_1 = THICKMATERIAL_1 // no space protection + armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + resistance_flags = FIRE_PROOF | LAVA_PROOF + +/obj/item/clothing/head/helmet/space/hostile_environment/Initialize() + . = ..() + AddComponent(/datum/component/spraycan_paintable) + update_icon() + +/obj/item/clothing/head/helmet/space/hostile_environment/update_icon() + ..() + cut_overlays() + var/mutable_appearance/glass_overlay = mutable_appearance(icon, "hostile_env_glass") + glass_overlay.appearance_flags = RESET_COLOR + add_overlay(glass_overlay) + +/obj/item/clothing/head/helmet/space/hostile_environment/worn_overlays(isinhands) + . = ..() + if(!isinhands) + var/mutable_appearance/M = mutable_appearance('icons/mob/head.dmi', "hostile_env_glass") + M.appearance_flags = RESET_COLOR + . += M + diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 5b8c40a976..5fe25b1d1f 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -104,10 +104,6 @@ direction = expected_dir ..() -/obj/machinery/door/airlock/survival_pod/shuttleRotate(rotation) - expected_dir = angle2dir(rotation+dir2angle(dir)) - ..() - /obj/machinery/door/airlock/survival_pod/vertical dir = EAST expected_dir = EAST @@ -127,10 +123,6 @@ direction = expected_dir ..() -/obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation) - expected_dir = angle2dir(rotation+dir2angle(dir)) - ..() - /obj/structure/door_assembly/door_assembly_pod/vertical dir = EAST expected_dir = EAST @@ -307,7 +299,7 @@ /obj/item/melee/supermatter_sword, /obj/item/shield/changeling, /obj/item/lava_staff, - /obj/item/dash/energy_katana, + /obj/item/energy_katana, /obj/item/hierophant_club, /obj/item/his_grace, /obj/item/gun/ballistic/minigun, diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm index d72d0e5f73..28a946a56b 100644 --- a/code/modules/mining/equipment/wormhole_jaunter.dm +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -17,7 +17,7 @@ /obj/item/device/wormhole_jaunter/attack_self(mob/user) user.visible_message("[user.name] activates the [src.name]!") SSblackbox.add_details("jaunter", "User") // user activated - activate(user) + activate(user, TRUE) /obj/item/device/wormhole_jaunter/proc/turf_check(mob/user) var/turf/device_turf = get_turf(user) @@ -46,7 +46,7 @@ return destinations -/obj/item/device/wormhole_jaunter/proc/activate(mob/user) +/obj/item/device/wormhole_jaunter/proc/activate(mob/user, adjacent) if(!turf_check(user)) return @@ -56,7 +56,8 @@ return var/chosen_beacon = pick(L) var/obj/effect/portal/wormhole/jaunt_tunnel/J = new (get_turf(src), src, 100, null, FALSE, get_turf(chosen_beacon)) - try_move_adjacent(J) + if(adjacent) + try_move_adjacent(J) playsound(src,'sound/effects/sparks4.ogg',50,1) qdel(src) @@ -78,7 +79,7 @@ if(user.get_item_by_slot(slot_belt) == src) to_chat(user, "Your [src] activates, saving you from the chasm!") SSblackbox.add_details("jaunter","Chasm") // chasm automatic activation - activate(user) + activate(user, FALSE) else to_chat(user, "The [src] is not attached to your belt, preventing it from saving you from the chasm. RIP.") diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index e16077fec1..95c4898605 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -932,6 +932,8 @@ name = "bubblegum chest" /obj/structure/closet/crate/necropolis/bubblegum/PopulateContents() + new /obj/item/clothing/suit/space/hostile_environment(src) + new /obj/item/clothing/head/helmet/space/hostile_environment(src) var/loot = rand(1,3) switch(loot) if(1) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 6661beff6d..9aab9e54f1 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -79,9 +79,12 @@ if(SSticker.current_state == GAME_STATE_PREGAME) var/time_remaining = SSticker.GetTimeLeft() - if(time_remaining >= 0) - time_remaining /= 10 - stat("Time To Start:", (time_remaining >= 0) ? "[round(time_remaining)]s" : "DELAYED") + if(time_remaining > 0) + stat("Time To Start:", "[round(time_remaining/10)]s") + else if(time_remaining == -10) + stat("Time To Start:", "DELAYED") + else + stat("Time To Start:", "SOON") stat("Players:", "[SSticker.totalPlayers]") if(client.holder) @@ -273,7 +276,7 @@ observer.started_as_observer = TRUE close_spawn_windows() - var/obj/O = locate("landmark*Observer-Start") + var/obj/effect/landmark/observer_start/O = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list to_chat(src, "Now teleporting.") if (O) observer.loc = O.loc diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index db47d43bd5..bbe02a3f8e 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -1,493 +1,515 @@ -//The code execution of the emote datum is located at code/datums/emotes.dm -/mob/living/emote(act, m_type = null, message = null) - act = lowertext(act) - var/param = message - var/custom_param = findchar(act, " ") - if(custom_param) - param = copytext(act, custom_param + 1, length(act) + 1) - act = copytext(act, 1, custom_param) - - var/datum/emote/E - E = E.emote_list[act] - if(!E) - to_chat(src, "Unusable emote '[act]'. Say *help for a list.") - return - E.run_emote(src, param, m_type) - -/* EMOTE DATUMS */ -/datum/emote/living - mob_type_allowed_typecache = list(/mob/living) - mob_type_blacklist_typecache = list(/mob/living/simple_animal/slime, /mob/living/brain) - -/datum/emote/living/blush - key = "blush" - key_third_person = "blushes" - message = "blushes." - -/datum/emote/living/bow - key = "bow" - key_third_person = "bows" - message = "bows." - message_param = "bows to %t." - -/datum/emote/living/burp - key = "burp" - key_third_person = "burps" - message = "burps." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/choke - key = "choke" - key_third_person = "chokes" - message = "chokes!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/cross - key = "cross" - key_third_person = "crosses" - message = "crosses their arms." - restraint_check = TRUE - -/datum/emote/living/chuckle - key = "chuckle" - key_third_person = "chuckles" - message = "chuckles." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/collapse - key = "collapse" - key_third_person = "collapses" - message = "collapses!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/collapse/run_emote(mob/user, params) - . = ..() - if(. && isliving(user)) - var/mob/living/L = user - L.Unconscious(40) - -/datum/emote/living/cough - key = "cough" - key_third_person = "coughs" - message = "coughs!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/dance - key = "dance" - key_third_person = "dances" - message = "dances around happily." - restraint_check = TRUE - -/datum/emote/living/deathgasp - key = "deathgasp" - key_third_person = "deathgasps" - message = "seizes up and falls limp, their eyes dead and lifeless..." - message_robot = "shudders violently for a moment before falling still, its eyes slowly darkening." - message_AI = "lets out a flurry of sparks, its screen flickering as its systems slowly halt." - message_alien = "lets out a waning guttural screech, green blood bubbling from its maw..." - message_larva = "lets out a sickly hiss of air and falls limply to the floor..." - message_monkey = "lets out a faint chimper as it collapses and stops moving..." - message_simple = "stops moving..." - stat_allowed = UNCONSCIOUS - -/datum/emote/living/deathgasp/run_emote(mob/user, params) - var/mob/living/simple_animal/S = user - if(istype(S) && S.deathmessage) - message_simple = S.deathmessage - . = ..() - message_simple = initial(message_simple) - if(. && isalienadult(user)) - playsound(user.loc, 'sound/voice/hiss6.ogg', 80, 1, 1) - -/datum/emote/living/drool - key = "drool" - key_third_person = "drools" - message = "drools." - -/datum/emote/living/faint - key = "faint" - key_third_person = "faints" - message = "faints." - -/datum/emote/living/faint/run_emote(mob/user, params) - . = ..() - if(. && isliving(user)) - var/mob/living/L = user - L.SetSleeping(200) - -/datum/emote/living/flap - key = "flap" - key_third_person = "flaps" - message = "flaps their wings." - var/wing_time = 20 - -/datum/emote/living/flap/run_emote(mob/user, params) - . = ..() - if(. && ishuman(user)) - var/mob/living/carbon/human/H = user - var/open = FALSE - if(H.dna.features["wings"] != "None") - if("wingsopen" in H.dna.species.mutant_bodyparts) - open = TRUE - H.CloseWings() - else - H.OpenWings() - addtimer(CALLBACK(H, open ? /mob/living/carbon/human.proc/OpenWings : /mob/living/carbon/human.proc/CloseWings), wing_time) - -/datum/emote/living/flap/aflap - key = "aflap" - key_third_person = "aflaps" - message = "flaps their wings ANGRILY!" - wing_time = 10 - -/datum/emote/living/flip - key = "flip" - key_third_person = "flips" - restraint_check = TRUE - -/datum/emote/living/flip/run_emote(mob/user, params) - . = ..() - if(!.) - user.SpinAnimation(7,1) - -/datum/emote/living/frown - key = "frown" - key_third_person = "frowns" - message = "frowns." - -/datum/emote/living/gag - key = "gag" - key_third_person = "gags" - message = "gags." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/gasp - key = "gasp" - key_third_person = "gasps" - message = "gasps!" - emote_type = EMOTE_AUDIBLE - stat_allowed = UNCONSCIOUS - -/datum/emote/living/giggle - key = "giggle" - key_third_person = "giggles" - message = "giggles." - message_mime = "giggles silently!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/glare - key = "glare" - key_third_person = "glares" - message = "glares." - message_param = "glares at %t." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/grin - key = "grin" - key_third_person = "grins" - message = "grins." - -/datum/emote/living/groan - key = "groan" - key_third_person = "groans" - message = "groans!" - message_mime = "appears to groan!" - -/datum/emote/living/grimace - key = "grimace" - key_third_person = "grimaces" - message = "grimaces." - -/datum/emote/living/jump - key = "jump" - key_third_person = "jumps" - message = "jumps!" - restraint_check = TRUE - -/datum/emote/living/kiss - key = "kiss" - key_third_person = "kisses" - message = "blows a kiss." - message_param = "blows a kiss to %t." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/laugh - key = "laugh" - key_third_person = "laughs" - message = "laughs." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/look - key = "look" - key_third_person = "looks" - message = "looks." - message_param = "looks at %t." - -/datum/emote/living/nod - key = "nod" - key_third_person = "nods" - message = "nods." - message_param = "nods at %t." - -/datum/emote/living/point - key = "point" - key_third_person = "points" - message = "points." - message_param = "points at %t." - restraint_check = TRUE - -/datum/emote/living/pout - key = "pout" - key_third_person = "pouts" - message = "pouts." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/scream - key = "scream" - key_third_person = "screams" - message = "screams." - message_mime = "acts out a scream!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/scowl - key = "scowl" - key_third_person = "scowls" - message = "scowls." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/shake - key = "shake" - key_third_person = "shakes" - message = "shakes their head." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/shiver - key = "shiver" - key_third_person = "shiver" - message = "shivers." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/sigh - key = "sigh" - key_third_person = "sighs" - message = "sighs." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/sit - key = "sit" - key_third_person = "sits" - message = "sits down." - -/datum/emote/living/smile - key = "smile" - key_third_person = "smiles" - message = "smiles." - -/datum/emote/living/sneeze - key = "sneeze" - key_third_person = "sneezes" - message = "sneezes." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/smug - key = "smug" - key_third_person = "smugs" - message = "grins smugly." - -/datum/emote/living/sniff - key = "sniff" - key_third_person = "sniffs" - message = "sniffs." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/snore - key = "snore" - key_third_person = "snores" - message = "snores." - message_mime = "sleeps soundly." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/stare - key = "stare" - key_third_person = "stares" - message = "stares." - message_param = "stares at %t." - -/datum/emote/living/strech - key = "stretch" - key_third_person = "stretches" - message = "stretches their arms." - -/datum/emote/living/sulk - key = "sulk" - key_third_person = "sulks" - message = "sulks down sadly." - -/datum/emote/living/surrender - key = "surrender" - key_third_person = "surrenders" +//The code execution of the emote datum is located at code/datums/emotes.dm +/mob/living/emote(act, m_type = null, message = null) + act = lowertext(act) + var/param = message + var/custom_param = findchar(act, " ") + if(custom_param) + param = copytext(act, custom_param + 1, length(act) + 1) + act = copytext(act, 1, custom_param) + + var/datum/emote/E + E = E.emote_list[act] + if(!E) + to_chat(src, "Unusable emote '[act]'. Say *help for a list.") + return + E.run_emote(src, param, m_type) + +/* EMOTE DATUMS */ +/datum/emote/living + mob_type_allowed_typecache = list(/mob/living) + mob_type_blacklist_typecache = list(/mob/living/simple_animal/slime, /mob/living/brain) + +/datum/emote/living/blush + key = "blush" + key_third_person = "blushes" + message = "blushes." + +/datum/emote/living/bow + key = "bow" + key_third_person = "bows" + message = "bows." + message_param = "bows to %t." + restraint_check = TRUE + +/datum/emote/living/burp + key = "burp" + key_third_person = "burps" + message = "burps." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/choke + key = "choke" + key_third_person = "chokes" + message = "chokes!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/cross + key = "cross" + key_third_person = "crosses" + message = "crosses their arms." + restraint_check = TRUE + +/datum/emote/living/chuckle + key = "chuckle" + key_third_person = "chuckles" + message = "chuckles." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/collapse + key = "collapse" + key_third_person = "collapses" + message = "collapses!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/collapse/run_emote(mob/user, params) + . = ..() + if(. && isliving(user)) + var/mob/living/L = user + L.Unconscious(40) + +/datum/emote/living/cough + key = "cough" + key_third_person = "coughs" + message = "coughs!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/dance + key = "dance" + key_third_person = "dances" + message = "dances around happily." + restraint_check = TRUE + +/datum/emote/living/deathgasp + key = "deathgasp" + key_third_person = "deathgasps" + message = "seizes up and falls limp, their eyes dead and lifeless..." + message_robot = "shudders violently for a moment before falling still, its eyes slowly darkening." + message_AI = "lets out a flurry of sparks, its screen flickering as its systems slowly halt." + message_alien = "lets out a waning guttural screech, green blood bubbling from its maw..." + message_larva = "lets out a sickly hiss of air and falls limply to the floor..." + message_monkey = "lets out a faint chimper as it collapses and stops moving..." + message_simple = "stops moving..." + stat_allowed = UNCONSCIOUS + +/datum/emote/living/deathgasp/run_emote(mob/user, params) + var/mob/living/simple_animal/S = user + if(istype(S) && S.deathmessage) + message_simple = S.deathmessage + . = ..() + message_simple = initial(message_simple) + if(. && isalienadult(user)) + playsound(user.loc, 'sound/voice/hiss6.ogg', 80, 1, 1) + +/datum/emote/living/drool + key = "drool" + key_third_person = "drools" + message = "drools." + +/datum/emote/living/faint + key = "faint" + key_third_person = "faints" + message = "faints." + +/datum/emote/living/faint/run_emote(mob/user, params) + . = ..() + if(. && isliving(user)) + var/mob/living/L = user + L.SetSleeping(200) + +/datum/emote/living/flap + key = "flap" + key_third_person = "flaps" + message = "flaps their wings." + restraint_check = TRUE + var/wing_time = 20 + +/datum/emote/living/flap/run_emote(mob/user, params) + . = ..() + if(. && ishuman(user)) + var/mob/living/carbon/human/H = user + var/open = FALSE + if(H.dna.features["wings"] != "None") + if("wingsopen" in H.dna.species.mutant_bodyparts) + open = TRUE + H.CloseWings() + else + H.OpenWings() + addtimer(CALLBACK(H, open ? /mob/living/carbon/human.proc/OpenWings : /mob/living/carbon/human.proc/CloseWings), wing_time) + +/datum/emote/living/flap/aflap + key = "aflap" + key_third_person = "aflaps" + message = "flaps their wings ANGRILY!" + restraint_check = TRUE + wing_time = 10 + +/datum/emote/living/flip + key = "flip" + key_third_person = "flips" + restraint_check = TRUE + +/datum/emote/living/flip/run_emote(mob/user, params) + . = ..() + if(.) + user.SpinAnimation(7,1) + +/datum/emote/living/frown + key = "frown" + key_third_person = "frowns" + message = "frowns." + +/datum/emote/living/gag + key = "gag" + key_third_person = "gags" + message = "gags." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/gasp + key = "gasp" + key_third_person = "gasps" + message = "gasps!" + emote_type = EMOTE_AUDIBLE + stat_allowed = UNCONSCIOUS + +/datum/emote/living/giggle + key = "giggle" + key_third_person = "giggles" + message = "giggles." + message_mime = "giggles silently!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/glare + key = "glare" + key_third_person = "glares" + message = "glares." + message_param = "glares at %t." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/grin + key = "grin" + key_third_person = "grins" + message = "grins." + +/datum/emote/living/groan + key = "groan" + key_third_person = "groans" + message = "groans!" + message_mime = "appears to groan!" + +/datum/emote/living/grimace + key = "grimace" + key_third_person = "grimaces" + message = "grimaces." + +/datum/emote/living/jump + key = "jump" + key_third_person = "jumps" + message = "jumps!" + restraint_check = TRUE + +/datum/emote/living/kiss + key = "kiss" + key_third_person = "kisses" + message = "blows a kiss." + message_param = "blows a kiss to %t." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/laugh + key = "laugh" + key_third_person = "laughs" + message = "laughs." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/laugh/can_run_emote(mob/living/user) + . = ..() + if(. && iscarbon(user)) + var/mob/living/carbon/C = user + return !C.silent + +/datum/emote/living/laugh/run_emote(mob/user, params) + . = ..() + if(. && ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.dna.species.id == "human") + if(user.gender == FEMALE) + playsound(H, 'sound/voice/human/womanlaugh.ogg', 50, 1) + else + playsound(H, pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg'), 50, 1) + +/datum/emote/living/look + key = "look" + key_third_person = "looks" + message = "looks." + message_param = "looks at %t." + +/datum/emote/living/nod + key = "nod" + key_third_person = "nods" + message = "nods." + message_param = "nods at %t." + +/datum/emote/living/point + key = "point" + key_third_person = "points" + message = "points." + message_param = "points at %t." + restraint_check = TRUE + +/datum/emote/living/pout + key = "pout" + key_third_person = "pouts" + message = "pouts." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/scream + key = "scream" + key_third_person = "screams" + message = "screams." + message_mime = "acts out a scream!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/scowl + key = "scowl" + key_third_person = "scowls" + message = "scowls." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/shake + key = "shake" + key_third_person = "shakes" + message = "shakes their head." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/shiver + key = "shiver" + key_third_person = "shiver" + message = "shivers." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/sigh + key = "sigh" + key_third_person = "sighs" + message = "sighs." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/sit + key = "sit" + key_third_person = "sits" + message = "sits down." + +/datum/emote/living/smile + key = "smile" + key_third_person = "smiles" + message = "smiles." + +/datum/emote/living/sneeze + key = "sneeze" + key_third_person = "sneezes" + message = "sneezes." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/smug + key = "smug" + key_third_person = "smugs" + message = "grins smugly." + +/datum/emote/living/sniff + key = "sniff" + key_third_person = "sniffs" + message = "sniffs." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/snore + key = "snore" + key_third_person = "snores" + message = "snores." + message_mime = "sleeps soundly." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/stare + key = "stare" + key_third_person = "stares" + message = "stares." + message_param = "stares at %t." + +/datum/emote/living/strech + key = "stretch" + key_third_person = "stretches" + message = "stretches their arms." + +/datum/emote/living/sulk + key = "sulk" + key_third_person = "sulks" + message = "sulks down sadly." + +/datum/emote/living/surrender + key = "surrender" + key_third_person = "surrenders" message = "puts their hands on their head and falls to the ground, they surrender!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/surrender/run_emote(mob/user, params) - . = ..() - if(. && isliving(user)) - var/mob/living/L = user - L.Knockdown(200) - -/datum/emote/living/sway - key = "sway" - key_third_person = "sways" - message = "sways around dizzily." - -/datum/emote/living/tremble - key = "tremble" - key_third_person = "trembles" - message = "trembles in fear!" - -/datum/emote/living/twitch - key = "twitch" - key_third_person = "twitches" - message = "twitches violently." - -/datum/emote/living/twitch_s - key = "twitch_s" - message = "twitches." - -/datum/emote/living/wave - key = "wave" - key_third_person = "waves" - message = "waves." - -/datum/emote/living/whimper - key = "whimper" - key_third_person = "whimpers" - message = "whimpers." - message_mime = "appears hurt." - -/datum/emote/living/wsmile - key = "wsmile" - key_third_person = "wsmiles" - message = "smiles weakly." - -/datum/emote/living/yawn - key = "yawn" - key_third_person = "yawns" - message = "yawns." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/custom - key = "me" - key_third_person = "custom" - message = null - -/datum/emote/living/custom/proc/check_invalid(mob/user, input) - . = TRUE - if(copytext(input,1,5) == "says") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,9) == "exclaims") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,6) == "yells") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,5) == "asks") - to_chat(user, "Invalid emote.") - else - . = FALSE - -/datum/emote/living/custom/run_emote(mob/user, params, type_override = null) - if(jobban_isbanned(user, "emote")) - to_chat(user, "You cannot send custom emotes (banned).") - return FALSE - else if(user.client && user.client.prefs.muted & MUTE_IC) - to_chat(user, "You cannot send IC messages (muted).") - return FALSE - else if(!params) - var/custom_emote = copytext(sanitize(input("Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN) - if(custom_emote && !check_invalid(user, custom_emote)) - var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable") - switch(type) - if("Visible") - emote_type = EMOTE_VISIBLE - if("Hearable") - emote_type = EMOTE_AUDIBLE - else - alert("Unable to use this emote, must be either hearable or visible.") - return - message = custom_emote - else - message = params - if(type_override) - emote_type = type_override - . = ..() - message = null - emote_type = EMOTE_VISIBLE - -/datum/emote/living/custom/replace_pronoun(mob/user, message) - return message - -/datum/emote/living/help - key = "help" - -/datum/emote/living/help/run_emote(mob/user, params) - var/list/keys = list() - var/list/message = list("Available emotes, you can use them with say \"*emote\": ") - - var/datum/emote/E - var/list/emote_list = E.emote_list - for(var/e in emote_list) - if(e in keys) - continue - E = emote_list[e] - if(E.can_run_emote(user, TRUE)) - keys += E.key - - keys = sortList(keys) - - for(var/emote in keys) - if(LAZYLEN(message) > 1) - message += ", [emote]" - else - message += "[emote]" - - message += "." - - message = jointext(message, "") - - to_chat(user, message) - -/datum/emote/sound/beep - key = "beep" - key_third_person = "beeps" - message = "beeps." - message_param = "beeps at %t." - sound = 'sound/machines/twobeep.ogg' - -/datum/emote/living/spin - key = "spin" - key_third_person = "spins" - -/datum/emote/living/spin/run_emote(mob/user) - user.spin(20, 1) - if(iscyborg(user)) - var/mob/living/silicon/robot/R = user - if(R.buckled_mobs) - for(var/mob/M in R.buckled_mobs) - if(R.riding_datum) - R.riding_datum.force_dismount(M) - else - R.unbuckle_all_mobs() - ..() - -/datum/emote/living/circle - key = "circle" - key_third_person = "circles" - restraint_check = TRUE - -/datum/emote/living/circle/run_emote(mob/user, params) - . = ..() - var/obj/item/circlegame/N = new(user) - if(user.put_in_hands(N)) - to_chat(user, "You make a circle with your hand.") - else - qdel(N) - to_chat(user, "You don't have any free hands to make a circle with.") + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/surrender/run_emote(mob/user, params) + . = ..() + if(. && isliving(user)) + var/mob/living/L = user + L.Knockdown(200) + +/datum/emote/living/sway + key = "sway" + key_third_person = "sways" + message = "sways around dizzily." + +/datum/emote/living/tremble + key = "tremble" + key_third_person = "trembles" + message = "trembles in fear!" + +/datum/emote/living/twitch + key = "twitch" + key_third_person = "twitches" + message = "twitches violently." + +/datum/emote/living/twitch_s + key = "twitch_s" + message = "twitches." + +/datum/emote/living/wave + key = "wave" + key_third_person = "waves" + message = "waves." + +/datum/emote/living/whimper + key = "whimper" + key_third_person = "whimpers" + message = "whimpers." + message_mime = "appears hurt." + +/datum/emote/living/wsmile + key = "wsmile" + key_third_person = "wsmiles" + message = "smiles weakly." + +/datum/emote/living/yawn + key = "yawn" + key_third_person = "yawns" + message = "yawns." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/custom + key = "me" + key_third_person = "custom" + message = null + +/datum/emote/living/custom/proc/check_invalid(mob/user, input) + . = TRUE + if(copytext(input,1,5) == "says") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,9) == "exclaims") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,6) == "yells") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,5) == "asks") + to_chat(user, "Invalid emote.") + else + . = FALSE + +/datum/emote/living/custom/run_emote(mob/user, params, type_override = null) + if(jobban_isbanned(user, "emote")) + to_chat(user, "You cannot send custom emotes (banned).") + return FALSE + else if(user.client && user.client.prefs.muted & MUTE_IC) + to_chat(user, "You cannot send IC messages (muted).") + return FALSE + else if(!params) + var/custom_emote = copytext(sanitize(input("Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN) + if(custom_emote && !check_invalid(user, custom_emote)) + var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable") + switch(type) + if("Visible") + emote_type = EMOTE_VISIBLE + if("Hearable") + emote_type = EMOTE_AUDIBLE + else + alert("Unable to use this emote, must be either hearable or visible.") + return + message = custom_emote + else + message = params + if(type_override) + emote_type = type_override + . = ..() + message = null + emote_type = EMOTE_VISIBLE + +/datum/emote/living/custom/replace_pronoun(mob/user, message) + return message + +/datum/emote/living/help + key = "help" + +/datum/emote/living/help/run_emote(mob/user, params) + var/list/keys = list() + var/list/message = list("Available emotes, you can use them with say \"*emote\": ") + + var/datum/emote/E + var/list/emote_list = E.emote_list + for(var/e in emote_list) + if(e in keys) + continue + E = emote_list[e] + if(E.can_run_emote(user, status_check = FALSE)) + keys += E.key + + keys = sortList(keys) + + for(var/emote in keys) + if(LAZYLEN(message) > 1) + message += ", [emote]" + else + message += "[emote]" + + message += "." + + message = jointext(message, "") + + to_chat(user, message) + +/datum/emote/sound/beep + key = "beep" + key_third_person = "beeps" + message = "beeps." + message_param = "beeps at %t." + sound = 'sound/machines/twobeep.ogg' + +/datum/emote/living/spin + key = "spin" + key_third_person = "spins" + restraint_check = TRUE + +/datum/emote/living/spin/run_emote(mob/user) + . = ..() + if(.) + user.spin(20, 1) + if(iscyborg(user)) + var/mob/living/silicon/robot/R = user + if(R.buckled_mobs) + for(var/mob/M in R.buckled_mobs) + if(R.riding_datum) + R.riding_datum.force_dismount(M) + else + R.unbuckle_all_mobs() + + +/datum/emote/living/circle + key = "circle" + key_third_person = "circles" + restraint_check = TRUE + +/datum/emote/living/circle/run_emote(mob/user, params) + . = ..() + var/obj/item/circlegame/N = new(user) + if(user.put_in_hands(N)) + to_chat(user, "You make a circle with your hand.") + else + qdel(N) + to_chat(user, "You don't have any free hands to make a circle with.") diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 0d1f346dcf..c53925e076 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -357,28 +357,6 @@ var/build_step = 0 var/created_name = "Securitron" //To preserve the name if it's a unique securitron I guess -/obj/item/clothing/head/helmet/attackby(obj/item/device/assembly/signaler/S, mob/user, params) - ..() - if(!issignaler(S)) - ..() - return - - if(type != /obj/item/clothing/head/helmet/sec) //Eh, but we don't want people making secbots out of space helmets. - return - - if(F) //Has a flashlight. Player must remove it, else it will be lost forever. - to_chat(user, "The mounted flashlight is in the way, remove it first!") - return - - if(S.secured) - qdel(S) - var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly - user.put_in_hands(A) - to_chat(user, "You add the signaler to the helmet.") - qdel(src) - else - return - /obj/item/secbot_assembly/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/weldingtool)) diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index e5ee4f671c..aa288e52d7 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -275,7 +275,7 @@ if(O.anchored) continue - if(isitem(O) || isstructure(O) || istype(O, /obj/machinery)) + if(isitem(O) || isstructure(O) || ismachinery(O)) cocoon_target = O busy = MOVING_TO_TARGET stop_automated_movement = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index b46000c339..edcf1a0f73 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -144,7 +144,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca icon_living = icon_state copy_overlays(O) add_overlay(googly_eyes) - if(isstructure(O) || istype(O, /obj/machinery)) + if(isstructure(O) || ismachinery(O)) health = (anchored * 50) + 50 destroy_objects = 1 if(O.density && O.anchored) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 4edf7a6dcb..d4b2c8f7c6 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -101,13 +101,6 @@ init_belly() verbs |= /mob/living/proc/animal_nom - -/mob/living/simple_animal/Login() - if(src && src.client) - src.client.screen = list() - client.screen += client.void - ..() - /mob/living/simple_animal/updatehealth() ..() health = Clamp(health, 0, maxHealth) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c75e0a27fb..4165651dbd 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -743,10 +743,6 @@ mob_spell_list -= S qdel(S) -//override to avoid rotating pixel_xy on mobs -/mob/shuttleRotate(rotation) - setDir(angle2dir(rotation+dir2angle(dir))) - //You can buckle on mobs if you're next to them since most are dense /mob/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) if(M.buckled) diff --git a/code/modules/modular_computers/hardware/recharger.dm b/code/modules/modular_computers/hardware/recharger.dm index 08ecc6e8c8..7096233d3a 100644 --- a/code/modules/modular_computers/hardware/recharger.dm +++ b/code/modules/modular_computers/hardware/recharger.dm @@ -31,7 +31,7 @@ origin_tech = "programming=2;engineering=2;powerstorage=3" /obj/item/computer_hardware/recharger/APC/use_power(amount, charging=0) - if(istype(holder.physical, /obj/machinery)) + if(ismachinery(holder.physical)) var/obj/machinery/M = holder.physical if(M.powered()) M.use_power(amount) @@ -55,13 +55,13 @@ origin_tech = "engineering=2;powerstorage=1" /obj/item/computer_hardware/recharger/wired/can_install(obj/item/device/modular_computer/M, mob/living/user = null) - if(istype(M.physical, /obj/machinery) && M.physical.anchored) + if(ismachinery(M.physical) && M.physical.anchored) return ..() to_chat(user, "\The [src] is incompatible with portable computers!") return 0 /obj/item/computer_hardware/recharger/wired/use_power(amount, charging=0) - if(istype(holder.physical, /obj/machinery) && holder.physical.anchored) + if(ismachinery(holder.physical) && holder.physical.anchored) var/obj/machinery/M = holder.physical var/turf/T = M.loc if(!T || !istype(T)) diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm index 8901c1b9fa..5a65a58d76 100644 --- a/code/modules/ninja/energy_katana.dm +++ b/code/modules/ninja/energy_katana.dm @@ -1,60 +1,4 @@ -/obj/item/dash - name = "abstract dash weapon" - var/max_charges = 3 - var/current_charges = 3 - var/charge_rate = 30 //In deciseconds - var/dash_toggled = TRUE - - var/bypass_density = FALSE //Can we beam past windows/airlocks/etc - - var/start_effect_type = /obj/effect/temp_visual/dir_setting/ninja/phase/out - var/end_effect_type = /obj/effect/temp_visual/dir_setting/ninja/phase - var/beam_icon_state = "blur" - var/dash_beam_type = /obj/effect/ebeam - -/obj/item/dash/proc/charge() - current_charges = Clamp(current_charges + 1, 0, max_charges) - if(istype(loc, /mob/living)) - to_chat(loc, "[src] now has [current_charges]/[max_charges] charges.") - -/obj/item/dash/attack_self(mob/user) - dash_toggled = !dash_toggled - to_chat(user, "You [dash_toggled ? "enable" : "disable"] the dash function on [src].") - -/obj/item/dash/afterattack(atom/target, mob/user, proximity_flag, click_parameters) - if(dash_toggled) - dash(user, target) - return - -/obj/item/dash/proc/dash(mob/user, atom/target) - if(!current_charges) - return - - if(Adjacent(target)) - return - - if(target.density) - return - - var/turf/T = get_turf(target) - - if(!bypass_density) - for(var/turf/turf in getline(get_turf(user),T)) - for(var/atom/A in turf) - if(A.density) - return - - if(target in view(user.client.view, get_turf(user))) - var/obj/spot1 = new start_effect_type(T, user.dir) - user.forceMove(T) - playsound(T, 'sound/magic/blink.ogg', 25, 1) - playsound(T, "sparks", 50, 1) - var/obj/spot2 = new end_effect_type(get_turf(user), user.dir) - spot1.Beam(spot2, beam_icon_state,time = 2, maxdistance = 20, beam_type = dash_beam_type) - current_charges-- - addtimer(CALLBACK(src, .proc/charge), charge_rate) - -/obj/item/dash/energy_katana +/obj/item/energy_katana name = "energy katana" desc = "A katana infused with strong energy." icon_state = "energy_katana" @@ -73,23 +17,41 @@ sharpness = IS_SHARP max_integrity = 200 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - bypass_density = TRUE var/datum/effect_system/spark_spread/spark_system + var/datum/action/innate/dash/ninja/jaunt + var/dash_toggled = TRUE -/obj/item/dash/energy_katana/afterattack(atom/target, mob/user, proximity_flag, click_parameters) +/obj/item/energy_katana/Initialize() + . = ..() + jaunt = new(src) + spark_system = new /datum/effect_system/spark_spread() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + +/obj/item/energy_katana/afterattack(atom/target, mob/user, proximity_flag, click_parameters) if(dash_toggled) - return ..() + jaunt.Teleport(user, target) if(proximity_flag && (isobj(target) || issilicon(target))) spark_system.start() playsound(user, "sparks", 50, 1) playsound(user, 'sound/weapons/blade1.ogg', 50, 1) target.emag_act(user) +/obj/item/energy_katana/pickup(mob/living/user) + . = ..() + jaunt.Grant(user, src) + user.update_icons() + playsound(src, 'sound/items/unsheath.ogg', 25, 1) + +/obj/item/energy_katana/dropped(mob/user) + . = ..() + jaunt.Remove(user) + user.update_icons() //If we hit the Ninja who owns this Katana, they catch it. //Works for if the Ninja throws it or it throws itself or someone tries //To throw it at the ninja -/obj/item/dash/energy_katana/throw_impact(atom/hit_atom) +/obj/item/energy_katana/throw_impact(atom/hit_atom) if(ishuman(hit_atom)) var/mob/living/carbon/human/H = hit_atom if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) @@ -100,7 +62,7 @@ ..() -/obj/item/dash/energy_katana/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0) +/obj/item/energy_katana/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0) if(!istype(user)) return forceMove(get_turf(user)) @@ -127,12 +89,15 @@ if(msg) to_chat(user, "[msg]") -/obj/item/dash/energy_katana/Initialize() - . = ..() - spark_system = new /datum/effect_system/spark_spread() - spark_system.set_up(5, 0, src) - spark_system.attach(src) -/obj/item/dash/energy_katana/Destroy() +/obj/item/energy_katana/Destroy() QDEL_NULL(spark_system) return ..() + +/datum/action/innate/dash/ninja + current_charges = 3 + max_charges = 3 + charge_rate = 30 + recharge_sound = null + + diff --git a/code/modules/ninja/outfit.dm b/code/modules/ninja/outfit.dm index 4ec9cde23c..2fd732f0ce 100644 --- a/code/modules/ninja/outfit.dm +++ b/code/modules/ninja/outfit.dm @@ -12,7 +12,7 @@ l_pocket = /obj/item/grenade/plastic/x4 r_pocket = /obj/item/tank/internals/emergency_oxygen internals_slot = slot_r_store - belt = /obj/item/dash/energy_katana + belt = /obj/item/energy_katana implants = list(/obj/item/implant/explosive) diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 40d18951e6..1dcfed99c0 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -30,7 +30,7 @@ Contents: var/datum/effect_system/spark_spread/spark_system var/list/stored_research = list()//For stealing station research. var/obj/item/disk/tech_disk/t_disk//To copy design onto disk. - var/obj/item/dash/energy_katana/energyKatana //For teleporting the katana back to the ninja (It's an ability) + var/obj/item/energy_katana/energyKatana //For teleporting the katana back to the ninja (It's an ability) //Other articles of ninja gear worn together, used to easily reference them after initializing. var/obj/item/clothing/head/helmet/space/space_ninja/n_hood diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 37ec831462..503eb88cd2 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -437,21 +437,6 @@ By design, d1 is the smallest direction and d2 is the highest if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to P.disconnect_from_network() //remove from current network -/obj/structure/cable/shuttleRotate(rotation) - //..() is not called because wires are not supposed to have a non-default direction - //Rotate connections - if(d1) - d1 = angle2dir(rotation+dir2angle(d1)) - if(d2) - d2 = angle2dir(rotation+dir2angle(d2)) - - //d1 should be less than d2 for cable icons to work - if(d1 > d2) - var/temp = d1 - d1 = d2 - d2 = temp - update_icon() - /////////////////////////////////////////////// // The cable coil object, used for laying cable diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 346ede4eb8..3ad3f6bc13 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -48,10 +48,6 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne ..() icon_state = "[get_status()]_[sprite_number]" -//prevents shuttles attempting to rotate this since it messes up sprites -/obj/machinery/gravity_generator/shuttleRotate() - return - /obj/machinery/gravity_generator/proc/get_status() return "off" diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index f2610f97b0..f4d09167c8 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -58,7 +58,7 @@ if(isliving(mover)) shock(mover) - if(istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover)) + if(ismachinery(mover) || isstructure(mover) || ismecha(mover)) bump_field(mover) /obj/machinery/field/containment/proc/set_master(master1,master2) @@ -90,13 +90,13 @@ if(isliving(mover)) shock(mover) return - if(istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover)) + if(ismachinery(mover) || isstructure(mover) || ismecha(mover)) bump_field(mover) return /obj/machinery/field/CanPass(atom/movable/mover, turf/target) - if(hasShocked || isliving(mover) || istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover)) + if(hasShocked || isliving(mover) || ismachinery(mover) || isstructure(mover) || ismecha(mover)) return FALSE return ..() diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index d8d396d311..503196aa4e 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -222,7 +222,7 @@ else if(closest_mob) continue - else if(istype(A, /obj/machinery)) + else if(ismachinery(A)) var/obj/machinery/M = A var/dist = get_dist(source, A) if(dist <= zap_range && (dist < closest_dist || !closest_machine) && !M.being_shocked) diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 8395ef4d83..cf38d5bfff 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -8,7 +8,7 @@ hitsound_wall = "ricochet" impact_effect_type = /obj/effect/temp_visual/impact_effect -/obj/item/projectile/bullet/pellet/Range() +/obj/item/projectile/bullet/pellet/shotgun_buckshot/Range() ..() damage -= 0.75 if(damage < 0) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 9bcd909faf..eeb5016445 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -11,14 +11,11 @@ var/last_tick = 1 var/addiction_tick = 1 var/list/datum/reagent/addiction_list = new/list() - var/flags_1 + var/flags /datum/reagents/New(maximum=100) maximum_volume = maximum - if(!(flags_1 & REAGENT_NOREACT)) - START_PROCESSING(SSobj, src) - //I dislike having these here but map-objects are initialised before world/New() is called. >_> if(!GLOB.chemical_reagents_list) //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id @@ -54,7 +51,6 @@ /datum/reagents/Destroy() . = ..() - STOP_PROCESSING(SSobj, src) var/list/cached_reagents = reagent_list for(var/reagent in cached_reagents) var/datum/reagent/R = reagent @@ -288,25 +284,11 @@ C.update_stamina() update_total() -/datum/reagents/process() - var/list/cached_reagents = reagent_list - if(flags_1 & REAGENT_NOREACT) - STOP_PROCESSING(SSobj, src) - return - - for(var/reagent in cached_reagents) - var/datum/reagent/R = reagent - R.on_tick() - /datum/reagents/proc/set_reacting(react = TRUE) if(react) - // Order is important, process() can remove from processing if - // the flag is present - flags_1 &= ~(REAGENT_NOREACT) - START_PROCESSING(SSobj, src) + flags &= ~(REAGENT_NOREACT) else - STOP_PROCESSING(SSobj, src) - flags_1 |= REAGENT_NOREACT + flags |= REAGENT_NOREACT /datum/reagents/proc/conditional_update_move(atom/A, Running = 0) var/list/cached_reagents = reagent_list @@ -326,7 +308,7 @@ var/list/cached_reagents = reagent_list var/list/cached_reactions = GLOB.chemical_reactions_list var/datum/cached_my_atom = my_atom - if(flags_1 & REAGENT_NOREACT) + if(flags & REAGENT_NOREACT) return //Yup, no reactions here. No siree. var/reaction_occurred = 0 diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 342e2154f8..5f76a87654 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -80,10 +80,6 @@ /datum/reagent/proc/on_update(atom/A) return -// Called every time reagent containers process. -/datum/reagent/proc/on_tick(data) - return - // Called when the reagent container is hit by an explosion /datum/reagent/proc/on_ex_act(severity) return diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index a3db8f7bc2..308fd47a16 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -169,18 +169,7 @@ /datum/reagent/consumable/laughter/on_mob_life(mob/living/carbon/M) if(!iscarbon(M)) return - if(!M.silent)//cant laugh if you're mute - M.emote("laugh") - var/laughnum = rand(1,2) - if(M.gender == MALE) - if(laughnum == 1) - playsound(get_turf(M), 'sound/voice/human/manlaugh1.ogg', 50, 1) - if(laughnum == 2) - playsound(get_turf(M), 'sound/voice/human/manlaugh2.ogg', 50, 1) - else if(M.gender == FEMALE) - playsound(get_turf(M), 'sound/voice/human/womanlaugh.ogg', 65, 1) - else//non-binary gender just sounds like a man - playsound(get_turf(M), 'sound/voice/human/manlaugh1.ogg', 50, 1) + M.emote("laugh") ..() /datum/reagent/consumable/potato_juice diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index 36320459e8..4c1965058c 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -196,13 +196,6 @@ M.bodytemperature -= 15 ..() -/datum/reagent/cryostylane/on_tick() - if(holder.has_reagent("oxygen")) - holder.remove_reagent("oxygen", 1) - holder.chem_temp -= 10 - holder.handle_reactions() - ..() - /datum/reagent/cryostylane/reaction_turf(turf/T, reac_volume) if(reac_volume >= 5) for(var/mob/living/simple_animal/slime/M in T) @@ -222,13 +215,6 @@ M.bodytemperature += 15 ..() -/datum/reagent/pyrosium/on_tick() - if(holder.has_reagent("oxygen")) - holder.remove_reagent("oxygen", 1) - holder.chem_temp += 10 - holder.handle_reactions() - ..() - /datum/reagent/teslium //Teslium. Causes periodic shocks, and makes shocks against the target much more effective. name = "Teslium" id = "teslium" diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 8ca65a6588..aa97dd3180 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -342,6 +342,23 @@ holder.chem_temp = 20 // cools the fuck down return +/datum/chemical_reaction/cryostylane_oxygen + name = "ephemeral cryostylane reaction" + id = "cryostylane_oxygen" + results = list("cryostylane" = 1) + required_reagents = list("cryostylane" = 1, "oxygen" = 1) + +/datum/chemical_reaction/cryostylane_oxygen/on_reaction(datum/reagents/holder, created_volume) + holder.chem_temp -= 10*created_volume + +/datum/chemical_reaction/pyrosium_oxygen + name = "ephemeral pyrosium reaction" + id = "pyrosium_oxygen" + results = list("pyrosium" = 1) + required_reagents = list("pyrosium" = 1, "oxygen" = 1) + +/datum/chemical_reaction/pyrosium_oxygen/on_reaction(datum/reagents/holder, created_volume) + holder.chem_temp += 10*created_volume /datum/chemical_reaction/pyrosium name = "pyrosium" diff --git a/code/modules/recycling/disposal-structures.dm b/code/modules/recycling/disposal-structures.dm index acb89f4bee..2fe36972e0 100644 --- a/code/modules/recycling/disposal-structures.dm +++ b/code/modules/recycling/disposal-structures.dm @@ -339,16 +339,6 @@ if(current_size >= STAGE_FIVE) deconstruct() -//Fixes dpdir on shuttle rotation -/obj/structure/disposalpipe/shuttleRotate(rotation) - ..() - var/new_dpdir = 0 - for(var/D in GLOB.cardinals) - if(dpdir & D) - new_dpdir = new_dpdir | angle2dir(rotation+dir2angle(D)) - dpdir = new_dpdir - - // *** TEST verb //client/verb/dispstop() // for(var/obj/structure/disposalholder/H in world) diff --git a/code/modules/shuttle/manipulator.dm b/code/modules/shuttle/manipulator.dm index 6e2741a6d7..3da4bcc03e 100644 --- a/code/modules/shuttle/manipulator.dm +++ b/code/modules/shuttle/manipulator.dm @@ -242,7 +242,7 @@ /obj/machinery/shuttle_manipulator/proc/load_template( datum/map_template/shuttle/S) // load shuttle template, centred at shuttle import landmark, - var/turf/landmark_turf = get_turf(locate("landmark*Shuttle Import")) + var/turf/landmark_turf = get_turf(locate(/obj/effect/landmark/shuttle_import) in GLOB.landmarks_list) S.load(landmark_turf, centered = TRUE) var/affected = S.get_affected_turfs(landmark_turf, centered=TRUE) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index b527894d0a..ebc684ee15 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -83,7 +83,7 @@ All ShuttleMove procs go here return if(rotation) - shuttleRotate(rotation) + shuttleRotate(rotation) //see shuttle_rotate.dm loc = newT if(length(client_mobs_in_contents)) update_parallax_contents() @@ -126,26 +126,6 @@ All ShuttleMove procs go here /area/proc/afterShuttleMove() return TRUE -/************************************Shuttle Rotation************************************/ - -/atom/proc/shuttleRotate(rotation) - //rotate our direction - setDir(angle2dir(rotation+dir2angle(dir))) - - //resmooth if need be. - if(smooth) - queue_smooth(src) - - //rotate the pixel offsets too. - if (pixel_x || pixel_y) - if (rotation < 0) - rotation += 360 - for (var/turntimes=rotation/90;turntimes>0;turntimes--) - var/oldPX = pixel_x - var/oldPY = pixel_y - pixel_x = oldPY - pixel_y = (oldPX*(-1)) - /************************************Turf move procs************************************/ /turf/open/afterShuttleMove(turf/oldT) //Recalculates SSair stuff for turfs on both sides @@ -203,7 +183,7 @@ All ShuttleMove procs go here if(pipe_vision_img) pipe_vision_img.loc = loc -/obj/machinery/computer/auxillary_base/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) +/obj/machinery/computer/auxillary_base/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) . = ..() if(z == ZLEVEL_MINING) //Avoids double logging and landing on other Z-levels due to badminnery SSblackbox.add_details("colonies_dropped", "[x]|[y]|[z]") //Number of times a base has been dropped! @@ -223,21 +203,6 @@ All ShuttleMove procs go here . = ..() . |= MOVE_CONTENTS -//Properly updates pipes on shuttle movement -/obj/machinery/atmospherics/shuttleRotate(rotation) - var/list/real_node_connect = getNodeConnects() - for(DEVICE_TYPE_LOOP) - real_node_connect[I] = angle2dir(rotation+dir2angle(real_node_connect[I])) - - . = ..() - SetInitDirections() - var/list/supposed_node_connect = getNodeConnects() - var/list/nodes_copy = nodes.Copy() - - for(DEVICE_TYPE_LOOP) - var/new_pos = supposed_node_connect.Find(real_node_connect[I]) - nodes[new_pos] = nodes_copy[I] - /obj/machinery/atmospherics/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) . = ..() var/missing_nodes = FALSE @@ -297,24 +262,25 @@ All ShuttleMove procs go here /************************************Item move procs************************************/ -/obj/item/storage/pod/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) +/obj/item/storage/pod/afterShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) + . = ..() unlocked = TRUE // If the pod was launched, the storage will always open. - return ..() /************************************Mob move procs************************************/ /mob/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) if(!move_on_shuttle) - return 0 - . = ..() - if(!.) return - if(client) + . = ..() + +/mob/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) + . = ..() + if(client && movement_force) + var/shake_force = max(movement_force["THROW"], movement_force["KNOCKDOWN"]) if(buckled) - shake_camera(src, 2, 1) // turn it down a bit come on - else - shake_camera(src, 7, 1) + shake_force *= 0.25 + shake_camera(src, shake_force, 1) /mob/living/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) . = ..() @@ -373,7 +339,6 @@ All ShuttleMove procs go here /obj/docking_port/stationary/public_mining_dock/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) id = "mining_public" //It will not move with the base, but will become enabled as a docking point. - return 0 /obj/effect/abstract/proximity_checker/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) //timer so it only happens once diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 99d707d289..22368c92fb 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -553,6 +553,8 @@ var/list/moved_atoms = list() //Everything not a turf that gets moved in the shuttle var/list/areas_to_move = list() //unique assoc list of areas on turfs being moved + CHECK_TICK + /****************************************All beforeShuttleMove procs*****************************************/ var/index = 0 for(var/place in old_turfs) @@ -578,6 +580,7 @@ areas_to_move[old_area] = TRUE old_turfs[place] = move_mode + CHECK_TICK /*******************************************All onShuttleMove procs******************************************/ @@ -608,17 +611,28 @@ var/turf/oldT = thing var/turf/newT = new_turfs[index] newT.afterShuttleMove(oldT) //turfs + CHECK_TICK for(var/i in 1 to moved_atoms.len) var/atom/movable/moved_object = moved_atoms[i] moved_object.afterShuttleMove(movement_force, dir, preferred_direction, movement_direction) //atoms + CHECK_TICK underlying_old_area.afterShuttleMove() for(var/thing in areas_to_move) var/area/internal_area = thing internal_area.afterShuttleMove() //areas + CHECK_TICK + // Parallax handling + var/new_parallax_dir = FALSE + if(istype(new_dock, /obj/docking_port/stationary/transit)) + new_parallax_dir = preferred_direction + for(var/i in shuttle_areas) + var/area/place = i + place.parallax_movedir = new_parallax_dir + CHECK_TICK check_poddoors() new_dock.last_dock_time = world.time setDir(new_dock.dir) diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm new file mode 100644 index 0000000000..389a2406ed --- /dev/null +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -0,0 +1,100 @@ +/* +All shuttleRotate procs go here +*/ + +/************************************Base proc************************************/ + +/atom/proc/shuttleRotate(rotation) + //rotate our direction + setDir(angle2dir(rotation+dir2angle(dir))) + + //resmooth if need be. + if(smooth) + queue_smooth(src) + + //rotate the pixel offsets too. + if (pixel_x || pixel_y) + if (rotation < 0) + rotation += 360 + for (var/turntimes=rotation/90;turntimes>0;turntimes--) + var/oldPX = pixel_x + var/oldPY = pixel_y + pixel_x = oldPY + pixel_y = (oldPX*(-1)) + +/************************************Turf rotate procs************************************/ + +/turf/closed/mineral/shuttleRotate(rotation) + setDir(angle2dir(rotation+dir2angle(dir))) + queue_smooth(src) + +/************************************Mob rotate procs************************************/ + +//override to avoid rotating pixel_xy on mobs +/mob/shuttleRotate(rotation) + setDir(angle2dir(rotation+dir2angle(dir))) + +/************************************Structure rotate procs************************************/ + +/obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation) + . = ..() + expected_dir = angle2dir(rotation+dir2angle(dir)) + +/obj/structure/cable/shuttleRotate(rotation) + //..() is not called because wires are not supposed to have a non-default direction + //Rotate connections + if(d1) + d1 = angle2dir(rotation+dir2angle(d1)) + if(d2) + d2 = angle2dir(rotation+dir2angle(d2)) + + //d1 should be less than d2 for cable icons to work + if(d1 > d2) + var/temp = d1 + d1 = d2 + d2 = temp + update_icon() + +//Fixes dpdir on shuttle rotation +/obj/structure/disposalpipe/shuttleRotate(rotation) + . = ..() + var/new_dpdir = 0 + for(var/D in GLOB.cardinals) + if(dpdir & D) + new_dpdir = new_dpdir | angle2dir(rotation+dir2angle(D)) + dpdir = new_dpdir + +/obj/structure/table/wood/bar/shuttleRotate(rotation) + . = ..() + boot_dir = angle2dir(rotation + dir2angle(boot_dir)) + +/obj/structure/alien/weeds/shuttleRotate(rotation) + return + +/************************************Machine rotate procs************************************/ + +/obj/machinery/atmospherics/shuttleRotate(rotation) + var/list/real_node_connect = getNodeConnects() + for(DEVICE_TYPE_LOOP) + real_node_connect[I] = angle2dir(rotation+dir2angle(real_node_connect[I])) + + . = ..() + SetInitDirections() + var/list/supposed_node_connect = getNodeConnects() + var/list/nodes_copy = nodes.Copy() + + for(DEVICE_TYPE_LOOP) + var/new_pos = supposed_node_connect.Find(real_node_connect[I]) + nodes[new_pos] = nodes_copy[I] + +//prevents shuttles attempting to rotate this since it messes up sprites +/obj/machinery/gateway/shuttleRotate() + return + +/obj/machinery/door/airlock/survival_pod/shuttleRotate(rotation) + expected_dir = angle2dir(rotation+dir2angle(dir)) + return ..() + +//prevents shuttles attempting to rotate this since it messes up sprites +/obj/machinery/gravity_generator/shuttleRotate() + return \ No newline at end of file diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index 0373ea5b53..f2d451f6e2 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -195,10 +195,6 @@ else . = ..() -/obj/structure/table/wood/bar/shuttleRotate(rotation) - . = ..() - boot_dir = angle2dir(rotation + dir2angle(boot_dir)) - /obj/structure/table/wood/bar/proc/is_barstaff(mob/living/user) . = FALSE if(ishuman(user)) diff --git a/html/changelogs/AutoChangeLog-pr-3135.yml b/html/changelogs/AutoChangeLog-pr-3135.yml new file mode 100644 index 0000000000..faef26ffd8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3135.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - balance: "Pyrosium and cryostylane now react at ludicrous speeds." diff --git a/html/changelogs/AutoChangeLog-pr-3138.yml b/html/changelogs/AutoChangeLog-pr-3138.yml new file mode 100644 index 0000000000..3fdfa942c2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3138.yml @@ -0,0 +1,4 @@ +author: "ShizCalev" +delete-after: True +changes: + - soundadd: "Space ninja energy katanas now make a swish when drawn!" diff --git a/html/changelogs/AutoChangeLog-pr-3139.yml b/html/changelogs/AutoChangeLog-pr-3139.yml new file mode 100644 index 0000000000..88cb158819 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3139.yml @@ -0,0 +1,4 @@ +author: "ShizCalev" +delete-after: True +changes: + - bugfix: "Wizards will now have the correct name when attacked with Envy's knife!" diff --git a/html/changelogs/AutoChangeLog-pr-3142.yml b/html/changelogs/AutoChangeLog-pr-3142.yml new file mode 100644 index 0000000000..e502707a59 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3142.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "The PDA default font has been switched from \"eye bleed\" to old-style monospace. Check your preference." diff --git a/html/changelogs/AutoChangeLog-pr-3144.yml b/html/changelogs/AutoChangeLog-pr-3144.yml new file mode 100644 index 0000000000..bf65dca23d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3144.yml @@ -0,0 +1,4 @@ +author: "RandomMarine" +delete-after: True +changes: + - bugfix: "Simple mobs should no longer experience severe hud/lighting glitches when reconnecting." diff --git a/html/changelogs/AutoChangeLog-pr-3147.yml b/html/changelogs/AutoChangeLog-pr-3147.yml new file mode 100644 index 0000000000..556149df01 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3147.yml @@ -0,0 +1,4 @@ +author: "JJRcop" +delete-after: True +changes: + - tweak: "Admin volume slider moved to its own menu for better visibility." diff --git a/html/changelogs/AutoChangeLog-pr-3148.yml b/html/changelogs/AutoChangeLog-pr-3148.yml new file mode 100644 index 0000000000..c9662ac387 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3148.yml @@ -0,0 +1,4 @@ +author: "Xhuis and Y0SH1_M4S73R" +delete-after: True +changes: + - bugfix: "Servants of Ratvar now spawn in as the actual race set on their preferences, with plasmamen getting the gear they need to not immediately die." diff --git a/html/changelogs/AutoChangeLog-pr-3153.yml b/html/changelogs/AutoChangeLog-pr-3153.yml new file mode 100644 index 0000000000..a79a3982ca --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3153.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Jaunters equipped on the belt slot will save you from chasms again." diff --git a/html/changelogs/AutoChangeLog-pr-3157.yml b/html/changelogs/AutoChangeLog-pr-3157.yml new file mode 100644 index 0000000000..69e7b10920 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3157.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Wigs are now available in AutoDrobe" diff --git a/html/changelogs/AutoChangeLog-pr-3159.yml b/html/changelogs/AutoChangeLog-pr-3159.yml new file mode 100644 index 0000000000..d835ae4122 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3159.yml @@ -0,0 +1,7 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Added the H.E.C.K. suit, a guaranteed loot frop from Bubblegum." + - rscadd: "The H.E.C.K. suit is fully fire (and ash) proof, and has very good melee armor." + - rscadd: "H.E.C.K. suits can also be painted with spraycans, to fully customize your experience." + - rscadd: "Despite spending centuries inside a demon king, H.E.C.K. suits are most definitely safe." diff --git a/html/changelogs/AutoChangeLog-pr-3160.yml b/html/changelogs/AutoChangeLog-pr-3160.yml new file mode 100644 index 0000000000..c9d48dc583 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3160.yml @@ -0,0 +1,5 @@ +author: "Kevak/Neri" +delete-after: True +changes: + - bugfix: "Fixed plasmaman organsprites being missing" + - imageadd: "Plasmaman organ sprites added. Credit to Toriate for the sprites" diff --git a/html/changelogs/AutoChangeLog-pr-3163.yml b/html/changelogs/AutoChangeLog-pr-3163.yml new file mode 100644 index 0000000000..3c82b42146 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3163.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "Emotes (e.g. spinning and flipping) will now properly check for consciousness, restraints, etc. when appropriate." diff --git a/html/changelogs/AutoChangeLog-pr-3168.yml b/html/changelogs/AutoChangeLog-pr-3168.yml new file mode 100644 index 0000000000..ee61a58860 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3168.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - tweak: "Made atmos tiny bit faster" diff --git a/html/changelogs/AutoChangeLog-pr-3170.yml b/html/changelogs/AutoChangeLog-pr-3170.yml new file mode 100644 index 0000000000..eeb9a06f55 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3170.yml @@ -0,0 +1,6 @@ +author: "Joan" +delete-after: True +changes: + - balance: "Ocular Warden base damage per second changed from 12.5 to 15." + - bugfix: "Ocular Wardens no longer count themselves when checking for dense objects, which decreased their overall damage by 15%." + - balance: "Ocular Wardens now only reduce their damage by 10% per dense object, and only do so once per turf. However, dense turfs now reduce their damage with the same 10% penalty." diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index f73a54ab1d..1ae0b0a2b5 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/obj/stack_objects.dmi b/icons/obj/stack_objects.dmi new file mode 100644 index 0000000000..f21c6c7579 Binary files /dev/null and b/icons/obj/stack_objects.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index d18a1bf262..18bbcb3610 100755 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/tgstation.dme b/tgstation.dme index c56498e5d7..34f7ecff20 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -266,6 +266,7 @@ #include "code\datums\browser.dm" #include "code\datums\callback.dm" #include "code\datums\cinematic.dm" +#include "code\datums\dash_weapon.dm" #include "code\datums\datacore.dm" #include "code\datums\datum.dm" #include "code\datums\datumvars.dm" @@ -302,6 +303,7 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\archaeology.dm" #include "code\datums\components\material_container.dm" +#include "code\datums\components\paintable.dm" #include "code\datums\components\slippery.dm" #include "code\datums\components\squeek.dm" #include "code\datums\diseases\_disease.dm" @@ -2162,6 +2164,7 @@ #include "code\modules\shuttle\on_move.dm" #include "code\modules\shuttle\ripple.dm" #include "code\modules\shuttle\shuttle.dm" +#include "code\modules\shuttle\shuttle_rotate.dm" #include "code\modules\shuttle\special.dm" #include "code\modules\shuttle\supply.dm" #include "code\modules\shuttle\syndicate.dm"