diff --git a/SQL/migrate/V023__Tickets_nullable_taker.sql b/SQL/migrate/V023__Tickets_nullable_taker.sql new file mode 100644 index 00000000000..13cc789a072 --- /dev/null +++ b/SQL/migrate/V023__Tickets_nullable_taker.sql @@ -0,0 +1,6 @@ +-- +-- Fixes a bug by allowing the "Taken by" admin to be null. +-- + +ALTER TABLE `ss13_tickets` + MODIFY `taken_by` VARCHAR(32) NULL DEFAULT NULL; diff --git a/SQL/migrate/V024__poll_links.sql b/SQL/migrate/V024__poll_links.sql new file mode 100644 index 00000000000..0225e44133a --- /dev/null +++ b/SQL/migrate/V024__poll_links.sql @@ -0,0 +1,6 @@ +-- +-- Allows to add a link to the poll +-- + +ALTER TABLE `ss13_poll_question` + ADD COLUMN `link` VARCHAR(250) NULL DEFAULT NULL AFTER `createdby_ip`; diff --git a/code/game/machinery/crusher_piston.dm b/code/game/machinery/crusher_piston.dm index 95b9cc43068..0f82f6d453c 100644 --- a/code/game/machinery/crusher_piston.dm +++ b/code/game/machinery/crusher_piston.dm @@ -75,14 +75,14 @@ var/oldloc = loc var/obj/machinery/crusher_base/left = locate(/obj/machinery/crusher_base, get_step(src, WEST)) var/obj/machinery/crusher_base/right = locate(/obj/machinery/crusher_base, get_step(src, EAST)) - + loc=null if(left) left.update_icon() if(right) right.update_icon() loc=oldloc - + QDEL_NULL(pstn) return ..() @@ -100,7 +100,7 @@ return if(default_part_replacement(user, O)) return - + //Stuff you can do if the maint hatch is open if(panel_open) if(iswrench(O)) @@ -138,7 +138,7 @@ if(QDELETED(left)) left = null - + if(QDELETED(right)) right = null @@ -164,7 +164,7 @@ holographic_overlay(src, icon, "[asmtype]-overlay-green") if(panel_open) add_overlay("[asmtype]-hatch") - update_above() + update_above() /obj/machinery/crusher_base/power_change() ..() @@ -214,7 +214,7 @@ status = "stage1" action_start_time = world.time initial = 1 - + //Extend the second piston else if(status == "stage1") if(valve_check()) @@ -248,7 +248,7 @@ status = "stage3" action_start_time = world.time initial = 1 - + //Wait a moment, then reverse the direction else if(status == "stage3") if(initial) @@ -308,7 +308,7 @@ action_start_time = world.time initial = 1 update_icon() - + //Move all the items in the move list for(var/atom/movable/AM in items_to_move) if(!AM.simulated) @@ -322,7 +322,7 @@ if(!AM.piston_move()) items_to_crush += AM CHECK_TICK - + //Destroy all the items in the crush list for(var/atom/movable/AM in items_to_crush) items_to_crush -= AM @@ -366,7 +366,7 @@ name = "trash compactor piston" desc = "A colossal piston used for crushing garbage." icon = 'icons/obj/machines/crusherpiston.dmi' //Placeholder TODO: Get a proper icon - icon_state = "piston_0" + icon_state = "piston_0" density = 0 anchored = 1 pixel_y = -64 @@ -513,6 +513,8 @@ // The crush act proc // /atom/movable/proc/crush_act() + if(!simulated) + return ex_act(1) if(!QDELETED(src)) qdel(src)//Just as a failsafe diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm index 99317004992..d4f83e4a7e7 100644 --- a/code/game/objects/items/weapons/material/twohanded.dm +++ b/code/game/objects/items/weapons/material/twohanded.dm @@ -317,6 +317,7 @@ base_icon = "chainsaw_off" flags = CONDUCT force = 10 + force_unwielded = 10 force_wielded = 20 throwforce = 5 w_class = ITEMSIZE_LARGE @@ -361,8 +362,9 @@ var/turf/T = get_turf(src) T.audible_message(span("notice", "\The [src] rumbles to life.")) playsound(src, "sound/weapons/chainsawstart.ogg", 25, 0, 30) - force = 20 - force_wielded = 40 + force = 15 + force_unwielded = 30 + force_wielded = 60 throwforce = 20 icon_state = "chainsaw_on" base_icon = "chainsaw_on" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index f5ce9bacc24..5ec2c2a26d0 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -182,7 +182,6 @@ update_icon() return 1 -// this should probably use dump_contents() /obj/structure/closet/ex_act(severity) switch(severity) if(1) @@ -194,15 +193,16 @@ if (health <= 0) for (var/atom/movable/A as mob|obj in src) - A.forceMove(loc) A.ex_act(severity + 1) + dump_contents() + new /obj/item/stack/material/steel(get_turf(src)) qdel(src) /obj/structure/closet/proc/damage(var/damage) health -= damage if(health <= 0) - for(var/atom/movable/A in src) - A.forceMove(loc) + dump_contents() + new /obj/item/stack/material/steel(get_turf(src)) qdel(src) /obj/structure/closet/bullet_act(var/obj/item/projectile/Proj) @@ -452,3 +452,14 @@ /obj/structure/closet/onDropInto(var/atom/movable/AM) return + +/obj/structure/closet/crush_act() + for (var/atom/movable/A in src) + if(istype(A, /mob/living)) + var/mob/living/M = A + M.gib() + else if(A.simulated) + A.ex_act(1) + dump_contents() + new /obj/item/stack/material/steel(get_turf(src)) + qdel(src) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index ea0d4fc66b9..b79518a17b3 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -134,6 +134,7 @@ density = 0 anchored = 1 use_power = 0 + var/spray_amount = 20 var/on = 0 var/obj/effect/mist/mymist = null var/ismist = 0 //needs a var so we can make it linger~ @@ -221,10 +222,10 @@ /obj/machinery/shower/proc/wash(atom/movable/O as obj|mob) if(!on) return - if(isliving(O)) - var/mob/living/L = O - L.ExtinguishMob() - L.fire_stacks = -20 //Douse ourselves with water to avoid fire more easily + var/obj/effect/effect/water/W = new(O) + W.create_reagents(spray_amount) + W.reagents.add_reagent("water", spray_amount) + W.set_up(O, spray_amount) if(iscarbon(O)) var/mob/living/carbon/M = O @@ -326,6 +327,7 @@ wash_floor() if(!mobpresent) return for(var/mob/living/L in loc) + wash(L) // Why was it not here before? process_heat(L) /obj/machinery/shower/proc/wash_floor() diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm index ef5afab1fcf..c07a0c9cb47 100644 --- a/code/game/turfs/simulated/water.dm +++ b/code/game/turfs/simulated/water.dm @@ -23,6 +23,7 @@ movement_cost = 2 var/watertype = "water5" var/obj/effect/water_effect/water_overlay + var/numobjects = 0 /turf/simulated/floor/beach/water/pool name = "pool" @@ -56,6 +57,7 @@ var/obj/effect/water_effect/W = new /obj/effect/water_effect(src) W.icon_state = watertype water_overlay = W + create_reagents(2) /turf/simulated/floor/beach/water/Destroy() if(water_overlay) @@ -86,20 +88,44 @@ return return_air() // Otherwise their head is above the water, so get the air from the atmosphere instead. /turf/simulated/floor/beach/water/Entered(atom/movable/AM, atom/oldloc) - if(istype(AM, /mob/living)) + if(!SSATOMS_IS_PROBABLY_DONE) + return + reagents.add_reagent("water", 2) + clean(src) + START_PROCESSING(SSprocessing, src) + if(istype(AM, /obj)) + numobjects += 1 + else if(istype(AM, /mob/living)) + numobjects += 1 var/mob/living/L = AM if(!istype(oldloc, /turf/simulated/floor/beach/water)) to_chat(L, "You get drenched in water from entering \the [src]!") - AM.water_act(5) + wash(L) ..() /turf/simulated/floor/beach/water/Exited(atom/movable/AM, atom/newloc) - if(istype(AM, /mob/living)) + if(!SSATOMS_IS_PROBABLY_DONE) + return + reagents.add_reagent("water", 2) + clean(src) + if(istype(AM, /obj) && numobjects) + numobjects -= 1 + else if(istype(AM, /mob/living)) + if(numobjects) + numobjects -= 1 var/mob/living/L = AM if(!istype(newloc, /turf/simulated/floor/beach/water)) to_chat(L, "You climb out of \the [src].") ..() +/turf/simulated/floor/beach/water/process() + reagents.add_reagent("water", 2) + clean(src) + for(var/mob/living/L in src) + wash(L) + if(!numobjects) + STOP_PROCESSING(SSprocessing, src) + /mob/living/proc/can_breathe_water() return FALSE @@ -108,11 +134,105 @@ return species.can_breathe_water() return ..() -// Use this to have things react to having water applied to them. -/atom/movable/proc/water_act(amount) - return +// Taken from shower +/turf/simulated/floor/beach/water/proc/wash(atom/movable/O as obj|mob) -/mob/living/water_act(amount) - adjust_fire_stacks(-amount * 5) - for(var/atom/movable/AM in contents) - AM.water_act(amount) \ No newline at end of file + var/obj/effect/effect/water/W = new(O) + W.create_reagents(100) + W.reagents.add_reagent("water", 100) + W.set_up(O, 100) + + if(iscarbon(O)) + var/mob/living/carbon/M = O + if(M.r_hand) + M.r_hand.clean_blood() + if(M.l_hand) + M.l_hand.clean_blood() + if(M.back) + if(M.back.clean_blood()) + M.update_inv_back(0) + + //flush away reagents on the skin + if(M.touching) + var/remove_amount = M.touching.maximum_volume * M.reagent_permeability() //take off your suit first + M.touching.remove_any(remove_amount) + + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/washgloves = 1 + var/washshoes = 1 + var/washmask = 1 + var/washears = 1 + var/washglasses = 1 + + if(H.wear_suit) + washgloves = !(H.wear_suit.flags_inv & HIDEGLOVES) + washshoes = !(H.wear_suit.flags_inv & HIDESHOES) + + if(H.head) + washmask = !(H.head.flags_inv & HIDEMASK) + washglasses = !(H.head.flags_inv & HIDEEYES) + washears = !(H.head.flags_inv & HIDEEARS) + + if(H.wear_mask) + if (washears) + washears = !(H.wear_mask.flags_inv & HIDEEARS) + if (washglasses) + washglasses = !(H.wear_mask.flags_inv & HIDEEYES) + + if(H.head) + if(H.head.clean_blood()) + H.update_inv_head(0) + if(H.wear_suit) + if(H.wear_suit.clean_blood()) + H.update_inv_wear_suit(0) + else if(H.w_uniform) + if(H.w_uniform.clean_blood()) + H.update_inv_w_uniform(0) + if(H.gloves && washgloves) + if(H.gloves.clean_blood()) + H.update_inv_gloves(0) + if(H.shoes && washshoes) + if(H.shoes.clean_blood()) + H.update_inv_shoes(0) + if(H.wear_mask && washmask) + if(H.wear_mask.clean_blood()) + H.update_inv_wear_mask(0) + if(H.glasses && washglasses) + if(H.glasses.clean_blood()) + H.update_inv_glasses(0) + if(H.l_ear && washears) + if(H.l_ear.clean_blood()) + H.update_inv_ears(0) + if(H.r_ear && washears) + if(H.r_ear.clean_blood()) + H.update_inv_ears(0) + if(H.belt) + if(H.belt.clean_blood()) + H.update_inv_belt(0) + H.clean_blood(washshoes) + else + if(M.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags + if(M.wear_mask.clean_blood()) + M.update_inv_wear_mask(0) + M.clean_blood() + else + O.clean_blood() + + if(istype(O, /obj/item/weapon/light)) + var/obj/item/weapon/light/L = O + L.brightness_color = initial(L.brightness_color) + L.update() + else if(istype(O, /obj/machinery/light)) + var/obj/machinery/light/L = O + L.brightness_color = initial(L.brightness_color) + L.update() + + O.color = initial(O.color) + + if(isturf(loc)) + var/turf/tile = loc + loc.clean_blood() + for(var/obj/effect/E in tile) + if(istype(E,/obj/effect/rune) || istype(E,/obj/effect/decal/cleanable) || istype(E,/obj/effect/overlay)) + qdel(E) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 698393e9424..4c5e8f5ebc2 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -99,8 +99,7 @@ var/list/admin_verbs_admin = list( /client/proc/clear_toxins, /client/proc/wipe_ai, // allow admins to force-wipe AIs /client/proc/fix_player_list, - /client/proc/reset_openturf, - /client/proc/create_poll //Allows to create polls + /client/proc/reset_openturf ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -371,7 +370,8 @@ var/list/admin_verbs_dev = list( //will need to be altered - Ryan784 /client/proc/cmd_dev_bst, /client/proc/lighting_show_verbs, /client/proc/cmd_display_del_log, - /client/proc/cmd_display_init_log + /client/proc/cmd_display_init_log, + /client/proc/create_poll //Allows to create polls ) var/list/admin_verbs_cciaa = list( /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ diff --git a/code/modules/admin/create_poll.dm b/code/modules/admin/create_poll.dm index 0d0d123e12c..cb8d78969a3 100644 --- a/code/modules/admin/create_poll.dm +++ b/code/modules/admin/create_poll.dm @@ -2,7 +2,7 @@ set category = "Special Verbs" set name = "Create Poll" - if(!check_rights(R_ADMIN|R_DEV)) + if(!check_rights(R_DEV)) return if(!establish_db_connection(dbcon)) to_chat(src,"Failed to establish database connection.") @@ -60,13 +60,20 @@ viewtoken = "'[sanitizeSQL(viewtoken)]'" else viewtoken = "NULL" + + var/link = null + link = input("Do you want to provide a link to get more information?","Link") as text + if(link) + link = "'[sanitizeSQL(link)]'" + else + link = "NULL" var/sql_ckey = sanitizeSQL(ckey) var/question = input("Write your question","Question") as message if(!question) return question = sanitizeSQL(question) - var/DBQuery/query_polladd_question = dbcon.NewQuery("INSERT INTO ss13_poll_question (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip, publicresult, viewtoken) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]', '[publicresult]', [viewtoken])") + var/DBQuery/query_polladd_question = dbcon.NewQuery("INSERT INTO ss13_poll_question (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip, publicresult, viewtoken, link) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]', '[publicresult]', [viewtoken], [link])") if(!query_polladd_question.Execute()) var/err = query_polladd_question.ErrorMsg() to_chat(src,"SQL ERROR adding new poll question to table. Error : \[[err]\]\n") diff --git a/code/modules/admin/ticket.dm b/code/modules/admin/ticket.dm index 17dee02e3de..4a57da7bb2c 100644 --- a/code/modules/admin/ticket.dm +++ b/code/modules/admin/ticket.dm @@ -135,14 +135,30 @@ var/global/list/ticket_panels = list() if (!establish_db_connection(dbcon)) return - var/DBQuery/Q = dbcon.NewQuery("INSERT INTO ss13_tickets (game_id, message_count, admin_count, admin_list, opened_by, taken_by, closed_by, response_delay, opened_at, closed_at) VALUES (:g_id:, :m_count:, :a_count:, :a_list:, :opened_by:, :taken_by, :closed_by:, :delay:, :opened_at:, :closed_at:)") - Q.Execute(list("g_id" = game_id, "m_count" = length(msgs), "a_count" = length(assigned_admins), "a_list" = json_encode(assigned_admins), "opened_by" = owner, "taken_by" = assigned_admins[0], "closed_by" = closed_by, "delay" = response_time, "opened_at" = SQLtime(opened_rt), "closed_at" = SQLtime(closed_rt))) + var/DBQuery/Q = dbcon.NewQuery({"INSERT INTO ss13_tickets + (game_id, message_count, admin_count, admin_list, opened_by, taken_by, + closed_by, response_delay, opened_at, closed_at) + VALUES + (:g_id:, :m_count:, :a_count:, :a_list:, :opened_by:, :taken_by:, + :closed_by:, :delay:, :opened_at:, :closed_at:)"}) + Q.Execute(list( + "g_id" = game_id, + "m_count" = length(msgs), + "a_count" = length(assigned_admins), + "a_list" = json_encode(assigned_admins), + "opened_by" = owner, + "taken_by" = length(assigned_admins) ? assigned_admins[1] : null, + "closed_by" = closed_by, + "delay" = response_time || -1, + "opened_at" = SQLtime(opened_rt), + "closed_at" = SQLtime(closed_rt) + )) /datum/ticket/proc/append_message(m_from, m_to, msg) msgs += new /datum/ticket_msg(m_from, m_to, msg) if (!response_time && m_from != owner) - response_time = round((world.time - opened_time) SECONDS) + response_time = round((world.time - opened_time) / 10) update_ticket_panels() diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 848a36523f9..f774e356b09 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -1936,4 +1936,107 @@ obj/item/clothing/suit/storage/hooded/fluff/make_poncho //Raincoat Poncho - M.A. icon = 'icons/obj/custom_items/fakhr_items.dmi' icon_state = "fakhr_hat" item_state = "fakhr_hat" - contained_sprite = TRUE \ No newline at end of file + contained_sprite = TRUE + + +/obj/item/fluff/daliyah_visa //NanoTrasen Exchange Visa - Daliyah Veridan - xanderdox + name = "NanoTrasen exchange visa" + desc = "A work visa authorizing the holder, Daliyah Veridan, to work within the Republic of Biesel. An Eridani and NanoTrasen logo are embossed on the back." + icon = 'icons/obj/custom_items/daliyah_visa.dmi' + icon_state = "daliyah_visa" + w_class = 2 + + +/obj/item/weapon/retractor/fluff/tristen_retractor //Laser Retractor - Tristen Wolff - elianabeth + name = "laser retractor" + desc = "The fabled laser retractor. It's a horrible amalgamation of a laser pointer, a retractor, and lots of tape." + icon = 'icons/obj/custom_items/tristen_retractor.dmi' + icon_state = "tristen_retractor" + + +/obj/item/fluff/amy_player //Music player - Amy Heris - golle + name = "music player" + desc = "An olive green HF24 in pristine condition, there is a small engraving on the back, reading \"To Amy, I will always be here for you, Varan.\"" + icon = 'icons/obj/custom_items/amy_player.dmi' + icon_state = "amy_player_off" + item_state = "electornic" + w_class = 2 + slot_flags = SLOT_BELT + var/broken = FALSE + var/open = FALSE + var/on = FALSE + var/obj/item/clothing/ears/earmuffs/earbuds + +/obj/item/fluff/amy_player/Initialize() + . = ..() + earbuds = new(src) + +/obj/item/fluff/amy_player/Destroy() + QDEL_NULL(earbuds) + return ..() + +/obj/item/fluff/amy_player/update_icon() + if(broken) + icon_state = "amy_player_broken" + return + if(on) + icon_state = "amy_player_on" + else + icon_state = "amy_player_off" + +/obj/item/fluff/amy_player/attack_self(mob/user as mob) + if(broken) + to_chat(user, "The screen flickers and blinks with errors.") + return + + if(!on) + to_chat(user, "You turn on \the [src].") + on = TRUE + + else + to_chat(user, "You turn off \the [src].") + on = FALSE + + update_icon() + + +/obj/item/fluff/amy_player/attack_hand(var/mob/user) + if(earbuds && src.loc == user) + earbuds.forceMove(user.loc) + user.put_in_hands(earbuds) + earbuds = null + update_icon() + return + + return ..() + +/obj/item/fluff/amy_player/attackby(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/clothing/ears/earmuffs) && !earbuds) + user.unEquip(I) + I.forceMove(src) + earbuds = I + to_chat(user, "You place \the [I] in \the [src].") + return + + if(broken) + if(isscrewdriver(I)) + if(!open) + open = TRUE + to_chat(user, "You unfasten the back panel.") + + else + open = FALSE + to_chat(user, "You secure the back panel.") + playsound(user.loc, 'sound/items/Screwdriver.ogg', 50, 1) + + if(ismultitool(I) && open) + to_chat(user, "You quickly pulse a few fires, and reset the screen and device.") + broken = FALSE + update_icon() + +/obj/item/fluff/amy_player/emp_act(severity) + broken = TRUE + on = FALSE + update_icon() + playsound(src, "spark", 50, 1, -1) + ..() \ No newline at end of file diff --git a/code/modules/mob/abstract/new_player/new_player.dm b/code/modules/mob/abstract/new_player/new_player.dm index 980bf896327..c046df081cf 100644 --- a/code/modules/mob/abstract/new_player/new_player.dm +++ b/code/modules/mob/abstract/new_player/new_player.dm @@ -216,6 +216,10 @@ INITIALIZE_IMMEDIATE(/mob/abstract/new_player) handle_player_polling() return + if(href_list["showpolllink"]) + show_poll_link(href_list["showpolllink"]) + return + if(href_list["pollid"]) var/pollid = href_list["pollid"] diff --git a/code/modules/mob/abstract/new_player/poll.dm b/code/modules/mob/abstract/new_player/poll.dm index cbaf9048686..ca491e4fe69 100644 --- a/code/modules/mob/abstract/new_player/poll.dm +++ b/code/modules/mob/abstract/new_player/poll.dm @@ -34,20 +34,35 @@ src << browse(output,"window=playerpolllist;size=500x300") +/mob/abstract/new_player/proc/show_poll_link(var/pollid = -1) + if(pollid == -1) return + establish_db_connection(dbcon) + if(dbcon.IsConnected()) + var/DBQuery/select_query = dbcon.NewQuery("SELECT link FROM ss13_poll_question WHERE id = :pollid:") + select_query.Execute(list("pollid"=pollid)) + + var/link = null + while(select_query.NextRow()) + link = select_query.item[1] + if(link && link != "") + usr << link(link) + else + log_debug("Polling: [usr.ckey] tried to open poll [pollid] with a invalid link: [link]") /mob/abstract/new_player/proc/poll_player(var/pollid = -1) if(pollid == -1) return establish_db_connection(dbcon) if(dbcon.IsConnected()) - var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM ss13_poll_question WHERE id = [pollid]") - select_query.Execute() + var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions, link FROM ss13_poll_question WHERE id = :pollid:") + select_query.Execute(list("pollid"=pollid)) var/pollstarttime = "" var/pollendtime = "" var/pollquestion = "" var/polltype = "" + var/haslink = 0 var/found = 0 var/multiplechoiceoptions = 0 @@ -56,6 +71,8 @@ pollendtime = select_query.item[2] pollquestion = select_query.item[3] polltype = select_query.item[4] + if(select_query.item[6] && select_query.item[6] != "") + haslink = 1 found = 1 break @@ -89,7 +106,10 @@ var/output = "
Player poll" output +="
" output += "Question: [pollquestion]
" - output += "Poll runs from [pollstarttime] until [pollendtime]

