diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 2f58d4e9ebb..a8a0459bcb1 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,4 +7,4 @@ assignees: '' --- -Please place all features requests here: https://nanotrasen.se/forum/60-suggestions/ +Please place all features requests here: https://www.paradisestation.org/forum/60-suggestions/ diff --git a/.travis.yml b/.travis.yml index 464e01c8f53..146be925c77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,8 @@ addons: env: global: - - BYOND_MAJOR="512" - - BYOND_MINOR="1454" + - BYOND_MAJOR="513" + - BYOND_MINOR="1505" - BYOND_MACRO_COUNT=4 matrix: - DM_MAPFILE="cyberiad" diff --git a/README.md b/README.md index d60fe8006c8..eafdb5ffe91 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![forthebadge](http://forthebadge.com/images/badges/contains-technical-debt.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/fuck-it-ship-it.svg)](http://forthebadge.com) -[Website](https://nanotrasen.se/) - [Code](https://github.com/ParadiseSS13/Paradise) - [Discord](https://discordapp.com/invite/YJDsXFE) +[Website](https://www.paradisestation.org/) - [Code](https://github.com/ParadiseSS13/Paradise) - [Discord](https://discordapp.com/invite/YJDsXFE) --- @@ -104,7 +104,7 @@ Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/paradise_schema.sql or /SQL/paradise_schema_prefix.sql, depending on if you want table prefixes. More detailed setup instructions are located on our wiki: -https://nanotrasen.se/wiki/index.php/Setting_up_the_Database +https://www.paradisestation.org/wiki/index.php/Setting_up_the_Database --- diff --git a/code/__DEFINES/crafting.dm b/code/__DEFINES/crafting.dm index 7bfd2935280..0fbd76b9e21 100644 --- a/code/__DEFINES/crafting.dm +++ b/code/__DEFINES/crafting.dm @@ -6,6 +6,10 @@ #define CAT_ROBOT "Robots" #define CAT_MISC "Misc" #define CAT_PRIMAL "Tribal" +#define CAT_DECORATIONS "Decorations" +#define CAT_DECORATION "Decorations" +#define CAT_HOLIDAY "Holiday" +#define CAT_LARGE_DECORATIONS "Large Decorations" #define CAT_CLOTHING "Clothing" #define CAT_FOOD "Foods" #define CAT_BREAD "Breads" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 5a2c087e1fd..6e1fa5e01fd 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -384,7 +384,7 @@ #define EXPLOSIVE_WALL_GROUP_SYNDICATE_BASE "syndicate_base" // Filters -#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, border=4, color="#04080FAA") +#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, color="#04080FAA") //Fullscreen overlay resolution in tiles. #define FULLSCREEN_OVERLAY_RESOLUTION_X 15 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 1db82f879fe..293d97e4fa3 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -95,6 +95,8 @@ #define APPEARANCE_ALL_BODY APPEARANCE_ALL_HAIR|APPEARANCE_HEAD_ACCESSORY|APPEARANCE_MARKINGS|APPEARANCE_BODY_ACCESSORY|APPEARANCE_ALT_HEAD #define APPEARANCE_ALL 32767 +#define STAMINA_REGEN_BLOCK_TIME (10 SECONDS) + //Slime evolution threshold. Controls how fast slimes can split/grow #define SLIME_EVOLUTION_THRESHOLD 10 diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 5b93e570222..34ad4d69e54 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -10,7 +10,6 @@ // justice if someone's abusing your role #define ROLE_SYNDICATE "Syndicate" #define ROLE_TRAITOR "traitor" -#define ROLE_MINDSLAVE "mindslave" #define ROLE_OPERATIVE "operative" #define ROLE_CHANGELING "changeling" #define ROLE_WIZARD "wizard" diff --git a/code/__DEFINES/typeids.dm b/code/__DEFINES/typeids.dm index 4fd2c390fa7..16b6e475b8e 100644 --- a/code/__DEFINES/typeids.dm +++ b/code/__DEFINES/typeids.dm @@ -2,5 +2,5 @@ #define TYPEID_NULL "0" #define TYPEID_NORMAL_LIST "f" //helper macros -#define GET_TYPEID(ref) ( ( (lentext(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, lentext(ref) - 6) ) ) +#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, length(ref) - 6) ) ) #define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST) \ No newline at end of file diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 49983658d48..5ffe891d95b 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -69,11 +69,6 @@ return list[index] return -/proc/islist(list/list) - if(istype(list)) - return 1 - return 0 - //Return either pick(list) or null if list is not of type /list or is empty /proc/safepick(list/list) if(!islist(list) || !list.len) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 10658df4c4b..7c61cf832b5 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -381,7 +381,7 @@ This is always put in the attack log. drifting = 0 Uloc = user.loc - if(!user || user.stat || user.weakened || user.stunned || (!drifting && user.loc != Uloc)|| (extra_checks && !extra_checks.Invoke())) + if(!user || user.stat || user.IsWeakened() || user.stunned || (!drifting && user.loc != Uloc)|| (extra_checks && !extra_checks.Invoke())) . = 0 break diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index f3b76064517..0f356aa4f4a 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -20,7 +20,7 @@ if(!istext(t)) t = "[t]" // Just quietly assume any non-texts are supposed to be text var/sqltext = dbcon.Quote(t); - return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that + return copytext(sqltext, 2, length(sqltext));//Quote() adds quotes around input, we already do that /proc/format_table_name(table as text) return sqlfdbktableprefix + table @@ -333,9 +333,9 @@ proc/checkhtml(var/t) //is in the other string at the same spot (assuming it is not a replace char). //This is used for fingerprints var/newtext = text - if(lentext(text) != lentext(compare)) + if(length(text) != length(compare)) return 0 - for(var/i = 1, i < lentext(text), i++) + for(var/i = 1, i < length(text), i++) var/a = copytext(text,i,i+1) var/b = copytext(compare,i,i+1) //if it isn't both the same letter, or if they are both the replacement character @@ -355,7 +355,7 @@ proc/checkhtml(var/t) if(!text || !character) return 0 var/count = 0 - for(var/i = 1, i <= lentext(text), i++) + for(var/i = 1, i <= length(text), i++) var/a = copytext(text,i,i+1) if(a == character) count++ @@ -400,8 +400,8 @@ proc/checkhtml(var/t) //Used in preferences' SetFlavorText and human's set_flavor verb //Previews a string of len or less length /proc/TextPreview(var/string,var/len=40) - if(lentext(string) <= len) - if(!lentext(string)) + if(length(string) <= len) + if(!length(string)) return "\[...\]" else return html_encode(string) //NO DECODED HTML YOU CHUCKLEFUCKS @@ -541,7 +541,7 @@ proc/checkhtml(var/t) text = "[text]" else text = "[text]" - + text = copytext(text, 1, MAX_PAPER_MESSAGE_LEN) return text diff --git a/code/__HELPERS/traits.dm b/code/__HELPERS/traits.dm index 472caea4490..7c1d2257e27 100644 --- a/code/__HELPERS/traits.dm +++ b/code/__HELPERS/traits.dm @@ -62,6 +62,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai //mob traits #define TRAIT_PACIFISM "pacifism" +#define TRAIT_WATERBREATH "waterbreathing" // common trait sources #define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 82295bc9d80..f1611b38fd9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -540,9 +540,20 @@ Returns 1 if the chain up to the area contains the given typepath /proc/between(var/low, var/middle, var/high) return max(min(middle, high), low) -proc/arctan(x) + + +#if DM_VERSION > 513 +#warn 513 is definitely stable now, remove this +#endif +#if DM_VERSION < 513 +/proc/arctan(x) var/y=arcsin(x/sqrt(1+x*x)) return y +/proc/islist(list/list) + if(istype(list)) + return 1 + return 0 +#endif //returns random gauss number proc/GaussRand(var/sigma) diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index a5586578b3f..9c0f498cd83 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -16,7 +16,7 @@ filters += filter(type = "outline", size = _size, color = _color) /obj/screen/plane_master/proc/shadow(_size, _border, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA") - filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset, border = _border) + filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset) /obj/screen/plane_master/proc/clear_filters() filters = list() diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index c279a7be2a5..c3c9b6f7e65 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -169,7 +169,7 @@ /obj/screen/storage/Click(location, control, params) if(world.time <= usr.next_move) return 1 - if(usr.stat || usr.paralysis || usr.stunned || usr.weakened) + if(usr.stat || usr.paralysis || usr.stunned || usr.IsWeakened()) return 1 if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech return 1 diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index 166083b36ff..504a2d74a2c 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -421,23 +421,23 @@ SUBSYSTEM_DEF(jobs) to_chat(H, "You are the [alt_title ? alt_title : rank].") to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.") - to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)") + to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)") if(job.is_service) - to_chat(H, "As a member of Service, make sure to read up on your Department SOP") + to_chat(H, "As a member of Service, make sure to read up on your Department SOP") if(job.is_supply) - to_chat(H, "As a member of Supply, make sure to read up on your Department SOP") + to_chat(H, "As a member of Supply, make sure to read up on your Department SOP") if(job.is_command) - to_chat(H, "As an important member of Command, read up on your Department SOP") + to_chat(H, "As an important member of Command, read up on your Department SOP") if(job.is_legal) - to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure") + to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure") if(job.is_engineering) - to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP") + to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP") if(job.is_medical) - to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP") + to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP") if(job.is_science) - to_chat(H, "As a member of Science, make sure to read up on your Department SOP") + to_chat(H, "As a member of Science, make sure to read up on your Department SOP") if(job.is_security) - to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP") + to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP") if(job.req_admin_notify) to_chat(H, "You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.") diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm index 24be623573e..058569250ec 100644 --- a/code/controllers/subsystem/tickets/tickets.dm +++ b/code/controllers/subsystem/tickets/tickets.dm @@ -23,7 +23,7 @@ SUBSYSTEM_DEF(tickets) flags = SS_BACKGROUND - var/list/allTickets + var/list/allTickets = list() //make it here because someone might ahelp before the system has initialized var/ticketCounter = 1 @@ -31,7 +31,6 @@ SUBSYSTEM_DEF(tickets) close_messages = list("- [ticket_name] Rejected! -", "Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.", "Your [ticket_name] has now been closed.") - LAZYINITLIST(allTickets) return ..() /datum/controller/subsystem/tickets/fire() diff --git a/code/datums/action.dm b/code/datums/action.dm index 043117efb84..b7af84e9ddf 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -72,7 +72,7 @@ if(owner.restrained()) return 0 if(check_flags & AB_CHECK_STUNNED) - if(owner.stunned || owner.weakened) + if(owner.stunned || owner.IsWeakened()) return 0 if(check_flags & AB_CHECK_LYING) if(owner.lying) diff --git a/code/datums/components/ducttape.dm b/code/datums/components/ducttape.dm index 85568f7a09c..98512589a46 100644 --- a/code/datums/components/ducttape.dm +++ b/code/datums/components/ducttape.dm @@ -2,20 +2,23 @@ var/x_offset = 0 var/y_offset = 0 var/icon/tape_overlay = null + var/hide_tape = FALSE -/datum/component/ducttape/Initialize(obj/item/I, mob/user, x, y) +/datum/component/ducttape/Initialize(obj/item/I, mob/user, x, y, hide_tape) if(!istype(I)) //Something went wrong return + if(!hide_tape) //if TRUE this hides the tape overlay and added examine text + RegisterSignal(parent, COMSIG_OBJ_UPDATE_ICON, .proc/add_tape_overlay) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/add_tape_text) x_offset = x y_offset = y - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/add_tape_text) - RegisterSignal(parent, COMSIG_OBJ_UPDATE_ICON, .proc/add_tape_overlay) RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/afterattack) RegisterSignal(parent, COMSIG_ITEM_PICKUP, .proc/pick_up) I.update_icon() //Do this first so the action button properly shows the icon - var/datum/action/item_action/remove_tape/RT = new(I) - if(I.loc == user) - RT.Grant(user) + if(!hide_tape) //the tape can no longer be removed if TRUE + var/datum/action/item_action/remove_tape/RT = new(I) + if(I.loc == user) + RT.Grant(user) /datum/component/proc/add_tape_text(datum/source, mob/user, list/examine_list) examine_list += "There's some sticky tape attached to [source]." diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm index 2f07f106d2a..4aa7eafbed6 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/datums/spells/area_teleport.dm @@ -25,10 +25,13 @@ var/A = null if(!randomise_selection) - A = input("Area to teleport to", "Teleport", A) in teleportlocs + A = input("Area to teleport to", "Teleport", A) as null|anything in teleportlocs else A = pick(teleportlocs) + if(!A) + return + var/area/thearea = teleportlocs[A] if(thearea.tele_proof && !istype(thearea, /area/wizard_station)) diff --git a/code/datums/spells/cluwne.dm b/code/datums/spells/cluwne.dm index 6a87419886c..58a33e31a44 100644 --- a/code/datums/spells/cluwne.dm +++ b/code/datums/spells/cluwne.dm @@ -17,7 +17,7 @@ var/obj/item/organ/internal/brain/cluwne/idiot_brain = new idiot_brain.insert(src, make_cluwne = 0) idiot_brain.dna = dna.Clone() - setBrainLoss(80) + setBrainLoss(80, use_brain_mod = FALSE) set_nutrition(9000) overeatduration = 9000 Confused(30) diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm index cc0cc307ed5..6c89ab45434 100644 --- a/code/game/gamemodes/autotraitor/autotraitor.dm +++ b/code/game/gamemodes/autotraitor/autotraitor.dm @@ -52,7 +52,7 @@ if(!traitor || !istype(traitor)) pre_traitors.Remove(traitor) continue - if(istype(traitor)) + if(istype(traitor)) traitor.special_role = SPECIAL_ROLE_TRAITOR traitor.restricted_roles = restricted_jobs diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index f94a9a3fbfd..cc7203d9c40 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -139,11 +139,7 @@ /mob/living/simple_animal/hostile/blob/blobspore/update_icons() ..() - if(overmind && overmind.blob_reagent_datum) - adjustcolors(overmind.blob_reagent_datum.complementary_color) - else - adjustcolors(overmind.blob_reagent_datum.complementary_color) //to ensure zombie/other overlays update - + adjustcolors(overmind?.blob_reagent_datum?.complementary_color) /mob/living/simple_animal/hostile/blob/blobspore/adjustcolors(var/a_color) color = a_color @@ -152,8 +148,7 @@ overlays.Cut() overlays = human_overlays var/image/I = image('icons/mob/blob.dmi', icon_state = "blob_head") - I.color = overmind.blob_reagent_datum.complementary_color - color = initial(overmind.blob_reagent_datum.complementary_color)//looks better. + I.color = color overlays += I ///////////////// @@ -191,6 +186,7 @@ else adjustBruteLoss(0.2) // If you are at full health, you won't lose health. You'll need it. However the moment anybody sneezes on you, the decaying will begin. adjustFireLoss(0.2) + ..() /mob/living/simple_animal/hostile/blob/blobbernaut/New() ..() diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm index a8fdc03ec96..b8bff19cbcf 100644 --- a/code/game/gamemodes/blob/blobs/factory.dm +++ b/code/game/gamemodes/blob/blobs/factory.dm @@ -23,6 +23,7 @@ flick("blob_factory_glow", src) spore_delay = world.time + 100 // 10 seconds var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore(src.loc, src) - BS.color = overmind.blob_reagent_datum.complementary_color - BS.overmind = overmind - overmind.blob_mobs.Add(BS) + if(overmind) + BS.color = overmind.blob_reagent_datum?.complementary_color + BS.overmind = overmind + overmind.blob_mobs.Add(BS) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 1cc55d99f0c..113487dc1dc 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -9,24 +9,28 @@ var/global/list/all_cults = list() /proc/is_convertable_to_cult(datum/mind/mind) if(!mind) - return 0 + return FALSE if(!mind.current) - return 0 + return FALSE if(iscultist(mind.current)) - return 1 //If they're already in the cult, assume they are convertable + return TRUE //If they're already in the cult, assume they are convertable if(ishuman(mind.current) && (mind.assigned_role in list("Captain", "Chaplain"))) - return 0 + return FALSE if(ishuman(mind.current)) var/mob/living/carbon/human/H = mind.current - if(ismindshielded(H)) - return 0 + if(ismindshielded(H)) //mindshield protects against conversions unless removed + return FALSE +// if(mind.offstation_role) cant convert offstation roles such as ghost spawns +// return FALSE Commented out until we can figure out why offstation_role is getting set to TRUE on normal crew if(issilicon(mind.current)) - return 0 //can't convert machines, that's ratvar's thing + return FALSE //can't convert machines, that's ratvar's thing if(isguardian(mind.current)) var/mob/living/simple_animal/hostile/guardian/G = mind.current if(!iscultist(G.summoner)) - return 0 //can't convert it unless the owner is converted - return 1 + return FALSE //can't convert it unless the owner is converted + if(isgolem(mind.current)) + return FALSE + return TRUE /proc/is_sacrifice_target(datum/mind/mind) if(SSticker.mode.name == "cult") diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index d30ac4f8a68..3489a087ec0 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -198,7 +198,7 @@ var/list/blacklisted_pylon_turfs = typecacheof(list( if(last_heal <= world.time) last_heal = world.time + heal_delay for(var/mob/living/L in range(5, src)) - if(iscultist(L) || istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct)) + if(iscultist(L) || iswizard(L) || istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct)) if(L.health != L.maxHealth) new /obj/effect/temp_visual/heal(get_turf(src), "#960000") if(ishuman(L)) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 2f2f0cae02e..d918bead0de 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -340,144 +340,100 @@ var/list/teleport_runes = list() fail_invoke() -//Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby. +//Rite of Offering: Converts a normal crewmember to the cult or sacrifices mindshielded and sacrifice targets. /obj/effect/rune/convert - cultist_name = "Rite of Enlightenment" - cultist_desc = "converts a normal crewmember on top of it to the cult. Does not work on mindshielded crew." + cultist_name = "Rite of Offering" + cultist_desc = "Offers a non-cultists on top of it to your deity, either converting or sacrificing them." invocation = "Mah'weyh pleggh at e'ntrath!" icon_state = "3" - req_cultists = 2 - + req_cultists = 1 + allow_excess_invokers = TRUE + rune_in_use = FALSE + /obj/effect/rune/convert/do_invoke_glow() return /obj/effect/rune/convert/invoke(var/list/invokers) - var/list/convertees = list() - var/turf/T = get_turf(src) - - for(var/mob/living/M in T.contents) - if(!iscultist(M) && !ismindshielded(M) && !isgolem(M) && ishuman(M)) - convertees.Add(M) - if(!convertees.len) - fail_invoke() - log_game("Convert rune failed - no eligible convertees") - return - var/mob/living/new_cultist = pick(convertees) - if(!is_convertable_to_cult(new_cultist.mind) || new_cultist.null_rod_check()) - for(var/M in invokers) - to_chat(M, "Something is shielding [new_cultist]'s mind!") - if(is_sacrifice_target(new_cultist.mind)) - to_chat(M, "\"I desire this one for myself. SACRIFICE THEM!\"") - fail_invoke() - log_game("Convert rune failed - convertee could not be converted") - return - ..() - - new_cultist.visible_message("[new_cultist] writhes in pain as the markings below them glow a bloody red!", \ - "AAAAAAAAAAAAAA-") - SSticker.mode.add_cultist(new_cultist.mind, 1) - new /obj/item/tome(get_turf(src)) - new_cultist.mind.special_role = "Cultist" - to_chat(new_cultist, "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ - and something evil takes root.") - to_chat(new_cultist, "Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve [SSticker.cultdat.entity_title3] above all else. Bring it back.\ - ") - -//Rite of Tribute: Sacrifices a crew member to Nar-Sie. Places them into a soul shard if they're in their body. -/obj/effect/rune/sacrifice - cultist_name = "Rite of Tribute" - cultist_desc = "sacrifices a crew member to your god. May place them into a soul shard if their spirit remains in their body." - icon_state = "3" - allow_excess_invokers = 1 - invocation = "Barhah hra zar'garis!" - rune_in_use = 0 - -/obj/effect/rune/sacrifice/New() - ..() - cultist_desc = "sacrifices a crew member to [SSticker.cultdat.entity_title3]. May place them into a soul shard if their spirit remains in their body." - -/obj/effect/rune/sacrifice/invoke(var/list/invokers) if(rune_in_use) return - rune_in_use = 1 - var/mob/living/user = invokers[1] //the first invoker is always the user + var/list/myriad_targets = list() var/turf/T = get_turf(src) - var/list/possible_targets = list() - for(var/mob/living/M in T.contents) - if(M.mind) - if(M.mind in sacrificed) - continue + for(var/mob/living/M in T) if(!iscultist(M)) - possible_targets.Add(M) - var/mob/offering - if(possible_targets.len > 1) //If there's more than one target, allow choice - offering = input(user, "Choose an offering to sacrifice.", "Unholy Tribute") as null|anything in possible_targets - if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated()) - return - else if(possible_targets.len) //Otherwise, if there's a target at all, pick the only one - offering = possible_targets[possible_targets.len] - if(!offering) - rune_in_use = 0 + myriad_targets |= M + if(!myriad_targets.len) + fail_invoke() + log_game("Offer rune failed - no eligible targets") + rune_in_use = FALSE return + + rune_in_use = TRUE + var/mob/living/new_cultist = pick(myriad_targets) + if(is_convertable_to_cult(new_cultist.mind) && !new_cultist.null_rod_check() && !is_sacrifice_target(new_cultist.mind) && new_cultist.stat != DEAD && new_cultist.client != null) + invocation = "Mah'weyh pleggh at e'ntrath!" + ..() + do_convert(new_cultist, invokers) + else + invocation = "Barhah hra zar'garis!" + ..() + do_sacrifice(new_cultist, invokers) + rune_in_use = FALSE + +/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers) + if(invokers.len < 2) + fail_invoke() + for(var/I in invokers) + to_chat(I, "You need at least two invokers to convert!") + return + else + convertee.visible_message("[convertee] writhes in pain as the markings below them glow a bloody red!", \ + "AAAAAAAAAAAAAA-") + SSticker.mode.add_cultist(convertee.mind, 1) + new /obj/item/tome(get_turf(src)) + convertee.mind.special_role = "Cultist" + to_chat(convertee, "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ + and something evil takes root.") + to_chat(convertee, "Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve [SSticker.cultdat.entity_title3] above all else. Bring it back.\ + ") + return + +/obj/effect/rune/convert/proc/do_sacrifice(mob/living/offering, list/invokers) + var/mob/living/user = invokers[1] //the first invoker is always the user if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD) || is_sacrifice_target(offering.mind)) //Requires three people to sacrifice living targets if(invokers.len < 3) for(var/M in invokers) to_chat(M, "[offering] is too greatly linked to the world! You need three acolytes!") fail_invoke() log_game("Sacrifice rune failed - not enough acolytes and target is living") - rune_in_use = 0 return - visible_message("[src] pulses blood red!") - color = rgb(126, 23, 23) - ..() - sac(invokers, offering) - color = initial(color) -/obj/effect/rune/sacrifice/proc/sac(var/list/invokers, mob/living/T) var/sacrifice_fulfilled var/datum/game_mode/cult/cult_mode = SSticker.mode - if(T) - if(isdog(T)) // Doggos are the best, but not cats - for(var/M in invokers) - var/mob/living/L = M - to_chat(L, "\"Even I have standards, such as they are!\"") - if(L.reagents) - L.reagents.add_reagent("hell_water", 2) - if(T.mind) - sacrificed.Add(T.mind) - if(is_sacrifice_target(T.mind)) - sacrifice_fulfilled = 1 - new /obj/effect/temp_visual/cult/sac(loc) - if(SSticker && SSticker.mode && SSticker.mode.name == "cult") - - cult_mode.harvested++ - for(var/M in invokers) - if(sacrifice_fulfilled) - to_chat(M, "\"Yes! This is the one I desire! You have done well.\"") - cult_mode.additional_phase() - else - if(ishuman(T) || isrobot(T)) - to_chat(M, "\"I accept this sacrifice.\"") - else - to_chat(M, "\"I accept this meager sacrifice.\"") - if(T.mind) - var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src)) - stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul() - if(!stone.transfer_soul("VICTIM", T, usr)) //If it cannot be added - qdel(stone) - if(stone) - stone.invisibility = 0 - if(!T) - rune_in_use = 0 - return - if(isrobot(T)) - playsound(T, 'sound/effects/EMPulse.ogg', 100, 1) - T.dust() //To prevent the MMI from remaining + if(offering.mind) + sacrificed.Add(offering.mind) + if(is_sacrifice_target(offering.mind)) + sacrifice_fulfilled = TRUE + new /obj/effect/temp_visual/cult/sac(loc) + if(SSticker && SSticker.mode && SSticker.mode.name == "cult") + cult_mode.harvested++ + for(var/M in invokers) + if(sacrifice_fulfilled) + to_chat(M, "\"Yes! This is the one I desire! You have done well.\"") + cult_mode.additional_phase() else - playsound(T, 'sound/magic/disintegrate.ogg', 100, 1) - T.gib() - rune_in_use = 0 + if(ishuman(offering) || isrobot(offering)) + to_chat(M, "\"I accept this sacrifice.\"") + else + to_chat(M, "\"I accept this meager sacrifice.\"") + playsound(offering, 'sound/misc/demon_consume.ogg', 100, 1) + if((ishuman(offering) || isrobot(offering)) && offering.client_mobs_in_contents?.len) + var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src)) + stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul() + stone.transfer_soul("FORCE", offering, user) //If it cannot be added + stone.invisibility = 0 + else + offering.dust() //Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station. /obj/effect/rune/narsie @@ -707,6 +663,7 @@ var/list/teleport_runes = list() /obj/effect/rune/raise_dead/fail_invoke() ..() + rune_in_use = FALSE for(var/mob/living/M in range(1,src)) if(M.stat == DEAD) M.visible_message("[M] twitches.") diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 908eaa5360f..9fce3cc6e24 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -184,7 +184,7 @@ var/obj/machinery/abductor/console/con = get_team_console(team_number) var/datum/objective/objective = team_objectives[team_number] if(con.experiment.points >= objective.target_amount) - SSshuttle.emergency.request(null, 0.5) + SSshuttle.emergency.request(null, 0.5, reason = "Large amount of abnormal thought patterns detected. All crew are recalled for mandatory evaluation and reconditioning.") SSshuttle.emergency.canRecall = FALSE finished = 1 return ..() diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index b761af6db92..f86f018757e 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -162,7 +162,7 @@ to_chat(src, "You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.") to_chat(src, "To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.") to_chat(src, "You do not remember anything of your past lives, nor will you remember anything about this one after your death.") - to_chat(src, "Be sure to read the wiki page at http://nanotrasen.se/wiki/index.php/Revenant to learn more.") + to_chat(src, "Be sure to read the wiki page at http://www.paradisestation.org/wiki/index.php/Revenant to learn more.") var/datum/objective/revenant/objective = new objective.owner = mind mind.objectives += objective diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 214c349978a..89ecb1d103b 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -1,4 +1,4 @@ -var/global/list/all_objectives = list() +GLOBAL_LIST_EMPTY(all_objectives) var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datum/theft_objective/steal - /datum/theft_objective/number - /datum/theft_objective/unique @@ -10,13 +10,13 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu var/completed = 0 //currently only used for custom objectives. var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead. -/datum/objective/New(var/text) - all_objectives |= src +/datum/objective/New(text) + GLOB.all_objectives += src if(text) explanation_text = text /datum/objective/Destroy() - all_objectives -= src + GLOB.all_objectives -= src return ..() /datum/objective/proc/check_completion() diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index b580f88c0b7..b4b4b265711 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -126,7 +126,7 @@ Made by Xhuis to_chat(shadow.current, "Currently, you are disguised as an employee aboard [world.name].") to_chat(shadow.current, "In your limited state, you have two abilities: Hatch and Shadowling Hivemind (:8).") to_chat(shadow.current, "Any other shadowlings are your allies. You must assist them as they shall assist you.") - to_chat(shadow.current, "If you are new to shadowling, or want to read about abilities, check the wiki page at http://nanotrasen.se/wiki/index.php/Shadowling
") + to_chat(shadow.current, "If you are new to shadowling, or want to read about abilities, check the wiki page at https://www.paradisestation.org/wiki/index.php/Shadowling
") diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 7791c48b432..6c9674d130e 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -584,7 +584,7 @@ return if(stat != DEAD) - if(weakened) + if(IsWeakened()) visible_message("[src] looks to be in pain!") adjustBrainLoss(60) else diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index cca11dc0a98..2edbb41cb95 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -205,24 +205,19 @@ /obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob) switch(choice) if("FORCE") - var/obj/item/soulstone/C = src - if(!iscarbon(target)) //TODO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul - return 0 - if(contents.len) - return 0 - var/mob/living/carbon/T = target + var/obj/item/soulstone/SS = src + var/mob/living/T = target if(T.client != null) - for(var/obj/item/W in T) - T.unEquip(W) - C.init_shade(T, U) - return 1 + SS.init_shade(T, U) else to_chat(U, "Capture failed!: The soul has already fled its mortal frame. You attempt to bring it back...") - return C.getCultGhost(T,U) + T.Paralyse(20) + if(!SS.getCultGhost(T,U)) + T.dust() //If we can't get a ghost, kill the sacrifice anyway. if("VICTIM") var/mob/living/carbon/human/T = target - var/obj/item/soulstone/C = src + var/obj/item/soulstone/SS = src if(T.stat == 0) to_chat(U, "Capture failed!: Kill or maim the victim first!") else @@ -231,94 +226,67 @@ else if(T.client == null) to_chat(U, "Capture failed!: The soul has already fled its mortal frame. You attempt to bring it back...") - C.getCultGhost(T,U) + SS.getCultGhost(T,U) else - if(C.contents.len) + if(SS.contents.len) to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") else - for(var/obj/item/W in T) - T.unEquip(W) - C.init_shade(T, U, vic = 1) - qdel(T) + SS.init_shade(T, U, vic = 1) + if("SHADE") var/mob/living/simple_animal/shade/T = target - var/obj/item/soulstone/C = src - if(!C.can_use(U)) + var/obj/item/soulstone/SS = src + if(!SS.can_use(U)) U.Paralyse(5) to_chat(U, "Your body is wracked with debilitating pain!") return if(T.stat == DEAD) to_chat(U, "Capture failed!: The shade has already been banished!") else - if(C.contents.len) + if(SS.contents.len) to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") else - T.loc = C //put shade in stone + T.loc = SS //put shade in stone T.status_flags |= GODMODE T.canmove = 0 T.health = T.maxHealth T.faction |= "\ref[U]" - C.icon_state = "soulstone2" + SS.icon_state = "soulstone2" to_chat(T, "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form") to_chat(U, "Capture successful!: [T.name]'s has been recaptured and stored within the soul stone.") if("CONSTRUCT") var/obj/structure/constructshell/T = target - var/obj/item/soulstone/C = src - var/mob/living/simple_animal/shade/A = locate() in C - if(A) + var/obj/item/soulstone/SS = src + var/mob/living/simple_animal/shade/SH = locate() in SS + if(SH) var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") switch(construct_class) if("Juggernaut") - var/mob/living/simple_animal/hostile/construct/armoured/Z = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc)) - Z.key = A.key - Z.faction |= "\ref[U]" - if(iscultist(U)) - if(SSticker.mode.name == "cult") - SSticker.mode:add_cultist(Z.mind) - else - SSticker.mode.cult+=Z.mind - SSticker.mode.update_cult_icons_added(Z.mind) - qdel(T) - to_chat(Z, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.") - to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") - Z.cancel_camera() - qdel(C) + var/mob/living/simple_animal/hostile/construct/armoured/C = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc)) + to_chat(C, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.") + init_construct(C,SH,SS,T) if("Wraith") - var/mob/living/simple_animal/hostile/construct/wraith/Z = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc)) - Z.key = A.key - Z.faction |= "\ref[U]" - if(iscultist(U)) - if(SSticker.mode.name == "cult") - SSticker.mode:add_cultist(Z.mind) - else - SSticker.mode.cult+=Z.mind - SSticker.mode.update_cult_icons_added(Z.mind) - qdel(T) - to_chat(Z, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.") - to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") - Z.cancel_camera() - qdel(C) + var/mob/living/simple_animal/hostile/construct/wraith/C = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc)) + to_chat(C, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.") + init_construct(C,SH,SS,T) if("Artificer") - var/mob/living/simple_animal/hostile/construct/builder/Z = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc)) - Z.key = A.key - Z.faction |= "\ref[U]" - if(iscultist(U)) - if(SSticker.mode.name == "cult") - SSticker.mode:add_cultist(Z.mind) - else - SSticker.mode.cult+=Z.mind - SSticker.mode.update_cult_icons_added(Z.mind) - qdel(T) - to_chat(Z, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).") - to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") - Z.cancel_camera() - qdel(C) + var/mob/living/simple_animal/hostile/construct/builder/C = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc)) + to_chat(C, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).") + init_construct(C,SH,SS,T) else to_chat(U, "Creation failed!: The soul stone is empty! Go kill someone!") return +/proc/init_construct(mob/living/simple_animal/hostile/construct/C, mob/living/simple_animal/shade/SH, obj/item/soulstone/SS, obj/structure/constructshell/T) + SH.mind.transfer_to(C) + qdel(T) + qdel(SH) + to_chat(C, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") + C.cancel_camera() + qdel(SS) + /proc/makeNewConstruct(var/mob/living/simple_animal/hostile/construct/ctype, var/mob/target, var/mob/stoner = null, cultoverride = 0) if(jobban_isbanned(target, "cultist") || jobban_isbanned(target, "Syndicate")) return @@ -332,14 +300,14 @@ SSticker.mode.cult+=newstruct.mind SSticker.mode.update_cult_icons_added(newstruct.mind) if(stoner && iswizard(stoner)) - to_chat(newstruct, "You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.") + to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") else if(stoner && iscultist(stoner)) - to_chat(newstruct, "You are still bound to serve the cult, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.") + to_chat(newstruct, "You are still bound to serve the cult, follow their orders and help them complete their goals at all costs.") else - to_chat(newstruct, "You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.") + to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") newstruct.cancel_camera() -/obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0) +/obj/item/soulstone/proc/init_shade(mob/living/T, mob/U, vic = 0) new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton T.invisibility = 101 var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc ) @@ -355,19 +323,30 @@ S.name = "Shade of [T.real_name]" S.real_name = "Shade of [T.real_name]" S.key = T.key - if(U) - S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation - if(U && iscultist(U)) - SSticker.mode.add_cultist(S.mind, 0) S.cancel_camera() name = "soulstone: Shade of [T.real_name]" icon_state = "soulstone2" - if(U && iswizard(U)) - to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help [U.p_them()] succeed in their goals at all costs.") - else if(U && iscultist(U)) - to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help [U.p_them()] succeed in their goals at all costs.") + if(U) + S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation + if(iswizard(U)) + SSticker.mode.update_wiz_icons_added(S.mind) + S.mind.special_role = SPECIAL_ROLE_WIZARD_APPRENTICE + if(iscultist(U)) + SSticker.mode.add_cultist(S.mind, 0) + S.mind.special_role = SPECIAL_ROLE_CULTIST + S.mind.store_memory("Serve the cult's will.") + to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.") + else + S.mind.store_memory("Serve [U.real_name], your creator.") + to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs.") if(vic && U) to_chat(U, "Capture successful!: [T.real_name]'s soul has been ripped from [U.p_their()] body and stored within the soul stone.") + if(isrobot(T))//Robots have to dust or else they spill out an empty robot brain, and unequiping them spills robot components that shouldn't spawn. + T.dust() + else + for(var/obj/item/W in T) + T.unEquip(W) + qdel(T) /obj/item/soulstone/proc/get_shade_type() return /mob/living/simple_animal/shade/cult @@ -375,7 +354,7 @@ /obj/item/soulstone/anybody/get_shade_type() return /mob/living/simple_animal/shade -/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U) +/obj/item/soulstone/proc/getCultGhost(mob/living/T, mob/U) var/mob/dead/observer/chosen_ghost for(var/mob/dead/observer/ghost in GLOB.player_list) //We put them back in their body @@ -395,8 +374,5 @@ if(contents.len) //If they used the soulstone on someone else in the meantime return 0 T.ckey = chosen_ghost.ckey - for(var/obj/item/W in T) - T.unEquip(W) init_shade(T, U) - qdel(T) return 1 diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index c8bdeb37ac4..2c6e60c3d52 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -52,7 +52,7 @@ /obj/machinery/optable/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) - if(usr.stat || (!ishuman(user) && !isrobot(user)) || user.restrained() || !check_table(user) || user.weakened || user.stunned) + if(usr.stat || (!ishuman(user) && !isrobot(user)) || user.restrained() || !check_table(user) || user.IsWeakened() || user.stunned) return if(!ismob(O)) //humans only diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index b0368d652fb..0863b65415a 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -140,6 +140,9 @@ if(stat & (NOPOWER|BROKEN)) return + if(occupant == user) + return // you cant reach that + if(panel_open) to_chat(user, "Close the maintenance panel first.") return diff --git a/code/game/machinery/chiller.dm b/code/game/machinery/chiller.dm index afb17f3c90a..f29bb26e8ca 100644 --- a/code/game/machinery/chiller.dm +++ b/code/game/machinery/chiller.dm @@ -11,9 +11,7 @@ /obj/machinery/space_heater/air_conditioner/New() ..() - cell = new(src) - cell.charge = 1000 - cell.maxcharge = 1000 + cell = new /obj/item/stock_parts/cell(src) update_icon() return diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index 672ebed32e4..bcabdeb511e 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -71,8 +71,8 @@ health_display = "DEAD" else if(total_loss) health_display = "HURT ([total_loss])" - if(is_station_level(M.z) && !istype(M.loc, /turf/space)) - loc_display = "[get_area(M)]" + if(is_station_level(Tr.z) && !istype(Tr.loc, /turf/space)) + loc_display = "[get_area(Tr)]" dat += "ID: [T.id]
Subject: [M]
Location: [loc_display]
Health: [health_display]
" dat += "(Message Holder) |
" dat += "********************************
" diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index ae8b3f5829c..abf6dc725b3 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -380,7 +380,7 @@ cult_mode.bypass_phase() //Update any existing objectives involving this mob. - for(var/datum/objective/O in all_objectives) + for(var/datum/objective/O in GLOB.all_objectives) // We don't want revs to get objectives that aren't for heads of staff. Letting // them win or lose based on cryo is silly so we remove the objective. if(istype(O,/datum/objective/mutiny) && O.target == occupant.mind) @@ -395,7 +395,7 @@ if(!O) return O.find_target() if(!(O.target)) - all_objectives -= O + GLOB.all_objectives -= O O.owner.objectives -= O qdel(O) if(occupant.mind && occupant.mind.assigned_role) diff --git a/code/game/machinery/defib_mount.dm b/code/game/machinery/defib_mount.dm index 4f27dfa4be5..267ea5da392 100644 --- a/code/game/machinery/defib_mount.dm +++ b/code/game/machinery/defib_mount.dm @@ -53,9 +53,9 @@ . += "There are a pair of bolts in the defib unit housing securing the [src] to the wall." /obj/machinery/defibrillator_mount/process() - if(defib && defib.bcell && defib.bcell.charge < defib.bcell.maxcharge && is_operational()) + if(defib && defib.cell && defib.cell.charge < defib.cell.maxcharge && is_operational()) use_power(200) - defib.bcell.give(180) //90% efficiency, slightly better than the cell charger's 87.5% + defib.cell.give(180) //90% efficiency, slightly better than the cell charger's 87.5% update_icon() /obj/machinery/defibrillator_mount/update_icon() @@ -64,7 +64,7 @@ add_overlay("defib") if(defib.powered) add_overlay(defib.safety ? "online" : "emagged") - var/ratio = defib.bcell.charge / defib.bcell.maxcharge + var/ratio = defib.cell.charge / defib.cell.maxcharge ratio = CEILING(ratio * 4, 1) * 25 add_overlay("charge[ratio]") if(clamps_locked) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index f23734a0079..8bd7af5dad4 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -444,7 +444,7 @@ //Stolen from status_display /obj/machinery/door_timer/proc/texticon(tn, px = 0, py = 0) var/image/I = image('icons/obj/status_display.dmi', "blank") - var/len = lentext(tn) + var/len = length(tn) for(var/d = 1 to len) var/char = copytext(tn, len-d+1, len-d+2) diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index 4b512297ffd..12804cfcc88 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -28,21 +28,21 @@ /obj/machinery/poolcontroller/invisible/sea name = "Sea Controller" desc = "A controller for the underwater portion of the sea. Players shouldn't see this." - deep_water = TRUE + deep_water = TRUE -/obj/machinery/poolcontroller/Initialize(mapload) - var/contents_loop = linked_area +/obj/machinery/poolcontroller/Initialize(mapload) + var/contents_loop = linked_area if(!linked_area) contents_loop = range(srange, src) for(var/turf/T in contents_loop) if(istype(T, /turf/simulated/floor/beach/water)) var/turf/simulated/floor/beach/water/W = T - W.linkedcontroller = src + W.linkedcontroller = src linkedturfs += T else if(istype(T, /turf/unsimulated/beach/water)) var/turf/unsimulated/beach/water/W = T - W.linkedcontroller = src + W.linkedcontroller = src linkedturfs += T . = ..() @@ -121,7 +121,7 @@ return //Has internals, no drowning if((NO_BREATHE in drownee.dna.species.species_traits) || (BREATHLESS in drownee.mutations)) return //doesn't breathe, no drowning - if(isskrell(drownee) || isneara(drownee)) + if(HAS_TRAIT(drownee,TRAIT_WATERBREATH)) return //fish things don't drown if(drownee.stat == DEAD) //Dead spacemen don't drown more diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index a07c639c36f..68c029f2111 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -353,7 +353,7 @@ var/list/turret_icons to_chat(user, "You remove the turret and salvage some components.") if(installation) var/obj/item/gun/energy/Gun = new installation(loc) - Gun.power_supply.charge = gun_charge + Gun.cell.charge = gun_charge Gun.update_icon() if(prob(50)) new /obj/item/stack/sheet/metal(loc, rand(1,4)) @@ -857,7 +857,7 @@ var/list/turret_icons to_chat(user, "\the [I] is stuck to your hand, you cannot put it in \the [src]") return installation = I.type //installation becomes I.type - gun_charge = E.power_supply.charge //the gun's charge is stored in gun_charge + gun_charge = E.cell.charge //the gun's charge is stored in gun_charge to_chat(user, "You add [I] to the turret.") if(istype(installation, /obj/item/gun/energy/laser/tag/blue) || istype(installation, /obj/item/gun/energy/laser/tag/red)) @@ -964,7 +964,7 @@ var/list/turret_icons build_step = 3 var/obj/item/gun/energy/Gun = new installation(loc) - Gun.power_supply.charge = gun_charge + Gun.cell.charge = gun_charge Gun.update_icon() installation = null gun_charge = 0 diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index ff5410f6953..8e4e5e3dc59 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -107,8 +107,8 @@ if(charging) if(istype(charging, /obj/item/gun/energy)) var/obj/item/gun/energy/E = charging - if(E.power_supply.charge < E.power_supply.maxcharge) - E.power_supply.give(E.power_supply.chargerate * recharge_coeff) + if(E.cell.charge < E.cell.maxcharge) + E.cell.give(E.cell.chargerate * recharge_coeff) E.on_recharge() use_power(250) using_power = TRUE @@ -116,8 +116,8 @@ if(istype(charging, /obj/item/melee/baton)) var/obj/item/melee/baton/B = charging - if(B.bcell) - if(B.bcell.give(B.bcell.chargerate)) + if(B.cell) + if(B.cell.give(B.cell.chargerate)) use_power(200) using_power = TRUE @@ -141,8 +141,8 @@ if(istype(charging, /obj/item/bodyanalyzer)) var/obj/item/bodyanalyzer/B = charging - if(B.power_supply) - if(B.power_supply.give(B.power_supply.chargerate)) + if(B.cell) + if(B.cell.give(B.cell.chargerate)) use_power(200) using_power = TRUE @@ -155,13 +155,13 @@ if(istype(charging, /obj/item/gun/energy)) var/obj/item/gun/energy/E = charging - if(E.power_supply) - E.power_supply.emp_act(severity) + if(E.cell) + E.cell.emp_act(severity) else if(istype(charging, /obj/item/melee/baton)) var/obj/item/melee/baton/B = charging - if(B.bcell) - B.bcell.charge = 0 + if(B.cell) + B.cell.charge = 0 ..(severity) /obj/machinery/recharger/update_icon(using_power = FALSE) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier. diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 4b081307762..57903822b50 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -173,17 +173,17 @@ F.icon_state = "flash" if(istype(O,/obj/item/gun/energy/disabler/cyborg)) var/obj/item/gun/energy/disabler/cyborg/D = O - if(D.power_supply.charge < D.power_supply.maxcharge) + if(D.cell.charge < D.cell.maxcharge) var/obj/item/ammo_casing/energy/E = D.ammo_type[D.select] - D.power_supply.give(E.e_cost) + D.cell.give(E.e_cost) D.on_recharge() D.update_icon() else D.charge_tick = 0 if(istype(O,/obj/item/melee/baton)) var/obj/item/melee/baton/B = O - if(B.bcell) - B.bcell.charge = B.bcell.maxcharge + if(B.cell) + B.cell.charge = B.cell.maxcharge //Service if(istype(O,/obj/item/reagent_containers/food/condiment/enzyme)) if(O.reagents.get_reagent_amount("enzyme") < 50) diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index eb3052dd909..eecdc0e4f4a 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -8,6 +8,7 @@ var/const/SAFETY_COOLDOWN = 100 layer = MOB_LAYER+1 // Overhead anchored = 1 density = 1 + damage_deflection = 10 var/safety_mode = 0 // Temporarily stops machine if it detects a mob var/icon_name = "grinder-o" var/blood = 0 diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 00d29b43459..3cfe6fe50ff 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -18,9 +18,7 @@ /obj/machinery/space_heater/New() ..() - cell = new(src) - cell.charge = 1000 - cell.maxcharge = 1000 + cell = new /obj/item/stock_parts/cell(src) update_icon() return diff --git a/code/game/machinery/supply_display.dm b/code/game/machinery/supply_display.dm index d08f68b2914..1fe7ee6e4cb 100644 --- a/code/game/machinery/supply_display.dm +++ b/code/game/machinery/supply_display.dm @@ -14,7 +14,7 @@ else message1 = "CARGO" message2 = SSshuttle.supply.getTimerStr() - if(lentext(message2) > CHARS_PER_LINE) + if(length(message2) > CHARS_PER_LINE) message2 = "Error" update_display(message1, message2) diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index b47693f1dcb..a82cc58e028 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -62,6 +62,4 @@ ME.attach(src) /obj/mecha/combat/gygax/dark/add_cell() - cell = new /obj/item/stock_parts/cell/bluespace(src) - cell.charge = 30000 - cell.maxcharge = 30000 \ No newline at end of file + cell = new /obj/item/stock_parts/cell/hyper(src) diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index 4b17b172c55..7bd95d87a35 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -59,8 +59,6 @@ /obj/mecha/combat/marauder/seraph/add_cell() cell = new /obj/item/stock_parts/cell/bluespace(src) - cell.charge = 40000 - cell.maxcharge = 40000 /obj/mecha/combat/marauder/seraph/loaded/New() ..()//Let it equip whatever is needed. diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index 5b5f483b94f..aacd605b730 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -316,40 +316,38 @@ var/mob/originaloccupant = chassis.occupant spawn(0) src = null //if src is deleted, still process the syringe - for(var/i=0, i<6, i++) + var/max_range = 6 + for(var/i=0, i [M] was hit by the syringe!") - if(M.can_inject(null, TRUE)) - if(mechsyringe.reagents) - for(var/datum/reagent/A in mechsyringe.reagents.reagent_list) - R += A.id + " (" - R += num2text(A.volume) + ")," - add_attack_logs(originaloccupant, M, "Shot with [src] containing [R], transferred [mechsyringe.reagents.total_volume] units") - mechsyringe.icon_state = initial(mechsyringe.icon_state) - mechsyringe.icon = initial(mechsyringe.icon) - mechsyringe.reagents.reaction(M, INGEST) - mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume) - M.take_organ_damage(2) - break - else if(mechsyringe.loc == trg) - mechsyringe.icon_state = initial(mechsyringe.icon_state) - mechsyringe.icon = initial(mechsyringe.icon) - mechsyringe.update_icon() - break - else - mechsyringe.icon_state = initial(mechsyringe.icon_state) - mechsyringe.icon = initial(mechsyringe.icon) - mechsyringe.update_icon() + if(!step_towards(mechsyringe,trg)) + break + + var/list/mobs = new + for(var/mob/living/carbon/M in mechsyringe.loc) + mobs += M + var/mob/living/carbon/M = safepick(mobs) + if(M) + var/R + mechsyringe.visible_message(" [M] was hit by the syringe!") + if(M.can_inject(null, TRUE)) + if(mechsyringe.reagents) + for(var/datum/reagent/A in mechsyringe.reagents.reagent_list) + R += A.id + " (" + R += num2text(A.volume) + ")," + add_attack_logs(originaloccupant, M, "Shot with [src] containing [R], transferred [mechsyringe.reagents.total_volume] units") + mechsyringe.reagents.reaction(M, INGEST) + mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume) + M.take_organ_damage(2) + break + else if(mechsyringe.loc == trg) break sleep(1) + if(mechsyringe) + // Revert the syringe icon to normal one once it stops flying. + mechsyringe.icon_state = initial(mechsyringe.icon_state) + mechsyringe.icon = initial(mechsyringe.icon) + mechsyringe.update_icon() return 1 diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index aed3216332c..85f511395f1 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1,9 +1,3 @@ - - -#define MECHAMOVE_RAND 1 -#define MECHAMOVE_TURN 2 -#define MECHAMOVE_STEP 4 - /obj/mecha name = "Mecha" desc = "Exosuit" diff --git a/code/game/objects/items/decorations.dm b/code/game/objects/items/decorations.dm new file mode 100644 index 00000000000..59ff6574890 --- /dev/null +++ b/code/game/objects/items/decorations.dm @@ -0,0 +1,274 @@ +/obj/item/decorations + icon = 'icons/obj/decorations.dmi' + + +//duct tape decorations +/obj/item/decorations/sticky_decorations + w_class = WEIGHT_CLASS_TINY + +/obj/item/decorations/sticky_decorations/New() + . = ..() + AddComponent(/datum/component/ducttape, src, null, 0, 0, TRUE)//add this to something to make it sticky but without the tape overlay + + + +/obj/item/decorations/sticky_decorations/flammable + resistance_flags = FLAMMABLE + + +//Non-holiday decorations + +/obj/item/decorations/sticky_decorations/flammable/heart + name = "paper heart" + desc = "Do not break." + icon_state = "decoration_heart" + +/obj/item/decorations/sticky_decorations/flammable/star + name = "paper star" + desc = "Throw it and make a wish!" + icon_state = "decoration_star" + +/obj/item/decorations/sticky_decorations/flammable/singleeye + name = "paper eye" + desc = "Feels like it stares into your soul." + icon_state = "paper_eye" + +/obj/item/decorations/sticky_decorations/flammable/googlyeyes + name = "paper googly eyes" + desc = "Seems to be looking at something with interest." + icon_state = "paper_googly_eyes" + +/obj/item/decorations/sticky_decorations/flammable/paperclock + name = "paper clock" + desc = "A paper clock. Right at least twice a day." + icon_state = "paper_clock" + + +//Holiday decorations + +//Halloween decorations + +/obj/item/decorations/sticky_decorations/flammable/jack_o_lantern + name = "paper jack o'lantern" + desc = "A paper jack o'lantern. Although you can't put a candle in him he has a fun loving smile none the less!" + icon_state = "decoration_jack_o_lantern" + +/obj/item/decorations/sticky_decorations/flammable/ghost + name = "paper ghost" + desc = "A paper ghost. If it starts moving on its own, you know who to call." + icon_state = "decoration_ghost" + +/obj/item/decorations/sticky_decorations/flammable/spider + name = "paper spider" + desc = "A paper spider. Creepy but not venomous, thankfully." + icon_state = "decoration_spider" + +/obj/item/decorations/sticky_decorations/flammable/spiderweb + name = "paper spiderweb" + desc = "A paper spiderweb. You see someone wrote 'For Rent' on it." + icon_state = "decoration_spider_web" + +/obj/item/decorations/sticky_decorations/flammable/skull + name = "paper skull" + desc = "A paper skull. Seems a paper skeleton lost their head!" + icon_state = "decoration_skull" + +/obj/item/decorations/sticky_decorations/flammable/skeleton + name = "paper skeleton" + desc = "A paper skeleton. Instead of rattling, his bones rustle." + icon_state = "decoration_skeleton" + +/obj/item/decorations/sticky_decorations/flammable/cauldron + name = "paper cauldron" + desc = "A paper cauldron. Careful, a paper witch might be about." + icon_state = "paper_cauldron" + +//Christmas decorations + +/obj/item/decorations/sticky_decorations/flammable/snowman + name = "paper snowman" + desc = "A paper snowman. This one won't melt when it gets warm." + icon_state = "decoration_snowman" + +/obj/item/decorations/sticky_decorations/flammable/christmas_stocking + name = "paper stocking" + desc = "A paper Christmas stocking. Sadly you won't find gifts in it but at least you won't find coal either." + icon_state = "decoration_christmas_stocking" + +/obj/item/decorations/sticky_decorations/flammable/christmas_tree + name = "paper christmas tree" + desc = "A paper Christmas tree. Maybe someone will leave a present under it?" + icon_state = "decoration_christmas_tree" + +/obj/item/decorations/sticky_decorations/flammable/snowflake + name = "paper snowflake" + desc = "A paper snowflake. Imagine if snow was this big!" + icon_state = "decoration_snowflake" + +/obj/item/decorations/sticky_decorations/flammable/candy_cane + name = "paper candy cane" + desc = "A paper candy cane. Sadly, non-edible." + icon_state = "decoration_candy_cane" + +/obj/item/decorations/sticky_decorations/flammable/mistletoe + name = "paper mistletoe" + desc = "Paper mistletoe. If you stand next to this, expect to be kissed." + icon_state = "decoration_mistletoe" + +/obj/item/decorations/sticky_decorations/flammable/holly + name = "paper holly" + desc = "Paper holly. Wait is it the red berries or the white ones you kiss under?" + icon_state = "decoration_holly" + +//Tinsel + +/obj/item/decorations/sticky_decorations/flammable/tinsel + name = "paper tinsel" + desc = "Paper tinsel, because Nanotrasen is too cheap to buy the real deal." + icon_state = "decoration_tinsel_white" + +/obj/item/decorations/sticky_decorations/flammable/tinsel/red + icon_state = "decoration_tinsel_red" + +/obj/item/decorations/sticky_decorations/flammable/tinsel/blue + icon_state = "decoration_tinsel_blue" + +/obj/item/decorations/sticky_decorations/flammable/tinsel/yellow + icon_state = "decoration_tinsel_yellow" + +/obj/item/decorations/sticky_decorations/flammable/tinsel/purple + icon_state = "decoration_tinsel_purple" + +/obj/item/decorations/sticky_decorations/flammable/tinsel/green + icon_state = "decoration_tinsel_green" + +/obj/item/decorations/sticky_decorations/flammable/tinsel/orange + icon_state = "decoration_tinsel_orange" + +/obj/item/decorations/sticky_decorations/flammable/tinsel/black + icon_state = "decoration_tinsel_black" + +/obj/item/decorations/sticky_decorations/flammable/tinsel/halloween + desc = "Paper tinsel, because Nanotrasen is too cheap to buy the real deal. At least this one is spooky." + icon_state = "decoration_tinsel_halloween" + +//Valentines decorations + + + +/obj/item/decorations/sticky_decorations/flammable/arrowed_heart + name = "paper heart" + desc = "A paper heart. It's been shot through and Cupid is to blame!" + icon_state = "decoration_arrow_heart" + +/obj/item/decorations/sticky_decorations/flammable/heart_chain + name = "paper heart chain" + desc = "A paper chain of hearts. May our hearts always be together." + icon_state = "decoration_heart_chain" + +//St. Patrick's day + +/obj/item/decorations/sticky_decorations/flammable/four_leaf_clover + name = "paper four leaf clover" + desc = "A paper four leaf clover. Take it with you, it might bring good luck!" + icon_state = "decoration_four_leaf_clover" + +/obj/item/decorations/sticky_decorations/flammable/pot_of_gold + name = "paper pot of gold" + desc = "A paper pot of gold. You found the end of the paper rainbow!" + icon_state = "decoration_pot_o_gold" + +/obj/item/decorations/sticky_decorations/flammable/leprechaun_hat + name = "paper leprechaun hat" + desc = "A paper leprechaun hat. If you find the paper leprechaun that dropped this they might give you their pot of paper gold!" + icon_state = "decoration_leprechaun_hat" + +//Easter + +/obj/item/decorations/sticky_decorations/flammable/easter_bunny + name = "paper Easter bunny" + desc = "A paper Easter bunny. Help him find his lost eggs!" + icon_state = "decoration_easter_bunny" + +/obj/item/decorations/sticky_decorations/flammable/easter_egg + name = "paper Easter egg" + desc = "A paper Easter egg. If the chef won't let us use their eggs, then this will have to do." + icon_state = "decoration_easter_egg_blue" + +/obj/item/decorations/sticky_decorations/flammable/easter_egg/yellow + icon_state = "decoration_easter_egg_yellow" + +/obj/item/decorations/sticky_decorations/flammable/easter_egg/red + icon_state = "decoration_easter_egg_red" + +/obj/item/decorations/sticky_decorations/flammable/easter_egg/purple + icon_state = "decoration_easter_egg_purple" + +/obj/item/decorations/sticky_decorations/flammable/easter_egg/orange + icon_state = "decoration_easter_egg_orange" + + + + +/////// +//Decorative structures +/////// + + +/obj/structure/decorative_structures + icon = 'icons/obj/decorations.dmi' + icon_state = "" + density = 1 + anchored = 0 + max_integrity = 100 + +/obj/structure/decorative_structures/metal + flags = CONDUCT + +/obj/structure/decorative_structures/metal/statue/metal_angel + name = "metal angel statue" + desc = "You feel a holy presence looking back at you." + icon_state = "metal_angel_statue" + +/obj/structure/decorative_structures/metal/statue/golden_disk + name = "golden disk statue" + desc = "You aren't sure what the runes say around the large plasma crystal." + icon_state = "golden_disk_statue" + +/obj/structure/decorative_structures/metal/statue/sun + name = "sun statue" + desc = "You wonder if you could be so grossly incandescent." + icon_state = "sun_statue" + +/obj/structure/decorative_structures/metal/statue/tesla + name = "tesla statue" + desc = "Lady Tesla, a powerful and dangerous mistress." + icon_state = "tesla_statue" + +/obj/structure/decorative_structures/metal/statue/moon + name = "moon statue" + desc = "Expect a lot of Vulps to howl around this thing." + icon_state = "moon_statue" + +/obj/structure/decorative_structures/metal/statue/tesla_monument + name = "tesla monument" + desc = "Praise be to lady Tesla!" + icon_state = "tesla_monument" + + +/obj/structure/decorative_structures/flammable + resistance_flags = FLAMMABLE + max_integrity = 50 + + +/obj/structure/decorative_structures/flammable/grandfather_clock + name = "grandfather clock" + desc = "Seems the hands have stopped." + icon_state = "grandfather_clock" + +/obj/structure/decorative_structures/flammable/lava_land_display + name = "lava land display" + desc = "The tomb of many a miner and possibly a home for much worse things." + icon_state = "lava_land_display" + + diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 0c791be07cc..536c3dfd0e2 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -600,7 +600,7 @@ REAGENT SCANNER throw_speed = 5 throw_range = 10 origin_tech = "magnets=6;biotech=6" - var/obj/item/stock_parts/cell/power_supply + var/obj/item/stock_parts/cell/cell var/cell_type = /obj/item/stock_parts/cell/upgraded var/ready = TRUE // Ready to scan var/time_to_use = 0 // How much time remaining before next scan is available. @@ -609,7 +609,7 @@ REAGENT SCANNER var/scan_cd = 60 SECONDS //how long before we can scan again /obj/item/bodyanalyzer/get_cell() - return power_supply + return cell /obj/item/bodyanalyzer/advanced cell_type = /obj/item/stock_parts/cell/upgraded/plus @@ -624,8 +624,8 @@ REAGENT SCANNER /obj/item/bodyanalyzer/New() ..() - power_supply = new cell_type(src) - power_supply.give(power_supply.maxcharge) + cell = new cell_type(src) + cell.give(cell.maxcharge) update_icon() /obj/item/bodyanalyzer/proc/setReady() @@ -635,7 +635,7 @@ REAGENT SCANNER /obj/item/bodyanalyzer/update_icon(printing = FALSE) overlays.Cut() - var/percent = power_supply.percent() + var/percent = cell.percent() if(ready) icon_state = "bodyanalyzer_1" else @@ -657,7 +657,7 @@ REAGENT SCANNER playsound(user.loc, 'sound/machines/buzz-sigh.ogg', 50, 1) return - if(power_supply.charge >= usecharge) + if(cell.charge >= usecharge) mobScan(M, user) else to_chat(user, "The scanner beeps angrily at you! It's out of charge!") @@ -691,7 +691,7 @@ REAGENT SCANNER var/mob/living/silicon/robot/R = user R.cell.use(usecharge) else - power_supply.use(usecharge) + cell.use(usecharge) ready = FALSE update_icon(TRUE) addtimer(CALLBACK(src, /obj/item/bodyanalyzer/.proc/setReady), scan_cd) diff --git a/code/game/objects/items/documents.dm b/code/game/objects/items/documents.dm index a2b1f2fdedb..2bf519b4a22 100644 --- a/code/game/objects/items/documents.dm +++ b/code/game/objects/items/documents.dm @@ -33,6 +33,7 @@ name = "'Yellow' secret documents" desc = "\"Top Secret\" documents printed on special copy-protected paper. It details sensitive Syndicate operational intelligence. These documents are marked \"Yellow\"." icon_state = "docs_yellow" + resistance_flags = NONE /obj/item/documents/syndicate/yellow/trapped desc = "\"Top Secret\" documents printed on special copy-protected paper. It details sensitive Syndicate operational intelligence. These documents are marked \"Yellow\", and have a thin film of clear material covering their surface." diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 7dc1a97a735..9f8c877aa24 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -12,7 +12,7 @@ var/heal_brute = 0 var/heal_burn = 0 var/self_delay = 20 - var/unique_handling = 0 //some things give a special prompt, do we want to bypass some checks in parent? + var/unique_handling = FALSE //some things give a special prompt, do we want to bypass some checks in parent? var/stop_bleeding = 0 var/healverb = "bandage" @@ -31,28 +31,20 @@ var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) if(!H.can_inject(user, TRUE)) - return 1 + return TRUE if(!affecting) to_chat(user, "That limb is missing!") - return 1 + return TRUE if(affecting.is_robotic()) to_chat(user, "This can't be used on a robotic limb.") - return 1 - - if(stop_bleeding) - if(H.bleedsuppress) - to_chat(user, "[H]'s bleeding is already bandaged!") - return 1 - else if(!H.bleed_rate) - to_chat(user, "[H] isn't bleeding!") - return 1 + return TRUE if(M == user && !unique_handling) user.visible_message("[user] starts to apply [src] on [H]...") if(!do_mob(user, H, self_delay)) - return 1 + return TRUE return if(isanimal(M)) @@ -123,6 +115,7 @@ desc = "Some sterile gauze to wrap around bloody stumps." icon_state = "gauze" origin_tech = "biotech=2" + heal_brute = 10 stop_bleeding = 1800 /obj/item/stack/medical/bruise_pack/attackby(obj/item/I, mob/user, params) @@ -140,13 +133,13 @@ /obj/item/stack/medical/bruise_pack/attack(mob/living/M, mob/user) if(..()) - return 1 + return TRUE if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - if(affecting.open == 0) + if(affecting.open == FALSE) affecting.germ_level = 0 if(stop_bleeding) @@ -187,6 +180,7 @@ icon_state = "ointment" origin_tech = "biotech=2" healverb = "salve" + heal_burn = 10 /obj/item/stack/medical/ointment/attack(mob/living/M, mob/user) if(..()) @@ -196,7 +190,7 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - if(affecting.open == 0) + if(affecting.open == FALSE) affecting.germ_level = 0 heal(H, user) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 71d5e36badf..0ad64e24f23 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1069,6 +1069,22 @@ obj/item/toy/cards/deck/syndicate/black name = "tuxedo cat plushie" icon_state = "tuxedocat" +/obj/item/toy/plushie/voxplushie + name = "vox plushie" + desc = "A stitched-together vox, fresh from the skipjack. Press its belly to hear it skree!" + icon_state = "plushie_vox" + item_state = "plushie_vox" + var/cooldown = 0 + +/obj/item/toy/plushie/voxplushie/attack_self(mob/user) + if(!cooldown) + playsound(user, 'sound/voice/shriek1.ogg', 10, 0) + visible_message("Skreee!") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + //New generation TG plushies /obj/item/toy/plushie/lizardplushie diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 23e81e3c41d..581c4395650 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -20,11 +20,11 @@ var/safety = 1 //if you can zap people with the defibs on harm mode var/powered = 0 //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise var/obj/item/twohanded/shockpaddles/paddles - var/obj/item/stock_parts/cell/high/bcell = null + var/obj/item/stock_parts/cell/high/cell = null var/combat = 0 //can we revive through space suits? /obj/item/defibrillator/get_cell() - return bcell + return cell /obj/item/defibrillator/New() //starts without a cell for rnd ..() @@ -35,7 +35,7 @@ /obj/item/defibrillator/loaded/New() //starts with hicap ..() paddles = make_paddles() - bcell = new(src) + cell = new(src) update_icon() return @@ -49,8 +49,8 @@ . += "Ctrl-click to remove the paddles from the defibrillator." /obj/item/defibrillator/proc/update_power() - if(bcell) - if(bcell.charge < paddles.revivecost) + if(cell) + if(cell.charge < paddles.revivecost) powered = 0 else powered = 1 @@ -63,21 +63,21 @@ overlays += "[icon_state]-paddles" if(powered) overlays += "[icon_state]-powered" - if(!bcell) + if(!cell) overlays += "[icon_state]-nocell" if(!safety) overlays += "[icon_state]-emagged" /obj/item/defibrillator/proc/update_charge() if(powered) //so it doesn't show charge if it's unpowered - if(bcell) - var/ratio = bcell.charge / bcell.maxcharge + if(cell) + var/ratio = cell.charge / cell.maxcharge ratio = Ceiling(ratio*4) * 25 overlays += "[icon_state]-charge[ratio]" /obj/item/defibrillator/CheckParts(list/parts_list) ..() - bcell = locate(/obj/item/stock_parts/cell) in contents + cell = locate(/obj/item/stock_parts/cell) in contents update_icon() /obj/item/defibrillator/ui_action_click() @@ -90,7 +90,7 @@ /obj/item/defibrillator/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stock_parts/cell)) var/obj/item/stock_parts/cell/C = W - if(bcell) + if(cell) to_chat(user, "[src] already has a cell.") else if(C.maxcharge < paddles.revivecost) @@ -98,14 +98,14 @@ return user.drop_item() W.loc = src - bcell = W + cell = W to_chat(user, "You install a cell in [src].") if(istype(W, /obj/item/screwdriver)) - if(bcell) - bcell.update_icon() - bcell.loc = get_turf(src.loc) - bcell = null + if(cell) + cell.update_icon() + cell.loc = get_turf(src.loc) + cell = null to_chat(user, "You remove the cell from the [src].") update_icon() @@ -120,7 +120,7 @@ to_chat(user, "You silently enable [src]'s safety protocols with the card.") /obj/item/defibrillator/emp_act(severity) - if(bcell) + if(cell) deductcharge(1000 / severity) if(safety) safety = 0 @@ -182,15 +182,15 @@ var/M = get(paddles, /mob) remove_paddles(M) QDEL_NULL(paddles) - QDEL_NULL(bcell) + QDEL_NULL(cell) return ..() /obj/item/defibrillator/proc/deductcharge(var/chrgdeductamt) - if(bcell) - if(bcell.charge < (paddles.revivecost+chrgdeductamt)) + if(cell) + if(cell.charge < (paddles.revivecost+chrgdeductamt)) powered = 0 update_icon() - if(bcell.use(chrgdeductamt)) + if(cell.use(chrgdeductamt)) update_icon() return 1 else @@ -199,8 +199,8 @@ /obj/item/defibrillator/proc/cooldowncheck(var/mob/user) spawn(50) - if(bcell) - if(bcell.charge >= paddles.revivecost) + if(cell) + if(cell.charge >= paddles.revivecost) user.visible_message("[src] beeps: Unit ready.") playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) else @@ -226,7 +226,7 @@ /obj/item/defibrillator/compact/loaded/New() ..() paddles = make_paddles() - bcell = new(src) + cell = new(src) update_icon() return @@ -239,7 +239,7 @@ /obj/item/defibrillator/compact/combat/loaded/New() ..() paddles = make_paddles() - bcell = new /obj/item/stock_parts/cell/infinite(src) + cell = new /obj/item/stock_parts/cell/infinite(src) update_icon() return diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 4d36c640784..4cc4cb948ce 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -18,7 +18,7 @@ - + @@ -164,7 +164,7 @@ - + @@ -805,7 +805,7 @@ - + @@ -828,7 +828,7 @@ - + diff --git a/code/game/objects/items/weapons/storage/artistic_toolbox.dm b/code/game/objects/items/weapons/storage/artistic_toolbox.dm index 0d8613cce4a..0c0e2b03b3c 100644 --- a/code/game/objects/items/weapons/storage/artistic_toolbox.dm +++ b/code/game/objects/items/weapons/storage/artistic_toolbox.dm @@ -71,7 +71,7 @@ return if(!victim) return - if(!victim.stat && !victim.restrained() && !victim.weakened) + if(!victim.stat && !victim.restrained() && !victim.IsWeakened()) to_chat(user, "They're moving too much to feed to His Grace!") return user.visible_message("[user] is trying to feed [victim] to [src]!") diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 5560f3b4306..0ebd553fc3b 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -396,7 +396,7 @@ ..() new /obj/item/lightreplacer(src) new /obj/item/holosign_creator(src) - new /obj/item/reagent_containers/spray(src) + new /obj/item/reagent_containers/spray/cleaner(src) new /obj/item/soap(src) new /obj/item/grenade/chem_grenade/cleaner(src) new /obj/item/grenade/chem_grenade/cleaner(src) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 9ef53c54601..b57bd8b9e50 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -459,7 +459,7 @@ boxes.plane = HUD_PLANE closer = new /obj/screen/close( ) closer.master = src - closer.icon_state = "x" + closer.icon_state = "backpack_close" closer.layer = ABOVE_HUD_LAYER closer.plane = ABOVE_HUD_PLANE orient2hud() diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 232d8384e45..6782057d928 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -13,7 +13,7 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) var/stunforce = 7 var/status = 0 - var/obj/item/stock_parts/cell/high/bcell = null + var/obj/item/stock_parts/cell/high/cell = null var/hitcost = 1000 var/throw_hit_chance = 35 @@ -22,7 +22,7 @@ return FIRELOSS /obj/item/melee/baton/get_cell() - return bcell + return cell /obj/item/melee/baton/New() ..() @@ -30,7 +30,7 @@ return /obj/item/melee/baton/Destroy() - QDEL_NULL(bcell) + QDEL_NULL(cell) return ..() /obj/item/melee/baton/throw_impact(atom/hit_atom) @@ -40,7 +40,7 @@ /obj/item/melee/baton/loaded/New() //this one starts with a cell pre-installed. ..() - bcell = new(src) + cell = new(src) update_icon() return @@ -55,12 +55,12 @@ return 1 else return 0 - if(bcell) - if(bcell.charge < (hitcost+chrgdeductamt)) // If after the deduction the baton doesn't have enough charge for a stun hit it turns off. + if(cell) + if(cell.charge < (hitcost+chrgdeductamt)) // If after the deduction the baton doesn't have enough charge for a stun hit it turns off. status = 0 update_icon() playsound(loc, "sparks", 75, 1, -1) - if(bcell.use(chrgdeductamt)) + if(cell.use(chrgdeductamt)) return 1 else return 0 @@ -68,7 +68,7 @@ /obj/item/melee/baton/update_icon() if(status) icon_state = "[base_icon]_active" - else if(!bcell) + else if(!cell) icon_state = "[base_icon]_nocell" else icon_state = "[base_icon]" @@ -77,15 +77,15 @@ . = ..() if(isrobot(loc)) . += "This baton is drawing power directly from your own internal charge." - if(bcell) - . += "The baton is [round(bcell.percent())]% charged." - if(!bcell) + if(cell) + . += "The baton is [round(cell.percent())]% charged." + if(!cell) . += "The baton does not have a power source installed." /obj/item/melee/baton/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stock_parts/cell)) var/obj/item/stock_parts/cell/C = W - if(bcell) + if(cell) to_chat(user, "[src] already has a cell.") else if(C.maxcharge < hitcost) @@ -94,15 +94,15 @@ if(!user.unEquip(W)) return W.loc = src - bcell = W + cell = W to_chat(user, "You install a cell in [src].") update_icon() else if(istype(W, /obj/item/screwdriver)) - if(bcell) - bcell.update_icon() - bcell.loc = get_turf(src.loc) - bcell = null + if(cell) + cell.update_icon() + cell.loc = get_turf(src.loc) + cell = null to_chat(user, "You remove the cell from the [src].") status = 0 update_icon() @@ -121,13 +121,13 @@ else status = 0 to_chat(user, "You do not have enough reserve power to charge the [src]!") - else if(bcell && bcell.charge >= hitcost) + else if(cell && cell.charge >= hitcost) status = !status to_chat(user, "[src] is now [status ? "on" : "off"].") playsound(loc, "sparks", 75, 1, -1) else status = 0 - if(!bcell) + if(!cell) to_chat(user, "[src] does not have a power source!") else to_chat(user, "[src] is out of charge.") @@ -203,13 +203,13 @@ H.forcesay(GLOB.hit_appends) /obj/item/melee/baton/emp_act(severity) - if(bcell) + if(cell) deductcharge(1000 / severity) ..() /obj/item/melee/baton/wash(mob/user, atom/source) - if(bcell) - if(bcell.charge > 0 && status == 1) + if(cell) + if(cell.charge > 0 && status == 1) flick("baton_active", source) user.Stun(stunforce) user.Weaken(stunforce) diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index c463c7897fc..117bb90c35f 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -70,9 +70,10 @@ Frequency: for(var/obj/item/implant/tracking/T in GLOB.tracked_implants) if(!T.implanted || !T.imp_in) continue + var/turf/Tr = get_turf(T) - if(T && T.z == z) - temp += "[T.id]: [T.imp_in.x], [T.imp_in.y], [T.imp_in.z]
" + if(Tr && Tr.z == sr.z) + temp += "[T.id]: [Tr.x], [Tr.y], [Tr.z]
" temp += "You are at \[[sr.x],[sr.y],[sr.z]\]." temp += "

