From 529125d3dd19143be27aa22d4f463923b58dc55a Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 May 2017 11:51:27 -0500 Subject: [PATCH 01/23] Moves tips from config to strings tree --- code/controllers/subsystem/ticker.dm | 4 ++-- code/modules/admin/verbs/deadsay.dm.rej | 10 ++++++++++ {config => strings}/admin_nicknames.txt | 0 {config => strings}/sillytips.txt | 0 {config => strings}/tips.txt | 0 5 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 code/modules/admin/verbs/deadsay.dm.rej rename {config => strings}/admin_nicknames.txt (100%) rename {config => strings}/sillytips.txt (100%) rename {config => strings}/tips.txt (100%) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index f701c051da..67599e4f4c 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -625,8 +625,8 @@ SUBSYSTEM_DEF(ticker) if(selected_tip) m = selected_tip else - var/list/randomtips = world.file2list("config/tips.txt") - var/list/memetips = world.file2list("config/sillytips.txt") + var/list/randomtips = world.file2list("strings/tips.txt") + var/list/memetips = world.file2list("strings/sillytips.txt") if(randomtips.len && prob(95)) m = pick(randomtips) else if(memetips.len) diff --git a/code/modules/admin/verbs/deadsay.dm.rej b/code/modules/admin/verbs/deadsay.dm.rej new file mode 100644 index 0000000000..7d0347427b --- /dev/null +++ b/code/modules/admin/verbs/deadsay.dm.rej @@ -0,0 +1,10 @@ +diff a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm (rejected hunks) +@@ -19,7 +19,7 @@ + + if (!msg) + return +- var/static/nicknames = world.file2list("strings/admin_nicknames.txt") ++ var/static/nicknames = world.file2list("config/admin_nicknames.txt") + + var/rendered = "DEAD: ADMIN([src.holder.fakekey ? pick(nicknames) : src.key]) says, \"[msg]\"" + diff --git a/config/admin_nicknames.txt b/strings/admin_nicknames.txt similarity index 100% rename from config/admin_nicknames.txt rename to strings/admin_nicknames.txt diff --git a/config/sillytips.txt b/strings/sillytips.txt similarity index 100% rename from config/sillytips.txt rename to strings/sillytips.txt diff --git a/config/tips.txt b/strings/tips.txt similarity index 100% rename from config/tips.txt rename to strings/tips.txt From 36dfc5a4dbd5e762782beef40441b1ce900a0f5f Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 May 2017 12:53:40 -0500 Subject: [PATCH 02/23] Holocalls --- code/controllers/subsystem/garbage.dm.rej | 9 + code/datums/holocall.dm | 154 ++++++++++++ code/game/machinery/hologram.dm | 149 +++++++++--- code/game/machinery/hologram.dm.rej | 226 ++++++++++++++++++ .../mob/living/silicon/ai/freelook/eye.dm | 2 +- tgstation.dme.rej | 9 + 6 files changed, 514 insertions(+), 35 deletions(-) create mode 100644 code/controllers/subsystem/garbage.dm.rej create mode 100644 code/datums/holocall.dm create mode 100644 code/game/machinery/hologram.dm.rej create mode 100644 tgstation.dme.rej diff --git a/code/controllers/subsystem/garbage.dm.rej b/code/controllers/subsystem/garbage.dm.rej new file mode 100644 index 0000000000..2075155c49 --- /dev/null +++ b/code/controllers/subsystem/garbage.dm.rej @@ -0,0 +1,9 @@ +diff a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm (rejected hunks) +@@ -725,7 +725,6 @@ var/datum/controller/subsystem/garbage_collector/SSgarbage + SearchVar(multiverse) + SearchVar(announcement_systems) + SearchVar(doppler_arrays) +- SearchVar(HOLOPAD_MODE) + SearchVar(holopads) + SearchVar(news_network) + SearchVar(allCasters) diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm new file mode 100644 index 0000000000..0153e41414 --- /dev/null +++ b/code/datums/holocall.dm @@ -0,0 +1,154 @@ +#define HOLOPAD_MAX_DIAL_TIME 200 + +/mob/camera/aiEye/remote/holo/setLoc() + . = ..() + var/obj/machinery/holopad/H = origin + H.move_hologram(eye_user, loc) + +//this datum manages it's own references + +/datum/holocall + var/mob/living/user //the one that called + var/obj/machinery/holopad/calling_holopad //the one that sent the call + var/obj/machinery/holopad/connected_holopad //the one that answered the call (may be null) + var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered + + var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected + var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected + + var/call_start_time + +//creates a holocall made by `caller` from `calling_pad` to `callees` +/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees) + call_start_time = world.time + user = caller + calling_pad.outgoing_call = src + calling_holopad = calling_pad + dialed_holopads = list() + + for(var/I in callees) + var/obj/machinery/holopad/H = I + if(!QDELETED(H) && H.is_operational()) + dialed_holopads += H + LAZYADD(H.holo_calls, src) + + if(!dialed_holopads.len) + calling_pad.say("Connection failure.") + qdel(src) + + testing("Holocall started") + +//cleans up ALL references :) +/datum/holocall/Destroy() + QDEL_NULL(eye) + + user.reset_perspective() + + user = null + hologram.HC = null + hologram = null + calling_holopad.outgoing_call = null + + for(var/I in dialed_holopads) + var/obj/machinery/holopad/H = I + LAZYREMOVE(H.holo_calls, src) + dialed_holopads.Cut() + + if(calling_holopad) + calling_holopad.SetLightsAndPower() + calling_holopad = null + if(connected_holopad) + connected_holopad.SetLightsAndPower() + connected_holopad = null + + testing("Holocall destroyed") + + return ..() + +//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection +/datum/holocall/proc/Disconnect(obj/machinery/holopad/H) + testing("Holocall disconnect") + if(H == connected_holopad) + calling_holopad.say("[usr] disconnected.") + else if(H == calling_holopad && connected_holopad) + connected_holopad.say("[usr] disconnected.") + + ConnectionFailure(H, TRUE) + +//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored. +/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE) + testing("Holocall connection failure: graceful [graceful]") + if(H == connected_holopad || H == calling_holopad) + if(!graceful) + calling_holopad.say("Connection failure.") + qdel(src) + return + + LAZYREMOVE(H.holo_calls, src) + dialed_holopads -= H + if(!dialed_holopads.len) + if(graceful) + calling_holopad.say("Call rejected.") + testing("No recipients, terminating") + qdel(src) + +//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored +/datum/holocall/proc/Answer(obj/machinery/holopad/H) + testing("Holocall answer") + if(H == calling_holopad) + CRASH("How cute, a holopad tried to answer itself.") + + if(!(H in dialed_holopads)) + return + + if(connected_holopad) + CRASH("Multi-connection holocall") + + connected_holopad = H + for(var/I in dialed_holopads) + if(I == H) + continue + var/obj/machinery/holopad/Holo = I + LAZYREMOVE(Holo.holo_calls, src) + dialed_holopads -= Holo + + if(!Check()) + return + + hologram = H.activate_holo(user) + hologram.HC = src + + //eyeobj code is horrid, this is the best copypasta I could make + eye = new + eye.origin = H + eye.eye_initialized = TRUE + eye.eye_user = user + eye.name = "Camera Eye ([user.name])" + user.remote_control = eye + user.reset_perspective(eye) + eye.setLoc(H.loc) + +//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise +/datum/holocall/proc/Check() + for(var/I in dialed_holopads) + var/obj/machinery/holopad/H = I + if(!H.is_operational()) + ConnectionFailure(H) + + if(QDELETED(src)) + return FALSE + + . = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc + + if(.) + if(connected_holopad) + . = !QDELETED(connected_holopad) && connected_holopad.is_operational() + else + . = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME) + if(!.) + calling_holopad.say("No answer recieved.") + calling_holopad.temp = "" + + if(!.) + testing("Holocall Check fail") + qdel(src) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index ae8c1ac1c4..ca9cc23380 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -57,8 +57,16 @@ Possible to do for anyone motivated enough: holopads += src /obj/machinery/holopad/Destroy() - for (var/mob/living/silicon/ai/master in masters) - clear_holo(master) + if(outgoing_call) + LAZYADD(holo_calls, outgoing_call) + + for(var/I in holo_calls) + var/datum/holocall/HC = I + HC.ConnectionFailure(src) + LAZYCLEARLIST(holo_calls) + + for (var/I in masters) + clear_holo(I) holopads -= src return ..() @@ -128,12 +136,49 @@ Possible to do for anyone motivated enough: temp = "A request for AI presence was already sent recently.
" temp += "Main Menu" + else if(href_list["Holocall"]) + if(outgoing_call) + return + + temp = "You must stand on the holopad to make a call!
" + temp += "Main Menu" + if(usr.loc == loc) + var/list/callnames = list() + for(var/I in holopads) + var/area/A = get_area(I) + if(A) + LAZYADD(callnames[A], I) + callnames -= get_area(src) + + var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames + if(QDELETED(usr) || !result || outgoing_call) + return + + if(usr.loc == loc) + temp = "Dialing...
" + temp += "Main Menu" + new /datum/holocall(usr, src, callnames[result]) + + else if(href_list["connectcall"]) + var/datum/holocall/call_to_connect = locate(href_list["connectcall"]) + if(!QDELETED(call_to_connect)) + call_to_connect.Answer(src) + temp = "" + + else if(href_list["disconnectcall"]) + var/datum/holocall/call_to_disconnect = locate(href_list["disconnectcall"]) + if(!QDELETED(call_to_disconnect)) + call_to_disconnect.Disconnect(src) + temp = "" + else if(href_list["mainmenu"]) temp = "" + if(outgoing_call) + outgoing_call.Disconnect() updateDialog() - add_fingerprint(usr) +//do not allow AIs to answer calls or people will use it to meta the AI sattelite /obj/machinery/holopad/attack_ai(mob/living/silicon/ai/user) if (!istype(user)) return @@ -148,39 +193,75 @@ Possible to do for anyone motivated enough: clear_holo(user) /obj/machinery/holopad/process() - if(masters.len)//If there is a hologram. - for (var/mob/living/silicon/ai/master in masters) - if(master && !master.stat && master.client && master.eyeobj)//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector. - if(!(stat & NOPOWER))//If the machine has power. - if(HOLOPAD_MODE == RANGE_BASED) - if(get_dist(master.eyeobj, src) <= holo_range) - return TRUE - else - var/obj/machinery/holopad/pad_close = get_closest_atom(/obj/machinery/holopad, holopads, master.eyeobj) - if(get_dist(pad_close, master.eyeobj) <= holo_range) - var/obj/effect/overlay/holo_pad_hologram/h = masters[master] - unset_holo(master) - pad_close.set_holo(master, h) - return TRUE - - else if (HOLOPAD_MODE == AREA_BASED) - - var/area/holo_area = get_area(src) - var/area/eye_area = get_area(master.eyeobj) - - if(eye_area in holo_area.related) - return TRUE - - clear_holo(master)//If not, we want to get rid of the hologram. - return TRUE - -/obj/machinery/holopad/proc/activate_holo(mob/living/silicon/ai/user) - if(!(stat & NOPOWER) && user.eyeobj.loc == src.loc)//If the projector has power and client eye is on it - if (istype(user.current, /obj/machinery/holopad)) + for(var/I in masters) + var/mob/living/master = I + var/mob/living/silicon/ai/AI = master + if(!istype(AI)) + AI = null + + if(!QDELETED(master) && !master.incapacitated() && master.client && (!AI || AI.eyeobj))//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector. + if(is_operational())//If the machine has power. + if(AI) //ais are range based + if(get_dist(AI.eyeobj, src) <= holo_range) + continue + else + var/obj/machinery/holopad/pad_close = get_closest_atom(/obj/machinery/holopad, holopads, AI.eyeobj) + if(get_dist(pad_close, AI.eyeobj) <= holo_range) + var/obj/effect/overlay/holo_pad_hologram/h = masters[master] + unset_holo(master) + pad_close.set_holo(master, h) + continue + else + continue + clear_holo(master)//If not, we want to get rid of the hologram. + + if(outgoing_call) + outgoing_call.Check() + + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad != src) + if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2))) + HC.Answer(src) + break + if(outgoing_call) + HC.Disconnect(src)//can't answer calls while calling + else + playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! + +/obj/machinery/holopad/proc/activate_holo(mob/living/user) + var/mob/living/silicon/ai/AI = user + if(!istype(AI)) + AI = null + + if(is_operational() && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it + if (AI && istype(AI.current, /obj/machinery/holopad)) to_chat(user, "ERROR: \black Image feed in progress.") return - create_holo(user)//Create one. - src.visible_message("A holographic image of [user] flicks to life right before your eyes!") + + var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. + if(AI) + Hologram.icon = AI.holo_icon + else //make it like real life + Hologram.icon = user.icon + Hologram.icon_state = user.icon_state + Hologram.copy_overlays(user, TRUE) + //codersprite some holo effects here + Hologram.alpha = 100 + Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) + Hologram.Impersonation = user + + Hologram.languages_spoken = user.languages_spoken + Hologram.mouse_opacity = 0//So you can't click on it. + Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. + Hologram.anchored = 1//So space wind cannot drag it. + Hologram.name = "[user.name] (Hologram)"//If someone decides to right click. + Hologram.set_light(2) //hologram lighting + + set_holo(user, Hologram) + visible_message("A holographic image of [user] flicks to life right before your eyes!") + + return Hologram else to_chat(user, "ERROR: \black Unable to project hologram.") diff --git a/code/game/machinery/hologram.dm.rej b/code/game/machinery/hologram.dm.rej new file mode 100644 index 0000000000..5dcbcc9d54 --- /dev/null +++ b/code/game/machinery/hologram.dm.rej @@ -0,0 +1,226 @@ +diff a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm (rejected hunks) +@@ -26,16 +26,12 @@ Possible to do for anyone motivated enough: + + #define HOLOPAD_PASSIVE_POWER_USAGE 1 + #define HOLOGRAM_POWER_USAGE 2 +-#define RANGE_BASED 4 +-#define AREA_BASED 6 +- +-var/const/HOLOPAD_MODE = RANGE_BASED + + var/list/holopads = list() + + /obj/machinery/holopad +- name = "\improper AI holopad" +- desc = "It's a floor-mounted device for projecting holographic images. It is activated remotely." ++ name = "Holopad" ++ desc = "It's a floor-mounted device for projecting holographic images." + icon_state = "holopad0" + layer = LOW_OBJ_LAYER + flags = HEAR +@@ -48,10 +44,13 @@ var/list/holopads = list() + obj_integrity = 300 + max_integrity = 300 + armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0) +- var/list/masters = list()//List of AIs that use the holopad ++ var/list/masters = list()//List of living mobs that use the holopad + var/last_request = 0 //to prevent request spam. ~Carn + var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating. + var/temp = "" ++ var/list/holo_calls //array of /datum/holocalls ++ var/datum/holocall/outgoing_call //do not modify the datums only check and call the public procs ++ var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging + + /obj/machinery/holopad/Initialize() + ..() +@@ -94,20 +101,60 @@ var/list/holopads = list() + return + return ..() + ++/obj/machinery/holopad/proc/CheckCallClose() ++ for(var/I in holo_calls) ++ var/datum/holocall/HC = I ++ if(usr == HC.eye) ++ HC.Disconnect(HC.calling_holopad) //disconnect via clicking the called holopad ++ return TRUE ++ return FALSE ++ ++/obj/machinery/holopad/Click(location,control,params) ++ if(!CheckCallClose()) ++ return ..() ++ + /obj/machinery/holopad/AltClick(mob/living/carbon/human/user) +- interact(user) ++ if(!CheckCallClose()) ++ interact(user) + + /obj/machinery/holopad/interact(mob/living/carbon/human/user) //Carn: Hologram requests. + if(!istype(user)) + return +- if(user.stat || stat & (NOPOWER|BROKEN)) ++ if(user.incapacitated() || !is_operational()) ++ return ++ ++ if(outgoing_call) //someone is making a call, leave them be + return ++ + user.set_machine(src) + var/dat + if(temp) + dat = temp + else +- dat = "request an AI's presence." ++ dat = "Request an AI's presence.
" ++ dat += "Call another holopad.
" ++ ++ if(LAZYLEN(holo_calls)) ++ dat += "=====================================================
" ++ ++ var/one_answered_call = FALSE ++ var/one_unanswered_call = FALSE ++ for(var/I in holo_calls) ++ var/datum/holocall/HC = I ++ if(HC.connected_holopad != src) ++ dat += "Answer call from [get_area(HC.calling_holopad)].
" ++ one_unanswered_call = TRUE ++ else ++ one_answered_call = TRUE ++ ++ if(one_answered_call && one_unanswered_call) ++ dat += "=====================================================
" ++ //we loop twice for formatting ++ for(var/I in holo_calls) ++ var/datum/holocall/HC = I ++ if(HC.connected_holopad == src) ++ dat += "Disconnect call from [HC.user].
" ++ + + var/datum/browser/popup = new(user, "holopad", name, 300, 130) + popup.set_content(dat) +@@ -115,7 +162,10 @@ var/list/holopads = list() + popup.open() + + /obj/machinery/holopad/Topic(href, href_list) +- if(..()) ++ if(..() || isAI(usr)) ++ return ++ add_fingerprint(usr) ++ if(!is_operational()) + return + if (href_list["AIrequest"]) + if(last_request + 200 < world.time) +@@ -194,59 +317,81 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ + for(var/mob/living/silicon/ai/master in masters) + if(masters[master] && speaker != master) + master.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans) ++ ++ for(var/I in holo_calls) ++ var/datum/holocall/HC = I ++ if(HC.connected_holopad == src && speaker != HC.hologram) ++ HC.user.Hear(message, speaker, message_langs, raw_message, radio_freq, spans) ++ ++ if(outgoing_call && speaker == outgoing_call.user) ++ outgoing_call.hologram.say(raw_message) ++ ++/obj/machinery/holopad/proc/SetLightsAndPower() ++ var/total_users = masters.len + LAZYLEN(holo_calls) ++ use_power = HOLOPAD_PASSIVE_POWER_USAGE + HOLOGRAM_POWER_USAGE * total_users ++ if(total_users) ++ set_light(2) ++ icon_state = "holopad1" ++ else ++ set_light(0) ++ icon_state = "holopad0" + +-/obj/machinery/holopad/proc/create_holo(mob/living/silicon/ai/A, turf/T = loc) +- var/obj/effect/overlay/holo_pad_hologram/h = new(T)//Spawn a blank effect at the location. +- h.icon = A.holo_icon +- h.mouse_opacity = 0//So you can't click on it. +- h.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. +- h.anchored = 1//So space wind cannot drag it. +- h.name = "[A.name] (Hologram)"//If someone decides to right click. +- h.set_light(2) //hologram lighting +- set_holo(A, h) +- return TRUE +- +-/obj/machinery/holopad/proc/set_holo(mob/living/silicon/ai/A, var/obj/effect/overlay/holo_pad_hologram/h) +- masters[A] = h +- set_light(2) // pad lighting +- icon_state = "holopad1" +- A.current = src +- use_power += HOLOGRAM_POWER_USAGE ++/obj/machinery/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h) ++ masters[user] = h ++ var/mob/living/silicon/ai/AI = user ++ if(istype(AI)) ++ AI.current = src ++ SetLightsAndPower() + return TRUE + +-/obj/machinery/holopad/proc/clear_holo(mob/living/silicon/ai/user) ++/obj/machinery/holopad/proc/clear_holo(mob/living/user) + qdel(masters[user]) // Get rid of user's hologram + unset_holo(user) + return TRUE + +-/obj/machinery/holopad/proc/unset_holo(mob/living/silicon/ai/user) +- if(user.current == src) +- user.current = null ++/obj/machinery/holopad/proc/unset_holo(mob/living/user) ++ var/mob/living/silicon/ai/AI = user ++ if(istype(AI) && AI.current == src) ++ AI.current = null + masters -= user // Discard AI from the list of those who use holopad +- use_power = max(HOLOPAD_PASSIVE_POWER_USAGE, use_power - HOLOGRAM_POWER_USAGE)//Reduce power usage +- if (!masters.len) // If no users left +- set_light(0) // pad lighting (hologram lighting will be handled automatically since its owner was deleted) +- icon_state = "holopad0" +- use_power = HOLOPAD_PASSIVE_POWER_USAGE ++ SetLightsAndPower() + return TRUE + +-/obj/machinery/holopad/proc/move_hologram(mob/living/silicon/ai/user) ++/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf) + if(masters[user]) +- step_to(masters[user], user.eyeobj) + var/obj/effect/overlay/holo_pad_hologram/H = masters[user] +- H.loc = get_turf(user.eyeobj) ++ step_to(H, new_turf) ++ H.loc = new_turf ++ var/area/holo_area = get_area(src) ++ var/area/eye_area = new_turf.loc ++ ++ if(!(eye_area in holo_area.related)) ++ clear_holo(user) + return TRUE + ++/obj/effect/overlay/holo_pad_hologram ++ var/mob/living/Impersonation ++ var/datum/holocall/HC ++ ++/obj/effect/overlay/holo_pad_hologram/Destroy() ++ Impersonation = null ++ if(HC) ++ HC.Disconnect(HC.calling_holopad) ++ return ..() ++ + /obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0) + return 1 + ++/obj/effect/overlay/holo_pad_hologram/examine(mob/user) ++ if(Impersonation) ++ return Impersonation.examine(user) ++ return ..() ++ + /obj/item/weapon/circuitboard/machine/holopad + name = "AI Holopad (Machine Board)" + build_path = /obj/machinery/holopad + origin_tech = "programming=1" + req_components = list(/obj/item/weapon/stock_parts/capacitor = 1) + +-#undef RANGE_BASED +-#undef AREA_BASED + #undef HOLOPAD_PASSIVE_POWER_USAGE +-#undef HOLOGRAM_POWER_USAGE ++#undef HOLOGRAM_POWER_USAGE +\ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index dce38bd664..56c43211e4 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -28,7 +28,7 @@ //Holopad if(istype(ai.current, /obj/machinery/holopad)) var/obj/machinery/holopad/H = ai.current - H.move_hologram(ai) + H.move_hologram(ai, T) /mob/camera/aiEye/Move() return 0 diff --git a/tgstation.dme.rej b/tgstation.dme.rej new file mode 100644 index 0000000000..0f29d8f023 --- /dev/null +++ b/tgstation.dme.rej @@ -0,0 +1,9 @@ +diff a/tgstation.dme b/tgstation.dme (rejected hunks) +@@ -206,6 +206,7 @@ + #include "code\datums\emotes.dm" + #include "code\datums\forced_movement.dm" + #include "code\datums\gas_overrides.dm" ++#include "code\datums\holocall.dm" + #include "code\datums\hud.dm" + #include "code\datums\map_config.dm" + #include "code\datums\martial.dm" From 00164a49a71928a38fbd3144b20c729e638141bb Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 May 2017 13:06:07 -0500 Subject: [PATCH 03/23] Subsystem change for the SM and TEG and slight QoL --- code/modules/power/generator.dm | 36 ++++++++++++++----- code/modules/power/generator.dm.rej | 13 +++++++ code/modules/power/supermatter/supermatter.dm | 5 ++- 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 code/modules/power/generator.dm.rej diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index dfbf3fe50b..70d4ea27a2 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -33,6 +33,7 @@ cold_circ = locate(circpath) in get_step(src, cold_dir) hot_circ = locate(circpath) in get_step(src, hot_dir) connect_to_network() + SSair.atmos_machinery += src if(cold_circ) switch(cold_dir) @@ -54,7 +55,10 @@ stat |= BROKEN update_icon() - + +/obj/machinery/power/generator/Destroy() + SSair.atmos_machinery -= src + return ..() /obj/machinery/power/generator/update_icon() @@ -104,7 +108,7 @@ var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity) var/heat = energy_transfer*(1-efficiency) - lastgen = energy_transfer*efficiency + lastgen += energy_transfer*efficiency //to_chat(world, "lastgen = [lastgen]; heat = [heat]; delta_temperature = [delta_temperature]; hot_air_heat_capacity = [hot_air_heat_capacity]; cold_air_heat_capacity = [cold_air_heat_capacity];") @@ -113,7 +117,7 @@ //to_chat(world, "POWER: [lastgen] W generated at [efficiency*100]% efficiency and sinks sizes [cold_air_heat_capacity], [hot_air_heat_capacity]") - add_avail(lastgen) + //add_avail(lastgen) This is done in process now // update icon overlays only if displayed level has changed if(hot_air) @@ -123,15 +127,23 @@ if(cold_air) var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1 cold_circ_air1.merge(cold_air) + + update_icon() - var/genlev = max(0, min( round(11*lastgen / 100000), 11)) var/circ = "[cold_circ && cold_circ.last_pressure_delta > 0 ? "1" : "0"][hot_circ && hot_circ.last_pressure_delta > 0 ? "1" : "0"]" - if((genlev != lastgenlev) || (circ != lastcirc)) - lastgenlev = genlev + if(circ != lastcirc) lastcirc = circ update_icon() src.updateDialog() + +/obj/machinery/power/generator/process() + //Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math** + var/power_output = round(lastgen / 10) + add_avail(power_output) + lastgenlev = power_output + lastgen -= power_output + ..() /obj/machinery/power/generator/attack_hand(mob/user) if(..()) @@ -150,9 +162,15 @@ var/datum/gas_mixture/hot_circ_air2 = hot_circ.AIR2 t += "
" - - t += "Output: [round(lastgen)] W" - + + var/displaygen = lastgenlev + if(displaygen < 1000000) //less than a MW + displaygen /= 1000 + t += "Output: [round(displaygen,0.01)] kW" + else + displaygen /= 1000000 + t += "Output: [round(displaygen,0.01)] MW" + t += "
" t += "Cold loop
" diff --git a/code/modules/power/generator.dm.rej b/code/modules/power/generator.dm.rej new file mode 100644 index 0000000000..9de6ba6b3a --- /dev/null +++ b/code/modules/power/generator.dm.rej @@ -0,0 +1,13 @@ +diff a/code/modules/power/generator.dm b/code/modules/power/generator.dm (rejected hunks) +@@ -64,9 +64,8 @@ + else + cut_overlays() + +- var/L = min(round(lastgenlev/100000),11) +- +- if(L != 0) ++ var/L = min(round(lastgenlev/100000),11) ++ if(L != 0) + add_overlay(image('icons/obj/power.dmi', "teg-op[L]")) + + add_overlay("teg-oc[lastcirc]") diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index fee8859de4..095a023fba 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -129,6 +129,7 @@ /obj/machinery/power/supermatter_shard/New() . = ..() + SSair.atmos_machinery += src countdown = new(src) countdown.start() GLOB.poi_list |= src @@ -139,6 +140,7 @@ /obj/machinery/power/supermatter_shard/Destroy() investigate_log("has been destroyed.", "supermatter") + SSair.atmos_machinery -= src QDEL_NULL(radio) GLOB.poi_list -= src QDEL_NULL(countdown) @@ -181,7 +183,7 @@ E.energy = power qdel(src) -/obj/machinery/power/supermatter_shard/process() +/obj/machinery/power/supermatter_shard/process_atmos() var/turf/T = loc if(isnull(T)) // We have a null turf...something is wrong, stop processing this entity. @@ -296,6 +298,7 @@ if(produces_gas) env.merge(removed) + air_update_turf() for(var/mob/living/carbon/human/l in view(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them. if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) From b45d4ba6685f3bf705d62a3f65e26e2a47c41c38 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 May 2017 17:32:29 -0500 Subject: [PATCH 04/23] Makes admin sound announcement use the right span --- code/modules/admin/verbs/playsound.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index ddc44592c0..613881281e 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -21,7 +21,7 @@ var/res = alert(usr, "Show the title of this song to the players?",, "No", "Yes", "Cancel") switch(res) if("Yes") - to_chat(world, "An admin played: [S]") + to_chat(world, "An admin played: [S]") if("Cancel") return From d29de62d697a87b6e6b1a124d663cde2ea643294 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 May 2017 17:34:34 -0500 Subject: [PATCH 05/23] Plants now react with turfs on squash() --- code/modules/hydroponics/grown.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 555df764b8..5104ab333a 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -111,6 +111,7 @@ for(var/datum/plant_gene/trait/trait in seed.genes) trait.on_squash(src, target) + reagents.reaction(T) for(var/A in T) reagents.reaction(A) From aa45f555e348415c6725f6cfc72ebe32cfd39a19 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 May 2017 04:57:29 -0500 Subject: [PATCH 06/23] Makes the cult Talisman of Horrors ranged --- code/game/gamemodes/cult/ritual.dm | 2 +- code/game/gamemodes/cult/talisman.dm | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 2ed6840c91..cc8c97fb9b 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -133,7 +133,7 @@ This file contains the arcane tome files. text += "Talisman of Armaments
The Talisman of Arming will equip the user with armored robes, a backpack, an eldritch longsword, an empowered bola, and a pair of boots. Any items that cannot \ be equipped will not be summoned. Attacking a fellow cultist with it will instead equip them.

