Merge remote-tracking branch 'upstream/master' into diagonal-movement

This commit is contained in:
Couls
2019-07-08 10:13:15 -04:00
54 changed files with 563 additions and 174 deletions
+21 -3
View File
@@ -279,6 +279,9 @@
/datum/pm_tracker/proc/add_message(client/title, client/sender, message, mob/user)
if(!pms[title.key])
pms[title.key] = new /datum/pm_convo(title)
else if(!pms[title.key].client)
// If they DCed earlier, we need to add the client reference back
pms[title.key].client = title
pms[title.key].add(sender, message)
if(!open)
@@ -308,16 +311,25 @@
dat += "<a class='[class]' href='?src=[UID()];newtitle=[title]'>[label]</a>"
var/datum/pm_convo/convo = pms[current_title]
var/datum/browser/popup = new(user, window_id, "Messages", 1000, 600, src)
if(convo)
popup.add_head_content(@{"<script type='text/javascript'>
window.onload = function () {
var msgs = document.getElementById('msgs');
msgs.scrollTop = msgs.scrollHeight;
}
</script>"})
convo.read = TRUE
dat += "<h2>[check_rights(R_ADMIN, FALSE, user) ? fancy_title(current_title) : current_title]</h2>"
dat += "<h4>"
dat += "<table style='width:950px; border: 3px solid;'>"
dat += "<div id='msgs' style='width:950px; border: 3px solid; overflow-y: scroll; height: 350px;'>"
dat += "<table>"
for(var/message in convo.messages)
dat += "<tr><td>[message]</td></tr>"
dat += "</table>"
dat += "</div>"
if(convo.typing)
dat += "<i><span class='typing'>[current_title] is typing</span></i>"
dat += "<br>"
@@ -327,17 +339,23 @@
if(check_rights(R_ADMIN, FALSE, user))
dat += "<a href='?src=[UID()];ping=[current_title]'>Ping</a>"
var/datum/browser/popup = new(user, window_id, "Messages", 1000, 600, src)
popup.set_content(dat)
popup.open()
open = TRUE
/datum/pm_tracker/proc/fancy_title(title)
var/client/C = pms[title].client
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)]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>)"
/datum/pm_tracker/proc/update_client(title)
var/client/C = GLOB.directory[ckey(title)]
if(C)
pms[title].client = C
return C
return null
/datum/pm_tracker/Topic(href, href_list)
if(href_list["archive"])
pms[href_list["archive"]].archived = !pms[href_list["archive"]].archived
@@ -455,6 +455,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'><b>[(toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</b></a><br>"
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'><b>[(toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]</b></a><br>"
dat += "<b>Ghost Sight:</b> <a href='?_src_=prefs;preference=ghost_sight'><b>[(toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</b></a><br>"
dat += "<b>Ghost PDA:</b> <a href='?_src_=prefs;preference=ghost_pda'><b>[(toggles & CHAT_GHOSTPDA) ? "All PDA Messages" : "No PDA Messages"]</b></a><br>"
if(check_rights(R_ADMIN,0))
dat += "<b>OOC Color:</b> <span style='border: 1px solid #161616; background-color: [ooccolor ? ooccolor : normal_ooc_colour];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=ooccolor;task=input'><b>Change</b></a><br>"
if(config.allow_Metadata)
@@ -2029,6 +2030,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("ghost_radio")
toggles ^= CHAT_GHOSTRADIO
if("ghost_pda")
toggles ^= CHAT_GHOSTPDA
if("ghost_anonsay")
ghost_anonsay = !ghost_anonsay
@@ -266,3 +266,11 @@
else
to_chat(usr, "<span class='notice'>You are now in QWERTY mode.")
return
/client/verb/toggle_ghost_pda()
set name = "Show/Hide GhostPDA"
set category = "Preferences"
set desc = ".Toggle seeing PDA messages as an observer."
prefs.toggles ^= CHAT_GHOSTPDA
to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTPDA) ? "see all PDA messages" : "no longer see PDA messages"].")
prefs.save_preferences(src)
feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -64,7 +64,6 @@
item_state = "lgloves"
flags = NODROP
/obj/item/clothing/gloves/color/yellow/stun
name = "stun gloves"
desc = "Horrendous and awful. It smells like cancer. The fact it has wires attached to it is incidental."
@@ -72,6 +71,9 @@
var/stun_strength = 5
var/stun_cost = 2000
/obj/item/clothing/gloves/color/yellow/stun/get_cell()
return cell
/obj/item/clothing/gloves/color/yellow/stun/New()
..()
update_icon()
@@ -97,6 +97,9 @@
to_chat(usr, "The maintenance panel is [open ? "open" : "closed"].")
to_chat(usr, "Hardsuit systems are [offline ? "<font color='red'>offline</font>" : "<font color='green'>online</font>"].")
/obj/item/rig/get_cell()
return cell
/obj/item/rig/New()
..()
@@ -164,7 +164,7 @@
// Virology Medical Smartfridge
// ----------------------------
/obj/machinery/smartfridge/secure/chemistry/virology
name = "smart virus storage"
name = "Smart Virus Storage"
desc = "A refrigerated storage unit for volatile sample storage."
req_access_txt = "39"
spawn_meds = list(/obj/item/reagent_containers/syringe/antiviral = 4,
@@ -386,7 +386,8 @@
return data
/obj/machinery/smartfridge/Topic(href, href_list)
if(..()) return 0
if(..())
return FALSE
var/mob/user = usr
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
@@ -396,7 +397,7 @@
if(href_list["close"])
user.unset_machine()
ui.close()
return 0
return FALSE
if(href_list["vend"])
var/index = text2num(href_list["vend"])
@@ -409,17 +410,26 @@
item_quants[K] = max(count - amount, 0)
var/i = amount
for(var/obj/O in contents)
if(O.name == K)
O.forceMove(loc)
adjust_item_drop_location(O)
update_icon()
i--
if(i <= 0)
return 1
return 1
return 0
if(i == 1 && Adjacent(user) && !issilicon(user))
for(var/obj/O in contents)
if(O.name == K)
if(!user.put_in_hands(O))
O.forceMove(loc)
adjust_item_drop_location(O)
update_icon()
break
return TRUE
else
for(var/obj/O in contents)
if(O.name == K)
O.forceMove(loc)
adjust_item_drop_location(O)
update_icon()
i--
if(i <= 0)
return TRUE
return TRUE
return FALSE
/obj/machinery/smartfridge/proc/throw_item()
var/obj/throw_item = null
+1
View File
@@ -82,6 +82,7 @@
/obj/item/flashlight/lantern
name = "lantern"
icon_state = "lantern"
item_state = "lantern"
desc = "A mining lantern."
brightness_on = 6 // luminosity when on
+18 -22
View File
@@ -402,9 +402,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(usr, "Not when you're not dead!")
return
var/area/A = input("Area to jump to", "BOOYEA") as null|anything in ghostteleportlocs
var/area/thearea = ghostteleportlocs[A]
var/datum/async_input/A = input_autocomplete_async(usr, "Area to jump to: ", ghostteleportlocs)
A.on_close(CALLBACK(src, .proc/teleport))
/mob/dead/observer/proc/teleport(area/thearea)
if(!thearea)
return
@@ -425,9 +426,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Follow and orbit a mob."
var/list/mobs = getpois(skip_mindless=1)
var/input = input("Please, select a mob!", "Haunt", null, null) as null|anything in mobs
var/mob/target = mobs[input]
ManualFollow(target)
var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a mob: ", mobs)
A.on_close(CALLBACK(src, .proc/ManualFollow))
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
@@ -499,25 +499,21 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Jump to Mob"
set desc = "Teleport to a mob"
if(isobserver(usr)) //Make sure they're an observer!
var/list/dest = list() //List of possible destinations (mobs)
var/target = null //Chosen target.
if(isobserver(usr)) //Make sure they're an observer!
var/list/dest = getpois(mobs_only=1) //Fill list, prompt user with list
var/datum/async_input/A = input_autocomplete_async(usr, "Enter a mob name: ", dest)
A.on_close(CALLBACK(src, .proc/jump_to_mob))
dest += getpois(mobs_only=1) //Fill list, prompt user with list
target = input("Please, select a mob!", "Jump to Mob", null, null) as null|anything in dest
if(!target) //Make sure we actually have a target
return
else
var/mob/M = dest[target] //Destination mob
var/mob/A = src //Source mob
var/turf/T = get_turf(M) //Turf of the destination mob
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
A.forceMove(T)
else
to_chat(A, "This mob is not located in the game world.")
/mob/dead/observer/proc/jump_to_mob(mob/M)
if(!M)
return
var/mob/A = src //Source mob
var/turf/T = get_turf(M) //Turf of the destination mob
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
A.forceMove(T)
return
to_chat(A, "This mob is not located in the game world.")
/* Now a spell. See spells.dm
/mob/dead/observer/verb/boo()
+53 -50
View File
@@ -216,56 +216,7 @@
add_attack_logs(M, src, "Shaked", ATKLOG_ALL)
if(health >= HEALTH_THRESHOLD_CRIT)
if(src == M && ishuman(src))
var/mob/living/carbon/human/H = src
visible_message( \
text("<span class='notice'>[src] examines [].</span>",gender==MALE?"himself":"herself"), \
"<span class='notice'>You check yourself for injuries.</span>" \
)
var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")
for(var/X in H.bodyparts)
var/obj/item/organ/external/LB = X
missing -= LB.limb_name
var/status = ""
var/brutedamage = LB.brute_dam
var/burndamage = LB.burn_dam
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
status = "battered"
if(brutedamage > 40)
status = "mangled"
if(brutedamage > 0 && burndamage > 0)
status += " and "
if(burndamage > 40)
status += "peeling away"
else if(burndamage > 10)
status += "blistered"
else if(burndamage > 0)
status += "numb"
if(LB.status & ORGAN_MUTATED)
status = "weirdly shapen."
if(status == "")
status = "OK"
to_chat(src, "\t <span class='[status == "OK" ? "notice" : "warning"]'>Your [LB.name] is [status].</span>")
for(var/obj/item/I in LB.embedded_objects)
to_chat(src, "\t <a href='byond://?src=[UID()];embedded_object=[I.UID()];embedded_limb=[LB.UID()]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
for(var/t in missing)
to_chat(src, "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>")
if(H.bleed_rate)
to_chat(src, "<span class='danger'>You are bleeding!</span>")
if(staminaloss)
if(staminaloss > 30)
to_chat(src, "<span class='info'>You're completely exhausted.</span>")
else
to_chat(src, "<span class='info'>You feel fatigued.</span>")
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
H.play_xylophone()
check_self_for_injuries()
else
if(player_logged)
M.visible_message("<span class='notice'>[M] shakes [src], but [p_they()] [p_do()] not respond. Probably suffering from SSD.", \
@@ -308,6 +259,58 @@
else if(H.w_uniform)
H.w_uniform.add_fingerprint(M)
/mob/living/carbon/proc/check_self_for_injuries()
var/mob/living/carbon/human/H = src
visible_message( \
text("<span class='notice'>[src] examines [].</span>",gender==MALE?"himself":"herself"), \
"<span class='notice'>You check yourself for injuries.</span>" \
)
var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")
for(var/X in H.bodyparts)
var/obj/item/organ/external/LB = X
missing -= LB.limb_name
var/status = ""
var/brutedamage = LB.brute_dam
var/burndamage = LB.burn_dam
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
status = "battered"
if(brutedamage > 40)
status = "mangled"
if(brutedamage > 0 && burndamage > 0)
status += " and "
if(burndamage > 40)
status += "peeling away"
else if(burndamage > 10)
status += "blistered"
else if(burndamage > 0)
status += "numb"
if(LB.status & ORGAN_MUTATED)
status = "weirdly shapen."
if(status == "")
status = "OK"
to_chat(src, "\t <span class='[status == "OK" ? "notice" : "warning"]'>Your [LB.name] is [status].</span>")
for(var/obj/item/I in LB.embedded_objects)
to_chat(src, "\t <a href='byond://?src=[UID()];embedded_object=[I.UID()];embedded_limb=[LB.UID()]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
for(var/t in missing)
to_chat(src, "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>")
if(H.bleed_rate)
to_chat(src, "<span class='danger'>You are bleeding!</span>")
if(staminaloss)
if(staminaloss > 30)
to_chat(src, "<span class='info'>You're completely exhausted.</span>")
else
to_chat(src, "<span class='info'>You feel fatigued.</span>")
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
H.play_xylophone()
/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
. = ..()
var/damage = intensity - check_eye_prot()
@@ -103,6 +103,9 @@ var/list/robot_verbs_default = list(
var/datum/action/item_action/toggle_research_scanner/scanner = null
var/list/module_actions = list()
/mob/living/silicon/robot/get_cell()
return cell
/mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0)
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
@@ -50,6 +50,9 @@
var/currentBloodColor = "#A10808"
var/currentDNA = null
/mob/living/simple_animal/bot/mulebot/get_cell()
return cell
/mob/living/simple_animal/bot/mulebot/New()
..()
wires = new /datum/wires/mulebot(src)
@@ -26,6 +26,10 @@
return battery_module.battery.give(amount)
return 0
/obj/item/modular_computer/get_cell()
var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL]
if(battery_module && battery_module.battery)
return battery_module.battery
// Used in following function to reduce copypaste
/obj/item/modular_computer/proc/power_failure()
@@ -8,6 +8,9 @@
var/obj/item/stock_parts/cell/battery = null
device_type = MC_CELL
/obj/item/computer_hardware/battery/get_cell()
return battery
/obj/item/computer_hardware/battery/New(loc, battery_type = null)
if(battery_type)
battery = new battery_type(src)
+3
View File
@@ -27,6 +27,9 @@ Contents:
var/obj/item/clothing/mask/gas/space_ninja/suitMask
var/mob/living/carbon/human/suitOccupant
/obj/item/clothing/suit/space/space_ninja/get_cell()
return suitCell
/obj/item/clothing/suit/space/space_ninja/proc/toggle_suit_lock(mob/living/carbon/human/user)
if(!suitActive)
if(!istype(user.wear_suit, /obj/item/clothing/suit/space/space_ninja))
+1 -3
View File
@@ -1,5 +1,3 @@
/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params)
if(U==suitOccupant)//Safety, in case you try doing this without wearing the suit/being the person with the suit.
if(istype(I, /obj/item/stock_parts/cell))
@@ -21,4 +19,4 @@
else
to_chat(U, "<span class='danger'>Procedure interrupted. Protocol terminated.</span>")
return
..()
..()
+12 -9
View File
@@ -75,16 +75,19 @@
assets.send(user)
var/data
if((!user.say_understands(null, GLOB.all_languages["Galactic Common"]) && !forceshow) || forcestars) //assuming all paper is written in common is better than hardcoded type checks
data = "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)][stamps]</BODY></HTML>"
if(view)
usr << browse(data, "window=[name];size=[paper_width]x[paper_height]")
onclose(usr, "[name]")
var/stars = (!user.say_understands(null, GLOB.all_languages["Galactic Common"]) && !forceshow) || forcestars
if(stars) //assuming all paper is written in common is better than hardcoded type checks
data = "[stars(info)][stamps]"
else
data = "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[infolinks ? info_links : info][stamps]</BODY></HTML>"
if(view)
usr << browse(data, "window=[name];size=[paper_width]x[paper_height]")
onclose(usr, "[name]")
data = "<div id='markdown'>[infolinks ? info_links : info]</div>[stamps]"
if(view)
var/datum/browser/popup = new(user, name, , paper_width, paper_height)
popup.stylesheets = list()
popup.set_content(data)
if(!stars)
popup.add_script("marked.js", 'html/browser/marked.js')
popup.add_head_content("<title>[name]</title>")
popup.open()
return data
/obj/item/paper/verb/rename()
+8
View File
@@ -169,10 +169,18 @@
if(useTC != 2) // Does our recipient have a broadcaster on their level?
to_chat(U, "ERROR: Cannot reach recipient.")
return
useMS.send_pda_message("[P.owner]","[pda.owner]","[t]")
tnote.Add(list(list("sent" = 1, "owner" = "[P.owner]", "job" = "[P.ownjob]", "message" = "[t]", "target" = "\ref[P]")))
PM.tnote.Add(list(list("sent" = 0, "owner" = "[pda.owner]", "job" = "[pda.ownjob]", "message" = "[t]", "target" = "\ref[pda]")))
pda.investigate_log("<span class='game say'>PDA Message - <span class='name'>[U.key] - [pda.owner]</span> -> <span class='name'>[P.owner]</span>: <span class='message'>[t]</span></span>", "pda")
// Show it to ghosts
for(var/mob/M in GLOB.dead_mob_list)
if(isobserver(M) && M.client && (M.client.prefs.toggles & CHAT_GHOSTPDA))
var/ghost_message = "<span class='name'>[pda.owner]</span> ([ghost_follow_link(pda, ghost=M)]) <span class='game say'>PDA Message</span> --> <span class='name'>[P.owner]</span> ([ghost_follow_link(P, ghost=M)]): <span class='message'>[t]</span>"
to_chat(M, "[ghost_message]")
if(!conversations.Find("\ref[P]"))
conversations.Add("\ref[P]")
if(!PM.conversations.Find("\ref[pda]"))
+3
View File
@@ -135,6 +135,9 @@
usesound = 'sound/items/deconstruct.ogg'
toolspeed = 1
/obj/machinery/power/apc/get_cell()
return cell
/obj/machinery/power/apc/connect_to_network()
//Override because the APC does not directly connect to the network; it goes through a terminal.
//The terminal is what the power computer looks for anyway.
+3
View File
@@ -19,6 +19,9 @@
var/ratingdesc = TRUE
var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it.
/obj/item/stock_parts/cell/get_cell()
return src
/obj/item/stock_parts/cell/New()
..()
START_PROCESSING(SSobj, src)
+3
View File
@@ -23,6 +23,9 @@
power_supply.use(round(power_supply.charge / severity))
update_icon()
/obj/item/gun/energy/get_cell()
return power_supply
/obj/item/gun/energy/New()
..()
if(cell_type)
@@ -22,6 +22,9 @@
var/obj/item/stock_parts/cell/cell = null // Used for firing superheated rods.
var/list/possible_tensions = list(XBOW_TENSION_20, XBOW_TENSION_40, XBOW_TENSION_60, XBOW_TENSION_80, XBOW_TENSION_FULL)
/obj/item/gun/throw/crossbow/get_cell()
return cell
/obj/item/gun/throw/crossbow/emp_act(severity)
if(cell && severity)
emp_act(severity)
@@ -24,6 +24,9 @@
var/hack_message = "You disable the safety safeguards, enabling the \"Mad Scientist\" mode."
var/unhack_message = "You re-enable the safety safeguards, enabling the \"NT Standard\" mode."
/obj/machinery/chem_dispenser/get_cell()
return cell
/obj/machinery/chem_dispenser/New()
..()
component_parts = list()
@@ -815,7 +815,7 @@
var/update_flags = STATUS_UPDATE_NONE
if(prob(5))
if(prob(10))
update_flags |= M.adjustToxLoss(rand(2.4), FALSE)
update_flags |= M.adjustToxLoss(rand(2,4), FALSE)
if(prob(7))
to_chat(M, "<span class='warning'>A horrible migraine overpowers you.</span>")
update_flags |= M.Stun(rand(2,5), FALSE)
+2
View File
@@ -92,6 +92,8 @@
has_paint = 1
update_icons()
/obj/spacepod/get_cell()
return battery
/obj/spacepod/New()
. = ..()
+3 -1
View File
@@ -128,11 +128,13 @@
var/teleporting = 0
var/chargecost = 1000
/obj/item/rcs/get_cell()
return rcell
/obj/item/rcs/New()
..()
rcell = new(src)
/obj/item/rcs/examine(mob/user)
..(user)
to_chat(user, "There are [round(rcell.charge/chargecost)] charge\s left.")