Skip to content

Commit

Permalink
feat(device/holopad): add personal holopad device
Browse files Browse the repository at this point in the history
  • Loading branch information
TermService authored Apr 14, 2020
1 parent 25818f3 commit d8dd57f
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 1 deletion.
1 change: 1 addition & 0 deletions baystation12.dme
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,7 @@
#include "code\game\objects\items\devices\floor_painter.dm"
#include "code\game\objects\items\devices\geiger.dm"
#include "code\game\objects\items\devices\hacktool.dm"
#include "code\game\objects\items\devices\holopad.dm"
#include "code\game\objects\items\devices\holowarrant.dm"
#include "code\game\objects\items\devices\lightreplacer.dm"
#include "code\game\objects\items\devices\megaphone.dm"
Expand Down
15 changes: 15 additions & 0 deletions code/_helpers/icons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -996,3 +996,18 @@ proc/generate_image(tx as num, ty as num, tz as num, range as num, cap_mode = CA
return "<img class='icon icon-[icon_state] [class]' style='width:[I.Width()]px;height:[I.Height()]px;min-height:[I.Height()]px' src=\"[url_encode(key)]\">"

return "<img class='icon icon-[icon_state] [class]' src=\"[url_encode(key)]\">"

/proc/build_composite_icon_omnidir(atom/A)
var/icon/composite = icon('icons/effects/effects.dmi', "icon_state"="nothing")
for(var/O in A.underlays)
var/image/I = O
composite.Blend(new /icon(I.icon, I.icon_state), ICON_OVERLAY)
var/icon/ico_omnidir = new(A.icon)
if(A.icon_state in ico_omnidir.IconStates())
composite.Blend(new /icon(ico_omnidir, A.icon_state), ICON_OVERLAY)
else
composite.Blend(new /icon(ico_omnidir, null), ICON_OVERLAY)
for(var/O in A.overlays)
var/image/I = O
composite.Blend(new /icon(I.icon, I.icon_state), ICON_OVERLAY)
return composite
193 changes: 193 additions & 0 deletions code/game/objects/items/devices/holopad.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#define CALL_NONE 0
#define CALL_CALLING 1
#define CALL_RINGING 2
#define CALL_IN_CALL 3

/obj/item/device/holopad
name = "Holopad"
desc = "Small handheld disk with controls."
icon = 'icons/obj/holopad.dmi'
icon_state = "holopad"
item_state = "card-id"
w_class = ITEM_SIZE_SMALL
var/voice
var/id
var/uniq_id
var/obj/item/device/holopad/abonent = null
var/call_state = CALL_NONE
var/obj/effect/hologram = null
var/updatingPos = 0
origin_tech = list(TECH_DATA = 4, TECH_BLUESPACE = 2, TECH_MAGNET = 4)

/obj/item/device/holopad/Initialize()
uniq_id = random_id("holopad_device", 00000, 99999)
id = rand(1000, 9999)
name = "[initial(name)] [id] #[uniq_id]"
voice = "Holopad [id]"
GLOB.listening_objects += src
. = ..()

/obj/item/device/holopad/Destroy()
GLOB.listening_objects -= src
abonent = null
. = ..()


/obj/item/device/holopad/verb/setID()
set name="Set ID"
set category = "Object"
set src in usr
var/newid = sanitize(input(usr, "What would be new ID?") as null|text, MAX_NAME_LEN)
if(newid && CanPhysicallyInteract(usr))
id = newid
name = "[initial(name)] [id] #[uniq_id]"

/obj/item/device/holopad/proc/getName(override_busy = 0)
if(call_state!=CALL_NONE && !override_busy)
return "Holopad [id] #[uniq_id] - busy"
else
return "Holopad [id] #[uniq_id]"

/obj/item/device/holopad/proc/incall(obj/item/device/holopad/caller)
if(call_state != CALL_NONE)
return FALSE
abonent = caller
call_state = CALL_RINGING
icon_state = "holopad_ringing"
desc = "[initial(desc)] Incoming call from [caller.getName()]."
INVOKE_ASYNC(src, .proc/ring)
return TRUE

/obj/item/device/holopad/proc/ring()
if(call_state != CALL_RINGING)
return
audible_message(SPAN_WARNING("Something vibrates.."), hearing_distance = 4)
addtimer(CALLBACK(src, .proc/ring), 50)

/obj/item/device/holopad/proc/placeCall(mob/user)
var/list/Targets = list()
for(var/obj/item/device/holopad/H in GLOB.listening_objects)
if(H == src)
continue
Targets[H.getName()] = H
var/selection = input("Who do you want to call?") as null|anything in Targets
if(!selection)
return
var/obj/item/device/holopad/target = Targets[selection]
if(!target)
return
if(target.incall(src))
call_state = CALL_CALLING
abonent = target
icon_state = "holopad_calling"
to_chat(user, SPAN_NOTICE("Calling [sanitize(abonent.getName(1))]"))
else
to_chat(user, SPAN_WARNING("Remote device is busy"))

/obj/item/device/holopad/proc/acceptCall()
if(call_state == CALL_RINGING)
if(abonent && abonent.call_state == CALL_CALLING)
abonent.acceptCall()
call_state = CALL_IN_CALL
icon_state = "holopad_in_call"
addtimer(CALLBACK(src, .proc/update_holo), 1)

audible_message("<span class='name'>[voice]</span> transmits, \"Connection established\"", hearing_distance = 1)
else
call_state = CALL_NONE
icon_state = initial(icon_state)
desc = initial(desc)
abonent = null

else if(call_state == CALL_CALLING)
call_state = CALL_IN_CALL
icon_state = "holopad_in_call"
addtimer(CALLBACK(src, .proc/update_holo), 1)

audible_message("<span class='name'>[voice]</span> transmits, \"Connection established\"", hearing_distance = 1)

/obj/item/device/holopad/proc/hangUp(remote = 0)
if(!remote && abonent)
abonent.hangUp(1)

if(call_state==CALL_NONE)
return

audible_message(SPAN_WARNING("Connection closed"), hearing_distance = 4)
call_state = CALL_NONE
icon_state = initial(icon_state)
desc = initial(desc)
abonent = null
qdel(hologram)

/obj/item/device/holopad/dropped()
update_holo()

/obj/item/device/holopad/proc/update_holo()
if(call_state == CALL_IN_CALL)
if(!abonent)
return
if(!abonent.hologram)
abonent.hologram = new()
abonent.hologram.name = "Hologram [sanitize(id)]"
abonent.hologram.layer = 5
if(isliving(loc))
abonent.hologram.icon = getHologramIcon(build_composite_icon_omnidir(loc))
else
abonent.hologram.icon = icon('icons/effects/effects.dmi', "icon_state"="nothing")
if(!abonent.updatingPos)
abonent.update_holo_pos()

/obj/item/device/holopad/proc/update_holo_pos()
if(call_state != CALL_IN_CALL)
updatingPos = 0
return
updatingPos = 1
if(isliving(loc))
var/mob/living/L = loc
hologram.dir = turn(L.dir,180)
hologram.loc = L.loc
hologram.pixel_x = ((L.dir&4)?32:((L.dir&8)?-32:0))
hologram.pixel_y = ((L.dir&1)?32:((L.dir&2)?-32:0))
else if(isturf(loc))
hologram.dir = 2
hologram.loc = loc
hologram.pixel_x = 0
hologram.pixel_y = 0
else
hangUp()
addtimer(CALLBACK(src, .proc/update_holo_pos), 2)


/obj/item/device/holopad/attack_self(mob/user)
switch(call_state)
if(CALL_NONE)
placeCall()
if(CALL_CALLING)
hangUp()
if(CALL_RINGING)
acceptCall()
if(CALL_IN_CALL)
hangUp()

/obj/item/device/holopad/hear_talk(mob/user, datum/language/speaking)
if(call_state == CALL_IN_CALL)
abonent.receive(speaking, user == loc)

/obj/item/device/holopad/proc/receive(speaking, mob/user)
var/list/listening = get_mobs_or_objects_in_view(3, src)

for(var/mob/observer/ghost/G in GLOB.ghost_mob_list)
if(get_dist(src, G) > world.view && G.get_preference_value(/datum/client_preference/ghost_ears) != GLOB.PREF_ALL_SPEECH)
continue
listening |= G

if(!user)
voice = "Holopad Background Voice"
for(var/mob/M in listening)
to_chat(M, "<span class='name'>[voice]</span> transmits, \"[speaking]\" ")

#undef CALL_NONE
#undef CALL_CALLING
#undef CALL_RINGING
#undef CALL_IN_CALL
11 changes: 10 additions & 1 deletion code/modules/research/designs/protolathe/dp-data.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,13 @@
desc = "Produce additional disks for storing technology data."
id = "tech_disk"
build_path = /obj/item/weapon/disk/tech_disk
sort_string = "AAAAB"
sort_string = "AAAAB"

/datum/design/item/holopad
name = "Holopad"
desc = "A holografic communication device."
id = "holopad_comm"
req_tech = list(TECH_BLUESPACE = 2, TECH_DATA = 1, TECH_BLUESPACE = 3)
materials = list(MATERIAL_STEEL = 700, MATERIAL_GLASS = 70)
build_path = /obj/item/device/holopad
sort_string = "AAAAC"
Binary file added icons/obj/holopad.dmi
Binary file not shown.

0 comments on commit d8dd57f

Please sign in to comment.