" - text += "Talisman of Horrors
The Talisman of Horror must be applied directly to the victim, it will shatter your victim's mind with visions of the endtimes that may incapitate them.

" + text += "Talisman of Horrors
The Talisman of Horror, unlike other talismans, can be applied at range, without the victim noticing. It will cause the victim to have severe hallucinations after a short while.

" text += "Talisman of Shackling
The Talisman of Shackling must be applied directly to the victim, it has 4 uses and cuffs victims with magic shackles that disappear when removed.

" diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 2876e80373..d2e1fcaf10 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -309,12 +309,12 @@ invocation = "Lo'Nab Na'Dm!" creation_time = 80 -/obj/item/weapon/paper/talisman/horror/attack(mob/living/target, mob/living/user) - if(iscultist(user)) - to_chat(user, "You disturb [target] with visons of the end!") +/obj/item/weapon/paper/talisman/horror/afterattack(mob/living/target, mob/living/user) + if(iscultist(user) && (get_dist(user, target) < 7)) + to_chat(user, "You disturb [target] with visions of madness!") if(iscarbon(target)) var/mob/living/carbon/H = target - H.reagents.add_reagent("mindbreaker", 25) + H.reagents.add_reagent("mindbreaker", 12) if(is_servant_of_ratvar(target)) to_chat(target, "You see a brief but horrible vision of Ratvar, rusted and scrapped, being torn apart.") target.emote("scream") From d422b9bb39b441b5a8d6bbcdd78d19bff417f299 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 May 2017 09:57:25 -0500 Subject: [PATCH 07/23] The alien hivemind uses a mob's real_name --- code/modules/mob/living/carbon/alien/say.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm index 72162387ee..12c131b3cc 100644 --- a/code/modules/mob/living/carbon/alien/say.dm +++ b/code/modules/mob/living/carbon/alien/say.dm @@ -1,4 +1,4 @@ -/mob/living/proc/alien_talk(message, shown_name = name) +/mob/living/proc/alien_talk(message, shown_name = real_name) log_say("[key_name(src)] : [message]") message = trim(message) if(!message) return From 7baccb8b85ffca86c37cb905fe5ca281a656d268 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 May 2017 12:47:20 -0500 Subject: [PATCH 08/23] Removes vestigial list from minds. --- code/datums/mind.dm | 2 -- code/modules/admin/verbs/randomverbs.dm | 1 - code/modules/spells/spell_types/mind_transfer.dm | 15 --------------- 3 files changed, 18 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 0acd33ad69..9e764fb5e4 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -44,9 +44,7 @@ var/datum/job/assigned_job var/list/datum/objective/objectives = list() - var/list/datum/objective/special_verbs = list() - var/list/cult_words = list() var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. var/datum/faction/faction //associated faction diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 547e8e1d03..f1bf4d6969 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -350,7 +350,6 @@ Traitors and the like can also be revived with the previous role mostly intact. if(G_found.mind && !G_found.mind.active) G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use - new_character.mind.special_verbs = list() else new_character.mind_initialize() if(!new_character.mind.assigned_role) diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/mind_transfer.dm index 7ebafe6e24..052c1f1162 100644 --- a/code/modules/spells/spell_types/mind_transfer.dm +++ b/code/modules/spells/spell_types/mind_transfer.dm @@ -62,29 +62,14 @@ Also, you never added distance checking after target is selected. I've went ahea var/mob/caster = user//The wizard/whomever doing the body transferring. //MIND TRANSFER BEGIN - if(caster.mind.special_verbs.len)//If the caster had any special verbs, remove them from the mob verb list. - for(var/V in caster.mind.special_verbs)//Since the caster is using an object spell system, this is mostly moot. - caster.verbs -= V//But a safety nontheless. - - if(victim.mind.special_verbs.len)//Now remove all of the victim's verbs. - for(var/V in victim.mind.special_verbs) - victim.verbs -= V - var/mob/dead/observer/ghost = victim.ghostize(0) caster.mind.transfer_to(victim) - if(victim.mind.special_verbs.len)//To add all the special verbs for the original caster. - for(var/V in caster.mind.special_verbs)//Not too important but could come into play. - caster.verbs += V - ghost.mind.transfer_to(caster) if(ghost.key) caster.key = ghost.key //have to transfer the key since the mind was not active qdel(ghost) - if(caster.mind.special_verbs.len)//If they had any special verbs, we add them here. - for(var/V in caster.mind.special_verbs) - caster.verbs += V //MIND TRANSFER END //Here we paralyze both mobs and knock them out for a time. From 8a221b96376abb7916103e02bb71d0fb65b60f96 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 3 May 2017 05:55:15 -0500 Subject: [PATCH 09/23] Ports pastries to Initialize --- .../food_and_drinks/food/snacks_pastry.dm | 16 ++++++++-------- .../chemistry/machinery/reagentgrinder.dm | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 76ef327bb6..6081838669 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -13,8 +13,8 @@ filling_color = "#D2691E" tastes = list("donut" = 1) -/obj/item/weapon/reagent_containers/food/snacks/donut/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/donut/Initialize() + . = ..() if(prob(30)) icon_state = "donut2" name = "frosted donut" @@ -28,8 +28,8 @@ bitesize = 10 tastes = list("donut" = 3, "chaos" = 1) -/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/Initialize() + . = ..() extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine") reagents.add_reagent("[extra_reagent]", 3) bonus_reagents = list("[extra_reagent]" = 3, "sugar" = 1) @@ -48,8 +48,8 @@ extra_reagent = "berryjuice" tastes = list("jelly" = 1, "donut" = 3) -/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/Initialize() + . = ..() if(extra_reagent) reagents.add_reagent("[extra_reagent]", 3) if(prob(30)) @@ -210,13 +210,13 @@ filling_color = "#F0E68C" tastes = list("mushroom" = 1, "biscuit" = 1) -/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/New() +/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/Initialize() var/fey = prob(10) if(fey) name = "exceptional plump helmet biscuit" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" bonus_reagents = list("omnizine" = 5, "nutriment" = 1, "vitamin" = 1) - ..() + . = ..() if(fey) reagents.add_reagent("omnizine", 5) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 2dbc0ff1c2..a8ab8fd426 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -38,7 +38,7 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/rice = list("rice" = -5), - /obj/item/weapon/reagent_containers/food/snacks/donut/New = list("sprinkles" = -2, "sugar" = 1), + /obj/item/weapon/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1), /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), /obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5), From e8fe273cc06713553a9a0619247aae181a5bf5c8 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Thu, 4 May 2017 16:07:53 -0700 Subject: [PATCH 10/23] Update flightpacks.dm --- code/controllers/subsystem/processing/flightpacks.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/processing/flightpacks.dm b/code/controllers/subsystem/processing/flightpacks.dm index 1d85811878..0639f64810 100644 --- a/code/controllers/subsystem/processing/flightpacks.dm +++ b/code/controllers/subsystem/processing/flightpacks.dm @@ -5,7 +5,7 @@ PROCESSING_SUBSYSTEM_DEF(flightpacks) stat_tag = "FM" flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING - var/flightsuit_processing = FLIGHTSUIT_PROCESSING_FULL + var/flightsuit_processing = FLIGHTSUIT_PROCESSING_NONE /datum/controller/subsystem/processing/flightpacks/Initialize() sync_flightsuit_processing() From 067e0b46edadc59a733dcc46bd815231a7ab6688 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 4 May 2017 19:45:08 -0500 Subject: [PATCH 11/23] Removes changeling genetic damage --- .../gamemodes/changeling/changeling_power.dm | 11 +---------- .../gamemodes/changeling/powers/absorb.dm | 1 - .../gamemodes/changeling/powers/biodegrade.dm | 3 --- .../changeling/powers/chameleon_skin.dm | 3 --- .../gamemodes/changeling/powers/fakedeath.dm | 2 -- .../gamemodes/changeling/powers/humanform.dm | 3 --- .../gamemodes/changeling/powers/lesserform.dm | 1 - .../gamemodes/changeling/powers/linglink.dm | 1 - .../gamemodes/changeling/powers/mutations.dm | 19 +++---------------- .../gamemodes/changeling/powers/tiny_prick.dm | 10 +++------- .../gamemodes/changeling/powers/transform.dm | 1 - 11 files changed, 7 insertions(+), 48 deletions(-) diff --git a/code/game/gamemodes/changeling/changeling_power.dm b/code/game/gamemodes/changeling/changeling_power.dm index 67eb216d58..489228a30c 100644 --- a/code/game/gamemodes/changeling/changeling_power.dm +++ b/code/game/gamemodes/changeling/changeling_power.dm @@ -13,8 +13,6 @@ var/req_dna = 0 //amount of dna needed to use this ability. Changelings always have atleast 1 var/req_human = 0 //if you need to be human to use this ability var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD - var/genetic_damage = 0 // genetic damage caused by using the sting. Nothing to do with cloneloss. - var/max_genetic_damage = 100 // hard counter for spamming abilities. Not used/balanced much yet. var/always_keep = 0 // important for abilities like revive that screw you if you lose them. var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag @@ -39,7 +37,7 @@ if(sting_action(user, target)) SSblackbox.add_details("changeling_powers",name) sting_feedback(user, target) - take_chemical_cost(c) + c.chem_charges -= chemical_cost /obj/effect/proc_holder/changeling/proc/sting_action(mob/user, mob/target) return 0 @@ -47,10 +45,6 @@ /obj/effect/proc_holder/changeling/proc/sting_feedback(mob/user, mob/target) return 0 -/obj/effect/proc_holder/changeling/proc/take_chemical_cost(datum/changeling/changeling) - changeling.chem_charges -= chemical_cost - changeling.geneticdamage += genetic_damage - //Fairly important to remember to return 1 on success >.< /obj/effect/proc_holder/changeling/proc/can_sting(mob/user, mob/target) if(!ishuman(user) && !ismonkey(user)) //typecast everything from mob to carbon from this point onwards @@ -71,9 +65,6 @@ if((user.status_flags & FAKEDEATH) && (!ignores_fakedeath)) to_chat(user, "We are incapacitated.") return 0 - if(c.geneticdamage > max_genetic_damage) - to_chat(user, "Our genomes are still reassembling. We need time to recover first.") - return 0 return 1 //used in /mob/Stat() diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 6a52ab9312..b6b3372ae3 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -4,7 +4,6 @@ chemical_cost = 0 dna_cost = 0 req_human = 1 - max_genetic_damage = 100 /obj/effect/proc_holder/changeling/absorbDNA/can_sting(mob/living/carbon/user) if(!..()) diff --git a/code/game/gamemodes/changeling/powers/biodegrade.dm b/code/game/gamemodes/changeling/powers/biodegrade.dm index 453dec9375..6e2d6b0ddd 100644 --- a/code/game/gamemodes/changeling/powers/biodegrade.dm +++ b/code/game/gamemodes/changeling/powers/biodegrade.dm @@ -5,9 +5,6 @@ chemical_cost = 30 //High cost to prevent spam dna_cost = 2 req_human = 1 - genetic_damage = 10 - max_genetic_damage = 0 - /obj/effect/proc_holder/changeling/biodegrade/sting_action(mob/living/carbon/human/user) var/used = FALSE // only one form of shackles removed per use diff --git a/code/game/gamemodes/changeling/powers/chameleon_skin.dm b/code/game/gamemodes/changeling/powers/chameleon_skin.dm index 1f18f628a8..3be5103105 100644 --- a/code/game/gamemodes/changeling/powers/chameleon_skin.dm +++ b/code/game/gamemodes/changeling/powers/chameleon_skin.dm @@ -5,9 +5,6 @@ dna_cost = 2 chemical_cost = 25 req_human = 1 - genetic_damage = 10 - max_genetic_damage = 50 - /obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user) var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1 diff --git a/code/game/gamemodes/changeling/powers/fakedeath.dm b/code/game/gamemodes/changeling/powers/fakedeath.dm index 798f8030e0..e35f04d9e7 100644 --- a/code/game/gamemodes/changeling/powers/fakedeath.dm +++ b/code/game/gamemodes/changeling/powers/fakedeath.dm @@ -5,8 +5,6 @@ dna_cost = 0 req_dna = 1 req_stat = DEAD - max_genetic_damage = 100 - //Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay. /obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user) diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm index 743dbc91e9..d92e622c2d 100644 --- a/code/game/gamemodes/changeling/powers/humanform.dm +++ b/code/game/gamemodes/changeling/powers/humanform.dm @@ -2,10 +2,7 @@ name = "Human Form" desc = "We change into a human." chemical_cost = 5 - genetic_damage = 3 req_dna = 1 - max_genetic_damage = 3 - //Transform into a human. /obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user) diff --git a/code/game/gamemodes/changeling/powers/lesserform.dm b/code/game/gamemodes/changeling/powers/lesserform.dm index 538803de00..06824f9bed 100644 --- a/code/game/gamemodes/changeling/powers/lesserform.dm +++ b/code/game/gamemodes/changeling/powers/lesserform.dm @@ -3,7 +3,6 @@ desc = "We debase ourselves and become lesser. We become a monkey." chemical_cost = 5 dna_cost = 1 - genetic_damage = 3 req_human = 1 //Transform into a monkey. diff --git a/code/game/gamemodes/changeling/powers/linglink.dm b/code/game/gamemodes/changeling/powers/linglink.dm index fc4b91b650..232774c937 100644 --- a/code/game/gamemodes/changeling/powers/linglink.dm +++ b/code/game/gamemodes/changeling/powers/linglink.dm @@ -4,7 +4,6 @@ chemical_cost = 0 dna_cost = 0 req_human = 1 - max_genetic_damage = 100 /obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user) if(!..()) diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index 54e8ea1e38..aef9b6f1d2 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -16,7 +16,6 @@ helptext = "Yell at Miauw and/or Perakp" chemical_cost = 1000 dna_cost = -1 - genetic_damage = 1000 var/silent = FALSE var/weapon_type @@ -67,7 +66,6 @@ helptext = "Yell at Miauw and/or Perakp" chemical_cost = 1000 dna_cost = -1 - genetic_damage = 1000 var/helmet_type = /obj/item var/suit_type = /obj/item @@ -89,7 +87,7 @@ return 1 var/mob/living/carbon/human/H = user if(istype(H.wear_suit, suit_type) || istype(H.head, helmet_type)) - H.visible_message("[H] casts off their [suit_name_simple]!", "We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]", "You hear the organic matter ripping and tearing!") + H.visible_message("[H] casts off their [suit_name_simple]!", "We cast off our [suit_name_simple].", "You hear the organic matter ripping and tearing!") H.temporarilyRemoveItemFromInventory(H.head, TRUE) //The qdel on dropped() takes care of it H.temporarilyRemoveItemFromInventory(H.wear_suit, TRUE) H.update_inv_wear_suit() @@ -100,7 +98,6 @@ H.add_splatter_floor() playsound(H.loc, 'sound/effects/splat.ogg', 50, 1) //So real sounds - changeling.geneticdamage += genetic_damage //Casting off a space suit leaves you weak for a few seconds. changeling.chem_recharge_slowdown -= recharge_slowdown return 1 @@ -139,9 +136,7 @@ helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form." chemical_cost = 20 dna_cost = 2 - genetic_damage = 10 req_human = 1 - max_genetic_damage = 20 weapon_type = /obj/item/weapon/melee/arm_blade weapon_name_simple = "blade" @@ -217,9 +212,7 @@ and Harm will stun it, and stab it if we're also holding a sharp weapon. Cannot be used while in lesser form." chemical_cost = 10 dna_cost = 2 - genetic_damage = 5 req_human = 1 - max_genetic_damage = 10 weapon_type = /obj/item/weapon/gun/magic/tentacle weapon_name_simple = "tentacle" silent = TRUE @@ -381,9 +374,7 @@ helptext = "Organic tissue cannot resist damage forever; the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form." chemical_cost = 20 dna_cost = 1 - genetic_damage = 12 req_human = 1 - max_genetic_damage = 20 weapon_type = /obj/item/weapon/shield/changeling weapon_name_simple = "shield" @@ -430,12 +421,10 @@ /obj/effect/proc_holder/changeling/suit/organic_space_suit name = "Organic Space Suit" desc = "We grow an organic suit to protect ourselves from space exposure." - helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Retreating the suit damages our genomes. Cannot be used in lesser form." + helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Cannot be used in lesser form." chemical_cost = 20 dna_cost = 2 - genetic_damage = 8 req_human = 1 - max_genetic_damage = 20 suit_type = /obj/item/clothing/suit/space/changeling helmet_type = /obj/item/clothing/head/helmet/space/changeling @@ -477,12 +466,10 @@ /obj/effect/proc_holder/changeling/suit/armor name = "Chitinous Armor" desc = "We turn our skin into tough chitin to protect us from damage." - helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Retreating the armor damages our genomes. Cannot be used in lesser form." + helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form." chemical_cost = 20 dna_cost = 1 - genetic_damage = 11 req_human = 1 - max_genetic_damage = 20 recharge_slowdown = 0.25 suit_type = /obj/item/clothing/suit/armor/changeling diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm index c44a32c24d..ad6bf81e7c 100644 --- a/code/game/gamemodes/changeling/powers/tiny_prick.dm +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -40,10 +40,9 @@ return if(!AStar(user, target.loc, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0)) return - if(target.mind && target.mind.changeling) - sting_feedback(user,target) - take_chemical_cost(user.mind.changeling) - return + if(target.mind && target.mind.changeling) + sting_feedback(user, target) + user.mind.changeling.chem_charges -= chemical_cost return 1 /obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target) @@ -62,7 +61,6 @@ sting_icon = "sting_transform" chemical_cost = 40 dna_cost = 3 - genetic_damage = 100 var/datum/changelingprofile/selected_dna = null /obj/effect/proc_holder/changeling/sting/transformation/Click() @@ -117,8 +115,6 @@ sting_icon = "sting_armblade" chemical_cost = 20 dna_cost = 1 - genetic_damage = 20 - max_genetic_damage = 10 /obj/item/weapon/melee/arm_blade/false desc = "A grotesque mass of flesh that used to be your arm. Although it looks dangerous at first, you can tell it's actually quite dull and useless." diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm index f9aca83d04..9d0b095cc2 100644 --- a/code/game/gamemodes/changeling/powers/transform.dm +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -5,7 +5,6 @@ dna_cost = 0 req_dna = 1 req_human = 1 - max_genetic_damage = 3 /obj/item/clothing/glasses/changeling name = "flesh" From 01d80a0cc073bfd5dbc709256e8a7fd37319bfc9 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 4 May 2017 20:40:05 -0500 Subject: [PATCH 12/23] Takes out an airlock in xenobiology's kill room [Pubby] --- _maps/map_files/PubbyStation/PubbyStation.dmm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index e0e721840d..8310ff2f50 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -32850,10 +32850,6 @@ /turf/open/floor/plasteel/white, /area/toxins/xenobiology) "bnU" = ( -/obj/machinery/door/airlock/research{ - name = "Kill Room Access"; - req_access_txt = "55" - }, /obj/structure/disposalpipe/segment{ dir = 4 }, From d67618815c77a0f90fb3efefb4b72399a72266a8 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 4 May 2017 20:59:29 -0500 Subject: [PATCH 13/23] Mobs that are faking death won't bleed. --- code/modules/mob/living/blood.dm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index ca380170f7..ca8b8f2d9d 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -35,22 +35,21 @@ blood_volume += 0.1 // regenerate blood VERY slowly //Effects of bloodloss + var/word = pick("dizzy","woozy","faint") switch(blood_volume) if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) if(prob(5)) - to_chat(src, "You feel [pick("dizzy","woozy","faint")].") + to_chat(src, "You feel [word].") adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) if(prob(5)) blur_eyes(6) - var/word = pick("dizzy","woozy","faint") to_chat(src, "You feel very [word].") if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) adjustOxyLoss(5) if(prob(15)) Paralyse(rand(1,3)) - var/word = pick("dizzy","woozy","faint") to_chat(src, "You feel extremely [word].") if(0 to BLOOD_VOLUME_SURVIVE) death() @@ -70,7 +69,7 @@ bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases - if(bleed_rate && !bleedsuppress) + if(bleed_rate && !bleedsuppress && !(status_flags & FAKEDEATH)) bleed(bleed_rate) //Makes a blood drop, leaking amt units of blood from the mob From 933a8646bae7db35d8b3ab5affdcc9942bcf040e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 5 May 2017 06:05:05 -0500 Subject: [PATCH 14/23] Only one successful Gang Tool recall per gang --- code/game/gamemodes/gang/gang_datum.dm | 3 ++- code/game/gamemodes/gang/recaller.dm | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/gang/gang_datum.dm b/code/game/gamemodes/gang/gang_datum.dm index 3c54d5436b..805cac552f 100644 --- a/code/game/gamemodes/gang/gang_datum.dm +++ b/code/game/gamemodes/gang/gang_datum.dm @@ -13,6 +13,7 @@ var/list/territory = list() var/list/territory_new = list() var/list/territory_lost = list() + var/recalls = 1 var/dom_attempts = 2 var/points = 15 var/datum/atom_hud/antag/gang/ganghud @@ -262,4 +263,4 @@ ganghud = new() /datum/gang/multiverse/income() - return \ No newline at end of file + return diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm index 0885b32612..f67bcad50a 100644 --- a/code/game/gamemodes/gang/recaller.dm +++ b/code/game/gamemodes/gang/recaller.dm @@ -168,6 +168,9 @@ if(recalling) to_chat(usr, "Error: Recall already in progress.") return 0 + + if(!gang.recalls) + to_chat(usr, "Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.") gang.message_gangtools("[usr] is attempting to recall the emergency shuttle.") recalling = 1 @@ -209,6 +212,7 @@ userturf = get_turf(user) if(userturf.z == 1) //Check one more time that they are on station. if(SSshuttle.cancelEvac(user)) + gang.recalls -= 1 return 1 to_chat(loc, "\icon[src]No response recieved. Emergency shuttle cannot be recalled at this time.") From c3f2e0830480c15245d55b3c402a38329188bbbb Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 5 May 2017 09:39:20 -0500 Subject: [PATCH 15/23] Automatic changelog generation for PR #708 [ci skip] --- html/changelogs/AutoChangeLog-pr-708.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-708.yml diff --git a/html/changelogs/AutoChangeLog-pr-708.yml b/html/changelogs/AutoChangeLog-pr-708.yml new file mode 100644 index 0000000000..6cb7c07312 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-708.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Squishy plants will now affect walls and other turfs they get squished on" From 5d82e4e729fe4ed9c42efca757547748fe55a54a Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 5 May 2017 09:39:55 -0500 Subject: [PATCH 16/23] Automatic changelog generation for PR #714 [ci skip] --- html/changelogs/AutoChangeLog-pr-714.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-714.yml diff --git a/html/changelogs/AutoChangeLog-pr-714.yml b/html/changelogs/AutoChangeLog-pr-714.yml new file mode 100644 index 0000000000..d5e4582f40 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-714.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - tweak: "Blood Cult's talisman of Horrors now works at range. It will still give no warning to the victim." From f902c11f3be28daa0ee88f31dd6948d7214266fe Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 5 May 2017 09:40:09 -0500 Subject: [PATCH 17/23] Automatic changelog generation for PR #717 [ci skip] --- html/changelogs/AutoChangeLog-pr-717.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-717.yml diff --git a/html/changelogs/AutoChangeLog-pr-717.yml b/html/changelogs/AutoChangeLog-pr-717.yml new file mode 100644 index 0000000000..fbb98e0039 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-717.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "When talking on the alien hivemind, a person will be identified by +their real name, rather than who they are disguised as." From fbdbd67f1d7c8de1909f3c78a9ef6407949d7055 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 5 May 2017 09:45:32 -0500 Subject: [PATCH 18/23] Automatic changelog generation for PR #771 [ci skip] --- html/changelogs/AutoChangeLog-pr-771.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-771.yml diff --git a/html/changelogs/AutoChangeLog-pr-771.yml b/html/changelogs/AutoChangeLog-pr-771.yml new file mode 100644 index 0000000000..031ec64151 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-771.yml @@ -0,0 +1,4 @@ +author: "BeeSting12" +delete-after: True +changes: + - bugfix: "Pubbystation no longer has two airlocks stacked on top of each other leading into xenobiology's kill room." From 20f3280c96db8a9a263b370d0b8f66edb91105b4 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 5 May 2017 09:52:47 -0500 Subject: [PATCH 19/23] this one time i ate boiled peanuts --- code/game/machinery/hologram.dm | 381 +++++++++++++++++++------------- tgstation.dme | 1 + 2 files changed, 224 insertions(+), 158 deletions(-) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index ca9cc23380..bc73c41f08 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -26,14 +26,13 @@ Possible to do for anyone motivated enough: #define HOLOPAD_PASSIVE_POWER_USAGE 1 #define HOLOGRAM_POWER_USAGE 2 -#define RANGE_BASED 4 -#define AREA_BASED 6 +GLOBAL_LIST_EMPTY(holopads) #define HOLOPAD_MODE RANGE_BASED /obj/machinery/holopad - name = "\improper AI holopad" - desc = "It's a floor-mounted device for projecting holographic images. It is activated remotely." + name = "Holopad" + desc = "It's a floor-mounted device for projecting holographic images." icon_state = "holopad0" layer = LOW_OBJ_LAYER flags = HEAR @@ -44,29 +43,32 @@ Possible to do for anyone motivated enough: obj_integrity = 300 max_integrity = 300 armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0) - var/list/masters = list()//List of AIs that use the holopad + var/list/masters = list()//List of living mobs that use the holopad var/last_request = 0 //to prevent request spam. ~Carn var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating. var/temp = "" + var/list/holo_calls //array of /datum/holocalls + var/datum/holocall/outgoing_call //do not modify the datums only check and call the public procs + var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging var/static/list/holopads = list() -/obj/machinery/holopad/New() +/obj/machinery/holopad/Initialize() ..() var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/holopad(null) B.apply_default_parts(src) holopads += src /obj/machinery/holopad/Destroy() - if(outgoing_call) - LAZYADD(holo_calls, outgoing_call) - - for(var/I in holo_calls) - var/datum/holocall/HC = I - HC.ConnectionFailure(src) - LAZYCLEARLIST(holo_calls) - - for (var/I in masters) - clear_holo(I) + if(outgoing_call) + LAZYADD(holo_calls, outgoing_call) + + for(var/I in holo_calls) + var/datum/holocall/HC = I + HC.ConnectionFailure(src) + LAZYCLEARLIST(holo_calls) + + for (var/I in masters) + clear_holo(I) holopads -= src return ..() @@ -99,20 +101,58 @@ Possible to do for anyone motivated enough: return return ..() +/obj/machinery/holopad/proc/CheckCallClose() + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(usr == HC.eye) + HC.Disconnect(HC.calling_holopad) //disconnect via clicking the called holopad + return TRUE + return FALSE + +/obj/machinery/holopad/Click(location,control,params) + if(!CheckCallClose()) + return ..() + /obj/machinery/holopad/AltClick(mob/living/carbon/human/user) - interact(user) + if(!CheckCallClose()) + interact(user) /obj/machinery/holopad/interact(mob/living/carbon/human/user) //Carn: Hologram requests. if(!istype(user)) return - if(user.stat || !is_operational()) + + if(outgoing_call || user.incapacitated() || !is_operational()) return + user.set_machine(src) var/dat if(temp) dat = temp else - dat = "request an AI's presence." + dat = "Request an AI's presence.
" + dat += "Call another holopad.
" + + if(LAZYLEN(holo_calls)) + dat += "=====================================================
" + + var/one_answered_call = FALSE + var/one_unanswered_call = FALSE + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad != src) + dat += "Answer call from [get_area(HC.calling_holopad)].
" + one_unanswered_call = TRUE + else + one_answered_call = TRUE + + if(one_answered_call && one_unanswered_call) + dat += "=====================================================
" + //we loop twice for formatting + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad == src) + dat += "Disconnect call from [HC.user].
" + var/datum/browser/popup = new(user, "holopad", name, 300, 130) popup.set_content(dat) @@ -120,7 +160,10 @@ Possible to do for anyone motivated enough: popup.open() /obj/machinery/holopad/Topic(href, href_list) - if(..() || !is_operational()) + if(..() || isAI(usr)) + return + add_fingerprint(usr) + if(!is_operational()) return if (href_list["AIrequest"]) if(last_request + 200 < world.time) @@ -128,7 +171,7 @@ Possible to do for anyone motivated enough: temp = "You requested an AI's presence.
" temp += "Main Menu" var/area/area = get_area(src) - for(var/mob/living/silicon/ai/AI in GLOB.living_mob_list) + for(var/mob/living/silicon/ai/AI in GLOB.silicon_mobs) if(!AI.client) continue to_chat(AI, "Your presence is requested at \the [area].") @@ -136,49 +179,49 @@ Possible to do for anyone motivated enough: temp = "A request for AI presence was already sent recently.
" temp += "Main Menu" - else if(href_list["Holocall"]) - if(outgoing_call) - return - - temp = "You must stand on the holopad to make a call!
" - temp += "Main Menu" - if(usr.loc == loc) - var/list/callnames = list() - for(var/I in holopads) - var/area/A = get_area(I) - if(A) - LAZYADD(callnames[A], I) - callnames -= get_area(src) - - var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames - if(QDELETED(usr) || !result || outgoing_call) - return - - if(usr.loc == loc) - temp = "Dialing...
" - temp += "Main Menu" - new /datum/holocall(usr, src, callnames[result]) - - else if(href_list["connectcall"]) - var/datum/holocall/call_to_connect = locate(href_list["connectcall"]) - if(!QDELETED(call_to_connect)) - call_to_connect.Answer(src) - temp = "" - - else if(href_list["disconnectcall"]) - var/datum/holocall/call_to_disconnect = locate(href_list["disconnectcall"]) - if(!QDELETED(call_to_disconnect)) - call_to_disconnect.Disconnect(src) - temp = "" - + else if(href_list["Holocall"]) + if(outgoing_call) + return + + temp = "You must stand on the holopad to make a call!
" + temp += "Main Menu" + if(usr.loc == loc) + var/list/callnames = list() + for(var/I in holopads) + var/area/A = get_area(I) + if(A) + LAZYADD(callnames[A], I) + callnames -= get_area(src) + + var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames + if(QDELETED(usr) || !result || outgoing_call) + return + + if(usr.loc == loc) + temp = "Dialing...
" + temp += "Main Menu" + new /datum/holocall(usr, src, callnames[result]) + + else if(href_list["connectcall"]) + var/datum/holocall/call_to_connect = locate(href_list["connectcall"]) + if(!QDELETED(call_to_connect)) + call_to_connect.Answer(src) + temp = "" + + else if(href_list["disconnectcall"]) + var/datum/holocall/call_to_disconnect = locate(href_list["disconnectcall"]) + if(!QDELETED(call_to_disconnect)) + call_to_disconnect.Disconnect(src) + temp = "" + else if(href_list["mainmenu"]) temp = "" - if(outgoing_call) - outgoing_call.Disconnect() + if(outgoing_call) + outgoing_call.Disconnect() updateDialog() -//do not allow AIs to answer calls or people will use it to meta the AI sattelite +//do not allow AIs to answer calls or people will use it to meta the AI sattelite /obj/machinery/holopad/attack_ai(mob/living/silicon/ai/user) if (!istype(user)) return @@ -193,75 +236,75 @@ Possible to do for anyone motivated enough: clear_holo(user) /obj/machinery/holopad/process() - for(var/I in masters) - var/mob/living/master = I - var/mob/living/silicon/ai/AI = master - if(!istype(AI)) - AI = null - - if(!QDELETED(master) && !master.incapacitated() && master.client && (!AI || AI.eyeobj))//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector. - if(is_operational())//If the machine has power. - if(AI) //ais are range based - if(get_dist(AI.eyeobj, src) <= holo_range) - continue - else - var/obj/machinery/holopad/pad_close = get_closest_atom(/obj/machinery/holopad, holopads, AI.eyeobj) - if(get_dist(pad_close, AI.eyeobj) <= holo_range) - var/obj/effect/overlay/holo_pad_hologram/h = masters[master] - unset_holo(master) - pad_close.set_holo(master, h) - continue - else - continue - clear_holo(master)//If not, we want to get rid of the hologram. - - if(outgoing_call) - outgoing_call.Check() - - for(var/I in holo_calls) - var/datum/holocall/HC = I - if(HC.connected_holopad != src) - if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2))) - HC.Answer(src) - break - if(outgoing_call) - HC.Disconnect(src)//can't answer calls while calling - else - playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! - -/obj/machinery/holopad/proc/activate_holo(mob/living/user) - var/mob/living/silicon/ai/AI = user - if(!istype(AI)) - AI = null - - if(is_operational() && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it - if (AI && istype(AI.current, /obj/machinery/holopad)) + for(var/I in masters) + var/mob/living/master = I + var/mob/living/silicon/ai/AI = master + if(!istype(AI)) + AI = null + + if(!QDELETED(master) && !master.incapacitated() && master.client && (!AI || AI.eyeobj))//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector. + if(is_operational())//If the machine has power. + if(AI) //ais are range based + if(get_dist(AI.eyeobj, src) <= holo_range) + continue + else + var/obj/machinery/holopad/pad_close = get_closest_atom(/obj/machinery/holopad, holopads, AI.eyeobj) + if(get_dist(pad_close, AI.eyeobj) <= holo_range) + var/obj/effect/overlay/holo_pad_hologram/h = masters[master] + unset_holo(master) + pad_close.set_holo(master, h) + continue + else + continue + clear_holo(master)//If not, we want to get rid of the hologram. + + if(outgoing_call) + outgoing_call.Check() + + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad != src) + if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2))) + HC.Answer(src) + break + if(outgoing_call) + HC.Disconnect(src)//can't answer calls while calling + else + playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! + +/obj/machinery/holopad/proc/activate_holo(mob/living/user) + var/mob/living/silicon/ai/AI = user + if(!istype(AI)) + AI = null + + if(is_operational() && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it + if (AI && istype(AI.current, /obj/machinery/holopad)) to_chat(user, "ERROR: \black Image feed in progress.") return - - var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. - if(AI) - Hologram.icon = AI.holo_icon - else //make it like real life - Hologram.icon = user.icon - Hologram.icon_state = user.icon_state - Hologram.copy_overlays(user, TRUE) - //codersprite some holo effects here - Hologram.alpha = 100 - Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) - Hologram.Impersonation = user - - Hologram.languages_spoken = user.languages_spoken - Hologram.mouse_opacity = 0//So you can't click on it. - Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - Hologram.anchored = 1//So space wind cannot drag it. - Hologram.name = "[user.name] (Hologram)"//If someone decides to right click. - Hologram.set_light(2) //hologram lighting - - set_holo(user, Hologram) - visible_message("A holographic image of [user] flicks to life right before your eyes!") - - return Hologram + + var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. + if(AI) + Hologram.icon = AI.holo_icon + else //make it like real life + Hologram.icon = user.icon + Hologram.icon_state = user.icon_state + Hologram.copy_overlays(user, TRUE) + //codersprite some holo effects here + Hologram.alpha = 100 + Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) + Hologram.Impersonation = user + + Hologram.languages = user.languages + Hologram.mouse_opacity = 0//So you can't click on it. + Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. + Hologram.anchored = 1//So space wind cannot drag it. + Hologram.name = "[user.name] (Hologram)"//If someone decides to right click. + Hologram.set_light(2) //hologram lighting + + set_holo(user, Hologram) + visible_message("A holographic image of [user] flicks to life right before your eyes!") + + return Hologram else to_chat(user, "ERROR: \black Unable to project hologram.") @@ -273,58 +316,80 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ if(masters[master] && speaker != master) master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mode) -/obj/machinery/holopad/proc/create_holo(mob/living/silicon/ai/A, turf/T = loc) - var/obj/effect/overlay/holo_pad_hologram/h = new(T)//Spawn a blank effect at the location. - h.icon = A.holo_icon - h.mouse_opacity = 0//So you can't click on it. - h.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - h.anchored = 1//So space wind cannot drag it. - h.name = "[A.name] (Hologram)"//If someone decides to right click. - h.set_light(2) //hologram lighting - set_holo(A, h) + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad == src && speaker != HC.hologram) + HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans) + + if(outgoing_call && speaker == outgoing_call.user) + outgoing_call.hologram.say(raw_message) + +/obj/machinery/holopad/proc/SetLightsAndPower() + var/total_users = masters.len + LAZYLEN(holo_calls) + use_power = HOLOPAD_PASSIVE_POWER_USAGE + HOLOGRAM_POWER_USAGE * total_users + if(total_users) + set_light(2) + icon_state = "holopad1" + else + set_light(0) + icon_state = "holopad0" + +/obj/machinery/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h) + masters[user] = h + var/mob/living/silicon/ai/AI = user + if(istype(AI)) + AI.current = src + SetLightsAndPower() return TRUE -/obj/machinery/holopad/proc/set_holo(mob/living/silicon/ai/A, var/obj/effect/overlay/holo_pad_hologram/h) - masters[A] = h - set_light(2) // pad lighting - icon_state = "holopad1" - A.current = src - use_power += HOLOGRAM_POWER_USAGE - return TRUE - -/obj/machinery/holopad/proc/clear_holo(mob/living/silicon/ai/user) +/obj/machinery/holopad/proc/clear_holo(mob/living/user) qdel(masters[user]) // Get rid of user's hologram unset_holo(user) return TRUE -/obj/machinery/holopad/proc/unset_holo(mob/living/silicon/ai/user) - if(user.current == src) - user.current = null +/obj/machinery/holopad/proc/unset_holo(mob/living/user) + var/mob/living/silicon/ai/AI = user + if(istype(AI) && AI.current == src) + AI.current = null masters -= user // Discard AI from the list of those who use holopad - use_power = max(HOLOPAD_PASSIVE_POWER_USAGE, use_power - HOLOGRAM_POWER_USAGE)//Reduce power usage - if (!masters.len) // If no users left - set_light(0) // pad lighting (hologram lighting will be handled automatically since its owner was deleted) - icon_state = "holopad0" - use_power = HOLOPAD_PASSIVE_POWER_USAGE + SetLightsAndPower() return TRUE -/obj/machinery/holopad/proc/move_hologram(mob/living/silicon/ai/user) +/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf) if(masters[user]) - step_to(masters[user], user.eyeobj) var/obj/effect/overlay/holo_pad_hologram/H = masters[user] - H.loc = get_turf(user.eyeobj) + step_to(H, new_turf) + H.loc = new_turf + var/area/holo_area = get_area(src) + var/area/eye_area = new_turf.loc + + if(!(eye_area in holo_area.related)) + clear_holo(user) return TRUE +/obj/effect/overlay/holo_pad_hologram + var/mob/living/Impersonation + var/datum/holocall/HC + +/obj/effect/overlay/holo_pad_hologram/Destroy() + Impersonation = null + if(HC) + HC.Disconnect(HC.calling_holopad) + return ..() + /obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0) return 1 +/obj/effect/overlay/holo_pad_hologram/examine(mob/user) + if(Impersonation) + return Impersonation.examine(user) + return ..() + /obj/item/weapon/circuitboard/machine/holopad name = "AI Holopad (Machine Board)" build_path = /obj/machinery/holopad origin_tech = "programming=1" req_components = list(/obj/item/weapon/stock_parts/capacitor = 1) -#undef RANGE_BASED -#undef AREA_BASED #undef HOLOPAD_PASSIVE_POWER_USAGE -#undef HOLOGRAM_POWER_USAGE +#undef HOLOGRAM_POWER_USAGE \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 8f80e4e005..6c0ff5f987 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -243,6 +243,7 @@ #include "code\datums\dog_fashion.dm" #include "code\datums\emotes.dm" #include "code\datums\forced_movement.dm" +#include "code\datums\holocall.dm" #include "code\datums\hud.dm" #include "code\datums\map_config.dm" #include "code\datums\martial.dm" From bbf43a464a26591ac39b49f72b59eb2ce4a5ac71 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 5 May 2017 10:00:17 -0500 Subject: [PATCH 20/23] yey --- code/modules/power/generator.dm | 67 ++++++++++++++++----------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 70d4ea27a2..9fe043a4a0 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -28,12 +28,12 @@ /obj/machinery/power/generator/Initialize(mapload) - . = ..() + . = ..() var/obj/machinery/atmospherics/components/binary/circulator/circpath = /obj/machinery/atmospherics/components/binary/circulator cold_circ = locate(circpath) in get_step(src, cold_dir) hot_circ = locate(circpath) in get_step(src, hot_dir) connect_to_network() - SSair.atmos_machinery += src + SSair.atmos_machinery += src if(cold_circ) switch(cold_dir) @@ -55,10 +55,10 @@ stat |= BROKEN update_icon() - -/obj/machinery/power/generator/Destroy() - SSair.atmos_machinery -= src - return ..() + +/obj/machinery/power/generator/Destroy() + SSair.atmos_machinery -= src + return ..() /obj/machinery/power/generator/update_icon() @@ -67,21 +67,20 @@ else cut_overlays() - if(lastgenlev != 0) - add_overlay("teg-op[lastgenlev]") + var/L = min(round(lastgenlev/100000),11) + if(L != 0) + add_overlay(image('icons/obj/power.dmi', "teg-op[L]")) - add_overlay("teg-oc[lastcirc]") + add_overlay("teg-oc[lastcirc]") #define GENRATE 800 // generator output coefficient from Q -/obj/machinery/power/generator/process() +/obj/machinery/power/generator/process_atmos() if(!cold_circ || !hot_circ) return - lastgen = 0 - if(powernet) //to_chat(world, "cold_circ and hot_circ pass") @@ -108,7 +107,7 @@ var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity) var/heat = energy_transfer*(1-efficiency) - lastgen += energy_transfer*efficiency + lastgen += energy_transfer*efficiency //to_chat(world, "lastgen = [lastgen]; heat = [heat]; delta_temperature = [delta_temperature]; hot_air_heat_capacity = [hot_air_heat_capacity]; cold_air_heat_capacity = [cold_air_heat_capacity];") @@ -117,7 +116,7 @@ //to_chat(world, "POWER: [lastgen] W generated at [efficiency*100]% efficiency and sinks sizes [cold_air_heat_capacity], [hot_air_heat_capacity]") - //add_avail(lastgen) This is done in process now + //add_avail(lastgen) This is done in process now // update icon overlays only if displayed level has changed if(hot_air) @@ -127,23 +126,23 @@ if(cold_air) var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1 cold_circ_air1.merge(cold_air) - - update_icon() + + update_icon() var/circ = "[cold_circ && cold_circ.last_pressure_delta > 0 ? "1" : "0"][hot_circ && hot_circ.last_pressure_delta > 0 ? "1" : "0"]" - if(circ != lastcirc) + if(circ != lastcirc) lastcirc = circ update_icon() src.updateDialog() - -/obj/machinery/power/generator/process() - //Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math** - var/power_output = round(lastgen / 10) - add_avail(power_output) - lastgenlev = power_output - lastgen -= power_output - ..() + +/obj/machinery/power/generator/process() + //Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math** + var/power_output = round(lastgen / 10) + add_avail(power_output) + lastgenlev = power_output + lastgen -= power_output + ..() /obj/machinery/power/generator/attack_hand(mob/user) if(..()) @@ -162,15 +161,15 @@ var/datum/gas_mixture/hot_circ_air2 = hot_circ.AIR2 t += "
" - - var/displaygen = lastgenlev - if(displaygen < 1000000) //less than a MW - displaygen /= 1000 - t += "Output: [round(displaygen,0.01)] kW" - else - displaygen /= 1000000 - t += "Output: [round(displaygen,0.01)] MW" - + + var/displaygen = lastgenlev + if(displaygen < 1000000) //less than a MW + displaygen /= 1000 + t += "Output: [round(displaygen,0.01)] kW" + else + displaygen /= 1000000 + t += "Output: [round(displaygen,0.01)] MW" + t += "
" t += "Cold loop
" From a873459fa4b06730f4fa4286dc3cd7104c448fc7 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 5 May 2017 10:19:29 -0500 Subject: [PATCH 21/23] Automatic changelog generation for PR #698 [ci skip] --- html/changelogs/AutoChangeLog-pr-698.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-698.yml diff --git a/html/changelogs/AutoChangeLog-pr-698.yml b/html/changelogs/AutoChangeLog-pr-698.yml new file mode 100644 index 0000000000..40e55644b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-698.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "You can now make holocalls! Simply stand on a pad, bring up the menu, and select the holopad you wish to call. Remain still until someone answers. When they do, you'll be able to act just like an AI hologram until the call ends" From d2612eaaafca74cf6de4a3b5e338fe13dd99caa5 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 5 May 2017 10:20:13 -0500 Subject: [PATCH 22/23] Automatic changelog generation for PR #701 [ci skip] --- html/changelogs/AutoChangeLog-pr-701.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-701.yml diff --git a/html/changelogs/AutoChangeLog-pr-701.yml b/html/changelogs/AutoChangeLog-pr-701.yml new file mode 100644 index 0000000000..8848bcb450 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-701.yml @@ -0,0 +1,7 @@ +author: "ninjanomnom" +delete-after: True +changes: + - tweak: "TEG displays power in kw or MW now" + - tweak: "TEG power bar only maxes over 1MW now" + - experiment: "Moves TEG to SSair" + - experiment: "Moves SM to SSair" From 1bb43eb7aea5a4b7991f527e454f79b948a55c33 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 5 May 2017 10:21:53 -0500 Subject: [PATCH 23/23] woo --- code/controllers/subsystem/garbage.dm.rej | 9 - code/datums/antagonists/datum_cult.dm.rej | 25 -- code/game/machinery/hologram.dm.rej | 226 ------------------ code/modules/admin/topic.dm.rej | 10 - code/modules/admin/verbs/deadsay.dm.rej | 10 - .../mob/living/carbon/human/death.dm.rej | 10 - code/modules/power/generator.dm.rej | 13 - tgstation.dme.rej | 9 - 8 files changed, 312 deletions(-) delete mode 100644 code/controllers/subsystem/garbage.dm.rej delete mode 100644 code/datums/antagonists/datum_cult.dm.rej delete mode 100644 code/game/machinery/hologram.dm.rej delete mode 100644 code/modules/admin/topic.dm.rej delete mode 100644 code/modules/admin/verbs/deadsay.dm.rej delete mode 100644 code/modules/mob/living/carbon/human/death.dm.rej delete mode 100644 code/modules/power/generator.dm.rej delete mode 100644 tgstation.dme.rej diff --git a/code/controllers/subsystem/garbage.dm.rej b/code/controllers/subsystem/garbage.dm.rej deleted file mode 100644 index 2075155c49..0000000000 --- a/code/controllers/subsystem/garbage.dm.rej +++ /dev/null @@ -1,9 +0,0 @@ -diff a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm (rejected hunks) -@@ -725,7 +725,6 @@ var/datum/controller/subsystem/garbage_collector/SSgarbage - SearchVar(multiverse) - SearchVar(announcement_systems) - SearchVar(doppler_arrays) -- SearchVar(HOLOPAD_MODE) - SearchVar(holopads) - SearchVar(news_network) - SearchVar(allCasters) diff --git a/code/datums/antagonists/datum_cult.dm.rej b/code/datums/antagonists/datum_cult.dm.rej deleted file mode 100644 index 0fc846a73c..0000000000 --- a/code/datums/antagonists/datum_cult.dm.rej +++ /dev/null @@ -1,25 +0,0 @@ -diff a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm (rejected hunks) -@@ -5,13 +5,20 @@ - qdel(communion) - return ..() - -+/datum/antagonist/cult/can_be_owned(datum/mind/new_owner) -+ . = ..() -+ if(.) -+ . = is_convertable_to_cult(new_owner.current) -+ - /datum/antagonist/cult/on_gain() - . = ..() -- if(!owner) -- return -+ SSticker.mode.cult += owner -+ SSticker.mode.update_cult_icons_added(owner) -+ if(istype(SSticker.mode, /datum/game_mode/cult)) -+ var/datum/game_mode/cult/C = SSticker.mode -+ C.memorize_cult_objectives(owner) - if(jobban_isbanned(owner.current, ROLE_CULTIST)) - addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner.current, ROLE_CULTIST, ROLE_CULTIST), 0) -- SSticker.mode.update_cult_icons_added(owner) - owner.current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - - /datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) diff --git a/code/game/machinery/hologram.dm.rej b/code/game/machinery/hologram.dm.rej deleted file mode 100644 index 5dcbcc9d54..0000000000 --- a/code/game/machinery/hologram.dm.rej +++ /dev/null @@ -1,226 +0,0 @@ -diff a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm (rejected hunks) -@@ -26,16 +26,12 @@ Possible to do for anyone motivated enough: - - #define HOLOPAD_PASSIVE_POWER_USAGE 1 - #define HOLOGRAM_POWER_USAGE 2 --#define RANGE_BASED 4 --#define AREA_BASED 6 -- --var/const/HOLOPAD_MODE = RANGE_BASED - - var/list/holopads = list() - - /obj/machinery/holopad -- name = "\improper AI holopad" -- desc = "It's a floor-mounted device for projecting holographic images. It is activated remotely." -+ name = "Holopad" -+ desc = "It's a floor-mounted device for projecting holographic images." - icon_state = "holopad0" - layer = LOW_OBJ_LAYER - flags = HEAR -@@ -48,10 +44,13 @@ var/list/holopads = list() - obj_integrity = 300 - max_integrity = 300 - armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0) -- var/list/masters = list()//List of AIs that use the holopad -+ var/list/masters = list()//List of living mobs that use the holopad - var/last_request = 0 //to prevent request spam. ~Carn - var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating. - var/temp = "" -+ var/list/holo_calls //array of /datum/holocalls -+ var/datum/holocall/outgoing_call //do not modify the datums only check and call the public procs -+ var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging - - /obj/machinery/holopad/Initialize() - ..() -@@ -94,20 +101,60 @@ var/list/holopads = list() - return - return ..() - -+/obj/machinery/holopad/proc/CheckCallClose() -+ for(var/I in holo_calls) -+ var/datum/holocall/HC = I -+ if(usr == HC.eye) -+ HC.Disconnect(HC.calling_holopad) //disconnect via clicking the called holopad -+ return TRUE -+ return FALSE -+ -+/obj/machinery/holopad/Click(location,control,params) -+ if(!CheckCallClose()) -+ return ..() -+ - /obj/machinery/holopad/AltClick(mob/living/carbon/human/user) -- interact(user) -+ if(!CheckCallClose()) -+ interact(user) - - /obj/machinery/holopad/interact(mob/living/carbon/human/user) //Carn: Hologram requests. - if(!istype(user)) - return -- if(user.stat || stat & (NOPOWER|BROKEN)) -+ if(user.incapacitated() || !is_operational()) -+ return -+ -+ if(outgoing_call) //someone is making a call, leave them be - return -+ - user.set_machine(src) - var/dat - if(temp) - dat = temp - else -- dat = "request an AI's presence." -+ dat = "Request an AI's presence.
" -+ dat += "Call another holopad.
" -+ -+ if(LAZYLEN(holo_calls)) -+ dat += "=====================================================
" -+ -+ var/one_answered_call = FALSE -+ var/one_unanswered_call = FALSE -+ for(var/I in holo_calls) -+ var/datum/holocall/HC = I -+ if(HC.connected_holopad != src) -+ dat += "Answer call from [get_area(HC.calling_holopad)].
" -+ one_unanswered_call = TRUE -+ else -+ one_answered_call = TRUE -+ -+ if(one_answered_call && one_unanswered_call) -+ dat += "=====================================================
" -+ //we loop twice for formatting -+ for(var/I in holo_calls) -+ var/datum/holocall/HC = I -+ if(HC.connected_holopad == src) -+ dat += "Disconnect call from [HC.user].
" -+ - - var/datum/browser/popup = new(user, "holopad", name, 300, 130) - popup.set_content(dat) -@@ -115,7 +162,10 @@ var/list/holopads = list() - popup.open() - - /obj/machinery/holopad/Topic(href, href_list) -- if(..()) -+ if(..() || isAI(usr)) -+ return -+ add_fingerprint(usr) -+ if(!is_operational()) - return - if (href_list["AIrequest"]) - if(last_request + 200 < world.time) -@@ -194,59 +317,81 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ - for(var/mob/living/silicon/ai/master in masters) - if(masters[master] && speaker != master) - master.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans) -+ -+ for(var/I in holo_calls) -+ var/datum/holocall/HC = I -+ if(HC.connected_holopad == src && speaker != HC.hologram) -+ HC.user.Hear(message, speaker, message_langs, raw_message, radio_freq, spans) -+ -+ if(outgoing_call && speaker == outgoing_call.user) -+ outgoing_call.hologram.say(raw_message) -+ -+/obj/machinery/holopad/proc/SetLightsAndPower() -+ var/total_users = masters.len + LAZYLEN(holo_calls) -+ use_power = HOLOPAD_PASSIVE_POWER_USAGE + HOLOGRAM_POWER_USAGE * total_users -+ if(total_users) -+ set_light(2) -+ icon_state = "holopad1" -+ else -+ set_light(0) -+ icon_state = "holopad0" - --/obj/machinery/holopad/proc/create_holo(mob/living/silicon/ai/A, turf/T = loc) -- var/obj/effect/overlay/holo_pad_hologram/h = new(T)//Spawn a blank effect at the location. -- h.icon = A.holo_icon -- h.mouse_opacity = 0//So you can't click on it. -- h.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. -- h.anchored = 1//So space wind cannot drag it. -- h.name = "[A.name] (Hologram)"//If someone decides to right click. -- h.set_light(2) //hologram lighting -- set_holo(A, h) -- return TRUE -- --/obj/machinery/holopad/proc/set_holo(mob/living/silicon/ai/A, var/obj/effect/overlay/holo_pad_hologram/h) -- masters[A] = h -- set_light(2) // pad lighting -- icon_state = "holopad1" -- A.current = src -- use_power += HOLOGRAM_POWER_USAGE -+/obj/machinery/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h) -+ masters[user] = h -+ var/mob/living/silicon/ai/AI = user -+ if(istype(AI)) -+ AI.current = src -+ SetLightsAndPower() - return TRUE - --/obj/machinery/holopad/proc/clear_holo(mob/living/silicon/ai/user) -+/obj/machinery/holopad/proc/clear_holo(mob/living/user) - qdel(masters[user]) // Get rid of user's hologram - unset_holo(user) - return TRUE - --/obj/machinery/holopad/proc/unset_holo(mob/living/silicon/ai/user) -- if(user.current == src) -- user.current = null -+/obj/machinery/holopad/proc/unset_holo(mob/living/user) -+ var/mob/living/silicon/ai/AI = user -+ if(istype(AI) && AI.current == src) -+ AI.current = null - masters -= user // Discard AI from the list of those who use holopad -- use_power = max(HOLOPAD_PASSIVE_POWER_USAGE, use_power - HOLOGRAM_POWER_USAGE)//Reduce power usage -- if (!masters.len) // If no users left -- set_light(0) // pad lighting (hologram lighting will be handled automatically since its owner was deleted) -- icon_state = "holopad0" -- use_power = HOLOPAD_PASSIVE_POWER_USAGE -+ SetLightsAndPower() - return TRUE - --/obj/machinery/holopad/proc/move_hologram(mob/living/silicon/ai/user) -+/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf) - if(masters[user]) -- step_to(masters[user], user.eyeobj) - var/obj/effect/overlay/holo_pad_hologram/H = masters[user] -- H.loc = get_turf(user.eyeobj) -+ step_to(H, new_turf) -+ H.loc = new_turf -+ var/area/holo_area = get_area(src) -+ var/area/eye_area = new_turf.loc -+ -+ if(!(eye_area in holo_area.related)) -+ clear_holo(user) - return TRUE - -+/obj/effect/overlay/holo_pad_hologram -+ var/mob/living/Impersonation -+ var/datum/holocall/HC -+ -+/obj/effect/overlay/holo_pad_hologram/Destroy() -+ Impersonation = null -+ if(HC) -+ HC.Disconnect(HC.calling_holopad) -+ return ..() -+ - /obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0) - return 1 - -+/obj/effect/overlay/holo_pad_hologram/examine(mob/user) -+ if(Impersonation) -+ return Impersonation.examine(user) -+ return ..() -+ - /obj/item/weapon/circuitboard/machine/holopad - name = "AI Holopad (Machine Board)" - build_path = /obj/machinery/holopad - origin_tech = "programming=1" - req_components = list(/obj/item/weapon/stock_parts/capacitor = 1) - --#undef RANGE_BASED --#undef AREA_BASED - #undef HOLOPAD_PASSIVE_POWER_USAGE --#undef HOLOGRAM_POWER_USAGE -+#undef HOLOGRAM_POWER_USAGE -\ No newline at end of file diff --git a/code/modules/admin/topic.dm.rej b/code/modules/admin/topic.dm.rej deleted file mode 100644 index 041ae92107..0000000000 --- a/code/modules/admin/topic.dm.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm (rejected hunks) -@@ -8,7 +8,7 @@ - if(href_list["ahelp"]) - if(!check_rights(R_ADMIN)) - return -- -+ - var/ahelp_ref = href_list["ahelp"] - var/datum/admin_help/AH = locate(ahelp_ref) - if(AH) diff --git a/code/modules/admin/verbs/deadsay.dm.rej b/code/modules/admin/verbs/deadsay.dm.rej deleted file mode 100644 index 7d0347427b..0000000000 --- a/code/modules/admin/verbs/deadsay.dm.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm (rejected hunks) -@@ -19,7 +19,7 @@ - - if (!msg) - return -- var/static/nicknames = world.file2list("strings/admin_nicknames.txt") -+ var/static/nicknames = world.file2list("config/admin_nicknames.txt") - - var/rendered = "DEAD: ADMIN([src.holder.fakekey ? pick(nicknames) : src.key]) says, \"[msg]\"" - diff --git a/code/modules/mob/living/carbon/human/death.dm.rej b/code/modules/mob/living/carbon/human/death.dm.rej deleted file mode 100644 index a4a1fc5a7c..0000000000 --- a/code/modules/mob/living/carbon/human/death.dm.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm (rejected hunks) -@@ -32,7 +32,7 @@ - - dna.species.spec_death(gibbed, src) - -- if(SSticker && SSticker.mode) -+ if(SSticker.HasRoundStarted()) - SSblackbox.ReportDeath(src) - if(mind && mind.devilinfo) - INVOKE_ASYNC(mind.devilinfo, /datum/devilinfo.proc/beginResurrectionCheck, src) diff --git a/code/modules/power/generator.dm.rej b/code/modules/power/generator.dm.rej deleted file mode 100644 index 9de6ba6b3a..0000000000 --- a/code/modules/power/generator.dm.rej +++ /dev/null @@ -1,13 +0,0 @@ -diff a/code/modules/power/generator.dm b/code/modules/power/generator.dm (rejected hunks) -@@ -64,9 +64,8 @@ - else - cut_overlays() - -- var/L = min(round(lastgenlev/100000),11) -- -- if(L != 0) -+ var/L = min(round(lastgenlev/100000),11) -+ if(L != 0) - add_overlay(image('icons/obj/power.dmi', "teg-op[L]")) - - add_overlay("teg-oc[lastcirc]") diff --git a/tgstation.dme.rej b/tgstation.dme.rej deleted file mode 100644 index 0f29d8f023..0000000000 --- a/tgstation.dme.rej +++ /dev/null @@ -1,9 +0,0 @@ -diff a/tgstation.dme b/tgstation.dme (rejected hunks) -@@ -206,6 +206,7 @@ - #include "code\datums\emotes.dm" - #include "code\datums\forced_movement.dm" - #include "code\datums\gas_overrides.dm" -+#include "code\datums\holocall.dm" - #include "code\datums\hud.dm" - #include "code\datums\map_config.dm" - #include "code\datums\martial.dm"