mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 03:25:49 +01:00
Merge branch 'master' of git://github.com/Baystation12/Baystation12
This commit is contained in:
+573
-415
@@ -1,415 +1,573 @@
|
||||
//All credit for this goes to Uristqwerty.
|
||||
|
||||
//And some to me! -Mini
|
||||
|
||||
|
||||
|
||||
//This file is partly designed around being able to uninclude it to go back to the old ai viewing system completely.
|
||||
//(And therefore also be portable to another similar codebase simply by transferring the file and including it after the other AI code files.)
|
||||
//There are probably a few parts that don't do that at the moment, but I'll fix them at some point.
|
||||
|
||||
/turf
|
||||
var/image/obscured
|
||||
var/image/dim
|
||||
|
||||
/turf/proc/visibilityChanged()
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/turf/New()
|
||||
..()
|
||||
cameranet.updateVisibility(src)
|
||||
/*
|
||||
/turf/Del()
|
||||
..()
|
||||
cameranet.updateVisibility(src)
|
||||
*/
|
||||
/datum/camerachunk
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/dimTurfs = list()
|
||||
var/list/obscured = list()
|
||||
var/list/dim = list()
|
||||
var/list/cameras = list()
|
||||
var/list/turfs = list()
|
||||
var/list/seenby = list()
|
||||
var/visible = 0
|
||||
var/changed = 0
|
||||
var/updating = 0
|
||||
|
||||
/mob/aiEye
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/ai = null
|
||||
density = 0
|
||||
|
||||
/datum/camerachunk/proc/add(mob/aiEye/ai)
|
||||
ai.visibleCameraChunks += src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images += obscured
|
||||
ai.ai.client.images += dim
|
||||
visible++
|
||||
seenby += ai
|
||||
if(changed && !updating)
|
||||
update()
|
||||
|
||||
/datum/camerachunk/proc/remove(mob/aiEye/ai)
|
||||
ai.visibleCameraChunks -= src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images -= obscured
|
||||
ai.ai.client.images -= dim
|
||||
seenby -= ai
|
||||
if(visible > 0)
|
||||
visible--
|
||||
|
||||
/datum/camerachunk/proc/visibilityChanged(turf/loc)
|
||||
if(!(loc in visibleTurfs))
|
||||
return
|
||||
|
||||
hasChanged()
|
||||
|
||||
/datum/camerachunk/proc/hasChanged()
|
||||
if(visible)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(10)//Batch large changes, such as many doors opening or closing at once
|
||||
update()
|
||||
updating = 0
|
||||
else
|
||||
changed = 1
|
||||
|
||||
/datum/camerachunk/proc/update()
|
||||
var/list/newDimTurfs = list()
|
||||
var/list/newVisibleTurfs = list()
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
var/lum = c.luminosity
|
||||
c.luminosity = 7
|
||||
for(var/turf/t in view(7, c))
|
||||
if(t in turfs)
|
||||
newDimTurfs += t
|
||||
|
||||
for(var/turf/t in view(6, c))
|
||||
if(t in turfs)
|
||||
newVisibleTurfs += t
|
||||
|
||||
c.luminosity = lum
|
||||
|
||||
var/list/dimAdded = newDimTurfs - dimTurfs
|
||||
var/list/dimRemoved = dimTurfs - newDimTurfs
|
||||
var/list/visAdded = newVisibleTurfs - visibleTurfs
|
||||
var/list/visRemoved = visibleTurfs - newVisibleTurfs
|
||||
|
||||
visibleTurfs = newVisibleTurfs
|
||||
dimTurfs = newDimTurfs
|
||||
obscuredTurfs = turfs - dimTurfs
|
||||
dimTurfs -= visibleTurfs
|
||||
|
||||
for(var/turf/t in dimRemoved)
|
||||
if(t.dim)
|
||||
dim -= t.dim
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.dim
|
||||
|
||||
if(!(t in visibleTurfs))
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.obscured
|
||||
|
||||
for(var/turf/t in dimAdded)
|
||||
if(!(t in visibleTurfs))
|
||||
if(!t.dim)
|
||||
t.dim = image('cameravis.dmi', t, "dim", 15)
|
||||
t.mouse_opacity = 0
|
||||
|
||||
dim += t.dim
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.dim
|
||||
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.obscured
|
||||
|
||||
for(var/turf/t in visAdded)
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.obscured
|
||||
|
||||
for(var/turf/t in visRemoved)
|
||||
if(t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.obscured
|
||||
|
||||
|
||||
|
||||
/datum/camerachunk/New(loc, x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
|
||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||
if(c.status)
|
||||
cameras += c
|
||||
|
||||
for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
|
||||
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
|
||||
turfs += t
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
var/lum = c.luminosity
|
||||
c.luminosity = 7
|
||||
for(var/turf/t in view(7, c))
|
||||
if(t in turfs)
|
||||
dimTurfs += t
|
||||
|
||||
for(var/turf/t in view(6, c))
|
||||
if(t in turfs)
|
||||
visibleTurfs += t
|
||||
|
||||
c.luminosity = lum
|
||||
|
||||
obscuredTurfs = turfs - dimTurfs
|
||||
dimTurfs -= visibleTurfs
|
||||
|
||||
for(var/turf/t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
|
||||
for(var/turf/t in dimTurfs)
|
||||
if(!(t in visibleTurfs))
|
||||
if(!t.dim)
|
||||
t.dim = image('cameravis.dmi', t, "dim", TURF_LAYER)
|
||||
t.dim.mouse_opacity = 0
|
||||
|
||||
dim += t.dim
|
||||
|
||||
var/datum/cameranet/cameranet = new()
|
||||
|
||||
/datum/cameranet
|
||||
var/list/cameras = list()
|
||||
var/list/chunks = list()
|
||||
var/network = "net1"
|
||||
var/ready = 0
|
||||
|
||||
/datum/cameranet/New()
|
||||
..()
|
||||
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
var/key = "[x],[y],[z]"
|
||||
return key in chunks
|
||||
|
||||
/datum/cameranet/proc/getCameraChunk(x, y, z)
|
||||
var/key = "[x],[y],[z]"
|
||||
|
||||
if(!(key in chunks))
|
||||
chunks[key] = new /datum/camerachunk(null, x, y, z)
|
||||
|
||||
return chunks[key]
|
||||
|
||||
/datum/cameranet/proc/visibility(mob/aiEye/ai)
|
||||
var/x1 = max(0, ai.x - 16) & ~0xf
|
||||
var/y1 = max(0, ai.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, ai.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, ai.y + 16) & ~0xf
|
||||
|
||||
var/list/visibleChunks = list()
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
visibleChunks += getCameraChunk(x, y, ai.z)
|
||||
|
||||
var/list/remove = ai.visibleCameraChunks - visibleChunks
|
||||
var/list/add = visibleChunks - ai.visibleCameraChunks
|
||||
|
||||
for(var/datum/camerachunk/c in remove)
|
||||
c.remove(ai)
|
||||
|
||||
for(var/datum/camerachunk/c in add)
|
||||
c.add(ai)
|
||||
|
||||
/datum/cameranet/proc/updateVisibility(turf/loc)
|
||||
if(!chunkGenerated(loc.x & ~0xf, loc.y & ~0xf, loc.z))
|
||||
return
|
||||
|
||||
var/datum/camerachunk/chunk = getCameraChunk(loc.x & ~0xf, loc.y & ~0xf, loc.z)
|
||||
chunk.visibilityChanged(loc)
|
||||
|
||||
/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
|
||||
var/x1 = max(0, c.x - 16) & ~0xf
|
||||
var/y1 = max(0, c.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, c.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, c.y + 16) & ~0xf
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, c.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, c.z)
|
||||
if(!(c in chunk.cameras))
|
||||
chunk.cameras += c
|
||||
chunk.hasChanged()
|
||||
|
||||
/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
|
||||
var/x1 = max(0, c.x - 16) & ~0xf
|
||||
var/y1 = max(0, c.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, c.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, c.y + 16) & ~0xf
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, c.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, c.z)
|
||||
if(!c)
|
||||
chunk.hasChanged()
|
||||
if(c in chunk.cameras)
|
||||
chunk.cameras -= c
|
||||
chunk.hasChanged()
|
||||
|
||||
/mob/living/silicon/ai/var/mob/aiEye/eyeobj = new()
|
||||
|
||||
/mob/living/silicon/ai/New()
|
||||
..()
|
||||
eyeobj.ai = src
|
||||
spawn(20)
|
||||
freelook()
|
||||
|
||||
/mob/living/silicon/ai/death(gibbed)
|
||||
if(client && client.eye == eyeobj)
|
||||
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
|
||||
c.remove(eyeobj)
|
||||
client.eye = src
|
||||
return ..(gibbed)
|
||||
|
||||
/mob/living/silicon/ai/verb/freelook()
|
||||
set category = "AI Commands"
|
||||
set name = "freelook"
|
||||
current = null //cancel camera view first, it causes problems
|
||||
cameraFollow = null
|
||||
// machine = null
|
||||
if(!eyeobj) //if it got deleted somehow (like an admin trying to fix things <.<')
|
||||
eyeobj = new()
|
||||
client.eye = eyeobj
|
||||
eyeobj.loc = loc
|
||||
cameranet.visibility(eyeobj)
|
||||
cameraFollow = null
|
||||
|
||||
/mob/aiEye/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
cameranet.visibility(src)
|
||||
|
||||
/client/AIMove(n, direct, var/mob/living/silicon/ai/user)
|
||||
if(eye == user.eyeobj)
|
||||
user.eyeobj.loc = get_step(user.eyeobj, direct)
|
||||
cameranet.visibility(user.eyeobj)
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
/*
|
||||
/client/AIMoveZ(direct, var/mob/living/silicon/ai/user)
|
||||
if(eye == user.eyeobj)
|
||||
var/dif = 0
|
||||
if(direct == UP && user.eyeobj.z > 1)
|
||||
dif = -1
|
||||
else if(direct == DOWN && user.eyeobj.z < 4)
|
||||
dif = 1
|
||||
user.eyeobj.loc = locate(user.eyeobj.x, user.eyeobj.y, user.eyeobj.z + dif)
|
||||
cameranet.visibility(user.eyeobj)
|
||||
else
|
||||
return ..()
|
||||
*/
|
||||
|
||||
/turf/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(AI.client.eye == AI.eyeobj)
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/door/update_nearby_tiles(need_rebuild)
|
||||
. = ..(need_rebuild)
|
||||
cameranet.updateVisibility(loc)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
cameranet.addCamera(src)
|
||||
|
||||
/obj/machinery/camera/Del()
|
||||
cameranet.removeCamera(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
. = ..(W, user)
|
||||
if(istype(W, /obj/item/weapon/wirecutters))
|
||||
if(status)
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/proc/checkcameravis(atom/A)
|
||||
for(var/obj/machinery/camera/C in view(A,7))
|
||||
if(!C.status || C.stat == 2)
|
||||
continue
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/switchCamera(var/obj/machinery/camera/C)
|
||||
if(C && isturf(C.loc))
|
||||
eyeobj.loc = C.loc
|
||||
cameranet.visibility(eyeobj)
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/attack_ai(var/mob/user as mob)
|
||||
if (user != src)
|
||||
return
|
||||
|
||||
if (stat == 2)
|
||||
return
|
||||
|
||||
var/list/L = list()
|
||||
for (var/obj/machinery/camera/C in world)
|
||||
L.Add(C)
|
||||
|
||||
camera_sort(L)
|
||||
L = camera_network_sort(L)
|
||||
|
||||
var/list/D = list()
|
||||
for (var/obj/machinery/camera/C in L)
|
||||
if ( C.network in src.networks )
|
||||
D[text("[]: [][]", C.network, C.c_tag, (C.status ? null : " (Deactivated)"))] = C
|
||||
D["Cancel"] = "Cancel"
|
||||
|
||||
var/t = input(user, "Which camera should you change to?") as null|anything in D
|
||||
|
||||
if (!t || t == "Cancel")
|
||||
return 0
|
||||
|
||||
var/obj/machinery/camera/C = D[t]
|
||||
|
||||
eyeobj.loc = C.loc
|
||||
cameranet.visibility(eyeobj)
|
||||
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/cancel_camera()
|
||||
set name = "Cancel Camera View"
|
||||
set category = "OOC"
|
||||
reset_view(null)
|
||||
machine = null
|
||||
del eyeobj
|
||||
src.freelook()
|
||||
//All credit for this goes to Uristqwerty.
|
||||
|
||||
//And some to me! -Mini
|
||||
|
||||
|
||||
|
||||
//This file is partly designed around being able to uninclude it to go back to the old ai viewing system completely.
|
||||
//(And therefore also be portable to another similar codebase simply by transferring the file and including it after the other AI code files.)
|
||||
//There are probably a few parts that don't do that at the moment, but I'll fix them at some point.
|
||||
|
||||
|
||||
#define MINIMAP_UPDATE_DELAY 1200
|
||||
|
||||
/turf
|
||||
var/image/obscured
|
||||
var/image/dim
|
||||
|
||||
/turf/proc/visibilityChanged()
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/turf/New()
|
||||
..()
|
||||
cameranet.updateVisibility(src)
|
||||
/*
|
||||
/turf/Del()
|
||||
..()
|
||||
cameranet.updateVisibility(src)
|
||||
*/
|
||||
/datum/camerachunk
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/dimTurfs = list()
|
||||
var/list/obscured = list()
|
||||
var/list/dim = list()
|
||||
var/list/cameras = list()
|
||||
var/list/turfs = list()
|
||||
var/list/seenby = list()
|
||||
var/visible = 0
|
||||
var/changed = 1
|
||||
var/updating = 0
|
||||
|
||||
var/x
|
||||
var/y
|
||||
var/z
|
||||
|
||||
var/minimap_updating = 0
|
||||
|
||||
var/icon/minimap_icon = new('minimap.dmi', "chunk_base")
|
||||
var/obj/minimap_obj/minimap_obj = new()
|
||||
|
||||
/obj/minimap_obj/Click(location, control, params)
|
||||
if(!istype(usr, /mob/dead) && !istype(usr, /mob/living/silicon/ai) && !(usr.client && usr.client.holder && usr.client.holder.level >= 4))
|
||||
return
|
||||
|
||||
var/list/par = params2list(params)
|
||||
var/screen_loc = par["screen-loc"]
|
||||
|
||||
if(findtext(screen_loc, "minimap:") != 1)
|
||||
return
|
||||
|
||||
screen_loc = copytext(screen_loc, length("minimap:") + 1)
|
||||
|
||||
var/x_text = copytext(screen_loc, 1, findtext(screen_loc, ","))
|
||||
var/y_text = copytext(screen_loc, findtext(screen_loc, ",") + 1)
|
||||
|
||||
var/x = (text2num(copytext(x_text, 1, findtext(x_text, ":"))) - 1) * 16
|
||||
x += round((text2num(copytext(x_text, findtext(x_text, ":") + 1)) + 1) / 2)
|
||||
|
||||
var/y = (text2num(copytext(y_text, 1, findtext(y_text, ":"))) - 1) * 16
|
||||
y += round((text2num(copytext(y_text, findtext(y_text, ":") + 1)) + 1) / 2)
|
||||
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/ai = usr
|
||||
ai.freelook()
|
||||
ai.eyeobj.loc = locate(max(1, x - 1), max(1, y - 1), ai.eyeobj.z)
|
||||
cameranet.visibility(ai.eyeobj)
|
||||
|
||||
else
|
||||
usr.loc = locate(max(1, x - 1), max(1, y - 1), usr.z)
|
||||
|
||||
/mob/dead/verb/Open_Minimap()
|
||||
set category = "Ghost"
|
||||
winshow(src, "minimapwindow", 1)
|
||||
client.screen |= cameranet.minimap
|
||||
|
||||
if(cameranet.generating_minimap)
|
||||
cameranet.minimap_viewers += src
|
||||
|
||||
/mob/living/silicon/ai/verb/Open_Minimap()
|
||||
set category = "AI Commands"
|
||||
winshow(src, "minimapwindow", 1)
|
||||
client.screen |= cameranet.minimap
|
||||
|
||||
if(cameranet.generating_minimap)
|
||||
cameranet.minimap_viewers += src
|
||||
|
||||
/client/proc/Open_Minimap()
|
||||
set category = "Admin"
|
||||
winshow(src, "minimapwindow", 1)
|
||||
screen |= cameranet.minimap
|
||||
|
||||
if(cameranet.generating_minimap)
|
||||
cameranet.minimap_viewers += src.mob
|
||||
|
||||
/datum/camerachunk/proc/update_minimap()
|
||||
if(changed && !updating)
|
||||
update()
|
||||
|
||||
minimap_icon.Blend(rgb(255, 0, 0), ICON_MULTIPLY)
|
||||
|
||||
var/list/turfs = visibleTurfs | dimTurfs
|
||||
|
||||
for(var/turf/turf in turfs)
|
||||
var/x = (turf.x & 0xf) * 2
|
||||
var/y = (turf.y & 0xf) * 2
|
||||
|
||||
if(turf.density)
|
||||
minimap_icon.DrawBox(rgb(100, 100, 100), x + 1, y + 1, x + 2, y + 2)
|
||||
continue
|
||||
|
||||
else if(istype(turf, /turf/space))
|
||||
minimap_icon.DrawBox(rgb(0, 0, 0), x + 1, y + 1, x + 2, y + 2)
|
||||
|
||||
else
|
||||
minimap_icon.DrawBox(rgb(200, 200, 200), x + 1, y + 1, x + 2, y + 2)
|
||||
|
||||
for(var/obj/structure/o in turf)
|
||||
if(o.density)
|
||||
if(istype(o, /obj/structure/window) && (o.dir == NORTH || o.dir == SOUTH || o.dir == EAST || o.dir == WEST))
|
||||
if(o.dir == NORTH)
|
||||
minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 2, x + 2, y + 2)
|
||||
else if(o.dir == SOUTH)
|
||||
minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 1, x + 2, y + 1)
|
||||
else if(o.dir == EAST)
|
||||
minimap_icon.DrawBox(rgb(150, 150, 200), x + 3, y + 1, x + 2, y + 2)
|
||||
else if(o.dir == WEST)
|
||||
minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 1, x + 1, y + 2)
|
||||
|
||||
else
|
||||
minimap_icon.DrawBox(rgb(150, 150, 150), x + 1, y + 1, x + 2, y + 2)
|
||||
break
|
||||
|
||||
for(var/obj/machinery/door/o in turf)
|
||||
if(istype(o, /obj/machinery/door/window))
|
||||
if(o.dir == NORTH)
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 2, x + 2, y + 2)
|
||||
else if(o.dir == SOUTH)
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 2, y + 1)
|
||||
else if(o.dir == EAST)
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 2, y + 1, x + 2, y + 2)
|
||||
else if(o.dir == WEST)
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 1, y + 2)
|
||||
|
||||
else
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 2, y + 2)
|
||||
break
|
||||
|
||||
minimap_obj.screen_loc = "minimap:[src.x / 16],[src.y / 16]"
|
||||
minimap_obj.icon = minimap_icon
|
||||
|
||||
/mob/aiEye
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/ai = null
|
||||
density = 0
|
||||
|
||||
/datum/camerachunk/proc/add(mob/aiEye/ai)
|
||||
ai.visibleCameraChunks += src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images += obscured
|
||||
ai.ai.client.images += dim
|
||||
visible++
|
||||
seenby += ai
|
||||
if(changed && !updating)
|
||||
update()
|
||||
changed = 0
|
||||
|
||||
/datum/camerachunk/proc/remove(mob/aiEye/ai)
|
||||
ai.visibleCameraChunks -= src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images -= obscured
|
||||
ai.ai.client.images -= dim
|
||||
seenby -= ai
|
||||
if(visible > 0)
|
||||
visible--
|
||||
|
||||
/datum/camerachunk/proc/visibilityChanged(turf/loc)
|
||||
if(!(loc in visibleTurfs))
|
||||
return
|
||||
|
||||
hasChanged()
|
||||
|
||||
/datum/camerachunk/proc/hasChanged()
|
||||
if(visible)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(10)//Batch large changes, such as many doors opening or closing at once
|
||||
update()
|
||||
updating = 0
|
||||
else
|
||||
changed = 1
|
||||
|
||||
if(!minimap_updating)
|
||||
minimap_updating = 1
|
||||
|
||||
spawn(MINIMAP_UPDATE_DELAY)
|
||||
if(changed && !updating)
|
||||
update()
|
||||
changed = 0
|
||||
|
||||
update_minimap()
|
||||
minimap_updating = 0
|
||||
|
||||
/datum/camerachunk/proc/update()
|
||||
|
||||
var/list/newDimTurfs = list()
|
||||
var/list/newVisibleTurfs = list()
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
var/lum = c.luminosity
|
||||
c.luminosity = 7
|
||||
|
||||
newDimTurfs |= turfs & view(7, c)
|
||||
newVisibleTurfs |= turfs & view(6, c)
|
||||
|
||||
c.luminosity = lum
|
||||
|
||||
var/list/dimAdded = newDimTurfs - dimTurfs
|
||||
var/list/dimRemoved = dimTurfs - newDimTurfs
|
||||
var/list/visAdded = newVisibleTurfs - visibleTurfs
|
||||
var/list/visRemoved = visibleTurfs - newVisibleTurfs
|
||||
|
||||
visibleTurfs = newVisibleTurfs
|
||||
dimTurfs = newDimTurfs
|
||||
obscuredTurfs = turfs - dimTurfs
|
||||
dimTurfs -= visibleTurfs
|
||||
|
||||
for(var/turf/t in dimRemoved)
|
||||
if(t.dim)
|
||||
dim -= t.dim
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.dim
|
||||
|
||||
if(!(t in visibleTurfs))
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.obscured
|
||||
|
||||
for(var/turf/t in dimAdded)
|
||||
if(!(t in visibleTurfs))
|
||||
if(!t.dim)
|
||||
t.dim = image('cameravis.dmi', t, "dim", 15)
|
||||
t.mouse_opacity = 0
|
||||
|
||||
dim += t.dim
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.dim
|
||||
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.obscured
|
||||
|
||||
for(var/turf/t in visAdded)
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.obscured
|
||||
|
||||
for(var/turf/t in visRemoved)
|
||||
if(t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.obscured
|
||||
|
||||
|
||||
/datum/camerachunk/New(loc, x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
|
||||
src.x = x
|
||||
src.y = y
|
||||
src.z = z
|
||||
|
||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||
if(c.status)
|
||||
cameras += c
|
||||
|
||||
turfs = block(locate(x, y, z), locate(min(world.maxx, x + 15), min(world.maxy, y + 15), z))
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
var/lum = c.luminosity
|
||||
c.luminosity = 7
|
||||
|
||||
dimTurfs |= turfs & view(7, c)
|
||||
visibleTurfs |= turfs & view(6, c)
|
||||
|
||||
c.luminosity = lum
|
||||
|
||||
obscuredTurfs = turfs - dimTurfs
|
||||
dimTurfs -= visibleTurfs
|
||||
|
||||
for(var/turf/t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
|
||||
for(var/turf/t in dimTurfs)
|
||||
if(!(t in visibleTurfs))
|
||||
if(!t.dim)
|
||||
t.dim = image('cameravis.dmi', t, "dim", TURF_LAYER)
|
||||
t.dim.mouse_opacity = 0
|
||||
|
||||
dim += t.dim
|
||||
|
||||
cameranet.minimap += minimap_obj
|
||||
|
||||
var/datum/cameranet/cameranet = new()
|
||||
|
||||
/datum/cameranet
|
||||
var/list/cameras = list()
|
||||
var/list/chunks = list()
|
||||
var/network = "net1"
|
||||
var/ready = 0
|
||||
|
||||
var/list/minimap = list()
|
||||
|
||||
var/generating_minimap = TRUE
|
||||
var/list/minimap_viewers = list()
|
||||
|
||||
/datum/cameranet/New()
|
||||
..()
|
||||
|
||||
spawn(200)
|
||||
for(var/x = 0, x <= world.maxx, x += 16)
|
||||
for(var/y = 0, y <= world.maxy, y += 16)
|
||||
sleep(1)
|
||||
var/datum/camerachunk/c = getCameraChunk(x, y, 1)
|
||||
c.update_minimap()
|
||||
|
||||
for(var/mob/m in minimap_viewers)
|
||||
m.client.screen |= c.minimap_obj
|
||||
|
||||
generating_minimap = FALSE
|
||||
minimap_viewers = list()
|
||||
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
var/key = "[x],[y],[z]"
|
||||
return key in chunks
|
||||
|
||||
/datum/cameranet/proc/getCameraChunk(x, y, z)
|
||||
var/key = "[x],[y],[z]"
|
||||
|
||||
if(!(key in chunks))
|
||||
chunks[key] = new /datum/camerachunk(null, x, y, z)
|
||||
|
||||
return chunks[key]
|
||||
|
||||
/datum/cameranet/proc/visibility(mob/aiEye/ai)
|
||||
var/x1 = max(0, ai.x - 16) & ~0xf
|
||||
var/y1 = max(0, ai.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, ai.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, ai.y + 16) & ~0xf
|
||||
|
||||
var/list/visibleChunks = list()
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
visibleChunks += getCameraChunk(x, y, ai.z)
|
||||
|
||||
var/list/remove = ai.visibleCameraChunks - visibleChunks
|
||||
var/list/add = visibleChunks - ai.visibleCameraChunks
|
||||
|
||||
for(var/datum/camerachunk/c in remove)
|
||||
c.remove(ai)
|
||||
|
||||
for(var/datum/camerachunk/c in add)
|
||||
c.add(ai)
|
||||
|
||||
/datum/cameranet/proc/updateVisibility(turf/loc)
|
||||
if(!chunkGenerated(loc.x & ~0xf, loc.y & ~0xf, loc.z))
|
||||
return
|
||||
|
||||
var/datum/camerachunk/chunk = getCameraChunk(loc.x & ~0xf, loc.y & ~0xf, loc.z)
|
||||
chunk.visibilityChanged(loc)
|
||||
|
||||
/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
|
||||
var/x1 = max(0, c.x - 16) & ~0xf
|
||||
var/y1 = max(0, c.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, c.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, c.y + 16) & ~0xf
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, c.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, c.z)
|
||||
if(!(c in chunk.cameras))
|
||||
chunk.cameras += c
|
||||
chunk.hasChanged()
|
||||
|
||||
/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
|
||||
var/x1 = max(0, c.x - 16) & ~0xf
|
||||
var/y1 = max(0, c.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, c.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, c.y + 16) & ~0xf
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, c.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, c.z)
|
||||
if(!c)
|
||||
chunk.hasChanged()
|
||||
if(c in chunk.cameras)
|
||||
chunk.cameras -= c
|
||||
chunk.hasChanged()
|
||||
|
||||
/mob/living/silicon/ai/var/mob/aiEye/eyeobj = new()
|
||||
|
||||
/mob/living/silicon/ai/New()
|
||||
..()
|
||||
eyeobj.ai = src
|
||||
spawn(20)
|
||||
freelook()
|
||||
|
||||
/mob/living/silicon/ai/death(gibbed)
|
||||
if(client && client.eye == eyeobj)
|
||||
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
|
||||
c.remove(eyeobj)
|
||||
client.eye = src
|
||||
return ..(gibbed)
|
||||
|
||||
/mob/living/silicon/ai/verb/freelook()
|
||||
set category = "AI Commands"
|
||||
set name = "freelook"
|
||||
current = null //cancel camera view first, it causes problems
|
||||
cameraFollow = null
|
||||
// machine = null
|
||||
if(!eyeobj) //if it got deleted somehow (like an admin trying to fix things <.<')
|
||||
eyeobj = new()
|
||||
eyeobj.ai = src
|
||||
client.eye = eyeobj
|
||||
eyeobj.loc = loc
|
||||
cameranet.visibility(eyeobj)
|
||||
cameraFollow = null
|
||||
|
||||
/mob/aiEye/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
cameranet.visibility(src)
|
||||
|
||||
/client/AIMove(n, direct, var/mob/living/silicon/ai/user)
|
||||
if(eye == user.eyeobj)
|
||||
user.eyeobj.loc = get_step(user.eyeobj, direct)
|
||||
cameranet.visibility(user.eyeobj)
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
/*
|
||||
/client/AIMoveZ(direct, var/mob/living/silicon/ai/user)
|
||||
if(eye == user.eyeobj)
|
||||
var/dif = 0
|
||||
if(direct == UP && user.eyeobj.z > 1)
|
||||
dif = -1
|
||||
else if(direct == DOWN && user.eyeobj.z < 4)
|
||||
dif = 1
|
||||
user.eyeobj.loc = locate(user.eyeobj.x, user.eyeobj.y, user.eyeobj.z + dif)
|
||||
cameranet.visibility(user.eyeobj)
|
||||
else
|
||||
return ..()
|
||||
*/
|
||||
|
||||
/turf/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(AI.client.eye == AI.eyeobj)
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/door/update_nearby_tiles(need_rebuild)
|
||||
. = ..(need_rebuild)
|
||||
cameranet.updateVisibility(loc)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
cameranet.addCamera(src)
|
||||
|
||||
/obj/machinery/camera/Del()
|
||||
cameranet.removeCamera(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
. = ..(W, user)
|
||||
if(istype(W, /obj/item/weapon/wirecutters))
|
||||
if(status)
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/proc/checkcameravis(atom/A)
|
||||
for(var/obj/machinery/camera/C in view(A,7))
|
||||
if(!C.status || C.stat == 2)
|
||||
continue
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/attack_ai(var/mob/user as mob)
|
||||
if (user != src)
|
||||
return
|
||||
|
||||
if (stat == 2)
|
||||
return
|
||||
|
||||
var/list/L = list()
|
||||
for (var/obj/machinery/camera/C in world)
|
||||
L.Add(C)
|
||||
|
||||
camera_sort(L)
|
||||
L = camera_network_sort(L)
|
||||
|
||||
var/list/D = list()
|
||||
for (var/obj/machinery/camera/C in L)
|
||||
if ( C.network in src.networks )
|
||||
D[text("[]: [][]", C.network, C.c_tag, (C.status ? null : " (Deactivated)"))] = C
|
||||
D["Cancel"] = "Cancel"
|
||||
|
||||
var/t = input(user, "Which camera should you change to?") as null|anything in D
|
||||
|
||||
if (!t || t == "Cancel")
|
||||
return 0
|
||||
|
||||
var/obj/machinery/camera/C = D[t]
|
||||
|
||||
eyeobj.loc = C.loc
|
||||
cameranet.visibility(eyeobj)
|
||||
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/cancel_camera()
|
||||
set name = "Cancel Camera View"
|
||||
set category = "OOC"
|
||||
reset_view(null)
|
||||
machine = null
|
||||
|
||||
/mob/living/silicon/ai/reset_view(atom/A)
|
||||
if (client)
|
||||
if(!eyeobj)
|
||||
eyeobj = new()
|
||||
eyeobj.ai = src
|
||||
|
||||
client.eye = eyeobj
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
|
||||
if (istype(A, /atom/movable))
|
||||
eyeobj.loc = locate(A.x, A.y, A.z)
|
||||
|
||||
else
|
||||
eyeobj.loc = locate(src.x, src.y, src.z)
|
||||
|
||||
cameranet.visibility(eyeobj)
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
/mob/aiEye
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/ai = null
|
||||
density = 0
|
||||
|
||||
/mob/living/silicon/ai/var/mob/aiEye/eyeobj = new()
|
||||
|
||||
/mob/living/silicon/ai/New()
|
||||
..()
|
||||
eyeobj.ai = src
|
||||
spawn(20)
|
||||
freelook()
|
||||
|
||||
/mob/living/silicon/ai/death(gibbed)
|
||||
if(client && client.eye == eyeobj)
|
||||
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
|
||||
c.remove(eyeobj)
|
||||
client.eye = src
|
||||
return ..(gibbed)
|
||||
|
||||
/mob/living/silicon/ai/verb/freelook()
|
||||
set category = "AI Commands"
|
||||
set name = "freelook"
|
||||
current = null //cancel camera view first, it causes problems
|
||||
cameraFollow = null
|
||||
if(!eyeobj) //if it got deleted somehow (like an admin trying to fix things <.<')
|
||||
eyeobj = new()
|
||||
eyeobj.ai = src
|
||||
client.eye = eyeobj
|
||||
eyeobj.loc = loc
|
||||
cameranet.visibility(eyeobj)
|
||||
|
||||
/mob/aiEye/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
cameranet.visibility(src)
|
||||
|
||||
/client/AIMove(n, direct, var/mob/living/silicon/ai/user)
|
||||
if(eye == user.eyeobj)
|
||||
user.eyeobj.loc = get_step(user.eyeobj, direct)
|
||||
cameranet.visibility(user.eyeobj)
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
/turf/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(AI.client.eye == AI.eyeobj)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/attack_ai(var/mob/user as mob)
|
||||
if (user != src)
|
||||
return
|
||||
|
||||
if (stat == 2)
|
||||
return
|
||||
|
||||
var/list/L = list()
|
||||
for (var/obj/machinery/camera/C in world)
|
||||
L.Add(C)
|
||||
|
||||
camera_sort(L)
|
||||
L = camera_network_sort(L)
|
||||
|
||||
var/list/D = list()
|
||||
for (var/obj/machinery/camera/C in L)
|
||||
if ( C.network in src.networks )
|
||||
D[text("[]: [][]", C.network, C.c_tag, (C.status ? null : " (Deactivated)"))] = C
|
||||
D["Cancel"] = "Cancel"
|
||||
|
||||
var/t = input(user, "Which camera should you change to?") as null|anything in D
|
||||
|
||||
if (!t || t == "Cancel")
|
||||
return 0
|
||||
|
||||
var/obj/machinery/camera/C = D[t]
|
||||
|
||||
eyeobj.loc = C.loc
|
||||
cameranet.visibility(eyeobj)
|
||||
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/cancel_camera()
|
||||
set name = "Cancel Camera View"
|
||||
set category = "OOC"
|
||||
reset_view(null)
|
||||
machine = null
|
||||
|
||||
/mob/living/silicon/ai/reset_view(atom/A)
|
||||
if (client)
|
||||
if(!eyeobj)
|
||||
eyeobj = new()
|
||||
eyeobj.ai = src
|
||||
|
||||
client.eye = eyeobj
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
|
||||
if (istype(A, /atom/movable))
|
||||
eyeobj.loc = locate(A.x, A.y, A.z)
|
||||
|
||||
else
|
||||
eyeobj.loc = locate(src.x, src.y, src.z)
|
||||
|
||||
cameranet.visibility(eyeobj)
|
||||
@@ -0,0 +1,156 @@
|
||||
//------------------------------------------------------------
|
||||
//
|
||||
// The Cameranet
|
||||
//
|
||||
// The cameranet is a single global instance of a unique
|
||||
// datum, which contains logic for managing the individual
|
||||
// chunks.
|
||||
//
|
||||
//------------------------------------------------------------
|
||||
|
||||
/datum/cameranet
|
||||
var/list/cameras = list()
|
||||
var/list/chunks = list()
|
||||
var/network = "net1"
|
||||
var/ready = 0
|
||||
|
||||
var/list/minimap = list()
|
||||
|
||||
var/generating_minimap = TRUE
|
||||
|
||||
var/datum/cameranet/cameranet = new()
|
||||
|
||||
|
||||
|
||||
/datum/cameranet/New()
|
||||
..()
|
||||
|
||||
spawn(100)
|
||||
init_minimap()
|
||||
|
||||
|
||||
/datum/cameranet/proc/init_minimap()
|
||||
for(var/x = 0, x <= world.maxx, x += 16)
|
||||
for(var/y = 0, y <= world.maxy, y += 16)
|
||||
sleep(1)
|
||||
getCameraChunk(x, y, 5)
|
||||
getCameraChunk(x, y, 1)
|
||||
|
||||
generating_minimap = FALSE
|
||||
|
||||
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
var/key = "[x],[y],[z]"
|
||||
return key in chunks
|
||||
|
||||
|
||||
/datum/cameranet/proc/getCameraChunk(x, y, z)
|
||||
var/key = "[x],[y],[z]"
|
||||
|
||||
if(!(key in chunks))
|
||||
chunks[key] = new /datum/camerachunk(null, x, y, z)
|
||||
|
||||
return chunks[key]
|
||||
|
||||
|
||||
|
||||
|
||||
// This proc updates what chunks are considered seen
|
||||
// by an aiEye. As part of the process, it will force
|
||||
// any newly visible chunks with pending unscheduled
|
||||
// updates to update, and show the correct obscuring
|
||||
// and dimming image sets. If you do not call this
|
||||
// after the eye has moved, it may result in the
|
||||
// affected AI gaining (partial) xray, seeing through
|
||||
// now-closed doors, not seeing through open doors,
|
||||
// or other visibility oddities, depending on if/when
|
||||
// they last visited any of the chunks in the nearby
|
||||
// area.
|
||||
|
||||
// It must be called manually, as there is no way to
|
||||
// have a proc called automatically every time an
|
||||
// object's loc changes.
|
||||
|
||||
/datum/cameranet/proc/visibility(mob/aiEye/ai)
|
||||
var/x1 = max(0, ai.x - 16) & ~0xf
|
||||
var/y1 = max(0, ai.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, ai.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, ai.y + 16) & ~0xf
|
||||
|
||||
var/list/visibleChunks = list()
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
visibleChunks += getCameraChunk(x, y, ai.z)
|
||||
|
||||
var/list/remove = ai.visibleCameraChunks - visibleChunks
|
||||
var/list/add = visibleChunks - ai.visibleCameraChunks
|
||||
|
||||
for(var/datum/camerachunk/c in remove)
|
||||
c.remove(ai)
|
||||
|
||||
for(var/datum/camerachunk/c in add)
|
||||
c.add(ai)
|
||||
|
||||
|
||||
|
||||
|
||||
// This proc should be called if a turf, or the contents
|
||||
// of a turf, changes opacity. This includes such things
|
||||
// as changing the turf, opening or closing a door, or
|
||||
// anything else that would alter line of sight in the
|
||||
// general area.
|
||||
|
||||
/datum/cameranet/proc/updateVisibility(turf/loc)
|
||||
if(!chunkGenerated(loc.x & ~0xf, loc.y & ~0xf, loc.z))
|
||||
return
|
||||
|
||||
var/datum/camerachunk/chunk = getCameraChunk(loc.x & ~0xf, loc.y & ~0xf, loc.z)
|
||||
chunk.visibilityChanged(loc)
|
||||
|
||||
|
||||
|
||||
|
||||
// This proc updates all relevant chunks when enabling or
|
||||
// creating a camera, allowing freelook and the minimap to
|
||||
// respond correctly.
|
||||
|
||||
/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
|
||||
var/x1 = max(0, c.x - 16) & ~0xf
|
||||
var/y1 = max(0, c.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, c.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, c.y + 16) & ~0xf
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, c.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, c.z)
|
||||
|
||||
if(!(c in chunk.cameras))
|
||||
chunk.cameras += c
|
||||
chunk.hasChanged()
|
||||
|
||||
|
||||
|
||||
|
||||
// This proc updates all relevant chunks when disabling or
|
||||
// deleting a camera, allowing freelook and the minimap to
|
||||
// respond correctly.
|
||||
|
||||
/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
|
||||
var/x1 = max(0, c.x - 16) & ~0xf
|
||||
var/y1 = max(0, c.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, c.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, c.y + 16) & ~0xf
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, c.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, c.z)
|
||||
|
||||
if(!c)
|
||||
chunk.hasChanged()
|
||||
|
||||
if(c in chunk.cameras)
|
||||
chunk.cameras -= c
|
||||
chunk.hasChanged()
|
||||
@@ -0,0 +1,221 @@
|
||||
#define MINIMAP_UPDATE_DELAY 1200
|
||||
|
||||
/datum/camerachunk
|
||||
var/list/turfs = list()
|
||||
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/dimTurfs = list()
|
||||
|
||||
var/list/obscured = list()
|
||||
var/list/dim = list()
|
||||
|
||||
var/list/cameras = list()
|
||||
var/list/seenby = list()
|
||||
|
||||
var/changed = 1
|
||||
var/updating = 0
|
||||
var/minimap_updating = 0
|
||||
|
||||
var/x
|
||||
var/y
|
||||
var/z
|
||||
|
||||
|
||||
var/icon/minimap_icon = new('minimap.dmi', "chunk_base")
|
||||
var/obj/minimap_obj/minimap_obj = new()
|
||||
|
||||
|
||||
|
||||
/datum/camerachunk/New(loc, x, y, z)
|
||||
//Round X and Y down to a multiple of 16, if nessecary
|
||||
src.x = x & ~0xF
|
||||
src.y = y & ~0xF
|
||||
src.z = z
|
||||
|
||||
rebuild_chunk()
|
||||
|
||||
|
||||
|
||||
// Completely re-calculate the whole chunk.
|
||||
|
||||
/datum/camerachunk/proc/rebuild_chunk()
|
||||
for(var/mob/aiEye/eye in seenby)
|
||||
if(!eye.ai)
|
||||
seenby -= eye
|
||||
continue
|
||||
|
||||
if(eye.ai.client)
|
||||
eye.ai.client.images -= obscured
|
||||
eye.ai.client.images -= dim
|
||||
|
||||
var/start = locate(x, y, z)
|
||||
var/end = locate(min(x + 15, world.maxx), min(y + 15, world.maxy), z)
|
||||
|
||||
turfs = block(start, end)
|
||||
dimTurfs = list()
|
||||
visibleTurfs = list()
|
||||
obscured = list()
|
||||
dim = list()
|
||||
cameras = list()
|
||||
|
||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||
if(c.status)
|
||||
cameras += c
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
var/lum = c.luminosity
|
||||
c.luminosity = 7
|
||||
|
||||
dimTurfs |= turfs & view(7, c)
|
||||
visibleTurfs |= turfs & view(6, c)
|
||||
|
||||
c.luminosity = lum
|
||||
|
||||
obscuredTurfs = turfs - dimTurfs
|
||||
dimTurfs -= visibleTurfs
|
||||
|
||||
for(var/turf/t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
|
||||
for(var/turf/t in dimTurfs)
|
||||
if(!t.dim)
|
||||
t.dim = image('cameravis.dmi', t, "dim", TURF_LAYER)
|
||||
t.dim.mouse_opacity = 0
|
||||
|
||||
dim += t.dim
|
||||
|
||||
cameranet.minimap |= minimap_obj
|
||||
|
||||
for(var/mob/aiEye/eye in seenby)
|
||||
if(eye.ai.client)
|
||||
eye.ai.client.images |= obscured
|
||||
eye.ai.client.images |= dim
|
||||
|
||||
|
||||
|
||||
/datum/camerachunk/proc/add(mob/aiEye/eye)
|
||||
eye.visibleCameraChunks |= src
|
||||
|
||||
if(eye.ai.client)
|
||||
eye.ai.client.images |= obscured
|
||||
eye.ai.client.images |= dim
|
||||
|
||||
seenby |= eye
|
||||
|
||||
if(changed && !updating)
|
||||
update()
|
||||
changed = 0
|
||||
|
||||
|
||||
|
||||
/datum/camerachunk/proc/remove(mob/aiEye/eye)
|
||||
eye.visibleCameraChunks -= src
|
||||
|
||||
if(eye.ai.client)
|
||||
eye.ai.client.images -= obscured
|
||||
eye.ai.client.images -= dim
|
||||
|
||||
seenby -= eye
|
||||
|
||||
/datum/camerachunk/proc/visibilityChanged(turf/loc)
|
||||
if(!(loc in visibleTurfs))
|
||||
return
|
||||
|
||||
hasChanged()
|
||||
|
||||
/datum/camerachunk/proc/hasChanged()
|
||||
if(length(seenby) > 0)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
|
||||
spawn(10)//Batch large changes, such as many doors opening or closing at once
|
||||
update()
|
||||
updating = 0
|
||||
|
||||
else
|
||||
changed = 1
|
||||
|
||||
if(!minimap_updating)
|
||||
minimap_updating = 1
|
||||
|
||||
spawn(MINIMAP_UPDATE_DELAY)
|
||||
if(changed && !updating)
|
||||
update()
|
||||
changed = 0
|
||||
|
||||
update_minimap()
|
||||
minimap_updating = 0
|
||||
|
||||
/datum/camerachunk/proc/update()
|
||||
|
||||
var/list/newDimTurfs = list()
|
||||
var/list/newVisibleTurfs = list()
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
var/lum = c.luminosity
|
||||
c.luminosity = 7
|
||||
|
||||
newDimTurfs |= turfs & view(7, c)
|
||||
newVisibleTurfs |= turfs & view(6, c)
|
||||
|
||||
c.luminosity = lum
|
||||
|
||||
var/list/dimAdded = newDimTurfs - dimTurfs
|
||||
var/list/dimRemoved = dimTurfs - newDimTurfs
|
||||
var/list/visAdded = newVisibleTurfs - visibleTurfs
|
||||
var/list/visRemoved = visibleTurfs - newVisibleTurfs
|
||||
|
||||
visibleTurfs = newVisibleTurfs
|
||||
dimTurfs = newDimTurfs
|
||||
obscuredTurfs = turfs - dimTurfs
|
||||
dimTurfs -= visibleTurfs
|
||||
|
||||
var/list/images_added = list()
|
||||
var/list/images_removed = list()
|
||||
|
||||
for(var/turf/t in dimRemoved)
|
||||
if(t.dim)
|
||||
dim -= t.dim
|
||||
images_removed += t.dim
|
||||
|
||||
if(!(t in visibleTurfs))
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
images_added += t.obscured
|
||||
|
||||
for(var/turf/t in dimAdded)
|
||||
if(!(t in visibleTurfs))
|
||||
if(!t.dim)
|
||||
t.dim = image('cameravis.dmi', t, "dim", 15)
|
||||
t.mouse_opacity = 0
|
||||
|
||||
dim += t.dim
|
||||
images_added += t.dim
|
||||
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
images_removed += t.obscured
|
||||
|
||||
for(var/turf/t in visAdded)
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
images_removed += t.obscured
|
||||
|
||||
for(var/turf/t in visRemoved)
|
||||
if(t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
images_added += t.obscured
|
||||
|
||||
for(var/mob/aiEye/eye in seenby)
|
||||
if(eye.ai.client)
|
||||
eye.ai.client.images -= images_removed
|
||||
eye.ai.client.images |= images_added
|
||||
@@ -0,0 +1,137 @@
|
||||
/client/var/minimap_view_z = 1
|
||||
|
||||
/obj/minimap_obj
|
||||
var/datum/camerachunk/chunk
|
||||
|
||||
/obj/minimap_obj/Click(location, control, params)
|
||||
if(!istype(usr, /mob/dead) && !istype(usr, /mob/living/silicon/ai) && !(usr.client && usr.client.holder && usr.client.holder.level >= 4))
|
||||
return
|
||||
|
||||
var/list/par = params2list(params)
|
||||
var/screen_loc = par["screen-loc"]
|
||||
|
||||
if(findtext(screen_loc, "minimap:") != 1)
|
||||
return
|
||||
|
||||
screen_loc = copytext(screen_loc, length("minimap:") + 1)
|
||||
|
||||
var/x_text = copytext(screen_loc, 1, findtext(screen_loc, ","))
|
||||
var/y_text = copytext(screen_loc, findtext(screen_loc, ",") + 1)
|
||||
|
||||
var/x = chunk.x
|
||||
x += round((text2num(copytext(x_text, findtext(x_text, ":") + 1)) + 1) / 2)
|
||||
|
||||
var/y = chunk.y
|
||||
y += round((text2num(copytext(y_text, findtext(y_text, ":") + 1)) + 1) / 2)
|
||||
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/ai = usr
|
||||
ai.freelook()
|
||||
ai.eyeobj.loc = locate(max(1, x - 1), max(1, y - 1), usr.client.minimap_view_z)
|
||||
cameranet.visibility(ai.eyeobj)
|
||||
|
||||
else
|
||||
usr.loc = locate(max(1, x - 1), max(1, y - 1), usr.client.minimap_view_z)
|
||||
|
||||
/mob/dead/verb/Open_Minimap()
|
||||
set category = "Ghost"
|
||||
cameranet.show_minimap(client)
|
||||
|
||||
|
||||
/mob/living/silicon/ai/verb/Open_Minimap()
|
||||
set category = "AI Commands"
|
||||
cameranet.show_minimap(client)
|
||||
|
||||
|
||||
/client/proc/Open_Minimap()
|
||||
set category = "Admin"
|
||||
cameranet.show_minimap(src)
|
||||
|
||||
|
||||
/mob/verb/Open_Minimap_Z()
|
||||
set hidden = 1
|
||||
|
||||
if(!istype(src, /mob/dead) && !istype(src, /mob/living/silicon/ai) && !(client && client.holder && client.holder.level >= 4))
|
||||
return
|
||||
|
||||
var/level = input("Select a Z level", "Z select", null) as null | anything in cameranet.minimap
|
||||
|
||||
if(level != null)
|
||||
cameranet.show_minimap(client, level)
|
||||
|
||||
|
||||
|
||||
/datum/cameranet/proc/show_minimap(client/client, z_level = "z-1")
|
||||
if(!istype(client.mob, /mob/dead) && !istype(client.mob, /mob/living/silicon/ai) && !(client.holder && client.holder.level >= 4))
|
||||
return
|
||||
|
||||
if(z_level in cameranet.minimap)
|
||||
winshow(client, "minimapwindow", 1)
|
||||
|
||||
for(var/key in cameranet.minimap)
|
||||
client.screen -= cameranet.minimap[key]
|
||||
|
||||
client.screen |= cameranet.minimap[z_level]
|
||||
|
||||
if(cameranet.generating_minimap)
|
||||
spawn(50)
|
||||
show_minimap(client, z_level)
|
||||
|
||||
client.minimap_view_z = text2num(copytext(z_level, 3))
|
||||
|
||||
|
||||
/datum/camerachunk/proc/update_minimap()
|
||||
if(changed && !updating)
|
||||
update()
|
||||
|
||||
minimap_icon.Blend(rgb(255, 0, 0), ICON_MULTIPLY)
|
||||
|
||||
var/list/turfs = visibleTurfs | dimTurfs
|
||||
|
||||
for(var/turf/turf in turfs)
|
||||
var/x = (turf.x & 0xf) * 2
|
||||
var/y = (turf.y & 0xf) * 2
|
||||
|
||||
if(turf.density)
|
||||
minimap_icon.DrawBox(rgb(100, 100, 100), x + 1, y + 1, x + 2, y + 2)
|
||||
continue
|
||||
|
||||
else if(istype(turf, /turf/space))
|
||||
minimap_icon.DrawBox(rgb(0, 0, 0), x + 1, y + 1, x + 2, y + 2)
|
||||
|
||||
else
|
||||
minimap_icon.DrawBox(rgb(200, 200, 200), x + 1, y + 1, x + 2, y + 2)
|
||||
|
||||
for(var/obj/structure/o in turf)
|
||||
if(o.density)
|
||||
if(istype(o, /obj/structure/window) && (o.dir == NORTH || o.dir == SOUTH || o.dir == EAST || o.dir == WEST))
|
||||
if(o.dir == NORTH)
|
||||
minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 2, x + 2, y + 2)
|
||||
else if(o.dir == SOUTH)
|
||||
minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 1, x + 2, y + 1)
|
||||
else if(o.dir == EAST)
|
||||
minimap_icon.DrawBox(rgb(150, 150, 200), x + 3, y + 1, x + 2, y + 2)
|
||||
else if(o.dir == WEST)
|
||||
minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 1, x + 1, y + 2)
|
||||
|
||||
else
|
||||
minimap_icon.DrawBox(rgb(150, 150, 150), x + 1, y + 1, x + 2, y + 2)
|
||||
break
|
||||
|
||||
for(var/obj/machinery/door/o in turf)
|
||||
if(istype(o, /obj/machinery/door/window))
|
||||
if(o.dir == NORTH)
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 2, x + 2, y + 2)
|
||||
else if(o.dir == SOUTH)
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 2, y + 1)
|
||||
else if(o.dir == EAST)
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 2, y + 1, x + 2, y + 2)
|
||||
else if(o.dir == WEST)
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 1, y + 2)
|
||||
|
||||
else
|
||||
minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 2, y + 2)
|
||||
break
|
||||
|
||||
minimap_obj.screen_loc = "minimap:[src.x / 16],[src.y / 16]"
|
||||
minimap_obj.icon = minimap_icon
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
/turf
|
||||
var/image/obscured
|
||||
var/image/dim
|
||||
|
||||
/turf/proc/visibilityChanged()
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/turf/New()
|
||||
..()
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/obj/machinery/door/update_nearby_tiles(need_rebuild)
|
||||
. = ..(need_rebuild)
|
||||
cameranet.updateVisibility(loc)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
cameranet.addCamera(src)
|
||||
|
||||
/obj/machinery/camera/Del()
|
||||
cameranet.removeCamera(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
. = ..(W, user)
|
||||
if(istype(W, /obj/item/weapon/wirecutters))
|
||||
if(status)
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/proc/checkcameravis(atom/A)
|
||||
for(var/obj/machinery/camera/C in view(A,7))
|
||||
if(!C.status || C.stat == 2)
|
||||
continue
|
||||
return 1
|
||||
return 0
|
||||
@@ -0,0 +1,64 @@
|
||||
//don't use this
|
||||
/mob/living/carbon/human/proc/Birdize()
|
||||
if (monkeyizing)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
drop_from_slot(W)
|
||||
update_clothing()
|
||||
monkeyizing = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( loc )
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'mob.dmi'
|
||||
animation.master = src
|
||||
flick("h2monkey", animation)
|
||||
sleep(48)
|
||||
//animation = null
|
||||
var/mob/living/carbon/human/birdman/O = new /mob/living/carbon/human/birdman( loc )
|
||||
del(animation)
|
||||
del(O.organs)
|
||||
O.organs = organs
|
||||
for(var/name in O.organs)
|
||||
var/datum/organ/external/organ = O.organs[name]
|
||||
organ.owner = O
|
||||
for(var/obj/item/weapon/implant/implant in organ.implant)
|
||||
implant.imp_in = O
|
||||
|
||||
O.real_name = real_name
|
||||
O.name = name
|
||||
O.dna = dna
|
||||
updateappearance(O,O.dna.uni_identity)
|
||||
O.loc = loc
|
||||
O.viruses = viruses
|
||||
viruses = list()
|
||||
for(var/datum/disease/D in O.viruses)
|
||||
D.affected_mob = O
|
||||
O.flavor_text = flavor_text
|
||||
O.universal_speak = 1 //hacky fix until someone can figure out how to make them only understand humans
|
||||
|
||||
if (client)
|
||||
client.mob = O
|
||||
if(mind)
|
||||
mind.transfer_to(O)
|
||||
O.update_body()
|
||||
O.update_face()
|
||||
O.update_clothing()
|
||||
O << "<B>You are now a Birdman.</B>"
|
||||
spawn(0)//To prevent the proc from returning null.
|
||||
del(src)
|
||||
return
|
||||
|
||||
/client/proc/make_birdman(mob/living/carbon/human/H as mob)
|
||||
set category = "Fun"
|
||||
set name = "Make Birdman"
|
||||
set desc = "Make (mob) into a birdman."
|
||||
|
||||
if (!holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
|
||||
if(istype(H))
|
||||
H:Birdize()
|
||||
@@ -0,0 +1,180 @@
|
||||
//these are bugged as fuck. dont use them if you like runtimes.
|
||||
//was testing some icon overlays. might actually fix them up one day
|
||||
|
||||
/mob/living/carbon/human/birdman
|
||||
name = "birdman"
|
||||
real_name = "birdman"
|
||||
voice_name = "birdman"
|
||||
icon = 'birdman.dmi'
|
||||
icon_state = "m_none"
|
||||
//
|
||||
universal_speak = 1 //hacky fix until someone can figure out how to make them only understand humans
|
||||
voice_message = "chirps"
|
||||
examine_text = "some kind of placeholder text for a birdman.."
|
||||
|
||||
/mob/living/carbon/human/birdman/New()
|
||||
var/g = "m"
|
||||
if (gender == FEMALE)
|
||||
g = "f"
|
||||
|
||||
spawn (1)
|
||||
if(!stand_icon)
|
||||
stand_icon = new /icon('birdman.dmi', "body_[g]_s")
|
||||
if(!lying_icon)
|
||||
lying_icon = new /icon('birdman.dmi', "body_[g]_l")
|
||||
icon = stand_icon
|
||||
update_clothing()
|
||||
src << "\blue Your icons have been generated!"
|
||||
|
||||
/mob/living/carbon/human/birdman/update_body()
|
||||
if(stand_icon)
|
||||
del(stand_icon)
|
||||
if(lying_icon)
|
||||
del(lying_icon)
|
||||
|
||||
if (mutantrace)
|
||||
return
|
||||
|
||||
var/g = "m"
|
||||
if (gender == MALE)
|
||||
g = "m"
|
||||
else if (gender == FEMALE)
|
||||
g = "f"
|
||||
|
||||
stand_icon = new /icon('birdman.dmi', "torso_[g]_s")
|
||||
lying_icon = new /icon('birdman.dmi', "torso_[g]_l")
|
||||
|
||||
|
||||
|
||||
var/husk = (mutations & HUSK)
|
||||
//var/obese = (mutations & FAT)
|
||||
|
||||
stand_icon.Blend(new /icon('birdman.dmi', "chest_[g]_s"), ICON_OVERLAY)
|
||||
lying_icon.Blend(new /icon('birdman.dmi', "chest_[g]_l"), ICON_OVERLAY)
|
||||
|
||||
var/datum/organ/external/head = organs["head"]
|
||||
if(!head.destroyed)
|
||||
stand_icon.Blend(new /icon('birdman.dmi', "head_[g]_s"), ICON_OVERLAY)
|
||||
lying_icon.Blend(new /icon('birdman.dmi', "head_[g]_l"), ICON_OVERLAY)
|
||||
|
||||
for(var/name in organs)
|
||||
var/datum/organ/external/part = organs[name]
|
||||
if(!istype(part, /datum/organ/external/groin) \
|
||||
&& !istype(part, /datum/organ/external/chest) \
|
||||
&& !istype(part, /datum/organ/external/head) \
|
||||
&& !part.destroyed)
|
||||
var/icon/temp = new /icon('birdman.dmi', "[part.icon_name]_s")
|
||||
if(part.robot) temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
||||
stand_icon.Blend(temp, ICON_OVERLAY)
|
||||
temp = new /icon('birdman.dmi', "[part.icon_name]_l")
|
||||
if(part.robot) temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
||||
lying_icon.Blend(temp , ICON_OVERLAY)
|
||||
|
||||
stand_icon.Blend(new /icon('birdman.dmi', "groin_[g]_s"), ICON_OVERLAY)
|
||||
lying_icon.Blend(new /icon('birdman.dmi', "groin_[g]_l"), ICON_OVERLAY)
|
||||
|
||||
if (husk)
|
||||
var/icon/husk_s = new /icon('birdman.dmi', "husk_s")
|
||||
var/icon/husk_l = new /icon('birdman.dmi', "husk_l")
|
||||
|
||||
for(var/name in organs)
|
||||
var/datum/organ/external/part = organs[name]
|
||||
if(!istype(part, /datum/organ/external/groin) \
|
||||
&& !istype(part, /datum/organ/external/chest) \
|
||||
&& !istype(part, /datum/organ/external/head) \
|
||||
&& part.destroyed)
|
||||
husk_s.Blend(new /icon('dam_mask.dmi', "[part.icon_name]"), ICON_SUBTRACT)
|
||||
husk_l.Blend(new /icon('dam_mask.dmi', "[part.icon_name]2"), ICON_SUBTRACT)
|
||||
|
||||
stand_icon.Blend(husk_s, ICON_OVERLAY)
|
||||
lying_icon.Blend(husk_l, ICON_OVERLAY)
|
||||
/*else if(obese)
|
||||
stand_icon.Blend(new /icon('human.dmi', "fatbody_s"), ICON_OVERLAY)
|
||||
lying_icon.Blend(new /icon('human.dmi', "fatbody_l"), ICON_OVERLAY)*/
|
||||
|
||||
// Skin tone
|
||||
if (s_tone >= 0)
|
||||
stand_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
|
||||
lying_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
|
||||
else
|
||||
stand_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
|
||||
lying_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
|
||||
|
||||
if (underwear > 0)
|
||||
//if(!obese)
|
||||
stand_icon.Blend(new /icon('birdman.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY)
|
||||
lying_icon.Blend(new /icon('birdman.dmi', "underwear[underwear]_[g]_l"), ICON_OVERLAY)
|
||||
|
||||
|
||||
/mob/living/carbon/human/birdman/update_face()
|
||||
if(organs)
|
||||
var/datum/organ/external/head = organs["head"]
|
||||
if(head)
|
||||
if(head.destroyed)
|
||||
del(face_standing)
|
||||
del(face_lying)
|
||||
return
|
||||
|
||||
//if(!facial_hair_style || !hair_style) return//Seems people like to lose their icons, this should stop the runtimes for now
|
||||
del(face_standing)
|
||||
del(face_lying)
|
||||
|
||||
if (mutantrace)
|
||||
return
|
||||
|
||||
var/g = "m"
|
||||
if (gender == MALE)
|
||||
g = "m"
|
||||
else if (gender == FEMALE)
|
||||
g = "f"
|
||||
|
||||
var/icon/eyes_s = new/icon("icon" = 'birdman_face.dmi', "icon_state" = "eyes_s")
|
||||
var/icon/eyes_l = new/icon("icon" = 'birdman_face.dmi', "icon_state" = "eyes_l")
|
||||
eyes_s.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
|
||||
eyes_l.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
|
||||
|
||||
//var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
//var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l")
|
||||
//hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
|
||||
//hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
|
||||
|
||||
//var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
|
||||
//var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l")
|
||||
//facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
|
||||
//facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
|
||||
|
||||
var/icon/mouth_s = new/icon("icon" = 'birdman_face.dmi', "icon_state" = "mouth_[g]_s")
|
||||
var/icon/mouth_l = new/icon("icon" = 'birdman_face.dmi', "icon_state" = "mouth_[g]_l")
|
||||
|
||||
// if the head or mask has the flag BLOCKHAIR (equal to 5), then do not apply hair
|
||||
//if((!(head && (head.flags & BLOCKHAIR))) && !(wear_mask && (wear_mask.flags & BLOCKHAIR)))
|
||||
//eyes_s.Blend(hair_s, ICON_OVERLAY)
|
||||
//eyes_l.Blend(hair_l, ICON_OVERLAY)
|
||||
|
||||
eyes_s.Blend(mouth_s, ICON_OVERLAY)
|
||||
eyes_l.Blend(mouth_l, ICON_OVERLAY)
|
||||
|
||||
// if BLOCKHAIR, do not apply facial hair
|
||||
//if((!(head && (head.flags & BLOCKHAIR))) && !(wear_mask && (wear_mask.flags & BLOCKHAIR)))
|
||||
//eyes_s.Blend(facial_s, ICON_OVERLAY)
|
||||
//eyes_l.Blend(facial_l, ICON_OVERLAY)
|
||||
|
||||
|
||||
face_standing = new /image()
|
||||
face_lying = new /image()
|
||||
face_standing.icon = eyes_s
|
||||
face_standing.layer = MOB_LAYER
|
||||
face_lying.icon = eyes_l
|
||||
face_lying.layer = MOB_LAYER
|
||||
|
||||
del(mouth_l)
|
||||
del(mouth_s)
|
||||
//del(facial_l)
|
||||
//del(facial_s)
|
||||
//del(hair_l)
|
||||
//del(hair_s)
|
||||
del(eyes_l)
|
||||
del(eyes_s)
|
||||
|
||||
/mob/living/carbon/human/birdman/co2overloadtime = null
|
||||
/mob/living/carbon/human/birdman/temperature_resistance = T0C+70
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -131,7 +131,7 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
radiation = 0
|
||||
|
||||
//update values
|
||||
var/transfer_ratio = 50 / field_strength
|
||||
var/transfer_ratio = field_strength / 50
|
||||
major_radius = field_strength * 0.21875// max = 8.75
|
||||
minor_radius = field_strength * 0.2125// max = 8.625
|
||||
volume_covered = PI * major_radius * minor_radius * 2.5 * 2.5 * 2.5 * 7 * 7 * transfer_ratio
|
||||
@@ -159,10 +159,12 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
var/datum/gas_mixture/plasma_captured = new /datum/gas_mixture()
|
||||
//
|
||||
plasma_captured.toxins = round(gas_covered.toxins * transfer_ratio)
|
||||
//world << "\blue[plasma_captured.toxins] moles of plasma captured"
|
||||
plasma_captured.temperature = gas_covered.temperature
|
||||
//plasma_captured.update_values()
|
||||
gas_covered.toxins -= plasma_captured.toxins
|
||||
plasma_captured.update_values()
|
||||
gas_covered.update_values()
|
||||
//gas_covered.update_values()
|
||||
//
|
||||
held_plasma.merge(plasma_captured)
|
||||
//
|
||||
environment.merge(gas_covered)
|
||||
@@ -187,7 +189,25 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
//if there is too much plasma in the field, lose some
|
||||
/*if( held_plasma.toxins > (MOLES_CELLSTANDARD * 7) * (50 / field_strength) )
|
||||
LosePlasma()*/
|
||||
LosePlasma()
|
||||
if(held_plasma.toxins > 1)
|
||||
//lose a random amount of plasma back into the air, increased by the field strength (want to switch this over to frequency eventually)
|
||||
var/loss_ratio = rand() * (0.05 + (0.05 * 50 / field_strength))
|
||||
//world << "lost [loss_ratio*100]% of held plasma"
|
||||
//
|
||||
var/datum/gas_mixture/plasma_lost = new
|
||||
plasma_lost.temperature = held_plasma.temperature
|
||||
//
|
||||
plasma_lost.toxins = held_plasma.toxins * loss_ratio
|
||||
//plasma_lost.update_values()
|
||||
held_plasma.toxins -= held_plasma.toxins * loss_ratio
|
||||
//held_plasma.update_values()
|
||||
//
|
||||
environment.merge(plasma_lost)
|
||||
radiation += loss_ratio * mega_energy * 0.1
|
||||
mega_energy -= loss_ratio * mega_energy * 0.1
|
||||
else
|
||||
held_plasma.toxins = 0
|
||||
//held_plasma.update_values()
|
||||
|
||||
//handle some reactants formatting
|
||||
//helium-4 has no use at the moment, but a buttload of it is produced
|
||||
@@ -293,30 +313,6 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
catcher.UpdateSize()
|
||||
return changed
|
||||
|
||||
proc/LosePlasma()
|
||||
if(held_plasma.toxins > 1)
|
||||
//lose a random amount of plasma back into the air, increased by the field strength (want to switch this over to frequency eventually)
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/loss_ratio = rand() * (0.05 + (0.05 * 50 / field_strength))
|
||||
//world << "lost [loss_ratio*100]% of held plasma"
|
||||
//
|
||||
var/datum/gas_mixture/plasma_lost = new
|
||||
plasma_lost.temperature = held_plasma.temperature
|
||||
//
|
||||
plasma_lost.toxins = held_plasma.toxins * loss_ratio
|
||||
plasma_lost.update_values()
|
||||
held_plasma.toxins -= held_plasma.toxins * loss_ratio
|
||||
held_plasma.update_values()
|
||||
//
|
||||
environment.merge(plasma_lost)
|
||||
radiation += loss_ratio * mega_energy * 0.1
|
||||
mega_energy -= loss_ratio * mega_energy * 0.1
|
||||
return 1
|
||||
else
|
||||
held_plasma.toxins = 0
|
||||
held_plasma.update_values()
|
||||
return 0
|
||||
|
||||
//the !!fun!! part
|
||||
//reactions have to be individually hardcoded, see AttemptReaction() below this
|
||||
proc/React()
|
||||
|
||||
@@ -104,11 +104,11 @@
|
||||
user.machine = null
|
||||
user << browse(null, "window=fuel_injector")
|
||||
return
|
||||
var/t = "<B>Reactor Core Fuel Injector</B><BR>"
|
||||
var/t = "<B>Reactor Core Fuel Injector</B><hr>"
|
||||
t += "<b>Stage:</b> <font color=blue>[stage]</font><br>"
|
||||
t += "<b>Status:</b> [injecting ? "<font color=green>Active</font> <a href='?src=\ref[src];end_injecting=1'>\[Disable\]</a>" : "<font color=blue>Standby</font> <a href='?src=\ref[src];begin_injecting=1'>\[Enable\]</a>"]<br>"
|
||||
t += "<b>Interval (sec):</b> <font color=blue>[rate/10]</font> <a href='?src=\ref[src];cyclerate=1'>\[Modify\]</a>"
|
||||
t += "<b>Fuel usage:</b> [fuel_usage*100]% <a href='?src=\ref[src];fuel_usage=1'>\[Modify\]</a>"
|
||||
t += "<b>Interval (sec):</b> <font color=blue>[rate/10]</font> <a href='?src=\ref[src];cyclerate=1'>\[Modify\]</a><br>"
|
||||
t += "<b>Fuel usage:</b> [fuel_usage*100]% <a href='?src=\ref[src];fuel_usage=1'>\[Modify\]</a><br>"
|
||||
/*
|
||||
var/t = "<B>Reactor Core Fuel Control</B><BR>"
|
||||
t += "Current fuel injection stage: [active_stage]<br>"
|
||||
@@ -146,6 +146,7 @@
|
||||
t += "</tr>"
|
||||
t += "</table>"
|
||||
*/
|
||||
t += "<hr>"
|
||||
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
|
||||
user << browse(t, "window=fuel_injector;size=500x800")
|
||||
user.machine = src
|
||||
@@ -178,26 +179,21 @@
|
||||
for(var/reagent in owned_assembly_port.cur_assembly.rod_quantities)
|
||||
//world << "checking [reagent]"
|
||||
if(owned_assembly_port.cur_assembly.rod_quantities[reagent] > 0)
|
||||
//world << " rods left: [owned_assembly_port.cur_assembly.rod_quantities[reagent]]]
|
||||
//world << " rods left: [owned_assembly_port.cur_assembly.rod_quantities[reagent]]"
|
||||
var/amount = owned_assembly_port.cur_assembly.rod_quantities[reagent] * fuel_usage
|
||||
var/numparticles = round(amount * 1000)
|
||||
if(numparticles < 1)
|
||||
numparticles = 1
|
||||
//world << " amount: [amount]"
|
||||
//world << " numparticles: [numparticles]"
|
||||
for(var/i=0, i<numparticles, i++)
|
||||
var/obj/effect/accelerated_particle/particle = new(src.loc, src.dir)
|
||||
particle.particle_type = reagent
|
||||
particle.energy = 0
|
||||
particle.icon_state = "particle_single"
|
||||
particle.pixel_x = rand(-10,10)
|
||||
particle.pixel_y = rand(-10,10)
|
||||
var/extra_particles = round(rand(0, numparticles - i - 1))
|
||||
//world << "[extra_particles + 1] [reagent] particles"
|
||||
particle.additional_particles = extra_particles
|
||||
particle.target = target_field
|
||||
i += extra_particles
|
||||
//world << "[reagent] particle injected"
|
||||
//
|
||||
var/obj/effect/accelerated_particle/particle = new/obj/effect/accelerated_particle(src.loc, src.dir)
|
||||
particle.particle_type = reagent
|
||||
particle.energy = 0
|
||||
particle.icon_state = "particle"
|
||||
particle.additional_particles = numparticles - 1
|
||||
particle.target = target_field
|
||||
//
|
||||
owned_assembly_port.cur_assembly.rod_quantities[reagent] -= amount
|
||||
amount_left += owned_assembly_port.cur_assembly.rod_quantities[reagent]
|
||||
owned_assembly_port.cur_assembly.amount_depleted = amount_left / 300
|
||||
|
||||
@@ -1,30 +1,35 @@
|
||||
/mob/living/carbon/human/proc/Tajaraize()
|
||||
if (monkeyizing)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
drop_from_slot(W)
|
||||
update_clothing()
|
||||
monkeyizing = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
overlays = list()
|
||||
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( loc )
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'mob.dmi'
|
||||
animation.master = src
|
||||
flick("h2monkey", animation)
|
||||
sleep(48)
|
||||
sleep(18)
|
||||
//animation = null
|
||||
var/mob/living/carbon/human/tajaran/O = new /mob/living/carbon/human/tajaran( loc )
|
||||
del(animation)
|
||||
del(O.organs)
|
||||
O.organs = organs
|
||||
for(var/name in O.organs)
|
||||
for(var/name in O.organs) //Ensuring organ trasnfer
|
||||
var/datum/organ/external/organ = O.organs[name]
|
||||
organ.owner = O
|
||||
for(var/obj/item/weapon/implant/implant in organ.implant)
|
||||
implant.imp_in = O
|
||||
for(var/obj/hud/H in contents) //Lets not get a duplicate hud
|
||||
del(H)
|
||||
for(var/named in vars) //Making them keep their crap.
|
||||
if(istype(vars[named], /obj/item))
|
||||
O.vars[named] = vars[named]
|
||||
else if (named == "contents")
|
||||
O.vars[named] = vars[named]
|
||||
|
||||
O.real_name = real_name
|
||||
O.name = name
|
||||
@@ -32,6 +37,7 @@
|
||||
updateappearance(O,O.dna.uni_identity)
|
||||
O.loc = loc
|
||||
O.viruses = viruses
|
||||
O.s_tone = s_tone
|
||||
viruses = list()
|
||||
for(var/datum/disease/D in O.viruses)
|
||||
D.affected_mob = O
|
||||
@@ -42,9 +48,14 @@
|
||||
client.mob = O
|
||||
if(mind)
|
||||
mind.transfer_to(O)
|
||||
|
||||
del(O.stand_icon) //Force it to update.
|
||||
del(O.lying_icon)
|
||||
|
||||
O.update_body()
|
||||
O.update_face()
|
||||
O.update_clothing()
|
||||
spawn(1)
|
||||
O.update_clothing()
|
||||
O << "<B>You are now a Tajara.</B>"
|
||||
spawn(0)//To prevent the proc from returning null.
|
||||
del(src)
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
real_name = "tajaran"
|
||||
voice_name = "tajaran"
|
||||
icon = 'tajaran.dmi'
|
||||
icon_state = "m-none"
|
||||
icon_state = "m_none"
|
||||
var/list/tajspeak_letters = list("~","*","-")
|
||||
//
|
||||
universal_speak = 1 //hacky fix until someone can figure out how to make them only understand humans
|
||||
taj_talk_understand = 1
|
||||
voice_message = "mrowls"
|
||||
examine_text = "one of the cat-like Tajarans."
|
||||
examine_text = "one of the cat-like Tajarans"
|
||||
|
||||
/mob/living/carbon/human/tajaran/New()
|
||||
var/g = "m"
|
||||
@@ -28,7 +28,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/tajaran/update_clothing()
|
||||
..()
|
||||
// ..()
|
||||
|
||||
if (monkeyizing)
|
||||
return
|
||||
@@ -239,9 +239,6 @@
|
||||
overlays += image("icon" = 'belt_mirror.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER)
|
||||
s_store.screen_loc = ui_sstore1
|
||||
|
||||
if (h_store)
|
||||
h_store.screen_loc = ui_hstore1
|
||||
|
||||
if(client) hud_used.other_update() //Update the screenloc of the items on the 'other' inventory bar
|
||||
//to hide / show them.
|
||||
if (client)
|
||||
@@ -592,94 +589,3 @@
|
||||
|
||||
/mob/living/carbon/human/tajaran/co2overloadtime = null
|
||||
/mob/living/carbon/human/tajaran/temperature_resistance = T0C+70
|
||||
|
||||
|
||||
/* //This is silly. -- Erthilo
|
||||
/mob/living/carbon/human/tajaran/Emissary/
|
||||
unacidable = 1
|
||||
var/aegis = 1
|
||||
|
||||
/mob/living/carbon/human/tajaran/Emissary/New()
|
||||
|
||||
..()
|
||||
|
||||
reagents.add_reagent("hyperzine", 5000) //From the dark, to the light, it's a supersonic flight!
|
||||
// Gotta keep it going!
|
||||
if (!(mutations & HULK))
|
||||
mutations |= HULK
|
||||
|
||||
if (!(mutations & LASER))
|
||||
mutations |= LASER
|
||||
|
||||
if (!(mutations & XRAY))
|
||||
mutations |= XRAY
|
||||
sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
|
||||
see_in_dark = 8
|
||||
see_invisible = 2
|
||||
|
||||
if (!(mutations & COLD_RESISTANCE))
|
||||
mutations |= COLD_RESISTANCE
|
||||
|
||||
if (!(mutations & TK))
|
||||
mutations |= TK
|
||||
|
||||
if(!(mutations & HEAL))
|
||||
mutations |= HEAL
|
||||
|
||||
spawn(0)
|
||||
while(src)
|
||||
adjustBruteLoss(-10)
|
||||
adjustToxLoss(-10)
|
||||
adjustOxyLoss(-10)
|
||||
adjustFireLoss(-10)
|
||||
sleep(10)
|
||||
|
||||
|
||||
/mob/living/carbon/human/tajaran/Emissary/ex_act()
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/tajaran/Emissary/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params)
|
||||
if(istype(target , /obj/machinery/door/airlock))
|
||||
if(target:locked)
|
||||
target:locked = 0
|
||||
if(!target:density)
|
||||
return 1
|
||||
if(target:operating > 0)
|
||||
return
|
||||
if(!ticker)
|
||||
return 0
|
||||
if(!target:operating)
|
||||
target:operating = 1
|
||||
|
||||
target:animate("opening")
|
||||
target:sd_SetOpacity(0)
|
||||
sleep(10)
|
||||
target:layer = 2.7
|
||||
target:density = 0
|
||||
target:update_icon()
|
||||
target:sd_SetOpacity(0)
|
||||
target:update_nearby_tiles()
|
||||
|
||||
target:operating = -1
|
||||
|
||||
user << "You force the door open, shearing the bolts and burning out the motor."
|
||||
|
||||
if(target:operating)
|
||||
target:operating = -1
|
||||
else if(istype(target , /obj/machinery/door/firedoor))
|
||||
target:open()
|
||||
|
||||
/mob/living/carbon/human/tajaran/Emissary/Life()
|
||||
|
||||
..()
|
||||
|
||||
if (!(mutations & HULK))
|
||||
mutations |= HULK
|
||||
|
||||
|
||||
if((stat == 2) && aegis)
|
||||
src.show_message("\red [src]'s eyes open suddenlly.", 3, "\red \"I gave a solemn vow to never die for long.\"", 2)
|
||||
src.heal_overall_damage(9001,9001)
|
||||
src.stat = 0
|
||||
aegis = 0
|
||||
*/
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,226 @@
|
||||
//links to a power monitor computer and transmits the amount of energy in the associated powercable network
|
||||
//uses the navbeacon sprite and transmits data via magic for now
|
||||
|
||||
/obj/machinery/powermonitor
|
||||
|
||||
icon = 'objects.dmi'
|
||||
icon_state = "navbeacon0-f"
|
||||
name = "power monitor"
|
||||
desc = "A monitoring device used to track power in a cable network."
|
||||
level = 1 // underfloor
|
||||
layer = 2.5
|
||||
anchored = 1
|
||||
|
||||
var/freq = 1427 // radio frequency
|
||||
var/powernet_tag = "" //the text tag associated with this power monitor's network
|
||||
var/open = 0 // true if cover is open
|
||||
var/locked = 1 // true if controls are locked
|
||||
var/list/codes // assoc. list of transponder codes
|
||||
var/codes_txt = "" // codes as set on map: "tag1;tag2" or "tag1=value;tag2=value"
|
||||
|
||||
req_access = list(access_engine)
|
||||
|
||||
New()
|
||||
..()
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
|
||||
set_codes()
|
||||
|
||||
spawn(5) // must wait for map loading to finish
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(src, freq, RADIO_POWER)
|
||||
|
||||
// set the transponder codes assoc list from codes_txt
|
||||
proc/set_codes()
|
||||
if(!codes_txt)
|
||||
return
|
||||
|
||||
codes = new()
|
||||
|
||||
var/list/entries = dd_text2List(codes_txt, ";") // entries are separated by semicolons
|
||||
|
||||
for(var/e in entries)
|
||||
var/index = findtext(e, "=") // format is "key=value"
|
||||
if(index)
|
||||
var/key = copytext(e, 1, index)
|
||||
var/val = copytext(e, index+1)
|
||||
codes[key] = val
|
||||
else
|
||||
codes[e] = "1"
|
||||
|
||||
// called when turf state changes
|
||||
// hide the object if turf is intact
|
||||
hide(var/intact)
|
||||
invisibility = intact ? 101 : 0
|
||||
updateicon()
|
||||
|
||||
// update the icon_state
|
||||
proc/updateicon()
|
||||
var/state="navbeacon[open]"
|
||||
if(invisibility)
|
||||
icon_state = "[state]-f" // if invisible, set icon to faded version
|
||||
// in case revealed by T-scanner
|
||||
else
|
||||
icon_state = "[state]"
|
||||
|
||||
// look for a signal of the form "getpowerlevel"
|
||||
// where X is any
|
||||
// or the location
|
||||
// or one of the set transponder keys
|
||||
// if found, return a signal
|
||||
receive_signal(datum/signal/signal)
|
||||
|
||||
var/request = signal.data["getpowermonitor"]
|
||||
if(request && (request == "any" || request == powernet_tag) )
|
||||
spawn(1)
|
||||
post_signal()
|
||||
|
||||
// return a signal giving the power network energy level
|
||||
proc/post_signal()
|
||||
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq)
|
||||
|
||||
if(!frequency) return
|
||||
|
||||
var/datum/signal/signal = new()
|
||||
signal.source = src
|
||||
signal.transmission_method = 1
|
||||
signal.data["powerlevel"] = 1 //TODO
|
||||
|
||||
for(var/key in codes)
|
||||
signal.data[key] = codes[key]
|
||||
|
||||
frequency.post_signal(src, signal, filter = RADIO_POWER)
|
||||
|
||||
attackby(var/obj/item/I, var/mob/user)
|
||||
var/turf/T = loc
|
||||
if(T.intact)
|
||||
return // prevent intraction when T-scanner revealed
|
||||
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
open = !open
|
||||
|
||||
user.visible_message("[user] [open ? "opens" : "closes"] the beacon's cover.", "You [open ? "open" : "close"] the beacon's cover.")
|
||||
|
||||
updateicon()
|
||||
|
||||
else if (istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda))
|
||||
if(open)
|
||||
if (src.allowed(user))
|
||||
src.locked = !src.locked
|
||||
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
|
||||
else
|
||||
user << "\red Access denied."
|
||||
updateDialog()
|
||||
else
|
||||
user << "You must open the cover first!"
|
||||
return
|
||||
|
||||
attack_ai(var/mob/user)
|
||||
interact(user, 1)
|
||||
|
||||
attack_paw()
|
||||
return
|
||||
|
||||
attack_hand(var/mob/user)
|
||||
interact(user, 0)
|
||||
|
||||
proc/interact(var/mob/user, var/ai = 0)
|
||||
var/turf/T = loc
|
||||
if(T.intact)
|
||||
return // prevent intraction when T-scanner revealed
|
||||
|
||||
if(!open && !ai) // can't alter controls if not open, unless you're an AI
|
||||
user << "The monitor's control cover is closed."
|
||||
return
|
||||
|
||||
var/dat = "<TT><B>Navigation Beacon</B><HR>"
|
||||
if(locked && !ai)
|
||||
dat += "<i>(swipe card to unlock controls)</i><BR>"
|
||||
else if(!ai)
|
||||
dat += "<i>(swipe card to lock controls)</i><BR>"
|
||||
|
||||
dat += "Frequency: "
|
||||
if(!locked)
|
||||
dat += "<A href='byond://?src=\ref[src];freq=-10'>-</A>"
|
||||
dat += "<A href='byond://?src=\ref[src];freq=-2'>-</A>"
|
||||
dat += "[format_frequency(freq)]"
|
||||
if(!locked)
|
||||
dat += "<A href='byond://?src=\ref[src];freq=2'>+</A>"
|
||||
dat += "<A href='byond://?src=\ref[src];freq=10'>+</A>"
|
||||
dat += "<hr>"
|
||||
|
||||
dat += "Power network tag: [powernet_tag ? powernet_tag : "(none)"]</A><BR>"
|
||||
dat += "Transponder Codes:<UL>"
|
||||
for(var/key in codes)
|
||||
dat += "<LI>[key] ... [codes[key]]"
|
||||
if(!locked)
|
||||
dat += " <small><A href='byond://?src=\ref[src];edit=1;code=[key]'>(edit)</A>"
|
||||
dat += " <A href='byond://?src=\ref[src];delete=1;code=[key]'>(delete)</A></small><BR>"
|
||||
if(!locked)
|
||||
dat += "<small><A href='byond://?src=\ref[src];add=1;'>(add new)</A></small><BR>"
|
||||
dat += "<UL></TT>"
|
||||
|
||||
user << browse(dat, "window=powermonitor")
|
||||
onclose(user, "powermonitor")
|
||||
return
|
||||
|
||||
Topic(href, href_list)
|
||||
..()
|
||||
if (usr.stat)
|
||||
return
|
||||
if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon)))
|
||||
if(open && !locked)
|
||||
usr.machine = src
|
||||
|
||||
if (href_list["freq"])
|
||||
freq = sanitize_frequency(freq + text2num(href_list["freq"]))
|
||||
updateDialog()
|
||||
|
||||
else if(href_list["modifytag"])
|
||||
var/newtag = input("Enter new power network tag", "Power Monitor", powernet_tag) as text|null
|
||||
if(newtag)
|
||||
powernet_tag = newtag
|
||||
updateDialog()
|
||||
|
||||
else if(href_list["edit"])
|
||||
var/codekey = href_list["code"]
|
||||
|
||||
var/newkey = input("Enter Transponder Code Key", "Power Monitor", codekey) as text|null
|
||||
if(!newkey)
|
||||
return
|
||||
|
||||
var/codeval = codes[codekey]
|
||||
var/newval = input("Enter Transponder Code Value", "Power Monitor", codeval) as text|null
|
||||
if(!newval)
|
||||
newval = codekey
|
||||
return
|
||||
|
||||
codes.Remove(codekey)
|
||||
codes[newkey] = newval
|
||||
|
||||
updateDialog()
|
||||
|
||||
else if(href_list["delete"])
|
||||
var/codekey = href_list["code"]
|
||||
codes.Remove(codekey)
|
||||
updateDialog()
|
||||
|
||||
else if(href_list["add"])
|
||||
|
||||
var/newkey = input("Enter New Transponder Code Key", "Power Monitor") as text|null
|
||||
if(!newkey)
|
||||
return
|
||||
|
||||
var/newval = input("Enter New Transponder Code Value", "Power Monitor") as text|null
|
||||
if(!newval)
|
||||
newval = "1"
|
||||
return
|
||||
|
||||
if(!codes)
|
||||
codes = new()
|
||||
|
||||
codes[newkey] = newval
|
||||
|
||||
updateDialog()
|
||||
@@ -21,7 +21,7 @@ log transactions
|
||||
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(ishuman(user))
|
||||
var/obj/item/weapon/card/id/user_id = src.scan_user(user)
|
||||
if(istype(I,/obj/item/weapon/spacecash))
|
||||
if(istype(I,/obj/item/weapon/money))
|
||||
user_id.money += I:worth
|
||||
del I
|
||||
|
||||
@@ -29,7 +29,7 @@ log transactions
|
||||
if(istype(user, /mob/living/silicon))
|
||||
user << "\red Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per NanoTrasen regulation #1005."
|
||||
return
|
||||
|
||||
|
||||
var/obj/item/weapon/card/id/user_id = src.scan_user(user)
|
||||
if(..())
|
||||
return
|
||||
@@ -51,21 +51,21 @@ log transactions
|
||||
//hueg switch for giving moneh out
|
||||
switch(amount)
|
||||
if(1)
|
||||
new /obj/item/weapon/spacecash(loc)
|
||||
new /obj/item/weapon/money(loc)
|
||||
if(10)
|
||||
new /obj/item/weapon/spacecash/c10(loc)
|
||||
new /obj/item/weapon/money/c10(loc)
|
||||
if(20)
|
||||
new /obj/item/weapon/spacecash/c20(loc)
|
||||
new /obj/item/weapon/money/c20(loc)
|
||||
if(50)
|
||||
new /obj/item/weapon/spacecash/c50(loc)
|
||||
new /obj/item/weapon/money/c50(loc)
|
||||
if(100)
|
||||
new /obj/item/weapon/spacecash/c100(loc)
|
||||
new /obj/item/weapon/money/c100(loc)
|
||||
if(200)
|
||||
new /obj/item/weapon/spacecash/c200(loc)
|
||||
new /obj/item/weapon/money/c200(loc)
|
||||
if(500)
|
||||
new /obj/item/weapon/spacecash/c500(loc)
|
||||
new /obj/item/weapon/money/c500(loc)
|
||||
if(1000)
|
||||
new /obj/item/weapon/spacecash/c1000(loc)
|
||||
new /obj/item/weapon/money/c1000(loc)
|
||||
else
|
||||
usr << browse("You don't have that much money!<br/><a href=\"?src=\ref[src]\">Back</a>","window=atm")
|
||||
return
|
||||
|
||||
@@ -7,27 +7,59 @@
|
||||
if("help")
|
||||
usr.a_intent = "disarm"
|
||||
usr.hud_used.action_intent.icon_state = "disarm"
|
||||
usr.hud_used.hurt_intent.icon_state = "harm_small"
|
||||
usr.hud_used.help_intent.icon_state = "help_small"
|
||||
usr.hud_used.grab_intent.icon_state = "grab_small"
|
||||
usr.hud_used.disarm_intent.icon_state = "disarm_small_active"
|
||||
if("disarm")
|
||||
usr.a_intent = "hurt"
|
||||
usr.hud_used.action_intent.icon_state = "harm"
|
||||
usr.hud_used.hurt_intent.icon_state = "harm_small_active"
|
||||
usr.hud_used.help_intent.icon_state = "help_small"
|
||||
usr.hud_used.grab_intent.icon_state = "grab_small"
|
||||
usr.hud_used.disarm_intent.icon_state = "disarm_small"
|
||||
if("hurt")
|
||||
usr.a_intent = "grab"
|
||||
usr.hud_used.action_intent.icon_state = "grab"
|
||||
usr.hud_used.hurt_intent.icon_state = "harm_small"
|
||||
usr.hud_used.help_intent.icon_state = "help_small"
|
||||
usr.hud_used.grab_intent.icon_state = "grab_small_active"
|
||||
usr.hud_used.disarm_intent.icon_state = "disarm_small"
|
||||
if("grab")
|
||||
usr.a_intent = "help"
|
||||
usr.hud_used.action_intent.icon_state = "help"
|
||||
usr.hud_used.hurt_intent.icon_state = "harm_small"
|
||||
usr.hud_used.help_intent.icon_state = "help_small_active"
|
||||
usr.hud_used.grab_intent.icon_state = "grab_small"
|
||||
usr.hud_used.disarm_intent.icon_state = "disarm_small"
|
||||
else if(changeto == -1)
|
||||
switch(usr.a_intent)
|
||||
if("help")
|
||||
usr.a_intent = "grab"
|
||||
usr.hud_used.action_intent.icon_state = "grab"
|
||||
usr.hud_used.hurt_intent.icon_state = "harm_small"
|
||||
usr.hud_used.help_intent.icon_state = "help_small"
|
||||
usr.hud_used.grab_intent.icon_state = "grab_small_active"
|
||||
usr.hud_used.disarm_intent.icon_state = "disarm_small"
|
||||
if("disarm")
|
||||
usr.a_intent = "help"
|
||||
usr.hud_used.action_intent.icon_state = "help"
|
||||
usr.hud_used.hurt_intent.icon_state = "harm_small"
|
||||
usr.hud_used.help_intent.icon_state = "help_small_active"
|
||||
usr.hud_used.grab_intent.icon_state = "grab_small"
|
||||
usr.hud_used.disarm_intent.icon_state = "disarm_small"
|
||||
if("hurt")
|
||||
usr.a_intent = "disarm"
|
||||
usr.hud_used.action_intent.icon_state = "disarm"
|
||||
usr.hud_used.hurt_intent.icon_state = "harm_small"
|
||||
usr.hud_used.help_intent.icon_state = "help_small"
|
||||
usr.hud_used.grab_intent.icon_state = "grab_small"
|
||||
usr.hud_used.disarm_intent.icon_state = "disarm_small_active"
|
||||
if("grab")
|
||||
usr.a_intent = "hurt"
|
||||
usr.hud_used.action_intent.icon_state = "harm"
|
||||
usr.hud_used.hurt_intent.icon_state = "harm_small_active"
|
||||
usr.hud_used.help_intent.icon_state = "help_small"
|
||||
usr.hud_used.grab_intent.icon_state = "grab_small"
|
||||
usr.hud_used.disarm_intent.icon_state = "disarm_small"
|
||||
return
|
||||
@@ -175,9 +175,9 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
if(text2num(href_list["cost"]) > uses) // Not enough crystals for the item
|
||||
return 0
|
||||
|
||||
//if(usr:mind && ticker.mode.traitors[usr:mind])
|
||||
//var/datum/traitorinfo/info = ticker.mode.traitors[usr:mind]
|
||||
//info.spawnlist += href_list["buy_item"]
|
||||
if(usr:mind && ticker.mode.traitors[usr:mind])
|
||||
var/datum/traitorinfo/info = ticker.mode.traitors[usr:mind]
|
||||
info.spawnlist += href_list["buy_item"]
|
||||
|
||||
uses -= text2num(href_list["cost"])
|
||||
|
||||
@@ -268,7 +268,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
else
|
||||
item:loc = get_turf(A)
|
||||
usr.update_clothing()
|
||||
// usr.client.onBought("[item:name]") When we have the stats again, uncomment.
|
||||
usr.client.onBought("[item:name]")
|
||||
/* if(istype(item, /obj/spawner)) // Spawners need to have del called on them to avoid leaving a marker behind
|
||||
del item*/
|
||||
//HEADFINDBACK
|
||||
@@ -371,7 +371,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
item:loc = get_turf(A)
|
||||
/* if(istype(item, /obj/spawner)) // Spawners need to have del called on them to avoid leaving a marker behind
|
||||
del item*/
|
||||
// usr.client.onBought("[item:name]") When we have the stats again, uncomment.
|
||||
usr.client.onBought("[item:name]")
|
||||
src.attack_self(usr)
|
||||
return
|
||||
|
||||
|
||||
@@ -49,11 +49,19 @@
|
||||
end = get_turf(locate(end.x+d,end.y,end.z))
|
||||
dir = "h"
|
||||
|
||||
while (cur!=end)
|
||||
var/can_place = 1
|
||||
while (cur!=end && can_place)
|
||||
if(cur.density == 1)
|
||||
usr << "\blue You can't run [src] through a wall!"
|
||||
return
|
||||
can_place = 0
|
||||
else
|
||||
for(var/obj/O in cur)
|
||||
if(O.density)
|
||||
can_place = 0
|
||||
break
|
||||
cur = get_step_towards(cur,end)
|
||||
if (!can_place)
|
||||
usr << "\blue You can't run \the [src] through that!"
|
||||
return
|
||||
|
||||
cur = start
|
||||
var/tapetest = 0
|
||||
|
||||
@@ -1,48 +1,65 @@
|
||||
//This looks to be the traitor win tracker code. Gonna comment it out as we lack it currently.
|
||||
/*
|
||||
//This looks to be the traitor win tracker code.
|
||||
client/proc/add_roundsjoined()
|
||||
if(!makejson)
|
||||
return
|
||||
var/DBConnection/dbcon = new()
|
||||
|
||||
dbcon.Connect("dbi:mysql:[sqldb]:[sqladdress]:[sqlport]","[sqllogin]","[sqlpass]")
|
||||
if(!dbcon.IsConnected()) return
|
||||
|
||||
var/DBQuery/cquery = dbcon.NewQuery("INSERT INTO `roundsjoined` (`ckey`) VALUES ('[ckey(src.key)]')")
|
||||
if(!cquery.Execute()) message_admins(cquery.ErrorMsg())
|
||||
|
||||
client/proc/add_roundssurvived()
|
||||
if(!makejson)
|
||||
return
|
||||
var/DBConnection/dbcon = new()
|
||||
|
||||
dbcon.Connect("dbi:mysql:[sqldb]:[sqladdress]:[sqlport]","[sqllogin]","[sqlpass]")
|
||||
if(!dbcon.IsConnected()) return
|
||||
|
||||
var/DBQuery/cquery = dbcon.NewQuery("INSERT INTO `roundsurvived` (`ckey`) VALUES ('[ckey(src.key)]')")
|
||||
if(!cquery.Execute()) message_admins(cquery.ErrorMsg())
|
||||
client/proc/onDeath(var/mob/A = src.mob)
|
||||
|
||||
client/proc/onDeath()
|
||||
if(!makejson)
|
||||
return
|
||||
roundinfo.deaths++
|
||||
if(!ismob(A))
|
||||
if(!ismob(mob))
|
||||
return
|
||||
var/ckey = src.ckey
|
||||
var/area
|
||||
var/area = get_area(mob)
|
||||
var/attacker
|
||||
var/tod = time2text(world.realtime)
|
||||
var/health
|
||||
var/last
|
||||
if(isturf(A.loc))
|
||||
area = A.loc:loc:name
|
||||
else
|
||||
area = A.loc:name
|
||||
if(ishuman(A.lastattacker))
|
||||
attacker = A.lastattacker:name
|
||||
if(ishuman(mob.lastattacker))
|
||||
attacker = mob.lastattacker:name
|
||||
else
|
||||
attacker = "None"
|
||||
health = "Oxy:[A.oxyloss]Brute:[A.bruteloss]Burn:[A.fireloss]Toxins:[A.toxloss]"
|
||||
if(A.logs.len >= 1)
|
||||
last = A.logs[A.logs.len]
|
||||
health = "Oxy:[mob.oxyloss]Brute:[mob.bruteloss]Burn:[mob.fireloss]Toxins:[mob.toxloss]Brain:[mob.brainloss]"
|
||||
if(mob.attack_log.len >= 1)
|
||||
last = mob.attack_log[mob.attack_log.len]
|
||||
else
|
||||
last = "None"
|
||||
|
||||
var/DBConnection/dbcon = new()
|
||||
|
||||
dbcon.Connect("dbi:mysql:[sqldb]:[sqladdress]:[sqlport]","[sqllogin]","[sqlpass]")
|
||||
if(!dbcon.IsConnected()) return
|
||||
|
||||
var/DBQuery/cquery = dbcon.NewQuery("INSERT INTO `deathlog` (`ckey`,`location`,`lastattacker`,`ToD`,`health`,`lasthit`) VALUES ('[ckey]',[dbcon.Quote(area)],[dbcon.Quote(attacker)],'[tod]','[health]',[dbcon.Quote(last)])")
|
||||
if(!cquery.Execute()) message_admins(cquery.ErrorMsg())
|
||||
|
||||
client/proc/onBought(names)
|
||||
if(!makejson) return
|
||||
if(!names) return
|
||||
var/DBConnection/dbcon = new()
|
||||
|
||||
dbcon.Connect("dbi:mysql:[sqldb]:[sqladdress]:[sqlport]","[sqllogin]","[sqlpass]")
|
||||
if(!dbcon.IsConnected()) return
|
||||
|
||||
var/DBQuery/cquery = dbcon.NewQuery("INSERT INTO `traitorbuy` (`type`) VALUES ([dbcon.Quote(names)])")
|
||||
if(!cquery.Execute()) message_admins(cquery.ErrorMsg())
|
||||
*/
|
||||
|
||||
datum/roundinfo
|
||||
var/core = 0
|
||||
@@ -17,13 +17,13 @@ log transactions
|
||||
idle_power_usage = 10
|
||||
var
|
||||
obj/item/weapon/card/id/card
|
||||
obj/item/weapon/spacecash/cashes = list()
|
||||
obj/item/weapon/money/cashes = list()
|
||||
inserted = 0
|
||||
accepted = 0
|
||||
pincode = 0
|
||||
|
||||
attackby(var/obj/A, var/mob/user)
|
||||
if(istype(A,/obj/item/weapon/spacecash))
|
||||
if(istype(A,/obj/item/weapon/money))
|
||||
cashes += A
|
||||
user.drop_item()
|
||||
A.loc = src
|
||||
@@ -100,21 +100,21 @@ log transactions
|
||||
card.money -= amount
|
||||
switch(amount)
|
||||
if(1)
|
||||
new /obj/item/weapon/spacecash(loc)
|
||||
new /obj/item/weapon/money(loc)
|
||||
if(10)
|
||||
new /obj/item/weapon/spacecash/c10(loc)
|
||||
new /obj/item/weapon/money/c10(loc)
|
||||
if(20)
|
||||
new /obj/item/weapon/spacecash/c20(loc)
|
||||
new /obj/item/weapon/money/c20(loc)
|
||||
if(50)
|
||||
new /obj/item/weapon/spacecash/c50(loc)
|
||||
new /obj/item/weapon/money/c50(loc)
|
||||
if(100)
|
||||
new /obj/item/weapon/spacecash/c100(loc)
|
||||
new /obj/item/weapon/money/c100(loc)
|
||||
if(200)
|
||||
new /obj/item/weapon/spacecash/c200(loc)
|
||||
new /obj/item/weapon/money/c200(loc)
|
||||
if(500)
|
||||
new /obj/item/weapon/spacecash/c500(loc)
|
||||
new /obj/item/weapon/money/c500(loc)
|
||||
if(1000)
|
||||
new /obj/item/weapon/spacecash/c1000(loc)
|
||||
new /obj/item/weapon/money/c1000(loc)
|
||||
else
|
||||
user << "\red Error: Insufficient funds."
|
||||
return
|
||||
@@ -143,7 +143,7 @@ log transactions
|
||||
if (usr.machine==src && get_dist(src, usr) <= 1 || istype(usr, /mob/living/silicon/ai))
|
||||
if(href_list["eca"])
|
||||
if(accepted)
|
||||
for(var/obj/item/weapon/spacecash/M in cashes)
|
||||
for(var/obj/item/weapon/money/M in cashes)
|
||||
M.loc = loc
|
||||
inserted = 0
|
||||
if(!cashes)
|
||||
@@ -154,6 +154,8 @@ log transactions
|
||||
if(accepted)
|
||||
card.money += inserted
|
||||
inserted = 0
|
||||
if(cashes)
|
||||
cashes = null
|
||||
if(href_list["lock"])
|
||||
card = null
|
||||
accepted = 0
|
||||
|
||||
+192
-121
@@ -47,10 +47,6 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
return
|
||||
if(!disease)
|
||||
return
|
||||
//immunity
|
||||
/*for(var/iii = 1, iii <= M.immunevirus2.len, iii++)
|
||||
if(disease.issame(M.immunevirus2[iii]))
|
||||
return*/
|
||||
|
||||
// if one of the antibodies in the mob's body matches one of the disease's antigens, don't infect
|
||||
if(M.antibodies & disease.antigen != 0) return
|
||||
@@ -266,7 +262,6 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
|
||||
|
||||
proc/getcopy()
|
||||
// world << "getting copy"
|
||||
var/datum/disease2/disease/disease = new /datum/disease2/disease
|
||||
disease.infectionchance = infectionchance
|
||||
disease.spreadtype = spreadtype
|
||||
@@ -274,7 +269,6 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
disease.antigen = antigen
|
||||
disease.uniqueID = uniqueID
|
||||
for(var/datum/disease2/effectholder/holder in effects)
|
||||
// world << "adding effects"
|
||||
var/datum/disease2/effectholder/newholder = new /datum/disease2/effectholder
|
||||
newholder.effect = new holder.effect.type
|
||||
newholder.chance = holder.chance
|
||||
@@ -283,8 +277,6 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
newholder.happensonce = holder.happensonce
|
||||
newholder.stage = holder.stage
|
||||
disease.effects += newholder
|
||||
// world << "[newholder.effect.name]"
|
||||
// world << "[disease]"
|
||||
return disease
|
||||
|
||||
proc/spread_airborne(var/mob/living/carbon/mob)
|
||||
@@ -298,9 +290,17 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
var/name = "Blanking effect"
|
||||
var/stage = 4
|
||||
var/maxm = 1
|
||||
var/happensalways = 0
|
||||
proc/activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
proc/deactivate(var/mob/living/carbon/mob)
|
||||
|
||||
// ================================
|
||||
// ======= DISEASE SYMPTOMS =======
|
||||
// ================================
|
||||
|
||||
// Special diseases
|
||||
// --------------------------------
|
||||
|
||||
/datum/disease2/effect/alien
|
||||
name = "Unidentified Foreign Body"
|
||||
stage = 4
|
||||
@@ -317,11 +317,68 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
mob:gib()
|
||||
del D
|
||||
|
||||
/datum/disease2/effect/greater/gibbingtons
|
||||
name = "Gibbingtons Syndrome"
|
||||
stage = 4
|
||||
// Greater Diseases, Stage 1
|
||||
// --------------------------------
|
||||
|
||||
|
||||
/datum/disease2/effect/greater/gunck
|
||||
name = "Flemmingtons"
|
||||
stage = 1
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.gib()
|
||||
mob << "\red Mucous runs down the back of your throat."
|
||||
|
||||
|
||||
// Greater Diseases, Stage 2
|
||||
// --------------------------------
|
||||
|
||||
/datum/disease2/effect/greater/cough
|
||||
name = "Anima Syndrome"
|
||||
stage = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*cough")
|
||||
if(mob.virus2) mob.virus2.spread_airborne(mob)
|
||||
if(mob.virus2) mob.virus2.spread_airborne(mob)
|
||||
if(prob(2))
|
||||
var/obj/effect/decal/cleanable/mucus/this = new(mob.loc)
|
||||
this.virus2 = mob.virus2
|
||||
|
||||
/datum/disease2/effect/greater/vomit
|
||||
name = "Bad Stomach Syndrome"
|
||||
stage = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
if(prob(20) && mob.nutrition > 200)
|
||||
mob.vomit()
|
||||
|
||||
|
||||
/datum/disease2/effect/greater/sneeze
|
||||
name = "Coldingtons Effect"
|
||||
stage = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*sneeze")
|
||||
if(mob.virus2) mob.virus2.spread_airborne(mob)
|
||||
if(mob.virus2) mob.virus2.spread_airborne(mob)
|
||||
if(prob(5))
|
||||
var/obj/effect/decal/cleanable/mucus/this = new(mob.loc)
|
||||
this.anchored = 0
|
||||
step(this, mob.dir)
|
||||
this.anchored = 1
|
||||
this.virus2 = mob.virus2
|
||||
|
||||
// Greater Diseases, Stage 3
|
||||
// --------------------------------
|
||||
|
||||
/datum/disease2/effect/greater/sleepy
|
||||
name = "Resting syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*collapse")
|
||||
|
||||
/datum/disease2/effect/greater/mind
|
||||
name = "Lazy mind syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.setBrainLoss(50)
|
||||
|
||||
|
||||
/datum/disease2/effect/greater/hallucinations
|
||||
name = "Hallucinational Syndrome"
|
||||
@@ -329,12 +386,6 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.hallucination += 25
|
||||
|
||||
/datum/disease2/effect/greater/radian
|
||||
name = "Radian's syndrome"
|
||||
stage = 4
|
||||
maxm = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.radiation += (20*multiplier)
|
||||
|
||||
/datum/disease2/effect/greater/toxins
|
||||
name = "Hyperacid Syndrome"
|
||||
@@ -356,6 +407,38 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
shake_camera(mob,5*multiplier)
|
||||
|
||||
|
||||
/datum/disease2/effect/greater/telepathic
|
||||
name = "Telepathy Syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.mutations |= 512
|
||||
|
||||
// Greater Diseases, Stage 4
|
||||
// --------------------------------
|
||||
|
||||
/datum/disease2/effect/greater/gibbingtons
|
||||
name = "Gibbingtons Syndrome"
|
||||
stage = 4
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.gib()
|
||||
|
||||
|
||||
/datum/disease2/effect/greater/blood_fountain
|
||||
name = "Blood Fountain Syndrome"
|
||||
stage = 4
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
if(prob(20))
|
||||
mob.visible_message("\red You see a fountain of blood erupt from [mob.name].","\red <b>Something wet is leaking from you.</b>","You hear a loud splash.")
|
||||
mob.drip(50)
|
||||
|
||||
/datum/disease2/effect/greater/radian
|
||||
name = "Radian's syndrome"
|
||||
stage = 4
|
||||
maxm = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.radiation += (20*multiplier)
|
||||
|
||||
/datum/disease2/effect/greater/fever
|
||||
name = "Fever syndrome"
|
||||
stage = 4
|
||||
@@ -363,6 +446,7 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.adjustFireLoss(10 * multiplier)
|
||||
|
||||
|
||||
/datum/disease2/effect/greater/weak_bones
|
||||
name = "Bone Density Syndrome"
|
||||
stage = 4
|
||||
@@ -371,7 +455,7 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
var/name = pick(mob.organs)
|
||||
var/datum/organ/external/organ = mob.organs[name]
|
||||
|
||||
if(!organ.broken)
|
||||
if(!organ.broken && !organ.robot)
|
||||
mob.adjustBruteLoss(10)
|
||||
mob.visible_message("\red You hear a loud cracking sound coming from [mob.name].","\red <b>Something feels like it shattered in your [organ.display_name]!</b>","You hear a sickening crack.")
|
||||
mob.emote("scream")
|
||||
@@ -379,17 +463,6 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
organ.wound = pick("broken","fracture","hairline fracture") //Randomise in future. Edit: Randomized. --SkyMarshal
|
||||
organ.perma_injury = 10
|
||||
|
||||
/datum/disease2/effect/invisible
|
||||
name = "Waiting Syndrome"
|
||||
stage = 1
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
return
|
||||
|
||||
/datum/disease2/effect/greater/telepathic
|
||||
name = "Telepathy Syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.mutations |= 512
|
||||
|
||||
/datum/disease2/effect/greater/monkey
|
||||
name = "Monkism syndrome"
|
||||
@@ -399,37 +472,6 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
var/mob/living/carbon/human/h = mob
|
||||
h.monkeyize()
|
||||
|
||||
/datum/disease2/effect/greater/sneeze
|
||||
name = "Coldingtons Effect"
|
||||
stage = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*sneeze")
|
||||
if(mob.virus2) mob.virus2.spread_airborne(mob)
|
||||
if(mob.virus2) mob.virus2.spread_airborne(mob)
|
||||
if(prob(5))
|
||||
var/obj/effect/decal/cleanable/mucus/this = new(mob.loc)
|
||||
this.anchored = 0
|
||||
step(this, mob.dir)
|
||||
this.anchored = 1
|
||||
this.virus2 = mob.virus2
|
||||
|
||||
|
||||
/datum/disease2/effect/greater/cough
|
||||
name = "Anima Syndrome"
|
||||
stage = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*cough")
|
||||
if(mob.virus2) mob.virus2.spread_airborne(mob)
|
||||
if(mob.virus2) mob.virus2.spread_airborne(mob)
|
||||
if(prob(2))
|
||||
var/obj/effect/decal/cleanable/mucus/this = new(mob.loc)
|
||||
this.virus2 = mob.virus2
|
||||
|
||||
/datum/disease2/effect/greater/gunck
|
||||
name = "Flemmingtons"
|
||||
stage = 1
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob << "\red Mucous runs down the back of your throat."
|
||||
|
||||
/datum/disease2/effect/greater/killertoxins
|
||||
name = "Toxification syndrome"
|
||||
@@ -437,36 +479,9 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.adjustToxLoss(15)
|
||||
|
||||
/datum/disease2/effect/greater/sleepy
|
||||
name = "Resting syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*collapse")
|
||||
|
||||
/datum/disease2/effect/greater/mind
|
||||
name = "Lazy mind syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.setBrainLoss(50)
|
||||
|
||||
// lesser syndromes, partly just copypastes
|
||||
/datum/disease2/effect/lesser/hallucinations
|
||||
name = "Hallucinational Syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.hallucination += 5
|
||||
|
||||
/datum/disease2/effect/lesser/mind
|
||||
name = "Lazy mind syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.setBrainLoss(20)
|
||||
|
||||
/datum/disease2/effect/lesser/deaf
|
||||
name = "Hard of hearing syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.ear_deaf = 5
|
||||
// Lesser Diseases, Stage 1
|
||||
// --------------------------------
|
||||
|
||||
/datum/disease2/effect/lesser/gunck
|
||||
name = "Flemmingtons"
|
||||
@@ -474,13 +489,30 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob << "\red Mucous runs down the back of your throat."
|
||||
|
||||
/datum/disease2/effect/lesser/radian
|
||||
name = "Radian's syndrome"
|
||||
stage = 4
|
||||
maxm = 3
|
||||
/datum/disease2/effect/lesser/fridge
|
||||
name = "Refridgerator Syndrome"
|
||||
stage = 1
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.radiation += 1
|
||||
if(prob(10)) mob << "\blue You feel extremely cold."
|
||||
|
||||
|
||||
/datum/disease2/effect/lesser/pale
|
||||
name = "Ghost Effect"
|
||||
stage = 1
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob << "\blue If you had a mirror, your reflection would probably look very pale.."
|
||||
|
||||
/datum/disease2/effect/lesser/hoarse
|
||||
name = "Hoarse Throat"
|
||||
stage = 1
|
||||
happensalways = 1 // the mob will have a permanently sore throat
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.disease_symptoms |= DISEASE_HOARSE
|
||||
if(prob(3)) mob << "\blue Your throat feels very sore.."
|
||||
|
||||
|
||||
// Lesser Diseases, Stage 2
|
||||
// --------------------------------
|
||||
/datum/disease2/effect/lesser/sneeze
|
||||
name = "Coldingtons Effect"
|
||||
stage = 2
|
||||
@@ -506,19 +538,49 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
var/obj/effect/decal/cleanable/mucus/this = new(mob.loc)
|
||||
this.virus2 = mob.virus2
|
||||
|
||||
/*/datum/disease2/effect/lesser/arm
|
||||
name = "Disarming Syndrome"
|
||||
stage = 4
|
||||
|
||||
/datum/disease2/effect/lesser/nosebleed
|
||||
name = "Nosebleed Effect"
|
||||
stage = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
var/datum/organ/external/org = mob.organs["r_arm"]
|
||||
org.take_damage(3,0,0,0)
|
||||
mob << "\red You feel a sting in your right arm."*/
|
||||
if(prob(30))
|
||||
mob.drip(1)
|
||||
|
||||
// Lesser Diseases, Stage 3
|
||||
// --------------------------------
|
||||
|
||||
/datum/disease2/effect/lesser/vomit
|
||||
name = "Bad Stomach Syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
if(prob(5) && mob.nutrition > 200)
|
||||
mob.vomit()
|
||||
|
||||
|
||||
// lesser syndromes, partly just copypastes
|
||||
/datum/disease2/effect/lesser/hallucinations
|
||||
name = "Hallucinational Syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.hallucination += 5
|
||||
|
||||
/datum/disease2/effect/lesser/mind
|
||||
name = "Lazy mind syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.setBrainLoss(20)
|
||||
|
||||
/datum/disease2/effect/lesser/deaf
|
||||
name = "Hard of hearing syndrome"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.ear_deaf = 5
|
||||
|
||||
/datum/disease2/effect/lesser/hungry
|
||||
name = "Appetiser Effect"
|
||||
stage = 3
|
||||
stage = 2
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.nutrition = max(0, mob.nutrition - 3)
|
||||
mob.nutrition = max(0, mob.nutrition - 1)
|
||||
|
||||
/datum/disease2/effect/lesser/groan
|
||||
name = "Groaning Syndrome"
|
||||
@@ -526,24 +588,12 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*groan")
|
||||
|
||||
/datum/disease2/effect/lesser/fridge
|
||||
name = "Refridgerator Syndrome"
|
||||
stage = 1
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*shiver")
|
||||
|
||||
/datum/disease2/effect/lesser/twitch
|
||||
name = "Twitcher"
|
||||
stage = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.say("*twitch")
|
||||
|
||||
/datum/disease2/effect/lesser/pale
|
||||
name = "Ghost Effect"
|
||||
stage = 1
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
if(prob(10))
|
||||
mob.emote("me",1,"looks very pale.")
|
||||
if(prob(5)) mob.say("*twitch")
|
||||
if(prob(20)) mob << "\blue Your muscles feel twitchy.."
|
||||
|
||||
/datum/disease2/effect/lesser/stumble
|
||||
name = "Poor Balance Syndrome"
|
||||
@@ -556,11 +606,32 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
step(mob, pick(cardinal))
|
||||
mob.emote("me",1,"stumbles over their own feet.")
|
||||
|
||||
/datum/disease2/effect/lesser/hoarse
|
||||
name = "Hoarse Throat"
|
||||
|
||||
// Lesser Diseases, Stage 4
|
||||
// --------------------------------
|
||||
|
||||
|
||||
/datum/disease2/effect/lesser/radian
|
||||
name = "Radian's syndrome"
|
||||
stage = 4
|
||||
maxm = 3
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.radiation += 1
|
||||
|
||||
// ============
|
||||
// END SYMPTOMS
|
||||
// ============
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/disease2/effect/invisible
|
||||
name = "Waiting Syndrome"
|
||||
stage = 1
|
||||
activate(var/mob/living/carbon/mob,var/multiplier)
|
||||
mob.disease_symptoms |= DISEASE_HOARSE
|
||||
return
|
||||
|
||||
|
||||
var/global/const/DISEASE_HOARSE = 2
|
||||
var/global/const/DISEASE_WHISPER = 4
|
||||
@@ -579,7 +650,7 @@ var/global/const/DISEASE_WHISPER = 4
|
||||
var/stage = 0
|
||||
|
||||
proc/runeffect(var/mob/living/carbon/human/mob,var/stage)
|
||||
if(happensonce > -1 && effect.stage <= stage && prob(chance))
|
||||
if(effect.stage <= stage) if(effect.happensalways || (happensonce > -1 && prob(chance)))
|
||||
effect.activate(mob)
|
||||
if(happensonce == 1)
|
||||
happensonce = -1
|
||||
|
||||
Reference in New Issue
Block a user