From 275266a73a7f2ba937244e0603424f383d51fc98 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 9 Sep 2019 01:26:50 -0400 Subject: [PATCH 01/41] Admin verb mega update changes/removes all sorts of admin verbs, requested by Kyet --- code/__DEFINES/subsystems.dm | 1 - code/controllers/subsystem/tickets/tickets.dm | 13 +- code/modules/admin/admin.dm | 4 +- code/modules/admin/admin_verbs.dm | 14 +- code/modules/admin/stickyban.dm | 210 ------------------ .../admin/tickets/adminticketsverbs.dm | 4 +- .../admin/tickets/mentorticketsverbs.dm | 4 +- code/modules/admin/topic.dm | 3 - code/modules/admin/verbs/adminjump.dm | 2 +- code/modules/admin/verbs/freeze.dm | 4 +- code/modules/admin/verbs/randomverbs.dm | 37 ++- paradise.dme | 1 - 12 files changed, 40 insertions(+), 257 deletions(-) delete mode 100644 code/modules/admin/stickyban.dm diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index c55fec2cd87..4807da6ec42 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -71,7 +71,6 @@ #define INIT_ORDER_ICON_SMOOTHING -5 #define INIT_ORDER_OVERLAY -6 #define INIT_ORDER_XKEYSCORE -10 -#define INIT_ORDER_STICKY_BAN -10 #define INIT_ORDER_TICKETS -10 #define INIT_ORDER_LIGHTING -20 #define INIT_ORDER_SHUTTLE -21 diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm index a5623775b5e..951a96558ca 100644 --- a/code/controllers/subsystem/tickets/tickets.dm +++ b/code/controllers/subsystem/tickets/tickets.dm @@ -263,7 +263,12 @@ UI STUFF else continue - dat += "" + dat += "" + dat += "

Resolve All

" + if(ticket_system_name == "Mentor Tickets") + dat += "Resolve All Open Mentor Tickets" + else + dat += "Resolve All Open Admin Tickets" return dat @@ -402,6 +407,12 @@ UI STUFF takeTicket(indexNum) showDetailUI(usr, indexNum) + if(href_list["resolveall"]) + if(ticket_system_name == "Mentor Tickets") + usr.client.resolveAllMentorTickets() + else + usr.client.resolveAllAdminTickets() + /datum/controller/subsystem/tickets/proc/takeTicket(var/index) if(assignStaffToTicket(usr.client, index)) if(span_class == "mentorhelp") diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index d32a05eb312..60210f51903 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -54,7 +54,7 @@ var/global/nologevent = 0 ///////////////////////////////////////////////////////////////////////////////////////////////Panels /datum/admins/proc/show_player_panel(var/mob/M in GLOB.mob_list) - set category = "Admin" + set category = null set name = "Show Player Panel" set desc="Edit player (respawn, ban, heal, etc)" @@ -937,9 +937,9 @@ var/global/nologevent = 0 message_admins("[key_name_admin(usr)] checked the AI laws") /client/proc/update_mob_sprite(mob/living/carbon/human/H as mob) - set category = "Admin" set name = "Update Mob Sprite" set desc = "Should fix any mob sprite update errors." + set category = null if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index b66f83543dd..1c4d569507e 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -71,13 +71,12 @@ var/list/admin_verbs_admin = list( /client/proc/alt_check, /client/proc/secrets, /client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */ - /client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */ + /client/proc/change_human_appearance_self, /* Allows the human-based mob itself to change its basic appearance */ /client/proc/debug_variables, /client/proc/reset_all_tcs, /*resets all telecomms scripts*/ /client/proc/toggle_mentor_chat, /client/proc/toggle_advanced_interaction, /*toggle admin ability to interact with not only machines, but also atoms such as buttons and doors*/ - /client/proc/list_ssds, - /client/proc/list_afks, + /client/proc/list_ssds_afks, /client/proc/cmd_admin_headset_message, /client/proc/spawn_floor_cluwne, /client/proc/show_discord_duplicates, // This needs removing at some point, ingame discord linking got removed in #11359 @@ -85,8 +84,7 @@ var/list/admin_verbs_admin = list( ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, - /client/proc/jobbans, - /client/proc/stickybanpanel + /client/proc/jobbans ) var/list/admin_verbs_sounds = list( /client/proc/play_local_sound, @@ -365,7 +363,7 @@ var/list/admin_verbs_ticket = list( /client/proc/player_panel() set name = "Player Panel" - set category = "Admin" + set category = null if(!check_rights(R_ADMIN)) return @@ -803,7 +801,7 @@ var/list/admin_verbs_ticket = list( /client/proc/change_human_appearance_admin(mob/living/carbon/human/H in GLOB.mob_list) set name = "C.M.A. - Admin" set desc = "Allows you to change the mob appearance" - set category = "Admin" + set category = null if(!check_rights(R_ADMIN)) return @@ -829,7 +827,7 @@ var/list/admin_verbs_ticket = list( /client/proc/change_human_appearance_self(mob/living/carbon/human/H in GLOB.mob_list) set name = "C.M.A. - Self" set desc = "Allows the mob to change its appearance" - set category = "Admin" + set category = null if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/stickyban.dm b/code/modules/admin/stickyban.dm deleted file mode 100644 index 61759f2e36d..00000000000 --- a/code/modules/admin/stickyban.dm +++ /dev/null @@ -1,210 +0,0 @@ -/datum/admins/proc/stickyban(action,data) - if(!check_rights(R_BAN)) - return - - switch(action) - if("show") - stickyban_show() - return - if("add") - var/list/ban = list() - var/ckey - ban["admin"] = usr.key - ban["type"] = list("sticky") - ban["reason"] = "(InGameBan)([usr.key])" //this will be displayed in dd only - - if(data["ckey"]) - ckey = ckey(data["ckey"]) - else - ckey = clean_input("Ckey","Ckey","") - if(!ckey) - return - ckey = ckey(ckey) - if(get_stickyban_from_ckey(ckey)) - to_chat(usr, "Error: Can not add a stickyban: User already has a current sticky ban") - - if(data["reason"]) - ban["message"] = data["reason"] - else - var/reason = clean_input("Reason","Reason","Ban Evasion") - if(!reason) - return - ban["message"] = "[reason]" - - world.SetConfig("ban", ckey, list2stickyban(ban)) - - log_admin("[key_name(usr)] has stickybanned [ckey].\nReason: [ban["message"]]") - message_admins("[key_name_admin(usr)] has stickybanned [ckey].\nReason: [ban["message"]]") - - if("remove") - if(!data["ckey"]) - return - var/ckey = data["ckey"] - - var/ban = get_stickyban_from_ckey(ckey) - if(!ban) - to_chat(usr, "Error: No sticky ban for [ckey] found!") - return - if(alert("Are you sure you want to remove the sticky ban on [ckey]?","Are you sure","Yes","No") == "No") - return - if(!get_stickyban_from_ckey(ckey)) - to_chat(usr, "Error: The ban disappeared.") - return - world.SetConfig("ban", ckey, null) - - log_admin("[key_name(usr)] removed [ckey]'s stickyban") - message_admins("[key_name_admin(usr)] removed [ckey]'s stickyban") - - if("remove_alt") - if(!data["ckey"]) - return - var/ckey = data["ckey"] - if(!data["alt"]) - return - var/alt = ckey(data["alt"]) - var/ban = get_stickyban_from_ckey(ckey) - if(!ban) - to_chat(usr, "Error: No sticky ban for [ckey] found!") - return - - var/found = 0 - //we have to do it this way because byond keeps the case in its sticky ban matches WHY!!! - for(var/key in ban["keys"]) - if(ckey(key) == alt) - found = 1 - break - - if(!found) - to_chat(usr, "Error: [alt] is not linked to [ckey]'s sticky ban!") - return - - if(alert("Are you sure you want to disassociate [alt] from [ckey]'s sticky ban? \nNote: Nothing stops byond from re-linking them","Are you sure","Yes","No") == "No") - return - - //we have to do this again incase something changes - ban = get_stickyban_from_ckey(ckey) - if(!ban) - to_chat(usr, "Error: The ban disappeared.") - return - - found = 0 - for(var/key in ban["keys"]) - if(ckey(key) == alt) - ban["keys"] -= key - found = 1 - break - - if(!found) - to_chat(usr, "Error: [alt] link to [ckey]'s sticky ban disappeared.") - return - - world.SetConfig("ban",ckey,list2stickyban(ban)) - - log_admin("[key_name(usr)] has disassociated [alt] from [ckey]'s sticky ban") - message_admins("[key_name_admin(usr)] has disassociated [alt] from [ckey]'s sticky ban") - - if("edit") - if(!data["ckey"]) - return - var/ckey = data["ckey"] - var/ban = get_stickyban_from_ckey(ckey) - if(!ban) - to_chat(usr, "Error: No sticky ban for [ckey] found!") - return - var/oldreason = ban["message"] - var/reason = clean_input("Reason","Reason","[ban["message"]]") - if(!reason || reason == oldreason) - return - //we have to do this again incase something changed while we waited for input - ban = get_stickyban_from_ckey(ckey) - if(!ban) - to_chat(usr, "Error: The ban disappeared.") - return - ban["message"] = "[reason]" - - world.SetConfig("ban",ckey,list2stickyban(ban)) - - log_admin("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]") - message_admins("[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]") - - spawn(10) - stickyban_show() - -/datum/admins/proc/stickyban_gethtml(ckey, ban) - . = "\[-\][ckey]
" - . += "[ban["message"]] \[Edit\]
" - if(ban["admin"]) - . += "[ban["admin"]]
" - else - . += "LEGACY
" - . += "Caught keys
\n
    " - for(var/key in ban["keys"]) - if(ckey(key) == ckey) - continue - . += "
  1. \[-\][key]
  2. " - . += "
\n" - -/datum/admins/proc/stickyban_show() - if(!check_rights(R_BAN)) - return - - var/list/bans = sortList(world.GetConfig("ban")) - var/banhtml = "" - for(var/key in bans) - var/ckey = ckey(key) - var/ban = stickyban2list(world.GetConfig("ban",key)) - banhtml += "

\n" - banhtml += stickyban_gethtml(ckey,ban) - - var/html = {" - - Sticky Bans - - -

All Sticky Bans:

