Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AI Multicamera mode #37695

Merged
merged 9 commits into from May 31, 2018
1,074 changes: 542 additions & 532 deletions _maps/map_files/generic/CentCom.dmm

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions code/_onclick/ai.dm
Expand Up @@ -26,6 +26,14 @@
return
next_click = world.time + 1

if(multicam_on)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this needed for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If multicamera mode is on and you click on something in one of the windows, you will also click on the window.

var/turf/T = get_turf(A)
if(T)
for(var/obj/screen/movable/pic_in_pic/ai/P in T.vis_locs)
if(P.ai == src)
P.Click(params)
break

if(check_click_intercept(params,A))
return

Expand Down
2 changes: 2 additions & 0 deletions code/_onclick/hud/_defines.dm
Expand Up @@ -134,6 +134,8 @@
#define ui_ai_take_picture "SOUTH:6,WEST+12"
#define ui_ai_view_images "SOUTH:6,WEST+13"
#define ui_ai_sensor "SOUTH:6,WEST+14"
#define ui_ai_multicam "SOUTH+1:6,WEST+13"
#define ui_ai_add_multicam "SOUTH+1:6,WEST+14"

//Pop-up inventory
#define ui_shoes "WEST+1:8,SOUTH:5"
Expand Down
30 changes: 29 additions & 1 deletion code/_onclick/hud/ai.dm
Expand Up @@ -164,6 +164,26 @@
var/mob/living/silicon/S = usr
S.toggle_sensors()

/obj/screen/ai/multicam
name = "Multicamera Mode"
icon_state = "multicam"

/obj/screen/ai/multicam/Click()
if(..())
return
var/mob/living/silicon/ai/AI = usr
AI.toggle_multicam()

/obj/screen/ai/add_multicam
name = "New Camera"
icon_state = "new_cam"

/obj/screen/ai/add_multicam/Click()
if(..())
return
var/mob/living/silicon/ai/AI = usr
AI.drop_new_multicam()


/datum/hud/ai
ui_style_icon = 'icons/mob/screen_ai.dmi'
Expand Down Expand Up @@ -247,12 +267,20 @@
using.screen_loc = ui_ai_view_images
static_inventory += using


//Medical/Security sensors
using = new /obj/screen/ai/sensors()
using.screen_loc = ui_ai_sensor
static_inventory += using

//Multicamera mode
using = new /obj/screen/ai/multicam()
using.screen_loc = ui_ai_multicam
static_inventory += using

//Add multicamera camera
using = new /obj/screen/ai/add_multicam()
using.screen_loc = ui_ai_add_multicam
static_inventory += using

/mob/living/silicon/ai/create_mob_hud()
if(client && !hud_used)
Expand Down
6 changes: 4 additions & 2 deletions code/_onclick/hud/movable_screen_objects.dm
Expand Up @@ -12,6 +12,8 @@
var/snap2grid = FALSE
var/moved = FALSE
var/locked = FALSE
var/x_off = -16
var/y_off = -16

//Snap Screen Object
//Tied to the grid, snaps to the nearest turf
Expand Down Expand Up @@ -42,8 +44,8 @@
screen_loc = "[screen_loc_X[1]],[screen_loc_Y[1]]"

else //Normalise Pixel Values (So the object drops at the center of the mouse, not 16 pixels off)
var/pix_X = text2num(screen_loc_X[2]) - 16
var/pix_Y = text2num(screen_loc_Y[2]) - 16
var/pix_X = text2num(screen_loc_X[2]) + x_off
var/pix_Y = text2num(screen_loc_Y[2]) + y_off
screen_loc = "[screen_loc_X[1]]:[pix_X],[screen_loc_Y[1]]:[pix_Y]"

moved = screen_loc
Expand Down
144 changes: 144 additions & 0 deletions code/_onclick/hud/picture_in_picture.dm
@@ -0,0 +1,144 @@
/obj/screen/movable/pic_in_pic
name = "Picture-in-picture"
screen_loc = "CENTER"
plane = GAME_PLANE
var/atom/center
var/width = 0
var/height = 0
var/list/shown_to = list()
var/list/viewing_turfs = list()
var/obj/screen/component_button/button_x
var/obj/screen/component_button/button_expand
var/obj/screen/component_button/button_shrink

var/mutable_appearance/standard_background
var/const/max_dimensions = 10