" + output += "Poll runs from [pollstarttime] until [pollendtime]" + if(haslink) + output += "
Additional information is available here" + output += "

" if(!voted) //Only make this a form if we have not voted yet output += "

" @@ -133,7 +153,10 @@ var/output = "
Player poll" output +="
" output += "Question: [pollquestion]
" - output += "Feedback gathering runs from [pollstarttime] until [pollendtime]

" + output += "Feedback gathering runs from [pollstarttime] until [pollendtime]" + if(haslink) + output += "
Additional information is available here" + output += "

" if(!voted) //Only make this a form if we have not voted yet output += "" @@ -167,7 +190,10 @@ var/output = "

Player poll" output +="
" output += "Question: [pollquestion]
" - output += "Poll runs from [pollstarttime] until [pollendtime]

" + output += "Poll runs from [pollstarttime] until [pollendtime]" + if(haslink) + output += "
Additional information is available here" + output += "

" var/voted = 0 while(voted_query.NextRow()) @@ -262,7 +288,10 @@ var/output = "

Player poll" output +="
" output += "Question: [pollquestion]
You can select up to [multiplechoiceoptions] options. If you select more, the first [multiplechoiceoptions] will be saved.
" - output += "Poll runs from [pollstarttime] until [pollendtime]

" + output += "Poll runs from [pollstarttime] until [pollendtime]" + if(haslink) + output += "
Additional information is available here" + output += "

