Files
CHOMPStation2/code/_onclick/hud/movable_screen_objects.dm
Rykka ef1acd0452 Add AI Picture-in-Picture Mode!
This adds a system for picture-in-picture UI windows using
vis_contents. Essentially, it allows you to make UI windows that show an area of turfs. It also refactors how cameranet visibility works.

Currently, this is implemented on AIs. They gain two new UI buttons - "Enter Multicam Mode", and "Create Multicam". When they go into Multicam Mode, they see a background of animated binary numbers, and they are allowed to create an infinite amount of these picture in picture windows, which subsequently creates an AI Eye for each one. They are able to control each AI eye individually, by first clicking on the PIP window to select it as "active" and then using the normal arrow key controls. The PIP windows can be freely resized and moved around the area.

You can control everything inside these PIP windows EXACTLY the same as you can using a traditional AI Eye, as demonstrated below.

For admins, there is a config option to disable PIP entirely - simply set `var/multicam_allowed = TRUE` to FALSE if you wish to disable it from being used. (Please be reasonable.) <3

You can see an example of how this works here:
![https://i.imgur.com/TCND8W9.mp4](https://i.imgur.com/TCND8W9.mp4)

AI Multicam functionality.

Do note that if the lightbulb in the AI core is busted, the multicam room is dark(er) than it would be, but you can still see your camera windows just fine. (I'll probably fix this later.) It only affects the "matrix" backdrop, the PIP windows are still fine.

This has been runtime-tested with the latest `master` revision and produces 0 runtimes, and has no noticeable impact on server CPU usage.

Chompstation port is here!
Port of https://github.com/VOREStation/VOREStation/pull/7752, YW port not incoming atm as they can fetch from upstream and frankly dog has done enuf ports for now x.x
2020-05-10 14:22:36 -04:00

143 lines
3.5 KiB
Plaintext

//////////////////////////
//Movable Screen Objects//
// By RemieRichards //
//////////////////////////
//Movable Screen Object
//Not tied to the grid, places it's center where the cursor is
/obj/screen/movable
var/snap2grid = FALSE
var/moved = FALSE
var/x_off = -16
var/y_off = -16
//Snap Screen Object
//Tied to the grid, snaps to the nearest turf
/obj/screen/movable/snap
snap2grid = TRUE
/obj/screen/movable/MouseDrop(over_object, src_location, over_location, src_control, over_control, params)
var/list/PM = params2list(params)
//No screen-loc information? abort.
if(!PM || !PM["screen-loc"])
return
//Split screen-loc up into X+Pixel_X and Y+Pixel_Y
var/list/screen_loc_params = splittext(PM["screen-loc"], ",")
//Split X+Pixel_X up into list(X, Pixel_X)
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
screen_loc_X[1] = encode_screen_X(text2num(screen_loc_X[1]))
//Split Y+Pixel_Y up into list(Y, Pixel_Y)
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
screen_loc_Y[1] = encode_screen_Y(text2num(screen_loc_Y[1]))
if(snap2grid) //Discard Pixel Values
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]) + 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]"
/obj/screen/movable/proc/encode_screen_X(X)
var/view_dist = world.view
if(view_dist)
view_dist = view_dist
if(X > view_dist+1)
. = "EAST-[view_dist *2 + 1-X]"
else if(X < view_dist +1)
. = "WEST+[X-1]"
else
. = "CENTER"
/obj/screen/movable/proc/decode_screen_X(X)
var/view_dist = world.view
if(view_dist)
view_dist = view_dist
//Find EAST/WEST implementations
if(findtext(X,"EAST-"))
var/num = text2num(copytext(X,6)) //Trim EAST-
if(!num)
num = 0
. = view_dist*2 + 1 - num
else if(findtext(X,"WEST+"))
var/num = text2num(copytext(X,6)) //Trim WEST+
if(!num)
num = 0
. = num+1
else if(findtext(X,"CENTER"))
. = view_dist+1
/obj/screen/movable/proc/encode_screen_Y(Y)
var/view_dist = world.view
if(view_dist)
view_dist = view_dist
if(Y > view_dist+1)
. = "NORTH-[view_dist*2 + 1-Y]"
else if(Y < view_dist+1)
. = "SOUTH+[Y-1]"
else
. = "CENTER"
/obj/screen/movable/proc/decode_screen_Y(Y)
var/view_dist = world.view
if(view_dist)
view_dist = view_dist
if(findtext(Y,"NORTH-"))
var/num = text2num(copytext(Y,7)) //Trim NORTH-
if(!num)
num = 0
. = view_dist*2 + 1 - num
else if(findtext(Y,"SOUTH+"))
var/num = text2num(copytext(Y,7)) //Time SOUTH+
if(!num)
num = 0
. = num+1
else if(findtext(Y,"CENTER"))
. = view_dist+1
//Debug procs
/client/proc/test_movable_UI()
set category = "Debug"
set name = "Spawn Movable UI Object"
var/obj/screen/movable/M = new()
M.name = "Movable UI Object"
M.icon_state = "block"
M.maptext = "Movable"
M.maptext_width = 64
var/screen_l = input(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Movable UI Object") as text
if(!screen_l)
return
M.screen_loc = screen_l
screen += M
/client/proc/test_snap_UI()
set category = "Debug"
set name = "Spawn Snap UI Object"
var/obj/screen/movable/snap/S = new()
S.name = "Snap UI Object"
S.icon_state = "block"
S.maptext = "Snap"
S.maptext_width = 64
var/screen_l = input(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Snap UI Object") as text
if(!screen_l)
return
S.screen_loc = screen_l
screen += S