Merge branch 'master' into kevinz000-patch-13
This commit is contained in:
@@ -124,7 +124,7 @@
|
||||
job = "AI"
|
||||
|
||||
create_eye()
|
||||
rename_self("ai")
|
||||
apply_pref_name("ai")
|
||||
|
||||
holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default"))
|
||||
|
||||
@@ -824,7 +824,7 @@
|
||||
//apc_override is needed here because AIs use their own APC when depowered
|
||||
return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(get_turf_pixel(A))) || apc_override
|
||||
//AI is carded/shunted
|
||||
//view(src) returns nothing for carded/shunted AIs and they have x-ray vision so just use get_dist
|
||||
//view(src) returns nothing for carded/shunted AIs and they have X-ray vision so just use get_dist
|
||||
var/list/viewscale = getviewsize(client.view)
|
||||
return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5)
|
||||
|
||||
|
||||
@@ -18,12 +18,21 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
// The object used for the clickable stat() button.
|
||||
var/obj/effect/statclick/statclick
|
||||
|
||||
// The object used in vis_contents of obscured turfs
|
||||
var/vis_contents
|
||||
// The image given to the effect in vis_contents on AI clients
|
||||
var/image/obscured
|
||||
|
||||
/datum/cameranet/New()
|
||||
vis_contents = new /obj/effect/overlay/camera_static()
|
||||
obscured = new('icons/effects/cameravis.dmi', vis_contents, null, BYOND_LIGHTING_LAYER + 0.1)
|
||||
obscured.plane = BYOND_LIGHTING_PLANE + 1
|
||||
|
||||
// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
var/key = "[x],[y],[z]"
|
||||
return (chunks[key])
|
||||
return chunks["[x],[y],[z]"]
|
||||
|
||||
// Returns the chunk in the x, y, z.
|
||||
// If there is no chunk, it creates a new chunk and returns that.
|
||||
@@ -31,10 +40,9 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
var/key = "[x],[y],[z]"
|
||||
if(!chunks[key])
|
||||
chunks[key] = new /datum/camerachunk(null, x, y, z)
|
||||
|
||||
return chunks[key]
|
||||
. = chunks[key]
|
||||
if(!.)
|
||||
chunks[key] = . = new /datum/camerachunk(x, y, z)
|
||||
|
||||
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
|
||||
|
||||
@@ -46,14 +54,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
else
|
||||
other_eyes = list()
|
||||
|
||||
var/list/chunks_pre_seen = list()
|
||||
var/list/chunks_post_seen = list()
|
||||
|
||||
for(var/V in moved_eyes)
|
||||
var/mob/camera/aiEye/eye = V
|
||||
if(C)
|
||||
chunks_pre_seen |= eye.visibleCameraChunks
|
||||
// 0xf = 15
|
||||
var/static_range = eye.static_visibility_range
|
||||
var/x1 = max(0, eye.x - static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/y1 = max(0, eye.y - static_range) & ~(CHUNK_SIZE - 1)
|
||||
@@ -71,44 +73,26 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
|
||||
for(var/chunk in remove)
|
||||
var/datum/camerachunk/c = chunk
|
||||
c.remove(eye, FALSE)
|
||||
c.remove(eye)
|
||||
|
||||
for(var/chunk in add)
|
||||
var/datum/camerachunk/c = chunk
|
||||
c.add(eye, FALSE)
|
||||
|
||||
if(C)
|
||||
chunks_post_seen |= eye.visibleCameraChunks
|
||||
c.add(eye)
|
||||
|
||||
if(C)
|
||||
for(var/V in other_eyes)
|
||||
var/mob/camera/aiEye/eye = V
|
||||
chunks_post_seen |= eye.visibleCameraChunks
|
||||
|
||||
var/list/remove = chunks_pre_seen - chunks_post_seen
|
||||
var/list/add = chunks_post_seen - chunks_pre_seen
|
||||
|
||||
for(var/chunk in remove)
|
||||
var/datum/camerachunk/c = chunk
|
||||
C.images -= c.obscured
|
||||
|
||||
for(var/chunk in add)
|
||||
var/datum/camerachunk/c = chunk
|
||||
C.images += c.obscured
|
||||
C.images += obscured
|
||||
|
||||
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
||||
|
||||
/datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1)
|
||||
|
||||
if(!SSticker || (opacity_check && !A.opacity))
|
||||
return
|
||||
majorChunkChange(A, 2)
|
||||
|
||||
/datum/cameranet/proc/updateChunk(x, y, z)
|
||||
// 0xf = 15
|
||||
if(!chunkGenerated(x, y, z))
|
||||
var/datum/camerachunk/chunk = chunkGenerated(x, y, z)
|
||||
if (!chunk)
|
||||
return
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, z)
|
||||
chunk.hasChanged()
|
||||
|
||||
// Removes a camera from a chunk.
|
||||
@@ -135,7 +119,6 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
// If you want to update the chunks around an object, without adding/removing a camera, use choice 2.
|
||||
|
||||
/datum/cameranet/proc/majorChunkChange(atom/c, choice)
|
||||
// 0xf = 15
|
||||
if(!c)
|
||||
return
|
||||
|
||||
@@ -147,8 +130,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
|
||||
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
|
||||
if(chunkGenerated(x, y, T.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
|
||||
var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z)
|
||||
if(chunk)
|
||||
if(choice == 0)
|
||||
// Remove the camera.
|
||||
chunk.cameras -= c
|
||||
@@ -160,14 +143,12 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
|
||||
|
||||
/datum/cameranet/proc/checkCameraVis(mob/living/target)
|
||||
|
||||
// 0xf = 15
|
||||
var/turf/position = get_turf(target)
|
||||
return checkTurfVis(position)
|
||||
|
||||
|
||||
/datum/cameranet/proc/checkTurfVis(turf/position)
|
||||
var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
|
||||
var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z)
|
||||
if(chunk)
|
||||
if(chunk.changed)
|
||||
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
|
||||
@@ -180,3 +161,17 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]"))
|
||||
|
||||
/obj/effect/overlay/camera_static
|
||||
name = "static"
|
||||
icon = null
|
||||
icon_state = null
|
||||
anchored = TRUE // should only appear in vis_contents, but to be safe
|
||||
appearance_flags = RESET_TRANSFORM | TILE_BOUND
|
||||
// this combination makes the static block clicks to everything below it,
|
||||
// without appearing in the right-click menu for non-AI clients
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
layer = BYOND_LIGHTING_LAYER + 0.1
|
||||
plane = BYOND_LIGHTING_PLANE + 1
|
||||
|
||||
@@ -8,11 +8,9 @@
|
||||
/datum/camerachunk
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/obscured = list()
|
||||
var/list/cameras = list()
|
||||
var/list/turfs = list()
|
||||
var/list/seenby = list()
|
||||
var/visible = FALSE
|
||||
var/changed = 0
|
||||
var/x = 0
|
||||
var/y = 0
|
||||
@@ -20,28 +18,17 @@
|
||||
|
||||
// Add an AI eye to the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/add(mob/camera/aiEye/eye, add_images = TRUE)
|
||||
if(add_images)
|
||||
var/client/client = eye.GetViewerClient()
|
||||
if(client)
|
||||
client.images += obscured
|
||||
/datum/camerachunk/proc/add(mob/camera/aiEye/eye)
|
||||
eye.visibleCameraChunks += src
|
||||
visible++
|
||||
seenby += eye
|
||||
if(changed)
|
||||
update()
|
||||
|
||||
// Remove an AI eye from the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/remove(mob/camera/aiEye/eye, remove_images = TRUE)
|
||||
if(remove_images)
|
||||
var/client/client = eye.GetViewerClient()
|
||||
if(client)
|
||||
client.images -= obscured
|
||||
/datum/camerachunk/proc/remove(mob/camera/aiEye/eye)
|
||||
eye.visibleCameraChunks -= src
|
||||
seenby -= eye
|
||||
if(visible > 0)
|
||||
visible--
|
||||
|
||||
// Called when a chunk has changed. I.E: A wall was deleted.
|
||||
|
||||
@@ -54,7 +41,7 @@
|
||||
// instead be flagged to update the next time an AI Eye moves near it.
|
||||
|
||||
/datum/camerachunk/proc/hasChanged(update_now = 0)
|
||||
if(visible || update_now)
|
||||
if(seenby.len || update_now)
|
||||
addtimer(CALLBACK(src, .proc/update), UPDATE_BUFFER, TIMER_UNIQUE)
|
||||
else
|
||||
changed = 1
|
||||
@@ -94,41 +81,18 @@
|
||||
|
||||
for(var/turf in visAdded)
|
||||
var/turf/t = turf
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/eye in seenby)
|
||||
var/mob/camera/aiEye/m = eye
|
||||
if(!m)
|
||||
continue
|
||||
var/client/client = m.GetViewerClient()
|
||||
if(client)
|
||||
client.images -= t.obscured
|
||||
t.vis_contents -= GLOB.cameranet.vis_contents
|
||||
|
||||
for(var/turf in visRemoved)
|
||||
var/turf/t = turf
|
||||
if(obscuredTurfs[t])
|
||||
if(!t.obscured)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER+0.1)
|
||||
t.obscured.pixel_x = -t.pixel_x
|
||||
t.obscured.pixel_y = -t.pixel_y
|
||||
t.obscured.plane = BYOND_LIGHTING_PLANE+0.1
|
||||
obscured += t.obscured
|
||||
for(var/eye in seenby)
|
||||
var/mob/camera/aiEye/m = eye
|
||||
if(!m)
|
||||
seenby -= m
|
||||
continue
|
||||
var/client/client = m.GetViewerClient()
|
||||
if(client)
|
||||
client.images += t.obscured
|
||||
if(obscuredTurfs[t] && !istype(t, /turf/open/ai_visible))
|
||||
t.vis_contents += GLOB.cameranet.vis_contents
|
||||
|
||||
changed = 0
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
|
||||
/datum/camerachunk/New(loc, x, y, z)
|
||||
|
||||
// 0xf = 15
|
||||
/datum/camerachunk/New(x, y, z)
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
|
||||
@@ -164,12 +128,7 @@
|
||||
|
||||
for(var/turf in obscuredTurfs)
|
||||
var/turf/t = turf
|
||||
if(!t.obscured)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER+0.1)
|
||||
t.obscured.pixel_x = -t.pixel_x
|
||||
t.obscured.pixel_y = -t.pixel_y
|
||||
t.obscured.plane = BYOND_LIGHTING_PLANE+0.1
|
||||
obscured += t.obscured
|
||||
t.vis_contents += GLOB.cameranet.vis_contents
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
#undef CHUNK_SIZE
|
||||
|
||||
@@ -50,9 +50,7 @@
|
||||
/mob/camera/aiEye/proc/RemoveImages()
|
||||
var/client/C = GetViewerClient()
|
||||
if(C && use_static)
|
||||
for(var/V in visibleCameraChunks)
|
||||
var/datum/camerachunk/c = V
|
||||
C.images -= c.obscured
|
||||
C.images -= GLOB.cameranet.obscured
|
||||
|
||||
/mob/camera/aiEye/Destroy()
|
||||
if(ai)
|
||||
@@ -98,8 +96,11 @@
|
||||
|
||||
// Return to the Core.
|
||||
/mob/living/silicon/ai/proc/view_core()
|
||||
|
||||
current = null
|
||||
if(istype(current,/obj/machinery/holopad))
|
||||
var/obj/machinery/holopad/H = current
|
||||
H.clear_holo(src)
|
||||
else
|
||||
current = null
|
||||
cameraFollow = null
|
||||
unset_machine()
|
||||
|
||||
|
||||
@@ -88,10 +88,6 @@
|
||||
icon_state = "room_background"
|
||||
flags_1 = NOJAUNT_1
|
||||
|
||||
/turf/open/ai_visible/Initialize()
|
||||
. = ..()
|
||||
obscured = image(null, src, null)
|
||||
|
||||
/area/ai_multicam_room
|
||||
name = "ai_multicam_room"
|
||||
icon_state = "ai_camera_room"
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
P.fold_out()
|
||||
|
||||
/datum/action/innate/pai/chassis
|
||||
name = "Holochassis Appearence Composite"
|
||||
name = "Holochassis Appearance Composite"
|
||||
button_icon_state = "pai_chassis"
|
||||
background_icon_state = "bg_tech"
|
||||
|
||||
|
||||
@@ -116,6 +116,6 @@
|
||||
|
||||
/mob/living/silicon/pai/mob_try_pickup(mob/living/user)
|
||||
if(!possible_chassis[chassis])
|
||||
to_chat(user, "<span class='wraning'>[src]'s current form isn't able to be carried!</span>")
|
||||
to_chat(user, "<span class='warning'>[src]'s current form isn't able to be carried!</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
pda.silent = !pda.silent
|
||||
else if(href_list["target"])
|
||||
if(silent)
|
||||
return alert("Communications circuits remain unitialized.")
|
||||
return alert("Communications circuits remain uninitialized.")
|
||||
|
||||
var/target = locate(href_list["target"])
|
||||
pda.create_message(src, target)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
sight_mode &= ~S.sight_mode
|
||||
update_sight()
|
||||
else if(istype(O, /obj/item/storage/bag/tray/))
|
||||
O.SendSignal(COMSIG_TRY_STORAGE_QUICK_EMPTY)
|
||||
SEND_SIGNAL(O, COMSIG_TRY_STORAGE_QUICK_EMPTY)
|
||||
//CITADEL EDIT reee proc, Dogborg modules
|
||||
if(istype(O,/obj/item/gun/energy/laser/cyborg))
|
||||
laser = FALSE
|
||||
@@ -34,12 +34,6 @@
|
||||
if(client)
|
||||
client.screen -= O
|
||||
observer_screen_update(O,FALSE)
|
||||
O.forceMove(module) //Return item to module so it appears in its contents, so it can be taken out again.
|
||||
|
||||
if(O.flags_1 & DROPDEL_1)
|
||||
O.flags_1 &= ~DROPDEL_1 //we shouldn't HAVE things with DROPDEL_1 in our modules, but better safe than runtiming horribly
|
||||
|
||||
O.dropped(src)
|
||||
|
||||
if(module_active == O)
|
||||
module_active = null
|
||||
@@ -52,6 +46,12 @@
|
||||
else if(held_items[3] == O)
|
||||
inv3.icon_state = "inv3"
|
||||
held_items[3] = null
|
||||
|
||||
if(O.item_flags & DROPDEL)
|
||||
O.item_flags &= ~DROPDEL //we shouldn't HAVE things with DROPDEL_1 in our modules, but better safe than runtiming horribly
|
||||
|
||||
O.forceMove(module) //Return item to module so it appears in its contents, so it can be taken out again.
|
||||
|
||||
hud_used.update_robot_modules_display()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -90,7 +90,16 @@
|
||||
/obj/item/clothing/head/wizard,
|
||||
/obj/item/clothing/head/nursehat,
|
||||
/obj/item/clothing/head/sombrero,
|
||||
/obj/item/clothing/head/helmet/chaplain/witchunter_hat)
|
||||
/obj/item/clothing/head/helmet/chaplain/witchunter_hat,
|
||||
/obj/item/clothing/head/soft/, //All baseball caps
|
||||
/obj/item/clothing/head/that, //top hat
|
||||
/obj/item/clothing/head/collectable/tophat, //Not sure where this one is found, but it looks the same so might as well include
|
||||
/obj/item/clothing/mask/bandana/, //All bandanas (which only work in hat mode)
|
||||
/obj/item/clothing/head/fedora,
|
||||
/obj/item/clothing/head/beanie/, //All beanies
|
||||
/obj/item/clothing/ears/headphones,
|
||||
/obj/item/clothing/head/helmet/skull,
|
||||
/obj/item/clothing/head/crown/fancy)
|
||||
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
@@ -164,7 +173,7 @@
|
||||
|
||||
//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO
|
||||
/mob/living/silicon/robot/Destroy()
|
||||
var/turf/T = get_turf(loc)//To hopefully prevent run time errors.
|
||||
var/atom/T = drop_location()//To hopefully prevent run time errors.
|
||||
if(mmi && mind)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside.
|
||||
if(T)
|
||||
mmi.forceMove(T)
|
||||
@@ -189,6 +198,10 @@
|
||||
connected_ai.connected_robots -= src
|
||||
if(shell)
|
||||
GLOB.available_ai_shells -= src
|
||||
else
|
||||
if(T && istype(radio) && istype(radio.keyslot))
|
||||
radio.keyslot.forceMove(T)
|
||||
radio.keyslot = null
|
||||
qdel(wires)
|
||||
qdel(module)
|
||||
qdel(eye_lights)
|
||||
@@ -230,14 +243,17 @@
|
||||
module.transform_to(modulelist[input_module])
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/updatename()
|
||||
/mob/living/silicon/robot/proc/updatename(client/C)
|
||||
if(shell)
|
||||
return
|
||||
if(!C)
|
||||
C = client
|
||||
var/changed_name = ""
|
||||
if(custom_name)
|
||||
changed_name = custom_name
|
||||
if(changed_name == "" && client)
|
||||
changed_name = client.prefs.custom_names["cyborg"]
|
||||
if(changed_name == "" && C && C.prefs.custom_names["cyborg"] != DEFAULT_CYBORG_NAME)
|
||||
if(apply_pref_name("cyborg", C))
|
||||
return //built in camera handled in proc
|
||||
if(!changed_name)
|
||||
changed_name = get_standard_name()
|
||||
|
||||
@@ -379,12 +395,8 @@
|
||||
to_chat(user, "<span class='notice'>You start fixing yourself...</span>")
|
||||
if(!W.use_tool(src, user, 50))
|
||||
return
|
||||
adjustBruteLoss(-10)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You start fixing [src]...</span>")
|
||||
if(!do_after(user, 30, target = src))
|
||||
return
|
||||
adjustBruteLoss(-30)
|
||||
|
||||
adjustBruteLoss(-30)
|
||||
updatehealth()
|
||||
add_fingerprint(user)
|
||||
visible_message("<span class='notice'>[user] has fixed some of the dents on [src].</span>")
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/mob/living/silicon/robot/attackby(obj/item/I, mob/living/user)
|
||||
if(hat_offset != INFINITY && user.a_intent == INTENT_HELP && is_type_in_typecache(I, equippable_hats))
|
||||
if(!(I.slot_flags & ITEM_SLOT_HEAD))
|
||||
to_chat(user, "<span class='warning'>You can't quite fit [I] onto [src]'s head.</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin to place [I] on [src]'s head...</span>")
|
||||
to_chat(src, "<span class='notice'>[user] is placing [I] on your head...</span>")
|
||||
if(do_after(user, 30, target = src))
|
||||
@@ -44,7 +47,7 @@
|
||||
damage = rand(20, 40)
|
||||
else
|
||||
damage = rand(5, 35)
|
||||
damage = round(damage / 2) // borgs recieve half damage
|
||||
damage = round(damage / 2) // borgs receive half damage
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
if(I.loc != src)
|
||||
I.forceMove(src)
|
||||
modules += I
|
||||
I.flags_1 |= NODROP_1
|
||||
I.item_flags |= NODROP
|
||||
I.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
if(nonstandard)
|
||||
added_modules += I
|
||||
|
||||
@@ -405,4 +405,7 @@
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/get_inactive_held_item()
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/handle_high_gravity(gravity)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user