" if(!voted) //Only make this a form if we have not voted yet output += "" diff --git a/code/modules/mob/living/carbon/human/species/station/machine_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/machine_subspecies.dm index 995160c33f4..18c84454f06 100644 --- a/code/modules/mob/living/carbon/human/species/station/machine_subspecies.dm +++ b/code/modules/mob/living/carbon/human/species/station/machine_subspecies.dm @@ -274,7 +274,7 @@ examine_color = "#bc4b00" - blurb = "The Xion Manufacturing Group, being a subsidiary of Hephaestus Industries, saw the original Industrial models and wanted to develop their own chassis based off of the original design. The result is the Xion Industrial model. Sturdy and strong, this chassis is quite powerful and equally durable, with an ample power cell and improved actuators for carrying the increased weight of the body. The Xion model also retains sturdiness without covering the chassis in plating, allowing for the cooling systems to vent heat much easier than the Hephaestus-brand model. The Group did not wish to leave exposed cooling conduits, however, so this chassis will require a suit to perform EVA." + blurb = "The Xion Manufacturing Group, being a subsidiary of Hephaestus Industries, saw the original Industrial models and wanted to develop their own chassis based off of the original design. The result is the Xion Industrial model. Sturdy and strong, this chassis is quite powerful and equally durable, with an ample power cell and improved actuators for carrying the increased weight of the body. The Xion model also retains sturdiness without covering the chassis in plating, allowing for the cooling systems to vent heat much easier than the Hephaestus-brand model. This unit cannot perform EVA" has_limbs = list( "chest" = list("path" = /obj/item/organ/external/chest/industrial/xion), diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 86ece271e13..749dbeda9c4 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -357,6 +357,8 @@ if(H) if(H.species.siemens_coefficient == 0) return + if(isvaurca(H)) //natural vaurca insulation + return if(H.gloves && contact_zone == "hand") var/obj/item/clothing/gloves/G = H.gloves if(G.siemens_coefficient == 0) return 0 //to avoid spamming with insulated glvoes on diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index bb342cc6ae0..0b9df0bdae6 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -11,88 +11,88 @@ volume = 50 var/shaken = 0 - on_reagent_change() +/obj/item/weapon/reagent_containers/food/drinks/on_reagent_change() + return + +/obj/item/weapon/reagent_containers/food/drinks/attack_self(mob/user as mob) + if(!is_open_container()) + if(user.a_intent == I_HURT && !shaken) + shaken = 1 + user.visible_message("[user] shakes the [src]!", "You shake the [src]!") + playsound(loc,'sound/items/Shaking_Soda_Can.ogg', rand(10,50), 1) + return + if(shaken) + boom(user) + else + open(user) + +/obj/item/weapon/reagent_containers/food/drinks/proc/open(mob/user as mob) + playsound(loc,'sound/effects/canopen.ogg', rand(10,50), 1) + user.visible_message("[user] opens the [src].", "You open the [src] with an audible pop!", "You can hear a pop,") + flags |= OPENCONTAINER + +/obj/item/weapon/reagent_containers/food/drinks/proc/boom(mob/user as mob) + user.visible_message("The [src] explodes all over [user] as they open it!","The [src] explodes all over you as you open it!","You can hear a soda can explode.") + playsound(loc,'sound/items/Soda_Burst.ogg', rand(20,50), 1) + QDEL_NULL(reagents) + flags |= OPENCONTAINER + shaken = 0 + +/obj/item/weapon/reagent_containers/food/drinks/attack(mob/M as mob, mob/user as mob, def_zone) + if(force && !(flags & NOBLUDGEON) && user.a_intent == I_HURT) + return ..() + + if(standard_feed_mob(user, M)) return - attack_self(mob/user as mob) - if(!is_open_container()) - if(user.a_intent == I_HURT && !shaken) - shaken = 1 - user << "You shake the [src]!" - playsound(loc,'sound/items/Shaking_Soda_Can.ogg', rand(10,50), 1) - return - if(shaken) - boom(user) - else - open(user) + return 0 - proc/open(mob/user) - playsound(loc,'sound/effects/canopen.ogg', rand(10,50), 1) - user << "You open [src] with an audible pop!" - flags |= OPENCONTAINER +/obj/item/weapon/reagent_containers/food/drinks/afterattack(obj/target, mob/user, proximity) + if(!proximity) + return + if(standard_dispenser_refill(user, target)) + return + if(standard_pour_into(user, target)) + return + return ..() - proc/boom(user) - user << "The [src] explodes all over you as you open it!" - playsound(loc,'sound/items/Soda_Burst.ogg', rand(20,50), 1) - QDEL_NULL(reagents) - flags |= OPENCONTAINER - shaken = 0 +/obj/item/weapon/reagent_containers/food/drinks/standard_feed_mob(var/mob/user, var/mob/target) + if(!is_open_container()) + user << "You need to open [src]!" + return 1 + return ..() - attack(mob/M as mob, mob/user as mob, def_zone) - if(force && !(flags & NOBLUDGEON) && user.a_intent == I_HURT) - return ..() +/obj/item/weapon/reagent_containers/food/drinks/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) + if(!is_open_container()) + user << "You need to open [src]!" + return 1 + return ..() - if(standard_feed_mob(user, M)) - return +/obj/item/weapon/reagent_containers/food/drinks/standard_pour_into(var/mob/user, var/atom/target) + if(!is_open_container()) + user << "You need to open [src]!" + return 1 + return ..() - return 0 +/obj/item/weapon/reagent_containers/food/drinks/self_feed_message(var/mob/user) + user << "You swallow a gulp from \the [src]." - afterattack(obj/target, mob/user, proximity) - if(!proximity) return +/obj/item/weapon/reagent_containers/food/drinks/feed_sound(var/mob/user) + playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1) - if(standard_dispenser_refill(user, target)) - return - if(standard_pour_into(user, target)) - return - return ..() - - standard_feed_mob(var/mob/user, var/mob/target) - if(!is_open_container()) - user << "You need to open [src]!" - return 1 - return ..() - - standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) - if(!is_open_container()) - user << "You need to open [src]!" - return 1 - return ..() - - standard_pour_into(var/mob/user, var/atom/target) - if(!is_open_container()) - user << "You need to open [src]!" - return 1 - return ..() - - self_feed_message(var/mob/user) - user << "You swallow a gulp from \the [src]." - - feed_sound(var/mob/user) - playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1) - - examine(mob/user) - if(!..(user, 1)) - return - if(!reagents || reagents.total_volume == 0) - user << "\The [src] is empty!" - else if (reagents.total_volume <= volume * 0.25) - user << "\The [src] is almost empty!" - else if (reagents.total_volume <= volume * 0.66) - user << "\The [src] is half full!" - else if (reagents.total_volume <= volume * 0.90) - user << "\The [src] is almost full!" - else - user << "\The [src] is full!" +/obj/item/weapon/reagent_containers/food/drinks/examine(mob/user) + if(!..(user, 1)) + return + if(!reagents || reagents.total_volume == 0) + user << "\The [src] is empty!" + else if (reagents.total_volume <= volume * 0.25) + user << "\The [src] is almost empty!" + else if (reagents.total_volume <= volume * 0.66) + user << "\The [src] is half full!" + else if (reagents.total_volume <= volume * 0.90) + user << "\The [src] is almost full!" + else + user << "\The [src] is full!" //////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/turbolift/turbolift.dm b/code/modules/turbolift/turbolift.dm index 6b1c67d5de1..0dd1df07e1e 100644 --- a/code/modules/turbolift/turbolift.dm +++ b/code/modules/turbolift/turbolift.dm @@ -94,11 +94,7 @@ if (!moving_upwards || next_floor == floors[floors.len]) // If moving down or moving to the top floor, squish. for(var/turf/T in destination) for(var/atom/movable/AM in T) - if(istype(AM, /mob/living)) - var/mob/living/M = AM - M.gib() - else if(AM.simulated && !istype(AM, /mob/abstract/eye)) - qdel(AM) + AM.crush_act() origin.move_contents_to(destination) diff --git a/html/changelog.html b/html/changelog.html index 08a0b30229a..b36d3cbd115 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,32 @@ -->

