This commit is contained in:
Aurorablade
2017-05-11 20:02:46 -04:00
parent 433a2d7cb7
commit 9e312ffadb
7 changed files with 478 additions and 284 deletions
+1 -1
View File
@@ -159,7 +159,7 @@
/atom/proc/AICtrlClick(var/mob/living/silicon/ai/user)
if(user.holo)
var/obj/machinery/hologram/holopad/H = user.holo
H.face_atom(src)
H.face_atom(src)//runtime
return
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
+159
View File
@@ -0,0 +1,159 @@
#define HOLOPAD_MAX_DIAL_TIME 200
/mob/camera/aiEye/remote/holo/setLoc()
. = ..()
var/obj/machinery/hologram/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/hologram/holopad/calling_holopad //the one that sent the call
var/obj/machinery/hologram/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/hologram/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/hologram/holopad/H = I
if(!qdeleted(H) && !(H.stat & NOPOWER))
dialed_holopads += H
LAZYADD(H.holo_calls, src)
if(!dialed_holopads.len)
calling_holopad.visible_message("Connection failure.")
qdel(src)
return
log_debug("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/hologram/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
log_debug("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/hologram/holopad/H)
testing("Holocall disconnect")
if(H == connected_holopad)
calling_holopad.visible_message("[usr] disconnected.")
else if(H == calling_holopad && connected_holopad)
connected_holopad.visible_message("[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/hologram/holopad/H, graceful = FALSE)
testing("Holocall connection failure: graceful [graceful]")
if(H == connected_holopad || H == calling_holopad)
if(!graceful)
calling_holopad.visible_message("Connection failure.")
qdel(src)
return
LAZYREMOVE(H.holo_calls, src)
dialed_holopads -= H
if(!dialed_holopads.len)
if(graceful)
calling_holopad.visible_message("Call rejected.")
log_debug("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/hologram/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")
for(var/I in dialed_holopads)
if(I == H)
continue
Disconnect(I)
for(var/I in H.holo_calls)
var/datum/holocall/HC = I
if(HC != src)
HC.Disconnect(H)
connected_holopad = H
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/hologram/holopad/H = I
if(!(H.stat & NOPOWER))
ConnectionFailure(H)
if(qdeleted(src))
return FALSE
. = !qdeleted(user) && !user.incapacitated() && !qdeleted(calling_holopad) && !(calling_holopad.stat & NOPOWER) && user.loc == calling_holopad.loc
if(.)
if(connected_holopad)
. = !qdeleted(connected_holopad) && !(calling_holopad.stat & NOPOWER)
else
. = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
if(!.)
calling_holopad.visible_message("No answer recieved.")
calling_holopad.temp = ""
if(!.)
log_debug("Holocall Check fail")
qdel(src)
-120
View File
@@ -1,120 +0,0 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
/obj/machinery/computer/hologram_comp
name = "hologram computer"
desc = "Rumoured to control holograms."
icon = 'icons/obj/stationobjs.dmi'
icon_keyboard = "tech_key"
icon_screen = "holocontrol"
var/obj/machinery/hologram/projector/projector = null
var/temp = null
var/lumens = 0.0
var/h_r = 245.0
var/h_g = 245.0
var/h_b = 245.0
/obj/machinery/computer/hologram_comp/New()
..()
spawn( 10 )
src.projector = locate(/obj/machinery/hologram/projector, get_step(src.loc, NORTH))
return
return
/obj/machinery/computer/hologram_comp/attack_hand()
if(!in_range(src, usr))
return 0
src.show_console(usr)
return
/obj/machinery/computer/hologram_comp/proc/render()
var/icon/I = new /icon('icons/mob/human.dmi', "body_m_s")
if(src.lumens >= 0)
I.Blend(rgb(src.lumens, src.lumens, src.lumens), ICON_ADD)
else
I.Blend(rgb(- src.lumens, -src.lumens, -src.lumens), ICON_SUBTRACT)
I.Blend(new /icon('icons/mob/human.dmi', "mouth_m_s"), ICON_OVERLAY)
I.Blend(new /icon('icons/mob/underwear.dmi', "Mens White"), ICON_OVERLAY)
var/icon/U = new /icon('icons/mob/human_face.dmi', "hair_a_s")
U.Blend(rgb(src.h_r, src.h_g, src.h_b), ICON_ADD)
I.Blend(U, ICON_OVERLAY)
src.projector.hologram.icon = I
/obj/machinery/computer/hologram_comp/proc/show_console(var/mob/user as mob)
var/dat
user.set_machine(src)
if(src.temp)
dat = text("[]<BR><BR><A href='?src=[UID()];temp=1'>Clear</A>", src.temp)
else
dat = text({"<B>Hologram Status:</B><HR>\n
Power: <A href='?src=[UID()];power=1'>[]</A><HR>\n
<B>Hologram Control:</B><BR>\n
Color Luminosity: []/220 <A href='?src=[UID()];reset=1'>\[Reset\]</A><BR>\n
Lighten: <A href='?src=[UID()];light=1'>1</A> <A href='?src=[UID()];light=10'>10</A><BR>\n
Darken: <A href='?src=[UID()];light=-1'>1</A> <A href='?src=[UID()];light=-10'>10</A><BR>\n
<BR>\nHair Color: ([],[],[]) <A href='?src=[UID()];h_reset=1'>\[Reset\]</A><BR>\n
Red (0-255): <A href='?src=[UID()];h_r=-300'>\[0\]</A> <A href='?src=[UID()];h_r=-10'>-10</A> <A href='?src=[UID()];h_r=-1'>-1</A> [] <A href='?src=[UID()];h_r=1'>1</A> <A href='?src=[UID()];h_r=10'>10</A> <A href='?src=[UID()];h_r=300'>\[255\]</A><BR>\n
Green (0-255): <A href='?src=[UID()];h_g=-300'>\[0\]</A> <A href='?src=[UID()];h_g=-10'>-10</A> <A href='?src=[UID()];h_g=-1'>-1</A> [] <A href='?src=[UID()];h_g=1'>1</A> <A href='?src=[UID()];h_g=10'>10</A> <A href='?src=[UID()];h_g=300'>\[255\]</A><BR>\n
Blue (0-255): <A href='?src=[UID()];h_b=-300'>\[0\]</A> <A href='?src=[UID()];h_b=-10'>-10</A> <A href='?src=[UID()];h_b=-1'>-1</A> [] <A href='?src=[UID()];h_b=1'>1</A> <A href='?src=[UID()];h_b=10'>10</A> <A href='?src=[UID()];h_b=300'>\[255\]</A><BR>
"}, (src.projector.hologram ? "On" : "Off"), -src.lumens + 35, src.h_r, src.h_g, src.h_b, src.h_r, src.h_g, src.h_b)
user << browse(dat, "window=hologram_console")
onclose(user, "hologram_console")
return
/obj/machinery/computer/hologram_comp/Topic(href, href_list)
if(..())
return 1
if(in_range(src, usr))
flick("holo_console1", src)
if(href_list["power"])
if(src.projector.hologram)
src.projector.icon_state = "hologram0"
//src.projector.hologram = null
qdel(src.projector.hologram)
else
src.projector.hologram = new(src.projector.loc)
src.projector.hologram.icon = 'icons/mob/human.dmi'
src.projector.hologram.icon_state = "body_m_s"
src.projector.icon_state = "hologram1"
src.render()
else
if(href_list["h_r"])
if(src.projector.hologram)
src.h_r += text2num(href_list["h_r"])
src.h_r = min(max(src.h_r, 0), 255)
render()
else
if(href_list["h_g"])
if(src.projector.hologram)
src.h_g += text2num(href_list["h_g"])
src.h_g = min(max(src.h_g, 0), 255)
render()
else
if(href_list["h_b"])
if(src.projector.hologram)
src.h_b += text2num(href_list["h_b"])
src.h_b = min(max(src.h_b, 0), 255)
render()
else
if(href_list["light"])
if(src.projector.hologram)
src.lumens += text2num(href_list["light"])
src.lumens = min(max(src.lumens, -185.0), 35)
render()
else
if(href_list["reset"])
if(src.projector.hologram)
src.lumens = 0
render()
else
if(href_list["temp"])
src.temp = null
for(var/mob/M in viewers(1, src))
if((M.client && M.machine == src))
src.show_console(M)
return
+308 -154
View File
@@ -1,7 +1,7 @@
/* Holograms!
/* holograms!
* Contains:
* Holopad
* Hologram
* hologram
* Other stuff
*/
@@ -9,7 +9,7 @@
Revised. Original based on space ninja hologram code. Which is also mine. /N
How it works:
AI clicks on holopad in camera view. View centers on holopad.
AI clicks again on the holopad to display a hologram. Hologram stays as long as AI is looking at the pad and it (the hologram) is in range of the pad.
AI clicks again on the holopad to display a hologram. hologram stays as long as AI is looking at the pad and it (the hologram) is in range of the pad.
AI can use the directional keys to move the hologram around, provided the above conditions are met and the AI in question is the holopad's master.
Only one AI may project from a holopad at any given time.
AI may cancel the hologram at any time by clicking on the holopad once more.
@@ -27,19 +27,31 @@ Possible to do for anyone motivated enough:
// HOLOPAD MODE
// 0 = RANGE BASED
// 1 = AREA BASED
#define HOLOPAD_PASSIVE_POWER_USAGE 1
#define HOLOGRAM_POWER_USAGE 2
var/const/HOLOPAD_MODE = 0
var/list/holopads = list()
/obj/machinery/hologram/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"
anchored = 1
use_power = 1
idle_power_usage = 5
active_power_usage = 100
layer = TURF_LAYER+0.1 //Preventing mice and drones from sneaking under them.
var/mob/living/silicon/ai/master//Which AI, if any, is controlling the object? Only one AI may control a hologram at any time.
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 = TRUE //Calls will be automatically answered after a couple rings, here for debugging
var/static/list/holopads = list()
/obj/machinery/hologram/holopad/New()
..()
@@ -49,6 +61,21 @@ var/list/holopads = list()
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
RefreshParts()
/obj/machinery/hologram/holopad/Destroy()
if(outgoing_call)
LAZYADD(holo_calls, outgoing_call)
outgoing_call = null
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 ..()
/obj/machinery/hologram/holopad/RefreshParts()
var/holograph_range = 4
for(var/obj/item/weapon/stock_parts/capacitor/B in component_parts)
@@ -68,7 +95,7 @@ var/list/holopads = list()
default_deconstruction_crowbar(P)
/obj/machinery/hologram/holopad/attack_hand(var/mob/living/carbon/human/user) //Carn: Hologram requests.
/obj/machinery/hologram/holopad/attack_hand(var/mob/living/carbon/human/user) //Carn: hologram requests.
if(!istype(user))
return
if(alert(user,"Would you like to request an AI's presence?",,"Yes","No") == "Yes")
@@ -82,184 +109,308 @@ var/list/holopads = list()
else
to_chat(user, "<span class='notice'>A request for AI presence was already sent recently.</span>")
/obj/machinery/hologram/holopad/attack_ai(mob/living/silicon/ai/user)
/obj/machinery/hologram/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/hologram/holopad/Click(location,control,params)
if(!CheckCallClose())
return ..()
/obj/machinery/hologram/holopad/AltClick(mob/living/carbon/human/user)
if(!CheckCallClose())
interact(user)
/obj/machinery/hologram/holopad/interact(mob/living/carbon/human/user) //Carn: hologram requests.
if(!istype(user))
return
if(outgoing_call || user.incapacitated() || !(stat & NOPOWER))
return
user.set_machine(src)
var/dat
if(temp)
dat = temp
else
dat = "<a href='?src=\ref[src];AIrequest=1'>Request an AI's presence.</a><br>"
dat += "<a href='?src=\ref[src];Holocall=1'>Call another holopad.</a><br>"
if(LAZYLEN(holo_calls))
dat += "=====================================================<br>"
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 += "<a href='?src=\ref[src];connectcall=\ref[HC]'>Answer call from [get_area(HC.calling_holopad)].</a><br>"
one_unanswered_call = TRUE
else
one_answered_call = TRUE
if(one_answered_call && one_unanswered_call)
dat += "=====================================================<br>"
//we loop twice for formatting
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad == src)
dat += "<a href='?src=\ref[src];disconnectcall=\ref[HC]'>Disconnect call from [HC.user].</a><br>"
var/datum/browser/popup = new(user, "holopad", name, 300, 130)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/hologram/holopad/Topic(href, href_list)
if(..() || isAI(usr))
return
add_fingerprint(usr)
if(!(stat & NOPOWER))
return
if (href_list["AIrequest"])
if(last_request + 200 < world.time)
last_request = world.time
temp = "You requested an AI's presence.<BR>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
var/area/area = get_area(src)
for(var/mob/living/silicon/ai/AI in ai_list)
if(!AI.client)
continue
to_chat(AI, "<span class='info'>Your presence is requested at <a href='?src=\ref[AI];jumptoholopad=\ref[src]'>\the [area]</a>.</span>")
else
temp = "A request for AI presence was already sent recently.<BR>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
else if(href_list["Holocall"])
if(outgoing_call)
return
temp = "You must stand on the holopad to make a call!<br>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
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...<br>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
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()
//do not allow AIs to answer calls or people will use it to meta the AI sattelite
/obj/machinery/hologram/holopad/attack_ai(mob/living/silicon/ai/user)
if (!istype(user))
return
/*There are pretty much only three ways to interact here.
I don't need to check for client since they're clicking on an object.
This may change in the future but for now will suffice.*/
if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already.
user.eyeobj.setLoc(get_turf(src))
else if(!hologram)//If there is no hologram, possibly make one.
else if(!masters[user])//If there is no hologram, possibly make one.
activate_holo(user, 0)
else if(master == user)//If there is a hologram, remove it. But only if the user is the master. Otherwise do nothing.
clear_holo()
return
else//If there is a hologram, remove it.
clear_holo(user)
/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/silicon/ai/user, var/force = 0)
if(!force && user.eyeobj.loc != src.loc) // allows holopads to pass off holograms to the next holopad in the chain
/obj/machinery/hologram/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(!(stat & NOPOWER))//If the machine has power.
if(AI) //ais are range based
if((HOLOPAD_MODE == 0 && (get_dist(AI.eyeobj, src) <= holo_range)))
return 1
else if(HOLOPAD_MODE == 1)
var/area/holo_area = get_area(src)
var/area/eye_area = get_area(AI.eyeobj)
if(eye_area != holo_area)
return 1
else
var/turf/target_turf = get_turf(AI.eyeobj)
//var/newdir = hologram.dir
clear_holo()//If not, we want to get rid of the hologram.
var/obj/machinery/hologram/holopad/pad_close = get_closest_atom(/obj/machinery/hologram/holopad, holopads, AI.eyeobj)
if(get_dist(pad_close, AI.eyeobj) <= pad_close.holo_range)
if(!(pad_close.stat & NOPOWER) && !pad_close.masters[src])
pad_close.activate_holo(AI, 1)
if(pad_close.masters[src])
pad_close.AI.forceMove(target_turf)
//pad_close.hologram.dir = newdir
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/hologram/holopad/proc/move_hologram(mob/living/user, turf/new_turf)
if(masters[user])
var/obj/effect/overlay/holo_pad_hologram/H = masters[user]
step_to(H, new_turf)
H.loc = new_turf
return 1
/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/user, var/force = 0)
var/mob/living/silicon/ai/AI = user
if(!istype(AI))
AI = null
if(istype(AI) && !force && AI.eyeobj.loc != src.loc) // allows holopads to pass off holograms to the next holopad in the chain
to_chat(user, "<font color='red'>ERROR:</font> Unable to project hologram.")
else if(!(stat & NOPOWER))//If the projector has power
if(user.holo)
var/obj/machinery/hologram/holopad/current = user.holo
current.clear_holo()
if(!hologram)//If there is not already a hologram.
if(!(stat & NOPOWER) && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it
if (AI && istype(AI.current, /obj/machinery/hologram/holopad))
to_chat(user, "<span class='danger'>ERROR:</span> \black Image feed in progress.")
return
if(!masters[user])//If there is not already a hologram.
create_holo(user)//Create one.
src.visible_message("A holographic image of [user] flicks to life right before your eyes!")
else
to_chat(user, "<font color='red'>ERROR:</font> Image feed in progress.")
visible_message("A holographic image of [user] flicks to life right before your eyes!")
else
to_chat(user, "<font color='red'>ERROR:</font> Unable to project hologram.")
return
to_chat(user, "<span class='danger'>ERROR:</span> \black Unable to project hologram.")
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking)
if(M && hologram && master)//Master is mostly a safety in case lag hits or something.
master.relay_speech(M, text, verb, speaking)
/obj/machinery/hologram/holopad/hear_talk(atom/movable/speaker, message, verb, datum/language/message_language)
if(speaker && masters.len)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios.
for(var/mob/living/silicon/ai/master in masters)
if(masters[master] && speaker != master)
master.relay_speech(speaker, message, verb, message_language)
/obj/machinery/hologram/holopad/hear_message(mob/living/M, text)
if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something.
var/name_used = M.GetVoice()
var/rendered = "<i><span class='game say'>Holopad received, <span class='name'>[name_used]</span> [text]</span></i>"
master.show_message(rendered, 2)
return
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, verb, message_language)//<<RUNTIME
/obj/machinery/hologram/holopad/proc/create_holo(mob/living/silicon/ai/A, turf/T = loc)
hologram = new(T)//Spawn a blank effect at the location.
hologram.icon = A.holo_icon
if(outgoing_call && speaker == outgoing_call.user)
outgoing_call.hologram.visible_message(message)
/obj/machinery/hologram/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/hologram/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/hologram/holopad/proc/create_holo(mob/living/user, turf/T = loc)
var/obj/effect/overlay/holo_pad_hologram/hologram = new(loc)//Spawn a blank effect at the location.
if(isAI(user))
var/mob/living/silicon/ai/AI = user
hologram.icon = AI.holo_icon
else //make it like real life
hologram.icon = user.icon
hologram.icon_state = user.icon_state
hologram.alpha = 100
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 = "[A.name] (Hologram)"//If someone decides to right click.
hologram.name = "[user.name] (hologram)"//If someone decides to right click.
hologram.set_light(2) //hologram lighting
set_light(2) //pad lighting
icon_state = "holopad1"
A.holo = src
master = A//AI is the master.
use_power = 2//Active power usage.
set_holo(user, hologram)
return 1
/obj/machinery/hologram/holopad/proc/clear_holo()
// hologram.set_light(0)//Clear lighting. //handled by the lighting controller when its ower is deleted
qdel(hologram)//Get rid of hologram.
hologram = null
if(master.holo == src)
master.holo = null
master = null//Null the master, since no-one is using it now.
set_light(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted)
icon_state = "holopad0"
use_power = 1//Passive power usage.
return 1
/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/user)
qdel(masters[user]) // Get rid of user's hologram
unset_holo(user)
return TRUE
/obj/machinery/hologram/holopad/process()
if(hologram)//If there is a hologram.
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 == 0 && (get_dist(master.eyeobj, src) <= holo_range)))
return 1
/obj/machinery/hologram/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
SetLightsAndPower()
return TRUE
else if(HOLOPAD_MODE == 1)
var/area/holo_area = get_area(src)
var/area/eye_area = get_area(master.eyeobj)
/obj/effect/overlay/holo_pad_hologram
var/mob/living/Impersonation
var/datum/holocall/HC
if(eye_area != holo_area)
return 1
var/mob/living/silicon/ai/theai = master
var/turf/target_turf = get_turf(master.eyeobj)
var/newdir = hologram.dir
clear_holo()//If not, we want to get rid of the hologram.
var/obj/machinery/hologram/holopad/pad_close = get_closest_atom(/obj/machinery/hologram/holopad, holopads, theai.eyeobj)
if(get_dist(pad_close, theai.eyeobj) <= pad_close.holo_range)
if(!(pad_close.stat & NOPOWER) && !pad_close.hologram)
pad_close.activate_holo(theai, 1)
if(pad_close.hologram)
pad_close.hologram.forceMove(target_turf)
pad_close.hologram.dir = newdir
return 1
/obj/machinery/hologram/holopad/proc/move_hologram()
if(hologram)
step_to(hologram, master.eyeobj) // So it turns.
hologram.loc = get_turf(master.eyeobj)
return 1
// Simple helper to face what you clicked on, in case it should be needed in more than one place
/obj/machinery/hologram/holopad/proc/face_atom(var/atom/A)
if( !hologram || !A || !hologram.x || !hologram.y || !A.x || !A.y ) return
var/dx = A.x - hologram.x
var/dy = A.y - hologram.y
if(!dx && !dy) // Wall items are graphically shifted but on the floor
if(A.pixel_y > 16) hologram.dir = NORTH
else if(A.pixel_y < -16)hologram.dir = SOUTH
else if(A.pixel_x > 16) hologram.dir = EAST
else if(A.pixel_x < -16)hologram.dir = WEST
return
if(abs(dx) < abs(dy))
if(dy > 0) hologram.dir = NORTH
else hologram.dir = SOUTH
else
if(dx > 0) hologram.dir = EAST
else hologram.dir = WEST
/*
* Hologram
*/
/obj/machinery/hologram
anchored = 1
use_power = 1
idle_power_usage = 5
active_power_usage = 100
var/obj/effect/overlay/hologram//The projection itself. If there is one, the instrument is on, off otherwise.
//Destruction procs.
/obj/machinery/hologram/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
if(2.0)
if(prob(50))
qdel(src)
if(3.0)
if(prob(5))
qdel(src)
return
/obj/machinery/hologram/blob_act()
qdel(src)
return
/obj/machinery/hologram/holopad/Destroy()
holopads -= src
if(hologram)
clear_holo()
/obj/effect/overlay/holo_pad_hologram/Destroy()
Impersonation = null
if(HC)
HC.Disconnect(HC.calling_holopad)
return ..()
/*
Holographic project of everything else.
/obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0)
return 1
/mob/verb/hologram_test()
set name = "Hologram Debug New"
set category = "CURRENT DEBUG"
/obj/effect/overlay/holo_pad_hologram/examine(mob/user)
if(Impersonation)
return Impersonation.examine(user)
return ..()
var/obj/effect/overlay/hologram = new(loc)//Spawn a blank effect at the location.
var/icon/flat_icon = icon(getFlatIcon(src,0))//Need to make sure it's a new icon so the old one is not reused.
flat_icon.ColorTone(rgb(125,180,225))//Let's make it bluish.
flat_icon.ChangeOpacity(0.5)//Make it half transparent.
var/input = input("Select what icon state to use in effect.",,"")
if(input)
var/icon/alpha_mask = new('icons/effects/effects.dmi', "[input]")
flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect.
hologram.icon = flat_icon
to_chat(world, "Your icon should appear now.")
return
*/
/*
* Other Stuff: Is this even used?
@@ -269,3 +420,6 @@ Holographic project of everything else.
desc = "It makes a hologram appear...with magnets or something..."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "hologram0"
#undef HOLOPAD_PASSIVE_POWER_USAGE
#undef HOLOGRAM_POWER_USAGE
@@ -30,8 +30,9 @@
if(ai.client)
ai.client.eye = src
//Holopad
if(ai.holo)
ai.holo.move_hologram()
if(istype(ai.current, /obj/machinery/hologram/holopad))
var/obj/machinery/hologram/holopad/H = ai.current
H.move_hologram(ai, T)
/mob/camera/aiEye/Move()
return 0
+6 -6
View File
@@ -75,8 +75,8 @@
if(!message)
return
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.hologram && T.master == src)//If there is a hologram and its master is the user.
var/obj/machinery/holopad/T = current
if(istype(T) && T.masters[src])
//Human-like, sorta, heard by those who understand humans.
var/rendered_a
@@ -116,8 +116,8 @@
if(!message)
return
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.hologram && T.master == src)
var/obj/machinery/holopad/T = current
if(istype(T) && T.masters[src])
var/rendered = "<span class='game say'><span class='name'>[name]</span> <span class='message'>[message]</span></span>"
to_chat(src, "<i><span class='game say'>Holopad action relayed, <span class='name'>[real_name]</span> <span class='message'>[message]</span></span></i>")
@@ -129,8 +129,8 @@
return 1
/mob/living/silicon/ai/emote(var/act, var/type, var/message)
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.hologram && T.master == src) //Is the AI using a holopad?
var/obj/machinery/holopad/T = current
if(istype(T) && T.masters[src])//Is the AI using a holopad?
src.holopad_emote(message)
else //Emote normally, then.
..()
+1 -1
View File
@@ -204,6 +204,7 @@
#include "code\datums\datacore.dm"
#include "code\datums\datumvars.dm"
#include "code\datums\gas_mixture.dm"
#include "code\datums\holocall.dm"
#include "code\datums\hud.dm"
#include "code\datums\material_container.dm"
#include "code\datums\mind.dm"
@@ -585,7 +586,6 @@
#include "code\game\machinery\computer\computer.dm"
#include "code\game\machinery\computer\crew.dm"
#include "code\game\machinery\computer\HolodeckControl.dm"
#include "code\game\machinery\computer\hologram.dm"
#include "code\game\machinery\computer\honkputer.dm"
#include "code\game\machinery\computer\law.dm"
#include "code\game\machinery\computer\medical.dm"