\[+\]
- [banhtml] - - "} - usr << browse(html,"window=stickybans;size=700x400") - -/proc/get_stickyban_from_ckey(var/ckey) - if(!ckey) - return null - ckey = ckey(ckey) - . = null - for(var/key in world.GetConfig("ban")) - if(ckey(key) == ckey) - . = stickyban2list(world.GetConfig("ban",key)) - break - -/proc/stickyban2list(var/ban) - if(!ban) - return null - . = params2list(ban) - .["keys"] = splittext(.["keys"], ",") - .["type"] = splittext(.["type"], ",") - .["IP"] = splittext(.["IP"], ",") - .["computer_id"] = splittext(.["computer_id"], ",") - -/proc/list2stickyban(var/list/ban) - if(!ban || !islist(ban)) - return null - . = ban.Copy() - if(.["keys"]) - .["keys"] = jointext(.["keys"], ",") - if(.["type"]) - .["type"] = jointext(.["type"], ",") - if(.["IP"]) - .["IP"] = jointext(.["IP"], ",") - if(.["computer_id"]) - .["computer_id"] = jointext(.["computer_id"], ",") - . = list2params(.) - -/client/proc/stickybanpanel() - set name = "Sticky Ban Panel" - set category = "Admin" - - if(!check_rights(R_BAN)) - return - - holder.stickyban_show() diff --git a/code/modules/admin/tickets/adminticketsverbs.dm b/code/modules/admin/tickets/adminticketsverbs.dm index 9ad1f722b08..406019745f8 100644 --- a/code/modules/admin/tickets/adminticketsverbs.dm +++ b/code/modules/admin/tickets/adminticketsverbs.dm @@ -12,12 +12,12 @@ /client/proc/resolveAllAdminTickets() set name = "Resolve All Open Admin Tickets" - set category = "Admin" + set category = null if(!holder || !check_rights(R_ADMIN)) return - if(alert("Are you sure you want to resolve ALL open tickets?","Resolve all open tickets?","Yes","No") != "Yes") + if(alert("Are you sure you want to resolve ALL open admin tickets?","Resolve all open admin tickets?","Yes","No") != "Yes") return SStickets.resolveAllOpenTickets() diff --git a/code/modules/admin/tickets/mentorticketsverbs.dm b/code/modules/admin/tickets/mentorticketsverbs.dm index 1122b770107..d65f4a30220 100644 --- a/code/modules/admin/tickets/mentorticketsverbs.dm +++ b/code/modules/admin/tickets/mentorticketsverbs.dm @@ -12,12 +12,12 @@ /client/proc/resolveAllMentorTickets() set name = "Resolve All Open Mentor Tickets" - set category = "Admin" + set category = null if(!holder || !check_rights(R_ADMIN)) return - if(alert("Are you sure you want to resolve ALL open tickets?","Resolve all open tickets?","Yes","No") != "Yes") + if(alert("Are you sure you want to resolve ALL open mentor tickets?","Resolve all open mentor tickets?","Yes","No") != "Yes") return SSmentor_tickets.resolveAllOpenTickets() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 21706aeabe3..3e4f5b374da 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -38,9 +38,6 @@ var/ticketID = text2num(href_list["openmentorticket"]) SSmentor_tickets.showDetailUI(usr, ticketID) - if(href_list["stickyban"]) - stickyban(href_list["stickyban"],href_list) - if(href_list["makeAntag"]) switch(href_list["makeAntag"]) if("1") diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index a8053e1faed..16a1c14694f 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -30,7 +30,7 @@ /client/proc/jumptoturf(var/turf/T in world) set name = "Jump to Turf" - set category = "Admin" + set category = null if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm index 209352993a0..bdef649468d 100644 --- a/code/modules/admin/verbs/freeze.dm +++ b/code/modules/admin/verbs/freeze.dm @@ -7,8 +7,8 @@ //////////////////////////////////////////////////////////////////////////////// var/global/list/frozen_mob_list = list() /client/proc/freeze(var/mob/living/M as mob in GLOB.mob_list) - set category = "Admin" set name = "Freeze" + set category = null if(!check_rights(R_ADMIN)) return @@ -87,8 +87,8 @@ var/global/list/frozen_mob_list = list() //////////////////////////Freeze Mech /client/proc/freezemecha(var/obj/mecha/O as obj in GLOB.mechas_list) - set category = "Admin" set name = "Freeze Mech" + set category = null if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 2c7c6181b1d..46dc9ec5b6a 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -776,8 +776,8 @@ Traitors and the like can also be revived with the previous role mostly intact. feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_check_contents(mob/living/M as mob in GLOB.mob_list) - set category = "Admin" set name = "Check Contents" + set category = null if(!check_rights(R_ADMIN)) return @@ -957,21 +957,24 @@ Traitors and the like can also be revived with the previous role mostly intact. message_admins("[key_name_admin(usr)] reset NTTC scripts.") feedback_add_details("admin_verb","RAT2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/list_ssds() +/client/proc/list_ssds_afks() set category = "Admin" - set name = "List SSDs" - set desc = "Lists SSD players" + set name = "List SSDs and AFKs" + set desc = "Lists SSD and AFK players" if(!check_rights(R_ADMIN)) return - var/msg = "SSD Report" + /* ======== SSD Section ========= */ + var/msg = "SSD & AFK Report" msg += "SSD Players:
" msg += "" var/mins_ssd var/job_string var/key_string var/role_string + var/obj_count = 0 + var/obj_string = "" for(var/mob/living/carbon/human/H in GLOB.living_mob_list) if(!isLivingSSD(H)) continue @@ -984,8 +987,6 @@ 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 = "-" - var/obj_count = 0 - var/obj_string = "" if(H.mind) if(H.mind.special_role) role_string = "[H.mind.special_role]" @@ -1003,24 +1004,12 @@ Traitors and the like can also be revived with the previous role mostly intact. else msg += "" msg += "" - msg += "
KeyReal NameJobMins SSDSpecial RoleAreaPPNCryo
Cryo
" - src << browse(msg, "window=Player_ssd_check") + msg += "
" -/client/proc/list_afks() - set category = "Admin" - set name = "List AFKs" - set desc = "Lists AFK players" - - if(!check_rights(R_ADMIN)) - return - - var/msg = "AFK Report" + /* ======== AFK Section ========= */ msg += "AFK Players:
" msg += "" var/mins_afk - var/job_string - var/key_string - var/role_string for(var/mob/living/carbon/human/H in GLOB.living_mob_list) if(H.client == null || H.stat == DEAD) // No clientless or dead continue @@ -1035,8 +1024,8 @@ 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 = "-" - var/obj_count = 0 - var/obj_string = "" + obj_count = 0 + obj_string = "" if(H.mind) if(H.mind.special_role) role_string = "[H.mind.special_role]" @@ -1055,7 +1044,7 @@ Traitors and the like can also be revived with the previous role mostly intact. msg += "" msg += "" msg += "
KeyReal NameJobMins AFKSpecial RoleAreaPPNCryo
Cryo
" - src << browse(msg, "window=Player_afk_check") + src << browse(msg, "window=Player_ssd_afk_check") /client/proc/toggle_ert_calling() set category = "Event" diff --git a/paradise.dme b/paradise.dme index cda0cebff3e..a5b66b166cd 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1175,7 +1175,6 @@ #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\secrets.dm" #include "code\modules\admin\sql_notes.dm" -#include "code\modules\admin\stickyban.dm" #include "code\modules\admin\topic.dm" #include "code\modules\admin\ToRban.dm" #include "code\modules\admin\watchlist.dm" From 5d50935f3100913a51caa695389f9f3efcd6a503 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Mon, 9 Sep 2019 01:34:02 -0400 Subject: [PATCH 02/41] Lavaland Update Part 3: Mob Spawning, Rivers, and Turfs --- code/__HELPERS/typelists.dm | 43 ++++ code/_globalvars/lists/misc.dm | 2 - code/controllers/subsystem/mapping.dm | 2 +- code/game/atoms_movable.dm | 8 +- code/game/machinery/computer/arcade.dm | 2 +- .../mecha/equipment/tools/mining_tools.dm | 2 +- code/game/turfs/simulated/floor/asteroid.dm | 145 +++++++------ .../turfs/simulated/floor/indestructible.dm | 2 +- code/game/turfs/simulated/minerals.dm | 194 ++++++++---------- code/game/turfs/simulated/river.dm | 2 +- .../guns/energy/kinetic_accelerator.dm | 13 +- paradise.dme | 1 + 12 files changed, 231 insertions(+), 185 deletions(-) create mode 100644 code/__HELPERS/typelists.dm diff --git a/code/__HELPERS/typelists.dm b/code/__HELPERS/typelists.dm new file mode 100644 index 00000000000..f271b9204de --- /dev/null +++ b/code/__HELPERS/typelists.dm @@ -0,0 +1,43 @@ +GLOBAL_LIST_EMPTY(typelists) + +#ifndef TESTING + +/datum/proc/typelist(key, list/values = list()) + var/list/mytypelist = GLOB.typelists[type] || (GLOB.typelists[type] = list()) + return mytypelist[key] || (mytypelist[key] = values.Copy()) + +#else +// mostly the same code as above, just more verbose, slower and has tallying for saved lists +/datum/proc/typelist(key, list/values) + if (!values) + values = list() + GLOB.typelistkeys |= key + if (GLOB.typelists[type]) + if (GLOB.typelists[type][key]) + GLOB.typelists[type]["[key]-saved"]++ + return GLOB.typelists[type][key] + else + GLOB.typelists[type][key] = values.Copy() + else + GLOB.typelists[type] = list() + GLOB.typelists[type][key] = values.Copy() + return GLOB.typelists[type][key] + +GLOBAL_LIST_EMPTY(typelistkeys) + +/proc/tallytypelistsavings() + var/savings = list() + var/saveditems = list() + for (var/key in GLOB.typelistkeys) + savings[key] = 0 + saveditems[key] = 0 + + for (var/type in GLOB.typelists) + for (var/saving in savings) + if (GLOB.typelists[type]["[saving]-saved"]) + savings[saving] += GLOB.typelists[type]["[saving]-saved"] + saveditems[saving] += (GLOB.typelists[type]["[saving]-saved"] * length(GLOB.typelists[type][saving])) + + for (var/saving in savings) + to_chat(world, "Savings for [saving]: [savings[saving]] lists, [saveditems[saving]] items") +#endif \ No newline at end of file diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm index e9c50b0f662..53040777467 100644 --- a/code/_globalvars/lists/misc.dm +++ b/code/_globalvars/lists/misc.dm @@ -34,8 +34,6 @@ GLOBAL_LIST_INIT(restricted_camera_networks, list( "Hotel" )) //Those networks can only be accessed by preexisting terminals. AIs and new terminals can't use them. -GLOBAL_LIST_INIT(mineral_turfs, list()) - GLOBAL_LIST_INIT(ruin_landmarks, list()) GLOBAL_LIST_INIT(round_end_sounds, list( diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index ec53c4b4d6b..bd885b90c8f 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -31,7 +31,7 @@ SUBSYSTEM_DEF(mapping) if (mining_type == "lavaland") // Spawn Lavaland ruins and rivers. seedRuins(list(level_name_to_num(MINING)), config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates) - spawn_rivers() + spawn_rivers(list(level_name_to_num(MINING))) else // Populate mining Z-level hidden rooms for(var/i = 0, i < max_secret_rooms, i++) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0a22c19770b..cb7bc3037b2 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -45,13 +45,7 @@ loc.handle_atom_del(src) for(var/atom/movable/AM in contents) qdel(AM) - var/turf/un_opaque - if(opacity && isturf(loc)) - un_opaque = loc - loc = null - if(un_opaque) - un_opaque.recalc_atom_opacity() if(pulledby) if(pulledby.pulling == src) pulledby.pulling = null @@ -120,7 +114,7 @@ return if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //separated from our puller and not in the middle of a diagonal move. pulledby.stop_pulling() - + /atom/movable/proc/can_be_pulled(user, grab_state, force) if(src == user || !isturf(loc)) return FALSE diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 741a4725c8d..c9d7f10302a 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -492,7 +492,7 @@ playsound(src.loc, 'sound/weapons/genhit.ogg', 100, 1) var/turf/space/T for(T in orange(1, src)) - T.ChangeTurf(/turf/simulated/floor/plating/) + T.ChangeTurf(/turf/simulated/floor/plating) else atom_say("Something slams into the floor around [src] - luckily, it didn't get through!") playsound(src.loc, 'sound/effects/bang.ogg', 20, 1) diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 445d881ee50..a0f6e4408d7 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -77,7 +77,7 @@ /turf/simulated/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) for(var/turf/simulated/floor/plating/asteroid/M in range(1, drill.chassis)) if((get_dir(drill.chassis, M) & drill.chassis.dir) && !M.dug) - M.gets_dug() + M.getDug() drill.log_message("Drilled through [src]") drill.move_ores() diff --git a/code/game/turfs/simulated/floor/asteroid.dm b/code/game/turfs/simulated/floor/asteroid.dm index e3e6c01c2bd..74bab572b30 100644 --- a/code/game/turfs/simulated/floor/asteroid.dm +++ b/code/game/turfs/simulated/floor/asteroid.dm @@ -1,6 +1,8 @@ + /**********************Asteroid**************************/ /turf/simulated/floor/plating/asteroid + gender = PLURAL name = "asteroid sand" baseturf = /turf/simulated/floor/plating/asteroid icon_state = "asteroid" @@ -8,17 +10,32 @@ footstep_sounds = list() var/environment_type = "asteroid" var/turf_type = /turf/simulated/floor/plating/asteroid //Because caves do whacky shit to revert to normal - var/dug = 0 //0 = has not yet been dug, 1 = has already been dug - var/sand_type = /obj/item/stack/ore/glass var/floor_variance = 20 //probability floor has a different icon state + var/obj/item/stack/digResult = /obj/item/stack/ore/glass/basalt + var/dug -/turf/simulated/floor/plating/asteroid/New() +/turf/simulated/floor/plating/asteroid/Initialize(mapload) var/proper_name = name - ..() + . = ..() name = proper_name if(prob(floor_variance)) icon_state = "[environment_type][rand(0,12)]" +/turf/simulated/floor/plating/asteroid/proc/getDug() + new digResult(src, 5) + icon_plating = "[environment_type]_dug" + icon_state = "[environment_type]_dug" + dug = TRUE + +/turf/simulated/floor/plating/asteroid/proc/can_dig(mob/user) + if(!dug) + return TRUE + if(user) + to_chat(user, "Looks like someone has dug here already.") + +/turf/simulated/floor/plating/asteroid/try_replace_tile(obj/item/stack/tile/T, mob/user, params) + return + /turf/simulated/floor/plating/asteroid/burn_tile() return @@ -31,46 +48,50 @@ /turf/simulated/floor/plating/asteroid/remove_plating() return -/turf/simulated/floor/plating/asteroid/ex_act(severity, target) +/turf/simulated/floor/plating/asteroid/ex_act(severity) + if(!can_dig()) + return switch(severity) if(3) return if(2) if(prob(20)) - gets_dug() + getDug() if(1) - gets_dug() + getDug() -/turf/simulated/floor/plating/asteroid/attackby(obj/item/W, mob/user, params) +/turf/simulated/floor/plating/asteroid/attackby(obj/item/I, mob/user, params) //note that this proc does not call ..() - if(!W || !user) - return 0 + if(!I|| !user) + return FALSE + + if((istype(I, /obj/item/shovel) || istype(I, /obj/item/pickaxe))) + if(!can_dig(user)) + return TRUE - if((istype(W, /obj/item/shovel) || istype(W, /obj/item/pickaxe))) var/turf/T = get_turf(user) if(!istype(T)) return - if(dug) - to_chat(user, "This area has already been dug!") - return - to_chat(user, "You start digging...") - playsound(src, W.usesound, 50, 1) - if(do_after(user, 20 * W.toolspeed, target = src)) - to_chat(user, "You dig a hole.") - gets_dug() - return - else if(istype(W,/obj/item/storage/bag/ore)) - var/obj/item/storage/bag/ore/S = W + playsound(src, I.usesound, 50, TRUE) + if(do_after(user, 40 * I.toolspeed, target = src)) + if(!can_dig(user)) + return TRUE + to_chat(user, "You dig a hole.") + getDug() + return TRUE + + else if(istype(I, /obj/item/storage/bag/ore)) + var/obj/item/storage/bag/ore/S = I if(S.collection_mode == 1) - for(var/obj/item/stack/ore/O in src.contents) - O.attackby(W,user) + for(var/obj/item/stack/ore/O in contents) + O.attackby(I, user) return - else if(istype(W, /obj/item/stack/tile)) - var/obj/item/stack/tile/Z = W + else if(istype(I, /obj/item/stack/tile)) + var/obj/item/stack/tile/Z = I if(!Z.use(1)) return if(istype(Z, /obj/item/stack/tile/plasteel)) // Turn asteroid floors into plating by default @@ -79,25 +100,14 @@ ChangeTurf(Z.turf_type, keep_icon = FALSE) playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) -/turf/simulated/floor/plating/asteroid/proc/gets_dug() - if(dug) - return - for(var/i in 1 to 5) - new sand_type(src) - dug = 1 - icon_plating = "[environment_type]_dug" - icon_state = "[environment_type]_dug" - slowdown = 0 - return - /turf/simulated/floor/plating/asteroid/basalt name = "volcanic floor" baseturf = /turf/simulated/floor/plating/asteroid/basalt icon_state = "basalt" icon_plating = "basalt" environment_type = "basalt" - sand_type = /obj/item/stack/ore/glass/basalt floor_variance = 15 + digResult = /obj/item/stack/ore/glass/basalt /turf/simulated/floor/plating/asteroid/basalt/lava //lava underneath baseturf = /turf/simulated/floor/plating/lava/smooth @@ -107,10 +117,14 @@ oxygen = 0 nitrogen = 0 -/turf/simulated/floor/plating/asteroid/basalt/Initialize() +/turf/simulated/floor/plating/asteroid/basalt/Initialize(mapload) . = ..() set_basalt_light(src) +/turf/simulated/floor/plating/asteroid/basalt/getDug() + set_light(0) + return ..() + /proc/set_basalt_light(turf/simulated/floor/B) switch(B.icon_state) if("basalt1", "basalt2", "basalt3") @@ -118,11 +132,6 @@ if("basalt5", "basalt9") B.set_light(1.4, 0.6, LIGHT_COLOR_LAVA) //barely anything! -/turf/simulated/floor/plating/asteroid/basalt/gets_dug() - if(!dug) - set_light(0) - ..() - ///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground. /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface @@ -138,9 +147,10 @@ nitrogen = 0 turf_type = /turf/simulated/floor/plating/asteroid/airless -#define SPAWN_MEGAFAUNA "MEGAFAUNA" +#define SPAWN_MEGAFAUNA "bluh bluh huge boss" +#define SPAWN_BUBBLEGUM 6 -GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/megafauna/dragon = 4, /mob/living/simple_animal/hostile/megafauna/colossus = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = 6)) +GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/megafauna/dragon = 4, /mob/living/simple_animal/hostile/megafauna/colossus = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = SPAWN_BUBBLEGUM)) /turf/simulated/floor/plating/asteroid/airless/cave var/length = 100 @@ -169,22 +179,20 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE /turf/simulated/floor/plating/asteroid/airless/cave/volcanic/has_data //subtype for producing a tunnel with given data has_data = TRUE -/turf/simulated/floor/plating/asteroid/airless/cave/New() +/turf/simulated/floor/plating/asteroid/airless/cave/Initialize(mapload) if (!mob_spawn_list) mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3) if (!megafauna_spawn_list) megafauna_spawn_list = GLOB.megafauna_spawn_list if (!flora_spawn_list) flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2) - + . = ..() if(!has_data) produce_tunnel_from_data() - ..() /turf/simulated/floor/plating/asteroid/airless/cave/proc/get_cave_data(set_length, exclude_dir = -1) // If set_length (arg1) isn't defined, get a random length; otherwise assign our length to the length arg. @@ -234,7 +242,7 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me if(istype(tunnel)) // Small chance to have forks in our tunnel; otherwise dig our tunnel. if(i > 3 && prob(20)) - var/turf/simulated/floor/plating/asteroid/airless/cave/C = tunnel.ChangeTurf(data_having_type,FALSE,TRUE) + var/turf/simulated/floor/plating/asteroid/airless/cave/C = tunnel.ChangeTurf(data_having_type, FALSE, TRUE) C.going_backwards = FALSE C.produce_tunnel_from_data(rand(10, 15), dir) else @@ -260,19 +268,22 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me SpawnFlora(T) SpawnMonster(T) - T.ChangeTurf(turf_type,FALSE,FALSE,TRUE) + T.ChangeTurf(turf_type, FALSE, FALSE, TRUE) /turf/simulated/floor/plating/asteroid/airless/cave/proc/SpawnMonster(turf/T) if(prob(30)) - if(istype(loc, /area/mine/explored) || istype(loc, /area/lavaland/surface/outdoors/explored)) + if(istype(loc, /area/mine/explored) || !istype(loc, /area/lavaland/surface/outdoors/unexplored)) return var/randumb = pickweight(mob_spawn_list) while(randumb == SPAWN_MEGAFAUNA) - var/maybe_boss = pickweight(megafauna_spawn_list) - if(megafauna_spawn_list[maybe_boss]) - randumb = maybe_boss - if(ispath(maybe_boss, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it - megafauna_spawn_list.Remove(maybe_boss) + if(istype(loc, /area/lavaland/surface/outdoors/unexplored/danger)) //this is danger. it's boss time. + var/maybe_boss = pickweight(megafauna_spawn_list) + if(megafauna_spawn_list[maybe_boss]) + randumb = maybe_boss + if(ispath(maybe_boss, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it + megafauna_spawn_list.Remove(maybe_boss) + 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) @@ -286,6 +297,7 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me return #undef SPAWN_MEGAFAUNA +#undef SPAWN_BUBBLEGUM /turf/simulated/floor/plating/asteroid/airless/cave/proc/SpawnFlora(turf/T) if(prob(12)) @@ -300,6 +312,7 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me /turf/simulated/floor/plating/asteroid/snow + gender = PLURAL name = "snow" desc = "Looks cold." icon = 'icons/turf/snow.dmi' @@ -309,7 +322,18 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me temperature = 180 slowdown = 2 environment_type = "snow" - sand_type = /obj/item/stack/sheet/mineral/snow + planetary_atmos = TRUE + burnt_states = list("snow_dug") + digResult = /obj/item/stack/sheet/mineral/snow + +/turf/simulated/floor/plating/asteroid/snow/burn_tile() + if(!burnt) + visible_message("[src] melts away!.") + slowdown = 0 + burnt = TRUE + icon_state = "snow_dug" + return TRUE + return FALSE /turf/simulated/floor/plating/asteroid/snow/airless temperature = TCMB @@ -322,4 +346,5 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/me /turf/simulated/floor/plating/asteroid/snow/atmosphere oxygen = 22 nitrogen = 82 - temperature = 180 \ No newline at end of file + temperature = 180 + planetary_atmos = FALSE \ No newline at end of file diff --git a/code/game/turfs/simulated/floor/indestructible.dm b/code/game/turfs/simulated/floor/indestructible.dm index 159f78ddd80..3217a4c7996 100644 --- a/code/game/turfs/simulated/floor/indestructible.dm +++ b/code/game/turfs/simulated/floor/indestructible.dm @@ -48,7 +48,7 @@ temperature = 300 planetary_atmos = TRUE -/turf/simulated/floor/indestructible/necropolis/Initialize() +/turf/simulated/floor/indestructible/necropolis/Initialize(mapload) . = ..() if(prob(12)) icon_state = "necro[rand(2,3)]" diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index 2109c8c62e5..964a0c3dcc5 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -6,12 +6,12 @@ icon_state = "rock" var/smooth_icon = 'icons/turf/smoothrocks.dmi' smooth = SMOOTH_MORE | SMOOTH_BORDER - canSmoothWith + canSmoothWith = null baseturf = /turf/simulated/floor/plating/asteroid/airless temperature = 2.7 opacity = 1 - density = 1 - blocks_air = 1 + density = TRUE + blocks_air = TRUE layer = EDGED_TURF_LAYER temperature = TCMB var/environment_type = "asteroid" @@ -21,21 +21,18 @@ var/spread = 0 //will the seam spread? var/spreadChance = 0 //the percentual chance of an ore spreading to the neighbouring tiles var/last_act = 0 - var/scan_state = null //Holder for the image we display when we're pinged by a mining scanner - var/defer_change = FALSE + var/scan_state = "" //Holder for the image we display when we're pinged by a mining scanner + var/defer_change = 0 -/turf/simulated/mineral/New() - if (!canSmoothWith) +/turf/simulated/mineral/Initialize(mapload) + if(!canSmoothWith) canSmoothWith = list(/turf/simulated/mineral) var/matrix/M = new M.Translate(-4, -4) transform = M icon = smooth_icon - - ..() - GLOB.mineral_turfs += src - - if (mineralType && mineralAmt && spread && spreadChance) + . = ..() + if(mineralType && mineralAmt && spread && spreadChance) for(var/dir in cardinal) if(prob(spreadChance)) var/turf/T = get_step(src, dir) @@ -56,37 +53,34 @@ return TRUE return ..() -/turf/simulated/mineral/attackby(var/obj/item/pickaxe/P as obj, mob/user as mob, params) +/turf/simulated/mineral/attackby(obj/item/I, mob/user, params) if(!user.IsAdvancedToolUser()) to_chat(usr, "You don't have the dexterity to do this!") return - if(istype(P, /obj/item/pickaxe)) + if(istype(I, /obj/item/pickaxe)) + var/obj/item/pickaxe/P = I var/turf/T = user.loc if(!isturf(T)) return if(last_act + (40 * P.toolspeed) > world.time) // Prevents message spam return - last_act = world.time to_chat(user, "You start picking...") P.playDigSound() if(do_after(user, 40 * P.toolspeed, target = src)) - if(istype(src, /turf/simulated/mineral)) //sanity check against turf being deleted during digspeed delay + if(ismineralturf(src)) //sanity check against turf being deleted during digspeed delay to_chat(user, "You finish cutting into the rock.") - P.update_icon() gets_drilled(user) feedback_add_details("pick_used_mining","[P.name]") else return attack_hand(user) /turf/simulated/mineral/proc/gets_drilled() - if(mineralType && (mineralAmt > 0) && (mineralAmt < 11)) - var/i - for(i=0; i < mineralAmt; i++) - new mineralType(src) + if(mineralType && (mineralAmt > 0)) + new mineralType(src, mineralAmt) feedback_add_details("ore_mined","[mineralType]|[mineralAmt]") for(var/obj/effect/temp_visual/mining_overlay/M in src) qdel(M) @@ -94,26 +88,20 @@ addtimer(CALLBACK(src, .proc/AfterChange), 1, TIMER_UNIQUE) playsound(src, 'sound/effects/break_stone.ogg', 50, 1) //beautiful destruction - if(rand(1, 750) == 1) - visible_message("An old dusty crate was buried within!") - new /obj/structure/closet/crate/secure/loot(src) - - return - /turf/simulated/mineral/attack_animal(mob/living/simple_animal/user as mob) if((user.environment_smash & ENVIRONMENT_SMASH_WALLS) || (user.environment_smash & ENVIRONMENT_SMASH_RWALLS)) gets_drilled() ..() -/turf/simulated/mineral/attack_alien(var/mob/living/carbon/alien/M) +/turf/simulated/mineral/attack_alien(mob/living/carbon/alien/M) to_chat(M, "You start digging into the rock...") - playsound(src, 'sound/effects/break_stone.ogg', 50, 1) + playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) if(do_after(M, 40, target = src)) to_chat(M, "You tunnel into the rock.") - gets_drilled() + gets_drilled(M) -/turf/simulated/mineral/Bumped(AM as mob|obj) - . = ..() +/turf/simulated/mineral/Bumped(atom/movable/AM) + ..() if(ishuman(AM)) var/mob/living/carbon/human/H = AM if((istype(H.l_hand,/obj/item/pickaxe)) && (!H.hand)) @@ -124,15 +112,15 @@ else if(isrobot(AM)) var/mob/living/silicon/robot/R = AM - if(istype(R.module_active,/obj/item/pickaxe)) - attackby(R.module_active,R) + if(istype(R.module_active, /obj/item/pickaxe)) + attackby(R.module_active, R) else if(ismecha(AM)) var/obj/mecha/M = AM - if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/drill)) + if(istype(M.selected, /obj/item/mecha_parts/mecha_equipment/drill)) M.selected.action(src) -/turf/simulated/mineral/ex_act(severity, target) +/turf/simulated/mineral/ex_act(severity) ..() switch(severity) if(3) @@ -145,22 +133,23 @@ gets_drilled(null, 1) /turf/simulated/mineral/random - var/mineralSpawnChanceList + var/mineralSpawnChanceList = list(/turf/simulated/mineral/uranium = 5, /turf/simulated/mineral/diamond = 1, /turf/simulated/mineral/gold = 10, + /turf/simulated/mineral/silver = 12, /turf/simulated/mineral/plasma = 20, /turf/simulated/mineral/iron = 40, /turf/simulated/mineral/titanium = 11, + /turf/simulated/mineral/gibtonite = 4, /turf/simulated/floor/plating/asteroid/airless/cave = 2, /turf/simulated/mineral/bscrystal = 1) + //Currently, Adamantine won't spawn as it has no uses. -Durandan var/mineralChance = 13 var/display_icon_state = "rock" -/turf/simulated/mineral/random/New() - if (!mineralSpawnChanceList) - mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium = 5, /turf/simulated/mineral/diamond = 1, /turf/simulated/mineral/gold = 10, - /turf/simulated/mineral/silver = 12, /turf/simulated/mineral/plasma = 20, /turf/simulated/mineral/iron = 40, /turf/simulated/mineral/titanium = 11, - /turf/simulated/mineral/gibtonite = 4, /turf/simulated/floor/plating/asteroid/airless/cave = 2, /turf/simulated/mineral/bscrystal = 1) - if (display_icon_state) +/turf/simulated/mineral/random/Initialize(mapload) + + mineralSpawnChanceList = typelist("mineralSpawnChanceList", mineralSpawnChanceList) + + if(display_icon_state) icon_state = display_icon_state - ..() + . = ..() if (prob(mineralChance)) var/path = pickweight(mineralSpawnChanceList) - var/turf/T = ChangeTurf(path,FALSE,TRUE) + var/turf/T = ChangeTurf(path, FALSE, TRUE) if(T && ismineralturf(T)) var/turf/simulated/mineral/M = T @@ -191,7 +180,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 mineralSpawnChanceList = list( /turf/simulated/mineral/uranium/volcanic = 35, /turf/simulated/mineral/diamond/volcanic = 30, /turf/simulated/mineral/gold/volcanic = 45, /turf/simulated/mineral/titanium/volcanic = 45, @@ -212,7 +200,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 mineralChance = 10 @@ -223,9 +210,9 @@ /turf/simulated/mineral/random/labormineral mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium = 2, /turf/simulated/mineral/diamond = 1, /turf/simulated/mineral/gold = 3, /turf/simulated/mineral/titanium = 4, - /turf/simulated/mineral/silver = 6, /turf/simulated/mineral/plasma = 15, /turf/simulated/mineral/iron = 80, - /turf/simulated/mineral/gibtonite = 3) + /turf/simulated/mineral/uranium = 3, /turf/simulated/mineral/diamond = 1, /turf/simulated/mineral/gold = 8, /turf/simulated/mineral/titanium = 8, + /turf/simulated/mineral/silver = 20, /turf/simulated/mineral/plasma = 30, /turf/simulated/mineral/iron = 95, + /turf/simulated/mineral/gibtonite = 2) icon_state = "rock_labor" /turf/simulated/mineral/random/labormineral/volcanic @@ -235,12 +222,11 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium/volcanic = 2, /turf/simulated/mineral/diamond/volcanic = 1, /turf/simulated/mineral/gold/volcanic = 3, /turf/simulated/mineral/titanium/volcanic = 4, - /turf/simulated/mineral/silver/volcanic = 6, /turf/simulated/mineral/plasma/volcanic = 15, /turf/simulated/mineral/iron/volcanic = 80, - /turf/simulated/mineral/gibtonite/volcanic = 3) + /turf/simulated/mineral/uranium/volcanic = 3, /turf/simulated/mineral/diamond/volcanic = 1, /turf/simulated/mineral/gold/volcanic = 8, /turf/simulated/mineral/titanium/volcanic = 8, + /turf/simulated/mineral/silver/volcanic = 20, /turf/simulated/mineral/plasma/volcanic = 30, /turf/simulated/mineral/bscrystal/volcanic = 1, /turf/simulated/mineral/gibtonite/volcanic = 2, + /turf/simulated/mineral/iron/volcanic = 95) // Actual minerals /turf/simulated/mineral/iron @@ -256,7 +242,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/uranium @@ -272,7 +257,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/diamond @@ -288,7 +272,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/gold @@ -304,7 +287,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/silver @@ -320,7 +302,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/titanium @@ -336,7 +317,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/plasma @@ -352,7 +332,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/clown @@ -369,7 +348,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/mime @@ -385,7 +363,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/bscrystal @@ -402,7 +379,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE defer_change = 1 /turf/simulated/mineral/volcanic @@ -412,7 +388,6 @@ oxygen = 14 nitrogen = 23 temperature = 300 - planetary_atmos = TRUE /turf/simulated/mineral/volcanic/lava_land_surface environment_type = "basalt" @@ -420,6 +395,12 @@ baseturf = /turf/simulated/floor/plating/lava/smooth/lava_land_surface defer_change = 1 +//gibtonite state defines +#define GIBTONITE_UNSTRUCK 0 +#define GIBTONITE_ACTIVE 1 +#define GIBTONITE_STABLE 2 +#define GIBTONITE_DETONATE 3 + // Gibtonite /turf/simulated/mineral/gibtonite mineralAmt = 1 @@ -427,39 +408,29 @@ spread = 0 scan_state = "rock_Gibtonite" var/det_time = 8 //Countdown till explosion, but also rewards the player for how close you were to detonation when you defuse it - var/stage = 0 //How far into the lifecycle of gibtonite we are, 0 is untouched, 1 is active and attempting to detonate, 2 is benign and ready for extraction + var/stage = GIBTONITE_UNSTRUCK //How far into the lifecycle of gibtonite we are var/activated_ckey = null //These are to track who triggered the gibtonite deposit for logging purposes var/activated_name = null - var/activated_image = null + var/mutable_appearance/activated_overlay -/turf/simulated/mineral/gibtonite/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = 14 - nitrogen = 23 - temperature = 300 - planetary_atmos = TRUE - defer_change = 1 - -/turf/simulated/mineral/gibtonite/New() +/turf/simulated/mineral/gibtonite/Initialize(mapload) det_time = rand(8,10) //So you don't know exactly when the hot potato will explode - ..() + . = ..() /turf/simulated/mineral/gibtonite/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/mining_scanner) || istype(I, /obj/item/t_scanner/adv_mining_scanner) && stage == 1) - user.visible_message("You use [I] to locate where to cut off the chain reaction and attempt to stop it...") + user.visible_message("[user] holds [I] to [src]...", "You use [I] to locate where to cut off the chain reaction and attempt to stop it...") defuse() - ..() + else + return ..() -/turf/simulated/mineral/gibtonite/proc/explosive_reaction(var/mob/user = null, triggered_by_explosion = 0) - if(stage == 0) - var/image/I = image('icons/turf/smoothrocks.dmi', loc = src, icon_state = "rock_Gibtonite_active", layer = ON_EDGED_TURF_LAYER) - add_overlay(I) - activated_image = I +/turf/simulated/mineral/gibtonite/proc/explosive_reaction(mob/user = null, triggered_by_explosion = 0) + if(stage == GIBTONITE_UNSTRUCK) + activated_overlay = mutable_appearance('icons/turf/smoothrocks.dmi', "rock_Gibtonite_active", ON_EDGED_TURF_LAYER) + add_overlay(activated_overlay) name = "gibtonite deposit" desc = "An active gibtonite reserve. Run!" - stage = 1 + stage = GIBTONITE_ACTIVE visible_message("There was gibtonite inside! It's going to explode!") var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) @@ -481,39 +452,39 @@ /turf/simulated/mineral/gibtonite/proc/countdown(notify_admins = 0) set waitfor = 0 - while(istype(src, /turf/simulated/mineral/gibtonite) && stage == 1 && det_time > 0 && mineralAmt >= 1) + while(istype(src, /turf/simulated/mineral/gibtonite) && stage == GIBTONITE_ACTIVE && det_time > 0 && mineralAmt >= 1) det_time-- sleep(5) if(istype(src, /turf/simulated/mineral/gibtonite)) - if(stage == 1 && det_time <= 0 && mineralAmt >= 1) + if(stage == GIBTONITE_ACTIVE && det_time <= 0 && mineralAmt >= 1) var/turf/bombturf = get_turf(src) mineralAmt = 0 - stage = 3 + stage = GIBTONITE_DETONATE explosion(bombturf,1,3,5, adminlog = notify_admins) /turf/simulated/mineral/gibtonite/proc/defuse() - if(stage == 1) - overlays -= activated_image - var/image/I = image('icons/turf/smoothrocks.dmi', loc = src, icon_state = "rock_Gibtonite_inactive", layer = ON_EDGED_TURF_LAYER) - add_overlay(I) + if(stage == GIBTONITE_ACTIVE) + cut_overlay(activated_overlay) + activated_overlay.icon_state = "rock_Gibtonite_inactive" + add_overlay(activated_overlay) desc = "An inactive gibtonite reserve. The ore can be extracted." - stage = 2 + stage = GIBTONITE_STABLE if(det_time < 0) det_time = 0 - visible_message("The chain reaction was stopped! The gibtonite had [src.det_time] reactions left till the explosion!") + visible_message("The chain reaction was stopped! The gibtonite had [det_time] reactions left till the explosion!") /turf/simulated/mineral/gibtonite/gets_drilled(var/mob/user, triggered_by_explosion = 0) - if(stage == 0 && mineralAmt >= 1) //Gibtonite deposit is activated - playsound(src, 'sound/effects/hit_on_shattered_glass.ogg',50,1) + if(stage == GIBTONITE_UNSTRUCK && mineralAmt >= 1) //Gibtonite deposit is activated + playsound(src,'sound/effects/hit_on_shattered_glass.ogg', 50, TRUE) explosive_reaction(user, triggered_by_explosion) return - if(stage == 1 && mineralAmt >= 1) //Gibtonite deposit goes kaboom + if(stage == GIBTONITE_ACTIVE && mineralAmt >= 1) //Gibtonite deposit goes kaboom var/turf/bombturf = get_turf(src) mineralAmt = 0 - stage = 3 - explosion(bombturf, 1, 2, 5, adminlog = 0) - if(stage == 2) //Gibtonite deposit is now benign and extractable. Depending on how close you were to it blowing up before defusing, you get better quality ore. - var/obj/item/twohanded/required/gibtonite/G = new /obj/item/twohanded/required/gibtonite/(src) + stage = GIBTONITE_DETONATE + explosion(bombturf,1,2,5, adminlog = 0) + if(stage == GIBTONITE_STABLE) //Gibtonite deposit is now benign and extractable. Depending on how close you were to it blowing up before defusing, you get better quality ore. + var/obj/item/twohanded/required/gibtonite/G = new(src) if(det_time <= 0) G.quality = 3 G.icon_state = "Gibtonite ore 3" @@ -523,3 +494,18 @@ ChangeTurf(turf_type, defer_change) addtimer(CALLBACK(src, .proc/AfterChange), 1, TIMER_UNIQUE) + + +/turf/simulated/mineral/gibtonite/volcanic + environment_type = "basalt" + turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface + baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface + oxygen = 14 + nitrogen = 23 + temperature = 300 + defer_change = 1 + +#undef GIBTONITE_UNSTRUCK +#undef GIBTONITE_ACTIVE +#undef GIBTONITE_STABLE +#undef GIBTONITE_DETONATE \ No newline at end of file diff --git a/code/game/turfs/simulated/river.dm b/code/game/turfs/simulated/river.dm index ed13f127019..c7a3e742b6c 100644 --- a/code/game/turfs/simulated/river.dm +++ b/code/game/turfs/simulated/river.dm @@ -4,7 +4,7 @@ #define RANDOM_LOWER_X 50 #define RANDOM_LOWER_Y 50 -/proc/spawn_rivers(target_z, nodes = 4, turf_type = /turf/simulated/floor/plating/lava/smooth/lava_land_surface, whitelist_area = /area/lavaland/surface/outdoors/unexplored, min_x = RANDOM_LOWER_X, min_y = RANDOM_LOWER_Y, max_x = RANDOM_UPPER_X, max_y = RANDOM_UPPER_Y) +/proc/spawn_rivers(target_z, nodes = 4, turf_type = /turf/simulated/floor/plating/lava/smooth/lava_land_surface, whitelist_area = /area/lavaland/surface/outdoors, min_x = RANDOM_LOWER_X, min_y = RANDOM_LOWER_Y, max_x = RANDOM_UPPER_X, max_y = RANDOM_UPPER_Y) var/list/river_nodes = list() var/num_spawned = 0 var/list/possible_locs = block(locate(min_x, min_y, target_z), locate(max_x, max_y, target_z)) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index b93ddefd0d5..9c1ea1a7a9f 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -79,7 +79,7 @@ holds_charge = TRUE unique_frequency = TRUE -/obj/item/gun/energy/kinetic_accelerator/New() +/obj/item/gun/energy/kinetic_accelerator/Initialize(mapload) . = ..() if(!holds_charge) empty() @@ -98,8 +98,7 @@ if(!QDELING(src) && !holds_charge) // Put it on a delay because moving item from slot to hand // calls dropped(). - spawn(2) - empty_if_not_held() + addtimer(CALLBACK(src, .proc/empty_if_not_held), 2) /obj/item/gun/energy/kinetic_accelerator/proc/empty_if_not_held() if(!ismob(loc)) @@ -143,17 +142,17 @@ overheat = FALSE /obj/item/gun/energy/kinetic_accelerator/update_icon() - overlays.Cut() + cut_overlays() if(empty_state && !can_shoot()) - overlays += empty_state + add_overlay(empty_state) if(gun_light && can_flashlight) var/iconF = "flight" if(gun_light.on) iconF = "flight_on" - overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) + add_overlay(image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset)) if(bayonet && can_bayonet) - overlays += knife_overlay + add_overlay(knife_overlay) /obj/item/gun/energy/kinetic_accelerator/experimental diff --git a/paradise.dme b/paradise.dme index cda0cebff3e..f7112848772 100644 --- a/paradise.dme +++ b/paradise.dme @@ -89,6 +89,7 @@ #include "code\__HELPERS\text.dm" #include "code\__HELPERS\time.dm" #include "code\__HELPERS\type2type.dm" +#include "code\__HELPERS\typelists.dm" #include "code\__HELPERS\unique_ids.dm" #include "code\__HELPERS\unsorted.dm" #include "code\__HELPERS\sorts\__main.dm" From 8fc8063c7432df6468808b8529224cec34355894 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 9 Sep 2019 02:00:31 -0400 Subject: [PATCH 03/41] taking player_panel out to the woodshed --- code/modules/admin/admin_verbs.dm | 12 ------ code/modules/admin/player_panel.dm | 59 ------------------------------ 2 files changed, 71 deletions(-) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 1c4d569507e..82c5d937cda 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -10,7 +10,6 @@ var/list/admin_verbs_default = list( var/list/admin_verbs_admin = list( /client/proc/check_antagonists, /*shows all antags*/ /datum/admins/proc/show_player_panel, - /client/proc/player_panel, /*shows an interface for all players, with links to various panels (old style)*/ /client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/ /client/proc/invisimin, /*allows our mob to go invisible/visible*/ /datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/ @@ -361,17 +360,6 @@ var/list/admin_verbs_ticket = list( to_chat(mob, "Invisimin on. You are now as invisible as a ghost.") mob.remove_from_all_data_huds() -/client/proc/player_panel() - set name = "Player Panel" - set category = null - - if(!check_rights(R_ADMIN)) - return - - holder.player_panel_old() - feedback_add_details("admin_verb","PP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - /client/proc/player_panel_new() set name = "Player Panel New" set category = "Admin" diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 9203477c7f9..51a7f442fbc 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -328,65 +328,6 @@ usr << browse(dat, "window=players;size=600x480") -//The old one -/datum/admins/proc/player_panel_old() - if(!usr.client.holder) - return - var/dat = "Player Menu" - dat += "" - //add to this if wanting to add back in IP checking - //add if you want to know their ip to the lists below - var/list/mobs = sortmobs() - - for(var/mob/M in mobs) - if(!M.ckey) continue - - dat += "" - if(isAI(M)) - dat += "" - else if(isrobot(M)) - dat += "" - else if(issmall(M)) - dat += "" - else if(ishuman(M)) - dat += "" - else if(istype(M, /mob/living/silicon/pai)) - dat += "" - else if(istype(M, /mob/new_player)) - dat += "" - else if(isobserver(M)) - dat += "" - else if(isalien(M)) - dat += "" - else - dat += "" - - - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(H.mind && H.mind.assigned_role) - dat += "" - else - dat += "" - - - dat += {" - - - "} - switch(is_special_character(M)) - if(0) - dat += {""} - if(1) - dat += {""} - if(2) - dat += {""} - - dat += "
NameReal NameAssigned JobKeyOptionsPMTraitor?
IP:(IP: [M.lastKnownIP])
[M.name]AICyborgMonkey[M.real_name]pAINew PlayerGhostAlienUnknown[H.mind.assigned_role]NA[(M.client ? "[M.client]" : "No client")]XPMTraitor?Traitor?Traitor?
" - - usr << browse(dat, "window=players;size=640x480") - - /datum/admins/proc/check_antagonists_line(mob/M, caption = "", close = 1) var/logout_status From 43ae1c832a30d0cc5f4389223fa639c8b5aafc74 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Mon, 9 Sep 2019 02:45:09 -0400 Subject: [PATCH 04/41] Ports Frozen Status Effect --- code/datums/status_effects/gas.dm | 46 ++++++++++++++++++ code/modules/mob/living/living.dm | 2 + .../simple_animal/hostile/mining/basilisk.dm | 9 +++- code/modules/mob/living/status_procs.dm | 5 ++ code/modules/mob/living/update_status.dm | 2 +- icons/effects/freeze.dmi | Bin 0 -> 2774 bytes icons/mob/screen_alert.dmi | Bin 47636 -> 49402 bytes paradise.dme | 1 + 8 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 code/datums/status_effects/gas.dm create mode 100644 icons/effects/freeze.dmi diff --git a/code/datums/status_effects/gas.dm b/code/datums/status_effects/gas.dm new file mode 100644 index 00000000000..bdd80e7fc32 --- /dev/null +++ b/code/datums/status_effects/gas.dm @@ -0,0 +1,46 @@ +/datum/status_effect/freon + id = "frozen" + duration = 100 + status_type = STATUS_EFFECT_UNIQUE + alert_type = /obj/screen/alert/status_effect/freon + var/icon/cube + var/can_melt = TRUE + +/obj/screen/alert/status_effect/freon + name = "Frozen Solid" + desc = "You're frozen inside an ice cube, and cannot move! You can still do stuff, like shooting. Resist out of the cube!" + icon_state = "frozen" + +/datum/status_effect/freon/on_apply() + RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/owner_resist) + if(!owner.stat) + to_chat(owner, "You become frozen in a cube!") + cube = icon('icons/effects/freeze.dmi', "ice_cube") + owner.add_overlay(cube) + owner.update_canmove() + return ..() + +/datum/status_effect/freon/tick() + owner.update_canmove() + if(can_melt && owner.bodytemperature >= BODYTEMP_NORMAL) + qdel(src) + +/datum/status_effect/freon/proc/owner_resist() + to_chat(owner, "You start breaking out of the ice cube!") + if(do_mob(owner, owner, 40)) + if(!QDELETED(src)) + to_chat(owner, "You break out of the ice cube!") + owner.remove_status_effect(/datum/status_effect/freon) + owner.update_canmove() + +/datum/status_effect/freon/on_remove() + if(!owner.stat) + to_chat(owner, "The cube melts!") + owner.cut_overlay(cube) + owner.adjust_bodytemperature(100) + owner.update_canmove() + UnregisterSignal(owner, COMSIG_LIVING_RESIST) + +/datum/status_effect/freon/watcher + duration = 8 + can_melt = FALSE \ No newline at end of file diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index cd20656254f..882f0b6b047 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -617,6 +617,8 @@ return changeNext_move(CLICK_CD_RESIST) + SEND_SIGNAL(src, COMSIG_LIVING_RESIST, src) + if(!restrained()) if(resist_grab()) return diff --git a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm index 4d5009109f3..4dbd306c9e0 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm @@ -132,7 +132,7 @@ . = ..() if(.) var/mob/living/L = target - if (istype(L)) + if(istype(L)) L.adjust_fire_stacks(0.1) L.IgniteMob() @@ -141,5 +141,12 @@ damage_type = BURN nodamage = FALSE +/obj/item/projectile/temp/basilisk/icewing/on_hit(atom/target, blocked = FALSE) + . = ..() + if(.) + var/mob/living/L = target + if(istype(L)) + L.apply_status_effect(/datum/status_effect/freon/watcher) + /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril fromtendril = TRUE \ No newline at end of file diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 0794b7d9c70..ad6d00d88aa 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -556,6 +556,11 @@ genemutcheck(src, block,null, MUTCHK_FORCED) dna.UpdateSE() +///////////////////////////////// FROZEN ///////////////////////////////////// + +/mob/living/proc/IsFrozen() + return has_status_effect(/datum/status_effect/freon) + ///////////////////////////////////// STUN ABSORPTION ///////////////////////////////////// /mob/living/proc/add_stun_absorption(key, duration, priority, message, self_message, examine_message) diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index 39357533abb..bdaa0972aef 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -89,7 +89,7 @@ else if((fall_over || resting) && !lying) fall(fall_over) - canmove = !(fall_over || resting || stunned || buckled) + canmove = !(fall_over || resting || stunned || IsFrozen() || buckled) density = !lying if(lying) if(layer == initial(layer)) diff --git a/icons/effects/freeze.dmi b/icons/effects/freeze.dmi new file mode 100644 index 0000000000000000000000000000000000000000..0461619064548d99017daacafbeda541a56e0f40 GIT binary patch literal 2774 zcmV;{3Muu8P)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex7wuvIWN;^NFm z%}mcIfpCgT5=&AQY!#F;lT+i9OOsNSxHwZXi;5L&6%4sJ(~1&vQz2{=g^87wxYQ{t zxca#$xcGW<0RZ%iCc8iLEPDU|3KvO4K~!jgy_rpH8^;yL|Ds4P%{6x!lQJoVlx#U7 zX~}jCLue2Lfl(*uhwIjeM4gb>qC(>dP)zu6{rOC&?Ii+xRt* z(8!f>d=K{S#dFVDJs%pm^49mnzYG9&3Oo(~=U+Jm07xi#oDK)sxTxiJ_4zCVE7nqArqdV4XeELJ-hWRFL z+%lqIXynRUb$)|D6TjU`__yR=w$l$6Z1!A?V_8~cjAL1|coGqB=|dv<0NLy++)f6mxirw#DbV7-1)mujx$>5c{IRQ2_R=d&o0?M`aaGeuRG8sr z?~_k@KN5@b9*_v4pLbQtZX#Y?%3g{_`TziX0|DHhyo-Dl@P>W)>IrGbr@K}@WXaOThs8u;15pNb?wBu zYuBeNLy9Z0fB^lT-6E| z{ECqTt;Ey9X`72rTOMX;;lyGb%P!dLxz8u3jB(wu-j78k^QJz_ZUK!)2;WsRl*}iCp;S5D(p%5`z*g!F!Kwl3XhvL_I$Xv2jSix+<)*8=}ZQF z9u6GO!?C^w1Ok|zd58eZVanbq+*>bf$u}Zk!Di19Fj)cGT8XD$n1~-uNm@e5w>%%1 z=ZLGCzF@N#toS*8k3hupelGxEmxsf#W5;SvdOQoC%VEsru9Oj9S;BVt4N36x$thUv z7prVfB7?kWjAL1{^2_NImeZ+*F(hZu$5FFc@x985NW?2jE#y^2!CGELUnGiET}LAE z06v!!8)^;(n;ivJMS1eBxE+2&5~Q03BAg61|BpWuZW1w?k~H(UtyX_4zKv-^BpL+( z$WjLRf`&jKh*G5rZhZ~?-QCE@GIskr-oBlDcnJUkzP+^xvx_2Py~1XE8_+uBHycRA zTdlm+I5OYqaFC^|#8&)Sy(%OV2_zErJEE_%w(5s^!kC_!LBUp&5eNqH%@<#xTCE~75QCy9I5Ieh2g#&({*_Y# zISs}*mKjY+jm^+zHz`(TuJcyemJaDC-*1c?O-Y(LQd;pNE~oh4wK8N`f+R2E=f{79 z*~cji9_+_gU;Gm`j>r7s5(56cP*ztlt5=2YSTCeZM%?#It)qODh+{5(Urc&-0|5S> zT}8*yV**g$0#>DtP8#IzR(0MSy5?kK7P=krG=Ie(5Ek0(f+R2E_}~wr6*Tlk4j?s` z#-71vg%!PszGwv1Y83!*ILM3sP#BIwM}s%U0H#eT}9a&G%ADP06OffgacbQHs(m7I>DxX z;MhyY8-Cv=pIPC(!e{gI!rggUp!tf|C!{kH_ILR4{>Rr5=;%P^lQFTYQg+8q{z6DE zEdc=B2M!7}zu_Q69}?(x7C?iL&F049_~o8n;g5fL z4}0n*vd8xn-n)ABx9?xQj{V0^2xR4Hep4BwMVPueqo1F+ajRudK#VSR+puI&YY;CyvOk9 z>2Q!G(XyOQ8A-C$sW3fut+EZiz5_nvcRH}K%Z-g<5z@?K*!Fe{t@w7Jb!XSAtD|3H z;>Im3$9nPnK)(?!be`CbZNfLMv9`%)0HBTIF*Q8{HM?r;`Bv7j1?W3=^Bo>wU83j{ zo|;n}AKp(kT&U3DPbbNV8@HO~GVvMnWyU6aCa!9_np4_8yq_%0#uIQlop2vGC~U=V z+v5-327ot)hYe@Yr4DEgyH-8H@c7pa&5-%U$)U<03S;8NEu_b;l>v;^`Sf=bZgP#a z13oi6{cb*hkSQj)e1Z0U&h6AwJ%4B1DZ(xMZ+_4G c-vhw^0K%R`(yQa|5&!@I07*qoM6N<$g1nDT9smFU literal 0 HcmV?d00001 diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index cb6a2c6bd648b32c715d49ad09f8a61329facb30..2b29cad5b0c7dca6cf61e190992069f9d9b9b651 100644 GIT binary patch delta 10794 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 diff --git a/paradise.dme b/paradise.dme index cda0cebff3e..b5e6fdac621 100644 --- a/paradise.dme +++ b/paradise.dme @@ -399,6 +399,7 @@ #include "code\datums\spells\wizard.dm" #include "code\datums\status_effects\buffs.dm" #include "code\datums\status_effects\debuffs.dm" +#include "code\datums\status_effects\gas.dm" #include "code\datums\status_effects\neutral.dm" #include "code\datums\status_effects\status_effect.dm" #include "code\datums\vr\level.dm" From 46ad75ec14e5c07155a63ebfa3bc3ebb8fe0f44a Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 9 Sep 2019 08:46:43 -0400 Subject: [PATCH 05/41] Revert "taking player_panel out to the woodshed" This reverts commit 8fc8063c7432df6468808b8529224cec34355894. --- code/modules/admin/admin_verbs.dm | 12 ++++++ code/modules/admin/player_panel.dm | 59 ++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 82c5d937cda..1c4d569507e 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -10,6 +10,7 @@ var/list/admin_verbs_default = list( var/list/admin_verbs_admin = list( /client/proc/check_antagonists, /*shows all antags*/ /datum/admins/proc/show_player_panel, + /client/proc/player_panel, /*shows an interface for all players, with links to various panels (old style)*/ /client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/ /client/proc/invisimin, /*allows our mob to go invisible/visible*/ /datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/ @@ -360,6 +361,17 @@ var/list/admin_verbs_ticket = list( to_chat(mob, "Invisimin on. You are now as invisible as a ghost.") mob.remove_from_all_data_huds() +/client/proc/player_panel() + set name = "Player Panel" + set category = null + + if(!check_rights(R_ADMIN)) + return + + holder.player_panel_old() + feedback_add_details("admin_verb","PP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return + /client/proc/player_panel_new() set name = "Player Panel New" set category = "Admin" diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 51a7f442fbc..9203477c7f9 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -328,6 +328,65 @@ usr << browse(dat, "window=players;size=600x480") +//The old one +/datum/admins/proc/player_panel_old() + if(!usr.client.holder) + return + var/dat = "Player Menu" + dat += "" + //add to this if wanting to add back in IP checking + //add if you want to know their ip to the lists below + var/list/mobs = sortmobs() + + for(var/mob/M in mobs) + if(!M.ckey) continue + + dat += "" + if(isAI(M)) + dat += "" + else if(isrobot(M)) + dat += "" + else if(issmall(M)) + dat += "" + else if(ishuman(M)) + dat += "" + else if(istype(M, /mob/living/silicon/pai)) + dat += "" + else if(istype(M, /mob/new_player)) + dat += "" + else if(isobserver(M)) + dat += "" + else if(isalien(M)) + dat += "" + else + dat += "" + + + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(H.mind && H.mind.assigned_role) + dat += "" + else + dat += "" + + + dat += {" + + + "} + switch(is_special_character(M)) + if(0) + dat += {""} + if(1) + dat += {""} + if(2) + dat += {""} + + dat += "
NameReal NameAssigned JobKeyOptionsPMTraitor?
IP:(IP: [M.lastKnownIP])
[M.name]AICyborgMonkey[M.real_name]pAINew PlayerGhostAlienUnknown[H.mind.assigned_role]NA[(M.client ? "[M.client]" : "No client")]XPMTraitor?Traitor?Traitor?
" + + usr << browse(dat, "window=players;size=640x480") + + /datum/admins/proc/check_antagonists_line(mob/M, caption = "", close = 1) var/logout_status From 4fb7d835954a710e1d3ef3f5660f69718895bfa4 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 9 Sep 2019 10:12:58 -0400 Subject: [PATCH 06/41] re-add sticky ban, player_panel, increase width of ssd/afk window a bit --- code/__DEFINES/subsystems.dm | 1 + code/modules/admin/admin_verbs.dm | 5 +- code/modules/admin/stickyban.dm | 210 ++++++++++++++++++++++++ code/modules/admin/topic.dm | 3 + code/modules/admin/verbs/randomverbs.dm | 2 +- paradise.dme | 1 + 6 files changed, 219 insertions(+), 3 deletions(-) create mode 100644 code/modules/admin/stickyban.dm diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 4807da6ec42..c55fec2cd87 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -71,6 +71,7 @@ #define INIT_ORDER_ICON_SMOOTHING -5 #define INIT_ORDER_OVERLAY -6 #define INIT_ORDER_XKEYSCORE -10 +#define INIT_ORDER_STICKY_BAN -10 #define INIT_ORDER_TICKETS -10 #define INIT_ORDER_LIGHTING -20 #define INIT_ORDER_SHUTTLE -21 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 1c4d569507e..199d4cf276a 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -84,7 +84,8 @@ var/list/admin_verbs_admin = list( ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, - /client/proc/jobbans + /client/proc/jobbans, + /client/proc/stickybanpanel ) var/list/admin_verbs_sounds = list( /client/proc/play_local_sound, @@ -363,7 +364,7 @@ var/list/admin_verbs_ticket = list( /client/proc/player_panel() set name = "Player Panel" - set category = null + set category = "Admin" if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/stickyban.dm b/code/modules/admin/stickyban.dm new file mode 100644 index 00000000000..61759f2e36d --- /dev/null +++ b/code/modules/admin/stickyban.dm @@ -0,0 +1,210 @@ +/datum/admins/proc/stickyban(action,data) + if(!check_rights(R_BAN)) + return + + switch(action) + if("show") + stickyban_show() + return + if("add") + var/list/ban = list() + var/ckey + ban["admin"] = usr.key + ban["type"] = list("sticky") + ban["reason"] = "(InGameBan)([usr.key])" //this will be displayed in dd only + + if(data["ckey"]) + ckey = ckey(data["ckey"]) + else + ckey = clean_input("Ckey","Ckey","") + if(!ckey) + return + ckey = ckey(ckey) + if(get_stickyban_from_ckey(ckey)) + to_chat(usr, "Error: Can not add a stickyban: User already has a current sticky ban") + + if(data["reason"]) + ban["message"] = data["reason"] + else + var/reason = clean_input("Reason","Reason","Ban Evasion") + if(!reason) + return + ban["message"] = "[reason]" + + world.SetConfig("ban", ckey, list2stickyban(ban)) + + log_admin("[key_name(usr)] has stickybanned [ckey].\nReason: [ban["message"]]") + message_admins("[key_name_admin(usr)] has stickybanned [ckey].\nReason: [ban["message"]]") + + if("remove") + if(!data["ckey"]) + return + var/ckey = data["ckey"] + + var/ban = get_stickyban_from_ckey(ckey) + if(!ban) + to_chat(usr, "Error: No sticky ban for [ckey] found!") + return + if(alert("Are you sure you want to remove the sticky ban on [ckey]?","Are you sure","Yes","No") == "No") + return + if(!get_stickyban_from_ckey(ckey)) + to_chat(usr, "Error: The ban disappeared.") + return + world.SetConfig("ban", ckey, null) + + log_admin("[key_name(usr)] removed [ckey]'s stickyban") + message_admins("[key_name_admin(usr)] removed [ckey]'s stickyban") + + if("remove_alt") + if(!data["ckey"]) + return + var/ckey = data["ckey"] + if(!data["alt"]) + return + var/alt = ckey(data["alt"]) + var/ban = get_stickyban_from_ckey(ckey) + if(!ban) + to_chat(usr, "Error: No sticky ban for [ckey] found!") + return + + var/found = 0 + //we have to do it this way because byond keeps the case in its sticky ban matches WHY!!! + for(var/key in ban["keys"]) + if(ckey(key) == alt) + found = 1 + break + + if(!found) + to_chat(usr, "Error: [alt] is not linked to [ckey]'s sticky ban!") + return + + if(alert("Are you sure you want to disassociate [alt] from [ckey]'s sticky ban? \nNote: Nothing stops byond from re-linking them","Are you sure","Yes","No") == "No") + return + + //we have to do this again incase something changes + ban = get_stickyban_from_ckey(ckey) + if(!ban) + to_chat(usr, "Error: The ban disappeared.") + return + + found = 0 + for(var/key in ban["keys"]) + if(ckey(key) == alt) + ban["keys"] -= key + found = 1 + break + + if(!found) + to_chat(usr, "Error: [alt] link to [ckey]'s sticky ban disappeared.") + return + + world.SetConfig("ban",ckey,list2stickyban(ban)) + + log_admin("[key_name(usr)] has disassociated [alt] from [ckey]'s sticky ban") + message_admins("[key_name_admin(usr)] has disassociated [alt] from [ckey]'s sticky ban") + + if("edit") + if(!data["ckey"]) + return + var/ckey = data["ckey"] + var/ban = get_stickyban_from_ckey(ckey) + if(!ban) + to_chat(usr, "Error: No sticky ban for [ckey] found!") + return + var/oldreason = ban["message"] + var/reason = clean_input("Reason","Reason","[ban["message"]]") + if(!reason || reason == oldreason) + return + //we have to do this again incase something changed while we waited for input + ban = get_stickyban_from_ckey(ckey) + if(!ban) + to_chat(usr, "Error: The ban disappeared.") + return + ban["message"] = "[reason]" + + world.SetConfig("ban",ckey,list2stickyban(ban)) + + log_admin("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]") + message_admins("[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]") + + spawn(10) + stickyban_show() + +/datum/admins/proc/stickyban_gethtml(ckey, ban) + . = "\[-\][ckey]
" + . += "[ban["message"]] \[Edit\]
" + if(ban["admin"]) + . += "[ban["admin"]]
" + else + . += "LEGACY
" + . += "Caught keys
\n
    " + for(var/key in ban["keys"]) + if(ckey(key) == ckey) + continue + . += "
  1. \[-\][key]
  2. " + . += "