+

25 April 2018

+

Alberyk updated:

+
    +
  • Vaurca should have proper natural insulation once more.
  • +
+

Arrow768 updated:

+
    +
  • You can now see if someone opens a sodacan that has been shaken.
  • +
+ +

19 April 2018

+

PoZe updated:

+
    +
  • Access to Research Division Maint door is fixed
  • +
  • Added missing firelocks to construction level of security
  • +
  • Fixed broken small light icon to appear properly
  • +
  • Shower now reacts with mobs as water supposed to, damaging slimes.
  • +
  • Pool, Ocean or generic water turfs now cleans anything that enters it, cleans it's own turf and damages slimes.
  • +
  • Fixed chainsaw unwielded force
  • +
  • Chainsaw powered force buffed, 30 unwielded and 60 wielded
  • +
  • Closets now spawn one sheet of metal upon being destroyed
  • +
  • Turbolifts now properly destroy atoms, and gib any mobs that are in closets
  • +
  • Crusher no longer kills AI eye
  • +
  • Medical construction level now has full camera coverage
  • +
+

15 April 2018

BurgerBB updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index a99a970dbb8..9a7bb7e623d 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -5371,3 +5371,22 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Lohikar: - bugfix: Openspaces will now properly show mobs/objects that became visible after roundstart. +2018-04-19: + PoZe: + - maptweak: Access to Research Division Maint door is fixed + - maptweak: Added missing firelocks to construction level of security + - bugfix: Fixed broken small light icon to appear properly + - tweak: Shower now reacts with mobs as water supposed to, damaging slimes. + - tweak: Pool, Ocean or generic water turfs now cleans anything that enters it, + cleans it's own turf and damages slimes. + - tweak: Fixed chainsaw unwielded force + - balance: Chainsaw powered force buffed, 30 unwielded and 60 wielded + - tweak: Closets now spawn one sheet of metal upon being destroyed + - tweak: Turbolifts now properly destroy atoms, and gib any mobs that are in closets + - bugfix: Crusher no longer kills AI eye + - maptweak: Medical construction level now has full camera coverage +2018-04-25: + Alberyk: + - bugfix: Vaurca should have proper natural insulation once more. + Arrow768: + - bugfix: You can now see if someone opens a sodacan that has been shaken. diff --git a/icons/obj/custom_items/amy_player.dmi b/icons/obj/custom_items/amy_player.dmi new file mode 100644 index 00000000000..a518f667fd0 Binary files /dev/null and b/icons/obj/custom_items/amy_player.dmi differ diff --git a/icons/obj/custom_items/daliyah_visa.dmi b/icons/obj/custom_items/daliyah_visa.dmi new file mode 100644 index 00000000000..ba46104615c Binary files /dev/null and b/icons/obj/custom_items/daliyah_visa.dmi differ diff --git a/icons/obj/custom_items/jawdat_paper.dmi b/icons/obj/custom_items/jawdat_paper.dmi index 546e523a512..b1381855a07 100644 Binary files a/icons/obj/custom_items/jawdat_paper.dmi and b/icons/obj/custom_items/jawdat_paper.dmi differ diff --git a/icons/obj/custom_items/tristen_retractor.dmi b/icons/obj/custom_items/tristen_retractor.dmi new file mode 100644 index 00000000000..d78075549b5 Binary files /dev/null and b/icons/obj/custom_items/tristen_retractor.dmi differ diff --git a/maps/aurora/aurora-4_mainlevel.dmm b/maps/aurora/aurora-4_mainlevel.dmm index bb01a39ecbf..c6a077f9003 100644 --- a/maps/aurora/aurora-4_mainlevel.dmm +++ b/maps/aurora/aurora-4_mainlevel.dmm @@ -12334,13 +12334,6 @@ /turf/simulated/open, /area/engineering/engine_waste) "awo" = ( -/obj/machinery/door/blast/regular{ - dir = 4; - icon_state = "pdoor1"; - id = "EngineVent"; - name = "Reactor Vent"; - p_open = 0 - }, /obj/machinery/door/blast/regular{ dir = 4; icon_state = "pdoor1"; @@ -51453,7 +51446,7 @@ /obj/machinery/door/airlock/maintenance{ name = "Research Division Maintenance"; req_access = list(47); - req_one_access = newlist() + req_one_access = null }, /obj/machinery/door/blast/regular{ density = 0; @@ -56021,6 +56014,10 @@ pixel_x = 0; pixel_y = 32 }, +/obj/machinery/light{ + dir = 1; + icon_state = "tube1" + }, /turf/simulated/floor/tiled, /area/hydroponics) "bSh" = ( @@ -57144,7 +57141,8 @@ "bUv" = ( /obj/machinery/portable_atmospherics/hydroponics, /obj/machinery/light{ - dir = 1 + dir = 1; + icon_state = "tube1" }, /turf/simulated/floor/tiled/dark, /area/hydroponics) @@ -64623,6 +64621,18 @@ icon_state = "asteroidplating" }, /area/outpost/mining_main/eva) +"clx" = ( +/obj/effect/floor_decal/corner/green{ + icon_state = "corner_white"; + dir = 9 + }, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1"; + pixel_y = 0 + }, +/turf/simulated/floor/tiled, +/area/hydroponics) (1,1,1) = {" aaa @@ -90500,7 +90510,7 @@ bUu bSO bSO bSO -bSO +clx bWn bWm bWY @@ -91529,7 +91539,7 @@ bUT bVs bVN bWb -bWp +bTt bWm bXb bXp diff --git a/maps/aurora/aurora-5_interstitial.dmm b/maps/aurora/aurora-5_interstitial.dmm index 7c3c80b67ac..935d4c64c8c 100644 --- a/maps/aurora/aurora-5_interstitial.dmm +++ b/maps/aurora/aurora-5_interstitial.dmm @@ -2764,8 +2764,24 @@ /turf/simulated/floor/carpet, /area/security/detectives_office) "ff" = ( -/turf/simulated/floor/holofloor/tiled, -/area/security/training) +/obj/effect/floor_decal/corner/green/full{ + icon_state = "corner_white_full"; + dir = 1 + }, +/obj/structure/flora/pottedplant, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1"; + pixel_x = 0 + }, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/obj/machinery/camera/network/medbay, +/turf/simulated/floor/tiled/white, +/area/medical/psych) "fg" = ( /obj/effect/floor_decal/corner/green{ icon_state = "corner_white"; @@ -3329,6 +3345,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/door/firedoor, /turf/simulated/floor/wood, /area/security/detectives_office) "gh" = ( @@ -3535,6 +3552,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/door/firedoor, /turf/simulated/floor/tiled, /area/security/forensics_office) "gy" = ( @@ -4072,6 +4090,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/door/firedoor, /turf/simulated/floor/plating, /area/security/investigations) "hk" = ( @@ -4132,7 +4151,6 @@ /area/security/forensics_office) "hn" = ( /obj/structure/grille, -/obj/machinery/door/firedoor, /obj/structure/window/reinforced{ dir = 4 }, @@ -4141,6 +4159,7 @@ dir = 1 }, /obj/structure/window/reinforced, +/obj/machinery/door/firedoor, /turf/simulated/floor/plating, /area/security/forensics_office) "ho" = ( @@ -4234,6 +4253,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/machinery/door/firedoor, /turf/simulated/floor/tiled, /area/security/training) "hw" = ( @@ -4555,6 +4575,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/door/firedoor, /turf/simulated/floor/plating, /area/security/training) "ib" = ( @@ -5339,13 +5360,22 @@ /turf/simulated/floor/tiled, /area/security/training) "jA" = ( -/obj/effect/floor_decal/corner/red{ +/obj/effect/floor_decal/corner/green{ icon_state = "corner_white"; + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, -/obj/structure/weightlifter, -/turf/simulated/floor/tiled, -/area/mine/unexplored) +/obj/machinery/firealarm/west, +/obj/machinery/camera/network/medbay{ + c_tag = "Medical - Isolation Room"; + dir = 4; + icon_state = "camera"; + network = list("Medical","Isolation Room") + }, +/turf/simulated/floor/tiled/white, +/area/medical/psych) "jB" = ( /obj/effect/floor_decal/corner/blue/full{ icon_state = "corner_white_full"; @@ -5466,32 +5496,18 @@ /turf/simulated/floor/tiled/white, /area/medical/psych) "jP" = ( -/obj/effect/floor_decal/corner/green/full{ - icon_state = "corner_white_full"; - dir = 1 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/obj/structure/flora/pottedplant, -/obj/machinery/light{ - dir = 4; - icon_state = "tube1"; - pixel_x = 0 - }, -/obj/machinery/alarm{ - dir = 8; - icon_state = "alarm0"; - pixel_x = 24 - }, -/turf/simulated/floor/tiled/white, +/obj/machinery/camera/network/medbay, +/turf/simulated/floor/tiled/dark, /area/medical/psych) "jQ" = ( /obj/effect/floor_decal/corner/green{ icon_state = "corner_white"; - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, -/obj/machinery/firealarm/west, +/obj/machinery/camera/network/medbay, /turf/simulated/floor/tiled/white, /area/medical/psych) "jR" = ( @@ -6512,6 +6528,12 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 }, +/obj/machinery/camera/network/medbay{ + c_tag = "Medical - Isolation Room"; + dir = 4; + icon_state = "camera"; + network = list("Medical","Isolation Room") + }, /turf/simulated/floor/tiled/white, /area/medical/psych) "lH" = ( @@ -42446,7 +42468,7 @@ ab ab jG jL -jQ +jA kb kl kw @@ -44761,7 +44783,7 @@ jH jM jV jG -ko +jP kB jG kS @@ -45792,7 +45814,7 @@ jG kr jG jG -jM +jQ lf lq kc @@ -46300,7 +46322,7 @@ aa ab ab jG -jP +ff jX ki kt diff --git a/maps/aurora/aurora-8_derelict.dmm b/maps/aurora/aurora-8_derelict.dmm index d68d5fed85f..08fc949e1bc 100644 --- a/maps/aurora/aurora-8_derelict.dmm +++ b/maps/aurora/aurora-8_derelict.dmm @@ -6343,9 +6343,9 @@ /area/derelict/hallway/southeast) "sR" = ( /obj/machinery/light/small{ - icon_state = "bulb-broken"; + base_state = "bulb_broken"; dir = 8; - base_state = "bulb-broken" + icon_state = "bulb_broken" }, /turf/simulated/floor/airless, /area/derelict/hallway/southeast) @@ -7739,9 +7739,9 @@ /area/derelict/hallway/southeast) "wp" = ( /obj/machinery/light/small{ - base_state = "bulb-broken"; + base_state = "bulb_broken"; dir = 4; - icon_state = "bulb-broken" + icon_state = "bulb_broken" }, /obj/structure/closet/walllocker/emerglocker/north, /turf/simulated/floor/airless,