Refresh
" diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 797f0922565..6849e6d07d3 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -132,7 +132,7 @@ if(user.restrained() || user.buckled) to_chat(user, "You need your hands and legs free for this.") return 0 - if(user.stat || user.paralysis || user.sleeping || user.lying || user.weakened) + if(user.stat || user.paralysis || user.sleeping || user.lying || user.IsWeakened()) return 0 if(issilicon(user)) to_chat(user, "You need hands for this.") diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index b58aecc7c78..23ee0d0c5df 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -270,7 +270,7 @@ return if(O.loc == user) return - if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.lying) + if(user.restrained() || user.stat || user.IsWeakened() || user.stunned || user.paralysis || user.lying) return if((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src))) return diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index a89bce34396..504d2b29644 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -104,6 +104,7 @@ icon_opened = "toolclosetopen" /obj/structure/closet/toolcloset/New() + ..() if(prob(40)) new /obj/item/clothing/suit/storage/hazardvest(src) if(prob(70)) diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 274645933b2..da3ec759d36 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -88,12 +88,12 @@ if(!playing || shouldStopPlaying(user)) //If the instrument is playing, or special case playing = 0 return - if(lentext(note) == 0) + if(length(note) == 0) continue var/cur_note = text2ascii(note) - 96 if(cur_note < 1 || cur_note > 7) continue - for(var/i=2 to lentext(note)) + for(var/i=2 to length(note)) var/ni = copytext(note,i,i+1) if(!text2num(ni)) if(ni == "#" || ni == "b" || ni == "n") @@ -159,11 +159,11 @@ if(!in_range(instrumentObj, usr)) return - if(lentext(t) >= 12000) + if(length(t) >= 12000) var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") if(cont == "no") break - while(lentext(t) > 12000) + while(length(t) > 12000) //split into lines spawn() @@ -180,7 +180,7 @@ lines.Cut(201) var/linenum = 1 for(var/l in lines) - if(lentext(l) > 200) + if(length(l) > 200) to_chat(usr, "Line [linenum] too long!") lines.Remove(l) else @@ -223,7 +223,7 @@ return if(lines.len > 200) return - if(lentext(newline) > 200) + if(length(newline) > 200) newline = copytext(newline, 1, 200) lines.Insert(num, newline) @@ -241,7 +241,7 @@ var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null) if(!content || !in_range(instrumentObj, usr)) return - if(lentext(content) > 200) + if(length(content) > 200) content = copytext(content, 1, 200) if(num > lines.len || num < 1) return diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index e3ebb0579a4..51738446750 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -12,9 +12,9 @@ /obj/structure/reflector/bullet_act(obj/item/projectile/P) var/turf/reflector_turf = get_turf(src) var/turf/reflect_turf - var/new_dir = get_reflection(dir, P.dir) if(!istype(P, /obj/item/projectile/beam)) return ..() + var/new_dir = get_reflection(dir, P.dir) if(new_dir) reflect_turf = get_step(reflect_turf, new_dir) else @@ -30,6 +30,10 @@ P.current = reflector_turf P.yo = reflect_turf.y - reflector_turf.y P.xo = reflect_turf.x - reflector_turf.x + P.ignore_source_check = TRUE //If shot by a laser, will now hit the mob that fired it + var/reflect_angle = dir2angle(new_dir) + P.setAngle(reflect_angle) + new_dir = 0 return -1 diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm index f960a7443ee..b3b3157c391 100644 --- a/code/game/objects/structures/spawner.dm +++ b/code/game/objects/structures/spawner.dm @@ -85,4 +85,16 @@ /obj/structure/spawner/mining/basilisk name = "basilisk den" desc = "A den housing a nest of basilisks, bring a coat." - mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk) \ No newline at end of file + mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk) + +/obj/structure/spawner/headcrab + name = "headcrab nest" + desc = "A living nest for headcrabs. It is moving ominously." + icon_state = "headcrab_nest" + icon = 'icons/mob/headcrab.dmi' + max_integrity = 200 + max_mobs = 15 + spawn_time = 600 + mob_types = list(/mob/living/simple_animal/hostile/headcrab, /mob/living/simple_animal/hostile/headcrab/fast, /mob/living/simple_animal/hostile/headcrab/poison) + spawn_text = "crawls out of" + faction = list("hostile") \ No newline at end of file diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index f8c65089324..6a2180efcac 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -8,6 +8,7 @@ max_integrity = 120 var/image/nest_overlay comfort = 0 + flags = NODECONSTRUCT /obj/structure/bed/nest/New() nest_overlay = image('icons/mob/alien.dmi', "nestoverlay", layer=MOB_LAYER - 0.2) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index c4c0f9b7965..c8c148ac1e1 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -696,7 +696,7 @@ return /obj/structure/rack/attack_hand(mob/living/user) - if(user.weakened || user.resting || user.lying) + if(user.IsWeakened() || user.resting || user.lying) return user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_KICK) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 654fb23fdd6..553f2c476e7 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -481,10 +481,9 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f reinf = TRUE cancolor = TRUE heat_resistance = 1600 - armor = list("melee" = 80, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) - max_integrity = 75 + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + max_integrity = 50 explosion_block = 1 - damage_deflection = 11 glass_type = /obj/item/stack/sheet/rglass /obj/structure/window/reinforced/tinted @@ -554,9 +553,9 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f shardtype = /obj/item/shard/plasma glass_type = /obj/item/stack/sheet/plasmaglass heat_resistance = 32000 - max_integrity = 200 + max_integrity = 150 explosion_block = 1 - armor = list("melee" = 80, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) + armor = list("melee" = 75, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) /obj/structure/window/plasmabasic/BlockSuperconductivity() return 1 @@ -570,7 +569,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f reinf = TRUE max_integrity = 500 explosion_block = 2 - armor = list("melee" = 80, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) + armor = list("melee" = 85, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) damage_deflection = 21 /obj/structure/window/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -607,7 +606,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f smooth = SMOOTH_TRUE canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced) explosion_block = 1 - armor = list("melee" = 80, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) + armor = list("melee" = 75, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) /obj/structure/window/full/plasmareinforced name = "reinforced plasma window" @@ -620,7 +619,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f reinf = TRUE max_integrity = 1000 explosion_block = 2 - armor = list("melee" = 80, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) + armor = list("melee" = 85, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) /obj/structure/window/full/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) return @@ -632,10 +631,10 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f icon_state = "r_window" smooth = SMOOTH_TRUE canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced) - max_integrity = 150 + max_integrity = 100 reinf = TRUE heat_resistance = 1600 - armor = list("melee" = 80, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) explosion_block = 1 glass_type = /obj/item/stack/sheet/rglass cancolor = TRUE @@ -658,11 +657,11 @@ obj/structure/window/full/reinforced/ice desc = "A reinforced, air-locked pod window." icon = 'icons/obj/smooth_structures/shuttle_window.dmi' icon_state = "shuttle_window" - max_integrity = 150 + max_integrity = 100 reinf = TRUE heat_resistance = 1600 explosion_block = 3 - armor = list("melee" = 90, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) smooth = SMOOTH_TRUE canSmoothWith = null glass_type = /obj/item/stack/sheet/titaniumglass @@ -679,12 +678,12 @@ obj/structure/window/full/reinforced/ice icon = 'icons/obj/smooth_structures/plastitanium_window.dmi' icon_state = "plastitanium_window" dir = FULLTILE_WINDOW_DIR - max_integrity = 200 + max_integrity = 100 fulltile = TRUE flags = PREVENT_CLICK_UNDER reinf = TRUE heat_resistance = 1600 - armor = list("melee" = 95, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) smooth = SMOOTH_TRUE canSmoothWith = null explosion_block = 3 @@ -744,4 +743,4 @@ obj/structure/window/full/reinforced/ice dir = FULLTILE_WINDOW_DIR max_integrity = 120 level = 3 - glass_amount = 2 + glass_amount = 2 \ No newline at end of file diff --git a/code/game/turfs/simulated/floor/asteroid.dm b/code/game/turfs/simulated/floor/asteroid.dm index 66c4cf1ac4d..049f5ff8509 100644 --- a/code/game/turfs/simulated/floor/asteroid.dm +++ b/code/game/turfs/simulated/floor/asteroid.dm @@ -283,12 +283,14 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me else //this is not danger, don't spawn a boss, spawn something else randumb = pickweight(mob_spawn_list) - for(var/mob/living/simple_animal/hostile/H in urange(12,T)) //prevents mob clumps - if((ispath(randumb, /mob/living/simple_animal/hostile/megafauna) || ismegafauna(H)) && get_dist(src, H) <= 7) + for(var/thing in urange(12, T)) //prevents mob clumps + if(!ishostile(thing) && !istype(thing, /obj/structure/spawner)) + continue + if((ispath(randumb, /mob/living/simple_animal/hostile/megafauna) || ismegafauna(thing)) && get_dist(src, thing) <= 7) return //if there's a megafauna within standard view don't spawn anything at all - if(ispath(randumb, /mob/living/simple_animal/hostile/asteroid) || istype(H, /mob/living/simple_animal/hostile/asteroid)) + if(ispath(randumb, /mob/living/simple_animal/hostile/asteroid) || istype(thing, /mob/living/simple_animal/hostile/asteroid)) return //if the random is a standard mob, avoid spawning if there's another one within 12 tiles - if((ispath(randumb, /obj/structure/spawner/lavaland) || istype(H, /obj/structure/spawner/lavaland)) && get_dist(src, H) <= 2) + if((ispath(randumb, /obj/structure/spawner/lavaland) || istype(thing, /obj/structure/spawner/lavaland)) && get_dist(src, thing) <= 2) return //prevents tendrils spawning in each other's collapse range if(ispath(randumb, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it diff --git a/code/game/turfs/simulated/floor/indestructible.dm b/code/game/turfs/simulated/floor/indestructible.dm index 480793fb561..3896dc513f2 100644 --- a/code/game/turfs/simulated/floor/indestructible.dm +++ b/code/game/turfs/simulated/floor/indestructible.dm @@ -45,7 +45,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE /turf/simulated/floor/indestructible/necropolis/Initialize(mapload) . = ..() @@ -65,7 +64,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE /turf/simulated/floor/indestructible/boss/air oxygen = MOLES_O2STANDARD @@ -79,7 +77,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE smooth = SMOOTH_TRUE /turf/simulated/floor/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 5a097b5fe5b..a29eab05a3b 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -188,5 +188,4 @@ desc = "Warm brass plating. You can feel it gently vibrating, as if machinery is on the other side." icon_state = "reebe" baseturf = /turf/simulated/floor/clockwork/reebe - uses_overlay = FALSE - planetary_atmos = TRUE + uses_overlay = FALSE \ No newline at end of file diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index 1ce6c2b90f0..86a6b228b60 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -469,13 +469,13 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) if(playercid) cidsearch = "AND computerid = '[playercid]' " else - if(adminckey && lentext(adminckey) >= 3) + if(adminckey && length(adminckey) >= 3) adminsearch = "AND a_ckey LIKE '[adminckey]%' " - if(playerckey && lentext(playerckey) >= 3) + if(playerckey && length(playerckey) >= 3) playersearch = "AND ckey LIKE '[playerckey]%' " - if(playerip && lentext(playerip) >= 3) + if(playerip && length(playerip) >= 3) ipsearch = "AND ip LIKE '[playerip]%' " - if(playercid && lentext(playercid) >= 7) + if(playercid && length(playercid) >= 7) cidsearch = "AND computerid LIKE '[playercid]%' " if(dbbantype) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 045819c365b..d776b4a2095 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -1,5 +1,5 @@ //Blocks an attempt to connect before even creating our client datum thing. -world/IsBanned(key, address, computer_id, check_ipintel = TRUE) +world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE) if(!config.ban_legacy_system) if(address) @@ -11,11 +11,20 @@ world/IsBanned(key, address, computer_id, check_ipintel = TRUE) log_adminwarn("Failed Login (invalid data): [key] [address]-[computer_id]") return list("reason"="invalid login data", "desc"="Error: Could not check ban status, please try again. Error message: Your computer provided invalid or blank information to the server on connection (BYOND Username, IP, and Computer ID). Provided information for reference: Username: '[key]' IP: '[address]' Computer ID: '[computer_id]'. If you continue to get this error, please restart byond or contact byond support.") + if(type == "world") + return ..() //shunt world topic banchecks to purely to byond's internal ban system + if(text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire log_adminwarn("Failed Login (invalid cid): [key] [address]-[computer_id]") return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.") + var/admin = 0 var/ckey = ckey(key) + + var/client/C = GLOB.directory[ckey] + if (C && ckey == C.ckey && computer_id == C.computer_id && address == C.address) + return //don't recheck connected clients. + if((ckey in admin_datums) || (ckey in GLOB.deadmins)) var/datum/admins/A = admin_datums[ckey] if(A && (A.rights & R_ADMIN)) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index dfba257b66c..6903930bee6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -3077,7 +3077,7 @@ else if(href_list["ac_set_channel_name"]) src.admincaster_feed_channel.channel_name = strip_html_simple(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "")) while(findtext(src.admincaster_feed_channel.channel_name," ") == 1) - src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1) + src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,length(src.admincaster_feed_channel.channel_name)+1) src.access_news_network() else if(href_list["ac_set_channel_lock"]) @@ -3116,7 +3116,7 @@ else if(href_list["ac_set_new_message"]) src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story", "Network Channel Handler", "")) while(findtext(src.admincaster_feed_message.body," ") == 1) - src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,lentext(src.admincaster_feed_message.body)+1) + src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,length(src.admincaster_feed_message.body)+1) src.access_news_network() else if(href_list["ac_submit_new_message"]) @@ -3170,13 +3170,13 @@ else if(href_list["ac_set_wanted_name"]) src.admincaster_feed_message.author = adminscrub(input(usr, "Provide the name of the Wanted person", "Network Security Handler", "")) while(findtext(src.admincaster_feed_message.author," ") == 1) - src.admincaster_feed_message.author = copytext(admincaster_feed_message.author,2,lentext(admincaster_feed_message.author)+1) + src.admincaster_feed_message.author = copytext(admincaster_feed_message.author,2,length(admincaster_feed_message.author)+1) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) src.admincaster_feed_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", "")) while(findtext(src.admincaster_feed_message.body," ") == 1) - src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,lentext(src.admincaster_feed_message.body)+1) + src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,length(src.admincaster_feed_message.body)+1) src.access_news_network() else if(href_list["ac_submit_wanted"]) diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm index 4d60fb72bee..9b01e94846c 100644 --- a/code/modules/admin/verbs/freeze.dm +++ b/code/modules/admin/verbs/freeze.dm @@ -26,7 +26,7 @@ var/global/list/frozen_mob_list = list() /mob/living/var/frozen = null //used for preventing attacks on admin-frozen mobs /mob/living/var/admin_prev_sleeping = 0 //used for keeping track of previous sleeping value with admin freeze -/mob/living/proc/admin_Freeze(var/client/admin, skip_overlays = FALSE) +/mob/living/proc/admin_Freeze(client/admin, skip_overlays = FALSE) if(istype(admin)) to_chat(src, "You have been frozen by [admin]") message_admins("[key_name_admin(admin)] froze [key_name_admin(src)]") @@ -34,24 +34,27 @@ var/global/list/frozen_mob_list = list() var/obj/effect/overlay/adminoverlay/AO = new if(skip_overlays) - src.overlays += AO + overlays += AO - anchored = 1 - frozen = AO + anchored = TRUE + canmove = FALSE admin_prev_sleeping = sleeping AdjustSleeping(20000) + frozen = AO if(!(src in frozen_mob_list)) frozen_mob_list += src -/mob/living/proc/admin_unFreeze(var/client/admin, skip_overlays = FALSE) +/mob/living/proc/admin_unFreeze(client/admin, skip_overlays = FALSE) if(istype(admin)) to_chat(src, "You have been unfrozen by [admin]") message_admins("[key_name_admin(admin)] unfroze [key_name_admin(src)]") log_admin("[key_name(admin)] unfroze [key_name(src)]") - anchored = 0 if(skip_overlays) overlays -= frozen + + anchored = FALSE + canmove = TRUE frozen = null SetSleeping(admin_prev_sleeping) admin_prev_sleeping = null diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index f3be2161bb2..c5348fbeabe 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -306,11 +306,11 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height", // the type with the base type removed from the begaining var/fancytype = types[D.type] if(findtext(fancytype, types[type])) - fancytype = copytext(fancytype, lentext(types[type])+1) - var/shorttype = copytext("[D.type]", lentext("[type]")+1) - if(lentext(shorttype) > lentext(fancytype)) + fancytype = copytext(fancytype, length(types[type])+1) + var/shorttype = copytext("[D.type]", length("[type]")+1) + if(length(shorttype) > length(fancytype)) shorttype = fancytype - if(!lentext(shorttype)) + if(!length(shorttype)) shorttype = "/" .["[D]([shorttype])\ref[D]#[i]"] = D diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index caf7fdf2663..2384c24b6ff 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -989,12 +989,14 @@ Traitors and the like can also be revived with the previous role mostly intact. if(job_string in command_positions) job_string = "" + job_string + "" role_string = "-" + obj_count = 0 + obj_string = "" if(H.mind) if(H.mind.special_role) role_string = "[H.mind.special_role]" if(!H.key && H.mind.key) key_string = H.mind.key - for(var/datum/objective/O in all_objectives) + for(var/datum/objective/O in GLOB.all_objectives) if(O.target == H.mind) obj_count++ if(obj_count > 0) @@ -1033,7 +1035,7 @@ Traitors and the like can also be revived with the previous role mostly intact. role_string = "[H.mind.special_role]" if(!H.key && H.mind.key) key_string = H.mind.key - for(var/datum/objective/O in all_objectives) + for(var/datum/objective/O in GLOB.all_objectives) if(O.target == H.mind) obj_count++ if(obj_count > 0) diff --git a/code/modules/antagonists/traitor/datum_mindslave.dm b/code/modules/antagonists/traitor/datum_mindslave.dm index c96b2182d9e..5efd35715ad 100644 --- a/code/modules/antagonists/traitor/datum_mindslave.dm +++ b/code/modules/antagonists/traitor/datum_mindslave.dm @@ -3,8 +3,8 @@ /datum/antagonist/mindslave name = "Mindslave" roundend_category = "mindslaves" - job_rank = ROLE_MINDSLAVE - var/special_role = ROLE_MINDSLAVE + job_rank = SPECIAL_ROLE_TRAITOR + var/special_role = SPECIAL_ROLE_TRAITOR /datum/antagonist/mindslave/on_gain() owner.special_role = special_role diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 4e9a5ad4bf7..9e6f1b79bfa 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -6,7 +6,7 @@ name = "Traitor" roundend_category = "traitors" job_rank = ROLE_TRAITOR - var/special_role = ROLE_TRAITOR + var/special_role = SPECIAL_ROLE_TRAITOR var/give_objectives = TRUE var/should_give_codewords = TRUE var/should_equip = TRUE @@ -28,6 +28,7 @@ forge_traitor_objectives() if(!silent) greet() + apply_innate_effects() update_traitor_icons_added() finalize_traitor() @@ -54,6 +55,7 @@ assigned_targets.Cut() SSticker.mode.traitors -= owner owner.special_role = null + remove_innate_effects() update_traitor_icons_removed() if(!silent && owner.current) @@ -67,8 +69,10 @@ if(owner.assigned_role == "Clown") var/mob/living/carbon/human/traitor_mob = owner.current if(traitor_mob && istype(traitor_mob)) - to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") + to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") traitor_mob.mutations.Remove(CLUMSY) + var/datum/action/innate/toggle_clumsy/A = new + A.Grant(traitor_mob) /datum/antagonist/traitor/remove_innate_effects() @@ -76,7 +80,11 @@ if(owner.assigned_role == "Clown") var/mob/living/carbon/human/traitor_mob = owner.current if(traitor_mob && istype(traitor_mob)) + to_chat(traitor_mob, "You lose your syndicate training and return to your own clumsy, clownish self.") traitor_mob.mutations.Add(CLUMSY) + for(var/datum/action/innate/A in traitor_mob.actions) + if(istype(A, /datum/action/innate/toggle_clumsy)) + A.Remove(traitor_mob) // Adding/removing objectives in the owner's mind until we can datumize all antags. Then we can use the /datum/antagonist/objectives var to handle them // Change "owner.objectives" to "objectives" once objectives are handled in antag datums instead of the mind diff --git a/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm b/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm index 63dfd3f5e4d..6c822c80c03 100644 --- a/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm +++ b/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm @@ -205,7 +205,7 @@ if(inawaymission) if(ismob(loc)) to_chat(loc, "Your [src] deactivates, as it is out of range from its power source.") - power_supply.charge = 0 + cell.charge = 0 inawaymission = 0 update_icon() diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 51ca4065801..5248ba22178 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -360,10 +360,10 @@ . = ..() //calls mob.Login() - if(ckey in clientmessages) - for(var/message in clientmessages[ckey]) + if(ckey in GLOB.clientmessages) + for(var/message in GLOB.clientmessages[ckey]) to_chat(src, message) - clientmessages.Remove(ckey) + GLOB.clientmessages.Remove(ckey) if(SSinput.initialized) set_macros() diff --git a/code/modules/client/message.dm b/code/modules/client/message.dm index a5c78008b4f..ba09e7e1567 100644 --- a/code/modules/client/message.dm +++ b/code/modules/client/message.dm @@ -1,9 +1,10 @@ -var/list/clientmessages = list() +GLOBAL_LIST_EMPTY(clientmessages) proc/addclientmessage(var/ckey, var/message) ckey = ckey(ckey) if(!ckey || !message) return - if(!(ckey in clientmessages)) - clientmessages[ckey] = list() - clientmessages[ckey] += message + var/list/L = GLOB.clientmessages[ckey] + if(!L) + GLOB.clientmessages[ckey] = L = list() + L += message \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_racial.dm b/code/modules/client/preference/loadout/loadout_racial.dm index 38d216ae156..2acec90e7b7 100644 --- a/code/modules/client/preference/loadout/loadout_racial.dm +++ b/code/modules/client/preference/loadout/loadout_racial.dm @@ -1,38 +1,40 @@ /datum/gear/racial sort_category = "Racial" subtype_path = /datum/gear/racial + +/datum/gear/racial/taj + slot = slot_glasses cost = 2 - -/datum/gear/racial/tajciv +/datum/gear/racial/taj/civ display_name = "embroidered veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind cost = 1 -/datum/gear/racial/tajsec +/datum/gear/racial/taj/sec display_name = "sleek veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built security HUD." path = /obj/item/clothing/glasses/hud/security/tajblind allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot", "Internal Affairs Agent", "Magistrate") -/datum/gear/racial/tajmed +/datum/gear/racial/taj/med display_name = "lightweight veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built medical HUD." path = /obj/item/clothing/glasses/hud/health/tajblind allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Psychiatrist", "Paramedic", "Virologist", "Brig Physician" , "Coroner") -/datum/gear/racial/tajsci +/datum/gear/racial/taj/sci display_name = "hi-tech veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind/sci -/datum/gear/racial/tajeng +/datum/gear/racial/taj/eng display_name = "industrial veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind/eng -/datum/gear/racial/tajcargo +/datum/gear/racial/taj/cargo display_name = "khaki veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. It is light and comfy!" path = /obj/item/clothing/glasses/tajblind/cargo @@ -40,4 +42,5 @@ /datum/gear/racial/footwraps display_name = "cloth footwraps" path = /obj/item/clothing/shoes/footwraps - cost = 1 \ No newline at end of file + slot = slot_shoes + cost = 1 diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 11eb454a241..56cb55b6b80 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -294,8 +294,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "Disabilities: \[Set\]
" dat += "Nanotrasen Relation: [nanotrasen_relation]
" dat += "Set Flavor Text
" - if(lentext(flavor_text) <= 40) - if(!lentext(flavor_text)) dat += "\[...\]
" + if(length(flavor_text) <= 40) + if(!length(flavor_text)) dat += "\[...\]
" else dat += "[flavor_text]
" else dat += "[TextPreview(flavor_text)]...
" @@ -886,21 +886,21 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts HTML += "Medical Records
" - if(lentext(med_record) <= 40) + if(length(med_record) <= 40) HTML += "[med_record]" else HTML += "[copytext(med_record, 1, 37)]..." HTML += "
Employment Records
" - if(lentext(gen_record) <= 40) + if(length(gen_record) <= 40) HTML += "[gen_record]" else HTML += "[copytext(gen_record, 1, 37)]..." HTML += "
Security Records
" - if(lentext(sec_record) <= 40) + if(length(sec_record) <= 40) HTML += "[sec_record]
" else HTML += "[copytext(sec_record, 1, 37)]...
" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index a6fe3789aae..adb35b0fb3b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -527,7 +527,7 @@ BLIND // can't see anything end up with a suffix of _open_open if adjusted twice, since their initial state is _open. */ item_state = copytext(item_state, 1, findtext(item_state, "_open")) if(adjust_flavour) - flavour = "[copytext(adjust_flavour, 3, lentext(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button. + flavour = "[copytext(adjust_flavour, 3, length(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button. to_chat(user, "You [flavour] \the [src].") suit_adjusted = 0 //Suit is no longer adjusted. for(var/X in actions) @@ -601,13 +601,14 @@ BLIND // can't see anything min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT - species_restricted = list("exclude","Vox","Wryn") + species_restricted = list("exclude","Wryn") flash_protect = 2 strip_delay = 50 put_on_delay = 50 resistance_flags = NONE dog_fashion = null + /obj/item/clothing/suit/space name = "Space suit" desc = "A suit that protects against low pressure environments. Has a big 13 on the back." @@ -630,7 +631,8 @@ BLIND // can't see anything put_on_delay = 80 resistance_flags = NONE hide_tail_by_species = null - species_restricted = list("exclude","Vox","Wryn") + species_restricted = list("exclude","Wryn") + //Under clothing /obj/item/clothing/under diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index 4670eca24a8..a97752a29db 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -197,6 +197,7 @@ "Grey" = 'icons/mob/species/grey/helmet.dmi', "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', "Unathi" = 'icons/mob/species/unathi/helmet.dmi', + "Vox" = 'icons/mob/species/vox/helmet.dmi', "Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi' ) @@ -210,9 +211,10 @@ sprite_sheets = list( "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', "Unathi" = 'icons/mob/species/unathi/suit.dmi', + "Vox" = 'icons/mob/species/vox/suit.dmi', "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi' ) - hide_tail_by_species = list("Unathi, Tajaran, Vulpkanin") + hide_tail_by_species = list("Unathi, Tajaran, Vox, Vulpkanin") /obj/item/clothing/suit/space/hardsuit/ert/paranormal/New() ..() diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index a786364e4e2..f516627e182 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -229,7 +229,6 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20, fire = 50, acid = 65) flash_protect = 0 species_restricted = list("exclude", "Wryn") - sprite_sheets = list( "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', "Unathi" = 'icons/mob/species/unathi/helmet.dmi', @@ -249,8 +248,9 @@ desc = ". . ." icon_state = "spacemimehelmet" item_state = "spacemimehelmet" - species_restricted = list("exclude","Vox","Wryn") - sprite_sheets = null + species_restricted = list("exclude","Wryn") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/helmet.dmi') sprite_sheets_obj = null /obj/item/clothing/suit/space/eva/mime @@ -259,8 +259,9 @@ desc = ". . ." icon_state = "spacemime_suit" item_state = "spacemime_items" - species_restricted = list("exclude","Vox","Wryn") - sprite_sheets = null + species_restricted = list("exclude","Wryn") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi') sprite_sheets_obj = null /obj/item/clothing/head/helmet/space/eva/clown @@ -269,8 +270,9 @@ desc = "An EVA helmet specifically designed for the clown. SPESSHONK!" icon_state = "clownhelmet" item_state = "clownhelmet" - species_restricted = list("exclude","Vox","Wryn") - sprite_sheets = null + species_restricted = list("exclude","Wryn") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/helmet.dmi') sprite_sheets_obj = null /obj/item/clothing/suit/space/eva/clown @@ -279,6 +281,7 @@ desc = "An EVA suit specifically designed for the clown. SPESSHONK!" icon_state = "spaceclown_suit" item_state = "spaceclown_items" - species_restricted = list("exclude","Vox","Wryn") - sprite_sheets = null + species_restricted = list("exclude","Wryn") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi') sprite_sheets_obj = null diff --git a/code/modules/clothing/spacesuits/rig/modules/modules.dm b/code/modules/clothing/spacesuits/rig/modules/modules.dm index 19c10a31c58..53330341bfe 100644 --- a/code/modules/clothing/spacesuits/rig/modules/modules.dm +++ b/code/modules/clothing/spacesuits/rig/modules/modules.dm @@ -13,7 +13,7 @@ desc = "It looks pretty sciency." icon = 'icons/obj/rig_modules.dmi' icon_state = "module" - + toolspeed = 1 var/damage = 0 @@ -155,7 +155,7 @@ to_chat(usr, "The suit is not initialized.") return 0 - if(usr.lying || usr.stat || usr.stunned || usr.paralysis || usr.weakened) + if(usr.lying || usr.stat || usr.stunned || usr.paralysis || usr.IsWeakened()) to_chat(usr, "You cannot use the suit in this state.") return 0 diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index c8b5e79eb32..3167e68ca6f 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -1052,7 +1052,7 @@ if(user.restrained()) to_chat(user, "You need your hands free for this.") return 0 - if(user.stat || user.paralysis || user.sleeping || user.lying || user.weakened) + if(user.stat || user.paralysis || user.sleeping || user.lying || user.IsWeakened()) return 0 return 1 #undef ONLY_DEPLOY diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index 44d9946dfd6..a1043eb2643 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -6,6 +6,13 @@ item_state = "syndicate" desc = "Has a tag on it: Totally not property of a hostile corporation, honest!" armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85) + sprite_sheets = list( + "Grey" = 'icons/mob/species/grey/helmet.dmi', + "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', + "Unathi" = 'icons/mob/species/unathi/helmet.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi', + "Vox" = 'icons/mob/species/vox/helmet.dmi') + /obj/item/clothing/suit/space/syndicate name = "red space suit" @@ -15,6 +22,11 @@ w_class = WEIGHT_CLASS_NORMAL allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank) armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85) + sprite_sheets = list( + "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', + "Unathi" = 'icons/mob/species/unathi/suit.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi', + "Vox" = 'icons/mob/species/vox/suit.dmi') //Green syndicate space suit diff --git a/code/modules/clothing/spacesuits/void.dm b/code/modules/clothing/spacesuits/void.dm index cd3bb043cae..0f97be88e10 100644 --- a/code/modules/clothing/spacesuits/void.dm +++ b/code/modules/clothing/spacesuits/void.dm @@ -6,6 +6,12 @@ icon_state = "void-red" item_state = "void" flags_inv = HIDEMASK|HIDEEARS + sprite_sheets = list( + "Grey" = 'icons/mob/species/grey/helmet.dmi', + "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', + "Unathi" = 'icons/mob/species/unathi/helmet.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi', + "Vox" = 'icons/mob/species/vox/helmet.dmi') /obj/item/clothing/suit/space/nasavoid name = "NASA Void Suit" @@ -13,6 +19,11 @@ item_state = "void" desc = "A high tech, NASA Centcom branch designed space suit. Used for AI satellite maintenance." allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/multitool) + sprite_sheets = list( + "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', + "Unathi" = 'icons/mob/species/unathi/suit.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi', + "Vox" = 'icons/mob/species/vox/suit.dmi') //Colors!!! /obj/item/clothing/head/helmet/space/nasavoid/green diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index f623ba4c087..09fab3322fb 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -181,7 +181,7 @@ min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 20, bio = 20, rad = 20, fire = 100, acid = 100) - actions_types = null //No inbuilt light + actions_types = list() //No inbuilt light resistance_flags = FIRE_PROOF | ACID_PROOF magical = TRUE diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index 0bd4060c831..391338fc181 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -8,6 +8,7 @@ CAT_MISC, CAT_PRIMAL, CAT_FOOD, + CAT_DECORATIONS, CAT_CLOTHING) var/list/subcategories = list( list( //Weapon subcategories @@ -20,7 +21,11 @@ CAT_CAKE, CAT_SUSHI, CAT_SANDWICH), - CAT_CLOTHING) //Clothing subcategories + list( //Decoration subcategories + CAT_DECORATION, + CAT_HOLIDAY, + CAT_LARGE_DECORATIONS), + CAT_CLOTHING) //Clothing subcategories var/display_craftable_only = FALSE var/display_compact = TRUE diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index d0ad4b8dc41..b49e20f1302 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -571,3 +571,448 @@ time = 50 category = CAT_MISC always_availible = FALSE + +/datum/crafting_recipe/paper_craft + name = "Paper Heart" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/heart + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 1) + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red)//cutters act as makeshift scissors. I doubt the barber wants to have their scissors stolen when somone wants to decorate + category = CAT_DECORATIONS + subcategory = CAT_DECORATION + +/datum/crafting_recipe/paper_craft/single_eye + name = "Paper Eye" + result = /obj/item/decorations/sticky_decorations/flammable/singleeye + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/toy/crayon/blue) + category = CAT_DECORATIONS + subcategory = CAT_DECORATION + +/datum/crafting_recipe/paper_craft/googlyeyes + name = "Paper Googly Eye" + result = /obj/item/decorations/sticky_decorations/flammable/googlyeyes + tools = list(/obj/item/wirecutters, + /obj/item/pen) + category = CAT_DECORATIONS + subcategory = CAT_DECORATION + +/datum/crafting_recipe/paper_craft/clock + name = "Paper Clock" + result = /obj/item/decorations/sticky_decorations/flammable/paperclock + tools = list(/obj/item/wirecutters, + /obj/item/pen) + category = CAT_DECORATIONS + subcategory = CAT_DECORATION + +/datum/crafting_recipe/paper_craft/jack_o_lantern + name = "Paper Jack o'Lantern" + result = /obj/item/decorations/sticky_decorations/flammable/jack_o_lantern + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/toy/crayon/orange, + /obj/item/toy/crayon/green)//pen ink is black + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/ghost + name = "Paper Ghost" + result = /obj/item/decorations/sticky_decorations/flammable/ghost + tools = list(/obj/item/wirecutters, + /obj/item/pen)//it's white paper why need a white crayon? + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/spider + name = "Paper Spider" + result = /obj/item/decorations/sticky_decorations/flammable/spider + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/toy/crayon/red) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/spiderweb + name = "Paper Spiderweb" + result = /obj/item/decorations/sticky_decorations/flammable/spiderweb + tools = list(/obj/item/wirecutters) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/skull + name = "Paper Skull" + result = /obj/item/decorations/sticky_decorations/flammable/skull + tools = list(/obj/item/wirecutters, + /obj/item/pen) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/skeleton + name = "Paper Skeleton" + result = /obj/item/decorations/sticky_decorations/flammable/skeleton + tools = list(/obj/item/wirecutters, + /obj/item/pen) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/cauldron + name = "Paper Cauldron" + result = /obj/item/decorations/sticky_decorations/flammable/cauldron + tools = list(/obj/item/wirecutters, + /obj/item/pen) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/snowman + name = "Paper Snowman" + result = /obj/item/decorations/sticky_decorations/flammable/snowman + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/toy/crayon/orange) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/christmas_stocking + name = "Paper Christmas Stocking" + result = /obj/item/decorations/sticky_decorations/flammable/christmas_stocking + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/christmas_tree + name = "Paper Christmas Tree" + result = /obj/item/decorations/sticky_decorations/flammable/christmas_tree + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red, + /obj/item/toy/crayon/yellow, + /obj/item/toy/crayon/blue, + /obj/item/toy/crayon/green) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/snowflake + name = "Paper Snowflake" + result = /obj/item/decorations/sticky_decorations/flammable/snowflake + tools = list(/obj/item/wirecutters) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/candy_cane + name = "Paper Candy Cane" + result = /obj/item/decorations/sticky_decorations/flammable/candy_cane + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/mistletoe + name = "Paper Mistletoe" + result = /obj/item/decorations/sticky_decorations/flammable/mistletoe + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red, + /obj/item/toy/crayon/green) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/holly + name = "Paper Holly" + result = /obj/item/decorations/sticky_decorations/flammable/holly + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red, + /obj/item/toy/crayon/green) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_white + name = "Paper Tinsel White" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_red + name = "Red Paper Tinsel" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel/red + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_blue + name = "Blue Paper Tinsel" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel/blue + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/blue) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_yellow + name = "Yellow Paper Tinsel" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel/yellow + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/yellow) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_purple + name = "Purple Paper Tinsel" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel/purple + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/purple) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_green + name = "Green Paper Tinsel" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel/green + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/green) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_orange + name = "Orange Paper Tinsel" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel/orange + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/orange) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_black + name = "Black Paper Tinsel" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel/black + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters, + /obj/item/pen) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/tinsel_halloween + name = "Halloween style Paper Tinsel" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/tinsel/halloween + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2) + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/toy/crayon/orange) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/arrowed_heart + name = "Paper Arrowed Heart" + result = /obj/item/decorations/sticky_decorations/flammable/arrowed_heart + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/heart_chain + name = "Paper Heart Chain" + result = /obj/item/decorations/sticky_decorations/flammable/heart_chain + reqs = list(/obj/item/paper = 1, + /obj/item/stack/tape_roll = 2, + /obj/item/stack/cable_coil = 2) + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/four_leaf_clover + name = "Paper Four Leaf Clover" + result = /obj/item/decorations/sticky_decorations/flammable/four_leaf_clover + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/green) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/pot_of_gold + name = "Paper Pot of Gold" + result = /obj/item/decorations/sticky_decorations/flammable/pot_of_gold + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/toy/crayon/red, + /obj/item/toy/crayon/yellow, + /obj/item/toy/crayon/orange, + /obj/item/toy/crayon/green, + /obj/item/toy/crayon/blue, + /obj/item/toy/crayon/purple) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/leprechaun_hat + name = "Paper Leprechaun Hat" + time = 10 + result = /obj/item/decorations/sticky_decorations/flammable/leprechaun_hat + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/toy/crayon/yellow, + /obj/item/toy/crayon/green) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/easter_bunny + name = "Paper Easter Bunny" + result = /obj/item/decorations/sticky_decorations/flammable/easter_bunny + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/toy/crayon/blue, + /obj/item/toy/crayon/purple) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/easter_egg_blue + name = "Blue Paper Easter Egg" + result = /obj/item/decorations/sticky_decorations/flammable/easter_egg + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/blue) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/easter_egg_yellow + name = "Yellow Paper Easter Egg" + result = /obj/item/decorations/sticky_decorations/flammable/easter_egg/yellow + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/yellow) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/easter_egg_red + name = "Red Paper Easter Egg" + result = /obj/item/decorations/sticky_decorations/flammable/easter_egg/red + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/red) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/easter_egg_purple + name = "Purple Paper Easter Egg" + result = /obj/item/decorations/sticky_decorations/flammable/easter_egg/purple + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/purple) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/paper_craft/easter_egg_orange + name = "Orange Paper Easter Egg" + result = /obj/item/decorations/sticky_decorations/flammable/easter_egg/orange + tools = list(/obj/item/wirecutters, + /obj/item/toy/crayon/orange) + category = CAT_DECORATIONS + subcategory = CAT_HOLIDAY + +/datum/crafting_recipe/metal_angel_statue + name = "Metal angel statue" + time = 50 + result = /obj/structure/decorative_structures/metal/statue/metal_angel + reqs = list(/obj/item/stack/sheet/metal = 10, + /obj/item/stack/sheet/mineral/gold = 6) + tools = list(/obj/item/weldingtool) + category = CAT_DECORATIONS + subcategory = CAT_LARGE_DECORATIONS + +/datum/crafting_recipe/golden_disk_statue + name = "Golden disk statue" + time = 50 + result = /obj/structure/decorative_structures/metal/statue/golden_disk + reqs = list(/obj/item/stack/sheet/metal = 10, + /obj/item/stack/sheet/mineral/plasma = 3, + /obj/item/stack/sheet/mineral/gold = 8) + tools = list(/obj/item/weldingtool) + category = CAT_DECORATIONS + subcategory = CAT_LARGE_DECORATIONS + +/datum/crafting_recipe/sun_statue + name = "Sun statue" + time = 40 + result = /obj/structure/decorative_structures/metal/statue/sun + reqs = list(/obj/item/stack/sheet/metal = 6, + /obj/item/stack/sheet/mineral/gold = 4) + tools = list(/obj/item/weldingtool) + category = CAT_DECORATIONS + subcategory = CAT_LARGE_DECORATIONS + +/datum/crafting_recipe/moon_statue + name = "Moon statue" + time = 50 + result = /obj/structure/decorative_structures/metal/statue/moon + reqs = list(/obj/item/stack/sheet/metal = 6, + /obj/item/stack/sheet/mineral/silver = 6, + /obj/item/stack/sheet/mineral/gold = 4) + tools = list(/obj/item/weldingtool) + category = CAT_DECORATIONS + subcategory = CAT_LARGE_DECORATIONS + +/datum/crafting_recipe/tesla_statue + name = "Tesla statue" + time = 40 + result = /obj/structure/decorative_structures/metal/statue/tesla + reqs = list(/obj/item/stack/sheet/metal = 4, + /obj/item/stack/sheet/glass = 8) + tools = list(/obj/item/weldingtool) + category = CAT_DECORATIONS + subcategory = CAT_LARGE_DECORATIONS + +/datum/crafting_recipe/tesla_monument + name = "Tesla monument" + time = 50 + result = /obj/structure/decorative_structures/metal/statue/tesla_monument + reqs = list(/obj/item/stack/sheet/metal = 8, + /obj/item/stock_parts/cell = 3, + /obj/item/stack/cable_coil = 4) + tools = list(/obj/item/weldingtool) + category = CAT_DECORATIONS + subcategory = CAT_LARGE_DECORATIONS + +/datum/crafting_recipe/grandfather_clock + name = "Grandfather clock" + time = 50 + result = /obj/structure/decorative_structures/flammable/grandfather_clock + reqs = list(/obj/item/stack/sheet/wood = 5, + /obj/item/stack/sheet/mineral/gold = 1, + /obj/item/stack/sheet/glass = 2) + category = CAT_DECORATIONS + subcategory = CAT_LARGE_DECORATIONS + +/datum/crafting_recipe/lava_land_display + name = "Lava land display" + time = 50 + result = /obj/structure/decorative_structures/flammable/lava_land_display + reqs = list(/obj/item/paper = 4, + /obj/item/stack/sheet/wood = 4, + /obj/item/stack/rods = 4, + /obj/item/stock_parts/cell = 1, + /obj/item/stack/cable_coil = 4)//thing is a wireframe construct with an electro magnetic hover field + tools = list(/obj/item/wirecutters, + /obj/item/pen, + /obj/item/weldingtool, + /obj/item/toy/crayon/red) + category = CAT_DECORATIONS + subcategory = CAT_LARGE_DECORATIONS diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 2d3cb8465c9..dd4eb3b6923 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -1,6 +1,8 @@ /datum/event/alien_infestation announceWhen = 400 + var/highpop_trigger = 80 var/spawncount = 2 + var/list/playercount var/successSpawn = 0 //So we don't make a command report if nothing gets spawned. /datum/event/alien_infestation/setup() @@ -12,6 +14,9 @@ /datum/event/alien_infestation/start() var/list/vents = list() + playercount = length(GLOB.clients)//grab playercount when event starts not when game starts + if(playercount >= highpop_trigger) //spawn with 4 if highpop + spawncount = 4 for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) if(temp_vent.parent.other_atmosmch.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 3f86b88924c..ece0b5c607e 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -181,7 +181,8 @@ var/list/event_last_fired = list() new /datum/event_meta(EVENT_LEVEL_MODERATE, "Revenant", /datum/event/revenant, 150), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Swarmer Spawn", /datum/event/spawn_swarmer, 150, is_one_shot = 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 40, is_one_shot = 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), 1) + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Headcrabs", /datum/event/headcrabs, 0, list(ASSIGNMENT_SECURITY = 20)) ) /datum/event_container/major @@ -196,8 +197,8 @@ var/list/event_last_fired = list() new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 180, is_one_shot = 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 0, list(ASSIGNMENT_SECURITY = 15), is_one_shot = 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Floor Cluwne", /datum/event/spawn_floor_cluwne, 15, is_one_shot = 1) + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1) + //new /datum/event_meta(EVENT_LEVEL_MAJOR, "Floor Cluwne", /datum/event/spawn_floor_cluwne, 15, is_one_shot = 1) ) diff --git a/code/modules/events/headcrabs.dm b/code/modules/events/headcrabs.dm index ced8562c96c..b1eef858d7e 100644 --- a/code/modules/events/headcrabs.dm +++ b/code/modules/events/headcrabs.dm @@ -1,114 +1,29 @@ -#define LOC_ATMOS_CONTROL 0 -#define LOC_FPMAINT 1 -#define LOC_FPMAINT2 2 -#define LOC_FSMAINT 3 -#define LOC_FSMAINT2 4 -#define LOC_ASMAINT 5 -#define LOC_ASMAINT2 6 -#define LOC_APMAINT 7 -#define LOC_MAINTCENTRAL 8 -#define LOC_FORE 9 -#define LOC_STARBOARD 10 -#define LOC_PORT 11 -#define LOC_AFT 12 -#define LOC_STORAGE 13 -#define LOC_DISPOSAL 14 -#define LOC_GENETICS 15 -#define LOC_ELECTRICAL 16 -#define LOC_ABANDONEDBAR 17 -#define LOC_ELECTRICAL_SHOP 18 -#define LOC_GAMBLING_DEN 19 - #define HEADCRAB_NORMAL 0 #define HEADCRAB_FASTMIX 1 #define HEADCRAB_FAST 2 #define HEADCRAB_POISONMIX 3 #define HEADCRAB_POISON 4 -/*#define HEADCRAB_CLOWN 5 */ //Planned for the future. maybe +#define HEADCRAB_SPAWNER 5 /datum/event/headcrabs announceWhen = 10 endWhen = 11 - var/location var/locstring - var/headcrab + var/headcrab_type /datum/event/headcrabs/start() - - location = rand(0,19) + var/list/availableareas = list() + for(var/area/maintenance/A in world) + availableareas += A + var/area/randomarea = pick(availableareas) var/list/turf/simulated/floor/turfs = list() - var/spawn_area_type - switch(location) - if(LOC_ATMOS_CONTROL) - spawn_area_type = /area/maintenance/atmos_control - locstring = "Atmospherics Maintenance" - if(LOC_FPMAINT) - spawn_area_type = /area/maintenance/fpmaint - locstring = "EVA Maintenance" - if(LOC_FPMAINT2) - spawn_area_type = /area/maintenance/fpmaint2 - locstring = "Arrivals North Maintenance" - if(LOC_FSMAINT) - spawn_area_type = /area/maintenance/fsmaint - locstring = "Dormitory Maintenance" - if(LOC_FSMAINT2) - spawn_area_type = /area/maintenance/fsmaint2 - locstring = "Bar Maintenance" - if(LOC_ASMAINT) - spawn_area_type = /area/maintenance/asmaint - locstring = "Medbay Maintenance" - if(LOC_ASMAINT2) - spawn_area_type = /area/maintenance/asmaint2 - locstring = "Science Maintenance" - if(LOC_APMAINT) - spawn_area_type = /area/maintenance/apmaint - locstring = "Cargo Maintenance" - if(LOC_MAINTCENTRAL) - spawn_area_type = /area/maintenance/maintcentral - locstring = "Bridge Maintenance" - if(LOC_FORE) - spawn_area_type = /area/maintenance/fore - locstring = "Fore Maintenance" - if(LOC_STARBOARD) - spawn_area_type = /area/maintenance/starboard - locstring = "Starboard Maintenance" - if(LOC_PORT) - spawn_area_type = /area/maintenance/port - locstring = "Locker Room Maintenance" - if(LOC_AFT) - spawn_area_type = /area/maintenance/aft - locstring = "Engineering Maintenance" - if(LOC_STORAGE) - spawn_area_type = /area/maintenance/storage - locstring = "Atmospherics Maintenance" - if(LOC_DISPOSAL) - spawn_area_type = /area/maintenance/disposal - locstring = "Waste Disposal" - if(LOC_GENETICS) - spawn_area_type = /area/maintenance/genetics - locstring = "Genetics Maintenance" - if(LOC_ELECTRICAL) - spawn_area_type = /area/maintenance/electrical - locstring = "Electrical Maintenance" - if(LOC_ABANDONEDBAR) - spawn_area_type = /area/maintenance/abandonedbar - locstring = "Maintenance Bar" - if(LOC_ELECTRICAL_SHOP) - spawn_area_type = /area/maintenance/electrical_shop - locstring ="Electronics Den" - if(LOC_GAMBLING_DEN) - spawn_area_type = /area/maintenance/gambling_den - locstring = "Gambling Den" - for(var/areapath in typesof(spawn_area_type)) - var/area/A = locate(areapath) - for(var/turf/simulated/floor/F in A.contents) - if(turf_clear(F)) - turfs += F - + for(var/turf/simulated/floor/F in randomarea) + if(turf_clear(F)) + turfs += F var/list/spawn_types = list() var/max_number - headcrab = rand(0, 4) //rand(0,x) for the future - switch(headcrab) //Switch is for the future + headcrab_type = rand(0, 5) + switch(headcrab_type) if(HEADCRAB_NORMAL) spawn_types = list(/mob/living/simple_animal/hostile/headcrab) max_number = 6 @@ -124,9 +39,13 @@ if(HEADCRAB_POISON) spawn_types = list(/mob/living/simple_animal/hostile/headcrab/poison) max_number = 3 + if(HEADCRAB_SPAWNER) + spawn_types = list(/obj/structure/spawner/headcrab) + max_number = 2 var/num = rand(2,max_number) + while(turfs.len > 0 && num > 0) var/turf/simulated/floor/T = pick(turfs) turfs.Remove(T) @@ -136,31 +55,11 @@ /datum/event/headcrabs/announce() - event_announcement.Announce("Bioscans indicate that creatures have been breeding in [locstring]. Clear them out, before this starts to affect productivity", "Lifesign Alert") - -#undef LOC_ATMOS_CONTROL -#undef LOC_FPMAINT -#undef LOC_FPMAINT2 -#undef LOC_FSMAINT -#undef LOC_FSMAINT2 -#undef LOC_ASMAINT -#undef LOC_ASMAINT2 -#undef LOC_APMAINT -#undef LOC_MAINTCENTRAL -#undef LOC_FORE -#undef LOC_STARBOARD -#undef LOC_PORT -#undef LOC_AFT -#undef LOC_STORAGE -#undef LOC_DISPOSAL -#undef LOC_GENETICS -#undef LOC_ELECTRICAL -#undef LOC_ABANDONEDBAR -#undef LOC_ELECTRICAL_SHOP -#undef LOC_GAMBLING_DEN + event_announcement.Announce("Bioscans indicate that headcrabs have been breeding on the station. Clear them out, before this starts to affect productivity", "Lifesign Alert") #undef HEADCRAB_NORMAL #undef HEADCRAB_FASTMIX #undef HEADCRAB_FAST #undef HEADCRAB_POISONMIX -#undef HEADCRAB_POISON \ No newline at end of file +#undef HEADCRAB_POISON +#undef HEADCRAB_SPAWNER \ No newline at end of file diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index 52e8918a16c..fb896e9e2a6 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -36,9 +36,9 @@ SA.universal_speak = 1 SA.sentience_act() SA.can_collar = 1 - SA.maxHealth = max(SA.maxHealth + 200) - SA.melee_damage_lower = max(SA.melee_damage_lower + 15) - SA.melee_damage_upper = max(SA.melee_damage_upper + 15) + SA.maxHealth += 200 + SA.melee_damage_lower += 15 + SA.melee_damage_upper += 15 SA.health = SA.maxHealth SA.del_on_death = FALSE greet_sentient(SA) @@ -50,4 +50,3 @@ to_chat(M, "Due to freak radiation, you have gained \ human level intelligence and the ability to speak and understand \ human language!") - diff --git a/code/modules/flufftext/TextFilters.dm b/code/modules/flufftext/TextFilters.dm index 02a02a6f5b2..e00f653ac45 100644 --- a/code/modules/flufftext/TextFilters.dm +++ b/code/modules/flufftext/TextFilters.dm @@ -1,7 +1,7 @@ proc/Intoxicated(phrase) phrase = html_decode(phrase) - var/leng=lentext(phrase) - var/counter=lentext(phrase) + var/leng=length(phrase) + var/counter=length(phrase) var/newphrase="" var/newletter="" while(counter>=1) diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm index f66d46f0da6..0eea67d946e 100644 --- a/code/modules/food_and_drinks/food/foods/meat.dm +++ b/code/modules/food_and_drinks/food/foods/meat.dm @@ -286,7 +286,7 @@ if(faction) creature.faction = faction if(LAZYLEN(fingerprintshidden)) - creature.fingerprintshidden = fingerprintshidden.Copy() + creature.fingerprintshidden = fingerprintshidden creature.set_species(monkey_type) SSmobs.cubemonkeys += creature qdel(src) diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index d59e3da4e8e..f38e485d226 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -25,7 +25,7 @@ else log_admin("Client [ckey] was just autokicked for flooding keysends; likely abuse but potentially lagspike.") message_admins("Client [ckey] was just autokicked for flooding keysends; likely abuse but potentially lagspike.") - QDEL_IN(src, 1) + qdel(src) return ///Check if the key is short enough to even be a real key @@ -33,7 +33,7 @@ to_chat(src, "Invalid KeyDown detected! You have been disconnected from the server automatically.") log_admin("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.") message_admins("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.") - QDEL_IN(src, 1) + qdel(src) return //offset by 1 because the buffer address is 0 indexed because the math was simpler keys_held[current_key_address + 1] = _key diff --git a/code/modules/martial_arts/cqc.dm b/code/modules/martial_arts/cqc.dm index b57e7fc4f98..556cfded723 100644 --- a/code/modules/martial_arts/cqc.dm +++ b/code/modules/martial_arts/cqc.dm @@ -53,7 +53,7 @@ /datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return FALSE - if(!D.weakened && !D.resting && !D.lying) + if(!D.IsWeakened() && !D.resting && !D.lying) D.visible_message("[A] slams [D] into the ground!", \ "[A] slams you into the ground!") playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1) @@ -70,7 +70,7 @@ if(!can_use(A)) return FALSE var/success = FALSE - if(!D.stat || !D.weakened) + if(!D.stat || !D.IsWeakened()) D.visible_message("[A] kicks [D] back!", \ "[A] kicks you back!") playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1) @@ -79,7 +79,7 @@ D.apply_damage(10, BRUTE) add_attack_logs(A, D, "Melee attacked with martial-art [src] : Kick", ATKLOG_ALL) success = TRUE - if(D.weakened && !D.stat) + if(D.IsWeakened() && !D.stat) D.visible_message("[A] kicks [D]'s head, knocking [D.p_them()] out!", \ "[A] kicks your head, knocking you out!") playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1) @@ -164,7 +164,7 @@ A.do_attack_animation(D) var/picked_hit_type = pick("CQC'd", "neck chopped", "gut punched", "Big Bossed") var/bonus_damage = 13 - if(D.weakened || D.resting || D.lying) + if(D.IsWeakened() || D.resting || D.lying) bonus_damage += 5 picked_hit_type = "stomps on" D.apply_damage(bonus_damage, BRUTE) @@ -175,7 +175,7 @@ D.visible_message("[A] [picked_hit_type] [D]!", \ "[A] [picked_hit_type] you!") add_attack_logs(A, D, "Melee attacked with martial-art [src] : [picked_hit_type]", ATKLOG_ALL) - if(A.resting && !D.stat && !D.weakened) + if(A.resting && !D.stat && !D.IsWeakened()) D.visible_message("[A] leg sweeps [D]!", \ "[A] leg sweeps you!") playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1) @@ -204,7 +204,7 @@ restraining = FALSE if(prob(65)) - if(!D.stat || !D.weakened || !restraining) + if(!D.stat || !D.IsWeakened() || !restraining) I = D.get_active_hand() D.visible_message("[A] strikes [D]'s jaw with their hand!", \ "[A] strikes your jaw, disorienting you!") diff --git a/code/modules/martial_arts/krav_maga.dm b/code/modules/martial_arts/krav_maga.dm index 5da6b329dcb..88e69919990 100644 --- a/code/modules/martial_arts/krav_maga.dm +++ b/code/modules/martial_arts/krav_maga.dm @@ -75,7 +75,7 @@ return 0 /datum/martial_art/krav_maga/proc/leg_sweep(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(D.stat || D.weakened) + if(D.stat || D.IsWeakened()) return 0 D.visible_message("[A] leg sweeps [D]!", \ "[A] leg sweeps you!") @@ -111,7 +111,7 @@ datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/livi add_attack_logs(A, D, "Melee attacked with [src]") var/picked_hit_type = pick("punches", "kicks") var/bonus_damage = 10 - if(D.weakened || D.resting || D.lying) + if(D.IsWeakened() || D.resting || D.lying) bonus_damage += 5 picked_hit_type = "stomps on" D.apply_damage(bonus_damage, BRUTE) diff --git a/code/modules/martial_arts/mimejutsu.dm b/code/modules/martial_arts/mimejutsu.dm index 5bfff3bf093..a6d6d9e3341 100644 --- a/code/modules/martial_arts/mimejutsu.dm +++ b/code/modules/martial_arts/mimejutsu.dm @@ -22,7 +22,7 @@ return 0 /datum/martial_art/mimejutsu/proc/mimeChuck(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.weakened) + if(!D.stat && !D.stunned && !D.IsWeakened()) var/damage = rand(5, 8) + A.dna.species.punchdamagelow if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) @@ -54,7 +54,7 @@ return basic_hit(A,D) /datum/martial_art/mimejutsu/proc/mimePalm(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.weakened) + if(!D.stat && !D.stunned && !D.IsWeakened()) D.visible_message("[A] has barely touched [D] with [A.p_their()] palm!", \ "[A] hovers [A.p_their()] palm over your face!") diff --git a/code/modules/martial_arts/sleeping_carp.dm b/code/modules/martial_arts/sleeping_carp.dm index 38f1dba77b9..b3e30930c6a 100644 --- a/code/modules/martial_arts/sleeping_carp.dm +++ b/code/modules/martial_arts/sleeping_carp.dm @@ -35,7 +35,7 @@ return 0 /datum/martial_art/the_sleeping_carp/proc/wristWrench(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.weakened) + if(!D.stat && !D.stunned && !D.IsWeakened()) A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) D.visible_message("[A] grabs [D]'s wrist and wrenches it sideways!", \ "[A] grabs your wrist and violently wrenches it to the side!") @@ -50,7 +50,7 @@ return basic_hit(A,D) /datum/martial_art/the_sleeping_carp/proc/backKick(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(A.dir == D.dir && !D.stat && !D.weakened) + if(A.dir == D.dir && !D.stat && !D.IsWeakened()) A.do_attack_animation(D, ATTACK_EFFECT_KICK) D.visible_message("[A] kicks [D] in the back!", \ "[A] kicks you in the back, making you stumble and fall!") @@ -63,7 +63,7 @@ return basic_hit(A,D) /datum/martial_art/the_sleeping_carp/proc/kneeStomach(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.weakened) + if(!D.stat && !D.IsWeakened()) A.do_attack_animation(D, ATTACK_EFFECT_KICK) D.visible_message("[A] knees [D] in the stomach!", \ "[A] winds you with a knee in the stomach!") @@ -77,7 +77,7 @@ return basic_hit(A,D) /datum/martial_art/the_sleeping_carp/proc/headKick(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.weakened) + if(!D.stat && !D.IsWeakened()) A.do_attack_animation(D, ATTACK_EFFECT_KICK) D.visible_message("[A] kicks [D] in the head!", \ "[A] kicks you in the jaw!") @@ -91,7 +91,7 @@ return basic_hit(A,D) /datum/martial_art/the_sleeping_carp/proc/elbowDrop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(D.weakened || D.resting || D.stat) + if(D.IsWeakened() || D.resting || D.stat) A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) D.visible_message("[A] elbow drops [D]!", \ "[A] piledrives you with [A.p_their()] elbow!") diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index ea76ad423e2..bb2ce3a68f8 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -80,7 +80,7 @@ flags = PREVENT_CLICK_UNDER reinf = TRUE heat_resistance = 1600 - armor = list("melee" = 90, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) smooth = SMOOTH_MORE canSmoothWith = list(/turf/simulated/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/shuttle/survival_pod) explosion_block = 3 diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 45d4cda2202..a91aeed7bdf 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -162,7 +162,7 @@ if(copytext(heardword,1, 1) in punctuation) heardword = copytext(heardword,2) if(copytext(heardword,-1) in punctuation) - heardword = copytext(heardword,1,lentext(heardword)) + heardword = copytext(heardword,1,length(heardword)) heard = "...You hear something about... '[heardword]'..." else heard = "...You almost hear something......" diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index bdc2ee31f77..7f17a8a87e1 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -25,7 +25,7 @@ icon_state = "alien[caste]_dead" pixel_y = 0 - else if(stat == UNCONSCIOUS || weakened) + else if(stat == UNCONSCIOUS || IsWeakened()) icon_state = "alien[caste]_unconscious" pixel_y = 0 else if(leap_on_click) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index fd60d5d49bd..af6bdb26af5 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -774,11 +774,14 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, spawn(0) resist_muzzle() if(restrained()) + var/obj/item/I = handcuffed + var/breakouttime = I.breakouttime + var/displaytime = breakouttime / 10 changeNext_move(CLICK_CD_BREAKOUT) last_special = world.time + CLICK_CD_BREAKOUT visible_message("[src] attempts to unbuckle [p_them()]self!", \ - "You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)") - if(do_after(src, 600, 0, target = src)) + "You attempt to unbuckle yourself... (This will take around [displaytime] seconds and you need to stay still.)") + if(do_after(src, breakouttime, 0, target = src)) if(!buckled) return buckled.user_unbuckle_mob(src,src) @@ -836,10 +839,10 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = 0) breakouttime = I.breakouttime - var/displaytime = breakouttime / 600 + var/displaytime = breakouttime / 10 if(!cuff_break) visible_message("[src] attempts to remove [I]!") - to_chat(src, "You attempt to remove [I]... (This will take around [displaytime] minutes and you need to stand still.)") + to_chat(src, "You attempt to remove [I]... (This will take around [displaytime] seconds and you need to stand still.)") if(do_after(src, breakouttime, 0, target = src)) if(I.loc != src || buckled) return diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index c23db2f5501..32841d3804d 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -383,7 +383,7 @@ message = "[src] flips in [M]'s general direction." SpinAnimation(5,1) else - if(lying || weakened) + if(lying || IsWeakened()) message = "[src] flops and flails around on the floor." else var/obj/item/grab/G diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 7a18e881eb6..85bb90a168e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -215,6 +215,12 @@ else if(E.status & ORGAN_SPLINTED) wound_flavor_text["[E.limb_name]"] = "[p_they(TRUE)] [p_have()] a splint on [p_their()] [E.name]!\n" + if(E.open) + if(E.is_robotic()) + msg += "The maintenance hatch on [p_their()] [ignore_limb_branding(E.limb_name)] is open!\n" + else + msg += "[p_their(TRUE)] [ignore_limb_branding(E.limb_name)] has an open incision!\n" + for(var/obj/item/I in E.embedded_objects) msg += "[p_they(TRUE)] [p_have()] \a [bicon(I)] [I] embedded in [p_their()] [E.name]!\n" @@ -370,7 +376,7 @@ msg += "*---------*" if(pose) - if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) + if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. msg += "\n[p_they(TRUE)] [p_are()] [pose]" @@ -403,3 +409,29 @@ return 0 else return 0 + +// Ignores robotic limb branding prefixes like "Morpheus Cybernetics" +/proc/ignore_limb_branding(limb_name) + switch(limb_name) + if("chest") + . = "upper body" + if("groin") + . = "lower body" + if("head") + . = "head" + if("l_arm") + . = "left arm" + if("r_arm") + . = "right arm" + if("l_leg") + . = "left leg" + if("r_leg") + . = "right leg" + if("l_foot") + . = "left foot" + if("r_foot") + . = "right foot" + if("l_hand") + . = "left hand" + if("r_hand") + . = "right hand" diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 71a3ae3e87c..65a75f80e8c 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -22,7 +22,7 @@ med_hud_set_status() handle_hud_icons_health() -/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE) +/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE, use_brain_mod = TRUE) if(status_flags & GODMODE) return STATUS_UPDATE_NONE //godmode @@ -30,7 +30,8 @@ var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) if(dna.species && amount > 0) - amount = amount * dna.species.brain_mod + if(use_brain_mod) + amount = amount * dna.species.brain_mod sponge.damage = Clamp(sponge.damage + amount, 0, 120) if(sponge.damage >= 120) visible_message("[src] goes limp, [p_their()] facial expression utterly blank.") @@ -39,7 +40,7 @@ update_stat("adjustBrainLoss") return STATUS_UPDATE_STAT -/mob/living/carbon/human/setBrainLoss(amount, updating = TRUE) +/mob/living/carbon/human/setBrainLoss(amount, updating = TRUE, use_brain_mod = TRUE) if(status_flags & GODMODE) return STATUS_UPDATE_NONE //godmode @@ -47,7 +48,8 @@ var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) if(dna.species && amount > 0) - amount = amount * dna.species.brain_mod + if(use_brain_mod) + amount = amount * dna.species.brain_mod sponge.damage = Clamp(amount, 0, 120) if(sponge.damage >= 120) visible_message("[src] goes limp, [p_their()] facial expression utterly blank.") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 433a6adcc8f..037b9fb7d87 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -16,20 +16,8 @@ emp_act if(check_reflect(def_zone)) // Checks if you've passed a reflection% check visible_message("The [P.name] gets reflected by [src]!", \ "The [P.name] gets reflected by [src]!") - // Find a turf near or on the original location to bounce to - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/turf/curloc = get_turf(src) - - // redirect the projectile - P.firer = src - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x - P.Angle = null + + P.reflect_back(src) return -1 // complete projectile permutation @@ -633,7 +621,7 @@ emp_act if("brute") if(M.force > 35) // durand and other heavy mechas Paralyse(1) - else if(M.force > 20 && !weakened) // lightweight mechas like gygax + else if(M.force > 20 && !IsWeakened()) // lightweight mechas like gygax Weaken(2) update |= affecting.receive_damage(dmg, 0) playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index c6c8b75518a..c56f0140ee2 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -246,7 +246,7 @@ if(H.r_hand && (H.r_hand.flags & HANDSLOW)) . += H.r_hand.slowdown - var/health_deficiency = (H.maxHealth - H.health + H.staminaloss) + var/health_deficiency = max(H.maxHealth - H.health, H.staminaloss) var/hungry = (500 - H.nutrition)/5 // So overeat would be 100 and default level would be 80 if(H.reagents) for(var/datum/reagent/R in H.reagents.reagent_list) @@ -751,7 +751,7 @@ return FALSE //Unsupported slot /datum/species/proc/get_perceived_trauma(mob/living/carbon/human/H) - return H.health - H.getStaminaLoss() + return min(H.health, H.maxHealth - H.getStaminaLoss()) /datum/species/proc/handle_hud_icons(mob/living/carbon/human/H) if(!H.client) diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 7c92d8748bd..f88670fc0c1 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -474,19 +474,9 @@ if(P.is_reflectable) H.visible_message("The [P.name] gets reflected by [H]'s glass skin!", \ "The [P.name] gets reflected by [H]'s glass skin!") - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/turf/curloc = get_turf(H) + + P.reflect_back(H) - // redirect the projectile - P.firer = src - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x - P.Angle = null return FALSE return TRUE diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index a0980256718..b357d2c5345 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -131,6 +131,13 @@ "appendix" = /obj/item/organ/internal/appendix, "eyes" = /obj/item/organ/internal/eyes/skrell //Tajara monkey-forms are uniquely colourblind and have excellent darksight, which is why they need a subtype of their greater-form's organ.. ) +/datum/species/monkey/skrell/on_species_gain(mob/living/carbon/human/H) + ..() + ADD_TRAIT(H, TRAIT_WATERBREATH, "species") + +/datum/species/monkey/skrell/on_species_loss(mob/living/carbon/human/H) + ..() + REMOVE_TRAIT(H, TRAIT_WATERBREATH, "species") /datum/species/monkey/unathi name = "Stok" diff --git a/code/modules/mob/living/carbon/human/species/skrell.dm b/code/modules/mob/living/carbon/human/species/skrell.dm index 009514f4902..9e21c0bf390 100644 --- a/code/modules/mob/living/carbon/human/species/skrell.dm +++ b/code/modules/mob/living/carbon/human/species/skrell.dm @@ -12,6 +12,7 @@ herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ the secrets of their empire to their allies." + species_traits = list(LIPS) clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS bodyflags = HAS_SKIN_COLOR | HAS_BODY_MARKINGS @@ -43,4 +44,12 @@ "is jamming their thumbs into their eye sockets!", "is twisting their own neck!", "makes like a fish and suffocates!", - "is strangling themselves with their own tendrils!") \ No newline at end of file + "is strangling themselves with their own tendrils!") + +/datum/species/skrell/on_species_gain(mob/living/carbon/human/H) + ..() + ADD_TRAIT(H, TRAIT_WATERBREATH, "species") + +/datum/species/skrell/on_species_loss(mob/living/carbon/human/H) + ..() + REMOVE_TRAIT(H, TRAIT_WATERBREATH, "species") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm index 42a566e450c..e7501486b72 100644 --- a/code/modules/mob/living/carbon/human/species/slime.dm +++ b/code/modules/mob/living/carbon/human/species/slime.dm @@ -72,6 +72,7 @@ grow.Grant(H) recolor = new() recolor.Grant(H) + ADD_TRAIT(H, TRAIT_WATERBREATH, "species") /datum/species/slime/on_species_loss(mob/living/carbon/human/H) ..() @@ -79,6 +80,7 @@ grow.Remove(H) if(recolor) recolor.Remove(H) + REMOVE_TRAIT(H, TRAIT_WATERBREATH, "species") /datum/species/slime/handle_life(mob/living/carbon/human/H) // Slowly shifting to the color of the reagents diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index a9263f58ea2..5352ba525f1 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -258,8 +258,10 @@ //this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc.. /mob/living/carbon/handle_status_effects() ..() - - setStaminaLoss(max((staminaloss - 3), 0)) + if(stam_regen_start_time <= world.time) + if(stam_paralyzed) + update_stamina() + setStaminaLoss(0, FALSE) var/restingpwr = 1 + 4 * resting diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm new file mode 100644 index 00000000000..a9f68773ed5 --- /dev/null +++ b/code/modules/mob/living/carbon/status_procs.dm @@ -0,0 +1,15 @@ +/mob/living/carbon/IsWeakened(include_stamcrit = TRUE) + return ..() || (include_stamcrit && stam_paralyzed) + +/mob/living/carbon/proc/enter_stamcrit() + if(!(status_flags & CANWEAKEN)) + return + if(absorb_stun(0)) //continuous effect, so we don't want it to increment the stuns absorbed. + return + if(!IsWeakened()) + to_chat(src, "You're too exhausted to keep going...") + var/prev = stam_paralyzed + stam_paralyzed = TRUE + update_canmove() + if(!prev && getStaminaLoss() < 120) // Puts you a little further into the initial stamcrit, makes stamcrit harder to outright counter with chems. + adjustStaminaLoss(30, FALSE) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/update_status.dm b/code/modules/mob/living/carbon/update_status.dm index 58c6e09764b..f78bdf63ec9 100644 --- a/code/modules/mob/living/carbon/update_status.dm +++ b/code/modules/mob/living/carbon/update_status.dm @@ -18,15 +18,13 @@ create_debug_log("woke up, trigger reason: [reason]") /mob/living/carbon/update_stamina() - ..() - if(staminaloss) - var/total_health = (health - staminaloss) - if(total_health <= HEALTH_THRESHOLD_CRIT && !stat) - to_chat(src, "You're too exhausted to keep going...") - Weaken(5) - setStaminaLoss(health - 2) - handle_hud_icons_health() - return + var/stam = getStaminaLoss() + if(stam > DAMAGE_PRECISION && (maxHealth - stam) <= HEALTH_THRESHOLD_CRIT && !stat) + enter_stamcrit() + else if(stam_paralyzed) + stam_paralyzed = FALSE + update_canmove() + handle_hud_icons_health() /mob/living/carbon/can_hear() . = FALSE diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 4f2323e2025..09abb09041d 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -260,28 +260,30 @@ if(status_flags & GODMODE) return FALSE var/old_stamloss = staminaloss - staminaloss = max(staminaloss + amount, 0) + staminaloss = min(max(staminaloss + amount, 0), 120) if(old_stamloss == staminaloss) updating = FALSE . = STATUS_UPDATE_NONE else . = STATUS_UPDATE_STAMINA + if(amount > 0) + stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME if(updating) - handle_hud_icons_health() update_stamina() /mob/living/proc/setStaminaLoss(amount, updating = TRUE) if(status_flags & GODMODE) return FALSE var/old_stamloss = staminaloss - staminaloss = amount + staminaloss = min(max(amount, 0), 120) if(old_stamloss == staminaloss) updating = FALSE . = STATUS_UPDATE_NONE else . = STATUS_UPDATE_STAMINA + if(amount > 0) + stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME if(updating) - handle_hud_icons_health() update_stamina() /mob/living/proc/getMaxHealth() diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 5bc42caab14..74a51a771ac 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -69,3 +69,5 @@ var/deathgasp_on_death = FALSE var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added + var/stam_regen_start_time = 0 //used to halt stamina regen temporarily + var/stam_paralyzed = FALSE //knocks you down \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 36f248cd2c2..b4db13f5452 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -129,7 +129,8 @@ var/const/VOX_PATH = "sound/vox_fem/" announcing_vox = world.time + VOX_DELAY - log_game("[key_name_admin(src)] made a vocal announcement with the following message: [message].") + log_game("[key_name(src)] made a vocal announcement: [message].") + message_admins("[key_name_admin(src)] made a vocal announcement: [message].") for(var/word in words) play_vox_word(word, src.z, null) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index cb6b3eaa104..4e280b20de8 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -318,7 +318,7 @@ set category = "pAI Commands" set name = "Unfold Chassis" - if(stat || sleeping || paralysis || weakened) + if(stat || sleeping || paralysis || IsWeakened()) return if(loc != card) @@ -353,7 +353,7 @@ set category = "pAI Commands" set name = "Collapse Chassis" - if(stat || sleeping || paralysis || weakened) + if(stat || sleeping || paralysis || IsWeakened()) return if(loc == card) @@ -538,7 +538,7 @@ if(print_flavor_text()) msg += "\n[print_flavor_text()]" if(pose) - if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) + if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. msg += "\nIt is [pose]" msg += "\n*---------*
" diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index edf53f56918..589f2f06b49 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -52,8 +52,7 @@ camera.network.Add("Engineering") //They are unable to be upgraded, so let's give them a bit of a better battery. - cell.maxcharge = 10000 - cell.charge = 10000 + cell = new /obj/item/stock_parts/cell/high(src) // NO BRAIN. mmi = null diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 56d01fea839..198b687e496 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -50,7 +50,7 @@ if(print_flavor_text()) msg += "\n[print_flavor_text()]\n" if(pose) - if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) + if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. msg += "\nIt is [pose]" diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index bf09191ecf2..258ccec026a 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -169,7 +169,7 @@ weaponlock_time = 120 /mob/living/silicon/robot/update_canmove(delay_action_updates = 0) - if(paralysis || stunned || weakened || buckled || lockcharge || stat) + if(paralysis || stunned || IsWeakened() || buckled || lockcharge || stat) canmove = 0 else canmove = 1 diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 59a0d38f15a..1cded581118 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -151,9 +151,7 @@ var/list/robot_verbs_default = list( C.wrapped = new C.external_type if(!cell) - cell = new /obj/item/stock_parts/cell(src) - cell.maxcharge = 7500 - cell.charge = 7500 + cell = new /obj/item/stock_parts/cell/high(src) ..() @@ -906,7 +904,7 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/update_icons() overlays.Cut() - if(stat != DEAD && !(paralysis || stunned || weakened || low_power_mode)) //Not dead, not stunned. + if(stat != DEAD && !(paralysis || stunned || IsWeakened() || low_power_mode)) //Not dead, not stunned. if(custom_panel in custom_eye_names) overlays += "eyes-[custom_panel]" else @@ -1316,8 +1314,7 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/deathsquad/New(loc) ..() - cell.maxcharge = 25000 - cell.charge = 25000 + cell = new /obj/item/stock_parts/cell/hyper(src) /mob/living/silicon/robot/deathsquad/init() laws = new /datum/ai_laws/deathsquad @@ -1370,8 +1367,7 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/ert/New(loc, cyborg_unlock) ..(loc) - cell.maxcharge = 25000 - cell.charge = 25000 + cell = new /obj/item/stock_parts/cell/hyper(src) var/rnum = rand(1,1000) var/borgname = "ERT [rnum]" name = borgname diff --git a/code/modules/mob/living/silicon/robot/syndicate.dm b/code/modules/mob/living/silicon/robot/syndicate.dm index f762ba440cf..f97b1f5c005 100644 --- a/code/modules/mob/living/silicon/robot/syndicate.dm +++ b/code/modules/mob/living/silicon/robot/syndicate.dm @@ -17,8 +17,7 @@ /mob/living/silicon/robot/syndicate/New(loc) ..() - cell.maxcharge = 25000 - cell.charge = 25000 + cell = new /obj/item/stock_parts/cell/hyper(src) /mob/living/silicon/robot/syndicate/init() laws = new /datum/ai_laws/syndicate_override diff --git a/code/modules/mob/living/silicon/robot/update_status.dm b/code/modules/mob/living/silicon/robot/update_status.dm index fafc5a4c8c3..63c13f97d24 100644 --- a/code/modules/mob/living/silicon/robot/update_status.dm +++ b/code/modules/mob/living/silicon/robot/update_status.dm @@ -1,6 +1,6 @@ // No args for restraints because robots don't have those /mob/living/silicon/robot/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_lying = FALSE) - if(stat || lockcharge || weakened || stunned || paralysis || !is_component_functioning("actuator")) + if(stat || lockcharge || IsWeakened() || stunned || paralysis || !is_component_functioning("actuator")) return TRUE /mob/living/silicon/robot/has_vision(information_only = FALSE) @@ -14,7 +14,7 @@ death() create_debug_log("died of damage, trigger reason: [reason]") return - if(!is_component_functioning("actuator") || !is_component_functioning("power cell") || paralysis || sleeping || resting || stunned || weakened || getOxyLoss() > maxHealth * 0.5) + if(!is_component_functioning("actuator") || !is_component_functioning("power cell") || paralysis || sleeping || resting || stunned || IsWeakened() || getOxyLoss() > maxHealth * 0.5) if(stat == CONSCIOUS) KnockOut() create_debug_log("fell unconscious, trigger reason: [reason]") diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index a22d373ba79..c457f90c3f5 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -384,15 +384,15 @@ if(!lasercolor) var/obj/item/gun/energy/gun/advtaser/G = new /obj/item/gun/energy/gun/advtaser(Tsec) - G.power_supply.charge = 0 + G.cell.charge = 0 G.update_icon() else if(lasercolor == "b") var/obj/item/gun/energy/laser/tag/blue/G = new /obj/item/gun/energy/laser/tag/blue(Tsec) - G.power_supply.charge = 0 + G.cell.charge = 0 G.update_icon() else if(lasercolor == "r") var/obj/item/gun/energy/laser/tag/red/G = new /obj/item/gun/energy/laser/tag/red(Tsec) - G.power_supply.charge = 0 + G.cell.charge = 0 G.update_icon() if(prob(50)) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index d0271feeb87..2c8e56f3fbe 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -59,9 +59,7 @@ var/datum/job/cargo_tech/J = new/datum/job/cargo_tech access_card.access = J.get_access() prev_access = access_card.access - cell = new(src) - cell.charge = 2000 - cell.maxcharge = 2000 + cell = new /obj/item/stock_parts/cell/upgraded(src) mulebot_count++ set_suffix(suffix ? suffix : "#[mulebot_count]") diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 0c003b9e3b8..9dce0cecb62 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -47,6 +47,10 @@ if(SSticker.cultdat?.theme == "blood") updateglow() +/mob/living/simple_animal/hostile/construct/death(gibbed) + . = ..() + SSticker.mode.remove_cultist(src.mind, FALSE) + /mob/living/simple_animal/hostile/construct/examine(mob/user) . = ..() @@ -132,19 +136,7 @@ visible_message("The [P.name] gets reflected by [src]'s shell!", \ "The [P.name] gets reflected by [src]'s shell!") - // Find a turf near or on the original location to bounce to - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/turf/curloc = get_turf(src) - - // redirect the projectile - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.firer = src - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x + P.reflect_back(src, list(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)) return -1 // complete projectile permutation diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 55aa587eff9..3717493d26c 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -37,7 +37,7 @@ playsound(src, yelp_sound, 75, TRUE) /mob/living/simple_animal/pet/dog/emote(act, m_type = 1, message = null, force) - if(!incapacitated()) + if(incapacitated()) return var/on_CD = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 71356b7c52c..ece990c7743 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -5,8 +5,9 @@ icon_state = "headcrab" icon_living = "headcrab" icon_dead = "headcrab_dead" - health = 40 - maxHealth = 40 + health = 60 + maxHealth = 60 + dodging = 1 melee_damage_lower = 5 melee_damage_upper = 10 ranged = 1 @@ -18,7 +19,8 @@ attack_sound = 'sound/creatures/headcrab_attack.ogg' speak_emote = list("hisses") var/is_zombie = 0 - stat_attack = DEAD //so they continue to attack when they are on the ground. + stat_attack = DEAD // Necessary for them to attack (zombify) dead humans + robust_searching = 1 var/host_species = "" var/list/human_overlays = list() @@ -28,6 +30,17 @@ if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD)) Zombify(H) break + var/cycles = 4 + if(cycles >= 4) + for(var/mob/living/simple_animal/K in oview(src, 1)) //Only for corpse right next to/on same tile + if(K.stat == DEAD || (!K.check_death_method() && K.health <= HEALTH_THRESHOLD_DEAD)) + visible_message("[src] consumes [target] whole!") + if(health < maxHealth) + health += 10 + qdel(K) + break + cycles = 0 + cycles++ ..() /mob/living/simple_animal/hostile/headcrab/OpenFire(atom/A) @@ -51,13 +64,14 @@ var/obj/item/clothing/suit/armor/A = H.wear_suit if(A.armor && A.armor["melee"]) maxHealth += A.armor["melee"] //That zombie's got armor, I want armor! - maxHealth += 50 + maxHealth += 200 health = maxHealth name = "zombie" desc = "A corpse animated by the alien being on its head." melee_damage_lower = 10 melee_damage_upper = 15 ranged = 0 + stat_attack = CONSCIOUS // Disables their targeting of dead mobs once they're already a zombie icon = H.icon speak = list('sound/creatures/zombie_idle1.ogg','sound/creatures/zombie_idle2.ogg','sound/creatures/zombie_idle3.ogg') speak_chance = 50 @@ -105,7 +119,13 @@ I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_gray") overlays += I - +/mob/living/simple_animal/hostile/headcrab/CanAttack(atom/the_target) + if(stat_attack == DEAD && isliving(the_target) && !ishuman(the_target)) + var/mob/living/L = the_target + if(L.stat == DEAD) + // Override default behavior of stat_attack, to stop headcrabs targeting dead mobs they cannot infect, such as silicons. + return FALSE + return ..() /mob/living/simple_animal/hostile/headcrab/fast name = "fast headcrab" @@ -114,8 +134,8 @@ icon_state = "fast_headcrab" icon_living = "fast_headcrab" icon_dead = "fast_headcrab_dead" - health = 30 - maxHealth = 30 + health = 40 + maxHealth = 40 ranged_cooldown_time = 30 jumpdistance = 8 jumpspeed = 2 @@ -144,11 +164,13 @@ icon_state = "poison_headcrab" icon_living = "poison_headcrab" icon_dead = "poison_headcrab_dead" - health = 60 - maxHealth = 60 + health = 80 + maxHealth = 80 ranged_cooldown_time = 50 jumpdistance = 3 jumpspeed = 1 + melee_damage_lower = 8 + melee_damage_upper = 20 attack_sound = 'sound/creatures/ph_scream1.ogg' speak_emote = list("screech") @@ -167,6 +189,10 @@ /mob/living/simple_animal/hostile/headcrab/poison/AttackingTarget() . = ..() - var/mob/living/carbon/C = target - if(C.can_inject(null, FALSE, "head", FALSE)) - C.reagents.add_reagent("lsd", 5) + if(iscarbon(target) && target.reagents) + var/inject_target = pick("chest", "head") + var/mob/living/carbon/C = target + if(C.stunned || C.can_inject(null, FALSE, inject_target, FALSE)) + if(C.eye_blurry < 60) + C.AdjustEyeBlurry(10) + visible_message("[src] buries its fangs deep into the [inject_target] of [target]!") diff --git a/code/modules/mob/living/simple_animal/hostile/headslug.dm b/code/modules/mob/living/simple_animal/hostile/headslug.dm index d2329162da7..801514a3256 100644 --- a/code/modules/mob/living/simple_animal/hostile/headslug.dm +++ b/code/modules/mob/living/simple_animal/hostile/headslug.dm @@ -22,6 +22,7 @@ ventcrawler = 2 var/datum/mind/origin var/egg_lain = 0 + sentience_type = SENTIENCE_OTHER /mob/living/simple_animal/hostile/headslug/examine(mob/user) . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/hellhound.dm b/code/modules/mob/living/simple_animal/hostile/hellhound.dm index d83ca04d6c4..9107aa03457 100644 --- a/code/modules/mob/living/simple_animal/hostile/hellhound.dm +++ b/code/modules/mob/living/simple_animal/hostile/hellhound.dm @@ -1,6 +1,6 @@ // Hellhound /mob/living/simple_animal/hostile/hellhound - // Sprites by FoS: http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 + // Sprites by FoS: https://www.paradisestation.org/forum/profile/335-fos name = "Lesser Hellhound" desc = "A demonic-looking black canine monster with glowing red eyes and sharp teeth. A firey, lava-like substance drips from it." icon_state = "hellhound" @@ -8,7 +8,6 @@ icon_dead = "hellhound_dead" icon_resting = "hellhound_rest" mutations = list(BREATHLESS) - gold_core_spawnable = HOSTILE_SPAWN atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 maxbodytemp = INFINITY @@ -92,11 +91,6 @@ return TRUE return FALSE -/mob/living/simple_animal/hostile/hellhound/AttackingTarget() - . = ..() - if(. && ishuman(target) && (!client || a_intent == INTENT_HARM)) - special_aoe() - /mob/living/simple_animal/hostile/hellhound/attackby(obj/item/C, mob/user, params) . = ..() if(target && isliving(target)) @@ -104,14 +98,6 @@ if(L.stat != CONSCIOUS) target = user -/mob/living/simple_animal/hostile/hellhound/proc/special_aoe() - if(world.time < (smoke_lastuse + smoke_freq)) - return - smoke_lastuse = world.time - var/datum/effect_system/smoke_spread/sleeping/smoke = new - smoke.set_up(10, 0, loc) - smoke.start() - /mob/living/simple_animal/hostile/hellhound/greater name = "Greater Hellhound" desc = "A demonic-looking black canine monster with glowing red eyes and sharp teeth. Greater hounds are far stronger than their lesser kin, and typically employed by powerful bluespace entities." @@ -121,9 +107,46 @@ maxHealth = 400 health = 400 force_threshold = 5 // no punching + universal_speak = 1 smoke_freq = 200 life_regen_cycle_trigger = 5 melee_damage_lower = 20 melee_damage_upper = 30 environment_smash = 2 - gold_core_spawnable = NO_SPAWN + +/mob/living/simple_animal/hostile/hellhound/greater/New() + . = ..() + // Movement + AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift) + var/obj/effect/proc_holder/spell/targeted/area_teleport/teleport/telespell = new + telespell.clothes_req = FALSE + telespell.invocation_type = "none" + AddSpell(telespell) + var/obj/effect/proc_holder/spell/aoe_turf/knock/knockspell = new + knockspell.invocation_type = "none" + AddSpell(knockspell) + // Defense + var/obj/effect/proc_holder/spell/targeted/forcewall/greater/wallspell = new + wallspell.clothes_req = FALSE + wallspell.invocation_type = "none" + AddSpell(wallspell) + // Offense + var/obj/effect/proc_holder/spell/aoe_turf/conjure/creature/summonspell = new + summonspell.charge_max = 1 + summonspell.invocation_type = "none" + summonspell.summon_type = list(/mob/living/simple_animal/hostile/hellhound) + summonspell.summon_amt = 1 + AddSpell(summonspell) + +/mob/living/simple_animal/hostile/hellhound/greater/AttackingTarget() + . = ..() + if(. && ishuman(target) && (!client || a_intent == INTENT_HARM)) + special_aoe() + +/mob/living/simple_animal/hostile/hellhound/greater/proc/special_aoe() + if(world.time < (smoke_lastuse + smoke_freq)) + return + smoke_lastuse = world.time + var/datum/effect_system/smoke_spread/sleeping/smoke = new + smoke.set_up(10, 0, loc) + smoke.start() diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index c0628cd72af..761f44d11bd 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -244,10 +244,10 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/ranged/OpenFire(the_target) if(Zapgun) - if(Zapgun.power_supply) + if(Zapgun.cell) var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.select] - if(Zapgun.power_supply.charge >= shot.e_cost) - Zapgun.power_supply.use(shot.e_cost) + if(Zapgun.cell.charge >= shot.e_cost) + Zapgun.cell.use(shot.e_cost) Zapgun.update_icon() ..() else if(Zapstick) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm index c9dc370648a..eae926b88e1 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm @@ -6,7 +6,7 @@ // -------------: AI: attacks to inject its venom, then retreats. Will inject its enemies multiple times then hang back to ensure they die. // -------------: SPECIAL: venom that does more damage the more of it is in you // -------------: TO FIGHT IT: if bitten once, retreat, get charcoal/etc treatment, and come back with a gun. -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/black name = "Black Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm index 1c6fcdb6e5d..fd30532a7bc 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm @@ -5,7 +5,7 @@ // -------------: AI: none - this is strictly adminspawn-only and intended for RP events, coder testing, and teaching people 'how to queen' // -------------: SPECIAL: Lay Eggs ability that allows laying queen-level eggs. // -------------: TO FIGHT IT: run away screaming? -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/queen/empress name = "Empress of Terror" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm index 14aa2b9299a..c06a7c2fee6 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm @@ -6,7 +6,7 @@ // -------------: AI: hides in vents, emerges when prey is near to kill it, then hides again. Intended to scare normal crew. // -------------: SPECIAL: invisible when on top of a vent, emerges when prey approaches or gets trapped in webs. // -------------: TO FIGHT IT: shoot it through a window, or make it regret ambushing you -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/gray name = "Gray Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm index 43d21286f8f..e7daced65ff 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm @@ -6,7 +6,7 @@ // -------------: AI: after it kills you, it webs you and lays new terror eggs on your body // -------------: SPECIAL: can also create webs, web normal objects, etc // -------------: TO FIGHT IT: kill it however you like - just don't die to it! -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/green name = "Green Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm index d1e171d2f55..65a3ff3db47 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm @@ -6,7 +6,7 @@ // -------------: AI: no special ai // -------------: SPECIAL: spawns an ungodly number of spiderlings when killed // -------------: TO FIGHT IT: don't! Just leave it alone! It is harmless by itself... but god help you if you aggro it. -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/mother name = "Mother of Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm index 646e9e50660..e486872abbb 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm @@ -6,7 +6,7 @@ // -------------: AI: no special ai // -------------: SPECIAL: massive health // -------------: TO FIGHT IT: a squad of at least 4 people with laser rifles. -// -------------: SPRITES FROM: Travelling Merchant, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=2766 +// -------------: SPRITES FROM: Travelling Merchant, https://www.paradisestation.org/forum/profile/2715-travelling-merchant/ /mob/living/simple_animal/hostile/poison/terror_spider/prince name = "Prince of Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm index 419f2a617f6..828e0e5f8f6 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm @@ -6,7 +6,7 @@ // -------------: AI: as green, but will evolve to queen when it can // -------------: SPECIAL: can evolve into a queen, if fed enough // -------------: TO FIGHT IT: kill it before it evolves -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/princess name = "Princess of Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm index 62832527293..92c7688e1e1 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm @@ -6,7 +6,7 @@ // -------------: AI: dies if too far from queen // -------------: SPECIAL: chance to stun on hit // -------------: TO FIGHT IT: shoot it from range, bring friends! -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/purple name = "Purple Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm index 3f16eb44837..a96486e473e 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm @@ -7,7 +7,7 @@ // -------------: AI: uses very powerful fangs to wreck people in melee // -------------: SPECIAL: the more you hurt it, the harder it bites you // -------------: TO FIGHT IT: shoot it from range. Kite it. -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/red name = "Red Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm index 8b5010c9d25..f62167792a3 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm @@ -5,7 +5,7 @@ // -------------: AI: injects a venom that makes you grow spiders in your body, then retreats // -------------: SPECIAL: stuns you on first attack - vulnerable to groups while it does this // -------------: TO FIGHT IT: blast it before it can get away -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/white name = "White Terror spider" diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 3f7b76c5af0..948c16314c9 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -28,6 +28,9 @@ del_on_death = 1 deathmessage = "lets out a contented sigh as their form unwinds." +/mob/living/simple_animal/shade/death(gibbed) + . = ..() + SSticker.mode.remove_cultist(src.mind, FALSE) /mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri if(istype(O, /obj/item/soulstone)) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 26f02503c14..01c1f7cfe43 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -500,7 +500,7 @@ . |= pcollar.GetAccess() /mob/living/simple_animal/update_canmove(delay_action_updates = 0) - if(paralysis || stunned || weakened || stat || resting) + if(paralysis || stunned || IsWeakened() || stat || resting) drop_r_hand() drop_l_hand() canmove = 0 diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 0e1a19da662..72f136304d7 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -344,6 +344,8 @@ return SetSleeping(max(sleeping, amount), updating, no_alert) /mob/living/SetSleeping(amount, updating = 1, no_alert = FALSE) + if(frozen) // If the mob has been admin frozen, sleeping should not be changeable + return . = STATUS_UPDATE_STAT if((!!amount) == (!!sleeping)) // We're not changing from + to 0 or vice versa updating = FALSE diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index bdaa0972aef..20cc969119f 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -62,11 +62,11 @@ // Whether the mob is capable of standing or not /mob/living/proc/can_stand() - return !(weakened || paralysis || stat || (status_flags & FAKEDEATH)) + return !(IsWeakened() || paralysis || stat || (status_flags & FAKEDEATH)) // Whether the mob is capable of actions or not /mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_lying = FALSE) - if(stat || paralysis || stunned || weakened || (!ignore_restraints && restrained()) || (!ignore_lying && lying)) + if(stat || paralysis || stunned || IsWeakened() || (!ignore_restraints && restrained()) || (!ignore_lying && lying)) return TRUE // wonderful proc names, I know - used to check whether the blur overlay diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c9e77e294d2..609940bc2a6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -726,7 +726,7 @@ var/list/slot_equipment_priority = list( \ /mob/proc/print_flavor_text(var/shrink = 1) if(flavor_text && flavor_text != "") var/msg = replacetext(flavor_text, "\n", " ") - if(lentext(msg) <= 40 || !shrink) + if(length(msg) <= 40 || !shrink) return "[html_encode(msg)]" //Repeat after me, "I will not give players access to decoded HTML." else return "[copytext_preserve_html(msg, 1, 37)]... More..." diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index ec81cc33950..a96a832fef4 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -201,8 +201,8 @@ /proc/slur(phrase, var/list/slurletters = ("'"))//use a different list as an input if you want to make robots slur with $#@%! characters phrase = html_decode(phrase) - var/leng=lentext(phrase) - var/counter=lentext(phrase) + var/leng=length(phrase) + var/counter=length(phrase) var/newphrase="" var/newletter="" while(counter>=1) @@ -295,8 +295,8 @@ proc/muffledspeech(phrase) phrase = html_decode(phrase) - var/leng=lentext(phrase) - var/counter=lentext(phrase) + var/leng=length(phrase) + var/counter=length(phrase) var/newphrase="" var/newletter="" while(counter>=1) @@ -568,10 +568,10 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM) //Fixes renames not being reflected in objective text var/length var/pos - for(var/datum/objective/objective in all_objectives) + for(var/datum/objective/objective in GLOB.all_objectives) if(!mind || objective.target != mind) continue - length = lentext(oldname) + length = length(oldname) pos = findtextEx(objective.explanation_text, oldname) objective.explanation_text = copytext(objective.explanation_text, 1, pos)+newname+copytext(objective.explanation_text, pos+length) return 1 @@ -610,8 +610,8 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM) /proc/cultslur(n) // Inflicted on victims of a stun talisman var/phrase = html_decode(n) - var/leng = lentext(phrase) - var/counter=lentext(phrase) + var/leng = length(phrase) + var/counter=length(phrase) var/newphrase="" var/newletter="" while(counter>=1) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index ac8917398c5..fc246f661c3 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -373,9 +373,9 @@ if(character.mind.assigned_role == "Cyborg") AnnounceCyborg(character, rank, join_message) else - data_core.manifest_inject(character) SSticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn if(!IsAdminJob(rank)) + data_core.manifest_inject(character) AnnounceArrival(character, rank, join_message) AddEmploymentContract(character) diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index f6e6e07673f..6716ea0e4a9 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -190,6 +190,9 @@ return +/mob/proc/IsWeakened() + return weakened + /mob/proc/Weaken() return diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index a03b7745d0a..52b3bb61b27 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -63,10 +63,7 @@ var/mob/living/silicon/robot/O = new /mob/living/silicon/robot( loc ) // cyborgs produced by Robotize get an automatic power cell - O.cell = new(O) - O.cell.maxcharge = 7500 - O.cell.charge = 7500 - + O.cell = new /obj/item/stock_parts/cell/high(O) O.gender = gender O.invisibility = 0 diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 5bd0f3827ac..0df04d27928 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -416,6 +416,11 @@ nanoui is used to open and update nano browser uis if(!initial_data) set_initial_data(src_object.ui_data(user, ui_key, state)) // Get the UI data. + // Preset the can_rezie and titlebar values on uis if the user has fancy uis set + // Prevents the ui from flickering when opened + if(user.client.prefs.nanoui_fancy) + set_window_options("focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=0;titlebar=0;") + user << browse(get_html(), "window=[window_id];[window_size][window_options]") winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map on_close_winset() diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 5a09e1a55a9..e7be4698fcf 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -317,7 +317,7 @@ src.add_fingerprint(user) if(target == user && !user.incapacitated()) visible_message("[usr] jumps onto [src]!") - else if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis) + else if(target != user && !user.restrained() && !user.stat && !user.IsWeakened() && !user.stunned && !user.paralysis) if(target.anchored) return if(!ishuman(user)) return visible_message("[usr] drags [target.name] onto [src]!") diff --git a/code/modules/pda/pdas.dm b/code/modules/pda/pdas.dm index 676d193a6d3..cb7b7731274 100644 --- a/code/modules/pda/pdas.dm +++ b/code/modules/pda/pdas.dm @@ -186,6 +186,12 @@ default_cartridge = /obj/item/cartridge/centcom icon_state = "pda-h" +/obj/item/pda/centcom/New() + ..() + var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) + if(M) + M.m_hidden = 1 + //Some spare PDAs in a box /obj/item/storage/box/PDAs name = "spare PDAs" diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 89df4beacd2..4d7dafa69bf 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -30,6 +30,11 @@ #define APC_UPDATE_ICON_COOLDOWN 200 // 20 seconds +// APC malf status +#define APC_MALF_NOT_HACKED 1 +#define APC_MALF_HACKED 2 // APC hacked by user, and user is in its core. +#define APC_MALF_SHUNTED_HERE 3 // User is shunted in this APC +#define APC_MALF_SHUNTED_OTHER 4 // User is shunted in another APC // the Area Power Controller (APC), formerly Power Distribution Unit (PDU) // one per area, needs wire conection to power network through a terminal @@ -205,7 +210,7 @@ has_electronics = 2 //installed and secured // is starting with a power cell installed, create it and set its charge level if(cell_type) - cell = new/obj/item/stock_parts/cell(src) + cell = new/obj/item/stock_parts/cell/upgraded(src) cell.maxcharge = cell_type // cell_type is maximum charge (old default was 1000 or 2500 (values one and two respectively) cell.charge = start_charge * cell.maxcharge / 100 // (convert percentage to actual value) @@ -749,18 +754,22 @@ /obj/machinery/power/apc/proc/get_malf_status(mob/living/silicon/ai/malf) - if(istype(malf) && malf.mind.has_antag_datum(/datum/antagonist/traitor)) - if(malfai == (malf.parent || malf)) - if(occupier == malf) - return 3 // 3 = User is shunted in this APC - else if(istype(malf.loc, /obj/machinery/power/apc)) - return 4 // 4 = User is shunted in another APC - else - return 2 // 2 = APC hacked by user, and user is in its core. + if(!istype(malf)) + return FALSE + + // Only if they're a traitor OR they have the malf picker from the combat module + if(!malf.mind.has_antag_datum(/datum/antagonist/traitor) && !malf.malf_picker) + return FALSE + + if(malfai == (malf.parent || malf)) + if(occupier == malf) + return APC_MALF_SHUNTED_HERE + else if(istype(malf.loc, /obj/machinery/power/apc)) + return APC_MALF_SHUNTED_OTHER else - return 1 // 1 = APC not hacked. + return APC_MALF_HACKED else - return 0 // 0 = User is not a Malf AI + return APC_MALF_NOT_HACKED /obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(!user) @@ -1008,7 +1017,7 @@ /obj/machinery/power/apc/proc/malfhack(mob/living/silicon/ai/malf) if(!istype(malf)) return - if(get_malf_status(malf) != 1) + if(get_malf_status(malf) != APC_MALF_NOT_HACKED) return if(malf.malfhacking) to_chat(malf, "You are already hacking an APC.") diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 8977062c947..82d78e99e53 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -254,6 +254,7 @@ shot_number = 0 P.setDir(dir) P.starting = loc + P.Angle = null P.fire() return P diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 531bde2b000..c67e676ee13 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -110,8 +110,12 @@ /obj/singularity/process() - if(current_size >= STAGE_TWO) + if(allowed_size >= STAGE_TWO) + // Start moving even before we reach "true" stage two. + // If we are stage one and are sufficiently energetic to be allowed to 2, + // it might mean we are stuck in a corner somewere. So move around to try to expand. move() + if(current_size >= STAGE_TWO) pulse() if(prob(event_chance))//Chance for it to run a special event TODO:Come up with one or two more that fit event() diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 3fbfcdaa934..c745d6be846 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/guns/energy.dmi' fire_sound_text = "laser blast" - var/obj/item/stock_parts/cell/power_supply //What type of power cell this uses + var/obj/item/stock_parts/cell/cell //What type of power cell this uses var/cell_type = /obj/item/stock_parts/cell var/modifystate = 0 var/list/ammo_type = list(/obj/item/ammo_casing/energy) @@ -20,7 +20,7 @@ var/charge_delay = 4 /obj/item/gun/energy/emp_act(severity) - power_supply.use(round(power_supply.charge / severity)) + cell.use(round(cell.charge / severity)) if(chambered)//phil235 if(chambered.BB) qdel(chambered.BB) @@ -30,15 +30,15 @@ update_icon() /obj/item/gun/energy/get_cell() - return power_supply + return cell /obj/item/gun/energy/New() ..() if(cell_type) - power_supply = new cell_type(src) + cell = new cell_type(src) else - power_supply = new(src) - power_supply.give(power_supply.maxcharge) + cell = new(src) + cell.give(cell.maxcharge) update_ammo_types() on_recharge() if(selfcharge) @@ -66,14 +66,14 @@ if(charge_tick < charge_delay) return charge_tick = 0 - if(!power_supply) + if(!cell) return // check if we actually need to recharge var/obj/item/ammo_casing/energy/E = ammo_type[select] if(use_external_power) - var/obj/item/stock_parts/cell/external = get_external_power_supply() + var/obj/item/stock_parts/cell/external = get_external_cell() if(!external || !external.use(E.e_cost)) //Take power from the borg... return //Note, uses /10 because of shitty mods to the cell system - power_supply.give(100) //... to recharge the shot + cell.give(100) //... to recharge the shot on_recharge() update_icon() @@ -91,14 +91,14 @@ /obj/item/gun/energy/can_shoot() var/obj/item/ammo_casing/energy/shot = ammo_type[select] - return power_supply.charge >= shot.e_cost + return cell.charge >= shot.e_cost /obj/item/gun/energy/newshot() - if(!ammo_type || !power_supply) + if(!ammo_type || !cell) return if(!chambered) var/obj/item/ammo_casing/energy/shot = ammo_type[select] - if(power_supply.charge >= shot.e_cost) //if there's enough power in the power_supply cell... + if(cell.charge >= shot.e_cost) //if there's enough power in the cell cell... chambered = shot //...prepare a new shot based on the current ammo type selected if(!chambered.BB) chambered.newshot() @@ -106,7 +106,7 @@ /obj/item/gun/energy/process_chamber() if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired... var/obj/item/ammo_casing/energy/shot = chambered - power_supply.use(shot.e_cost)//... drain the power_supply cell + cell.use(shot.e_cost)//... drain the cell cell robocharge() chambered = null //either way, released the prepared shot newshot() @@ -131,7 +131,7 @@ /obj/item/gun/energy/update_icon() overlays.Cut() - var/ratio = Ceiling((power_supply.charge / power_supply.maxcharge) * charge_sections) + var/ratio = Ceiling((cell.charge / cell.maxcharge) * charge_sections) var/obj/item/ammo_casing/energy/shot = ammo_type[select] var/iconState = "[icon_state]_charge" var/itemState = null @@ -142,7 +142,7 @@ iconState += "_[shot.select_name]" if(itemState) itemState += "[shot.select_name]" - if(power_supply.charge < shot.e_cost) + if(cell.charge < shot.e_cost) overlays += "[icon_state]_empty" else if(!shaded_charge) @@ -172,7 +172,7 @@ user.visible_message("[user] melts [user.p_their()] face off with the [name]!") playsound(loc, fire_sound, 50, 1, -1) var/obj/item/ammo_casing/energy/shot = ammo_type[select] - power_supply.use(shot.e_cost) + cell.use(shot.e_cost) update_icon() return FIRELOSS else @@ -198,9 +198,9 @@ if(R && R.cell) var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot if(R.cell.use(shot.e_cost)) //Take power from the borg... - power_supply.give(shot.e_cost) //... to recharge the shot + cell.give(shot.e_cost) //... to recharge the shot -/obj/item/gun/energy/proc/get_external_power_supply() +/obj/item/gun/energy/proc/get_external_cell() if(istype(loc, /obj/item/rig_module)) var/obj/item/rig_module/module = loc if(module.holder && module.holder.wearer) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 1b8eebbf311..60ab08f979d 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -106,7 +106,7 @@ empty() /obj/item/gun/energy/kinetic_accelerator/proc/empty() - power_supply.use(500) + cell.use(500) update_icon() /obj/item/gun/energy/kinetic_accelerator/proc/attempt_reload(recharge_time) @@ -136,7 +136,7 @@ return /obj/item/gun/energy/kinetic_accelerator/proc/reload() - power_supply.give(500) + cell.give(500) on_recharge() if(!suppressed) playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 1a8a5afd1eb..4663b2d5c04 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -39,8 +39,8 @@ /obj/item/gun/energy/gun/mini/New() gun_light = new /obj/item/flashlight/seclite(src) ..() - power_supply.maxcharge = 600 - power_supply.charge = 600 + cell.maxcharge = 600 + cell.charge = 600 /obj/item/gun/energy/gun/mini/update_icon() ..() diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 5a9e87aa119..0572ce36f76 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -43,7 +43,7 @@ /obj/item/gun/energy/decloner/update_icon() ..() var/obj/item/ammo_casing/energy/shot = ammo_type[select] - if(power_supply.charge > shot.e_cost) + if(cell.charge > shot.e_cost) overlays += "decloner_spin" // Flora Gun // @@ -160,26 +160,26 @@ /obj/item/gun/energy/plasmacutter/examine(mob/user) . = ..() - if(power_supply) - . += "[src] is [round(power_supply.percent())]% charged." + if(cell) + . += "[src] is [round(cell.percent())]% charged." /obj/item/gun/energy/plasmacutter/attackby(obj/item/A, mob/user) if(istype(A, /obj/item/stack/sheet/mineral/plasma)) - if(power_supply.charge >= power_supply.maxcharge) + if(cell.charge >= cell.maxcharge) to_chat(user,"[src] is already fully charged.") return var/obj/item/stack/sheet/S = A S.use(1) - power_supply.give(1000) + cell.give(1000) on_recharge() to_chat(user, "You insert [A] in [src], recharging it.") else if(istype(A, /obj/item/stack/ore/plasma)) - if(power_supply.charge >= power_supply.maxcharge) + if(cell.charge >= cell.maxcharge) to_chat(user,"[src] is already fully charged.") return var/obj/item/stack/ore/S = A S.use(1) - power_supply.give(500) + cell.give(500) on_recharge() to_chat(user, "You insert [A] in [src], recharging it.") else @@ -489,7 +489,7 @@ M.update_inv_r_hand() /obj/item/gun/energy/temperature/proc/update_charge() - var/charge = power_supply.charge + var/charge = cell.charge switch(charge) if(900 to INFINITY) overlays += "900" if(800 to 900) overlays += "800" diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index dc798e10830..d31231823f8 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -24,7 +24,7 @@ var/p_x = 16 var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center var/speed = 1 //Amount of deciseconds it takes for projectile to travel - var/Angle = 0 + var/Angle = null var/spread = 0 //amount (in degrees) of projectile spread var/legacy = FALSE //legacy projectile system animate_movement = 0 @@ -240,8 +240,7 @@ if(!paused) if((!( current ) || loc == current)) current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) - - if(!Angle) + if(isnull(Angle)) Angle=round(Get_Angle(src,current)) if(spread) Angle += (rand() - 0.5) * spread @@ -302,6 +301,25 @@ Range() sleep(1) +obj/item/projectile/proc/reflect_back(atom/source, list/position_modifiers = list(0, 0, 0, 0, 0, -1, 1, -2, 2)) + if(starting) + var/new_x = starting.x + pick(position_modifiers) + var/new_y = starting.y + pick(position_modifiers) + var/turf/curloc = get_turf(source) + + if(ismob(source)) + firer = source // The reflecting mob will be the new firer + else + firer = null // Reflected by something other than a mob so firer will be null + + // redirect the projectile + original = locate(new_x, new_y, z) + starting = curloc + current = curloc + yo = new_y - curloc.y + xo = new_x - curloc.x + Angle = null // Will be calculated in fire() + obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile with a projectile is hit by it. ..() if(isliving(AM) && AM.density && !checkpass(PASSMOB)) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 22d6c3744d1..814ac3d7e46 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -47,7 +47,7 @@ /obj/item/projectile/beam/disabler name = "disabler beam" icon_state = "omnilaser" - damage = 36 + damage = 30 damage_type = STAMINA flag = "energy" hitsound = 'sound/weapons/tap.ogg' diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index e8f7d16cc37..1945c6dffe5 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -314,7 +314,6 @@ var/const/INGEST = 2 if(update_flags & STATUS_UPDATE_CANMOVE) M.update_canmove() if(update_flags & STATUS_UPDATE_STAMINA) - M.handle_hud_icons_health() M.update_stamina() if(update_flags & STATUS_UPDATE_BLIND) M.update_blind_effects() diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 41a0a747118..9601746443a 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -134,76 +134,88 @@ icon_state = "juicer0" /obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params) - if(default_unfasten_wrench(user, I)) - return + if(default_unfasten_wrench(user, I)) + return - if(exchange_parts(user, I)) - return + if(exchange_parts(user, I)) + return - if(anchored && !beaker) - if(default_deconstruction_screwdriver(user, "juicer_open", "juicer0", I)) - return + if(anchored && !beaker) + if(default_deconstruction_screwdriver(user, "juicer_open", "juicer0", I)) + return - if(panel_open && istype(I, /obj/item/crowbar)) - default_deconstruction_crowbar(I) - return + if(panel_open && istype(I, /obj/item/crowbar)) + default_deconstruction_crowbar(I) + return - if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER) ) - if(beaker) - to_chat(user, "There's already a container inside.") - else if(panel_open) - to_chat(user, "Close the maintenance panel first.") - else - if(!user.drop_item()) - return 1 - beaker = I - beaker.loc = src - update_icon() - src.updateUsrDialog() - return 1 //no afterattack + if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER) ) + if(beaker) + to_chat(user, "There's already a container inside.") + else if(panel_open) + to_chat(user, "Close the maintenance panel first.") + else + if(!user.drop_item()) + return FALSE + beaker = I + beaker.loc = src + update_icon() + updateUsrDialog() + return TRUE //no afterattack - if(is_type_in_list(I, dried_items)) - if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) - var/obj/item/reagent_containers/food/snacks/grown/G = I - if(!G.dry) - to_chat(user, "You must dry that first!") - return 1 + if(is_type_in_list(I, dried_items)) + if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) + var/obj/item/reagent_containers/food/snacks/grown/G = I + if(!G.dry) + to_chat(user, "You must dry that first!") + return FALSE - if(holdingitems && holdingitems.len >= limit) - to_chat(usr, "The machine cannot hold anymore items.") - return 1 + if(holdingitems && holdingitems.len >= limit) + to_chat(usr, "The machine cannot hold anymore items.") + return FALSE - //Fill machine with a bag! - if(istype(I, /obj/item/storage/bag)) - var/obj/item/storage/bag/B = I - for (var/obj/item/reagent_containers/food/snacks/grown/G in B.contents) - B.remove_from_storage(G, src) - holdingitems += G - if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill - to_chat(user, "You fill the All-In-One grinder to the brim.") - break + //Fill machine with a bag! + if(istype(I, /obj/item/storage/bag)) + var/obj/item/storage/bag/B = I + if(!B.contents.len) + to_chat(user, "[B] is empty.") + return FALSE - if(!I.contents.len) - to_chat(user, "You empty the plant bag into the All-In-One grinder.") + var/original_contents_len = B.contents.len - src.updateUsrDialog() - return 1 + for(var/obj/item/G in B.contents) + if(is_type_in_list(G, blend_items) || is_type_in_list(G, juice_items)) + B.remove_from_storage(G, src) + holdingitems += G + if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill + to_chat(user, "You fill the All-In-One grinder to the brim.") + break - if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) - if(user.a_intent == INTENT_HARM) - return ..() - else - to_chat(user, "Cannot refine into a reagent!") - return 1 + if(B.contents.len == original_contents_len) + to_chat(user, "Nothing in [B] can be put into the All-In-One grinder.") + return FALSE + else if(!B.contents.len) + to_chat(user, "You empty all of [B]'s contents into the All-In-One grinder.") + else + to_chat(user, "You empty some of [B]'s contents into the All-In-One grinder.") - if(user.drop_item()) - I.loc = src - holdingitems += I - src.updateUsrDialog() - return 0 + updateUsrDialog() + return TRUE + + if(!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) + if(user.a_intent == INTENT_HARM) + return ..() + else + to_chat(user, "Cannot refine into a reagent!") + return TRUE + + if(user.drop_item()) + I.loc = src + holdingitems += I + src.updateUsrDialog() + return FALSE /obj/machinery/reagentgrinder/attack_ai(mob/user) - return 0 + return FALSE /obj/machinery/reagentgrinder/attack_hand(mob/user) user.set_machine(src) @@ -301,8 +313,8 @@ /obj/machinery/reagentgrinder/proc/is_allowed(obj/item/reagent_containers/O) for (var/i in blend_items) if(istype(O, i)) - return 1 - return 0 + return TRUE + return FALSE /obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/O) for (var/i in blend_items) diff --git a/code/modules/reagents/chemistry/reagents/blob.dm b/code/modules/reagents/chemistry/reagents/blob.dm index 903ac9fa350..571db376f80 100644 --- a/code/modules/reagents/chemistry/reagents/blob.dm +++ b/code/modules/reagents/chemistry/reagents/blob.dm @@ -25,7 +25,7 @@ if(method == TOUCH) volume = ..() M.apply_damage(0.6*volume, BRUTE) - M.adjustStaminaLoss(0.4*volume) + M.adjustStaminaLoss(volume) if(iscarbon(M)) M.emote("scream") @@ -105,7 +105,7 @@ if(method == TOUCH) volume = ..() M.apply_damage(0.4*volume, BURN) - M.adjustStaminaLoss(0.4*volume) + M.adjustStaminaLoss(volume) if(M.reagents) M.reagents.add_reagent("frostoil", 0.4*volume) diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index b8ccede11bd..59a7d07e241 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -419,7 +419,7 @@ color = "#9ACD32" taste_description = "bitterness" -/datum/reagent/spores/on_mob_life(mob/living/M) +/datum/reagent/spore/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE update_flags |= M.adjustToxLoss(1, FALSE) M.damageoverlaytemp = 60 diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 482b8b20ccd..a4320639f39 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -43,21 +43,22 @@ to_chat(user, "[src] is empty!") return + var/contents_log = reagents.reagent_list.Join(", ") spray(A) playsound(loc, 'sound/effects/spray2.ogg', 50, 1, -6) user.changeNext_move(CLICK_CD_RANGE*2) user.newtonian_move(get_dir(A, user)) - if(reagents.has_reagent("sacid")) - msg_admin_attack("[key_name_admin(user)] fired sulphuric acid from \a [src] at [COORD(user)].", ATKLOG_FEW) - log_game("[key_name(user)] fired sulphuric acid from \a [src] at [COORD(user)].") - if(reagents.has_reagent("facid")) - msg_admin_attack("[key_name_admin(user)] fired fluorosulfuric acid from \a [src] at [COORD(user)].", ATKLOG_FEW) - log_game("[key_name(user)] fired fluorosulfuric Acid from \a [src] at [COORD(user)].") - if(reagents.has_reagent("lube")) - msg_admin_attack("[key_name_admin(user)] fired space lube from \a [src] at [COORD(user)].") - log_game("[key_name(user)] fired space lube from \a [src] at [COORD(user)].") + if(reagents.reagent_list.len == 1 && reagents.has_reagent("cleaner")) // Only show space cleaner logs if it's burning people from being too hot or cold + if(reagents.chem_temp < 300 && reagents.chem_temp > 280) // 280 is the cold threshold for slimes, 300 the hot threshold for drask + return + + var/attack_log_type = ATKLOG_MOST + if(reagents.has_reagent("sacid") || reagents.has_reagent("facid") || reagents.has_reagent("lube")) + attack_log_type = ATKLOG_FEW + msg_admin_attack("[key_name_admin(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type) + log_game("[key_name(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K") return diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 8efd181ac1a..02ca42e94d9 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -189,20 +189,20 @@ var/target_loc = target.loc var/msg for(var/mob/V in viewers(usr)) - if(target == user && !user.stat && !user.weakened && !user.stunned && !user.paralysis) + if(target == user && !user.stat && !user.IsWeakened() && !user.stunned && !user.paralysis) V.show_message("[usr] starts climbing into the disposal.", 3) - if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis) + if(target != user && !user.restrained() && !user.stat && !user.IsWeakened() && !user.stunned && !user.paralysis) if(target.anchored) return V.show_message("[usr] starts stuffing [target.name] into the disposal.", 3) if(!do_after(usr, 20, target = target)) return if(target_loc != target.loc) return - if(target == user && !user.stat && !user.weakened && !user.stunned && !user.paralysis) // if drop self, then climbed in + if(target == user && !user.stat && !user.IsWeakened() && !user.stunned && !user.paralysis) // if drop self, then climbed in // must be awake, not stunned or whatever msg = "[user.name] climbs into the [src]." to_chat(user, "You climb into the [src].") - else if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis) + else if(target != user && !user.restrained() && !user.stat && !user.IsWeakened() && !user.stunned && !user.paralysis) msg = "[user.name] stuffs [target.name] into the [src]!" to_chat(user, "You stuff [target.name] into the [src]!") diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 9c62b44cdf9..202b931b7a9 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -357,7 +357,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, submenu = 0 if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. for(var/material in linked_destroy.loaded_item.materials) - linked_lathe.materials.insert_amount(min((linked_lathe.materials.max_amount - linked_lathe.materials.total_amount), (linked_destroy.loaded_item.materials[material]*(linked_destroy.decon_mod/10))), material) + var/can_insert = min(linked_lathe.materials.max_amount - linked_lathe.materials.total_amount, linked_destroy.loaded_item.materials[material] * (linked_destroy.decon_mod / 10), linked_destroy.loaded_item.materials[material]) + linked_lathe.materials.insert_amount(can_insert, material) linked_destroy.loaded_item = null else menu = 0 diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 953c0e6682c..5af2d472416 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -174,43 +174,37 @@ /obj/docking_port/mobile/emergency/proc/is_hijacked() for(var/mob/living/player in GLOB.player_list) - if(player.mind) - if(player.stat != DEAD || !iszombie(player)) - if(issilicon(player)) //Borgs are technically dead anyways + if(!player.mind) + continue + if(player.stat == DEAD) // Corpses + continue + if(iszombie(player)) // Walking corpses + continue + if(issilicon(player)) //Borgs are technically dead anyways + continue + if(isanimal(player)) //Poly does not own the shuttle + continue + if(ishuman(player)) //hostages allowed on the shuttle, check for restraints + var/mob/living/carbon/human/H = player + if(!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD) //new crit users who are in hard crit are considered dead + continue + if(H.handcuffed) //cuffs + continue + if(H.wear_suit && H.wear_suit.breakouttime) //straight jacket + continue + if(istype(H.loc, /obj/structure/closet)) //locked/welded locker, all aboard the clown train honk honk + var/obj/structure/closet/C = H.loc + if(C.welded || C.locked) continue - if(isanimal(player)) //Poly does not own the shuttle - continue - if(ishuman(player)) //hostages allowed on the shuttle, check for restraints - var/mob/living/carbon/human/H = player - if(!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD) //new crit users who are in hard crit are considered dead - continue - if(H.handcuffed) //cuffs - continue - if(H.wear_suit && H.wear_suit.breakouttime) //straight jacket - continue - if(istype(H.loc, /obj/structure/closet)) //locked/welded locker, all aboard the clown train honk honk - var/obj/structure/closet/C = H.loc - if(C.welded || C.locked) - continue - var/special_role = player.mind.special_role - if(special_role) - if(special_role == SPECIAL_ROLE_TRAITOR) // traitors can hijack the shuttle - continue + var/special_role = player.mind.special_role + if(special_role) + // There's a long list of special roles, but almost all of them are antags anyway. + // If you manage to escape with a pet slaughter demon - go for it! Greentext well earned! + if(special_role != SPECIAL_ROLE_EVENTMISC && special_role != SPECIAL_ROLE_ERT && special_role != SPECIAL_ROLE_DEATHSQUAD) + continue - if(special_role == SPECIAL_ROLE_CHANGELING) // changelings as well - continue - - if(special_role == SPECIAL_ROLE_VAMPIRE || special_role == SPECIAL_ROLE_VAMPIRE_THRALL) // for traitorvamp - continue - - if(special_role == SPECIAL_ROLE_NUKEOPS) // so can nukeops, for the hell of it - continue - - if(special_role == SPECIAL_ROLE_SYNDICATE_DEATHSQUAD) // and the syndie deathsquad i guess - continue - - if(get_area(player) == areaInstance) - return FALSE + if(get_area(player) == areaInstance) + return FALSE return TRUE diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 9da43d08fbf..446b6466dc5 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -475,7 +475,7 @@ SSnanoui.update_uis(src) return 1 - var/index = copytext(href_list["doorder"], 1, lentext(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1)) + var/index = copytext(href_list["doorder"], 1, length(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1)) var/multi = text2num(copytext(href_list["doorder"], -1)) if(!isnum(multi)) return 1 @@ -656,7 +656,7 @@ SSnanoui.update_uis(src) return 1 - var/index = copytext(href_list["doorder"], 1, lentext(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1)) + var/index = copytext(href_list["doorder"], 1, length(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1)) var/multi = text2num(copytext(href_list["doorder"], -1)) if(!isnum(multi)) return 1 diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm index 5cc26bcca14..a55657fc724 100644 --- a/code/modules/station_goals/dna_vault.dm +++ b/code/modules/station_goals/dna_vault.dm @@ -110,6 +110,9 @@ var/list/non_simple_animals = typecacheof(list(/mob/living/carbon/human/monkey,/ //humans if(ishuman(target)) var/mob/living/carbon/human/H = target + if(NO_DNA in H.dna.species.species_traits) + to_chat(user, "This humanoid doesn't have DNA.") + return if(dna[H.dna.uni_identity]) to_chat(user, "Humanoid data already present in local storage.") return diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index c66d95df899..54a9c4c88be 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -83,7 +83,7 @@ /datum/surgery_step/generic/clamp_bleeders/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(" [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ + user.visible_message(" [user]'s hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ " Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!",) affected.receive_damage(10) return 0 diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index c63cd286787..867e53579be 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -144,9 +144,9 @@ /proc/can_operate(mob/living/carbon/M) if(locate(/obj/machinery/optable, M.loc) && (M.lying || M.resting)) return TRUE - if(locate(/obj/structure/bed, M.loc) && (M.buckled || M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat)) + if(locate(/obj/structure/bed, M.loc) && (M.buckled || M.lying || M.IsWeakened() || M.stunned || M.paralysis || M.sleeping || M.stat)) return TRUE - if(locate(/obj/structure/table, M.loc) && (M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat)) + if(locate(/obj/structure/table, M.loc) && (M.lying || M.IsWeakened() || M.stunned || M.paralysis || M.sleeping || M.stat)) return TRUE return FALSE diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 2c891632770..1fde13e246e 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -47,7 +47,7 @@ var/damage_msg = "You feel an intense pain" var/broken_description - var/open = 0 + var/open = 0 // If the body part has an open incision from surgery var/sabotaged = 0 //If a prosthetic limb is emagged, it will detonate when it fails. var/encased // Needs to be opened with a saw to access the organs. diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 98ed11672fb..25f87d71104 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -283,7 +283,7 @@ /obj/item/organ/internal/honktumor/cursed/on_life() //No matter what you do, no matter who you are, no matter where you go, you're always going to be a fat, stuttering dimwit. ..() - owner.setBrainLoss(80) + owner.setBrainLoss(80, use_brain_mod = FALSE) owner.set_nutrition(9000) owner.overeatduration = 9000 diff --git a/config/example/motd.txt b/config/example/motd.txt index 106be771704..f39e579a6f7 100644 --- a/config/example/motd.txt +++ b/config/example/motd.txt @@ -1,5 +1,5 @@

Welcome to Space Station 13!

--This server is running Paradise's modification of the Baystation 12 and /tg/station13 SS13 code. +-This server is running Paradise's modification of the Baystation 12 and /tg/station13 SS13 code.

GitHub: https://github.com/ParadiseSS13/Paradise diff --git a/config/example/rules.html b/config/example/rules.html index c7a717aca63..ef37effcea4 100644 --- a/config/example/rules.html +++ b/config/example/rules.html @@ -4,7 +4,7 @@ diff --git a/goon/browserassets/html/browserOutput.html b/goon/browserassets/html/browserOutput.html index cfa67167f88..a7dfb16abee 100644 --- a/goon/browserassets/html/browserOutput.html +++ b/goon/browserassets/html/browserOutput.html @@ -15,7 +15,6 @@ - diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js index 1fcca3c6068..40a69245188 100644 --- a/goon/browserassets/js/browserOutput.js +++ b/goon/browserassets/js/browserOutput.js @@ -41,6 +41,7 @@ var opts = { 'suppressOptionsClose': false, //Whether or not we should be hiding the suboptions menu 'highlightTerms': [], 'highlightLimit': 5, + 'highlightRegexEnable':false, 'highlightColor': '#FFFF00', //The color of the highlighted message 'pingDisabled': false, //Has the user disabled the ping counter @@ -71,6 +72,8 @@ var opts = { 'enableEmoji': true }; +var regexHasError = false; //variable to check if regex has excepted + function outerHTML(el) { var wrap = document.createElement('div'); wrap.appendChild(el.cloneNode(true)); @@ -90,6 +93,19 @@ if (typeof String.prototype.trim !== 'function') { }; } +//Polyfill for string.prototype.includes. Why the fuck. Just why the fuck. +if (!String.prototype.includes) { + String.prototype.includes = function(search, start) { + 'use strict'; + + if (search instanceof RegExp) { + throw TypeError('first argument must not be a RegExp'); + } + if (start === undefined) { start = 0; } + return this.indexOf(search, start) !== -1; + }; +} + //Shit fucking piece of crap that doesn't work god fuckin damn it function linkify(text) { var rex = /((?:'+el.innerHTML+'
' //encloseincludes + continue; + } + var rexp; + try{ + rexp = new RegExp(opts.highlightTerms[i],"gmi") + } catch(e){ + el.innerHTML+='
Your highlight regex - '+opts.highlightTerms[i]+' - is malformed. Thrown exception: '+e+'' + regexHasError = true; + return; + } + el.innerHTML = el.innerHTML.replace(rexp,"$0") //i cant figure out a proper, non snowflakey way to let people select the group that gets highlighted } } } @@ -390,7 +416,8 @@ function handleClientData(ckey, ip, compid) { } } - if (opts.clientData.length >= opts.clientDataLimit) { + //Lets make sure we obey our limit (can connect from server with higher limit) + while (opts.clientData.length >= opts.clientDataLimit) { opts.clientData.shift(); } } else { @@ -572,6 +599,7 @@ $(function() { 'spingDisabled': getCookie('pingdisabled'), 'shighlightTerms': getCookie('highlightterms'), 'shighlightColor': getCookie('highlightcolor'), + 'shighlightRegexEnable': getCookie('highlightregexenable') == "true", 'shideSpam': getCookie('hidespam'), 'darkChat': getCookie('darkChat'), }; @@ -609,6 +637,10 @@ $(function() { opts.highlightColor = savedConfig.shighlightColor; internalOutput('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal'); } + if (savedConfig.shighlightRegexEnable) { + opts.highlightRegexEnable = savedConfig.shighlightRegexEnable; + internalOutput('Loaded highlight regex enable of: '+savedConfig.shighlightRegexEnable+'', 'internal'); + } if (savedConfig.shideSpam) { opts.hideSpam = $.parseJSON(savedConfig.shideSpam); internalOutput('Loaded hide spam preference of: ' + savedConfig.shideSpam + '', 'internal'); @@ -965,10 +997,6 @@ $(function() { }); $('#highlightTerm').click(function(e) { - if(!($().mark)) { - internalOutput('Highlighting is disabled. You are probably using Internet Explorer 8 and need to update.', 'internal'); - return; - } if ($('.popup .highlightTerm').is(':visible')) {return;} var termInputs = ''; for (var i = 0; i < opts.highlightLimit; i++) { @@ -976,7 +1004,9 @@ $(function() { } var popupContent = '
String Highlighting
' + '
' + - '
Choose up to '+opts.highlightLimit+' strings that will highlight the line when they appear in chat.
' + + '
Choose up to '+opts.highlightLimit+' strings that will highlight the line when they appear in chat.
'+ + 'Enable Regex'+ + '
See here for details
' + '
' + termInputs + '
' + '
'; createPopup(popupContent, 250); + document.querySelector(".popup #highlightRegexEnable").checked = opts.highlightRegexEnable; }); - $('body').on('keyup', '#highlightColor', function() { var color = $('#highlightColor').val(); color = color.trim(); @@ -1014,15 +1044,19 @@ $(function() { } var color = $('#highlightColor').val(); + opts.highlightRegexEnable = document.querySelector("#highlightRegexEnable").checked color = color.trim(); if (color == '' || color.charAt(0) != '#') { opts.highlightColor = '#FFFF00'; } else { opts.highlightColor = color; } + regexHasError = false; //they changed the regex so it might be valid now + var $popup = $('#highlightPopup').closest('.popup'); $popup.remove(); + setCookie('highlightregexenable', opts.highlightRegexEnable,365) setCookie('highlightterms', JSON.stringify(opts.highlightTerms), 365); setCookie('highlightcolor', opts.highlightColor, 365); }); diff --git a/goon/browserassets/js/jquery.mark.min.js b/goon/browserassets/js/jquery.mark.min.js deleted file mode 100644 index b399b7901b4..00000000000 --- a/goon/browserassets/js/jquery.mark.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*!*************************************************** - * mark.js v7.0.2 - * https://github.com/julmot/mark.js - * Copyright (c) 2014–2016, Julian Motz - * Released under the MIT license https://git.io/vwTVl - *****************************************************/ -"use strict";function _classCallCheck(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var _extends=Object.assign||function(a){for(var b=1;b-1)return!1;a=a.replace(new RegExp("["+b+"]","gmi"),"["+b+"]"),c.push(b)}return!0})}),a}},{key:"createMergedBlanksRegExp",value:function(a){return a.replace(/[\s]+/gim,"[\\s]*")}},{key:"createAccuracyRegExp",value:function(a){var b=this,c=this.opt.accuracy,d="string"==typeof c?c:c.value,e="string"==typeof c?[]:c.limiters,f="";switch(e.forEach(function(a){f+="|"+b.escapeStr(a)}),d){case"partially":return"()("+a+")";case"complementary":return"()([^\\s"+f+"]*"+a+"[^\\s"+f+"]*)";case"exactly":return"(^|\\s"+f+")("+a+")(?=$|\\s"+f+")"}}},{key:"getSeparatedKeywords",value:function(a){var b=this,c=[];return a.forEach(function(a){b.opt.separateWordSearch?a.split(" ").forEach(function(a){a.trim()&&c.push(a)}):a.trim()&&c.push(a)}),{keywords:c,length:c.length}}},{key:"getElements",value:function(){var a=void 0,b=[];return a="undefined"==typeof this.ctx?[]:this.ctx instanceof HTMLElement?[this.ctx]:Array.isArray(this.ctx)?this.ctx:Array.prototype.slice.call(this.ctx),a.forEach(function(a){if(-1===b.indexOf(a)){b.push(a);var c=a.querySelectorAll("*");c.length&&(b=b.concat(Array.prototype.slice.call(c)))}}),a.length||this.log("Empty context","warn"),{elements:b,length:b.length}}},{key:"matches",value:function(a,b){return(a.matches||a.matchesSelector||a.msMatchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.oMatchesSelector).call(a,b)}},{key:"matchesExclude",value:function(a,b){var c=this,d=!0,e=this.opt.exclude.concat(["script","style","title"]);return this.opt.iframes||(e=e.concat(["iframe"])),b&&(e=e.concat(["*[data-markjs='true']"])),e.every(function(b){return c.matches(a,b)?d=!1:!0}),!d}},{key:"onIframeReady",value:function(a,b,c){try{!function(){var d=a.contentWindow,e="about:blank",f="complete",g=function(){try{if(null===d.document)throw new Error("iframe inaccessible");b(d.document)}catch(a){c()}},h=function(){var b=a.getAttribute("src").trim(),c=d.location.href;return c===e&&b!==e&&b},i=function(){var b=function b(){try{h()||(a.removeEventListener("load",b),g())}catch(a){c()}};a.addEventListener("load",b)};d.document.readyState===f?h()?i():g():i()}()}catch(a){c()}}},{key:"forEachElementInIframe",value:function(a,b){var c=this,d=arguments.length<=2||void 0===arguments[2]?function(){}:arguments[2],e=0,f=function(){--e<1&&d()};this.onIframeReady(a,function(a){var d=Array.prototype.slice.call(a.querySelectorAll("*"));0===(e=d.length)&&f(),d.forEach(function(a){"iframe"===a.tagName.toLowerCase()?!function(){var d=0;c.forEachElementInIframe(a,function(a,c){b(a,c),c-1===d&&f(),d++},f)}():(b(a,d.length),f())})},function(){var b=a.getAttribute("src");c.log("iframe '"+b+"' could not be accessed","warn"),f()})}},{key:"forEachElement",value:function(a){var b=this,c=arguments.length<=1||void 0===arguments[1]?function(){}:arguments[1],d=arguments.length<=2||void 0===arguments[2]?!0:arguments[2],e=this.getElements(),f=e.elements,g=e.length,h=function(){0===--g&&c()};h(++g),f.forEach(function(c){if(!b.matchesExclude(c,d)){if("iframe"===c.tagName.toLowerCase())return void b.forEachElementInIframe(c,function(c){b.matchesExclude(c,d)||a(c)},h);a(c)}h()})}},{key:"forEachNode",value:function(a){var b=arguments.length<=1||void 0===arguments[1]?function(){}:arguments[1];this.forEachElement(function(b){for(b=b.firstChild;b;b=b.nextSibling)3===b.nodeType&&b.textContent.trim()&&a(b)},b)}},{key:"wrapMatches",value:function(a,c,d,e,f){for(var g=this.opt.element?this.opt.element:"mark",h=d?0:2,i=void 0;null!==(i=c.exec(a.textContent));)if(e(i[h])){var j=i.index;d||(j+=i[h-1].length);var k=a.splitText(j);if(a=k.splitText(i[h].length),null!==k.parentNode){var l=b.createElement(g);l.setAttribute("data-markjs","true"),this.opt.className&&l.setAttribute("class",this.opt.className),l.textContent=i[h],k.parentNode.replaceChild(l,k),f(l)}c.lastIndex=0}}},{key:"unwrapMatches",value:function(a){for(var c=a.parentNode,d=b.createDocumentFragment();a.firstChild;)d.appendChild(a.removeChild(a.firstChild));c.replaceChild(d,a),c.normalize()}},{key:"markRegExp",value:function(a,b){var c=this;this.opt=b,this.log('Searching with expression "'+a+'"');var d=0,e=function(a){d++,c.opt.each(a)};this.forEachNode(function(b){c.wrapMatches(b,a,!0,function(a){return c.opt.filter(b,a,d)},e)},function(){0===d&&c.opt.noMatch(a),c.opt.done(d)})}},{key:"mark",value:function(a,b){var c=this;this.opt=b;var d=this.getSeparatedKeywords("string"==typeof a?[a]:a),e=d.keywords,f=d.length,g=0;0===f&&this.opt.done(g),e.forEach(function(a){var b=new RegExp(c.createRegExp(a),"gmi"),d=0,h=function(a){d++,g++,c.opt.each(a)};c.log('Searching with expression "'+b+'"'),c.forEachNode(function(e){c.wrapMatches(e,b,!1,function(){return c.opt.filter(e,a,d,g)},h)},function(){0===d&&c.opt.noMatch(a),e[f-1]===a&&c.opt.done(g)})})}},{key:"unmark",value:function(a){var b=this;this.opt=a;var c=this.opt.element?this.opt.element:"*";c+="[data-markjs]",this.opt.className&&(c+="."+this.opt.className),this.log('Removal selector "'+c+'"'),this.forEachElement(function(a){b.matches(a,c)&&b.unwrapMatches(a)},function(){b.opt.done()},!1)}},{key:"opt",set:function(b){this._opt=_extends({},{element:"",className:"",exclude:[],iframes:!1,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",each:function(){},noMatch:function(){},filter:function(){return!0},done:function(){},debug:!1,log:a.console},b)},get:function(){return this._opt}}]),c}();return c.fn.mark=function(a,b){return new d(this).mark(a,b),this},c.fn.markRegExp=function(a,b){return new d(this).markRegExp(a,b),this},c.fn.unmark=function(a){return new d(this).unmark(a),this},c},window,document); \ No newline at end of file diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm index cbeb7ae3ab0..f782e663d0a 100644 --- a/goon/code/datums/browserOutput.dm +++ b/goon/code/datums/browserOutput.dm @@ -16,11 +16,18 @@ var/list/chatResources = list( "goon/browserassets/html/saveInstructions.html" ) +//Should match the value set in the browser js +#define MAX_COOKIE_LENGTH 5 + /var/savefile/iconCache = new /savefile("data/iconCache.sav") /var/chatDebug = file("data/chatDebug.log") /datum/chatOutput var/client/owner = null + // How many times client data has been checked + var/total_checks = 0 + // When to next clear the client data checks counter + var/next_time_to_clear = 0 var/loaded = 0 var/list/messageQueue = list() var/cookieSent = 0 @@ -137,6 +144,16 @@ var/list/chatResources = list( ehjax_send(data = data) /datum/chatOutput/proc/analyzeClientData(cookie = "") + //Spam check + if(world.time > next_time_to_clear) + next_time_to_clear = world.time + (3 SECONDS) + total_checks = 0 + total_checks += 1 + if(total_checks > SPAM_TRIGGER_AUTOMUTE) + message_admins("[key_name(owner)] kicked for goonchat topic spam") + qdel(owner) + return + if(!cookie) return @@ -145,13 +162,21 @@ var/list/chatResources = list( if(connData && islist(connData) && connData.len > 0 && connData["connData"]) connectionHistory = connData["connData"] var/list/found = new() + if(connectionHistory.len > MAX_COOKIE_LENGTH) + message_admins("[key_name(src.owner)] was kicked for an invalid ban cookie)") + qdel(owner) + return for(var/i = connectionHistory.len; i >= 1; i--) + if(QDELETED(owner)) + //he got cleaned up before we were done + return var/list/row = connectionHistory[i] if(!row || row.len < 3 || !(row["ckey"] && row["compid"] && row["ip"])) return - if(world.IsBanned(row["ckey"], row["ip"], row["compid"], FALSE)) + if(world.IsBanned(key=row["ckey"], address=row["ip"], computer_id=row["compid"], type=null, check_ipintel=FALSE)) found = row break + CHECK_TICK //Add autoban using the DB_ban_record function //Uh oh this fucker has a history of playing on a banned account!! if (found.len > 0) @@ -284,3 +309,5 @@ var/to_chat_src to_chat_immediate(target, message, flag) return SSchat.queue(target, message, flag) + +#undef MAX_COOKIE_LENGTH \ No newline at end of file diff --git a/html/changelog.html b/html/changelog.html index d95c936a8cb..3ffad2b6c96 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -25,8 +25,7 @@
Paradise Station
-

- Visit our Discord channel:-Click Here- +

@@ -56,6 +55,82 @@ -->
+

27 October 2019

+

AdamElTablawy updated:

+
    +
  • Xenobiology can no longer produce hellhounds with gold slime cores.
  • +
+

AzuleUtama updated:

+
    +
  • Vampire's shape shift ability and DNA scrambler item now clear flavour text on use.
  • +
+

Darkmight9 updated:

+
    +
  • Adds a wide variety of craftable decorations! You can find them in the new 'Decorations' tab in the crafting menu.
  • +
  • tweaked the duct tape component so that you can now add it to items to make them naturally stick to walls.
  • +
  • added decorative sprites.
  • +
+

Fox McCloud updated:

+
    +
  • windows are easier to break
  • +
  • Adds in the Rod of Asclepius, a healing item that carries an immense burden
  • +
  • Fixes Bubblegum spawning being ridiculously rare
  • +
  • Fixes planetary atmos not correctly happening
  • +
  • Fixes atmos pipe unwrenching
  • +
  • Survival pod medical vendors only have 2 pairs of splints instead of a wide array of medicines
  • +
  • Hivelord core, when used on someone, no longer fully revives them; instead it heals 25 burn, 25 brute, resets body temperature, removes all CC, cures all internal bleeding, and mends all fractures (slowdown bonus still stays
  • +
  • updates the close icon for storage to not be a trashy codersprite
  • +
  • Fixes excessive mob and tendril clumping on Lavaland
  • +
  • Fixes being able to exploit the destructive analyzer for unlimited materials
  • +
  • Fixes Hierophant arena atmos
  • +
+

Ionward updated:

+
    +
  • fixed Battlemage armor having an unintended helmet light
  • +
  • added Vox versions of Battlemage, Paranormal, Inquisitor, Berserker, and Syndicate Elite Hardsuits.
  • +
+

SteelSlayer updated:

+
    +
  • Fixes the RPED and bluespace RPED not displaying a list of parts in players chat when used on a machine
  • +
+

TDSSS updated:

+
    +
  • yellow documents are no longer indestructible.
  • +
+

Tayyyyyyy updated:

+
    +
  • single quotes showing up weird in names and announcement titles
  • +
+

Terilia updated:

+
    +
  • Headcrab Nests
  • +
  • Headcrabs can now eat dead simple_animal corpses to regain 10 hp.
  • +
  • Poison Headcrabs will not inject LSD anymore.
  • +
  • Headcrabs have more HP and some do more damage.
  • +
  • Headcrabs will not stop attacking people after they are unconscious.
  • +
  • Headcrab Nest DMI
  • +
+

Ty-Omaha updated:

+
    +
  • Admin attack log level of heirophant club updated
  • +
+

actioninja updated:

+
    +
  • Nanoui interfaces in fancy mode now open more cleanly
  • +
+

craftxbox updated:

+
    +
  • Vanilla JS Regex for chat highlighting
  • +
  • Removed jquery mark
  • +
  • quickfix to stop people using the scanner inside it
  • +
+

farie82 updated:

+
    +
  • Cult whispering now uses your real name
  • +
  • Fixed the invisible blob zombies
  • +
  • A runtime in blob/factory/run_action
  • +
+

13 October 2019

Darkmight9 updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index d43324f9143..07c327faac8 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -11754,3 +11754,60 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscdel: Reverted autoban using legacy system causing issues streather: - spellcheck: fixed a typo in the autolathe +2019-10-27: + AdamElTablawy: + - rscdel: Xenobiology can no longer produce hellhounds with gold slime cores. + AzuleUtama: + - tweak: Vampire's shape shift ability and DNA scrambler item now clear flavour + text on use. + Darkmight9: + - rscadd: Adds a wide variety of craftable decorations! You can find them in the + new 'Decorations' tab in the crafting menu. + - tweak: tweaked the duct tape component so that you can now add it to items to + make them naturally stick to walls. + - imageadd: added decorative sprites. + Fox McCloud: + - tweak: windows are easier to break + - rscadd: Adds in the Rod of Asclepius, a healing item that carries an immense burden + - bugfix: Fixes Bubblegum spawning being ridiculously rare + - bugfix: Fixes planetary atmos not correctly happening + - bugfix: Fixes atmos pipe unwrenching + - tweak: Survival pod medical vendors only have 2 pairs of splints instead of a + wide array of medicines + - tweak: Hivelord core, when used on someone, no longer fully revives them; instead + it heals 25 burn, 25 brute, resets body temperature, removes all CC, cures all + internal bleeding, and mends all fractures (slowdown bonus still stays + - rscadd: updates the close icon for storage to not be a trashy codersprite + - bugfix: Fixes excessive mob and tendril clumping on Lavaland + - bugfix: Fixes being able to exploit the destructive analyzer for unlimited materials + - bugfix: Fixes Hierophant arena atmos + Ionward: + - bugfix: fixed Battlemage armor having an unintended helmet light + - imageadd: added Vox versions of Battlemage, Paranormal, Inquisitor, Berserker, + and Syndicate Elite Hardsuits. + SteelSlayer: + - bugfix: Fixes the RPED and bluespace RPED not displaying a list of parts in players + chat when used on a machine + TDSSS: + - tweak: yellow documents are no longer indestructible. + Tayyyyyyy: + - bugfix: single quotes showing up weird in names and announcement titles + Terilia: + - rscadd: Headcrab Nests + - tweak: Headcrabs can now eat dead simple_animal corpses to regain 10 hp. + - tweak: Poison Headcrabs will not inject LSD anymore. + - tweak: Headcrabs have more HP and some do more damage. + - tweak: Headcrabs will not stop attacking people after they are unconscious. + - imageadd: Headcrab Nest DMI + Ty-Omaha: + - tweak: Admin attack log level of heirophant club updated + actioninja: + - bugfix: Nanoui interfaces in fancy mode now open more cleanly + craftxbox: + - rscadd: Vanilla JS Regex for chat highlighting + - rscdel: Removed jquery mark + - bugfix: quickfix to stop people using the scanner inside it + farie82: + - tweak: Cult whispering now uses your real name + - bugfix: Fixed the invisible blob zombies + - bugfix: A runtime in blob/factory/run_action diff --git a/html/changelogs/AutoChangeLog-pr-12459.yml b/html/changelogs/AutoChangeLog-pr-12459.yml new file mode 100644 index 00000000000..18ab9dbd1f8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12459.yml @@ -0,0 +1,4 @@ +author: "Kyep" +delete-after: True +changes: + - tweak: "Tweaked Greater Hellhound, added more non-violent options and one unique combat spell." diff --git a/html/changelogs/AutoChangeLog-pr-12546.yml b/html/changelogs/AutoChangeLog-pr-12546.yml deleted file mode 100644 index df9349cefc1..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12546.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "AzuleUtama" -delete-after: True -changes: - - tweak: "Vampire's shape shift ability and DNA scrambler item now clear flavour text on use." diff --git a/html/changelogs/AutoChangeLog-pr-12548.yml b/html/changelogs/AutoChangeLog-pr-12548.yml deleted file mode 100644 index b592273a361..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12548.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - rscadd: "Adds in the Rod of Asclepius, a healing item that carries an immense burden" diff --git a/html/changelogs/AutoChangeLog-pr-12560.yml b/html/changelogs/AutoChangeLog-pr-12560.yml deleted file mode 100644 index c5e2280cf71..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12560.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "farie82" -delete-after: True -changes: - - tweak: "Cult whispering now uses your real name" diff --git a/html/changelogs/AutoChangeLog-pr-12571.yml b/html/changelogs/AutoChangeLog-pr-12571.yml new file mode 100644 index 00000000000..d9d46a5766f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12571.yml @@ -0,0 +1,5 @@ +author: "JKnutson101" +delete-after: True +changes: + - tweak: "Combined the Rite of Tribute and Rite of Enlightenment into one Rite of Offering." + - bugfix: "Sacrificing now properly puts victims that have at one point had CKeys into soul stones, or polls dead-chat to do so." diff --git a/html/changelogs/AutoChangeLog-pr-12572.yml b/html/changelogs/AutoChangeLog-pr-12572.yml deleted file mode 100644 index ae6508c8ec2..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12572.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - bugfix: "Fixes Bubblegum spawning being ridiculously rare" diff --git a/html/changelogs/AutoChangeLog-pr-12581.yml b/html/changelogs/AutoChangeLog-pr-12581.yml deleted file mode 100644 index 9be4f8a2d43..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12581.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SteelSlayer" -delete-after: True -changes: - - bugfix: "Fixes the RPED and bluespace RPED not displaying a list of parts in players chat when used on a machine" diff --git a/html/changelogs/AutoChangeLog-pr-12582.yml b/html/changelogs/AutoChangeLog-pr-12582.yml deleted file mode 100644 index 005b7e7a9e5..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12582.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ty-Omaha" -delete-after: True -changes: - - tweak: "Admin attack log level of heirophant club updated" diff --git a/html/changelogs/AutoChangeLog-pr-12583.yml b/html/changelogs/AutoChangeLog-pr-12583.yml deleted file mode 100644 index 09aef16b438..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12583.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Tayyyyyyy" -delete-after: True -changes: - - bugfix: "single quotes showing up weird in names and announcement titles" diff --git a/html/changelogs/AutoChangeLog-pr-12584.yml b/html/changelogs/AutoChangeLog-pr-12584.yml deleted file mode 100644 index f1d5b4c16f4..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12584.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - bugfix: "Fixes planetary atmos not correctly happening" diff --git a/html/changelogs/AutoChangeLog-pr-12586.yml b/html/changelogs/AutoChangeLog-pr-12586.yml deleted file mode 100644 index 8a35eb2a970..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12586.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - bugfix: "Fixes atmos pipe unwrenching" diff --git a/html/changelogs/AutoChangeLog-pr-12587.yml b/html/changelogs/AutoChangeLog-pr-12587.yml deleted file mode 100644 index 2aeb4c5506c..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12587.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - tweak: "Survival pod medical vendors only have 2 pairs of splints instead of a wide array of medicines" - - tweak: "Hivelord core, when used on someone, no longer fully revives them; instead it heals 25 burn, 25 brute, resets body temperature, removes all CC, cures all internal bleeding, and mends all fractures (slowdown bonus still stays" diff --git a/html/changelogs/AutoChangeLog-pr-12596.yml b/html/changelogs/AutoChangeLog-pr-12596.yml new file mode 100644 index 00000000000..ca0b0e32f0d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12596.yml @@ -0,0 +1,6 @@ +author: "Ionward" +delete-after: True +changes: + - tweak: "Grey, Tajaran, Unathi, and Vulpkanin now properly have species specific fits for soft space suits." + - tweak: "Vox can now wear soft space suits, such as EVA (Clown and Mime included), NASA Void, and Syndicate suits." + - imageadd: "Added Vox soft suit sprites." diff --git a/html/changelogs/AutoChangeLog-pr-12600.yml b/html/changelogs/AutoChangeLog-pr-12600.yml new file mode 100644 index 00000000000..0b84030ed0a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12600.yml @@ -0,0 +1,5 @@ +author: "SteelSlayer" +delete-after: True +changes: + - bugfix: "Fixes the \"List SSDs and AFKs panel\" showing everyone as the target of an assassinate objective" + - bugfix: "The global objectives list is now viewable in the MC Globals menu" diff --git a/html/changelogs/AutoChangeLog-pr-12655.yml b/html/changelogs/AutoChangeLog-pr-12655.yml new file mode 100644 index 00000000000..c32a92c9289 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12655.yml @@ -0,0 +1,6 @@ +author: "craftxbox" +delete-after: True +changes: + - bugfix: "fixed colors not working without regex" + - bugfix: "fixed text panel not loading when an invalid regex is added" + - rscadd: "polyfilled string.prototype.includes" diff --git a/html/changelogs/AutoChangeLog-pr-12665.yml b/html/changelogs/AutoChangeLog-pr-12665.yml new file mode 100644 index 00000000000..7761e78cf63 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12665.yml @@ -0,0 +1,4 @@ +author: "TDSSS" +delete-after: True +changes: + - rscdel: "duplicate mecha definitions" diff --git a/html/changelogs/AutoChangeLog-pr-12717.yml b/html/changelogs/AutoChangeLog-pr-12717.yml new file mode 100644 index 00000000000..6f11a3b38d0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12717.yml @@ -0,0 +1,5 @@ +author: "moxian" +delete-after: True +changes: + - bugfix: "being in a locker no longer interferes with tracking implant tracking" + - bugfix: "locator no longer locates tracking implants on other z levels." diff --git a/html/changelogs/AutoChangeLog-pr-12720.yml b/html/changelogs/AutoChangeLog-pr-12720.yml new file mode 100644 index 00000000000..0efc114b24e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12720.yml @@ -0,0 +1,4 @@ +author: "moxian" +delete-after: True +changes: + - bugfix: "fixed singulo being unable to expand when placed next to containment wall" diff --git a/html/changelogs/AutoChangeLog-pr-12725.yml b/html/changelogs/AutoChangeLog-pr-12725.yml new file mode 100644 index 00000000000..24b8ec37da8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12725.yml @@ -0,0 +1,4 @@ +author: "TDSSS" +delete-after: True +changes: + - bugfix: "blobbernaut vision blur now clears as intended." diff --git a/html/changelogs/AutoChangeLog-pr-12740.yml b/html/changelogs/AutoChangeLog-pr-12740.yml new file mode 100644 index 00000000000..b2e1d3fff39 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12740.yml @@ -0,0 +1,4 @@ +author: "Drakeven" +delete-after: True +changes: + - bugfix: "Fixed mislabeled traitor and mindslave special role." diff --git a/html/changelogs/AutoChangeLog-pr-12747.yml b/html/changelogs/AutoChangeLog-pr-12747.yml new file mode 100644 index 00000000000..ca9e96e84c1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12747.yml @@ -0,0 +1,5 @@ +author: "Cazdon" +delete-after: True +changes: + - bugfix: "Admin Roles no longer appear on manifest." + - tweak: "Central Command PDA's no longer appear on the messenger list." diff --git a/html/changelogs/AutoChangeLog-pr-12751.yml b/html/changelogs/AutoChangeLog-pr-12751.yml new file mode 100644 index 00000000000..1dc7c27f527 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12751.yml @@ -0,0 +1,4 @@ +author: "TDSSS" +delete-after: True +changes: + - bugfix: "fixed a bug preventing ticket system from working under some circumstances." diff --git a/html/changelogs/AutoChangeLog-pr-12756.yml b/html/changelogs/AutoChangeLog-pr-12756.yml new file mode 100644 index 00000000000..50e5e5e4bd9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12756.yml @@ -0,0 +1,4 @@ +author: "SteelSlayer" +delete-after: True +changes: + - bugfix: "Reverts some terrible changes that are causing some bugs with traitors" diff --git a/html/changelogs/AutoChangeLog-pr-12757.yml b/html/changelogs/AutoChangeLog-pr-12757.yml new file mode 100644 index 00000000000..9cba05e588f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12757.yml @@ -0,0 +1,4 @@ +author: "VeteranKyl" +delete-after: True +changes: + - bugfix: "DNA Samplers now check if the target species has DNA." diff --git a/html/changelogs/AutoChangeLog-pr-12760.yml b/html/changelogs/AutoChangeLog-pr-12760.yml new file mode 100644 index 00000000000..92600e6ed76 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12760.yml @@ -0,0 +1,4 @@ +author: "SteelSlayer" +delete-after: True +changes: + - bugfix: "Fixes AIs with the combat module not being able to hack APCs" diff --git a/html/changelogs/AutoChangeLog-pr-12761.yml b/html/changelogs/AutoChangeLog-pr-12761.yml new file mode 100644 index 00000000000..7355e826a7b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12761.yml @@ -0,0 +1,4 @@ +author: "VeteranKyl" +delete-after: True +changes: + - bugfix: "Fixed the envenomed blob's spore toxin not causing harm." diff --git a/html/changelogs/AutoChangeLog-pr-12765.yml b/html/changelogs/AutoChangeLog-pr-12765.yml new file mode 100644 index 00000000000..b1ee7b0dd05 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12765.yml @@ -0,0 +1,4 @@ +author: "Cazdon" +delete-after: True +changes: + - bugfix: "Potential Convertee's being unable to be converted." diff --git a/html/templates/header.html b/html/templates/header.html index fac4d7b280a..5d499bbc347 100644 --- a/html/templates/header.html +++ b/html/templates/header.html @@ -25,7 +25,7 @@
    Paradise Station
    -

    +

    Visit our Discord channel:-Click Here- diff --git a/icons/mob/headcrab.dmi b/icons/mob/headcrab.dmi index b308179b45f..a1081b39835 100644 Binary files a/icons/mob/headcrab.dmi and b/icons/mob/headcrab.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 78778b27d97..6a29745a7a7 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/species/vox/helmet.dmi b/icons/mob/species/vox/helmet.dmi index 74bd0762ff8..7aba8b0d3d8 100644 Binary files a/icons/mob/species/vox/helmet.dmi and b/icons/mob/species/vox/helmet.dmi differ diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi index a088466564f..467dcd713aa 100644 Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ diff --git a/icons/obj/decorations.dmi b/icons/obj/decorations.dmi index a3b7f9dcd20..8bbfa2e3592 100644 Binary files a/icons/obj/decorations.dmi and b/icons/obj/decorations.dmi differ diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 17ebf4c9219..511b578ad4a 100644 Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ diff --git a/paradise.dme b/paradise.dme index abd9b1372a3..62d9624cf5c 100644 --- a/paradise.dme +++ b/paradise.dme @@ -844,6 +844,7 @@ #include "code\game\objects\items\contraband.dm" #include "code\game\objects\items\control_wand.dm" #include "code\game\objects\items\crayons.dm" +#include "code\game\objects\items\decorations.dm" #include "code\game\objects\items\dehy_carp.dm" #include "code\game\objects\items\documents.dm" #include "code\game\objects\items\flag.dm" @@ -1755,6 +1756,7 @@ #include "code\modules\mob\living\carbon\death.dm" #include "code\modules\mob\living\carbon\give.dm" #include "code\modules\mob\living\carbon\life.dm" +#include "code\modules\mob\living\carbon\status_procs.dm" #include "code\modules\mob\living\carbon\superheroes.dm" #include "code\modules\mob\living\carbon\update_icons.dm" #include "code\modules\mob\living\carbon\update_status.dm" diff --git a/tools/mapmerge2/requirements.txt b/tools/mapmerge2/requirements.txt index adb42438e7e..d24cb40dcc6 100644 --- a/tools/mapmerge2/requirements.txt +++ b/tools/mapmerge2/requirements.txt @@ -1,3 +1,3 @@ pygit2==0.27.2 bidict==0.13.1 -Pillow==5.1.0 +Pillow==6.2.0