\n" + +/datum/admins/proc/stickyban_show() + if(!check_rights(R_BAN)) + return + + var/list/bans = sortList(world.GetConfig("ban")) + var/banhtml = "" + for(var/key in bans) + var/ckey = ckey(key) + var/ban = stickyban2list(world.GetConfig("ban",key)) + banhtml += "

\n" + banhtml += stickyban_gethtml(ckey,ban) + + var/html = {" + + Sticky Bans + + +

All Sticky Bans:

\[+\]
+ [banhtml] + + "} + usr << browse(html,"window=stickybans;size=700x400") + +/proc/get_stickyban_from_ckey(var/ckey) + if(!ckey) + return null + ckey = ckey(ckey) + . = null + for(var/key in world.GetConfig("ban")) + if(ckey(key) == ckey) + . = stickyban2list(world.GetConfig("ban",key)) + break + +/proc/stickyban2list(var/ban) + if(!ban) + return null + . = params2list(ban) + .["keys"] = splittext(.["keys"], ",") + .["type"] = splittext(.["type"], ",") + .["IP"] = splittext(.["IP"], ",") + .["computer_id"] = splittext(.["computer_id"], ",") + +/proc/list2stickyban(var/list/ban) + if(!ban || !islist(ban)) + return null + . = ban.Copy() + if(.["keys"]) + .["keys"] = jointext(.["keys"], ",") + if(.["type"]) + .["type"] = jointext(.["type"], ",") + if(.["IP"]) + .["IP"] = jointext(.["IP"], ",") + if(.["computer_id"]) + .["computer_id"] = jointext(.["computer_id"], ",") + . = list2params(.) + +/client/proc/stickybanpanel() + set name = "Sticky Ban Panel" + set category = "Admin" + + if(!check_rights(R_BAN)) + return + + holder.stickyban_show() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 3e4f5b374da..9aaef943421 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -37,6 +37,9 @@ return var/ticketID = text2num(href_list["openmentorticket"]) SSmentor_tickets.showDetailUI(usr, ticketID) + + if(href_list["stickyban"]) + stickyban(href_list["stickyban"],href_list) if(href_list["makeAntag"]) switch(href_list["makeAntag"]) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 46dc9ec5b6a..aa22dfe944c 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1044,7 +1044,7 @@ Traitors and the like can also be revived with the previous role mostly intact. msg += "Cryo" msg += "" msg += "" - src << browse(msg, "window=Player_ssd_afk_check") + src << browse(msg, "window=Player_ssd_afk_check;size=600x300") /client/proc/toggle_ert_calling() set category = "Event" diff --git a/paradise.dme b/paradise.dme index a5b66b166cd..cda0cebff3e 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1175,6 +1175,7 @@ #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\secrets.dm" #include "code\modules\admin\sql_notes.dm" +#include "code\modules\admin\stickyban.dm" #include "code\modules\admin\topic.dm" #include "code\modules\admin\ToRban.dm" #include "code\modules\admin\watchlist.dm" From cdd5190e36f72b113c0adf1aae2a2550a8a447b3 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Mon, 9 Sep 2019 17:47:26 -0400 Subject: [PATCH 07/41] Fixes Some Tastes; Tweaks a Few --- code/_globalvars/lists/reagents.dm | 4 +-- .../reagents/chemistry/reagents/alcohol.dm | 1 - .../reagents/chemistry/reagents/disease.dm | 15 +++++++++- .../reagents/chemistry/reagents/drugs.dm | 22 ++++----------- .../reagents/chemistry/reagents/food.dm | 28 ++++++------------- .../reagents/chemistry/reagents/medicine.dm | 4 ++- .../reagents/chemistry/reagents/misc.dm | 4 +++ .../chemistry/reagents/pyrotechnic.dm | 11 +++++++- .../reagents/chemistry/reagents/toxins.dm | 27 ++++++++++++++++-- .../reagents/chemistry/reagents/water.dm | 4 +-- 10 files changed, 74 insertions(+), 46 deletions(-) diff --git a/code/_globalvars/lists/reagents.dm b/code/_globalvars/lists/reagents.dm index c69f53f2246..981eb63aa7e 100644 --- a/code/_globalvars/lists/reagents.dm +++ b/code/_globalvars/lists/reagents.dm @@ -4,7 +4,7 @@ GLOBAL_LIST_INIT(base_chemicals, list("water","oxygen","nitrogen","hydrogen","po "iron","aluminum","silicon","sugar","ethanol")) // Standard chemicals GLOBAL_LIST_INIT(standard_chemicals, list("slimejelly","blood","water","lube","charcoal","toxin","cyanide", - "morphine","epinephrine","space_drugs","serotrotium","oxygen","copper", + "morphine","epinephrine","space_drugs","oxygen","copper", "nitrogen","hydrogen","potassium","mercury","sulfur","carbon","chlorine", "fluorine","sodium","phosphorus","lithium","sugar","sacid","facid", "glycerol","radium","mutadone","thermite","mutagen","virusfood","iron", @@ -20,7 +20,7 @@ GLOBAL_LIST_INIT(standard_chemicals, list("slimejelly","blood","water","lube","c GLOBAL_LIST_INIT(rare_chemicals, list("minttoxin","syndicate_nanites", "xenomicrobes")) // Standard medicines GLOBAL_LIST_INIT(standard_medicines, list("charcoal","toxin","cyanide","morphine","epinephrine","space_drugs", - "serotrotium","mutadone","mutagen","teporone","lexorin","silver_sulfadiazine", + "mutadone","mutagen","teporone","lexorin","silver_sulfadiazine", "salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol", "potass_iodide","pen_acid","mannitol","oculine","styptic_powder", "methamphetamine","spaceacillin","carpotoxin","lsd","ethanol","ammonia", diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm index 5b65a062ea7..d4d2bbe2d88 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol.dm @@ -362,7 +362,6 @@ drink_icon = "cubalibreglass" drink_name = "Cuba Libre" drink_desc = "A classic mix of rum and cola." - taste_description = "fruity alcohol" taste_description = "liberation" /datum/reagent/consumable/ethanol/whiskey_cola diff --git a/code/modules/reagents/chemistry/reagents/disease.dm b/code/modules/reagents/chemistry/reagents/disease.dm index 27fe0dacc40..331157d4acc 100644 --- a/code/modules/reagents/chemistry/reagents/disease.dm +++ b/code/modules/reagents/chemistry/reagents/disease.dm @@ -5,6 +5,7 @@ reagent_state = SOLID color = "#FFFFFF" can_synth = FALSE + taste_mult = 0 /datum/reagent/spider_eggs/on_mob_life(mob/living/M) if(volume > 2.5) @@ -20,6 +21,7 @@ description = "Microscopic construction robots." color = "#535E66" // rgb: 83, 94, 102 can_synth = FALSE + taste_mult = 0 /datum/reagent/nanomachines/on_mob_life(mob/living/carbon/M) if(volume > 1.5) @@ -33,6 +35,7 @@ description = "Microbes with an entirely alien cellular structure." color = "#535E66" // rgb: 83, 94, 102 can_synth = FALSE + taste_mult = 0 /datum/reagent/xenomicrobes/on_mob_life(mob/living/carbon/M) if(volume > 1.5) @@ -45,6 +48,7 @@ description = "Active fungal spores." color = "#92D17D" // rgb: 146, 209, 125 can_synth = FALSE + taste_mult = 0 /datum/reagent/fungalspores/on_mob_life(mob/living/carbon/M) if(volume > 2.5) @@ -58,6 +62,7 @@ reagent_state = SOLID color = "#FA0000" // rgb: 250, 0, 0 can_synth = FALSE + taste_mult = 0 /datum/reagent/jagged_crystals/on_mob_life(mob/living/carbon/M) M.ForceContractDisease(new /datum/disease/berserker(0)) @@ -70,6 +75,7 @@ reagent_state = LIQUID color = "#1E4600" can_synth = FALSE + taste_mult = 0 /datum/reagent/salmonella/on_mob_life(mob/living/carbon/M) M.ForceContractDisease(new /datum/disease/food_poisoning(0)) @@ -82,6 +88,7 @@ reagent_state = LIQUID color = "#FF0000" can_synth = FALSE + taste_mult = 0 /datum/reagent/gibbis/on_mob_life(mob/living/carbon/M) if(volume > 2.5) @@ -95,6 +102,7 @@ reagent_state = LIQUID color = "#FFFFFF" can_synth = FALSE + taste_mult = 0 /datum/reagent/prions/on_mob_life(mob/living/carbon/M) if(volume > 4.5) @@ -108,6 +116,7 @@ reagent_state = LIQUID color = "#465046" can_synth = FALSE + taste_mult = 0 /datum/reagent/grave_dust/on_mob_life(mob/living/carbon/M) if(volume > 4.5) @@ -121,6 +130,7 @@ reagent_state = LIQUID color = "#F7E6B1" can_synth = FALSE + taste_description = "bacon" /datum/reagent/bacon_grease/on_mob_life(mob/living/carbon/M) if(volume > 4.5) @@ -134,6 +144,7 @@ reagent_state = SOLID color = "#925D6C" can_synth = FALSE + taste_mult = 0 /datum/reagent/heartworms/on_mob_life(mob/living/carbon/M) if(volume > 4.5) @@ -152,6 +163,7 @@ reagent_state = LIQUID color = "#AB1CCF" can_synth = FALSE + taste_mult = 0 /datum/reagent/concentrated_initro/on_mob_life(mob/living/M) if(volume >= 5) @@ -170,6 +182,7 @@ reagent_state = LIQUID nutriment_factor = 2 * REAGENTS_METABOLISM color = "#899613" // rgb: 137, 150, 19 + taste_description = "watery milk" /datum/reagent/mutagen/mutagenvirusfood name = "mutagenic agar" @@ -198,4 +211,4 @@ /datum/reagent/plasma_dust/plasmavirusfood/weak name = "weakened virus plasma" id = "weakplasmavirusfood" - color = "#CEC3C6" // rgb: 206,195,198 + color = "#CEC3C6" // rgb: 206,195,198 \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/drugs.dm b/code/modules/reagents/chemistry/reagents/drugs.dm index a2736cec719..1e2099a901b 100644 --- a/code/modules/reagents/chemistry/reagents/drugs.dm +++ b/code/modules/reagents/chemistry/reagents/drugs.dm @@ -1,18 +1,3 @@ -/datum/reagent/serotrotium - name = "Serotrotium" - id = "serotrotium" - description = "A chemical compound that promotes concentrated production of the serotonin neurotransmitter in humans." - reagent_state = LIQUID - color = "#202040" // rgb: 20, 20, 40 - metabolization_rate = 0.25 * REAGENTS_METABOLISM - -/datum/reagent/serotrotium/on_mob_life(mob/living/M) - if(ishuman(M)) - if(prob(7)) - M.emote(pick("twitch","drool","moan","gasp")) - return ..() - - /datum/reagent/lithium name = "Lithium" id = "lithium" @@ -170,6 +155,7 @@ color = "#60A584" // rgb: 96, 165, 132 overdose_threshold = 20 addiction_chance = 50 + taste_description = "bitterness" /datum/reagent/crank/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -475,7 +461,7 @@ reagent_state = LIQUID color = "#644600" addiction_chance = 30 - taste_description = "puke... or worse" + taste_description = "the inside of a toilet... or worse" /datum/reagent/jenkem/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -491,6 +477,7 @@ description = "An illegal performance enhancing drug. Side effects might include chest pain, seizures, swelling, headache, fever... ... ..." reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 + taste_description = "bitterness" /datum/reagent/aranesp/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -515,6 +502,7 @@ description = "A mild psychoactive chemical extracted from the cannabis plant." reagent_state = LIQUID color = "#0FBE0F" + taste_description = "man like, totally the best like, thing ever dude" /datum/reagent/thc/on_mob_life(mob/living/M) M.stuttering += rand(0,2) @@ -697,7 +685,7 @@ process_flags = SYNTHETIC overdose_threshold = 20 addiction_chance = 50 - taste_description = "silicone" + taste_description = "silicon" /datum/reagent/surge/on_mob_life(mob/living/M) diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index 2479a82decf..46d2e1f4db3 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -25,6 +25,8 @@ reagent_state = SOLID nutriment_factor = 15 * REAGENTS_METABOLISM color = "#664330" // rgb: 102, 67, 48 + var/brute_heal = 1 + var/burn_heal = 0 /datum/reagent/consumable/nutriment/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -33,10 +35,8 @@ var/mob/living/carbon/human/H = M if(H.can_eat(diet_flags)) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients if(prob(50)) - update_flags |= M.adjustBruteLoss(-1, FALSE) - if(!(NO_BLOOD in H.dna.species.species_traits))//do not restore blood on things with no blood by nature. - if(H.blood_volume < BLOOD_VOLUME_NORMAL) - H.blood_volume += 0.4 + update_flags |= M.adjustBruteLoss(-brute_heal, FALSE) + update_flags |= M.adjustFireLoss(-burn_heal, FALSE) return ..() | update_flags /datum/reagent/consumable/nutriment/on_new(list/supplied_data) @@ -66,36 +66,26 @@ id = "protein" description = "Various essential proteins and fats commonly found in animal flesh and blood." diet_flags = DIET_CARN | DIET_OMNI - taste_description = "meat" //TODO: Remove /datum/reagent/consumable/nutriment/plantmatter // Plant-based biomatter, digestable by herbivores and omnivores, worthless to carnivores name = "Plant-matter" id = "plantmatter" description = "Vitamin-rich fibers and natural sugars commonly found in fresh produce." diet_flags = DIET_HERB | DIET_OMNI - taste_description = "vegetables" //TODO: Remove -/datum/reagent/consumable/vitamin +/datum/reagent/consumable/nutriment/vitamin name = "Vitamin" id = "vitamin" description = "All the best vitamins, minerals, and carbohydrates the body needs in pure form." reagent_state = SOLID color = "#664330" // rgb: 102, 67, 48 - taste_description = "nutrition" + brute_heal = 1 + burn_heal = 1 -/datum/reagent/consumable/vitamin/on_mob_life(mob/living/M) - var/update_flags = STATUS_UPDATE_NONE - if(prob(50)) - update_flags |= M.adjustBruteLoss(-1, FALSE) - update_flags |= M.adjustFireLoss(-1, FALSE) +/datum/reagent/consumable/nutriment/vitamin/on_mob_life(mob/living/M) if(M.satiety < 600) M.satiety += 30 - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!(NO_BLOOD in H.dna.species.species_traits))//do not restore blood on things with no blood by nature. - if(H.blood_volume < BLOOD_VOLUME_NORMAL) - H.blood_volume += 0.5 - return ..() | update_flags + return ..() /datum/reagent/consumable/sugar name = "Sugar" diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 09ee8cb3948..8bfae21c758 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -1,6 +1,7 @@ /datum/reagent/medicine name = "Medicine" id = "medicine" + taste_description = "bitterness" /datum/reagent/medicine/on_mob_life(mob/living/M) current_cycle++ @@ -728,7 +729,7 @@ id = "mannitol" description = "Mannitol is a sugar alcohol that can help alleviate cranial swelling." color = "#D1D1F1" - taste_description = "neurogenisis" + taste_description = "sweetness" /datum/reagent/medicine/mannitol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -786,6 +787,7 @@ description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and stun." color = "#C8A5DC" can_synth = FALSE + taste_description = "and unstoppable force" /datum/reagent/medicine/stimulants/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index d34e6537cb8..359af633383 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -614,6 +614,7 @@ description = "A potent alchemic ingredient." reagent_state = LIQUID color = "#092D09" + taste_description = "alchemy" /datum/reagent/woolbat name = "Wool of bat" @@ -621,6 +622,7 @@ description = "A potent alchemic ingredient." reagent_state = LIQUID color = "#080808" + taste_description = "alchemy" /datum/reagent/tonguedog name = "Tongue of dog" @@ -628,6 +630,7 @@ description = "A potent alchemic ingredient." reagent_state = LIQUID color = "#2D0909" + taste_description = "alchemy" /datum/reagent/triplepiss name = "Triplepiss" @@ -635,6 +638,7 @@ description = "Ewwwwwwwww." reagent_state = LIQUID color = "#857400" + taste_description = "alchemy" /datum/reagent/spraytan name = "Spray Tan" diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm index bd4079d69c6..a01c034a4ae 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -5,6 +5,7 @@ reagent_state = LIQUID color = "#FFAF00" process_flags = ORGANIC | SYNTHETIC + taste_description = "burning" var/temp_fire = 4000 var/temp_deviance = 1000 var/size_divisor = 40 @@ -49,6 +50,7 @@ reagent_state = LIQUID process_flags = ORGANIC | SYNTHETIC color = "#C86432" + taste_description = "burning" /datum/reagent/napalm/reaction_temperature(exposed_temperature, exposed_volume) if(exposed_temperature > T0C + 100) @@ -253,6 +255,7 @@ description = "Sends everything flying from the detonation point." reagent_state = LIQUID color = "#FFA500" + taste_description = "air and bitterness" /datum/reagent/sorium/reaction_turf(turf/T, volume) // oh no if(prob(75)) @@ -269,7 +272,7 @@ description = "Sucks everything into the detonation point." reagent_state = LIQUID color = "#800080" - taste_description = "the end of the world" + taste_description = "compressed bitterness" /datum/reagent/liquid_dark_matter/reaction_turf(turf/T, volume) //Oh gosh, why if(prob(75)) @@ -302,6 +305,7 @@ reagent_state = LIQUID color = "#FFFF00" penetrates_skin = TRUE + taste_description = "salt" /datum/reagent/smoke_powder name = "Smoke Powder" @@ -309,6 +313,7 @@ description = "Makes a large cloud of smoke that can carry reagents." reagent_state = LIQUID color = "#808080" + taste_description = "smoke" /datum/reagent/sonic_powder name = "Sonic Powder" @@ -317,6 +322,7 @@ reagent_state = LIQUID color = "#0000FF" penetrates_skin = TRUE + taste_description = "loud noises" /datum/reagent/cryostylane name = "Cryostylane" @@ -324,6 +330,7 @@ description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Cryostylane slowly cools all other reagents in the mob down to 0K." color = "#B2B2FF" // rgb: 139, 166, 233 process_flags = ORGANIC | SYNTHETIC + taste_description = "bitterness" /datum/reagent/cryostylane/on_mob_life(mob/living/M) //TODO: code freezing into an ice cube if(M.reagents.has_reagent("oxygen")) @@ -358,6 +365,7 @@ description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly heats all other reagents." color = "#B20000" // rgb: 139, 166, 233 process_flags = ORGANIC | SYNTHETIC + taste_description = "bitterness" /datum/reagent/pyrosium/on_mob_life(mob/living/M) if(M.reagents.has_reagent("oxygen")) @@ -380,6 +388,7 @@ reagent_state = LIQUID color = "#A0A090" var/cooling_temperature = 3 // more effective than water + taste_description = "the inside of a fire extinguisher" /datum/reagent/firefighting_foam/reaction_mob(mob/living/M, method=TOUCH, volume) // Put out fire diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 43278d135e5..df67e3ae5da 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -5,6 +5,7 @@ reagent_state = LIQUID color = "#CF3600" // rgb: 207, 54, 0 taste_mult = 1.2 + taste_description = "bitterness" /datum/reagent/toxin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -17,6 +18,7 @@ description = "A toxic venom injected by spacefaring arachnids." reagent_state = LIQUID color = "#CF3600" // rgb: 207, 54, 0 + taste_description = "bitterness" /datum/reagent/spider_venom/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -81,6 +83,7 @@ reagent_state = LIQUID color = "#13BC5E" // rgb: 19, 188, 94 can_synth = FALSE + taste_description = "slime" /datum/reagent/aslimetoxin/reaction_mob(mob/living/M, method=TOUCH, volume) if(method != TOUCH) @@ -95,7 +98,6 @@ color = "#484848" // rgb: 72, 72, 72 metabolization_rate = 0.2 penetrates_skin = TRUE - taste_description = "metal" taste_mult = 0 // elemental mercury is tasteless /datum/reagent/mercury/on_mob_life(mob/living/M) @@ -127,7 +129,7 @@ color = "#6A6054" penetrates_skin = TRUE process_flags = ORGANIC | SYNTHETIC - taste_description = "spicy freshness" + taste_description = "acid" /datum/reagent/fluorine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -142,6 +144,7 @@ reagent_state = SOLID color = "#C7C7C7" // rgb: 199,199,199 penetrates_skin = TRUE + taste_description = "the colour blue and regret" /datum/reagent/radium/on_mob_life(mob/living/M) if(M.radiation < 80) @@ -160,6 +163,7 @@ color = "#04DF27" metabolization_rate = 0.3 taste_mult = 0.9 + taste_description = "slime" /datum/reagent/mutagen/reaction_mob(mob/living/M, method=TOUCH, volume) if(!..()) @@ -186,6 +190,7 @@ description = "Just the regular, boring sort of mutagenic compound. Works in a completely predictable manner." reagent_state = LIQUID color = "#7DFF00" + taste_description = "slime" /datum/reagent/stable_mutagen/on_mob_life(mob/living/M) if(!ishuman(M) || !M.dna) @@ -251,6 +256,7 @@ reagent_state = SOLID color = "#B8B8C0" // rgb: 184, 184, 192 taste_mult = 0 + taste_description = "the inside of a reactor" /datum/reagent/uranium/on_mob_life(mob/living/M) M.apply_effect(2, IRRADIATE, negate_armor = 1) @@ -268,6 +274,7 @@ reagent_state = LIQUID color = "#52685D" metabolization_rate = 0.2 + taste_description = "sweetness" /datum/reagent/lexorin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -332,6 +339,7 @@ description = "A deadly neurotoxin produced by the dreaded spess carp." reagent_state = LIQUID color = "#003333" // rgb: 0, 51, 51 + taste_description = "fish" /datum/reagent/carpotoxin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -345,6 +353,7 @@ reagent_state = LIQUID color = "#6E2828" data = 13 + taste_description = "bitterness" /datum/reagent/staminatoxin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -358,6 +367,7 @@ id = "spore" description = "A natural toxin produced by blob spores that inhibits vision when ingested." color = "#9ACD32" + taste_description = "bitterness" /datum/reagent/spores/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -376,6 +386,7 @@ drink_name = "Beer glass" drink_desc = "A freezing pint of beer" taste_description = "beer" + taste_description = "piss water" /datum/reagent/beer2/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -487,6 +498,7 @@ reagent_state = LIQUID color = "#DED6D0" penetrates_skin = TRUE + taste_description = "bitterness" /datum/reagent/formaldehyde/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -504,6 +516,7 @@ metabolization_rate = 0.2 overdose_threshold = 40 can_synth = FALSE + taste_mult = 0 /datum/reagent/venom/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -529,6 +542,7 @@ reagent_state = LIQUID color = "#60A584" metabolization_rate = 1 + taste_mult = 0 /datum/reagent/neurotoxin2/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -593,6 +607,7 @@ color = "#B0B0B0" metabolization_rate = 0.3 penetrates_skin = TRUE + taste_description = "prickliness" /datum/reagent/itching_powder/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_STAT @@ -806,6 +821,7 @@ reagent_state = LIQUID color = "#6BA688" metabolization_rate = 0.1 + taste_mult = 0 /datum/reagent/sulfonal/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -871,6 +887,7 @@ color = "#C2D8CD" metabolization_rate = 0.05 can_synth = FALSE + taste_mult = 0 /datum/reagent/coniine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -886,6 +903,7 @@ color = "#191919" metabolization_rate = 0.1 penetrates_skin = TRUE + taste_mult = 0 /datum/reagent/curare/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -919,6 +937,7 @@ reagent_state = LIQUID color = "#C8C8C8" //RGB: 200, 200, 200 metabolization_rate = 0.2 * REAGENTS_METABOLISM + taste_mult = 0 /datum/reagent/heparin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -993,6 +1012,7 @@ reagent_state = LIQUID color = "#d3cf50" var/lethality = 0 //Glyphosate is non-toxic to people + taste_description = "bitterness" /datum/reagent/glyphosate/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1045,6 +1065,7 @@ id = "pestkiller" description = "A harmful toxic mixture to kill pests. Do not ingest!" color = "#4B004B" // rgb: 75, 0, 75 + taste_description = "bitterness" /datum/reagent/pestkiller/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1125,6 +1146,7 @@ description = "A filthy, carcinogenic sludge produced by the Slurrypod plant." reagent_state = LIQUID color = "#00C81E" + taste_description = "slime" /datum/reagent/toxic_slurry/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1143,6 +1165,7 @@ description = "This is probably not good for you." reagent_state = LIQUID color = "#00FD00" + taste_description = "slime" /datum/reagent/glowing_slurry/reaction_mob(mob/living/M, method=TOUCH, volume) //same as mutagen if(!..()) diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index 64156a7cadd..68b7b9bb955 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -246,7 +246,7 @@ description = "Filthy water scoured from a nasty toilet bowl. Absolutely disgusting." reagent_state = LIQUID color = "#757547" - taste_description = "puke" + taste_description = taste_description = "the inside of a toilet... or worse" /datum/reagent/fishwater/toiletwater/reaction_mob(mob/living/M, method=TOUCH, volume) //For shennanigans return @@ -391,7 +391,7 @@ process_flags = ORGANIC | SYNTHETIC //Admin-bus has no brakes! KILL THEM ALL. metabolization_rate = 1 can_synth = FALSE - taste_description = "admin abuse" + taste_description = "burning" /datum/reagent/hellwater/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE From a1f85926ba538474abd06538fd2a922b967afddb Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Mon, 9 Sep 2019 17:55:08 -0400 Subject: [PATCH 08/41] fix --- code/modules/reagents/chemistry/reagents/medicine.dm | 2 +- code/modules/reagents/chemistry/reagents/water.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 8bfae21c758..6862e51a04c 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -787,7 +787,7 @@ description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and stun." color = "#C8A5DC" can_synth = FALSE - taste_description = "and unstoppable force" + taste_description = "an unstoppable force" /datum/reagent/medicine/stimulants/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index 68b7b9bb955..8d70ddc2430 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -246,7 +246,7 @@ description = "Filthy water scoured from a nasty toilet bowl. Absolutely disgusting." reagent_state = LIQUID color = "#757547" - taste_description = taste_description = "the inside of a toilet... or worse" + taste_description = "the inside of a toilet... or worse" /datum/reagent/fishwater/toiletwater/reaction_mob(mob/living/M, method=TOUCH, volume) //For shennanigans return From 64045ac7c27af8d5fe2c735375087e1227979dba Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 9 Sep 2019 19:23:07 -0400 Subject: [PATCH 09/41] The gravity catapult no longer affects ghosts --- code/game/mecha/equipment/tools/other_tools.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 4cfbc5c8143..5944ac9f536 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -119,6 +119,7 @@ atoms = orange(3, target) for(var/atom/movable/A in atoms) if(A.anchored) continue + if(isobserver(A)) continue spawn(0) var/iter = 5-get_dist(A,target) for(var/i=0 to iter) From f5d3b92a70479357c8ab99a2c7bc3504e8e30f7f Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 9 Sep 2019 20:08:34 -0400 Subject: [PATCH 10/41] move_resist == INFINITY --- code/game/mecha/equipment/tools/other_tools.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 5944ac9f536..e5d00901849 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -119,7 +119,7 @@ atoms = orange(3, target) for(var/atom/movable/A in atoms) if(A.anchored) continue - if(isobserver(A)) continue + if(A.move_resist == INFINITY) continue spawn(0) var/iter = 5-get_dist(A,target) for(var/i=0 to iter) From 42564c65f31f0388d7a5cbf24c2def2f15f81d15 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Mon, 9 Sep 2019 20:11:26 -0400 Subject: [PATCH 11/41] Refactors Atmos Air Current Pushing --- .../components/unary_devices/vent_pump.dm | 6 +- .../components/unary_devices/vent_scrubber.dm | 6 +- code/LINDA/LINDA_turf_tile.dm | 71 ++---- code/datums/uplink_item.dm | 27 +- code/game/gamemodes/blob/blobs/blob_mobs.dm | 7 +- code/game/gamemodes/wizard/spellbook.dm | 2 +- code/game/machinery/alarm.dm | 8 - code/game/machinery/atmoalter/canister.dm | 2 +- code/game/machinery/atmoalter/scrubber.dm | 2 +- code/game/machinery/machinery.dm | 2 +- code/game/machinery/suit_storage_unit.dm | 3 - code/game/objects/effects/effects.dm | 3 + code/game/objects/items.dm | 2 +- code/game/objects/items/documents.dm | 2 +- .../objects/items/weapons/flamethrower.dm | 231 ++++++++++-------- .../game/objects/items/weapons/tanks/tanks.dm | 2 +- .../objects/items/weapons/tanks/watertank.dm | 10 +- .../crates_lockers/closets/secure/medical.dm | 1 - .../crates_lockers/closets/syndicate.dm | 1 - .../living/carbon/alien/humanoid/humanoid.dm | 2 - .../mob/living/carbon/alien/humanoid/queen.dm | 1 + .../mob/living/carbon/carbon_defines.dm | 1 + .../mob/living/carbon/human/human_defense.dm | 11 +- .../mob/living/carbon/human/human_defines.dm | 2 +- code/modules/mob/living/living.dm | 28 +++ code/modules/mob/living/living_defines.dm | 3 +- .../mob/living/silicon/robot/syndicate.dm | 3 +- .../mob/living/simple_animal/bot/syndicate.dm | 2 - .../mob/living/simple_animal/constructs.dm | 1 + .../mob/living/simple_animal/hostile/alien.dm | 2 - .../mob/living/simple_animal/hostile/carp.dm | 1 + .../simple_animal/hostile/retaliate/undead.dm | 2 +- .../hostile/terror_spiders/terror_spiders.dm | 4 - code/modules/paperwork/paper_bundle.dm | 2 +- code/modules/projectiles/projectile.dm | 6 +- code/modules/vehicle/ambulance.dm | 1 - 36 files changed, 233 insertions(+), 227 deletions(-) diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm index 2a22052c7dc..8de40b636b6 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm @@ -80,7 +80,7 @@ /obj/machinery/atmospherics/unary/vent_pump/update_icon(var/safety = 0) ..() - + plane = FLOOR_PLANE if(!check_icon_cache()) @@ -152,7 +152,7 @@ if(pressure_delta > 0.5) if(air_contents.temperature > 0) - var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION) / 5 + var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION) var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) @@ -170,7 +170,7 @@ if(pressure_delta > 0.5) if(environment.temperature > 0) - var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION) / 5 + var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION) var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) if(isnull(removed)) //in space diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm index a6f0b8c8adb..20218f7f2d0 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm @@ -98,7 +98,7 @@ /obj/machinery/atmospherics/unary/vent_scrubber/update_icon(var/safety = 0) ..() - + plane = FLOOR_PLANE if(!check_icon_cache()) @@ -227,7 +227,7 @@ if(scrubbing) if((scrub_O2 && environment.oxygen>0.001) || (scrub_N2 && environment.nitrogen>0.001) || (scrub_CO2 && environment.carbon_dioxide>0.001) || (scrub_Toxins && environment.toxins>0.001) || (environment.trace_gases.len>0)) - var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() / 5 + var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() //Take a gas sample var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) @@ -269,7 +269,7 @@ if(air_contents.return_pressure()>=50*ONE_ATMOSPHERE) return - var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) / 5 + var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm index b7a71e68bff..94cc2751c27 100644 --- a/code/LINDA/LINDA_turf_tile.dm +++ b/code/LINDA/LINDA_turf_tile.dm @@ -298,63 +298,30 @@ excited_group.reset_cooldowns() /turf/proc/high_pressure_movements() - for(var/atom/movable/M in src) - M.experience_pressure_difference(pressure_difference, pressure_direction) + var/atom/movable/M + for(var/thing in src) + M = thing + if(!M.anchored && !M.pulledby && M.last_high_pressure_movement_air_cycle < SSair.times_fired) + M.experience_pressure_difference(pressure_difference, pressure_direction) -/atom/movable/var/pressure_resistance = 5 -/atom/movable/var/throw_pressure_limit = 15 -/atom/movable/var/last_forced_movement = 0 +/atom/movable/var/pressure_resistance = 10 +/atom/movable/var/last_high_pressure_movement_air_cycle = 0 -/atom/movable/proc/experience_pressure_difference(pressure_difference, direction) - if(last_forced_movement >= SSair.times_fired) - return 0 - if(anchored || move_resist == INFINITY) - return 0 - else if(!pulledby) - var/turf/target = get_turf(src) - var/datum/gas_mixture/target_air = target.return_air() - if(isspaceturf(target) || isunsimulatedturf(target) || pressure_resistance > target_air.return_pressure()) - return 0 - if(pressure_difference >= throw_pressure_limit) - var/general_direction = get_edge_target_turf(src, direction) - if(last_forced_movement + 10 < SSair.times_fired && is_valid_tochat_target(src)) //the first check prevents spamming throw to_chat - to_chat(src, "The pressure sends you flying!") - spawn() - var/max_distance = 14 // reduce by one each calculation to prevent infinate loops. - var/min_observed_pressure = INFINITY - var/turf/possible_target = get_turf(src) - while(!isspaceturf(target) && !isunsimulatedturf(target) && max_distance > 0) - max_distance-- - target_air = target.return_air() - min_observed_pressure = target_air.return_pressure() - possible_target = get_step_towards(target,general_direction) - if(istype(possible_target, /turf/space)) - target = possible_target - break - if(!CanAtmosPass(possible_target)) - target = possible_target - max_distance = 0 - break - var/datum/gas_mixture/possible_target_air = possible_target.return_air() - if(possible_target_air.return_pressure() > min_observed_pressure) - target = possible_target - break - target = possible_target - if(max_distance) - throw_at(target, get_dist(src, target), pressure_difference / 200, null, 0, 0, null) - else - throw_at(target, pressure_difference / 10, pressure_difference / 200, null, 0, 0, null) - last_forced_movement = SSair.times_fired - return 1 - else if(pressure_difference > pressure_resistance) - spawn() - step(src, direction) - last_forced_movement = SSair.times_fired - return 1 - return 0 +/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0) + var/const/PROBABILITY_OFFSET = 25 + var/const/PROBABILITY_BASE_PRECENT = 75 + var/max_force = sqrt(pressure_difference) * (MOVE_FORCE_DEFAULT / 5) + set waitfor = 0 + var/move_prob = 100 + if(pressure_resistance > 0) + move_prob = (pressure_difference / pressure_resistance * PROBABILITY_BASE_PRECENT) - PROBABILITY_OFFSET + move_prob += pressure_resistance_prob_delta + if(move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO)))) + step(src, direction) + last_high_pressure_movement_air_cycle = SSair.times_fired diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 0b6c5fff868..73bc7437bce 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -1169,6 +1169,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "CHAM" item = /obj/item/storage/box/syndie_kit/chameleon cost = 2 + excludefrom = list(/datum/game_mode/nuclear) /datum/uplink_item/stealthy_tools/chameleon_proj name = "Chameleon-Projector" @@ -1209,6 +1210,21 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 surplus = 30 +/datum/uplink_item/stealthy_tools/syndigaloshes + name = "No-Slip Chameleon Shoes" + desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. They do not work on heavily lubricated surfaces." + reference = "NOCS" + item = /obj/item/clothing/shoes/chameleon/noslip + cost = 2 + excludefrom = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_tools/syndigaloshes/nuke + reference = "NOCSN" + item = /obj/item/clothing/shoes/chameleon/noslip + cost = 4 + excludefrom = list() + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/stealthy_tools/cutouts name = "Adaptive Cardboard Cutouts" desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. This pack contains three as well as a \ @@ -1373,16 +1389,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) These reverse-engineered knockoffs of Nanotrasen's 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." reference = "BRMB" item = /obj/item/clothing/shoes/magboots/syndie - cost = 3 - excludefrom = list(/datum/game_mode/nuclear) - -/datum/uplink_item/device_tools/magboots/advance - name = "Advanced Blood-Red Magboots" - desc = "Reverse-engineered magboots that appear to be based on an advanced model, as they have a lighter magnetic pull. Property of Gorlex Marauders." - reference = "ABRMB" - item = /obj/item/clothing/shoes/magboots/syndie/advance - cost = 3 - excludefrom = list() + cost = 2 gamemodes = list(/datum/game_mode/nuclear) /datum/uplink_item/device_tools/powersink diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index f15f1dc742c..fac2661337e 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -45,8 +45,6 @@ var/obj/structure/blob/factory/factory = null var/list/human_overlays = list() var/is_zombie = 0 - pressure_resistance = 100 //100 kPa difference required to push - throw_pressure_limit = 120 //120 kPa difference required to throw /mob/living/simple_animal/hostile/blob/blobspore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) ..() @@ -97,8 +95,6 @@ human_overlays = H.overlays update_icons() H.forceMove(src) - pressure_resistance = 20 //5 kPa difference required to push lowered - throw_pressure_limit = 30 //15 kPa difference required to throw lowered visible_message("The corpse of [H.name] suddenly rises!") /mob/living/simple_animal/hostile/blob/blobspore/death(gibbed) @@ -176,8 +172,7 @@ force_threshold = 10 mob_size = MOB_SIZE_LARGE environment_smash = ENVIRONMENT_SMASH_STRUCTURES - pressure_resistance = 100 //100 kPa difference required to push - throw_pressure_limit = 120 //120 kPa difference required to throw + pressure_resistance = 50 see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 4193ad7b751..56cc3594ee2 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -456,7 +456,7 @@ /datum/spellbook_entry/item/armor/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) . = ..() if(.) - new /obj/item/clothing/shoes/magboots/wizard(get_turf(user)) + new /obj/item/clothing/shoes/sandal(get_turf(user)) //In case they've lost them. new /obj/item/clothing/gloves/color/purple(get_turf(user)) // To complete the outfit /datum/spellbook_entry/item/mjolnir diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 52cd5bdfee8..0fc8581cd2d 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -119,8 +119,6 @@ var/report_danger_level = TRUE - var/automatic_emergency = TRUE //Does the alarm automaticly respond to an emergency condition - /obj/machinery/alarm/monitor report_danger_level = FALSE @@ -315,12 +313,6 @@ if(old_danger_level!=danger_level) apply_danger_level() - if(automatic_emergency && mode == AALARM_MODE_SCRUBBING && danger_level == ATMOS_ALARM_DANGER) - if(pressure_dangerlevel == ATMOS_ALARM_DANGER) - mode = AALARM_MODE_OFF - if(temperature_dangerlevel == ATMOS_ALARM_DANGER && cur_tlv.max2 <= environment.temperature) - mode = AALARM_MODE_PANIC - apply_mode() if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05) mode = AALARM_MODE_SCRUBBING diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index e392b468557..9a6bf73de11 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -71,7 +71,7 @@ var/datum/canister_icons/canister_icon_container = new() var/can_label = 1 var/filled = 0.5 - pressure_resistance = 7*ONE_ATMOSPHERE + pressure_resistance = 7 * ONE_ATMOSPHERE var/temperature_resistance = 1000 + T0C volume = 1000 use_power = NO_POWER_USE diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index a11ccac3834..eea0d8c20d7 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -12,7 +12,7 @@ volume = 750 var/minrate = 0//probably useless, but whatever - var/maxrate = 10 * ONE_ATMOSPHERE / 4 + var/maxrate = 10 * ONE_ATMOSPHERE /obj/machinery/portable_atmospherics/scrubber/emp_act(severity) if(stat & (BROKEN|NOPOWER)) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index f8305e0fb7d..fad3f21c3fc 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -96,7 +96,7 @@ Class Procs: /obj/machinery name = "machinery" icon = 'icons/obj/stationobjs.dmi' - pressure_resistance = 10 + pressure_resistance = 15 layer = BELOW_OBJ_LAYER var/stat = 0 var/emagged = 0 diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 671a7d1caff..a4182198d20 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -84,7 +84,6 @@ name = "security suit storage unit" suit_type = /obj/item/clothing/suit/space/hardsuit/security mask_type = /obj/item/clothing/mask/gas/sechailer - magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_security) /obj/machinery/suit_storage_unit/security/secure @@ -130,7 +129,6 @@ /obj/machinery/suit_storage_unit/cmo/secure/sec_storage name = "medical suit storage unit" mask_type = /obj/item/clothing/mask/gas - magboots_type = /obj/item/clothing/shoes/magboots /obj/machinery/suit_storage_unit/clown name = "clown suit storage unit" @@ -154,7 +152,6 @@ name = "syndicate suit storage unit" suit_type = /obj/item/clothing/suit/space/hardsuit/syndi mask_type = /obj/item/clothing/mask/gas/syndicate - magboots_type = /obj/item/clothing/shoes/magboots/syndie storage_type = /obj/item/tank/jetpack/oxygen/harness req_access = list(access_syndicate) safeties = FALSE //in a syndicate base, everything can be used as a murder weapon at a moment's notice. diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 6b9d89a984a..fda96373825 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -15,6 +15,9 @@ /obj/effect/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) return FALSE +/obj/effect/experience_pressure_difference() + return + /obj/effect/decal plane = FLOOR_PLANE var/no_scoop = FALSE //if it has this, don't let it be scooped up diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index a5e3ad4205b..95c00447b92 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -25,7 +25,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d var/w_class = WEIGHT_CLASS_NORMAL var/slot_flags = 0 //This is used to determine on which slots an item can fit. pass_flags = PASSTABLE - pressure_resistance = 3 + pressure_resistance = 4 // causeerrorheresoifixthis var/obj/item/master = null diff --git a/code/game/objects/items/documents.dm b/code/game/objects/items/documents.dm index 8c4144f7c68..908c205939d 100644 --- a/code/game/objects/items/documents.dm +++ b/code/game/objects/items/documents.dm @@ -9,7 +9,7 @@ throw_range = 1 throw_speed = 1 layer = 4 - pressure_resistance = 1 + pressure_resistance = 2 /obj/item/documents/nanotrasen desc = "\"Top Secret\" Nanotrasen documents printed on special copy-protected paper. It is filled with complex diagrams and lists of names, dates and coordinates." diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index dd67d7c67a4..7f416679092 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -7,32 +7,35 @@ lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/guns_righthand.dmi' flags = CONDUCT - force = 3.0 - throwforce = 10.0 + force = 3 + throwforce = 10 throw_speed = 1 throw_range = 5 w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=500) origin_tech = "combat=1;plasmatech=2;engineering=2" - var/status = 0 - var/lit = 0 //on or off - var/operating = 0//cooldown - var/turf/previousturf = null + var/status = FALSE + var/lit = FALSE //on or off + var/operating = FALSE//cooldown var/obj/item/weldingtool/weldtool = null var/obj/item/assembly/igniter/igniter = null var/obj/item/tank/plasma/ptank = null + var/warned_admins = FALSE //for the message_admins() when lit + //variables for prebuilt flamethrowers + var/create_full = FALSE + var/create_with_tank = FALSE + var/igniter_type = /obj/item/assembly/igniter /obj/item/flamethrower/Destroy() QDEL_NULL(weldtool) QDEL_NULL(igniter) QDEL_NULL(ptank) - previousturf = null return ..() /obj/item/flamethrower/process() - if(!lit) + if(!lit || !igniter) STOP_PROCESSING(SSobj, src) return null var/turf/location = loc @@ -41,133 +44,139 @@ if(M.l_hand == src || M.r_hand == src) location = M.loc if(isturf(location)) //start a fire if possible - location.hotspot_expose(700, 2) - return + igniter.flamethrower_process(location) /obj/item/flamethrower/update_icon() - overlays.Cut() + cut_overlays() if(igniter) - overlays += "+igniter[status]" + add_overlay("+igniter[status]") if(ptank) - overlays += "+ptank" + add_overlay("+ptank") if(lit) - overlays += "+lit" + add_overlay("+lit") item_state = "flamethrower_1" else item_state = "flamethrower_0" - return + if(ismob(loc)) + var/mob/M = loc + M.update_inv_l_hand() + M.update_inv_r_hand() /obj/item/flamethrower/afterattack(atom/target, mob/user, flag) - if(flag) return // too close - // Make sure our user is still holding us - if(user && user.is_in_active_hand(src)) + . = ..() + if(flag) + return // too close + if(user && user.get_active_hand() == src) // Make sure our user is still holding us var/turf/target_turf = get_turf(target) if(target_turf) var/turflist = getline(user, target_turf) add_attack_logs(user, target, "Flamethrowered at [target.x],[target.y],[target.z]") flame_turf(turflist) -/obj/item/flamethrower/attackby(obj/item/W as obj, mob/user as mob, params) - if(user.stat || user.restrained() || user.lying) return - if(iswrench(W) && !status)//Taking this apart +/obj/item/flamethrower/attackby(obj/item/I, mob/user, params) + if(iswrench(I) && !status)//Taking this apart var/turf/T = get_turf(src) if(weldtool) - weldtool.loc = T + weldtool.forceMove(T) weldtool = null if(igniter) - igniter.loc = T + igniter.forceMove(T) igniter = null if(ptank) - ptank.loc = T + ptank.forceMove(T) ptank = null new /obj/item/stack/rods(T) qdel(src) return - if(isscrewdriver(W) && igniter && !lit) + else if(isscrewdriver(I) && igniter && !lit) status = !status to_chat(user, "[igniter] is now [status ? "secured" : "unsecured"]!") update_icon() return - if(isigniter(W)) - var/obj/item/assembly/igniter/I = W - if(I.secured) return - if(igniter) return - user.drop_item() - I.loc = src - igniter = I - update_icon() - return - - if(istype(W,/obj/item/tank/plasma)) - if(ptank) - to_chat(user, "There appears to already be a plasma tank loaded in [src]!") + else if(isigniter(I)) + var/obj/item/assembly/igniter/IG = I + if(IG.secured) return - user.drop_item() - ptank = W - W.loc = src + if(igniter) + return + if(!user.drop_item()) + return + IG.forceMove(src) + igniter = IG update_icon() return - if(istype(W, /obj/item/analyzer) && ptank) + else if(istype(I, /obj/item/tank/plasma)) + if(ptank) + if(user.drop_item()) + I.forceMove(src) + ptank.forceMove(get_turf(src)) + ptank = I + to_chat(user, "You swap the plasma tank in [src]!") + return + if(!user.drop_item()) + return + I.forceMove(src) + ptank = I + update_icon() + return + + else if(istype(I, /obj/item/analyzer) && ptank) atmosanalyzer_scan(ptank.air_contents, user) + else + return ..() + + +/obj/item/flamethrower/attack_self(mob/user) + toggle_igniter(user) + +/obj/item/flamethrower/AltClick(mob/user) + if(ptank && isliving(user) && user.Adjacent(src)) + user.put_in_hands(ptank) + ptank = null + to_chat(user, "You remove the plasma tank from [src]!") + update_icon() + +/obj/item/flamethrower/examine(mob/user) ..() - return + if(ptank) + to_chat(user, "[src] has \a [ptank] attached. Alt-click to remove it.") - -/obj/item/flamethrower/attack_self(mob/user as mob) - if(user.stat || user.restrained() || user.lying) return - user.set_machine(src) +/obj/item/flamethrower/proc/toggle_igniter(mob/user) if(!ptank) to_chat(user, "Attach a plasma tank first!") return - var/dat = text("Flamethrower ([lit ? "Lit" : "Unlit"])
\n Tank Pressure: [ptank.air_contents.return_pressure()]
\nRemove plasmatank - Close
") - user << browse(dat, "window=flamethrower;size=600x300") - onclose(user, "flamethrower") - return - - -/obj/item/flamethrower/Topic(href,href_list[]) - if(href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=flamethrower") + if(!status) + to_chat(user, "Secure the igniter first!") return - if(usr.stat || usr.restrained() || usr.lying) return - usr.set_machine(src) - if(href_list["light"]) - if(!ptank) return - if(!status) return - lit = !lit - if(lit) - START_PROCESSING(SSobj, src) - if(href_list["remove"]) - if(!ptank) return - usr.put_in_hands(ptank) - ptank = null - lit = 0 - usr.unset_machine() - usr << browse(null, "window=flamethrower") - for(var/mob/M in viewers(1, loc)) - if((M.client && M.machine == src)) - attack_self(M) + to_chat(user, "You [lit ? "extinguish" : "ignite"] [src]!") + lit = !lit + if(lit) + START_PROCESSING(SSobj, src) + if(!warned_admins) + message_admins("[ADMIN_LOOKUPFLW(user)] has lit a flamethrower.") + warned_admins = TRUE + else + STOP_PROCESSING(SSobj,src) update_icon() - return /obj/item/flamethrower/CheckParts(list/parts_list) ..() weldtool = locate(/obj/item/weldingtool) in contents igniter = locate(/obj/item/assembly/igniter) in contents - weldtool.status = 0 - igniter.secured = 0 - status = 1 + weldtool.status = FALSE + igniter.secured = FALSE + status = TRUE update_icon() //Called from turf.dm turf/dblclick /obj/item/flamethrower/proc/flame_turf(turflist) - if(!lit || operating) return - operating = 1 + if(!lit || operating) + return + operating = TRUE var/turf/previousturf = get_turf(src) for(var/turf/simulated/T in turflist) if(!T.air) @@ -176,47 +185,61 @@ continue //so we don't burn the tile we be standin on if(!T.CanAtmosPass(previousturf)) break - ignite_turf(T) + if(igniter) + igniter.ignite_turf(src, T) + else + default_ignite(T) sleep(1) previousturf = T - operating = 0 + operating = FALSE for(var/mob/M in viewers(1, loc)) if((M.client && M.machine == src)) attack_self(M) - return -/obj/item/flamethrower/proc/ignite_turf(turf/target, release_amount = 0.05) +/obj/item/flamethrower/proc/default_ignite(turf/target, release_amount = 0.05) + //TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this... + //Transfer 5% of current tank air contents to turf var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount) - air_transfer.toxins = air_transfer.toxins // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE + if(air_transfer.toxins) + air_transfer.toxins = air_transfer.toxins * 5 target.assume_air(air_transfer) //Burn it based on transfered gas - target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) // -- More of my "how do I shot fire?" dickery. -- TLE + target.hotspot_expose((ptank.air_contents.temperature*2) + 380, 500) //location.hotspot_expose(1000,500,1) SSair.add_to_active(target, 0) - return -/obj/item/flamethrower/full/New(var/loc) - ..() - if(!weldtool) - weldtool = new /obj/item/weldingtool(src) - weldtool.status = 0 - if(!igniter) - igniter = new /obj/item/assembly/igniter(src) - igniter.secured = 0 - status = 1 - update_icon() +/obj/item/flamethrower/Initialize(mapload) + . = ..() + if(create_full) + if(!weldtool) + weldtool = new /obj/item/weldingtool(src) + weldtool.status = FALSE + if(!igniter) + igniter = new igniter_type(src) + igniter.secured = FALSE + status = TRUE + if(create_with_tank) + ptank = new /obj/item/tank/plasma/full(src) + update_icon() -/obj/item/flamethrower/full/tank/New(var/loc) - ..() - ptank = new /obj/item/tank/plasma/full(src) - update_icon() +/obj/item/flamethrower/full + create_full = TRUE + +/obj/item/flamethrower/full/tank + create_with_tank = TRUE /obj/item/flamethrower/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) if(ptank && damage && attack_type == PROJECTILE_ATTACK && prob(15)) owner.visible_message("[attack_text] hits the fueltank on [owner]'s [src], rupturing it! What a shot!") var/target_turf = get_turf(owner) - ignite_turf(target_turf, 100) - qdel(ptank) + igniter.ignite_turf(src,target_turf, release_amount = 100) + QDEL_NULL(ptank) return 1 //It hit the flamethrower, not them + +/obj/item/assembly/igniter/proc/flamethrower_process(turf/simulated/location) + location.hotspot_expose(700, 2) + +/obj/item/assembly/igniter/proc/ignite_turf(obj/item/flamethrower/F, turf/simulated/location, release_amount = 0.05) + F.default_ignite(location, release_amount) \ No newline at end of file diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index c44264c6529..97de014cbf8 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -8,7 +8,7 @@ slot_flags = SLOT_BACK hitsound = 'sound/weapons/smash.ogg' w_class = WEIGHT_CLASS_NORMAL - pressure_resistance = ONE_ATMOSPHERE*5 + pressure_resistance = ONE_ATMOSPHERE * 5 force = 5.0 throwforce = 10.0 throw_speed = 1 diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm index 96dd853be09..3d2972d4ac6 100644 --- a/code/game/objects/items/weapons/tanks/watertank.dm +++ b/code/game/objects/items/weapons/tanks/watertank.dm @@ -278,22 +278,22 @@ if(Adj) return //Safety check so you don't blast yourself trying to refill your tank var/datum/reagents/R = reagents - if(R.total_volume < 50) - to_chat(user, "You need at least 50 units of water to use the nanofrost launcher!") + if(R.total_volume < 100) + to_chat(user, "You need at least 100 units of water to use the nanofrost launcher!") return if(nanofrost_cooldown) to_chat(user, "Nanofrost launcher is still recharging") return nanofrost_cooldown = 1 - R.remove_any(50) + R.remove_any(100) var/obj/effect/nanofrost_container/A = new /obj/effect/nanofrost_container(get_turf(src)) log_game("[key_name(user)] used Nanofrost at [get_area(user)] ([user.x], [user.y], [user.z]).") playsound(src,'sound/items/syringeproj.ogg',40,1) for(var/a=0, a<5, a++) step_towards(A, target) - sleep(1) + sleep(2) A.Smoke() - spawn(50) + spawn(100) if(src) nanofrost_cooldown = 0 return diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 73dbc88487a..6a15d3d7e5b 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -272,7 +272,6 @@ new /obj/item/sensor_device(src) new /obj/item/key/ambulance(src) new /obj/item/pinpointer/crew(src) - new /obj/item/clothing/shoes/magboots(src) new /obj/item/handheld_defibrillator(src) /obj/structure/closet/secure_closet/reagents diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index 3c3ea235b58..01a9affbe43 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -26,7 +26,6 @@ new /obj/item/clothing/mask/gas/syndicate(src) new /obj/item/clothing/suit/space/hardsuit/syndi(src) new /obj/item/tank/jetpack/oxygen/harness(src) - new /obj/item/clothing/shoes/magboots/syndie(src) /obj/structure/closet/syndicate/nuclear desc = "It's a storage unit for a Syndicate boarding party." diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index e6b45a1649a..788b8aa936d 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -14,8 +14,6 @@ var/custom_pixel_x_offset = 0 //for admin fuckery. var/custom_pixel_y_offset = 0 pass_flags = PASSTABLE - pressure_resistance = 100 //100 kPa difference required to push - throw_pressure_limit = 120 //120 kPa difference required to throw //This is fine right now, if we're adding organ specific damage this needs to be updated /mob/living/carbon/alien/humanoid/New() diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 14124afef3e..e946c5a2ba8 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -8,6 +8,7 @@ heal_rate = 5 large = 1 ventcrawler = 0 + pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper. /mob/living/carbon/alien/humanoid/queen/New() create_reagents(100) diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 4ecd81e1338..f8e9f7e9aff 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -1,5 +1,6 @@ /mob/living/carbon gender = MALE + pressure_resistance = 15 var/list/stomach_contents = list() var/list/internal_organs = list() var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access. diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index d172fabef00..ad3e459c552 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -500,11 +500,12 @@ emp_act return /mob/living/carbon/human/experience_pressure_difference(pressure_difference, direction) - playsound(src, 'sound/effects/space_wind.ogg', 50, 1) - if(shoes) - if(istype(shoes,/obj/item/clothing/shoes/magboots) && (shoes.flags & NOSLIP)) //TODO: Make a not-shit shoe var system to negate airflow. - return 0 - ..() + playsound(src, 'sound/effects/space_wind.ogg', 50, TRUE) + if(shoes && istype(shoes, /obj/item/clothing)) + var/obj/item/clothing/S = shoes + if (S.flags & NOSLIP) + return FALSE + return ..() /mob/living/carbon/human/water_act(volume, temperature, source, method = TOUCH) . = ..() diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 987041bc7ad..1aeb1476f64 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -2,7 +2,7 @@ var/global/default_martial_art = new/datum/martial_art /mob/living/carbon/human hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,GLAND_HUD) - + pressure_resistance = 25 //Marking colour and style var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000. var/list/m_styles = DEFAULT_MARKING_STYLES //All markings set to None. diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index cd20656254f..d17d3c67525 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -604,6 +604,34 @@ else return pick("trails_1", "trails_2") +/mob/living/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0) + if(buckled) + return + if(client && client.move_delay >= world.time + world.tick_lag * 2) + pressure_resistance_prob_delta -= 30 + + var/list/turfs_to_check = list() + + if(has_limbs) + var/turf/T = get_step(src, angle2dir(dir2angle(direction) + 90)) + if (T) + turfs_to_check += T + + T = get_step(src, angle2dir(dir2angle(direction) - 90)) + if(T) + turfs_to_check += T + + for(var/t in turfs_to_check) + T = t + if(T.density) + pressure_resistance_prob_delta -= 20 + continue + for(var/atom/movable/AM in T) + if(AM.density && AM.anchored) + pressure_resistance_prob_delta -= 20 + break + + ..(pressure_difference, direction, pressure_resistance_prob_delta) /*////////////////////// START RESIST PROCS diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 837e75738a9..1e3343f90f7 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -1,5 +1,6 @@ /mob/living see_invisible = SEE_INVISIBLE_LIVING + pressure_resistance = 10 //Health and life related vars var/maxHealth = 100 //Maximum health that should be possible. @@ -65,7 +66,7 @@ hud_possible = list(HEALTH_HUD,STATUS_HUD,SPECIALROLE_HUD) var/list/status_effects //a list of all status effects the mob has - + var/deathgasp_on_death = FALSE var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added diff --git a/code/modules/mob/living/silicon/robot/syndicate.dm b/code/modules/mob/living/silicon/robot/syndicate.dm index cc5fe804a36..f762ba440cf 100644 --- a/code/modules/mob/living/silicon/robot/syndicate.dm +++ b/code/modules/mob/living/silicon/robot/syndicate.dm @@ -9,7 +9,6 @@ modtype = "Syndicate" req_access = list(access_syndicate) ionpulse = 1 - magpulse = 1 lawchannel = "State" var/playstyle_string = "You are a Syndicate assault cyborg!
\ You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ @@ -80,7 +79,7 @@ var/datum/action/thermals = new /datum/action/innate/robot_sight/thermal() thermals.Grant(src) - + /mob/living/silicon/robot/syndicate/saboteur/verb/modify_name() set name = "Modify Name" set desc = "Change your systems' registered name to fool Nanotrasen systems. No cost." diff --git a/code/modules/mob/living/simple_animal/bot/syndicate.dm b/code/modules/mob/living/simple_animal/bot/syndicate.dm index 7ac95186c51..ae26bfee220 100644 --- a/code/modules/mob/living/simple_animal/bot/syndicate.dm +++ b/code/modules/mob/living/simple_animal/bot/syndicate.dm @@ -16,8 +16,6 @@ faction = list("syndicate") shoot_sound = 'sound/weapons/wave.ogg' anchored = 1 - pressure_resistance = 100 //100 kPa difference required to push - throw_pressure_limit = 120 window_id = "syndiebot" window_name = "Syndicate Bot Interface" var/turf/saved_turf diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 3a26265466b..ea8e80d2e3c 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -18,6 +18,7 @@ minbodytemp = 0 faction = list("cult") flying = 1 + pressure_resistance = 100 universal_speak = 1 AIStatus = AI_OFF //normal constructs don't have AI var/const_type = "shade" diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 52f149f0775..35b6885f143 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -24,8 +24,6 @@ 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) unsuitable_atmos_damage = 15 heat_damage_per_tick = 20 - pressure_resistance = 100 //100 kPa difference required to push - throw_pressure_limit = 120 //120 kPa difference required to throw faction = list("alien") status_flags = CANPUSH minbodytemp = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 48021ad2593..ef0ddb2baf9 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -30,6 +30,7 @@ faction = list("carp") flying = 1 + pressure_resistance = 200 gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE var/carp_color = "carp" //holder for icon set diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm index d80e68b7542..f4ef47b21a7 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm @@ -46,7 +46,7 @@ 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 - + pressure_resistance = 300 faction = list("undead") // did I mention ghost loot = list(/obj/item/reagent_containers/food/snacks/ectoplasm) del_on_death = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index f84ec5f90d7..23d7b30691b 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -49,10 +49,6 @@ var/global/list/ts_spiderling_list = list() // '1' (default for most simple_mobs, including terror spiders) converts to 3.5, or 2.8 tiles/sec. // '2' converts to 4.5, or 2.2 tiles/sec. - // Atmos - pressure_resistance = 50 //50 kPa difference required to push - throw_pressure_limit = 100 //100 kPa difference required to throw - // Ventcrawling ventcrawler = 1 // allows player ventcrawling var/ai_ventcrawls = TRUE diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 01974ad3694..704ec5b5819 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -9,7 +9,7 @@ throw_range = 2 throw_speed = 1 layer = 4 - pressure_resistance = 1 + pressure_resistance = 2 attack_verb = list("bapped") var/amount = 0 //Amount of items clipped to the paper. Note: If you have 2 paper, this should be 1 var/page = 1 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 881635d0e21..081c57ddb79 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -10,7 +10,6 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT hitsound = 'sound/weapons/pierce.ogg' var/hitsound_wall = "" - pressure_resistance = INFINITY burn_state = LAVA_PROOF var/def_zone = "" //Aiming at var/mob/firer = null//Who shot it @@ -98,7 +97,7 @@ var/turf/simulated/wall/W = target_loca if(impact_effect_type) new impact_effect_type(target_loca, hitx, hity) - + W.add_dent(WALL_DENT_SHOT, hitx, hity) return 0 if(alwayslog) @@ -334,3 +333,6 @@ obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile wi /obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides. Angle = new_angle return TRUE + +/obj/item/projectile/experience_pressure_difference() + return \ No newline at end of file diff --git a/code/modules/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm index 4c808c4d30f..102b8895bf6 100644 --- a/code/modules/vehicle/ambulance.dm +++ b/code/modules/vehicle/ambulance.dm @@ -100,7 +100,6 @@ icon = 'icons/vehicles/CargoTrain.dmi' icon_state = "ambulance" anchored = FALSE - throw_pressure_limit = INFINITY //Throwing an ambulance trolley can kill the process scheduler. /obj/structure/bed/amb_trolley/examine(mob/user) . = ..() From 6d24c1ff09f9046e1112606909fb181f7cdbaf21 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 9 Sep 2019 21:59:53 -0400 Subject: [PATCH 12/41] yes --- code/game/mecha/equipment/tools/other_tools.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index e5d00901849..664927b1d3a 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -118,8 +118,7 @@ else atoms = orange(3, target) for(var/atom/movable/A in atoms) - if(A.anchored) continue - if(A.move_resist == INFINITY) continue + if(A.anchored || A.move_resist == INFINITY) continue spawn(0) var/iter = 5-get_dist(A,target) for(var/i=0 to iter) From 1b955f23b016a58b54d23c0ec529c6328be0f3a0 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Mon, 9 Sep 2019 22:42:30 -0400 Subject: [PATCH 13/41] Automatic changelog generation for PR #12249 [ci skip] --- html/changelogs/AutoChangeLog-pr-12249.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12249.yml diff --git a/html/changelogs/AutoChangeLog-pr-12249.yml b/html/changelogs/AutoChangeLog-pr-12249.yml new file mode 100644 index 00000000000..664bac8af85 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12249.yml @@ -0,0 +1,4 @@ +author: "SteelSlayer" +delete-after: True +changes: + - bugfix: "The gravitational catapult no longer pushes ghosts when used" From 40428e47d9021e9c8d76230a513ab2cc94c0bc48 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Tue, 10 Sep 2019 03:08:44 -0400 Subject: [PATCH 14/41] Refactors Shards, Improved Light Replacer, Adds Plasmaspear --- .../objects/items/devices/lightreplacer.dm | 229 ++++++++++-------- code/game/objects/items/weapons/shards.dm | 116 +++++---- code/game/objects/items/weapons/twohanded.dm | 21 +- code/game/objects/items/weapons/weaponry.dm | 7 +- .../mob/living/silicon/robot/robot_modules.dm | 8 +- code/modules/power/lighting.dm | 5 +- icons/mob/inhands/items_lefthand.dmi | Bin 153294 -> 154068 bytes icons/mob/inhands/items_righthand.dmi | Bin 150314 -> 151108 bytes icons/obj/items.dmi | Bin 148797 -> 149035 bytes 9 files changed, 200 insertions(+), 186 deletions(-) diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 6c58b4e1414..94731757895 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -41,160 +41,160 @@ /obj/item/lightreplacer name = "light replacer" - desc = "A device to automatically replace lights. Refill with working lightbulbs." + desc = "A device to automatically replace lights. Refill with broken or working light bulbs, or sheets of glass." icon = 'icons/obj/janitor.dmi' icon_state = "lightreplacer0" item_state = "electronic" - + w_class = WEIGHT_CLASS_SMALL flags = CONDUCT slot_flags = SLOT_BELT origin_tech = "magnets=3;engineering=4" + force = 8 + var/emagged = FALSE var/max_uses = 20 - var/uses = 0 - var/shards = 0 - var/recycle = 3 - var/emagged = 0 - var/failmsg = "" + var/uses = 10 // How much to increase per each glass? var/increment = 5 // How much to take from the glass? var/decrement = 1 var/charge = 1 -/obj/item/lightreplacer/New() - uses = max_uses / 2 - failmsg = "The [name]'s refill light blinks red." - ..() + // Eating used bulbs gives us bulb shards + var/bulb_shards = 0 + // when we get this many shards, we get a free bulb. + var/shards_required = 4 + /obj/item/lightreplacer/examine(mob/user) - if(..(user, 2)) - to_chat(user, "It has [uses] lights and [shards] shards remaining.") + ..() + to_chat(user, status_string()) -/obj/item/lightreplacer/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/stack/sheet/glass)) - var/obj/item/stack/sheet/glass/G = W - if(G.amount - decrement >= 0 && uses < max_uses) - var/remaining = max(G.amount - decrement, 0) - if(!remaining && !(G.amount - decrement) == 0) - to_chat(user, "There isn't enough glass.") - return - G.amount = remaining - if(!G.amount) - user.drop_item() - qdel(G) - AddUses(increment) - to_chat(user, "You insert a piece of glass into the [src.name]. You have [uses] lights remaining.") +/obj/item/lightreplacer/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/stack/sheet/glass)) + var/obj/item/stack/sheet/glass/G = I + if(uses >= max_uses) + to_chat(user, "[src] is full.") return + else if(G.use(decrement)) + AddUses(increment) + to_chat(user, "You insert a piece of glass into [src]. You have [uses] light\s remaining.") + return + else + to_chat(user, "You need one sheet of glass to replace lights!") + return - if(istype(W, /obj/item/light)) - var/obj/item/light/L = W + if(istype(I, /obj/item/shard)) + if(uses >= max_uses) + to_chat(user, "[src] is full.") + return + if(!user.unEquip(I)) + return + AddUses(round(increment * 0.75)) + to_chat(user, "You insert a shard of glass into [src]. You have [uses] light\s remaining.") + qdel(I) + return + + if(istype(I, /obj/item/light)) + var/obj/item/light/L = I if(L.status == 0) // LIGHT OKAY - if(!user.drop_item()) - to_chat(user, "[L] is stuck to your hand!") - return if(uses < max_uses) + if(!user.unEquip(L)) + return AddUses(1) - to_chat(user, "You insert the [L.name] into the [src.name]. You have [uses] lights remaining.") - user.drop_item() - qdel(L) - return - else if(L.status == 2 || L.status == 3) - if(!user.drop_item()) - to_chat(user, "[L] is stuck to your hand!") - return - else - AddShards(1) - to_chat(user, "You insert [L] into [src]. You have [shards] shards remaining.") - user.drop_item() qdel(L) + else + if(!user.unEquip(L)) return + to_chat(user, "You insert [L] into [src].") + AddShards(1, user) + qdel(L) + return - if(istype(W, /obj/item/storage)) - var/obj/item/storage/S = W - var/found_lightbulbs = 0 + if(istype(I, /obj/item/storage)) + var/obj/item/storage/S = I + var/found_lightbulbs = FALSE + var/replaced_something = TRUE - for(var/obj/item/I in S.contents) - if(istype(I,/obj/item/light)) - var/obj/item/light/L = I - found_lightbulbs = 1 + for(var/obj/item/IT in S.contents) + if(istype(IT, /obj/item/light)) + var/obj/item/light/L = IT + found_lightbulbs = TRUE if(uses >= max_uses) - to_chat(user, "[src] is full!") break - if(L.status == 0) + if(L.status == LIGHT_OK) + replaced_something = TRUE AddUses(1) qdel(L) - else if(L.status == 2 || L.status == 3) - AddShards(1) + + else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED) + replaced_something = TRUE + AddShards(1, user) qdel(L) - to_chat(user, "You fill [src] with lights from [S].") + if(!found_lightbulbs) to_chat(user, "[S] contains no bulbs.") return + if(!replaced_something && uses == max_uses) + to_chat(user, "[src] is full!") + return + + to_chat(user, "You fill [src] with lights from [S]. " + status_string() + "") + return + return ..() + /obj/item/lightreplacer/emag_act(user as mob) if(!emagged) Emag() /obj/item/lightreplacer/attack_self(mob/user) - /* // This would probably be a bit OP. If you want it though, uncomment the code. - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R.emagged) - src.Emag() - to_chat(usr, "You shortcircuit the [src].") - return - */ - to_chat(usr, "It has [uses] lights remaining.") + for(var/obj/machinery/light/target in user.loc) + ReplaceLight(target, user) + to_chat(user, status_string()) /obj/item/lightreplacer/update_icon() icon_state = "lightreplacer[emagged]" +/obj/item/lightreplacer/proc/status_string() + return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)." -/obj/item/lightreplacer/proc/Use(var/mob/user) - - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) +/obj/item/lightreplacer/proc/Use(mob/user) + playsound(loc, 'sound/machines/click.ogg', 50, TRUE) AddUses(-1) return 1 // Negative numbers will subtract -/obj/item/lightreplacer/proc/AddUses(var/amount = 1) - uses = min(max(uses + amount, 0), max_uses) +/obj/item/lightreplacer/proc/AddUses(amount = 1) + uses = Clamp(uses + amount, 0, max_uses) -/obj/item/lightreplacer/proc/AddShards(amount = 1) - shards += amount - var/recycled_lights = round(shards / recycle) - if(recycled_lights > 0) - AddUses(recycled_lights) - shards = shards % recycle - return recycled_lights +/obj/item/lightreplacer/proc/AddShards(amount = 1, user) + bulb_shards += amount + var/new_bulbs = round(bulb_shards / shards_required) + if(new_bulbs > 0) + AddUses(new_bulbs) + bulb_shards = bulb_shards % shards_required + if(new_bulbs != 0) + to_chat(user, "[src] has fabricated a new bulb from the broken glass it has stored. It now has [uses] uses.") + playsound(loc, 'sound/machines/ding.ogg', 50, TRUE) + return new_bulbs /obj/item/lightreplacer/proc/Charge(var/mob/user) charge += 1 - if(charge > 7) + if(charge > 3) AddUses(1) charge = 1 -/obj/item/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U) - +/obj/item/lightreplacer/proc/ReplaceLight(obj/machinery/light/target, mob/living/U) if(target.status != LIGHT_OK) if(CanUse(U)) - if(!Use(U)) return - to_chat(U, "You replace the [target.fitting] with the [src].") + if(!Use(U)) + return + to_chat(U, "You replace [target.fitting] with [src].") if(target.status != LIGHT_EMPTY) - - var/obj/item/light/L1 = new target.light_type(target.loc) - L1.status = target.status - L1.rigged = target.rigged - L1.brightness_range = target.brightness_range - L1.brightness_power = target.brightness_power - L1.brightness_color = target.brightness_color - L1.switchcount = target.switchcount - target.switchcount = 0 - L1.update() - + AddShards(1, U) target.status = LIGHT_EMPTY target.update() @@ -215,37 +215,54 @@ return else - to_chat(U, failmsg) + to_chat(U, "[src]'s refill light blinks red.") return else - to_chat(U, "There is a working [target.fitting] already inserted.") + to_chat(U, "There is a working [target.fitting] already inserted!") return /obj/item/lightreplacer/proc/Emag() emagged = !emagged - playsound(src.loc, "sparks", 100, 1) + playsound(loc, "sparks", 100, TRUE) if(emagged) - name = "Shortcircuited [initial(name)]" + name = "shortcircuited [initial(name)]" else name = initial(name) update_icon() -//Can you use it? +/obj/item/lightreplacer/proc/CanUse(mob/living/user) + add_fingerprint(user) + if(uses > 0) + return 1 + else + return 0 + +/obj/item/lightreplacer/afterattack(atom/T, mob/U, proximity) + if(!proximity) + return + if(!isturf(T)) + return + + var/used = FALSE + for(var/atom/A in T) + if(!CanUse(U)) + break + used = TRUE + if(istype(A, /obj/machinery/light)) + ReplaceLight(A, U) + + if(!used) + to_chat(U, "[src]'s refill light blinks red.") /obj/item/lightreplacer/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) J.put_in_cart(src, user) J.myreplacer = src J.update_icon() -/obj/item/lightreplacer/proc/CanUse(var/mob/living/user) - src.add_fingerprint(user) - //Not sure what else to check for. Maybe if clumsy? - if(uses > 0) - return 1 - else - return 0 +/obj/item/lightreplacer/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J) + return #undef LIGHT_OK #undef LIGHT_EMPTY #undef LIGHT_BROKEN -#undef LIGHT_BURNED +#undef LIGHT_BURNED \ No newline at end of file diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm index 4c8697da247..35418aaf01a 100644 --- a/code/game/objects/items/weapons/shards.dm +++ b/code/game/objects/items/weapons/shards.dm @@ -1,27 +1,30 @@ // Glass shards /obj/item/shard - name = "glass shard" + name = "shard" + desc = "A nasty looking shard of glass." icon = 'icons/obj/shards.dmi' icon_state = "large" - sharp = TRUE - desc = "Could probably be used as ... a throwing weapon?" w_class = WEIGHT_CLASS_TINY force = 5 throwforce = 10 item_state = "shard-glass" - materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + materials = list(MAT_GLASS = MINERAL_MATERIAL_AMOUNT) attack_verb = list("stabbed", "slashed", "sliced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0) + sharp = TRUE + var/cooldown = 0 + var/icon_prefix + var/obj/item/stack/sheet/welded_type = /obj/item/stack/sheet/glass /obj/item/shard/suicide_act(mob/user) to_chat(viewers(user), pick("[user] is slitting [user.p_their()] wrists with [src]! It looks like [user.p_theyre()] trying to commit suicide.", "[user] is slitting [user.p_their()] throat with [src]! It looks like [user.p_theyre()] trying to commit suicide.")) return BRUTELOSS -/obj/item/shard/New() - ..() +/obj/item/shard/Initialize(mapload) + . = ..() icon_state = pick("large", "medium", "small") switch(icon_state) if("small") @@ -33,8 +36,11 @@ if("large") pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) + if(icon_prefix) + icon_state = "[icon_prefix][icon_state]" /obj/item/shard/afterattack(atom/movable/AM, mob/user, proximity) + . = ..() if(!proximity || !(src in user)) return if(isturf(AM)) @@ -48,15 +54,17 @@ if(affecting.is_robotic()) return to_chat(H, "[src] cuts into your hand!") - if(affecting.receive_damage(force*0.5)) + if(affecting.receive_damage(force * 0.5)) H.UpdateDamageIcon() /obj/item/shard/attackby(obj/item/I, mob/user, params) if(iswelder(I)) var/obj/item/weldingtool/WT = I if(WT.remove_fuel(0, user)) - var/obj/item/stack/sheet/glass/NG = new (user.loc) - for(var/obj/item/stack/sheet/glass/G in user.loc) + var/obj/item/stack/sheet/NG = new welded_type(user.loc) + for(var/obj/item/stack/sheet/G in user.loc) + if(!istype(G, welded_type)) + continue if(G == NG) continue if(G.amount >= G.max_amount) @@ -64,64 +72,48 @@ G.attackby(NG, user) to_chat(user, "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s.") qdel(src) - else - return ..() + return + if(istype(I, /obj/item/lightreplacer)) + I.attackby(src, user) + return + return ..() -/obj/item/shard/Crossed(AM as mob|obj, oldloc) - if(isliving(AM)) - var/mob/living/M = AM - if(M.incorporeal_move || M.flying || M.throwing)//you are incorporal or flying or being thrown ..no shard stepping! +/obj/item/shard/Crossed(mob/living/L, oldloc) + if(istype(L) && has_gravity(loc)) + if(L.incorporeal_move || L.flying) return - to_chat(M, "You step on \the [src]!") - playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds - if(ishuman(M)) - var/mob/living/carbon/human/H = M + playsound(loc, 'sound/effects/glass_step.ogg', 50, TRUE) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + var/obj/item/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot")) + if(!affecting) + return + if(affecting.is_robotic()) + return + var/feetCover = (H.wear_suit && H.wear_suit.body_parts_covered & FEET) || (H.w_uniform && H.w_uniform.body_parts_covered & FEET) + if(H.shoes || feetCover || H.buckled) + return + if(affecting.receive_damage(force, 0)) + H.UpdateDamageIcon() - if( !H.shoes && ( !H.wear_suit || !(H.wear_suit.body_parts_covered & FEET) ) ) - var/obj/item/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot")) - if(!affecting) - return - if(affecting.is_robotic()) - return - H.Weaken(3) - if(affecting.receive_damage(5, 0)) - H.UpdateDamageIcon() - ..() + if(cooldown < world.time - 10) //cooldown to avoid message spam. + if(!H.incapacitated(ignore_restraints = TRUE)) + H.visible_message("[H] steps on [src]!", \ + "You step on [src]!") + else + H.visible_message("[H] slides on [src]!", \ + "You slide on [src]!") + + cooldown = world.time + H.Weaken(3) + return ..() /obj/item/shard/plasma name = "plasma shard" desc = "A shard of plasma glass. Considerably tougher then normal glass shards. Apparently not tough enough to be a window." - force = 8 - throwforce = 15 + force = 6 + throwforce = 11 icon_state = "plasmalarge" - sharp = TRUE - -/obj/item/shard/plasma/New() - ..() - icon_state = pick("plasmalarge", "plasmamedium", "plasmasmall") - switch(icon_state) - if("plasmasmall") - pixel_x = rand(-12, 12) - pixel_y = rand(-12, 12) - if("plasmamedium") - pixel_x = rand(-8, 8) - pixel_y = rand(-8, 8) - if("plasmalarge") - pixel_x = rand(-5, 5) - pixel_y = rand(-5, 5) - -/obj/item/shard/plasma/attackby(obj/item/W, mob/user, params) - if(iswelder(W)) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0, user)) - var/obj/item/stack/sheet/plasmaglass/NG = new (user.loc) - for(var/obj/item/stack/sheet/plasmaglass/G in user.loc) - if(G == NG) - continue - if(G.amount >= G.max_amount) - continue - G.attackby(NG, user, params) - to_chat(usr, "You add the newly-formed plasma glass to the stack. It now contains [NG.amount] sheets.") - qdel(src) - else - return ..() + materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) + icon_prefix = "plasma" + welded_type = /obj/item/stack/sheet/plasmaglass \ No newline at end of file diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 15456386541..0f0a657f0ab 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -337,14 +337,23 @@ sharp = TRUE no_spin_thrown = TRUE var/obj/item/grenade/explosive = null + var/icon_prefix = "spearglass" /obj/item/twohanded/spear/update_icon() - if(explosive) - icon_state = "spearbomb[wielded]" - else - icon_state = "spearglass[wielded]" + icon_state = "[icon_prefix][wielded]" + +/obj/item/twohanded/spear/CheckParts(list/parts_list) + var/obj/item/shard/tip = locate() in parts_list + if(istype(tip, /obj/item/shard/plasma)) + force_wielded = 19 + force_unwielded = 11 + throwforce = 21 + icon_prefix = "spearplasma" + update_icon() + qdel(tip) ..() + /obj/item/twohanded/spear/afterattack(atom/movable/AM, mob/user, proximity) if(!proximity) return @@ -370,9 +379,7 @@ force_wielded = 20 //I have no idea how to balance throwforce = 22 armour_penetration = 15 //Enhanced armor piercing - -/obj/item/twohanded/spear/bonespear/update_icon() - icon_state = "bone_spear[wielded]" + icon_prefix = "bone_spear" //GREY TIDE /obj/item/twohanded/spear/grey_tide diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 501f1780a0b..56a692e7645 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -105,7 +105,12 @@ ..() if(istype(I, /obj/item/shard)) var/obj/item/twohanded/spear/S = new /obj/item/twohanded/spear - + if(istype(I, /obj/item/shard/plasma)) + S.force_wielded = 19 + S.force_unwielded = 11 + S.throwforce = 21 + S.icon_prefix = "spearplasma" + S.update_icon() if(!remove_item_from_storage(user)) user.unEquip(src) user.unEquip(I) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 699376c927f..76c7f5bc1af 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -252,7 +252,7 @@ modules += new /obj/item/soap/nanotrasen(src) modules += new /obj/item/storage/bag/trash/cyborg(src) modules += new /obj/item/mop/advanced/cyborg(src) - modules += new /obj/item/lightreplacer(src) + modules += new /obj/item/lightreplacer/cyborg(src) modules += new /obj/item/holosign_creator(src) emag = new /obj/item/reagent_containers/spray(src) @@ -544,7 +544,7 @@ modules += new /obj/item/crowbar/cyborg(src) modules += new /obj/item/wirecutters/cyborg(src) modules += new /obj/item/multitool/cyborg(src) - modules += new /obj/item/lightreplacer(src) + modules += new /obj/item/lightreplacer/cyborg(src) modules += new /obj/item/gripper(src) modules += new /obj/item/matter_decompiler(src) modules += new /obj/item/reagent_containers/spray/cleaner/drone(src) @@ -562,10 +562,6 @@ /obj/item/robot_module/drone/respawn_consumable(mob/living/silicon/robot/R) var/obj/item/reagent_containers/spray/cleaner/C = locate() in modules C.reagents.add_reagent("cleaner", 3) - - var/obj/item/lightreplacer/LR = locate() in modules - LR.Charge(R) - ..() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index b186e862f01..6b4b5f05e82 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -303,10 +303,7 @@ //Light replacer code if(istype(W, /obj/item/lightreplacer)) var/obj/item/lightreplacer/LR = W - if(isliving(user)) - var/mob/living/U = user - LR.ReplaceLight(src, U) - return + LR.ReplaceLight(src, user) // attempt to insert light if(istype(W, /obj/item/light)) diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 10eef3b03379e2e0c0fb2e8563a836bbd0a5d2d0..7d0961fc449acad260b304736c2c238467559319 100644 GIT binary patch delta 6806 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 delta 6024 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 VgF!=-HYJD@s)}0BB83+p{|~J59b*6h diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 926e04b28bf2f5ddff3896b123723080573d074f..5850e4d8d8c600a22d733b9c0203fbaa1f8d0387 100644 GIT binary patch delta 6049 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 delta 5249 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 diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 463e135d35f8cbbcc7a4a67a6543705cc1ebec27..35f0fb7349dc7453d94d0ba17d330fcc916e970f 100644 GIT binary patch delta 24419 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 Date: Tue, 10 Sep 2019 03:21:41 -0400 Subject: [PATCH 15/41] fix --- code/game/objects/items/weapons/shards.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm index 35418aaf01a..e2fc07712bf 100644 --- a/code/game/objects/items/weapons/shards.dm +++ b/code/game/objects/items/weapons/shards.dm @@ -40,7 +40,6 @@ icon_state = "[icon_prefix][icon_state]" /obj/item/shard/afterattack(atom/movable/AM, mob/user, proximity) - . = ..() if(!proximity || !(src in user)) return if(isturf(AM)) From 829d1297cf295c04ee604513fc4c42df1ac9293c Mon Sep 17 00:00:00 2001 From: xProlithium Date: Tue, 10 Sep 2019 03:38:26 -0400 Subject: [PATCH 16/41] CA to TP on adminpm and prayers I missed changing CA to TP on these two folders. --- code/modules/admin/verbs/adminpm.dm | 8 ++++---- code/modules/admin/verbs/pray.dm | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 1069e981c37..270a6bd6179 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -191,7 +191,7 @@ else if(check_rights(R_ADMIN|R_MOD, 0, X.mob)) to_chat(X, "[type]: [key_name(src, TRUE, type)]->[key_name(C, TRUE, type)]: [emoji_msg]") - + //Check if the mob being PM'd has any open admin tickets. var/tickets = list() if(type == "Mentorhelp") @@ -205,10 +205,10 @@ if(type == "Mentorhelp") if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets tickets = SSmentor_tickets.checkForTicket(src) - else // Ahelp + else // Ahelp if(check_rights(R_ADMIN|R_MOD, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets tickets = SStickets.checkForTicket(src) - + if(tickets) for(var/datum/ticket/i in tickets) i.addResponse(src, msg) @@ -351,7 +351,7 @@ var/client/C = pms[title].client || update_client(title) if(!C) return "[title] (Disconnected)" - return "[key_name(C, FALSE)] ([ADMIN_QUE(C.mob,"?")]) ([ADMIN_PP(C.mob,"PP")]) ([ADMIN_VV(C.mob,"VV")]) ([ADMIN_SM(C.mob,"SM")]) ([admin_jump_link(C.mob)]) (CA)" + return "[key_name(C, FALSE)] ([ADMIN_QUE(C.mob,"?")]) ([ADMIN_PP(C.mob,"PP")]) ([ADMIN_VV(C.mob,"VV")]) ([ADMIN_TP(C.mob,"TP")]) ([ADMIN_SM(C.mob,"SM")]) ([admin_jump_link(C.mob)])" /datum/pm_tracker/proc/update_client(title) var/client/C = GLOB.directory[ckey(title)] diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index b6986f4960f..9973de89c85 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -30,7 +30,7 @@ deity = SSticker.cultdat.entity_name log_say("(PRAYER) [msg]", usr) - msg = "[bicon(cross)][prayer_type][deity ? " (to [deity])" : ""][mind && mind.isholy ? " (blessings: [mind.num_blessed])" : ""]: [key_name(src, 1)] ([ADMIN_QUE(src,"?")]) ([ADMIN_PP(src,"PP")]) ([ADMIN_VV(src,"VV")]) ([ADMIN_SM(src,"SM")]) ([admin_jump_link(src)]) (CA) ([ADMIN_SC(src,"SC")]) (BLESS) (SMITE): [msg]" + msg = "[bicon(cross)][prayer_type][deity ? " (to [deity])" : ""][mind && mind.isholy ? " (blessings: [mind.num_blessed])" : ""]: [key_name(src, 1)] ([ADMIN_QUE(src,"?")]) ([ADMIN_PP(src,"PP")]) ([ADMIN_VV(src,"VV")]) ([ADMIN_TP(src,"TP")]) ([ADMIN_SM(src,"SM")]) ([admin_jump_link(src)]) ([ADMIN_SC(src,"SC")]) (BLESS) (SMITE): [msg]" for(var/client/X in GLOB.admins) if(check_rights(R_EVENT,0,X.mob)) @@ -41,7 +41,7 @@ /proc/Centcomm_announce(var/text , var/mob/Sender) var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) - msg = "CENTCOMM: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) (CA) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")])): [msg]" + msg = "CENTCOMM: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")])): [msg]" for(var/client/X in GLOB.admins) if(R_EVENT & X.holder.rights) to_chat(X, msg) @@ -50,7 +50,7 @@ /proc/Syndicate_announce(var/text , var/mob/Sender) var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) - msg = "SYNDICATE: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) (CA) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_SYNDICATE_REPLY(Sender,"RPLY")]): [msg]" + msg = "SYNDICATE: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_SYNDICATE_REPLY(Sender,"RPLY")]): [msg]" for(var/client/X in GLOB.admins) if(check_rights(R_EVENT,0,X.mob)) to_chat(X, msg) @@ -59,7 +59,7 @@ /proc/HONK_announce(var/text , var/mob/Sender) var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) - msg = "HONK: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) (CA) ([ADMIN_BSA(Sender,"BSA")]) (RPLY): [msg]" + msg = "HONK: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) (RPLY): [msg]" for(var/client/X in GLOB.admins) if(R_EVENT & X.holder.rights) to_chat(X, msg) @@ -68,7 +68,7 @@ /proc/ERT_Announce(var/text , var/mob/Sender, var/repeat_warning) var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) - msg = "ERT REQUEST: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) (CA) ([ADMIN_BSA(Sender,"BSA")]) (RESPOND): [msg]" + msg = "ERT REQUEST: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) (RESPOND): [msg]" if(repeat_warning) msg += "
WARNING: ERT request has gone 5 minutes with no reply!" for(var/client/X in GLOB.admins) @@ -80,7 +80,7 @@ /proc/Nuke_request(text , mob/Sender) var/nuke_code = get_nuke_code() var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) - msg = "NUKE CODE REQUEST: [key_name(Sender)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) (CA) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")]): [msg]" + msg = "NUKE CODE REQUEST: [key_name(Sender)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")]): [msg]" for(var/client/X in GLOB.admins) if(check_rights(R_EVENT,0,X.mob)) to_chat(X, msg) From 7e07355b74f02d22c471ad8a1b8c85b0bbcf0f02 Mon Sep 17 00:00:00 2001 From: Ty-Omaha Date: Tue, 10 Sep 2019 06:41:58 -0400 Subject: [PATCH 17/41] stuff --- goon/code/datums/browserOutput.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm index 3359e7c6232..b4b0281d379 100644 --- a/goon/code/datums/browserOutput.dm +++ b/goon/code/datums/browserOutput.dm @@ -155,7 +155,7 @@ var/list/chatResources = list( //Uh oh this fucker has a history of playing on a banned account!! if (found.len > 0) - //TODO: add a new evasion ban for the CURRENT client details, using the matched row details + AddBan(owner.ckey, owner.computer_id, "Ban evasion on account: [found["ckey"]]", "System", 0, 0) message_admins("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])") log_admin("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])") From d86f294d8761d0137c59737ae524cfa465c5811d Mon Sep 17 00:00:00 2001 From: Ty-Omaha Date: Tue, 10 Sep 2019 06:49:40 -0400 Subject: [PATCH 18/41] ip --- goon/code/datums/browserOutput.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm index b4b0281d379..be752e1205d 100644 --- a/goon/code/datums/browserOutput.dm +++ b/goon/code/datums/browserOutput.dm @@ -155,7 +155,7 @@ var/list/chatResources = list( //Uh oh this fucker has a history of playing on a banned account!! if (found.len > 0) - AddBan(owner.ckey, owner.computer_id, "Ban evasion on account: [found["ckey"]]", "System", 0, 0) + AddBan(owner.ckey, owner.computer_id, "Ban evasion on account: [found["ckey"]]", "System", 0, 0, owner.address) message_admins("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])") log_admin("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])") From a92d2a79dc8e355de5d1ebf8babcdff0a388e087 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 07:05:52 -0400 Subject: [PATCH 19/41] Automatic changelog generation for PR #12258 [ci skip] --- html/changelogs/AutoChangeLog-pr-12258.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12258.yml diff --git a/html/changelogs/AutoChangeLog-pr-12258.yml b/html/changelogs/AutoChangeLog-pr-12258.yml new file mode 100644 index 00000000000..742827e0df6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12258.yml @@ -0,0 +1,4 @@ +author: "Ty-Omaha" +delete-after: True +changes: + - tweak: "Minor ban evasion update" From 5e50e2ea855e6ff89b8532a19b0d3d4640eb8b67 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 07:15:42 -0400 Subject: [PATCH 20/41] Automatic changelog generation for PR #12256 [ci skip] --- html/changelogs/AutoChangeLog-pr-12256.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12256.yml diff --git a/html/changelogs/AutoChangeLog-pr-12256.yml b/html/changelogs/AutoChangeLog-pr-12256.yml new file mode 100644 index 00000000000..162b69bd369 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12256.yml @@ -0,0 +1,4 @@ +author: "xProlithium" +delete-after: True +changes: + - tweak: "Altered CA to TP for prayers and adminpms." From 7e4b757f81435445a41e9e7ad59da83781cb2ab6 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 07:54:10 -0400 Subject: [PATCH 21/41] Automatic changelog generation for PR #12240 [ci skip] --- html/changelogs/AutoChangeLog-pr-12240.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12240.yml diff --git a/html/changelogs/AutoChangeLog-pr-12240.yml b/html/changelogs/AutoChangeLog-pr-12240.yml new file mode 100644 index 00000000000..eb3240dcf3a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12240.yml @@ -0,0 +1,7 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes Megafauna spawning near the base" + - bugfix: "Fixes lava rivers not forming" + - tweak: "Upped the labor mineral spawn rate" + - rscdel: "Removed the ability to find random code-locked crates when mining" From 240cf390257df1159ffc833e1ad067aa4bba4283 Mon Sep 17 00:00:00 2001 From: Ty-Omaha Date: Tue, 10 Sep 2019 17:00:10 -0400 Subject: [PATCH 22/41] Revert "Adds Auto-Note for Manual Bans" --- code/modules/admin/topic.dm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 21706aeabe3..50c5df98c10 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -169,14 +169,6 @@ message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom IP and computer id fields replaced with the IP and computer id from the located mob") DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid ) - if(BANTYPE_PERMA) - add_note(banckey, "Permanently Banned - [banreason]", null, usr.ckey, 0) - else if(BANTYPE_TEMP) - add_note(banckey, "Banned for [banduration] minutes - [banreason]", null, usr.ckey, 0) - else if(BANTYPE_JOB_PERMA) - add_note(banckey, "Banned from [banjob] - [banreason]", null, usr.ckey, 0) - else - add_note(banckey, "[banreason]", null, usr.ckey, 0) else if(href_list["editrights"]) From ec27b1039b3ca4e73afcac82a6602e74228168b4 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 19:38:03 -0400 Subject: [PATCH 23/41] Automatic changelog generation for PR #12241 [ci skip] --- html/changelogs/AutoChangeLog-pr-12241.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12241.yml diff --git a/html/changelogs/AutoChangeLog-pr-12241.yml b/html/changelogs/AutoChangeLog-pr-12241.yml new file mode 100644 index 00000000000..ac25b462a95 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12241.yml @@ -0,0 +1,15 @@ +author: "SteelSlayer" +delete-after: True +changes: + - tweak: "The \"Show Player Panel\" verb is now right click only" + - tweak: "The \"C.M.A. - Admin\" verb is now right click only" + - tweak: "The \"C.M.A. - Self\" verb is now right click only" + - tweak: "The \"Check Contents\" verb is now right click only" + - tweak: "The \"Freeze\" verb is now right click only" + - tweak: "The \"Freeze Mech\" verb is now right click only" + - tweak: "The \"Jump to Turf\" verb is now right click only" + - tweak: "The \"Update Mob Sprite\" verb is now right click only" + - tweak: "The \"List SSDs\" and \"List AFKs\" verbs have been combined into one verb named \"List SSDs and AFKs\"" + - tweak: "The \"Resolve All Open Mentor Tickets\" verb has been moved inside the mentor ticket interface window" + - tweak: "The \"Resolve All Open Admin Tickets\" verb has been moved inside the admin ticket interface window" + - tweak: "Increases the width of the new \"List SSDs and AFKs\" window a bit" From ffcae4c75f7ba63cd9da8f5fa668a97ac9063fd3 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 19:38:34 -0400 Subject: [PATCH 24/41] Automatic changelog generation for PR #12242 [ci skip] --- html/changelogs/AutoChangeLog-pr-12242.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12242.yml diff --git a/html/changelogs/AutoChangeLog-pr-12242.yml b/html/changelogs/AutoChangeLog-pr-12242.yml new file mode 100644 index 00000000000..0222b6b6ff8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12242.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - rscadd: "Watcher Icewing blasts will briefly freeze you" From 7f31e4f7a364ad484c2c00b38a3a319326d6624f Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 19:38:58 -0400 Subject: [PATCH 25/41] Automatic changelog generation for PR #12248 [ci skip] --- html/changelogs/AutoChangeLog-pr-12248.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12248.yml diff --git a/html/changelogs/AutoChangeLog-pr-12248.yml b/html/changelogs/AutoChangeLog-pr-12248.yml new file mode 100644 index 00000000000..11705330985 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12248.yml @@ -0,0 +1,6 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Tweaks a few reagents tastes" + - bugfix: "fixes being able to taste metaphorical salt" + - tweak: "nutriment no longer restores blood" From 11784c95e22915be9c351cc22974871b905094cc Mon Sep 17 00:00:00 2001 From: Terilia Date: Wed, 11 Sep 2019 01:48:53 +0200 Subject: [PATCH 26/41] Headcrab fix 1 --- code/modules/mob/living/simple_animal/hostile/headcrab.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 0429a53ad11..b3a0ea5ed06 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -18,7 +18,7 @@ attack_sound = 'sound/creatures/headcrab_attack.ogg' speak_emote = list("hisses") var/is_zombie = 0 - stat_attack = UNCONSCIOUS //so they continue to attack when they are on the ground. + stat_attack = DEAD //so they continue to attack when they are on the ground. var/host_species = "" var/list/human_overlays = list() From dd3ac3569869e3c3fe28097e6e000f2abfe6ef03 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 21:06:43 -0400 Subject: [PATCH 27/41] Automatic changelog generation for PR #12261 [ci skip] --- html/changelogs/AutoChangeLog-pr-12261.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12261.yml diff --git a/html/changelogs/AutoChangeLog-pr-12261.yml b/html/changelogs/AutoChangeLog-pr-12261.yml new file mode 100644 index 00000000000..3fe8b5ab303 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12261.yml @@ -0,0 +1,4 @@ +author: "Terilia" +delete-after: True +changes: + - bugfix: "stat_attack from unconscious to dead" From bff1d203e6b26d0033a3632e8adecf4e36f538a1 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 21:54:42 -0400 Subject: [PATCH 28/41] Automatic changelog generation for PR #12259 [ci skip] --- html/changelogs/AutoChangeLog-pr-12259.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12259.yml diff --git a/html/changelogs/AutoChangeLog-pr-12259.yml b/html/changelogs/AutoChangeLog-pr-12259.yml new file mode 100644 index 00000000000..3c0eded2ca9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12259.yml @@ -0,0 +1,4 @@ +author: "Ty-Omaha" +delete-after: True +changes: + - rscdel: "Autonote for manual bans removed" From fda20578d1c5ff3b6c1eeb2191642064300869f4 Mon Sep 17 00:00:00 2001 From: Shadow Date: Tue, 10 Sep 2019 21:35:45 -0500 Subject: [PATCH 29/41] HUNGRY HUNGRY :boxen: --- code/modules/projectiles/guns/energy/special.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 4499fca3797..0e037f0a292 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -164,6 +164,9 @@ to_chat(user, "[src] is [round(power_supply.percent())]% charged.") /obj/item/gun/energy/plasmacutter/attackby(obj/item/A, mob/user) + if(power_supply.charge >= power_supply.maxcharge) + to_chat(user,"[src] is already fully charged.") + return if(istype(A, /obj/item/stack/sheet/mineral/plasma)) var/obj/item/stack/sheet/S = A S.use(1) From 960424903a24da7df444428cbf0d39880cc3d7e8 Mon Sep 17 00:00:00 2001 From: Shadow Date: Tue, 10 Sep 2019 21:51:15 -0500 Subject: [PATCH 30/41] :kappap: --- code/modules/projectiles/guns/energy/special.dm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 0e037f0a292..d51f9446b49 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -164,16 +164,19 @@ to_chat(user, "[src] is [round(power_supply.percent())]% charged.") /obj/item/gun/energy/plasmacutter/attackby(obj/item/A, mob/user) - if(power_supply.charge >= power_supply.maxcharge) - to_chat(user,"[src] is already fully charged.") - return if(istype(A, /obj/item/stack/sheet/mineral/plasma)) + if(power_supply.charge >= power_supply.maxcharge) + to_chat(user,"[src] is already fully charged.") + return var/obj/item/stack/sheet/S = A S.use(1) power_supply.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) + to_chat(user,"[src] is already fully charged.") + return var/obj/item/stack/ore/S = A S.use(1) power_supply.give(500) From cf6c7a67f7ed20e936cbe639218ca53af27d9f89 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Tue, 10 Sep 2019 23:03:18 -0400 Subject: [PATCH 31/41] Automatic changelog generation for PR #12262 [ci skip] --- html/changelogs/AutoChangeLog-pr-12262.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12262.yml diff --git a/html/changelogs/AutoChangeLog-pr-12262.yml b/html/changelogs/AutoChangeLog-pr-12262.yml new file mode 100644 index 00000000000..d3b197a72ea --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12262.yml @@ -0,0 +1,4 @@ +author: "Shadow-Quill" +delete-after: True +changes: + - bugfix: "Plasma cutters will no longer eat plasma if you try recharging a full gun." From 18b270cb7ec30cf09913c1aaa9813d67a81d9d75 Mon Sep 17 00:00:00 2001 From: variableundefined <40092670+variableundefined@users.noreply.github.com> Date: Wed, 11 Sep 2019 00:28:27 -0400 Subject: [PATCH 32/41] Remove the structure/chair/wood/normal subtype, moving all properties to its parent. --- _maps/map_files/Delta/delta.dmm | 62 +++++++++---------- .../MetaStation/MetaStation.v41A.II.dmm | 10 +-- .../RandomRuins/SpaceRuins/wizardcrash.dmm | 6 +- _maps/map_files/RandomZLevels/academy.dmm | 4 +- _maps/map_files/RandomZLevels/example.dmm | 8 +-- .../map_files/RandomZLevels/moonoutpost19.dmm | 6 +- .../map_files/RandomZLevels/terrorspiders.dmm | 34 +++++----- .../RandomZLevels/undergroundoutpost45.dmm | 18 +++--- _maps/map_files/RandomZLevels/wildwest.dmm | 20 +++--- _maps/map_files/cyberiad/cyberiad.dmm | 16 ++--- _maps/map_files/cyberiad/z6.dmm | 18 +++--- .../items/stacks/sheets/sheet_types.dm | 2 +- .../structures/stool_bed_chair_nest/chairs.dm | 10 +-- .../mining/lavaland/loot/colossus_loot.dm | 4 +- 14 files changed, 107 insertions(+), 111 deletions(-) diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm index 32348eb0027..b1e8f101202 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -22514,7 +22514,7 @@ }, /area/crew_quarters/bar/atrium) "aRy" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/carpet, /area/crew_quarters/bar/atrium) "aRz" = ( @@ -23422,7 +23422,7 @@ d2 = 8; icon_state = "1-8" }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/carpet, @@ -24305,7 +24305,7 @@ }, /area/crew_quarters/bar/atrium) "aUH" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 1 }, /turf/simulated/floor/carpet, @@ -89006,7 +89006,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/wood{ broken = 1; icon_state = "wood-broken" @@ -89016,12 +89016,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plating, /area/maintenance/gambling_den) "dcT" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ icon_state = "wood" }, @@ -90537,7 +90537,7 @@ /area/maintenance/gambling_den) "dfP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/wood{ @@ -91371,7 +91371,7 @@ }, /area/maintenance/gambling_den) "dhw" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -91380,7 +91380,7 @@ /area/maintenance/gambling_den) "dhx" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/plating, @@ -92327,7 +92327,7 @@ /turf/simulated/floor/plating, /area/maintenance/starboard) "diY" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/wood{ @@ -92346,7 +92346,7 @@ /area/maintenance/gambling_den) "dja" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/plasteel{ @@ -93121,7 +93121,7 @@ }, /area/maintenance/gambling_den) "dkr" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plating, @@ -94305,7 +94305,7 @@ /turf/simulated/floor/plasteel, /area/hallway/secondary/construction) "dmM" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plating, /area/maintenance/gambling_den) "dmN" = ( @@ -96153,7 +96153,7 @@ /turf/simulated/floor/plasteel, /area/crew_quarters/hor) "dpR" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 1 }, /turf/simulated/floor/plating, @@ -96848,7 +96848,7 @@ }, /area/maintenance/gambling_den) "dra" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/plating, @@ -101412,7 +101412,7 @@ }, /area/crew_quarters/theatre) "dzq" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -102176,7 +102176,7 @@ dir = 4; level = 1 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -102619,7 +102619,7 @@ }, /area/crew_quarters/theatre) "dBq" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -108948,21 +108948,21 @@ }, /area/chapel/office) "dMT" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "chapel" }, /area/chapel/main) "dMU" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ icon_state = "chapel" }, /area/chapel/main) "dMV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "chapel" @@ -108970,14 +108970,14 @@ /area/chapel/main) "dMW" = ( /obj/structure/disposalpipe/segment, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "chapel" }, /area/chapel/main) "dMX" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /obj/machinery/firealarm{ dir = 4; pixel_x = 28 @@ -109317,14 +109317,14 @@ }, /area/chapel/office) "dNJ" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "chapel" }, /area/chapel/main) "dNK" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "chapel" @@ -109332,7 +109332,7 @@ /area/chapel/main) "dNL" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "chapel" @@ -109340,7 +109340,7 @@ /area/chapel/main) "dNM" = ( /obj/structure/disposalpipe/segment, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "chapel" @@ -109692,7 +109692,7 @@ }, /area/chapel/office) "dOq" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /obj/machinery/light{ icon_state = "tube1"; dir = 8 @@ -109715,7 +109715,7 @@ }, /area/chapel/main) "dOt" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /obj/machinery/light{ icon_state = "tube1"; dir = 4 @@ -111770,7 +111770,7 @@ /area/chapel/office) "dSf" = ( /obj/machinery/light/small, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /obj/machinery/newscaster{ @@ -111783,7 +111783,7 @@ /area/chapel/main) "dSg" = ( /obj/machinery/light/small, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /obj/machinery/newscaster{ diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index f0c2f14698d..a14842c2007 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -13578,7 +13578,7 @@ /turf/simulated/floor/plating, /area/maintenance/fore) "aya" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/wood, /area/crew_quarters/mrchangs) "ayb" = ( @@ -14935,7 +14935,7 @@ name = "Port Maintenance" }) "aAB" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 1 }, /turf/simulated/floor/wood, @@ -14952,7 +14952,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 1 }, /turf/simulated/floor/wood, @@ -15652,7 +15652,7 @@ /turf/simulated/floor/wood, /area/crew_quarters/sleep) "aBS" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 1 }, /turf/simulated/floor/wood, @@ -21926,7 +21926,7 @@ name = "\improper Warehouse" }) "aMA" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/wood, diff --git a/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm b/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm index 67adb3e7467..fef87df8950 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm @@ -78,7 +78,7 @@ /obj/item/shard{ icon_state = "medium" }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/wood, @@ -128,7 +128,7 @@ /turf/simulated/floor/wood, /area/ruin/unpowered) "av" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/wood, @@ -201,7 +201,7 @@ /turf/simulated/floor/wood, /area/ruin/unpowered) "aH" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/carpet, diff --git a/_maps/map_files/RandomZLevels/academy.dmm b/_maps/map_files/RandomZLevels/academy.dmm index 2f37e69604e..87f3573eb00 100644 --- a/_maps/map_files/RandomZLevels/academy.dmm +++ b/_maps/map_files/RandomZLevels/academy.dmm @@ -1134,7 +1134,7 @@ /turf/simulated/floor/plasteel, /area/awaymission/academy/classrooms) "ds" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 1 }, /turf/simulated/floor/wood, @@ -2204,7 +2204,7 @@ }, /area/awaymission/academy/classrooms) "gb" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/wood, /area/awaymission/academy/classrooms) "gc" = ( diff --git a/_maps/map_files/RandomZLevels/example.dmm b/_maps/map_files/RandomZLevels/example.dmm index 779a0bede34..695005bada4 100644 --- a/_maps/map_files/RandomZLevels/example.dmm +++ b/_maps/map_files/RandomZLevels/example.dmm @@ -605,7 +605,7 @@ }, /area/awaymission/example) "bB" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ icon_state = "bar" }, @@ -670,7 +670,7 @@ }, /area/awaymission/example) "bJ" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (EAST)"; icon_state = "wooden_chair"; dir = 4 @@ -680,7 +680,7 @@ }, /area/awaymission/example) "bK" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (WEST)"; icon_state = "wooden_chair"; dir = 8 @@ -706,7 +706,7 @@ }, /area/awaymission/example) "bN" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (NORTH)"; icon_state = "wooden_chair"; dir = 1 diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm index fe5445dc8c3..8bbc6b2fead 100644 --- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm +++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm @@ -2195,7 +2195,7 @@ name = "Syndicate Outpost" }) "dh" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /obj/machinery/alarm/monitor{ dir = 4; frequency = 1439; @@ -7981,7 +7981,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /obj/machinery/alarm/monitor{ dir = 8; frequency = 1439; @@ -8717,7 +8717,7 @@ name = "MO19 Arrivals" }) "mB" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/carpet, diff --git a/_maps/map_files/RandomZLevels/terrorspiders.dmm b/_maps/map_files/RandomZLevels/terrorspiders.dmm index 143385681b3..e03bfab5397 100644 --- a/_maps/map_files/RandomZLevels/terrorspiders.dmm +++ b/_maps/map_files/RandomZLevels/terrorspiders.dmm @@ -224,7 +224,7 @@ }, /area/awaymission/UO71/plaza) "aH" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (NORTH)"; icon_state = "wooden_chair"; dir = 1 @@ -873,7 +873,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (EAST)"; icon_state = "wooden_chair"; dir = 4 @@ -921,7 +921,7 @@ on = 1; pressure_checks = 1 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (NORTH)"; icon_state = "wooden_chair"; dir = 1 @@ -2216,7 +2216,7 @@ on = 1; pressure_checks = 1 }, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/carpet, /area/awaymission/UO71/plaza) "eW" = ( @@ -6161,7 +6161,7 @@ pixel_y = 23; req_access = null }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /obj/item/paper/terrorspiders4, @@ -6479,7 +6479,7 @@ req_access_txt = "0"; specialfunctions = 4 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (NORTH)"; icon_state = "wooden_chair"; dir = 1 @@ -8632,7 +8632,7 @@ }, /area/awaymission/UO71/centralhall) "qL" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/carpet, /area/awaymission/UO71/centralhall) "qM" = ( @@ -9040,7 +9040,7 @@ /turf/simulated/floor/carpet, /area/awaymission/UO71/centralhall) "ru" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/carpet, @@ -12195,7 +12195,7 @@ /obj/machinery/light/small{ dir = 1 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/carpet, @@ -12540,7 +12540,7 @@ }, /area/awaymission/UO71/eng) "xF" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/carpet, /area/awaymission/UO71/mining) "xG" = ( @@ -13396,7 +13396,7 @@ /turf/simulated/floor/carpet, /area/awaymission/UO71/loot) "zt" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /obj/item/clothing/shoes/chameleon/noslip, /turf/simulated/floor/carpet, /area/awaymission/UO71/loot) @@ -13506,12 +13506,12 @@ /turf/simulated/floor/wood, /area/awaymission/UO71/queen) "zW" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/wood, /area/awaymission/UO71/queen) "zX" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (EAST)"; icon_state = "wooden_chair"; dir = 4 @@ -13523,7 +13523,7 @@ /turf/simulated/floor/wood, /area/awaymission/UO71/queen) "zZ" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (EAST)"; icon_state = "wooden_chair"; dir = 4 @@ -13531,7 +13531,7 @@ /turf/simulated/floor/wood, /area/awaymission/UO71/queen) "Aa" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/wood, @@ -13544,7 +13544,7 @@ /turf/simulated/floor/wood, /area/awaymission/UO71/queen) "Ac" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (NORTH)"; icon_state = "wooden_chair"; dir = 1 @@ -13568,7 +13568,7 @@ /turf/simulated/floor/wood, /area/awaymission/UO71/queen) "Ag" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /obj/machinery/light, diff --git a/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm b/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm index c5741039f2b..5d83a75af83 100644 --- a/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm @@ -1423,7 +1423,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (EAST)"; icon_state = "wooden_chair"; dir = 4 @@ -1491,7 +1491,7 @@ on = 1; pressure_checks = 1 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (NORTH)"; icon_state = "wooden_chair"; dir = 1 @@ -3362,7 +3362,7 @@ on = 1; pressure_checks = 1 }, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/carpet, /area/awaycontent/a1{ has_gravity = 1; @@ -8156,7 +8156,7 @@ pixel_y = 23; req_access = null }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/carpet, @@ -8519,7 +8519,7 @@ req_access_txt = "0"; specialfunctions = 4 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ tag = "icon-wooden_chair (NORTH)"; icon_state = "wooden_chair"; dir = 1 @@ -11135,7 +11135,7 @@ name = "UO45 Crew Quarters" }) "qt" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/carpet, /area/awaycontent/a2{ has_gravity = 1; @@ -11629,7 +11629,7 @@ name = "UO45 Crew Quarters" }) "ra" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/carpet, @@ -15331,7 +15331,7 @@ /obj/machinery/light/small{ dir = 1 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/carpet, @@ -15833,7 +15833,7 @@ name = "UO45 Engineering" }) "wN" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/carpet, /area/awaycontent/a4{ has_gravity = 1; diff --git a/_maps/map_files/RandomZLevels/wildwest.dmm b/_maps/map_files/RandomZLevels/wildwest.dmm index ca6d20a6eba..9d33f3a6efd 100644 --- a/_maps/map_files/RandomZLevels/wildwest.dmm +++ b/_maps/map_files/RandomZLevels/wildwest.dmm @@ -682,7 +682,7 @@ }, /area/awaymission/wwmines) "cc" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -704,7 +704,7 @@ }, /area/awaymission/wwmines) "ce" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/plasteel{ @@ -861,7 +861,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwgov) "cA" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/wood, @@ -995,13 +995,13 @@ /turf/simulated/floor/wood, /area/awaymission/wwmines) "cV" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/wood, /area/awaymission/wwmines) "cW" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/wood, @@ -2303,7 +2303,7 @@ /turf/simulated/wall/mineral/sandstone, /area/awaymission/wwmines) "gm" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -2312,7 +2312,7 @@ }, /area/awaymission/wwmines) "gn" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/plasteel{ @@ -2428,7 +2428,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwmines) "gD" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -2479,7 +2479,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwmines) "gL" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 1 }, /turf/simulated/floor/plasteel{ @@ -2528,7 +2528,7 @@ tag = "icon-gibup1"; icon_state = "gibup1" }, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index a83823e65dc..40efa820622 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -18897,7 +18897,7 @@ /obj/structure/sign/poster/contraband/random{ pixel_y = 32 }, -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plating, /area/maintenance/fpmaint) "aGk" = ( @@ -33468,7 +33468,7 @@ }, /area/hallway/primary/central/north) "biP" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/carpet, @@ -33483,7 +33483,7 @@ /turf/simulated/floor/carpet, /area/crew_quarters/mrchangs) "biR" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/carpet, @@ -79735,7 +79735,7 @@ /turf/simulated/floor/plasteel, /area/atmos/control) "cMb" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/wood{ @@ -79748,7 +79748,7 @@ /turf/simulated/floor/wood, /area/maintenance/asmaint) "cMd" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/carpet, @@ -83569,7 +83569,7 @@ /turf/simulated/floor/carpet, /area/crew_quarters/mrchangs) "cSX" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /obj/structure/cable{ d1 = 1; d2 = 2; @@ -84339,7 +84339,7 @@ /turf/simulated/floor/plating, /area/maintenance/aft) "cUi" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/carpet, /area/crew_quarters/mrchangs) "cUj" = ( @@ -91152,7 +91152,7 @@ name = "station intercom (General)"; pixel_y = -28 }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/wood, diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm index f47b299a8d7..0ee95c18491 100644 --- a/_maps/map_files/cyberiad/z6.dmm +++ b/_maps/map_files/cyberiad/z6.dmm @@ -3384,7 +3384,7 @@ /turf/simulated/floor/plating/airless, /area/space/nearstation) "hx" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/wood{ tag = "icon-wood-broken7"; icon_state = "wood-broken7" @@ -3946,7 +3946,7 @@ }, /area/derelict/crew_quarters) "ix" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/wood{ @@ -4279,7 +4279,7 @@ name = "Derelict Annex" }) "je" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -4296,7 +4296,7 @@ }, /area/derelict/arrival) "jg" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /obj/structure/sign/poster/contraband/random{ @@ -4370,7 +4370,7 @@ /turf/simulated/floor/plasteel, /area/derelict/crew_quarters) "jn" = ( -/obj/structure/chair/wood/normal, +/obj/structure/chair/wood, /turf/simulated/floor/plasteel{ icon_state = "wood" }, @@ -4613,7 +4613,7 @@ }, /area/derelict/crew_quarters) "jM" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 8 }, /turf/simulated/floor/plasteel{ @@ -7287,7 +7287,7 @@ d2 = 2; icon_state = "1-2" }, -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -7301,7 +7301,7 @@ }, /area/derelict/crew_quarters) "qo" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /turf/simulated/floor/plasteel{ @@ -8210,7 +8210,7 @@ name = "Derelict Annex" }) "sd" = ( -/obj/structure/chair/wood/normal{ +/obj/structure/chair/wood{ dir = 4 }, /obj/effect/decal/cleanable/dirt, diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index c98f3355538..27061500607 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -166,7 +166,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list( new /datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), new /datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), new /datum/stack_recipe("wood table frame", /obj/structure/table_frame/wood, 2, time = 10), \ - new /datum/stack_recipe("wooden chair", /obj/structure/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), + new /datum/stack_recipe("wooden chair", /obj/structure/chair/wood, 3, time = 10, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("bookcase", /obj/structure/bookcase, 5, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("dresser", /obj/structure/dresser, 30, time = 50, one_per_turf = 1, on_floor = 1), diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index c958096cc74..8192e39b85d 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -133,6 +133,9 @@ // Chair types /obj/structure/chair/wood + name = "wooden chair" + desc = "Old is never too old to not be in fashion." + icon_state = "wooden_chair" burn_state = FLAMMABLE burntime = 20 buildstackamount = 3 @@ -142,15 +145,8 @@ /obj/structure/chair/wood/narsie_act() return -/obj/structure/chair/wood/normal - icon_state = "wooden_chair" - name = "wooden chair" - desc = "Old is never too old to not be in fashion." - /obj/structure/chair/wood/wings icon_state = "wooden_chair_wings" - name = "wooden chair" - desc = "Old is never too old to not be in fashion." item_chair = /obj/item/chair/wood/wings /obj/structure/chair/comfy diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index 24210fc2ff0..fbe1067918a 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -213,13 +213,13 @@ if("winter") //Snow terrain is slow to move in and cold! Get the assistants to shovel your driveway. NewTerrainFloors = /turf/simulated/floor/snow // Needs to be updated after turf update NewTerrainWalls = /turf/simulated/wall/mineral/wood - NewTerrainChairs = /obj/structure/chair/wood/normal + NewTerrainChairs = /obj/structure/chair/wood NewTerrainTables = /obj/structure/table/glass NewFlora = list(/obj/structure/flora/grass/green, /obj/structure/flora/grass/brown, /obj/structure/flora/grass/both) if("jungle") //Beneficial due to actually having breathable air. Plus, monkeys and bows and arrows. NewTerrainFloors = /turf/simulated/floor/grass NewTerrainWalls = /turf/simulated/wall/mineral/sandstone - NewTerrainChairs = /obj/structure/chair/wood/normal + NewTerrainChairs = /obj/structure/chair/wood NewTerrainTables = /obj/structure/table/wood NewFlora = list(/obj/structure/flora/ausbushes/sparsegrass, /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/leafybush, /obj/structure/flora/ausbushes/grassybush, /obj/structure/flora/ausbushes/sunnybush, /obj/structure/flora/tree/palm, /mob/living/carbon/human/monkey, From 3489d4c3b25d943bea49d4541bf0ece14cf16e8d Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Wed, 11 Sep 2019 01:00:43 -0400 Subject: [PATCH 33/41] Automatic changelog generation for PR #12263 [ci skip] --- html/changelogs/AutoChangeLog-pr-12263.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12263.yml diff --git a/html/changelogs/AutoChangeLog-pr-12263.yml b/html/changelogs/AutoChangeLog-pr-12263.yml new file mode 100644 index 00000000000..c581f3ae316 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12263.yml @@ -0,0 +1,4 @@ +author: "variableundefined" +delete-after: True +changes: + - bugfix: "Refactored wooden chair so placing them won't make you see normal metallic chair anymore." From 92f3edf853253f517d9ccfdf17c33cd73f02028b Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Wed, 11 Sep 2019 01:20:30 -0400 Subject: [PATCH 34/41] tweaks to uplink --- code/datums/uplink_item.dm | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 73bc7437bce..75e37c3ca3d 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -1108,21 +1108,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 1 surplus = 35 -/datum/uplink_item/stealthy_tools/syndigaloshes - name = "No-Slip Chameleon Shoes" - desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \ - They do not work on heavily lubricated surfaces." - reference = "NSSS" - item = /obj/item/clothing/shoes/chameleon/noslip - cost = 2 - excludefrom = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_tools/syndigaloshes/nuke - reference = "TNSSS" - cost = 4 //but they aren't - excludefrom = list() - gamemodes = list(/datum/game_mode/nuclear) - /datum/uplink_item/stealthy_tools/chamsechud name = "Chameleon Security HUD" desc = "A stolen Nanotrasen Security HUD with Syndicate chameleon technology implemented into it. Similarly to a chameleon jumpsuit, the HUD can be morphed into various other eyewear, while retaining the HUD qualities when worn." @@ -1168,9 +1153,30 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) Due to budget cuts, the shoes don't provide protection against slipping. The set comes with a complementary chameleon stamp." reference = "CHAM" item = /obj/item/storage/box/syndie_kit/chameleon + cost = 4 + excludefrom = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_tools/chameleon/nuke + reference = "NCHAM" + cost = 6 + excludefrom = list() + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_tools/syndigaloshes + name = "No-Slip Chameleon Shoes" + desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \ + They do not work on heavily lubricated surfaces." + reference = "NSSS" + item = /obj/item/clothing/shoes/chameleon/noslip cost = 2 excludefrom = list(/datum/game_mode/nuclear) +/datum/uplink_item/stealthy_tools/syndigaloshes/nuke + reference = "NNSSS" + cost = 4 + excludefrom = list() + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/stealthy_tools/chameleon_proj name = "Chameleon-Projector" desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't move the projector from their hand. The disguised user cannot run and projectiles pass over them." From a5027332e1a1d37cc17a6a5621c4d41b892fb9ce Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Wed, 11 Sep 2019 01:28:57 -0400 Subject: [PATCH 35/41] Automatic changelog generation for PR #12250 [ci skip] --- html/changelogs/AutoChangeLog-pr-12250.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12250.yml diff --git a/html/changelogs/AutoChangeLog-pr-12250.yml b/html/changelogs/AutoChangeLog-pr-12250.yml new file mode 100644 index 00000000000..d3c7fd77e68 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12250.yml @@ -0,0 +1,21 @@ +author: "Fox McCloud" +delete-after: True +changes: + - rscdel: "Nuke ops can no longer advanced syndie magboots" + - bugfix: "Fixes an inconsistency with chameleon kit pricing--it was only 2 TC, making the no slip syndicate shoes worthless; price is now 4 TC" + - tweak: "operatives pay 2 TC more for the no slip syndicate shoes and the chameleon kit" + - rscdel: "Wizard hardsuits no longer come with magboots" + - tweak: "Syndie magboots are nuke ops only" + - tweak: "Can purchase no slip shoes from the uplink instead of a full chameleon kit" + - tweak: "Operatives can purchase no slip syndicate shoes" + - tweak: "No slip shoes can protect against atmos pushing" + - rscdel: "removed most round-start magboots with the exception of EVA, atmostechs, CE, and engineering hardsuit dispensers" + - bugfix: "Fixes carp not being a threat to the station due to killing themselves" + - bugfix: "Fixes being able to exploit simple mob AI so it kills itself in an atmos death blender" + - tweak: "vent and scrubbers work far more efficiently and quickly now" + - bugfix: "Fixes wideband on scrubbers constantly resetting itself" + - tweak: "Portable scrubbers far more effective" + - tweak: "Flamethrowers far more effective" + - tweak: "Nanofrost twice as expensive" + - tweak: "regular syndicate borgs don't have magpulse by default" + - tweak: "Atmos pushing completely refactored; it'll still push you frequently and push items around frequently, but it won't throw you. Depending on how many dense objects or turfs are around you to \"grab onto\" will determine how effective atmos is at pushing you around. Does not alter the speed at which LINDA runs." From 86eb450c567ccef9743e7207ff681b33d9d0619a Mon Sep 17 00:00:00 2001 From: TDSSS <32099540+TDSSS@users.noreply.github.com> Date: Wed, 11 Sep 2019 07:48:45 +0200 Subject: [PATCH 36/41] Fix really silly mistake --- code/modules/reagents/chemistry/reagents/medicine.dm | 1 + code/modules/ruins/lavalandruin_code/fountain_hall.dm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 09ee8cb3948..0f8c5e42dab 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -292,6 +292,7 @@ /datum/reagent/medicine/omnizine/godblood name = "Godblood" + id = "godblood" description = "Slowly heals all damage types. Has a rather high overdose threshold. Glows with mysterious power." overdose_threshold = 150 diff --git a/code/modules/ruins/lavalandruin_code/fountain_hall.dm b/code/modules/ruins/lavalandruin_code/fountain_hall.dm index 917ea4e4bd0..5a232286558 100644 --- a/code/modules/ruins/lavalandruin_code/fountain_hall.dm +++ b/code/modules/ruins/lavalandruin_code/fountain_hall.dm @@ -38,7 +38,7 @@ return last_process = world.time to_chat(user, "The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.") - user.reagents.add_reagent(/datum/reagent/medicine/omnizine/godblood, 20) + user.reagents.add_reagent("godblood", 20) //why is add_reagent so stupid ?!? update_icon() addtimer(CALLBACK(src, .proc/update_icon), time_between_uses) From f02cbc4e60ae5a3dcd50ba2110ee2bf111a6b0f8 Mon Sep 17 00:00:00 2001 From: TDSSS <32099540+TDSSS@users.noreply.github.com> Date: Wed, 11 Sep 2019 12:05:47 +0200 Subject: [PATCH 37/41] [Comment redacted] --- code/modules/reagents/chemistry/reagents/medicine.dm | 12 ++++++------ .../modules/ruins/lavalandruin_code/fountain_hall.dm | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 0f8c5e42dab..b379386801d 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -290,12 +290,6 @@ addiction_chance = 5 taste_description = "health" -/datum/reagent/medicine/omnizine/godblood - name = "Godblood" - id = "godblood" - description = "Slowly heals all damage types. Has a rather high overdose threshold. Glows with mysterious power." - overdose_threshold = 150 - /datum/reagent/medicine/omnizine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE update_flags |= M.adjustToxLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) @@ -963,6 +957,12 @@ metabolization_rate = 0.1 taste_description = "faint hope" +/datum/reagent/medicine/omnizine_diluted/godblood + name = "Godblood" + id = "godblood" + description = "Slowly heals all damage types. Has a rather high overdose threshold. Glows with mysterious power." + overdose_threshold = 150 + /datum/reagent/medicine/omnizine_diluted/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE update_flags |= M.adjustToxLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) diff --git a/code/modules/ruins/lavalandruin_code/fountain_hall.dm b/code/modules/ruins/lavalandruin_code/fountain_hall.dm index 5a232286558..3de758ac0c9 100644 --- a/code/modules/ruins/lavalandruin_code/fountain_hall.dm +++ b/code/modules/ruins/lavalandruin_code/fountain_hall.dm @@ -38,7 +38,7 @@ return last_process = world.time to_chat(user, "The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.") - user.reagents.add_reagent("godblood", 20) //why is add_reagent so stupid ?!? + user.reagents.add_reagent("godblood", 20) update_icon() addtimer(CALLBACK(src, .proc/update_icon), time_between_uses) From 2529ebfdea6468d0f06d40c2eecff0f609d0e3d6 Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Wed, 11 Sep 2019 06:38:53 -0400 Subject: [PATCH 38/41] Automatic changelog generation for PR #12265 [ci skip] --- html/changelogs/AutoChangeLog-pr-12265.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12265.yml diff --git a/html/changelogs/AutoChangeLog-pr-12265.yml b/html/changelogs/AutoChangeLog-pr-12265.yml new file mode 100644 index 00000000000..1abb27cad08 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12265.yml @@ -0,0 +1,4 @@ +author: "TDSSS" +delete-after: True +changes: + - bugfix: "healing fountain lavaland ruin now correctly heals" From d6a475de5b5ba99c3c4dec8cc52e7609effdb4dd Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Wed, 11 Sep 2019 10:10:20 -0400 Subject: [PATCH 39/41] Automatic changelog generation for PR #12255 [ci skip] --- html/changelogs/AutoChangeLog-pr-12255.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12255.yml diff --git a/html/changelogs/AutoChangeLog-pr-12255.yml b/html/changelogs/AutoChangeLog-pr-12255.yml new file mode 100644 index 00000000000..a320bb2b102 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12255.yml @@ -0,0 +1,7 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Plasma glass shards do less damage when attacking, but slightly more when stepping on them" + - tweak: "Spears made out of plasma glass do slightly more damage" + - tweak: "Light replacer can now be used in-hand to attempt to reload empty lighting fixtures around you in addition to showing how many lights it has" + - tweak: "Light replacer needs less shards to increment bulbs" From 7778c91c45cf0b97645c517dde875e89da7a5cca Mon Sep 17 00:00:00 2001 From: Kyep Date: Wed, 11 Sep 2019 16:13:35 -0700 Subject: [PATCH 40/41] semi-mirror TG PR 46425 --- code/__DEFINES/admin.dm | 9 ++++- code/modules/client/client defines.dm | 5 +++ code/modules/keybindings/bindings_client.dm | 45 ++++++++++++++++++++- code/modules/keybindings/setup.dm | 20 ++++++--- 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 3877ac213c5..65f4da2b50a 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -63,4 +63,11 @@ #define AREACOORD(src) "[src ? "[get_area_name(src, TRUE)] [COORD(src)]" : "nonexistent location" ]" #define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" #define ADMIN_VERBOSEJMP(src) "[src ? "[AREACOORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" -#define ADMIN_SHOWDETAILS(mask, content) "[mask]" \ No newline at end of file +#define ADMIN_SHOWDETAILS(mask, content) "[mask]" + +///Max length of a keypress command before it's considered to be a forged packet/bogus command +#define MAX_KEYPRESS_COMMANDLENGTH 16 +///Max amount of keypress messages per second over two seconds before client is autokicked +#define MAX_KEYPRESS_AUTOKICK 50 +///Length of held key rolling buffer +#define HELD_KEY_BUFFER_LENGTH 15 \ No newline at end of file diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 22325fed75f..0feca103c12 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -95,3 +95,8 @@ // Has the client been varedited by an admin? [Inherits from datum now] // var/var_edited = FALSE + + var/client_keysend_amount = 0 + var/next_keysend_reset = 0 + var/next_keysend_trip_reset = 0 + var/keysend_tripped = FALSE \ No newline at end of file diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index e3925aa5283..d59e3da4e8e 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -3,7 +3,46 @@ /client/verb/keyDown(_key as text) set instant = TRUE set hidden = TRUE + + client_keysend_amount += 1 + + var/cache = client_keysend_amount + + if(keysend_tripped && next_keysend_trip_reset <= world.time) + keysend_tripped = FALSE + + if(next_keysend_reset <= world.time) + client_keysend_amount = 0 + next_keysend_reset = world.time + (1 SECONDS) + + //The "tripped" system is to confirm that flooding is still happening after one spike + //not entirely sure how byond commands interact in relation to lag + //don't want to kick people if a lag spike results in a huge flood of commands being sent + if(cache >= MAX_KEYPRESS_AUTOKICK) + if(!keysend_tripped) + keysend_tripped = TRUE + next_keysend_trip_reset = world.time + (2 SECONDS) + 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) + return + + ///Check if the key is short enough to even be a real key + if(LAZYLEN(_key) > MAX_KEYPRESS_COMMANDLENGTH) + 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) + return + //offset by 1 because the buffer address is 0 indexed because the math was simpler + keys_held[current_key_address + 1] = _key + //the time a key was pressed isn't actually used anywhere (as of 2019-9-10) but this allows easier access usage/checking + keys_held[_key] = world.time + + current_key_address = ((current_key_address + 1) % HELD_KEY_BUFFER_LENGTH) + var/movement = SSinput.movement_keys[_key] if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key] if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"]) @@ -40,7 +79,11 @@ /client/verb/keyUp(_key as text) set instant = TRUE set hidden = TRUE - keys_held -= _key + //Can't just do a remove because it would alter the length of the rolling buffer, instead search for the key then null it out if it exists + for(var/i in 1 to HELD_KEY_BUFFER_LENGTH) + if(keys_held[i] == _key) + keys_held[i] = null + break var/movement = SSinput.movement_keys[_key] if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key] if(!(next_move_dir_add & movement)) diff --git a/code/modules/keybindings/setup.dm b/code/modules/keybindings/setup.dm index cc76256386e..b6e80452304 100644 --- a/code/modules/keybindings/setup.dm +++ b/code/modules/keybindings/setup.dm @@ -1,9 +1,14 @@ /client - var/list/keys_held = list() // A list of any keys held currently - // These next two vars are to apply movement for keypresses and releases made while move delayed. - // Because discarding that input makes the game less responsive. - var/next_move_dir_add // On next move, add this dir to the move that would otherwise be done - var/next_move_dir_sub // On next move, subtract this dir from the move that would otherwise be done + /// A rolling buffer of any keys held currently + var/list/keys_held = list() + ///used to keep track of the current rolling buffer position + var/current_key_address = 0 + /// These next two vars are to apply movement for keypresses and releases made while move delayed. + /// Because discarding that input makes the game less responsive. + /// On next move, add this dir to the move that would otherwise be done + var/next_move_dir_add + /// On next move, subtract this dir from the move that would otherwise be done + var/next_move_dir_sub // Set a client's focus to an object and override these procs on that object to let it handle keypresses @@ -31,6 +36,11 @@ /client/proc/set_macros() set waitfor = FALSE + //Reset and populate the rolling buffer + keys_held.Cut() + for(var/i in 1 to HELD_KEY_BUFFER_LENGTH) + keys_held += null + erase_all_macros() var/list/macro_sets = SSinput.macro_sets From 4867e8d6b7ca4c3d542be0b8a38170156751df2e Mon Sep 17 00:00:00 2001 From: ParadiseSS13-Bot Date: Wed, 11 Sep 2019 19:25:26 -0400 Subject: [PATCH 41/41] Automatic changelog generation for PR #12276 [ci skip] --- html/changelogs/AutoChangeLog-pr-12276.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-12276.yml diff --git a/html/changelogs/AutoChangeLog-pr-12276.yml b/html/changelogs/AutoChangeLog-pr-12276.yml new file mode 100644 index 00000000000..731eb403af1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12276.yml @@ -0,0 +1,4 @@ +author: "Kyep" +delete-after: True +changes: + - bugfix: "fixed an issue with keyboard input"