/obj/screen/movable/pic_in_pic/Initialize()
. = ..()
make_backgrounds()

/obj/screen/movable/pic_in_pic/Destroy()
for(var/C in shown_to)
unshow_to(C)
QDEL_NULL(button_x)
QDEL_NULL(button_shrink)
QDEL_NULL(button_expand)
return ..()

/obj/screen/movable/pic_in_pic/component_click(obj/screen/component_button/component, params)
if(component == button_x)
qdel(src)
else if(component == button_expand)
set_view_size(width+1, height+1)
else if(component == button_shrink)
set_view_size(width-1, height-1)

/obj/screen/movable/pic_in_pic/proc/make_backgrounds()
standard_background = new /mutable_appearance()
standard_background.icon = 'icons/misc/pic_in_pic.dmi'
standard_background.icon_state = "background"
standard_background.layer = SPACE_LAYER

/obj/screen/movable/pic_in_pic/proc/add_buttons()
var/static/mutable_appearance/move_tab
if(!move_tab)
move_tab = new /mutable_appearance()
//all these properties are always the same, and since adding something to the overlay
//list makes a copy, there is no reason to make a new one each call
move_tab.icon = 'icons/misc/pic_in_pic.dmi'
move_tab.icon_state = "move"
move_tab.plane = HUD_PLANE
var/matrix/M = matrix()
M.Translate(0, (height + 0.25) * world.icon_size)
move_tab.transform = M
add_overlay(move_tab)

if(!button_x)
button_x = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "close"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "x"
MA.plane = HUD_PLANE
button_x.appearance = MA
M = matrix()
M.Translate((max(4, width) - 0.75) * world.icon_size, (height + 0.25) * world.icon_size)
button_x.transform = M
vis_contents += button_x

if(!button_expand)
button_expand = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "expand"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "expand"
MA.plane = HUD_PLANE
button_expand.appearance = MA
M = matrix()
M.Translate(world.icon_size, (height + 0.25) * world.icon_size)
button_expand.transform = M
vis_contents += button_expand

if(!button_shrink)
button_shrink = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "shrink"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "shrink"
MA.plane = HUD_PLANE
button_shrink.appearance = MA
M = matrix()
M.Translate(2 * world.icon_size, (height + 0.25) * world.icon_size)
button_shrink.transform = M
vis_contents += button_shrink

/obj/screen/movable/pic_in_pic/proc/add_background()
if((width > 0) && (height > 0))
var/matrix/M = matrix()
M.Scale(width + 0.5, height + 0.5)
M.Translate((width-1)/2 * world.icon_size, (height-1)/2 * world.icon_size)
standard_background.transform = M
add_overlay(standard_background)

/obj/screen/movable/pic_in_pic/proc/set_view_size(width, height, do_refresh = TRUE)
width = CLAMP(width, 0, max_dimensions)
height = CLAMP(height, 0, max_dimensions)
src.width = width
src.height = height

y_off = -height * world.icon_size - 16

cut_overlays()
add_background()
add_buttons()
if(do_refresh)
refresh_view()

/obj/screen/movable/pic_in_pic/proc/set_view_center(atom/target, do_refresh = TRUE)
center = target
if(do_refresh)
refresh_view()

/obj/screen/movable/pic_in_pic/proc/refresh_view()
vis_contents -= viewing_turfs
if(!width || !height)
return
var/turf/T = get_turf(center)
if(!T)
return
var/turf/lowerleft = locate(max(1, T.x - round(width/2)), max(1, T.y - round(height/2)), T.z)
var/turf/upperright = locate(min(world.maxx, lowerleft.x + width - 1), min(world.maxy, lowerleft.y + height - 1), lowerleft.z)
viewing_turfs = block(lowerleft, upperright)
vis_contents += viewing_turfs


/obj/screen/movable/pic_in_pic/proc/show_to(client/C)
if(C)
shown_to[C] = 1
C.screen += src

/obj/screen/movable/pic_in_pic/proc/unshow_to(client/C)
if(C)
shown_to -= C
C.screen -= src
15 changes: 15 additions & 0 deletions code/_onclick/hud/screen_objects.dm
Expand Up @@ -30,6 +30,9 @@
/obj/screen/orbit()
return

/obj/screen/proc/component_click(obj/screen/component_button/component, params)
return

/obj/screen/text
icon = null
icon_state = null
Expand Down Expand Up @@ -604,3 +607,15 @@
holder.screen -= src
holder = null
return ..()


/obj/screen/component_button
var/obj/screen/parent

/obj/screen/component_button/Initialize(mapload, obj/screen/parent)
. = ..()
src.parent = parent

/obj/screen/component_button/Click(params)
if(parent)
parent.component_click(src, params)
5 changes: 1 addition & 4 deletions code/datums/holocall.dm
Expand Up @@ -60,9 +60,6 @@
user.remote_control = null

if(!QDELETED(eye))
if(user_good && user.client)
for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
chunk.remove(eye)
qdel(eye)
eye = null

Expand Down Expand Up @@ -284,7 +281,7 @@
else
var/datum/preset_holoimage/H = new preset_image_type
record.caller_image = H.build_image()

//These build caller image from outfit and some additional data, for use by mappers for ruin holorecords
/datum/preset_holoimage
var/nonhuman_mobtype //Fill this if you just want something nonhuman
Expand Down
3 changes: 2 additions & 1 deletion code/game/machinery/camera/camera.dm
Expand Up @@ -36,6 +36,7 @@
var/alarm_on = FALSE
var/busy = FALSE
var/emped = FALSE //Number of consecutive EMP's on this camera
var/in_use_lights = 0

// Upgrades bitflag
var/upgrades = 0
Expand Down Expand Up @@ -285,7 +286,7 @@
else if (stat & EMPED)
icon_state = "[initial(icon_state)]emp"
else
icon_state = "[initial(icon_state)]"
icon_state = "[initial(icon_state)][in_use_lights ? "_in_use" : ""]"

/obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = 1)
status = !status
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/computer/camera_advanced.dm
Expand Up @@ -190,7 +190,7 @@
else
moveToNullspace()
if(use_static)
GLOB.cameranet.visibility(src)
GLOB.cameranet.visibility(src, GetViewerClient())
if(visible_icon)
if(eye_user.client)
eye_user.client.images -= user_image
Expand Down
2 changes: 0 additions & 2 deletions code/modules/lighting/lighting_object.dm
Expand Up @@ -11,8 +11,6 @@
layer = LIGHTING_LAYER
invisibility = INVISIBILITY_LIGHTING

blend_mode = BLEND_ADD
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know why, but if this is set, you cannot see darkness through the vis_contents of screen objects. This should always be overridden by the darkness plane master (which is set to BLEND_MULTIPLY) anyway, so I have no idea why this is the case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


var/needs_update = FALSE
var/turf/myturf

Expand Down
23 changes: 20 additions & 3 deletions code/modules/mob/living/silicon/ai/ai.dm
Expand Up @@ -74,7 +74,7 @@
var/nuking = FALSE
var/obj/machinery/doomsday_device/doomsday_device

var/mob/camera/aiEye/eyeobj = new
var/mob/camera/aiEye/eyeobj
var/sprint = 10
var/cooldown = 0
var/acceleration = 1
Expand All @@ -85,6 +85,13 @@
var/datum/action/innate/deploy_last_shell/redeploy_action = new
var/chnotify = 0

var/multicam_allowed = FALSE
var/multicam_on = FALSE
var/obj/screen/movable/pic_in_pic/ai/master_multicam
var/list/multicam_screens = list()
var/list/all_eyes = list()
var/max_multicams = 6

/mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
. = ..()
if(!target_ai) //If there is no player/brain inside.
Expand Down Expand Up @@ -116,8 +123,7 @@

job = "AI"

eyeobj.ai = src
eyeobj.forceMove(src.loc)
create_eye()
rename_self("ai")

holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default"))
Expand Down Expand Up @@ -870,9 +876,12 @@
current = A
if(client)
if(ismovableatom(A))
if(A != GLOB.ai_camera_room_landmark)
end_multicam()
client.perspective = EYE_PERSPECTIVE
client.eye = A
else
end_multicam()
if(isturf(loc))
if(eyeobj)
client.eye = eyeobj
Expand Down Expand Up @@ -992,3 +1001,11 @@
. = ..()
if(!target_ai)
target_ai = src //cheat! just give... ourselves as the spawned AI, because that's technically correct

/mob/living/silicon/ai/proc/camera_visibility(mob/camera/aiEye/moved_eye)
GLOB.cameranet.visibility(moved_eye, client, all_eyes)

/mob/living/silicon/ai/forceMove(atom/destination)
. = ..()
if(.)
end_multicam()