From 6764c54989c3e052a70135b357aabab8978be4c0 Mon Sep 17 00:00:00 2001 From: jack-fractal Date: Sat, 26 Oct 2013 16:52:14 -0400 Subject: [PATCH 01/18] making a generic version of the AI's visibility code so that it can be reused by the Cult Spirits --- baystation12.dme | 10 +- .../AI_Visibility/_old_AI_Visibility.dm | 68 +++---- code/WorkInProgress/AI_Visibility/ai.dm | 10 +- .../WorkInProgress/AI_Visibility/cameranet.dm | 24 +-- code/WorkInProgress/AI_Visibility/chunk.dm | 2 +- code/WorkInProgress/AI_Visibility/minimap.dm | 24 +-- code/WorkInProgress/AI_Visibility/util.dm | 14 +- code/controllers/verbs.dm | 2 +- code/datums/visibility_networks/chunk.dm | 179 ++++++++++++++++++ code/datums/visibility_networks/dictionary.dm | 7 + .../visibility_interface.dm | 46 +++++ .../visibility_networks/visibility_network.dm | 135 +++++++++++++ code/defines/obj/weapon.dm | 3 +- .../gamemodes/malfunction/Malf_Modules.dm | 6 +- code/game/machinery/camera/camera.dm | 8 +- code/game/machinery/camera/camera_assembly.dm | 2 +- code/game/machinery/camera/tracking.dm | 6 +- code/game/machinery/computer/camera.dm | 2 +- code/modules/admin/verbs/mapping.dm | 4 +- code/modules/clothing/spacesuits/ert.dm | 2 +- code/modules/clothing/spacesuits/rig.dm | 2 +- code/modules/mob/living/silicon/ai/ai.dm | 6 +- .../living/silicon/ai/freelook/cameranet.dm | 20 ++ .../mob/living/silicon/ai/freelook/chunk.dm | 30 ++- .../mob/living/silicon/ai/freelook/eye.dm | 10 +- .../mob/living/silicon/ai/freelook/read_me.dm | 2 +- .../silicon/ai/freelook/update_triggers.dm | 29 +-- .../ai/freelook/visibility_interface.dm | 10 + .../modules/mob/living/silicon/robot/robot.dm | 2 +- code/modules/mob/mob_defines.dm | 1 + code/modules/mob/mob_helpers.dm | 5 + code/modules/mob/mob_movement.dm | 3 +- code/modules/mob/spirit/cultnet.dm | 8 + code/modules/mob/spirit/movement.dm | 40 ++++ code/modules/mob/spirit/spirit.dm | 42 ++++ code/setup.dm | 3 + code/unused/AI_Visibility.dm | 30 +-- 37 files changed, 668 insertions(+), 129 deletions(-) create mode 100644 code/datums/visibility_networks/chunk.dm create mode 100644 code/datums/visibility_networks/dictionary.dm create mode 100644 code/datums/visibility_networks/visibility_interface.dm create mode 100644 code/datums/visibility_networks/visibility_network.dm create mode 100644 code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm create mode 100644 code/modules/mob/spirit/cultnet.dm create mode 100644 code/modules/mob/spirit/movement.dm create mode 100644 code/modules/mob/spirit/spirit.dm diff --git a/baystation12.dme b/baystation12.dme index 2a699386a9..74dea3f7ff 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -153,6 +153,10 @@ #include "code\datums\spells\trigger.dm" #include "code\datums\spells\turf_teleport.dm" #include "code\datums\spells\wizard.dm" +#include "code\datums\visibility_networks\chunk.dm" +#include "code\datums\visibility_networks\dictionary.dm" +#include "code\datums\visibility_networks\visibility_interface.dm" +#include "code\datums\visibility_networks\visibility_network.dm" #include "code\defines\obj.dm" #include "code\defines\obj\hydro.dm" #include "code\defines\obj\weapon.dm" @@ -950,6 +954,7 @@ #include "code\modules\mob\living\silicon\ai\freelook\eye.dm" #include "code\modules\mob\living\silicon\ai\freelook\read_me.dm" #include "code\modules\mob\living\silicon\ai\freelook\update_triggers.dm" +#include "code\modules\mob\living\silicon\ai\freelook\visibility_interface.dm" #include "code\modules\mob\living\silicon\decoy\death.dm" #include "code\modules\mob\living\silicon\decoy\decoy.dm" #include "code\modules\mob\living\silicon\decoy\life.dm" @@ -1018,6 +1023,9 @@ #include "code\modules\mob\new_player\preferences_setup.dm" #include "code\modules\mob\new_player\skill.dm" #include "code\modules\mob\new_player\sprite_accessories.dm" +#include "code\modules\mob\spirit\cultnet.dm" +#include "code\modules\mob\spirit\movement.dm" +#include "code\modules\mob\spirit\spirit.dm" #include "code\modules\nano\_JSON.dm" #include "code\modules\nano\JSON Reader.dm" #include "code\modules\nano\JSON Writer.dm" @@ -1291,7 +1299,6 @@ #include "code\WorkInProgress\Cael_Aislinn\ShieldGen\shield_gen.dm" #include "code\WorkInProgress\Cael_Aislinn\ShieldGen\shield_gen_external.dm" #include "code\WorkInProgress\Cael_Aislinn\Supermatter\LaserComputer.dm" -#include "code\WorkInProgress\Cael_Aislinn\Supermatter\SuperMatter.dm" #include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm" #include "code\WorkInProgress\Chinsky\ashtray.dm" #include "code\WorkInProgress\Cib\MedicalSideEffects.dm" @@ -1300,6 +1307,7 @@ #include "code\WorkInProgress\Ported\policetape.dm" #include "code\WorkInProgress\SkyMarshal\officer_stuff.dm" #include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm" +#include "code\WorkInProgress\Yinadele\Supermatter.dm" #include "code\ZAS\Airflow.dm" #include "code\ZAS\Connection.dm" #include "code\ZAS\Debug.dm" diff --git a/code/WorkInProgress/AI_Visibility/_old_AI_Visibility.dm b/code/WorkInProgress/AI_Visibility/_old_AI_Visibility.dm index 9b50c74f68..831d20f229 100644 --- a/code/WorkInProgress/AI_Visibility/_old_AI_Visibility.dm +++ b/code/WorkInProgress/AI_Visibility/_old_AI_Visibility.dm @@ -16,15 +16,15 @@ var/image/dim /turf/proc/visibilityChanged() - cameranet.updateVisibility(src) + cameraNetwork.updateVisibility(src) /turf/New() ..() - cameranet.updateVisibility(src) + cameraNetwork.updateVisibility(src) /* /turf/Del() ..() - cameranet.updateVisibility(src) + cameraNetwork.updateVisibility(src) */ /datum/camerachunk var/list/obscuredTurfs = list() @@ -73,7 +73,7 @@ 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) + cameraNetwork.visibility(ai.eyeobj) else usr.loc = locate(max(1, x - 1), max(1, y - 1), usr.z) @@ -81,26 +81,26 @@ /mob/dead/verb/Open_Minimap() set category = "Ghost" winshow(src, "minimapwindow", 1) - client.screen |= cameranet.minimap + client.screen |= cameraNetwork.minimap - if(cameranet.generating_minimap) - cameranet.minimap_viewers += src + if(cameraNetwork.generating_minimap) + cameraNetwork.minimap_viewers += src /mob/living/silicon/ai/verb/Open_Minimap() set category = "AI Commands" winshow(src, "minimapwindow", 1) - client.screen |= cameranet.minimap + client.screen |= cameraNetwork.minimap - if(cameranet.generating_minimap) - cameranet.minimap_viewers += src + if(cameraNetwork.generating_minimap) + cameraNetwork.minimap_viewers += src /client/proc/Open_Minimap() set category = "Admin" winshow(src, "minimapwindow", 1) - screen |= cameranet.minimap + screen |= cameraNetwork.minimap - if(cameranet.generating_minimap) - cameranet.minimap_viewers += src.mob + if(cameraNetwork.generating_minimap) + cameraNetwork.minimap_viewers += src.mob /datum/camerachunk/proc/update_minimap() if(changed && !updating) @@ -325,11 +325,11 @@ dim += t.dim - cameranet.minimap += minimap_obj + cameraNetwork.minimap += minimap_obj -var/datum/cameranet/cameranet = new() +var/datum/cameraNetwork/cameraNetwork = new() -/datum/cameranet +/datum/cameraNetwork var/list/cameras = list() var/list/chunks = list() var/network = "net1" @@ -340,7 +340,7 @@ var/datum/cameranet/cameranet = new() var/generating_minimap = TRUE var/list/minimap_viewers = list() -/datum/cameranet/New() +/datum/cameraNetwork/New() ..() spawn(200) @@ -356,11 +356,11 @@ var/datum/cameranet/cameranet = new() generating_minimap = FALSE minimap_viewers = list() -/datum/cameranet/proc/chunkGenerated(x, y, z) +/datum/cameraNetwork/proc/chunkGenerated(x, y, z) var/key = "[x],[y],[z]" return key in chunks -/datum/cameranet/proc/getCameraChunk(x, y, z) +/datum/cameraNetwork/proc/getCameraChunk(x, y, z) var/key = "[x],[y],[z]" if(!(key in chunks)) @@ -368,7 +368,7 @@ var/datum/cameranet/cameranet = new() return chunks[key] -/datum/cameranet/proc/visibility(mob/aiEye/ai) +/datum/cameraNetwork/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 @@ -389,14 +389,14 @@ var/datum/cameranet/cameranet = new() for(var/datum/camerachunk/c in add) c.add(ai) -/datum/cameranet/proc/updateVisibility(turf/loc) +/datum/cameraNetwork/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) +/datum/cameraNetwork/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 @@ -410,7 +410,7 @@ var/datum/cameranet/cameranet = new() chunk.cameras += c chunk.hasChanged() -/datum/cameranet/proc/removeCamera(obj/machinery/camera/c) +/datum/cameraNetwork/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 @@ -452,18 +452,18 @@ var/datum/cameranet/cameranet = new() eyeobj.ai = src client.eye = eyeobj eyeobj.loc = loc - cameranet.visibility(eyeobj) + cameraNetwork.visibility(eyeobj) cameraFollow = null /mob/aiEye/Move() . = ..() if(.) - cameranet.visibility(src) + cameraNetwork.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) + cameraNetwork.visibility(user.eyeobj) else return ..() @@ -477,7 +477,7 @@ var/datum/cameranet/cameranet = new() 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) + cameraNetwork.visibility(user.eyeobj) else return ..() */ @@ -492,23 +492,23 @@ var/datum/cameranet/cameranet = new() /obj/machinery/door/update_nearby_tiles(need_rebuild) . = ..(need_rebuild) - cameranet.updateVisibility(loc) + cameraNetwork.updateVisibility(loc) /obj/machinery/camera/New() ..() - cameranet.addCamera(src) + cameraNetwork.addViewpoint(src) /obj/machinery/camera/Del() - cameranet.removeCamera(src) + cameraNetwork.removeViewpoint(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) + cameraNetwork.addViewpoint(src) else - cameranet.removeCamera(src) + cameraNetwork.removeViewpoint(src) /proc/checkcameravis(atom/A) for(var/obj/machinery/camera/C in view(A,7)) @@ -545,7 +545,7 @@ var/datum/cameranet/cameranet = new() var/obj/machinery/camera/C = D[t] eyeobj.loc = C.loc - cameranet.visibility(eyeobj) + cameraNetwork.visibility(eyeobj) return @@ -570,4 +570,4 @@ var/datum/cameranet/cameranet = new() else eyeobj.loc = locate(src.x, src.y, src.z) - cameranet.visibility(eyeobj) + cameraNetwork.visibility(eyeobj) diff --git a/code/WorkInProgress/AI_Visibility/ai.dm b/code/WorkInProgress/AI_Visibility/ai.dm index 7dcbf54e67..a8c5470036 100644 --- a/code/WorkInProgress/AI_Visibility/ai.dm +++ b/code/WorkInProgress/AI_Visibility/ai.dm @@ -29,17 +29,17 @@ eyeobj.ai = src client.eye = eyeobj eyeobj.loc = loc - cameranet.visibility(eyeobj) + cameraNetwork.visibility(eyeobj) /mob/aiEye/Move() . = ..() if(.) - cameranet.visibility(src) + cameraNetwork.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) + cameraNetwork.visibility(user.eyeobj) else return ..() @@ -79,7 +79,7 @@ var/obj/machinery/camera/C = D[t] eyeobj.loc = C.loc - cameranet.visibility(eyeobj) + cameraNetwork.visibility(eyeobj) return @@ -104,4 +104,4 @@ else eyeobj.loc = locate(src.x, src.y, src.z) - cameranet.visibility(eyeobj) + cameraNetwork.visibility(eyeobj) diff --git a/code/WorkInProgress/AI_Visibility/cameranet.dm b/code/WorkInProgress/AI_Visibility/cameranet.dm index 3b46844e6b..d234142511 100644 --- a/code/WorkInProgress/AI_Visibility/cameranet.dm +++ b/code/WorkInProgress/AI_Visibility/cameranet.dm @@ -1,14 +1,14 @@ //------------------------------------------------------------ // -// The Cameranet +// The cameraNetwork // -// The cameranet is a single global instance of a unique +// The cameraNetwork is a single global instance of a unique // datum, which contains logic for managing the individual // chunks. // //------------------------------------------------------------ -/datum/cameranet +/datum/cameraNetwork var/list/cameras = list() var/list/chunks = list() var/network = "net1" @@ -18,18 +18,18 @@ var/generating_minimap = TRUE -var/datum/cameranet/cameranet = new() +var/datum/cameraNetwork/cameraNetwork = new() -/datum/cameranet/New() +/datum/cameraNetwork/New() ..() spawn(100) init_minimap() -/datum/cameranet/proc/init_minimap() +/datum/cameraNetwork/proc/init_minimap() for(var/x = 0, x <= world.maxx, x += 16) for(var/y = 0, y <= world.maxy, y += 16) sleep(1) @@ -39,12 +39,12 @@ var/datum/cameranet/cameranet = new() generating_minimap = FALSE -/datum/cameranet/proc/chunkGenerated(x, y, z) +/datum/cameraNetwork/proc/chunkGenerated(x, y, z) var/key = "[x],[y],[z]" return key in chunks -/datum/cameranet/proc/getCameraChunk(x, y, z) +/datum/cameraNetwork/proc/getCameraChunk(x, y, z) var/key = "[x],[y],[z]" if(!(key in chunks)) @@ -71,7 +71,7 @@ var/datum/cameranet/cameranet = new() // have a proc called automatically every time an // object's loc changes. -/datum/cameranet/proc/visibility(mob/aiEye/ai) +/datum/cameraNetwork/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 @@ -101,7 +101,7 @@ var/datum/cameranet/cameranet = new() // anything else that would alter line of sight in the // general area. -/datum/cameranet/proc/updateVisibility(turf/loc) +/datum/cameraNetwork/proc/updateVisibility(turf/loc) if(!chunkGenerated(loc.x & ~0xf, loc.y & ~0xf, loc.z)) return @@ -115,7 +115,7 @@ var/datum/cameranet/cameranet = new() // creating a camera, allowing freelook and the minimap to // respond correctly. -/datum/cameranet/proc/addCamera(obj/machinery/camera/c) +/datum/cameraNetwork/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 @@ -137,7 +137,7 @@ var/datum/cameranet/cameranet = new() // deleting a camera, allowing freelook and the minimap to // respond correctly. -/datum/cameranet/proc/removeCamera(obj/machinery/camera/c) +/datum/cameraNetwork/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 diff --git a/code/WorkInProgress/AI_Visibility/chunk.dm b/code/WorkInProgress/AI_Visibility/chunk.dm index 8a6886a1ad..134d6097b5 100644 --- a/code/WorkInProgress/AI_Visibility/chunk.dm +++ b/code/WorkInProgress/AI_Visibility/chunk.dm @@ -88,7 +88,7 @@ dim += t.dim - cameranet.minimap |= minimap_obj + cameraNetwork.minimap |= minimap_obj for(var/mob/aiEye/eye in seenby) if(eye.ai.client) diff --git a/code/WorkInProgress/AI_Visibility/minimap.dm b/code/WorkInProgress/AI_Visibility/minimap.dm index c97b01e0f8..e4d4f7274f 100644 --- a/code/WorkInProgress/AI_Visibility/minimap.dm +++ b/code/WorkInProgress/AI_Visibility/minimap.dm @@ -28,24 +28,24 @@ 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) + cameraNetwork.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) + cameraNetwork.show_minimap(client) /mob/living/silicon/ai/verb/Open_Minimap() set category = "AI Commands" - cameranet.show_minimap(client) + cameraNetwork.show_minimap(client) /client/proc/Open_Minimap() set category = "Admin" - cameranet.show_minimap(src) + cameraNetwork.show_minimap(src) /mob/verb/Open_Minimap_Z() @@ -54,26 +54,26 @@ 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 + var/level = input("Select a Z level", "Z select", null) as null | anything in cameraNetwork.minimap if(level != null) - cameranet.show_minimap(client, level) + cameraNetwork.show_minimap(client, level) -/datum/cameranet/proc/show_minimap(client/client, z_level = "z-1") +/datum/cameraNetwork/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) + if(z_level in cameraNetwork.minimap) winshow(client, "minimapwindow", 1) - for(var/key in cameranet.minimap) - client.screen -= cameranet.minimap[key] + for(var/key in cameraNetwork.minimap) + client.screen -= cameraNetwork.minimap[key] - client.screen |= cameranet.minimap[z_level] + client.screen |= cameraNetwork.minimap[z_level] - if(cameranet.generating_minimap) + if(cameraNetwork.generating_minimap) spawn(50) show_minimap(client, z_level) diff --git a/code/WorkInProgress/AI_Visibility/util.dm b/code/WorkInProgress/AI_Visibility/util.dm index da576cbd40..0e32f8dec8 100644 --- a/code/WorkInProgress/AI_Visibility/util.dm +++ b/code/WorkInProgress/AI_Visibility/util.dm @@ -4,31 +4,31 @@ var/image/dim /turf/proc/visibilityChanged() - cameranet.updateVisibility(src) + cameraNetwork.updateVisibility(src) /turf/New() ..() - cameranet.updateVisibility(src) + cameraNetwork.updateVisibility(src) /obj/machinery/door/update_nearby_tiles(need_rebuild) . = ..(need_rebuild) - cameranet.updateVisibility(loc) + cameraNetwork.updateVisibility(loc) /obj/machinery/camera/New() ..() - cameranet.addCamera(src) + cameraNetwork.addViewpoint(src) /obj/machinery/camera/Del() - cameranet.removeCamera(src) + cameraNetwork.removeViewpoint(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) + cameraNetwork.addViewpoint(src) else - cameranet.removeCamera(src) + cameraNetwork.removeViewpoint(src) /proc/checkcameravis(atom/A) for(var/obj/machinery/camera/C in view(A,7)) diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index d659d2fa68..3b2d9697bf 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -72,7 +72,7 @@ debug_variables(paiController) feedback_add_details("admin_verb","DpAI") if("Cameras") - debug_variables(cameranet) + debug_variables(cameraNetwork) feedback_add_details("admin_verb","DCameras") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") return diff --git a/code/datums/visibility_networks/chunk.dm b/code/datums/visibility_networks/chunk.dm new file mode 100644 index 0000000000..4abc1340b0 --- /dev/null +++ b/code/datums/visibility_networks/chunk.dm @@ -0,0 +1,179 @@ +#define UPDATE_BUFFER 25 // 2.5 seconds + +// CAMERA CHUNK +// +// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. +// Allows the mob using this chunk to stream these chunks and know what it can and cannot see. + +/datum/visibility_chunk + var/obscured_image = 'icons/effects/cameravis.dmi' + var/obscured_sub = "black" + var/list/obscuredTurfs = list() + var/list/visibleTurfs = list() + var/list/obscured = list() + var/list/viewpoints = list() + var/list/turfs = list() + var/list/seenby = list() + var/visible = 0 + var/changed = 0 + var/updating = 0 + var/x = 0 + var/y = 0 + var/z = 0 + +/datum/visibility_chunk/proc/add(mob/new_mob) + + // if this thing doesn't use one of these visibility systems, kick it out + if (!new_mob.visibility_interface) + return + + // if the mob being added isn't a valid form of that mob, kick it out + if (!new_mob.visibility_interface:canBeAddedToChunk(src)) + return + + // add this chunk to the list of visible chunks + new_mob.visibility_interface:addChunk(src) + + visible++ + seenby += new_mob + if(changed && !updating) + update() + +/datum/visibility_chunk/proc/remove(mob/new_mob) + // if this thing doesn't use one of these visibility systems, kick it out + if (!new_mob.visibility_interface) + return + + // if the mob being added isn't a valid form of that mob, kick it out + if (!new_mob.visibility_interface:canBeAddedToChunk(src)) + return + + // remove the chunk + new_mob.visibility_interface:removeChunk(src) + + // remove the mob from out lists + seenby -= new_mob + if(visible > 0) + visible-- + +/datum/visibility_chunk/proc/visibilityChanged(turf/loc) + if(!visibleTurfs[loc]) + return + hasChanged() + +/datum/visibility_chunk/proc/hasChanged(var/update_now = 0) + if(visible || update_now) + if(!updating) + updating = 1 + spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once + update() + updating = 0 + else + changed = 1 + + +/* +This function needs to be overwritten to return True if the viewpoint object is valid, and false if it is not. +*/ +/datum/visibility_chunk/proc/validViewpoint(var/viewpoint) + return FALSE + +/* +This function needs to be overwritten to return a list of visible turfs for that viewpoint +*/ +/datum/visibility_chunk/proc/getVisibleTurfsForViewpoint(var/viewpoint) + return list() + +// returns a list of turfs which can be seen in by the chunks viewpoints +/datum/visibility_chunk/proc/getVisibleTurfs() + var/list/newVisibleTurfs = list() + for(var/viewpoint in viewpoints) + if (validViewpoint(viewpoint)) + for (var/turf/t in getVisibleTurfsForViewpoint(viewpoint)) + newVisibleTurfs[t]=t + return newVisibleTurfs + +/* +This function needs to be overwritten to find nearby viewpoint objects to the chunk center. +*/ +/datum/visibility_chunk/proc/findNearbyViewpoints() + return FALSE + +/* +This function can be overwritten to change or randomize the obscuring images +*/ +/datum/visibility_chunk/proc/setObscuredImage(var/turf/target_turf) + if(!target_turf.obscured) + target_turf.obscured = image(obscured_image, target_turf, obscured_sub, 15) + +/datum/visibility_chunk/proc/update() + + set background = 1 + + // get a list of all the turfs that our viewpoints can see + var/list/newVisibleTurfs = getVisibleTurfs() + + // Removes turf that isn't in turfs. + newVisibleTurfs &= turfs + + var/list/visAdded = newVisibleTurfs - visibleTurfs + var/list/visRemoved = visibleTurfs - newVisibleTurfs + + visibleTurfs = newVisibleTurfs + obscuredTurfs = turfs - newVisibleTurfs + + // update the visibility overlays + for(var/turf in visAdded) + var/turf/t = turf + if(t.obscured) + obscured -= t.obscured + for(var/mob/current_mob in seenby) + if (current_mob.visibility_interface) + current_mob.visibility_interface:removeObscuredTurf(t) + + for(var/turf in visRemoved) + var/turf/t = turf + if(obscuredTurfs[t]) + setObscuredImage(t) + obscured += t.obscured + for(var/mob/current_mob in seenby) + if (current_mob.visibility_interface) + current_mob.visibility_interface:addObscuredTurf(t) + else + seenby -= current_mob + + +// Create a new chunk, since the chunks are made as they are needed. +/datum/visibility_chunk/New(loc, x, y, z) + + // 0xf = 15 + x &= ~0xf + y &= ~0xf + + src.x = x + src.y = y + src.z = z + + 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] = t + + // locate all nearby viewpoints + findNearbyViewpoints() + + // get the turfs that are visible to those viewpoints + visibleTurfs = getVisibleTurfs() + + // Removes turf that isn't in turfs. + visibleTurfs &= turfs + + // create the list of turfs we can't see + obscuredTurfs = turfs - visibleTurfs + + // create the list of obscuring images to add to viewing clients + for(var/turf in obscuredTurfs) + var/turf/t = turf + setObscuredImage(t) + obscured += t.obscured + +#undef UPDATE_BUFFER \ No newline at end of file diff --git a/code/datums/visibility_networks/dictionary.dm b/code/datums/visibility_networks/dictionary.dm new file mode 100644 index 0000000000..3877332985 --- /dev/null +++ b/code/datums/visibility_networks/dictionary.dm @@ -0,0 +1,7 @@ +var/datum/visibility_network/cameras/cameraNetwork = new /datum/visibility_network/cameras() +var/datum/visibility_network/list/visibility_networks = list("ALL_CAMERAS"=cameraNetwork) + +// used by turfs and objects to update all visibility networks +/proc/updateVisibilityNetworks(atom/A, var/opacity_check = 1) + for (var/datum/visibility_network/currentNetwork in visibility_networks) + currentNetwork.updateVisibility(A, opacity_check) \ No newline at end of file diff --git a/code/datums/visibility_networks/visibility_interface.dm b/code/datums/visibility_networks/visibility_interface.dm new file mode 100644 index 0000000000..7d8efba41d --- /dev/null +++ b/code/datums/visibility_networks/visibility_interface.dm @@ -0,0 +1,46 @@ +/datum/visibility_interface + var/chunk_type = null + var/mob/controller = null + var/list/visible_chunks = list() + + +/datum/visibility_interface/New(var/mob/controller) + src.controller = controller + + +/datum/visibility_interface/proc/validMob() + return getClient() + +/datum/visibility_interface/proc/getClient() + return controller.client + +/datum/visibility_interface/proc/canBeAddedToChunk(var/datum/visibility_chunk/test_chunk) + return istype(test_chunk,chunk_type) + + +/datum/visibility_interface/proc/addChunk(var/datum/visibility_chunk/test_chunk) + visible_chunks+=test_chunk + var/client/currentClient = getClient() + if(currentClient) + currentClient.images += test_chunk.obscured + + +/datum/visibility_interface/proc/removeChunk(var/datum/visibility_chunk/test_chunk) + visible_chunks-=test_chunk + var/client/currentClient = getClient() + if(currentClient) + currentClient.images -= test_chunk.obscured + + +/datum/visibility_interface/proc/removeObscuredTurf(var/turf/target_turf) + if(validMob()) + var/client/currentClient = getClient() + if(currentClient) + currentClient.images -= target_turf.obscured + + +/datum/visibility_interface/proc/addObscuredTurf(var/turf/target_turf) + if(validMob()) + var/client/currentClient = getClient() + if(currentClient) + currentClient.images -= target_turf.obscured \ No newline at end of file diff --git a/code/datums/visibility_networks/visibility_network.dm b/code/datums/visibility_networks/visibility_network.dm new file mode 100644 index 0000000000..99fe810a6e --- /dev/null +++ b/code/datums/visibility_networks/visibility_network.dm @@ -0,0 +1,135 @@ +/datum/visibility_network + var/list/viewpoints = list() + + // the type of chunk used by this network + var/datum/visibility_chunk/ChunkType = /datum/visibility_chunk + + // The chunks of the map, mapping the areas that the viewpoints can see. + var/list/chunks = list() + + var/ready = 0 + + +// Creates a chunk key string from x,y,z coordinates +/datum/visibility_network/proc/createChunkKey(x,y,z) + x &= ~0xf + y &= ~0xf + return "[x],[y],[z]" + + +// Checks if a chunk has been Generated in x, y, z. +/datum/visibility_network/proc/chunkGenerated(x, y, z) + return (chunks[createChunkKey(x, y, z)]) + + +// Returns the chunk in the x, y, z. +// If there is no chunk, it creates a new chunk and returns that. +/datum/visibility_network/proc/getChunk(x, y, z) + var/key = createChunkKey(x, y, z) + if(!chunks[key]) + chunks[key] = new ChunkType(null, x, y, z) + return chunks[key] + + +/datum/visibility_network/proc/visibility(var/mob/targetMob) + + // if we've got not visibility interface on the mob, we canot do this + if (!targetMob.visibility_interface) + return + + // 0xf = 15 + var/x1 = max(0, targetMob.x - 16) & ~0xf + var/y1 = max(0, targetMob.y - 16) & ~0xf + var/x2 = min(world.maxx, targetMob.x + 16) & ~0xf + var/y2 = min(world.maxy, targetMob.y + 16) & ~0xf + + var/list/visibleChunks = list() + + for(var/x = x1; x <= x2; x += 16) + for(var/y = y1; y <= y2; y += 16) + visibleChunks += getChunk(x, y, targetMob.z) + + var/list/remove = targetMob.visibility_interface:visible_chunks - visibleChunks + var/list/add = visibleChunks - targetMob.visibility_interface:visible_chunks + + for(var/chunk in remove) + chunk:remove(targetMob) + + for(var/chunk in add) + chunk:add(targetMob) + + +// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. +/datum/visibility_network/proc/updateVisibility(atom/A, var/opacity_check = 1) + if(!ticker || (opacity_check && !A.opacity)) + return + majorChunkChange(A, 2) + + +/datum/visibility_network/proc/updateChunk(x, y, z) + if(!chunkGenerated(x, y, z)) + return + var/datum/visibility_chunk/chunk = getChunk(x, y, z) + chunk.hasChanged() + + +/datum/visibility_network/proc/validViewpoint(var/viewpoint) + return FALSE + + +/datum/visibility_network/proc/addViewpoint(var/viewpoint) + if(validViewpoint(viewpoint)) + majorChunkChange(viewpoint, 1) + + +/datum/visibility_network/proc/removeViewpoint(var/viewpoint) + if(validViewpoint(viewpoint)) + majorChunkChange(viewpoint, 0) + + +/datum/visibility_network/proc/updateViewpoint(var/viewpoint) + if(validViewpoint(viewpoint)) + majorChunkChange(viewpoint, 1) + + +// Never access this proc directly!!!! +// This will update the chunk and all the surrounding chunks. +// It will also add the atom to the cameras list if you set the choice to 1. +// Setting the choice to 0 will remove the viewpoint from the chunks. +// If you want to update the chunks around an object, without adding/removing a viewpoint, use choice 2. +/datum/visibility_network/proc/majorChunkChange(atom/c, var/choice) + // 0xf = 15 + if(!c) + return + + var/turf/T = get_turf(c) + if(T) + var/x1 = max(0, T.x - 8) & ~0xf + var/y1 = max(0, T.y - 8) & ~0xf + var/x2 = min(world.maxx, T.x + 8) & ~0xf + var/y2 = min(world.maxy, T.y + 8) & ~0xf + + //world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]" + + for(var/x = x1; x <= x2; x += 16) + for(var/y = y1; y <= y2; y += 16) + if(chunkGenerated(x, y, T.z)) + var/datum/visibility_chunk/chunk = getChunk(x, y, T.z) + if(choice == 0) + // Remove the viewpoint. + chunk.viewpoints -= c + else if(choice == 1) + // You can't have the same viewpoint in the list twice. + chunk.viewpoints |= c + chunk.hasChanged() + +// checks if the network can see a particular atom +/datum/visibility_network/proc/checkCanSee(var/atom/target) + var/turf/position = get_turf(target) + var/datum/visibility_chunk/chunk = getChunk(position.x, position.y, position.z) + if(chunk) + if(chunk.changed) + chunk.hasChanged(1) // Update now, no matter if it's visible or not. + if(chunk.visibleTurfs[position]) + return 1 + return 0 \ No newline at end of file diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index b84388f583..36e5100750 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -422,7 +422,8 @@ /obj/item/weapon/camera_bug/attack_self(mob/usr as mob) var/list/cameras = new/list() - for (var/obj/machinery/camera/C in cameranet.cameras) + + for (var/obj/machinery/camera/C in cameraNetwork.viewpoints) if (C.bugged && C.status) cameras.Add(C) if (length(cameras) == 0) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 104fbf1cdb..60bb93912e 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -122,7 +122,7 @@ rcd light flash thingy on matter drain mod_pick_name = "recam" uses = 10 -/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras) +/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameraNetwork.viewpoints) set name = "Reactivate Camera" set category = "Malfunction" if (istype (C, /obj/machinery/camera)) @@ -143,7 +143,7 @@ rcd light flash thingy on matter drain mod_pick_name = "upgradecam" uses = 10 -/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras) +/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameraNetwork.viewpoints) set name = "Upgrade Camera" set category = "Malfunction" if(istype(C)) @@ -156,7 +156,7 @@ rcd light flash thingy on matter drain if(!C.isXRay()) C.upgradeXRay() //Update what it can see. - cameranet.updateVisibility(C) + cameraNetwork.updateVisibility(C) upgraded = 1 if(!C.isEmpProof()) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index daea3219d6..38dc530fb0 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -39,7 +39,7 @@ assembly = new(src) assembly.state = 4 /* // Use this to look for cameras that have the same c_tag. - for(var/obj/machinery/camera/C in cameranet.cameras) + for(var/obj/machinery/camera/C in cameraNetwork.viewpoints) var/list/tempnetwork = C.network&src.network if(C != src && C.c_tag == src.c_tag && tempnetwork.len) world.log << "[src.c_tag] [src.x] [src.y] [src.z] conflicts with [C.c_tag] [C.x] [C.y] [C.z]" @@ -59,7 +59,7 @@ icon_state = "[initial(icon_state)]emp" var/list/previous_network = network network = list() - cameranet.removeCamera(src) + cameraNetwork.removeViewpoint(src) stat |= EMPED SetLuminosity(0) triggerCameraAlarm() @@ -69,7 +69,7 @@ stat &= ~EMPED cancelCameraAlarm() if(can_use()) - cameranet.addCamera(src) + cameraNetwork.addViewpoint(src) for(var/mob/O in mob_list) if (istype(O.machine, /obj/machinery/computer/security)) var/obj/machinery/computer/security/S = O.machine @@ -92,7 +92,7 @@ /obj/machinery/camera/proc/setViewRange(var/num = 7) src.view_range = num - cameranet.updateVisibility(src, 0) + cameraNetwork.updateVisibility(src, 0) /obj/machinery/camera/proc/shock(var/mob/living/user) if(!istype(user)) diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index d5408d3330..c4afc34edf 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -100,7 +100,7 @@ C.network = uniquelist(tempnetwork) tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS) if(!tempnetwork.len)//Camera isn't on any open network - remove its chunk from AI visibility. - cameranet.removeCamera(C) + cameraNetwork.removeViewpoint(C) C.c_tag = input diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index e088103fab..b745cd37f8 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -4,7 +4,7 @@ return var/list/L = list() - for (var/obj/machinery/camera/C in cameranet.cameras) + for (var/obj/machinery/camera/C in cameraNetwork.viewpoints) L.Add(C) camera_sort(L) @@ -168,9 +168,9 @@ return 0 if(isrobot(M)) var/mob/living/silicon/robot/R = M - if(!(R.camera && R.camera.can_use()) && !cameranet.checkCameraVis(M)) + if(!(R.camera && R.camera.can_use()) && !cameraNetwork.checkCanSee(M)) return 0 - else if(!cameranet.checkCameraVis(M)) + else if(!cameraNetwork.checkCanSee(M)) return 0 return 1 diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 1b21ecac95..2392eed994 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -36,7 +36,7 @@ user.set_machine(src) var/list/L = list() - for (var/obj/machinery/camera/C in cameranet.cameras) + for (var/obj/machinery/camera/C in cameraNetwork.viewpoints) L.Add(C) camera_sort(L) diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 76f1b42046..19edf26e77 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -58,7 +58,7 @@ var/intercom_range_display_status = 0 del(C) if(camera_range_display_status) - for(var/obj/machinery/camera/C in cameranet.cameras) + for(var/obj/machinery/camera/C in cameraNetwork.viewpoints) new/obj/effect/debugging/camera_range(C.loc) feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -74,7 +74,7 @@ var/intercom_range_display_status = 0 var/list/obj/machinery/camera/CL = list() - for(var/obj/machinery/camera/C in cameranet.cameras) + for(var/obj/machinery/camera/C in cameraNetwork.viewpoints) CL += C var/output = {"CAMERA ANNOMALITIES REPORT
diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index 90ae7667dd..efbee3cfd6 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -13,7 +13,7 @@ else camera = new /obj/machinery/camera(src) camera.network = list("ERT") - cameranet.removeCamera(camera) + cameraNetwork.removeViewpoint(camera) camera.c_tag = user.name user << "\blue User scanned as [camera.c_tag]. Camera activated." diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index 027a2e3a57..a898df5bcc 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -97,7 +97,7 @@ else camera = new /obj/machinery/camera(src) camera.network = list("NUKE") - cameranet.removeCamera(camera) + cameraNetwork.removeViewpoint(camera) camera.c_tag = user.name user << "\blue User scanned as [camera.c_tag]. Camera activated." diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 42c4b0745b..937ed92874 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -318,7 +318,7 @@ var/list/ai_list = list() unset_machine() src << browse(null, t1) if (href_list["switchcamera"]) - switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras + switchCamera(locate(href_list["switchcamera"])) in cameraNetwork.viewpoints if (href_list["showalerts"]) ai_alerts() //Carn: holopad requests @@ -548,7 +548,7 @@ var/list/ai_list = list() var/mob/living/silicon/ai/U = usr - for (var/obj/machinery/camera/C in cameranet.cameras) + for (var/obj/machinery/camera/C in cameraNetwork.viewpoints) if(!C.can_use()) continue @@ -566,7 +566,7 @@ var/list/ai_list = list() if(isnull(network)) network = old_network // If nothing is selected else - for(var/obj/machinery/camera/C in cameranet.cameras) + for(var/obj/machinery/camera/C in cameraNetwork.viewpoints) if(!C.can_use()) continue if(network in C.network) diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index 7d52fbd7a2..8264f705a1 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -1,3 +1,21 @@ +/datum/visibility_network/cameras + ChunkType = /datum/visibility_chunk/camera + +/datum/visibility_network/cameras/validViewpoint(var/viewpoint) + var/obj/machinery/camera/c = viewpoint + if (!c) + return FALSE + return c.can_use() + + + + + + + + + +/* // CAMERA NET // // The datum containing all the chunks. @@ -145,4 +163,6 @@ var/datum/cameranet/cameranet = new() if(cameranet.chunkGenerated(x, y, z)) var/datum/camerachunk/chunk = cameranet.getCameraChunk(x, y, z) usr.client.debug_variables(chunk) +*/ + */ \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 33dbfd0966..da1cc370f0 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -1,3 +1,29 @@ + +/datum/visibility_chunk/camera + +/datum/visibility_chunk/camera/validViewpoint(var/viewpoint) + var/obj/machinery/camera/c = viewpoint + if(!c) + return FALSE + if(!c.can_use()) + return FALSE + var/turf/point = locate(src.x + 8, src.y + 8, src.z) + if(get_dist(point, c) > 24) + return FALSE + return TRUE + + +/datum/visibility_chunk/camera/getVisibleTurfsForViewpoint(var/viewpoint) + var/obj/machinery/camera/c = viewpoint + return c.can_see() + + +/datum/visibility_chunk/camera/findNearbyViewpoints() + for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z))) + if(c.can_use()) + viewpoints += c +/* + #define UPDATE_BUFFER 25 // 2.5 seconds // CAMERA CHUNK @@ -165,4 +191,6 @@ t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) obscured += t.obscured -#undef UPDATE_BUFFER \ No newline at end of file +#undef UPDATE_BUFFER + +*/ \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index c82fbb7c76..44081bb636 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -6,13 +6,16 @@ /mob/aiEye name = "Inactive AI Eye" icon = 'icons/obj/status_display.dmi' // For AI friend secret shh :o - var/list/visibleCameraChunks = list() var/mob/living/silicon/ai/ai = null density = 0 status_flags = GODMODE // You can't damage it. mouse_opacity = 0 see_in_dark = 7 +/mob/aiEye/New() + ..() + visibility_interface = new /datum/visibility_interface/ai_eye(src) + // Movement code. Returns 0 to stop air movement from moving it. /mob/aiEye/Move() return 0 @@ -43,7 +46,7 @@ return T = get_turf(T) loc = T - cameranet.visibility(src) + cameraNetwork.visibility(src) if(ai.client) ai.client.eye = src //Holopad @@ -136,7 +139,8 @@ if(client && client.eye) client.eye = src - for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks) + + for(var/datum/visibility_chunk/camera/c in eyeobj.visibility_interface.visible_chunks) c.remove(eyeobj) /mob/living/silicon/ai/verb/toggle_acceleration() diff --git a/code/modules/mob/living/silicon/ai/freelook/read_me.dm b/code/modules/mob/living/silicon/ai/freelook/read_me.dm index 53e68ff137..aa3d99bdba 100644 --- a/code/modules/mob/living/silicon/ai/freelook/read_me.dm +++ b/code/modules/mob/living/silicon/ai/freelook/read_me.dm @@ -43,7 +43,7 @@ WHERE IS EVERYTHING? - cameranet.dm = Everything about the cameranet datum. + cameraNetwork.dm = Everything about the cameraNetwork datum. chunk.dm = Everything about the chunk datum. eye.dm = Everything about the AI and the AIEye. updating.dm = Everything about triggers that will update chunks. diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index c1f6331372..224d22f506 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -9,7 +9,7 @@ /turf/proc/visibilityChanged() if(ticker) - cameranet.updateVisibility(src) + updateVisibilityNetworks(src) /turf/simulated/Del() visibilityChanged() @@ -25,25 +25,25 @@ /obj/structure/Del() if(ticker) - cameranet.updateVisibility(src) + updateVisibilityNetworks(src) ..() /obj/structure/New() ..() if(ticker) - cameranet.updateVisibility(src) + updateVisibilityNetworks(src) // EFFECTS /obj/effect/Del() if(ticker) - cameranet.updateVisibility(src) + updateVisibilityNetworks(src) ..() /obj/effect/New() ..() if(ticker) - cameranet.updateVisibility(src) + updateVisibilityNetworks(src) // DOORS @@ -53,8 +53,9 @@ . = ..(need_rebuild) // Glass door glass = 1 // don't check then? - if(!glass && cameranet) - cameranet.updateVisibility(src, 0) + if(!glass) + world << "Updating visibility for [src]" + updateVisibilityNetworks(src,0) // ROBOT MOVEMENT @@ -72,7 +73,7 @@ updating = 1 spawn(BORG_CAMERA_BUFFER) if(oldLoc != src.loc) - cameranet.updatePortableCamera(src.camera) + cameraNetwork.updateViewpoint(src.camera) updating = 0 // CAMERA @@ -82,23 +83,23 @@ /obj/machinery/camera/deactivate(user as mob, var/choice = 1) ..(user, choice) if(src.can_use()) - cameranet.addCamera(src) + cameraNetwork.addViewpoint(src) else src.SetLuminosity(0) - cameranet.removeCamera(src) + cameraNetwork.removeViewpoint(src) /obj/machinery/camera/New() ..() - cameranet.cameras += src //Camera must be added to global list of all cameras no matter what... + cameraNetwork.viewpoints += src //Camera must be added to global list of all cameras no matter what... var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles. if(open_networks.len) //If there is at least one open network, chunk is available for AI usage. - cameranet.addCamera(src) + cameraNetwork.addViewpoint(src) /obj/machinery/camera/Del() - cameranet.cameras -= src + cameraNetwork.viewpoints -= src var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) if(open_networks.len) - cameranet.removeCamera(src) + cameraNetwork.removeViewpoint(src) ..() #undef BORG_CAMERA_BUFFER \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm b/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm new file mode 100644 index 0000000000..b55598c609 --- /dev/null +++ b/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm @@ -0,0 +1,10 @@ +/datum/visibility_interface/ai_eye + chunk_type = /datum/visibility_chunk/camera + +/datum/visibility_interface/ai_eye/getClient() + var/mob/aiEye/eye = controller + if (!eye) + return FALSE + if (!eye.ai) + return FALSE + return eye.ai.client diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 611243f654..8740c4a4f9 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1201,7 +1201,7 @@ //Disconnect it's camera so it's not so easily tracked. if(src.camera) src.camera.network = list() - cameranet.removeCamera(src.camera) + cameraNetwork.removeViewpoint(src.camera) /mob/living/silicon/robot/proc/ResetSecurityCodes() diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 5f7c707635..fd0f6be901 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -204,6 +204,7 @@ var/obj/control_object //Used by admins to possess objects. All mobs should have this var + var/datum/visibility_interface/visibility_interface = null // used by the visibility system to provide an interface for the visibility networks //Whether or not mobs can understand other mobtypes. These stay in /mob so that ghosts can hear everything. var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 314a4026ab..66c665644f 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -114,6 +114,11 @@ proc/isobserver(A) if(istype(A, /mob/dead/observer)) return 1 return 0 + +/proc/isSpirit(A) + if(istype(A, /mob/spirit)) + return 1 + return 0 proc/isorgan(A) if(istype(A, /datum/organ/external)) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 1ea768d005..399e7b9a73 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -176,7 +176,8 @@ return if(mob.stat==2) return - + + if(isSpirit(mob)) return mob:Spirit_Move(direct) if(isAI(mob)) return AIMove(n,direct,mob) if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var diff --git a/code/modules/mob/spirit/cultnet.dm b/code/modules/mob/spirit/cultnet.dm new file mode 100644 index 0000000000..9847a80b0c --- /dev/null +++ b/code/modules/mob/spirit/cultnet.dm @@ -0,0 +1,8 @@ +/* + +This file contains the code necessary to do the display code for cult spirits. + +It reuses a lot of code from the AIEye cameraNetwork. In order to work properly, some of those files needed to be modified as well. + +*/ + diff --git a/code/modules/mob/spirit/movement.dm b/code/modules/mob/spirit/movement.dm new file mode 100644 index 0000000000..a7b05856ff --- /dev/null +++ b/code/modules/mob/spirit/movement.dm @@ -0,0 +1,40 @@ +// spirits are not moved by airflow +mob/spirit/Move() + return 0 + +// this is the main move proc for spirits, it uses their 'setLoc' function to handle all the visibility shenanigans +// this, like most movement code for these guys, is cribbed from the AIEye movement code +mob/spirit/proc/Spirit_Move(direct) + + var/initial = initial(sprint) + var/max_sprint = 50 + + // if we haven't moved in a while, we stop sprinting + if(cooldown && cooldown < world.timeofday) // 3 seconds + sprint = initial + + for(var/i = 0; i < max(sprint, initial); i += 20) + var/turf/step = get_turf(get_step(src, direct)) + if(step) + setLoc(step) + + cooldown = world.timeofday + 5 + if(acceleration) + sprint = min(sprint + 0.5, max_sprint) + else + sprint = initial + + // if we're trying to move, we want to stop following our target + follow_target = null + +mob/spirit/proc/setLoc(var/T) + T = get_turf(T) + loc = T + //cultnet.visibility(src) + +mob/spirit/verb/toggle_acceleration() + set category = "Spirit" + set name = "Toggle Acceleration" + + acceleration = !acceleration + usr << "Acceleration has been toggled [acceleration ? "on" : "off"]." \ No newline at end of file diff --git a/code/modules/mob/spirit/spirit.dm b/code/modules/mob/spirit/spirit.dm new file mode 100644 index 0000000000..d03a679c57 --- /dev/null +++ b/code/modules/mob/spirit/spirit.dm @@ -0,0 +1,42 @@ +/* +This mob type is used for entities that exist within the Cult's spirit world. They share the same visibility network and are intangible. + + +NOTES + +- make chunks generic + - subclass them for camerachunks and for cultchunks +- do the same thing with visibility networks + - cultnet and cameraNetwork etc. +*/ + +mob/spirit + name = "spirit" + desc = "A spirit" + icon = 'icons/mob/mob.dmi' + icon_state = "ghost" + layer = 4 + stat = CONSCIOUS + status_flags = GODMODE // spirits cannot be killed + density = 0 + canmove = 0 + blinded = 0 + anchored = 1 + invisibility = INVISIBILITY_SPIRIT + + // pseudo-movement values + var/sprint = 10 + var/cooldown = 0 + var/acceleration = 1 + var/follow_target = null + +mob/spirit/New() + sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF + see_invisible = SEE_SPIRITS + see_in_dark = 100 + + loc = pick(latejoin) + + // no nameless spirits + if (!name) + name = "Boogyman" \ No newline at end of file diff --git a/code/setup.dm b/code/setup.dm index 62515d050c..a689ec7011 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -529,6 +529,9 @@ var/list/liftable_structures = list(\ #define SEE_INVISIBLE_LEVEL_TWO 45 //Used by some other stuff in code. It's really poorly organized. #define INVISIBILITY_LEVEL_TWO 45 //Used by some other stuff in code. It's really poorly organized. +#define INVISIBILITY_SPIRIT 50 +#define SEE_SPIRITS 50 + #define INVISIBILITY_OBSERVER 60 #define SEE_INVISIBLE_OBSERVER 60 diff --git a/code/unused/AI_Visibility.dm b/code/unused/AI_Visibility.dm index d218f4409b..0769f8ca87 100644 --- a/code/unused/AI_Visibility.dm +++ b/code/unused/AI_Visibility.dm @@ -5,7 +5,7 @@ var/image/dim /turf/proc/visibilityChanged() - cameranet.updateVisibility(src) + cameraNetwork.updateVisibility(src) /datum/camerachunk var/list/obscuredTurfs = list() @@ -180,22 +180,22 @@ dim += t.dim -var/datum/cameranet/cameranet = new() +var/datum/cameraNetwork/cameraNetwork = new() -/datum/cameranet +/datum/cameraNetwork var/list/cameras = list() var/list/chunks = list() var/network = "net1" var/ready = 0 -/datum/cameranet/New() +/datum/cameraNetwork/New() ..() -/datum/cameranet/proc/chunkGenerated(x, y, z) +/datum/cameraNetwork/proc/chunkGenerated(x, y, z) var/key = "[x],[y],[z]" return key in chunks -/datum/cameranet/proc/getCameraChunk(x, y, z) +/datum/cameraNetwork/proc/getCameraChunk(x, y, z) var/key = "[x],[y],[z]" if(!(key in chunks)) @@ -203,7 +203,7 @@ var/datum/cameranet/cameranet = new() return chunks[key] -/datum/cameranet/proc/visibility(mob/aiEye/ai) +/datum/cameraNetwork/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 @@ -224,14 +224,14 @@ var/datum/cameranet/cameranet = new() for(var/datum/camerachunk/c in add) c.add(ai) -/datum/cameranet/proc/updateVisibility(turf/loc) +/datum/cameraNetwork/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) +/datum/cameraNetwork/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 @@ -265,17 +265,17 @@ var/datum/cameranet/cameranet = new() else client.eye = eyeobj eyeobj.loc = loc - cameranet.visibility(eyeobj) + cameraNetwork.visibility(eyeobj) cameraFollow = null /mob/aiEye/Move() . = ..() if(.) - cameranet.visibility(src) + cameraNetwork.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) + cameraNetwork.visibility(user.eyeobj) else return ..() @@ -289,7 +289,7 @@ var/datum/cameranet/cameranet = new() 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) + cameraNetwork.visibility(user.eyeobj) else return ..() */ @@ -303,8 +303,8 @@ var/datum/cameranet/cameranet = new() /obj/machinery/door/update_nearby_tiles(need_rebuild) . = ..(need_rebuild) - cameranet.updateVisibility(loc) + cameraNetwork.updateVisibility(loc) /obj/machinery/camera/New() ..() - cameranet.addCamera(src) \ No newline at end of file + cameraNetwork.addViewpoint(src) \ No newline at end of file From d370c6f81ecadda331cf2ce85e2684d1e7c8d8cb Mon Sep 17 00:00:00 2001 From: jack-fractal Date: Sat, 26 Oct 2013 17:33:53 -0400 Subject: [PATCH 02/18] * fixing the visibility update loop through the dictionary * moving the standard turf and object update triggers to the visibility_network update_triggers.dm file --- code/datums/visibility_networks/dictionary.dm | 4 +- .../visibility_networks/update_triggers.dm | 55 ++++++++++++++++++ .../visibility_networks/visibility_network.dm | 2 - .../silicon/ai/freelook/update_triggers.dm | 58 ------------------- 4 files changed, 58 insertions(+), 61 deletions(-) create mode 100644 code/datums/visibility_networks/update_triggers.dm diff --git a/code/datums/visibility_networks/dictionary.dm b/code/datums/visibility_networks/dictionary.dm index 3877332985..426a8bea1d 100644 --- a/code/datums/visibility_networks/dictionary.dm +++ b/code/datums/visibility_networks/dictionary.dm @@ -3,5 +3,7 @@ var/datum/visibility_network/list/visibility_networks = list("ALL_CAMERAS"=camer // used by turfs and objects to update all visibility networks /proc/updateVisibilityNetworks(atom/A, var/opacity_check = 1) - for (var/datum/visibility_network/currentNetwork in visibility_networks) + var/datum/visibility_network/currentNetwork + for (var/networkName in visibility_networks) + currentNetwork = visibility_networks[networkName] currentNetwork.updateVisibility(A, opacity_check) \ No newline at end of file diff --git a/code/datums/visibility_networks/update_triggers.dm b/code/datums/visibility_networks/update_triggers.dm new file mode 100644 index 0000000000..78c8f9fe03 --- /dev/null +++ b/code/datums/visibility_networks/update_triggers.dm @@ -0,0 +1,55 @@ +//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. + +// TURFS + +/turf + var/image/obscured + +/turf/proc/visibilityChanged() + if(ticker) + updateVisibilityNetworks(src) + +/turf/simulated/Del() + visibilityChanged() + ..() + +/turf/simulated/New() + ..() + visibilityChanged() + + + +// STRUCTURES + +/obj/structure/Del() + if(ticker) + updateVisibilityNetworks(src) + ..() + +/obj/structure/New() + ..() + if(ticker) + updateVisibilityNetworks(src) + +// EFFECTS + +/obj/effect/Del() + if(ticker) + updateVisibilityNetworks(src) + ..() + +/obj/effect/New() + ..() + if(ticker) + updateVisibilityNetworks(src) + + +// DOORS + +// Simply updates the visibility of the area when it opens/closes/destroyed. +/obj/machinery/door/update_nearby_tiles(need_rebuild) + . = ..(need_rebuild) + // Glass door glass = 1 + // don't check then? + if(!glass) + updateVisibilityNetworks(src,0) \ No newline at end of file diff --git a/code/datums/visibility_networks/visibility_network.dm b/code/datums/visibility_networks/visibility_network.dm index 99fe810a6e..72f73a6d49 100644 --- a/code/datums/visibility_networks/visibility_network.dm +++ b/code/datums/visibility_networks/visibility_network.dm @@ -109,8 +109,6 @@ var/x2 = min(world.maxx, T.x + 8) & ~0xf var/y2 = min(world.maxy, T.y + 8) & ~0xf - //world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]" - for(var/x = x1; x <= x2; x += 16) for(var/y = y1; y <= y2; y += 16) if(chunkGenerated(x, y, T.z)) diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index 224d22f506..05aa5ef317 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -1,63 +1,5 @@ #define BORG_CAMERA_BUFFER 30 -//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. - -// TURFS - -/turf - var/image/obscured - -/turf/proc/visibilityChanged() - if(ticker) - updateVisibilityNetworks(src) - -/turf/simulated/Del() - visibilityChanged() - ..() - -/turf/simulated/New() - ..() - visibilityChanged() - - - -// STRUCTURES - -/obj/structure/Del() - if(ticker) - updateVisibilityNetworks(src) - ..() - -/obj/structure/New() - ..() - if(ticker) - updateVisibilityNetworks(src) - -// EFFECTS - -/obj/effect/Del() - if(ticker) - updateVisibilityNetworks(src) - ..() - -/obj/effect/New() - ..() - if(ticker) - updateVisibilityNetworks(src) - - -// DOORS - -// Simply updates the visibility of the area when it opens/closes/destroyed. -/obj/machinery/door/update_nearby_tiles(need_rebuild) - . = ..(need_rebuild) - // Glass door glass = 1 - // don't check then? - if(!glass) - world << "Updating visibility for [src]" - updateVisibilityNetworks(src,0) - - // ROBOT MOVEMENT // Update the portable camera everytime the Robot moves. From c6ec4329046bc94116e3b12308b446f071c9bef6 Mon Sep 17 00:00:00 2001 From: jack-fractal Date: Sun, 17 Nov 2013 16:23:36 -0500 Subject: [PATCH 03/18] - major update to all systems - creating the mask entity - modifying the code for cult icons - updating the camera net - adding visibility network updates to all mobs - unifying the culting and deculting process - adding "Make Mask" function to Player Panel --- baystation12.dme | 3 + baystation12.int | 3 + code/__HELPERS/global_lists.dm | 1 + code/controllers/verbs.dm | 5 +- code/datums/datumvars.dm | 14 +- code/datums/mind.dm | 8 + .../datums/visibility_networks/NEXT THING.txt | 7 + code/datums/visibility_networks/dictionary.dm | 6 +- .../visibility_networks/update_triggers.dm | 49 +- .../visibility_networks/visibility_network.dm | 8 + code/game/gamemodes/cult/cult.dm | 137 +- code/game/gamemodes/cult/ritual.dm | 10 +- code/game/gamemodes/cult/runes.dm | 1802 +++++++++-------- code/game/machinery/doors/door.dm | 4 + code/modules/admin/admin.dm | 1 + code/modules/admin/topic.dm | 9 + code/modules/mob/living/carbon/human/death.dm | 7 +- code/modules/mob/living/living.dm | 1 + .../living/silicon/ai/freelook/cameranet.dm | 168 +- .../mob/living/silicon/ai/freelook/chunk.dm | 175 +- .../mob/living/silicon/ai/freelook/eye.dm | 1 - .../silicon/ai/freelook/update_triggers.dm | 18 - .../modules/mob/living/silicon/robot/robot.dm | 5 + code/modules/mob/spirit/cultnet.dm | 74 +- code/modules/mob/spirit/mask/mask.dm | 171 ++ code/modules/mob/spirit/movement.dm | 22 +- code/modules/mob/spirit/spirit.dm | 52 +- code/modules/mob/spirit/viewpoint.dm | 195 ++ code/modules/mob/transform_procs.dm | 64 + code/stylesheet.dm | 1 + 30 files changed, 1735 insertions(+), 1286 deletions(-) create mode 100644 code/datums/visibility_networks/NEXT THING.txt create mode 100644 code/modules/mob/spirit/mask/mask.dm create mode 100644 code/modules/mob/spirit/viewpoint.dm diff --git a/baystation12.dme b/baystation12.dme index 74dea3f7ff..ccda06046a 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -155,6 +155,7 @@ #include "code\datums\spells\wizard.dm" #include "code\datums\visibility_networks\chunk.dm" #include "code\datums\visibility_networks\dictionary.dm" +#include "code\datums\visibility_networks\update_triggers.dm" #include "code\datums\visibility_networks\visibility_interface.dm" #include "code\datums\visibility_networks\visibility_network.dm" #include "code\defines\obj.dm" @@ -1026,6 +1027,8 @@ #include "code\modules\mob\spirit\cultnet.dm" #include "code\modules\mob\spirit\movement.dm" #include "code\modules\mob\spirit\spirit.dm" +#include "code\modules\mob\spirit\viewpoint.dm" +#include "code\modules\mob\spirit\mask\mask.dm" #include "code\modules\nano\_JSON.dm" #include "code\modules\nano\JSON Reader.dm" #include "code\modules\nano\JSON Writer.dm" diff --git a/baystation12.int b/baystation12.int index b82874fded..aefda4d8d7 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,6 +1,9 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 +LAST_COMPILE_VERSION: 501.1217 +DIR: code code\datums code\datums\visibility_networks code\defines\obj code\game code\game\gamemodes code\game\gamemodes\cult code\game\gamemodes\malfunction code\game\machinery code\game\machinery\camera code\modules code\modules\admin code\modules\mob code\modules\mob\living code\modules\mob\living\carbon code\modules\mob\living\carbon\human +LAST_COMPILE_TIME: 1384721250 AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 956e6be255..20bb1bedeb 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -7,6 +7,7 @@ var/list/directory = list() //list of all ckeys with associated client var/global/list/player_list = list() //List of all mobs **with clients attached**. Excludes /mob/new_player var/global/list/mob_list = list() //List of all mobs, including clientless +var/global/list/spirits = list() //List of all the spirits, including Masks var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 3b2d9697bf..777fbbd3fb 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -28,7 +28,7 @@ return -/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI", "Cameras")) +/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI", "Cameras","CultNetwork")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -74,5 +74,8 @@ if("Cameras") debug_variables(cameraNetwork) feedback_add_details("admin_verb","DCameras") + if("CultNetwork") + debug_variables(cultNetwork) + feedback_add_details("admin_verb","DCultNetwork") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") return diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index dc3a3b36db..7c1dbb0f8c 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -263,6 +263,7 @@ client body += "" body += "" body += "" + body += "" body += "" body += "" body += "" @@ -724,7 +725,18 @@ client usr << "Mob doesn't exist anymore" return holder.Topic(href, list("makeai"=href_list["makeai"])) - + + + else if(href_list["makemask"]) + if(!check_rights(R_SPAWN)) return + var/mob/currentMob = locate(href_list["makemask"]) + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return + if(!currentMob) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makemask"=href_list["makemask"])) + + else if(href_list["setmutantrace"]) if(!check_rights(R_SPAWN)) return diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 7adc6a9679..d41a521ac3 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -589,6 +589,11 @@ datum/mind log_admin("[key_name_admin(usr)] has de-cult'ed [current].") if("cultist") if(!(src in ticker.mode.cult)) + ticker.mode.add_cultist(src) + special_role = "Cultist" + current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." + current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + /* ticker.mode.cult += src ticker.mode.update_cult_icons_added(src) special_role = "Cultist" @@ -597,6 +602,9 @@ datum/mind var/datum/game_mode/cult/cult = ticker.mode if (istype(cult)) cult.memoize_cult_objectives(src) + var/obj/cult_viewpoint/viewpoint = new(current) + viewpoint.loc = current + */ log_admin("[key_name_admin(usr)] has cult'ed [current].") if("tome") var/mob/living/carbon/human/H = current diff --git a/code/datums/visibility_networks/NEXT THING.txt b/code/datums/visibility_networks/NEXT THING.txt new file mode 100644 index 0000000000..0d2cd53750 --- /dev/null +++ b/code/datums/visibility_networks/NEXT THING.txt @@ -0,0 +1,7 @@ +Next Thing To Do + +- sprites! +- follow! + - can we hide inside cultists? +- cult names! +- powers \ No newline at end of file diff --git a/code/datums/visibility_networks/dictionary.dm b/code/datums/visibility_networks/dictionary.dm index 426a8bea1d..3dcb1bc427 100644 --- a/code/datums/visibility_networks/dictionary.dm +++ b/code/datums/visibility_networks/dictionary.dm @@ -1,5 +1,7 @@ -var/datum/visibility_network/cameras/cameraNetwork = new /datum/visibility_network/cameras() -var/datum/visibility_network/list/visibility_networks = list("ALL_CAMERAS"=cameraNetwork) +var/datum/visibility_network/cameras/cameraNetwork = new() +var/datum/visibility_network/cult/cultNetwork = new() +var/datum/visibility_network/list/visibility_networks = list("ALL_CAMERAS"=cameraNetwork, "CULT" = cultNetwork) + // used by turfs and objects to update all visibility networks /proc/updateVisibilityNetworks(atom/A, var/opacity_check = 1) diff --git a/code/datums/visibility_networks/update_triggers.dm b/code/datums/visibility_networks/update_triggers.dm index 78c8f9fe03..f1835eeeb5 100644 --- a/code/datums/visibility_networks/update_triggers.dm +++ b/code/datums/visibility_networks/update_triggers.dm @@ -47,9 +47,48 @@ // DOORS // Simply updates the visibility of the area when it opens/closes/destroyed. -/obj/machinery/door/update_nearby_tiles(need_rebuild) - . = ..(need_rebuild) - // Glass door glass = 1 - // don't check then? +/obj/machinery/door/proc/update_nearby_tiles(need_rebuild) + if(!glass) - updateVisibilityNetworks(src,0) \ No newline at end of file + updateVisibilityNetworks(src,0) + + if(!air_master) + return 0 + + for(var/turf/simulated/turf in locs) + update_heat_protection(turf) + air_master.AddTurfToUpdate(turf) + + return 1 + + + +#define UPDATE_VISIBILITY_NETWORK_BUFFER 30 + +/mob + var/datum/visibility_network/list/visibilityNetworks=list() + var/updatingVisibilityNetworks=FALSE + +/mob/Move(n,direct) + var/oldLoc = src.loc + . = ..() + if(.) + if(src.visibilityNetworks.len) + if(!src.updatingVisibilityNetworks) + src.updatingVisibilityNetworks = 1 + spawn(UPDATE_VISIBILITY_NETWORK_BUFFER) + if(oldLoc != src.loc) + for (var/datum/visibility_network/currentNetwork in src.visibilityNetworks) + currentNetwork.updateMob(src) + src.updatingVisibilityNetworks = 0 + return ..(n,direct) + +/mob/proc/addToVisibilityNetwork(var/datum/visibility_network/network) + if(network) + src.visibilityNetworks+=network + +/mob/proc/removeFromVisibilityNetwork(var/datum/visibility_network/network) + if(network) + src.visibilityNetworks|=network + +#undef UPDATE_VISIBILITY_NETWORK_BUFFER \ No newline at end of file diff --git a/code/datums/visibility_networks/visibility_network.dm b/code/datums/visibility_networks/visibility_network.dm index 72f73a6d49..4361d8ef14 100644 --- a/code/datums/visibility_networks/visibility_network.dm +++ b/code/datums/visibility_networks/visibility_network.dm @@ -86,6 +86,14 @@ if(validViewpoint(viewpoint)) majorChunkChange(viewpoint, 0) +/datum/visibility_network/proc/getViewpointFromMob(var/mob/currentMob) + return FALSE + +/datum/visibility_network/proc/updateMob(var/mob/currentMob) + var/viewpoint = getViewpointFromMob(currentMob) + if(viewpoint) + updateViewpoint(viewpoint) + /datum/visibility_network/proc/updateViewpoint(var/viewpoint) if(validViewpoint(viewpoint)) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index ee16e21a77..401644c631 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -134,6 +134,10 @@ mob.mutations.Remove(CLUMSY) + var/obj/cult_viewpoint/viewpoint = new(mob) + viewpoint.loc = mob + world << "Spawning viewpoint on [mob]" + var/obj/item/weapon/paper/talisman/supply/T = new(mob) var/list/slots = list ( "backpack" = slot_in_backpack, @@ -174,6 +178,8 @@ return 0 if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind)) cult += cult_mind + var/obj/cult_viewpoint/viewpoint = new(cult_mind.current) + viewpoint.loc = cult_mind.current update_cult_icons_added(cult_mind) return 1 @@ -189,29 +195,134 @@ cult -= cult_mind cult_mind.current << "\red An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it." cult_mind.memory = "" + + // remove the cult viewpoint object + var/obj/viewpoint = getCultViewpoint(cult_mind.current) + del(viewpoint) + update_cult_icons_removed(cult_mind) if(show_message) for(var/mob/M in viewers(cult_mind.current)) M << "[cult_mind.current] looks like they just reverted to their old faith!" + /datum/game_mode/proc/update_all_cult_icons() spawn(0) + // reset the cult + for(var/datum/mind/cultist in cult) + reset_cult_icons_for_cultist(cultist) + // reset the spirits + for(var/mob/spirit/currentSpirit in spirits) + reset_cult_icons_for_spirit(currentSpirit) + + +/datum/game_mode/proc/reset_cult_icons_for_cultist(var/datum/mind/target) + if(target.current) + if(target.current.client) + remove_all_cult_icons(target) + for(var/datum/mind/cultist in cult) + if(cultist.current) + add_cult_icon(target.current.client,cultist.current) + + +/datum/game_mode/proc/reset_cult_icons_for_spirit(mob/spirit/target) + if (target.client) + remove_all_cult_icons(target) for(var/datum/mind/cultist in cult) if(cultist.current) - if(cultist.current.client) - for(var/image/I in cultist.current.client.images) - if(I.icon_state == "cult") - del(I) + add_cult_icon(target.client,cultist.current) + + +/datum/game_mode/proc/add_cult_icon(client/target_client,mob/target_mob) + var/I = image('icons/mob/mob.dmi', loc = target_mob, icon_state = "cult") + target_client.images += I + +/datum/game_mode/proc/remove_cult_icon(client/target_client,mob/target_mob) + for(var/image/I in target_client.images) + if(I.icon_state == "cult" && I.loc == target_mob) + del(I) + + +/datum/game_mode/proc/remove_all_cult_icons_from_client(client/target) + for(var/image/I in target.images) + if(I.icon_state == "cult") + del(I) + + +/datum/game_mode/proc/remove_all_cult_icons(target) + var/datum/mind/cultist = target + if(istype(cultist)) + if(cultist.current) + if(cultist.current.client) + remove_all_cult_icons_from_client(cultist.current.client) + return TRUE + var/mob/spirit/currentSpirit = target + if(istype(currentSpirit)) + if (currentSpirit.client) + remove_all_cult_icons_from_client(currentSpirit.client) + return TRUE + return FALSE + + +/datum/game_mode/proc/add_cult_icon_to_spirit(mob/spirit/currentSpirit,datum/mind/cultist) + if(!istype(currentSpirit) || !istype(cultist)) + return FALSE + if (currentSpirit.client) + if (cultist.current) + add_cult_icon(currentSpirit.client,cultist.current) + + +/datum/game_mode/proc/add_cult_icon_to_cultist(datum/mind/first_cultist,datum/mind/second_cultist) + if(first_cultist.current && second_cultist.current) + if(first_cultist.current.client) + add_cult_icon(first_cultist.current.client, second_cultist.current) + + +/datum/game_mode/proc/remove_cult_icon_from_cultist(datum/mind/first_cultist,datum/mind/second_cultist) + if(first_cultist.current && second_cultist.current) + if(first_cultist.current.client) + remove_cult_icon(first_cultist.current.client,second_cultist.current) + + +/datum/game_mode/proc/remove_cult_icon_from_spirit(mob/spirit/currentSpirit,datum/mind/cultist) + if(!istype(currentSpirit) || !istype(cultist)) + return FALSE + if (currentSpirit.client) + if (cultist.current) + remove_cult_icon(currentSpirit.client,cultist.current) + + +/datum/game_mode/proc/cult_icon_pair_link(datum/mind/first_cultist,datum/mind/second_cultist) + if (!istype(first_cultist) || !istype(second_cultist)) + return 0 + add_cult_icon_to_cultist(first_cultist,second_cultist) + add_cult_icon_to_cultist(second_cultist,first_cultist) + + +/datum/game_mode/proc/cult_icon_pair_unlink(datum/mind/first_cultist,datum/mind/second_cultist) + if (!istype(first_cultist) || !istype(second_cultist)) + return 0 + remove_cult_icon(first_cultist,second_cultist) + remove_cult_icon(second_cultist,first_cultist) + + +/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind) + spawn(0) for(var/datum/mind/cultist in cult) - if(cultist.current) - if(cultist.current.client) - for(var/datum/mind/cultist_1 in cult) - if(cultist_1.current) - var/I = image('icons/mob/mob.dmi', loc = cultist_1.current, icon_state = "cult") - cultist.current.client.images += I - - + cult_icon_pair_link(cultist,cult_mind) + for(var/mob/spirit/currentSpirit in spirits) + add_cult_icon_to_spirit(currentSpirit,cult_mind) + + +/datum/game_mode/proc/update_cult_icons_removed(datum/mind/cult_mind) + spawn(0) + for(var/datum/mind/cultist in cult) + cult_icon_pair_unlink(cultist,cult_mind) + for(var/mob/spirit/currentSpirit in spirits) + remove_cult_icon_from_spirit(currentSpirit,cult_mind) + +/* /datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind) spawn(0) for(var/datum/mind/cultist in cult) @@ -239,7 +350,7 @@ for(var/image/I in cult_mind.current.client.images) if(I.icon_state == "cult") del(I) - +*/ /datum/game_mode/cult/proc/get_unconvertables() var/list/ucs = list() diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 2d408a1a4f..69bd5cc42b 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -25,6 +25,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", icon = 'icons/obj/rune.dmi' icon_state = "1" var/visibility = 0 + var/view_range = 7 unacidable = 1 layer = TURF_LAYER @@ -67,11 +68,18 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", blood.override = 1 for(var/mob/living/silicon/ai/AI in player_list) AI.client.images += blood + cultNetwork.viewpoints+=src + cultNetwork.addViewpoint(src) + + Del() + ..() + cultNetwork.viewpoints-=src + cultNetwork.removeViewpoint(src) examine() set src in view(2) - if(!iscultist(usr)) + if(!iscultist(usr) && !isSpirit(usr)) usr << "A strange collection of symbols drawn in blood." return /* Explosions... really? diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index e5be5d60a7..d17f9022aa 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1,197 +1,196 @@ var/list/sacrificed = list() -/obj/effect/rune + /////////////////////////////////////////FIRST RUNE - proc - teleport(var/key) - var/mob/living/user = usr - var/allrunesloc[] - allrunesloc = new/list() - var/index = 0 - // var/tempnum = 0 - for(var/obj/effect/rune/R in world) - if(R == src) - continue - if(R.word1 == cultwords["travel"] && R.word2 == cultwords["self"] && R.word3 == key && R.z != 2) - index++ - allrunesloc.len = index - allrunesloc[index] = R.loc - if(index >= 5) - user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" - if (istype(user, /mob/living)) - user.take_overall_damage(5, 0) - del(src) - if(allrunesloc && index != 0) - if(istype(src,/obj/effect/rune)) - user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting - else - user.whisper("Sas[pick("'","`")]so c'arta forbici!") - user.visible_message("\red [user] disappears in a flash of red light!", \ - "\red You feel as your body gets dragged through the dimension of Nar-Sie!", \ - "\red You hear a sickening crunch and sloshing of viscera.") - user.loc = allrunesloc[rand(1,index)] - return - if(istype(src,/obj/effect/rune)) - return fizzle() //Use friggin manuals, Dorf, your list was of zero length. - else - call(/obj/effect/rune/proc/fizzle)() - return +/obj/effect/rune/proc/teleport(var/key) + var/mob/living/user = usr + var/allrunesloc[] + allrunesloc = new/list() + var/index = 0 +// var/tempnum = 0 + for(var/obj/effect/rune/R in world) + if(R == src) + continue + if(R.word1 == cultwords["travel"] && R.word2 == cultwords["self"] && R.word3 == key && R.z != 2) + index++ + allrunesloc.len = index + allrunesloc[index] = R.loc + if(index >= 5) + user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" + if (istype(user, /mob/living)) + user.take_overall_damage(5, 0) + del(src) + if(allrunesloc && index != 0) + if(istype(src,/obj/effect/rune)) + user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting + else + user.whisper("Sas[pick("'","`")]so c'arta forbici!") + user.visible_message("\red [user] disappears in a flash of red light!", \ + "\red You feel as your body gets dragged through the dimension of Nar-Sie!", \ + "\red You hear a sickening crunch and sloshing of viscera.") + user.loc = allrunesloc[rand(1,index)] + return + if(istype(src,/obj/effect/rune)) + return fizzle() //Use friggin manuals, Dorf, your list was of zero length. + else + call(/obj/effect/rune/proc/fizzle)() + return - itemport(var/key) +/obj/effect/rune/proc/itemport(var/key) // var/allrunesloc[] // allrunesloc = new/list() // var/index = 0 - // var/tempnum = 0 - var/culcount = 0 - var/runecount = 0 - var/obj/effect/rune/IP = null - var/mob/living/user = usr - for(var/obj/effect/rune/R in world) - if(R == src) - continue - if(R.word1 == cultwords["travel"] && R.word2 == cultwords["other"] && R.word3 == key) - IP = R - runecount++ - if(runecount >= 2) - user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" - if (istype(user, /mob/living)) - user.take_overall_damage(5, 0) - del(src) - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - culcount++ - if(culcount>=3) - user.say("Sas[pick("'","`")]so c'arta forbici tarem!") - user.visible_message("\red You feel air moving from the rune - like as it was swapped with somewhere else.", \ - "\red You feel air moving from the rune - like as it was swapped with somewhere else.", \ - "\red You smell ozone.") - for(var/obj/O in src.loc) - if(!O.anchored) - O.loc = IP.loc - for(var/mob/M in src.loc) - M.loc = IP.loc - return +// var/tempnum = 0 + var/culcount = 0 + var/runecount = 0 + var/obj/effect/rune/IP = null + var/mob/living/user = usr + for(var/obj/effect/rune/R in world) + if(R == src) + continue + if(R.word1 == cultwords["travel"] && R.word2 == cultwords["other"] && R.word3 == key) + IP = R + runecount++ + if(runecount >= 2) + user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" + if (istype(user, /mob/living)) + user.take_overall_damage(5, 0) + del(src) + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + culcount++ + if(culcount>=3) + user.say("Sas[pick("'","`")]so c'arta forbici tarem!") + user.visible_message("\red You feel air moving from the rune - like as it was swapped with somewhere else.", \ + "\red You feel air moving from the rune - like as it was swapped with somewhere else.", \ + "\red You smell ozone.") + for(var/obj/O in src.loc) + if(!O.anchored) + O.loc = IP.loc + for(var/mob/M in src.loc) + M.loc = IP.loc + return - return fizzle() + return fizzle() /////////////////////////////////////////SECOND RUNE - tomesummon() - if(istype(src,/obj/effect/rune)) - usr.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") - else - usr.whisper("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") - usr.visible_message("\red Rune disappears with a flash of red light, and in its place now a book lies.", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a book.", \ - "\red You hear a pop and smell ozone.") - if(istype(src,/obj/effect/rune)) - new /obj/item/weapon/tome(src.loc) - else - new /obj/item/weapon/tome(usr.loc) - del(src) - return +/obj/effect/rune/proc/tomesummon() + if(istype(src,/obj/effect/rune)) + usr.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") + else + usr.whisper("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") + usr.visible_message("\red Rune disappears with a flash of red light, and in its place now a book lies.", \ + "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a book.", \ + "\red You hear a pop and smell ozone.") + if(istype(src,/obj/effect/rune)) + new /obj/item/weapon/tome(src.loc) + else + new /obj/item/weapon/tome(usr.loc) + del(src) + return /////////////////////////////////////////THIRD RUNE - convert() - for(var/mob/living/carbon/M in src.loc) - if(iscultist(M)) - continue - if(M.stat==2) - continue - usr.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!") - M.visible_message("\red [M] writhes in pain as the markings below him glow a bloody red.", \ - "\red AAAAAAHHHH!.", \ - "\red You hear an anguished scream.") - if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist"))//putting jobban check here because is_convertable uses mind as argument - ticker.mode.add_cultist(M.mind) - M.mind.special_role = "Cultist" - M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - return 1 - else - M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "And you were able to force it out of your mind. You now know the truth, there's something horrible out there, stop it and its minions at all costs." - return 0 +/obj/effect/rune/proc/convert() + for(var/mob/living/carbon/M in src.loc) + if(iscultist(M)) + continue + if(M.stat==2) + continue + usr.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!") + M.visible_message("\red [M] writhes in pain as the markings below him glow a bloody red.", \ + "\red AAAAAAHHHH!.", \ + "\red You hear an anguished scream.") + if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist"))//putting jobban check here because is_convertable uses mind as argument + ticker.mode.add_cultist(M.mind) + M.mind.special_role = "Cultist" + M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + M << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + return 1 + else + M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + M << "And you were able to force it out of your mind. You now know the truth, there's something horrible out there, stop it and its minions at all costs." + return 0 - return fizzle() + return fizzle() /////////////////////////////////////////FOURTH RUNE - tearreality() - var/cultist_count = 0 - for(var/mob/M in range(1,src)) - if(iscultist(M) && !M.stat) - M.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!") - cultist_count += 1 - if(cultist_count >= 9) - new /obj/machinery/singularity/narsie/large(src.loc) - if(ticker.mode.name == "cult") - ticker.mode:eldergod = 0 - return - else - return fizzle() +/obj/effect/rune/proc/tearreality() + var/cultist_count = 0 + for(var/mob/M in range(1,src)) + if(iscultist(M) && !M.stat) + M.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!") + cultist_count += 1 + if(cultist_count >= 9) + new /obj/machinery/singularity/narsie/large(src.loc) + if(ticker.mode.name == "cult") + ticker.mode:eldergod = 0 + return + else + return fizzle() /////////////////////////////////////////FIFTH RUNE - emp(var/U,var/range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist - if(istype(src,/obj/effect/rune)) - usr.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!") - else - usr.whisper("Ta'gh fara[pick("'","`")]qha fel d'amar det!") - playsound(U, 'sound/items/Welder2.ogg', 25, 1) - var/turf/T = get_turf(U) - if(T) - T.hotspot_expose(700,125) - var/rune = src // detaching the proc - in theory - empulse(U, (range_red - 2), range_red) - del(rune) - return +/obj/effect/rune/proc/emp(var/U,var/range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist + if(istype(src,/obj/effect/rune)) + usr.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!") + else + usr.whisper("Ta'gh fara[pick("'","`")]qha fel d'amar det!") + playsound(U, 'sound/items/Welder2.ogg', 25, 1) + var/turf/T = get_turf(U) + if(T) + T.hotspot_expose(700,125) + var/rune = src // detaching the proc - in theory + empulse(U, (range_red - 2), range_red) + del(rune) + return /////////////////////////////////////////SIXTH RUNE - drain() - var/drain = 0 - for(var/obj/effect/rune/R in world) - if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"]) - for(var/mob/living/carbon/D in R.loc) - if(D.stat!=2) - var/bdrain = rand(1,25) - D << "\red You feel weakened." - D.take_overall_damage(bdrain, 0) - drain += bdrain - if(!drain) - return fizzle() - usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!") - usr.visible_message("\red Blood flows from the rune into [usr]!", \ - "\red The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.", \ - "\red You hear a liquid flowing.") - var/mob/living/user = usr - if(user.bhunger) - user.bhunger = max(user.bhunger-2*drain,0) - if(drain>=50) - user.visible_message("\red [user]'s eyes give off eerie red glow!", \ - "\red ...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.", \ - "\red You hear a heartbeat.") - user.bhunger += drain - src = user - spawn() - for (,user.bhunger>0,user.bhunger--) - sleep(50) - user.take_overall_damage(3, 0) - return - user.heal_organ_damage(drain%5, 0) - drain-=drain%5 - for (,drain>0,drain-=5) - sleep(2) - user.heal_organ_damage(5, 0) - return +/obj/effect/rune/proc/drain() + var/drain = 0 + for(var/obj/effect/rune/R in world) + if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"]) + for(var/mob/living/carbon/D in R.loc) + if(D.stat!=2) + var/bdrain = rand(1,25) + D << "\red You feel weakened." + D.take_overall_damage(bdrain, 0) + drain += bdrain + if(!drain) + return fizzle() + usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!") + usr.visible_message("\red Blood flows from the rune into [usr]!", \ + "\red The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.", \ + "\red You hear a liquid flowing.") + var/mob/living/user = usr + if(user.bhunger) + user.bhunger = max(user.bhunger-2*drain,0) + if(drain>=50) + user.visible_message("\red [user]'s eyes give off eerie red glow!", \ + "\red ...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.", \ + "\red You hear a heartbeat.") + user.bhunger += drain + src = user + spawn() + for (,user.bhunger>0,user.bhunger--) + sleep(50) + user.take_overall_damage(3, 0) + return + user.heal_organ_damage(drain%5, 0) + drain-=drain%5 + for (,drain>0,drain-=5) + sleep(2) + user.heal_organ_damage(5, 0) + return @@ -200,98 +199,98 @@ var/list/sacrificed = list() /////////////////////////////////////////SEVENTH RUNE - seer() - if(usr.loc==src.loc) - if(usr.seer==1) - usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.") - usr << "\red The world beyond fades from your vision." - usr.see_invisible = SEE_INVISIBLE_LIVING - usr.seer = 0 - else if(usr.see_invisible!=SEE_INVISIBLE_LIVING) - usr << "\red The world beyond flashes your eyes but disappears quickly, as if something is disrupting your vision." - usr.see_invisible = SEE_INVISIBLE_OBSERVER - usr.seer = 0 - else - usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!") - usr << "\red The world beyond opens to your eyes." - usr.see_invisible = SEE_INVISIBLE_OBSERVER - usr.seer = 1 - return - return fizzle() +/obj/effect/rune/proc/seer() + if(usr.loc==src.loc) + if(usr.seer==1) + usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.") + usr << "\red The world beyond fades from your vision." + usr.see_invisible = SEE_INVISIBLE_LIVING + usr.seer = 0 + else if(usr.see_invisible!=SEE_INVISIBLE_LIVING) + usr << "\red The world beyond flashes your eyes but disappears quickly, as if something is disrupting your vision." + usr.see_invisible = SEE_INVISIBLE_OBSERVER + usr.seer = 0 + else + usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!") + usr << "\red The world beyond opens to your eyes." + usr.see_invisible = SEE_INVISIBLE_OBSERVER + usr.seer = 1 + return + return fizzle() /////////////////////////////////////////EIGHTH RUNE - raise() - var/mob/living/carbon/human/corpse_to_raise - var/mob/living/carbon/human/body_to_sacrifice +/obj/effect/rune/proc/raise() + var/mob/living/carbon/human/corpse_to_raise + var/mob/living/carbon/human/body_to_sacrifice - var/is_sacrifice_target = 0 - for(var/mob/living/carbon/human/M in src.loc) - if(M.stat == DEAD) - if(ticker.mode.name == "cult" && M.mind == ticker.mode:sacrifice_target) + var/is_sacrifice_target = 0 + for(var/mob/living/carbon/human/M in src.loc) + if(M.stat == DEAD) + if(ticker.mode.name == "cult" && M.mind == ticker.mode:sacrifice_target) + is_sacrifice_target = 1 + else + corpse_to_raise = M + if(M.key) + M.ghostize(1) //kick them out of their body + break + if(!corpse_to_raise) + if(is_sacrifice_target) + usr << "\red The Geometer of blood wants this mortal for himself." + return fizzle() + + + is_sacrifice_target = 0 + find_sacrifice: + for(var/obj/effect/rune/R in world) + if(R.word1==cultwords["blood"] && R.word2==cultwords["join"] && R.word3==cultwords["hell"]) + for(var/mob/living/carbon/human/N in R.loc) + if(ticker.mode.name == "cult" && N.mind && N.mind == ticker.mode:sacrifice_target) is_sacrifice_target = 1 else - corpse_to_raise = M - if(M.key) - M.ghostize(1) //kick them out of their body - break - if(!corpse_to_raise) - if(is_sacrifice_target) - usr << "\red The Geometer of blood wants this mortal for himself." - return fizzle() + if(N.stat!= DEAD) + body_to_sacrifice = N + break find_sacrifice + if(!body_to_sacrifice) + if (is_sacrifice_target) + usr << "\red The Geometer of blood wants that corpse for himself." + else + usr << "\red The sacrifical corpse is not dead. You must free it from this world of illusions before it may be used." + return fizzle() - is_sacrifice_target = 0 - find_sacrifice: - for(var/obj/effect/rune/R in world) - if(R.word1==cultwords["blood"] && R.word2==cultwords["join"] && R.word3==cultwords["hell"]) - for(var/mob/living/carbon/human/N in R.loc) - if(ticker.mode.name == "cult" && N.mind && N.mind == ticker.mode:sacrifice_target) - is_sacrifice_target = 1 - else - if(N.stat!= DEAD) - body_to_sacrifice = N - break find_sacrifice + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in loc) + if(!O.client) continue + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue + ghost = O + break - if(!body_to_sacrifice) - if (is_sacrifice_target) - usr << "\red The Geometer of blood wants that corpse for himself." - else - usr << "\red The sacrifical corpse is not dead. You must free it from this world of illusions before it may be used." - return fizzle() + if(!ghost) + usr << "\red You require a restless spirit which clings to this world. Beckon their prescence with the sacred chants of Nar-Sie." + return fizzle() - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break + corpse_to_raise.revive() - if(!ghost) - usr << "\red You require a restless spirit which clings to this world. Beckon their prescence with the sacred chants of Nar-Sie." - return fizzle() - - corpse_to_raise.revive() - - corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed) - //This means, should that player leave the body, the original may re-enter - usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!") - corpse_to_raise.visible_message("\red [corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.", \ - "\red Life... I'm alive again...", \ - "\red You hear a faint, slightly familiar whisper.") - body_to_sacrifice.visible_message("\red [body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from his remains!", \ - "\red You feel as your blood boils, tearing you apart.", \ - "\red You hear a thousand voices, all crying in pain.") - body_to_sacrifice.gib() + corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed) + //This means, should that player leave the body, the original may re-enter + usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!") + corpse_to_raise.visible_message("\red [corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.", \ + "\red Life... I'm alive again...", \ + "\red You hear a faint, slightly familiar whisper.") + body_to_sacrifice.visible_message("\red [body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from his remains!", \ + "\red You feel as your blood boils, tearing you apart.", \ + "\red You hear a thousand voices, all crying in pain.") + body_to_sacrifice.gib() // if(ticker.mode.name == "cult") // ticker.mode:add_cultist(corpse_to_raise.mind) // else // ticker.mode.cult |= corpse_to_raise.mind - corpse_to_raise << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - corpse_to_raise << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - return + corpse_to_raise << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + corpse_to_raise << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + return @@ -299,111 +298,111 @@ var/list/sacrificed = list() /////////////////////////////////////////NINETH RUNE - obscure(var/rad) - var/S=0 - for(var/obj/effect/rune/R in orange(rad,src)) - if(R!=src) - R.invisibility=INVISIBILITY_OBSERVER - S=1 - if(S) - if(istype(src,/obj/effect/rune)) - usr.say("Kla[pick("'","`")]atu barada nikt'o!") - for (var/mob/V in viewers(src)) - V.show_message("\red The rune turns into gray dust, veiling the surrounding runes.", 3) - del(src) - else - usr.whisper("Kla[pick("'","`")]atu barada nikt'o!") - usr << "\red Your talisman turns into gray dust, veiling the surrounding runes." - for (var/mob/V in orange(1,src)) - if(V!=usr) - V.show_message("\red Dust emanates from [usr]'s hands for a moment.", 3) +/obj/effect/rune/proc/obscure(var/rad) + var/S=0 + for(var/obj/effect/rune/R in orange(rad,src)) + if(R!=src) + R.invisibility=INVISIBILITY_OBSERVER + S=1 + if(S) + if(istype(src,/obj/effect/rune)) + usr.say("Kla[pick("'","`")]atu barada nikt'o!") + for (var/mob/V in viewers(src)) + V.show_message("\red The rune turns into gray dust, veiling the surrounding runes.", 3) + del(src) + else + usr.whisper("Kla[pick("'","`")]atu barada nikt'o!") + usr << "\red Your talisman turns into gray dust, veiling the surrounding runes." + for (var/mob/V in orange(1,src)) + if(V!=usr) + V.show_message("\red Dust emanates from [usr]'s hands for a moment.", 3) - return - if(istype(src,/obj/effect/rune)) - return fizzle() - else - call(/obj/effect/rune/proc/fizzle)() - return + return + if(istype(src,/obj/effect/rune)) + return fizzle() + else + call(/obj/effect/rune/proc/fizzle)() + return /////////////////////////////////////////TENTH RUNE - ajourney() //some bits copypastaed from admin tools - Urist - if(usr.loc==src.loc) - var/mob/living/carbon/human/L = usr - usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!") - usr.visible_message("\red [usr]'s eyes glow blue as \he freezes in place, absolutely motionless.", \ - "\red The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...", \ - "\red You hear only complete silence for a moment.") - usr.ghostize(1) - L.ajourn = 1 - while(L) - if(L.key) - L.ajourn=0 - return - else - L.take_organ_damage(10, 0) - sleep(100) - return fizzle() +/obj/effect/rune/proc/ajourney() //some bits copypastaed from admin tools - Urist + if(usr.loc==src.loc) + var/mob/living/carbon/human/L = usr + usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!") + usr.visible_message("\red [usr]'s eyes glow blue as \he freezes in place, absolutely motionless.", \ + "\red The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...", \ + "\red You hear only complete silence for a moment.") + usr.ghostize(1) + L.ajourn = 1 + while(L) + if(L.key) + L.ajourn=0 + return + else + L.take_organ_damage(10, 0) + sleep(100) + return fizzle() /////////////////////////////////////////ELEVENTH RUNE - manifest() - var/obj/effect/rune/this_rune = src - src = null - if(usr.loc!=this_rune.loc) - return this_rune.fizzle() - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in this_rune.loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break - if(!ghost) - return this_rune.fizzle() - if(jobban_isbanned(ghost, "cultist")) - return this_rune.fizzle() +/obj/effect/rune/proc/manifest() + var/obj/effect/rune/this_rune = src + src = null + if(usr.loc!=this_rune.loc) + return this_rune.fizzle() + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in this_rune.loc) + if(!O.client) continue + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue + ghost = O + break + if(!ghost) + return this_rune.fizzle() + if(jobban_isbanned(ghost, "cultist")) + return this_rune.fizzle() - usr.say("Gal'h'rfikk harfrandid mud[pick("'","`")]gib!") - var/mob/living/carbon/human/dummy/D = new(this_rune.loc) - usr.visible_message("\red A shape forms in the center of the rune. A shape of... a man.", \ - "\red A shape forms in the center of the rune. A shape of... a man.", \ - "\red You hear liquid flowing.") - D.real_name = "Unknown" - var/chose_name = 0 - for(var/obj/item/weapon/paper/P in this_rune.loc) - if(P.info) - D.real_name = copytext(P.info, findtext(P.info,">")+1, findtext(P.info,"<",2) ) - chose_name = 1 - break - if(!chose_name) - D.real_name = "[pick(first_names_male)] [pick(last_names)]" - D.universal_speak = 1 - D.status_flags &= ~GODMODE + usr.say("Gal'h'rfikk harfrandid mud[pick("'","`")]gib!") + var/mob/living/carbon/human/dummy/D = new(this_rune.loc) + usr.visible_message("\red A shape forms in the center of the rune. A shape of... a man.", \ + "\red A shape forms in the center of the rune. A shape of... a man.", \ + "\red You hear liquid flowing.") + D.real_name = "Unknown" + var/chose_name = 0 + for(var/obj/item/weapon/paper/P in this_rune.loc) + if(P.info) + D.real_name = copytext(P.info, findtext(P.info,">")+1, findtext(P.info,"<",2) ) + chose_name = 1 + break + if(!chose_name) + D.real_name = "[pick(first_names_male)] [pick(last_names)]" + D.universal_speak = 1 + D.status_flags &= ~GODMODE - D.key = ghost.key + D.key = ghost.key - if(ticker.mode.name == "cult") - ticker.mode:add_cultist(D.mind) - else - ticker.mode.cult+=D.mind + if(ticker.mode.name == "cult") + ticker.mode:add_cultist(D.mind) + else + ticker.mode.cult+=D.mind - D.mind.special_role = "Cultist" - D << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - D << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + D.mind.special_role = "Cultist" + D << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + D << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - var/mob/living/user = usr - while(this_rune && user && user.stat==CONSCIOUS && user.client && user.loc==this_rune.loc) - user.take_organ_damage(1, 0) - sleep(30) - if(D) - D.visible_message("\red [D] slowly dissipates into dust and bones.", \ - "\red You feel pain, as bonds formed between your soul and this homunculus break.", \ - "\red You hear faint rustle.") - D.dust() - return + var/mob/living/user = usr + while(this_rune && user && user.stat==CONSCIOUS && user.client && user.loc==this_rune.loc) + user.take_organ_damage(1, 0) + sleep(30) + if(D) + D.visible_message("\red [D] slowly dissipates into dust and bones.", \ + "\red You feel pain, as bonds formed between your soul and this homunculus break.", \ + "\red You hear faint rustle.") + D.dust() + return @@ -411,629 +410,642 @@ var/list/sacrificed = list() /////////////////////////////////////////TWELFTH RUNE - talisman()//only hide, emp, teleport, deafen, blind and tome runes can be imbued atm - var/obj/item/weapon/paper/newtalisman - var/unsuitable_newtalisman = 0 - for(var/obj/item/weapon/paper/P in src.loc) - if(!P.info) - newtalisman = P - break - else - unsuitable_newtalisman = 1 - if (!newtalisman) - if (unsuitable_newtalisman) - usr << "\red The blank is tainted. It is unsuitable." - return fizzle() +/obj/effect/rune/proc/talisman()//only hide, emp, teleport, deafen, blind and tome runes can be imbued atm + var/obj/item/weapon/paper/newtalisman + var/unsuitable_newtalisman = 0 + for(var/obj/item/weapon/paper/P in src.loc) + if(!P.info) + newtalisman = P + break + else + unsuitable_newtalisman = 1 + if (!newtalisman) + if (unsuitable_newtalisman) + usr << "\red The blank is tainted. It is unsuitable." + return fizzle() - var/obj/effect/rune/imbued_from - var/obj/item/weapon/paper/talisman/T - for(var/obj/effect/rune/R in orange(1,src)) - if(R==src) - continue - if(R.word1==cultwords["travel"] && R.word2==cultwords["self"]) //teleport - T = new(src.loc) - T.imbue = "[R.word3]" - T.info = "[R.word3]" - imbued_from = R - break - if(R.word1==cultwords["see"] && R.word2==cultwords["blood"] && R.word3==cultwords["hell"]) //tome - T = new(src.loc) - T.imbue = "newtome" - imbued_from = R - break - if(R.word1==cultwords["destroy"] && R.word2==cultwords["see"] && R.word3==cultwords["technology"]) //emp - T = new(src.loc) - T.imbue = "emp" - imbued_from = R - break - if(R.word1==cultwords["blood"] && R.word2==cultwords["see"] && R.word3==cultwords["destroy"]) //conceal - T = new(src.loc) - T.imbue = "conceal" - imbued_from = R - break - if(R.word1==cultwords["hell"] && R.word2==cultwords["destroy"] && R.word3==cultwords["other"]) //armor - T = new(src.loc) - T.imbue = "armor" - imbued_from = R - break - if(R.word1==cultwords["blood"] && R.word2==cultwords["see"] && R.word3==cultwords["hide"]) //reveal - T = new(src.loc) - T.imbue = "revealrunes" - imbued_from = R - break - if(R.word1==cultwords["hide"] && R.word2==cultwords["other"] && R.word3==cultwords["see"]) //deafen - T = new(src.loc) - T.imbue = "deafen" - imbued_from = R - break - if(R.word1==cultwords["destroy"] && R.word2==cultwords["see"] && R.word3==cultwords["other"]) //blind - T = new(src.loc) - T.imbue = "blind" - imbued_from = R - break - if(R.word1==cultwords["self"] && R.word2==cultwords["other"] && R.word3==cultwords["technology"]) //communicat - T = new(src.loc) - T.imbue = "communicate" - imbued_from = R - break - if(R.word1==cultwords["join"] && R.word2==cultwords["hide"] && R.word3==cultwords["technology"]) //communicat - T = new(src.loc) - T.imbue = "runestun" - imbued_from = R - break - if (imbued_from) - for (var/mob/V in viewers(src)) - V.show_message("\red The runes turn into dust, which then forms into an arcane image on the paper.", 3) - usr.say("H'drak v[pick("'","`")]loso, mir'kanas verbot!") - del(imbued_from) - del(newtalisman) - else - return fizzle() + var/obj/effect/rune/imbued_from + var/obj/item/weapon/paper/talisman/T + for(var/obj/effect/rune/R in orange(1,src)) + if(R==src) + continue + if(R.word1==cultwords["travel"] && R.word2==cultwords["self"]) //teleport + T = new(src.loc) + T.imbue = "[R.word3]" + T.info = "[R.word3]" + imbued_from = R + break + if(R.word1==cultwords["see"] && R.word2==cultwords["blood"] && R.word3==cultwords["hell"]) //tome + T = new(src.loc) + T.imbue = "newtome" + imbued_from = R + break + if(R.word1==cultwords["destroy"] && R.word2==cultwords["see"] && R.word3==cultwords["technology"]) //emp + T = new(src.loc) + T.imbue = "emp" + imbued_from = R + break + if(R.word1==cultwords["blood"] && R.word2==cultwords["see"] && R.word3==cultwords["destroy"]) //conceal + T = new(src.loc) + T.imbue = "conceal" + imbued_from = R + break + if(R.word1==cultwords["hell"] && R.word2==cultwords["destroy"] && R.word3==cultwords["other"]) //armor + T = new(src.loc) + T.imbue = "armor" + imbued_from = R + break + if(R.word1==cultwords["blood"] && R.word2==cultwords["see"] && R.word3==cultwords["hide"]) //reveal + T = new(src.loc) + T.imbue = "revealrunes" + imbued_from = R + break + if(R.word1==cultwords["hide"] && R.word2==cultwords["other"] && R.word3==cultwords["see"]) //deafen + T = new(src.loc) + T.imbue = "deafen" + imbued_from = R + break + if(R.word1==cultwords["destroy"] && R.word2==cultwords["see"] && R.word3==cultwords["other"]) //blind + T = new(src.loc) + T.imbue = "blind" + imbued_from = R + break + if(R.word1==cultwords["self"] && R.word2==cultwords["other"] && R.word3==cultwords["technology"]) //communicat + T = new(src.loc) + T.imbue = "communicate" + imbued_from = R + break + if(R.word1==cultwords["join"] && R.word2==cultwords["hide"] && R.word3==cultwords["technology"]) //communicat + T = new(src.loc) + T.imbue = "runestun" + imbued_from = R + break + if (imbued_from) + for (var/mob/V in viewers(src)) + V.show_message("\red The runes turn into dust, which then forms into an arcane image on the paper.", 3) + usr.say("H'drak v[pick("'","`")]loso, mir'kanas verbot!") + del(imbued_from) + del(newtalisman) + else + return fizzle() /////////////////////////////////////////THIRTEENTH RUNE - mend() - var/mob/living/user = usr - src = null - user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!") - user.take_overall_damage(200, 0) - runedec+=10 - user.visible_message("\red [user] keels over dead, his blood glowing blue as it escapes his body and dissipates into thin air.", \ - "\red In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.", \ - "\red You hear faint rustle.") - for(,user.stat==2) - sleep(600) - if (!user) - return - runedec-=10 +/obj/effect/rune/proc/mend() + var/mob/living/user = usr + src = null + user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!") + user.take_overall_damage(200, 0) + runedec+=10 + user.visible_message("\red [user] keels over dead, his blood glowing blue as it escapes his body and dissipates into thin air.", \ + "\red In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.", \ + "\red You hear faint rustle.") + for(,user.stat==2) + sleep(600) + if (!user) return + runedec-=10 + return /////////////////////////////////////////FOURTEETH RUNE - // returns 0 if the rune is not used. returns 1 if the rune is used. - communicate() - . = 1 // Default output is 1. If the rune is deleted it will return 1 - var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input) - if (istype(src)) - fizzle() - return 0 - else - return 0 - if(istype(src,/obj/effect/rune)) - usr.say("O bidai nabora se[pick("'","`")]sma!") - else - usr.whisper("O bidai nabora se[pick("'","`")]sma!") +// returns 0 if the rune is not used. returns 1 if the rune is used. +/obj/effect/rune/proc/communicate() + . = 1 // Default output is 1. If the rune is deleted it will return 1 + var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") + if(!input) + if (istype(src)) + fizzle() + return 0 + else + return 0 - if(istype(src,/obj/effect/rune)) - usr.say("[input]") - else - usr.whisper("[input]") - for(var/datum/mind/H in ticker.mode.cult) - if (H.current) - H.current << "\red \b [input]" - del(src) - return 1 + var/obj/cult_viewpoint/vp = getCultViewpoint(usr) + if (!vp) + return 0 + + var/displayName = vp.get_display_name() + var/cultName = vp.get_cult_name() + + if(istype(src,/obj/effect/rune)) + usr.say("O bidai nabora se[pick("'","`")]sma!") + else + usr.whisper("O bidai nabora se[pick("'","`")]sma!") + + if(istype(src,/obj/effect/rune)) + usr.say("[input]") + else + usr.whisper("[input]") + + for(var/datum/mind/H in ticker.mode.cult) + if (H.current) + H.current << "[cultName]: [input]" + + for(var/mob/spirit/spirit in spirits) + spirit << "[displayName]: [input]" + + del(src) + return 1 /////////////////////////////////////////FIFTEENTH RUNE - sacrifice() - var/list/mob/living/carbon/human/cultsinrange = list() - var/list/mob/living/carbon/human/victims = list() - for(var/mob/living/carbon/human/V in src.loc)//Checks for non-cultist humans to sacrifice - if(ishuman(V)) - if(!(iscultist(V))) - victims += V//Checks for cult status and mob type - for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards - if(istype(I,/obj/item/brain)) - var/obj/item/brain/B = I - victims += B.brainmob - else if(istype(I,/obj/item/device/mmi)) - var/obj/item/device/mmi/B = I - victims += B.brainmob - else if(istype(I,/obj/item/device/aicard)) - for(var/mob/living/silicon/ai/A in I) - victims += A - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - cultsinrange += C - C.say("Barhah hra zar[pick("'","`")]garis!") - for(var/mob/H in victims) - if (ticker.mode.name == "cult") - if(H.mind == ticker.mode:sacrifice_target) - if(cultsinrange.len >= 3) - sacrificed += H.mind - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." - else - usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." +/obj/effect/rune/proc/sacrifice() + var/list/mob/living/carbon/human/cultsinrange = list() + var/list/mob/living/carbon/human/victims = list() + for(var/mob/living/carbon/human/V in src.loc)//Checks for non-cultist humans to sacrifice + if(ishuman(V)) + if(!(iscultist(V))) + victims += V//Checks for cult status and mob type + for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards + if(istype(I,/obj/item/brain)) + var/obj/item/brain/B = I + victims += B.brainmob + else if(istype(I,/obj/item/device/mmi)) + var/obj/item/device/mmi/B = I + victims += B.brainmob + else if(istype(I,/obj/item/device/aicard)) + for(var/mob/living/silicon/ai/A in I) + victims += A + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + cultsinrange += C + C.say("Barhah hra zar[pick("'","`")]garis!") + for(var/mob/H in victims) + if (ticker.mode.name == "cult") + if(H.mind == ticker.mode:sacrifice_target) + if(cultsinrange.len >= 3) + sacrificed += H.mind + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining else - if(cultsinrange.len >= 3) - if(H.stat !=2) - if(prob(80)) - usr << "\red The Geometer of Blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, this soul was not enough to gain His favor." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - else - if(prob(40)) - usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere dead body is not enough to satisfy Him." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - else - if(H.stat !=2) - usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." - else - if(prob(40)) - usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere dead body is not enough to satisfy Him." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() + H.gib() + usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." else - if(cultsinrange.len >= 3) - if(H.stat !=2) - if(prob(80)) - usr << "\red The Geometer of Blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, this soul was not enough to gain His favor." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - else - if(prob(40)) - usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere dead body is not enough to satisfy Him." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - else - if(H.stat !=2) - usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." - else - if(prob(40)) - usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere dead body is not enough to satisfy Him." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - for(var/mob/living/carbon/monkey/M in src.loc) - if (ticker.mode.name == "cult") - if(M.mind == ticker.mode:sacrifice_target) - if(cultsinrange.len >= 3) - sacrificed += M.mind - usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." - else - usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." - continue - else - if(prob(20)) - usr << "\red The Geometer of Blood accepts your meager sacrifice." + usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." + else + if(cultsinrange.len >= 3) + if(H.stat !=2) + if(prob(80)) + usr << "\red The Geometer of Blood accepts this sacrifice." ticker.mode:grant_runeword(usr) else usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere monkey is not enough to satisfy Him." + usr << "\red However, this soul was not enough to gain His favor." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() else - usr << "\red The Geometer of Blood accepts your meager sacrifice." - if(prob(20)) - ticker.mode.grant_runeword(usr) - M.gib() -/* for(var/mob/living/carbon/alien/A) - for(var/mob/K in cultsinrange) - K.say("Barhah hra zar'garis!") - A.dust() /// A.gib() doesnt work for some reason, and dust() leaves that skull and bones thingy which we dont really need. - if (ticker.mode.name == "cult") - if(prob(75)) - usr << "\red The Geometer of Blood accepts your exotic sacrifice." + if(H.stat !=2) + usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." + else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + else + if(cultsinrange.len >= 3) + if(H.stat !=2) + if(prob(80)) + usr << "\red The Geometer of Blood accepts this sacrifice." ticker.mode:grant_runeword(usr) else - usr << "\red The Geometer of Blood accepts your exotic sacrifice." - usr << "\red However, this alien is not enough to gain His favor." + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, this soul was not enough to gain His favor." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() else - usr << "\red The Geometer of Blood accepts your exotic sacrifice." - return - return fizzle() */ + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + else + if(H.stat !=2) + usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." + else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + for(var/mob/living/carbon/monkey/M in src.loc) + if (ticker.mode.name == "cult") + if(M.mind == ticker.mode:sacrifice_target) + if(cultsinrange.len >= 3) + sacrificed += M.mind + usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." + else + usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." + continue + else + if(prob(20)) + usr << "\red The Geometer of Blood accepts your meager sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere monkey is not enough to satisfy Him." + else + usr << "\red The Geometer of Blood accepts your meager sacrifice." + if(prob(20)) + ticker.mode.grant_runeword(usr) + M.gib() +/* for(var/mob/living/carbon/alien/A) + for(var/mob/K in cultsinrange) + K.say("Barhah hra zar'garis!") + A.dust() /// A.gib() doesnt work for some reason, and dust() leaves that skull and bones thingy which we dont really need. + if (ticker.mode.name == "cult") + if(prob(75)) + usr << "\red The Geometer of Blood accepts your exotic sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of Blood accepts your exotic sacrifice." + usr << "\red However, this alien is not enough to gain His favor." + else + usr << "\red The Geometer of Blood accepts your exotic sacrifice." + return + return fizzle() */ /////////////////////////////////////////SIXTEENTH RUNE - revealrunes(var/obj/W as obj) - var/go=0 - var/rad - var/S=0 - if(istype(W,/obj/effect/rune)) - rad = 6 - go = 1 - if (istype(W,/obj/item/weapon/paper/talisman)) - rad = 4 - go = 1 - if (istype(W,/obj/item/weapon/nullrod)) - rad = 1 - go = 1 - if(go) - for(var/obj/effect/rune/R in orange(rad,src)) - if(R!=src) - R:visibility=15 - S=1 - if(S) - if(istype(W,/obj/item/weapon/nullrod)) - usr << "\red Arcane markings suddenly glow from underneath a thin layer of dust!" - return - if(istype(W,/obj/effect/rune)) - usr.say("Nikt[pick("'","`")]o barada kla'atu!") - for (var/mob/V in viewers(src)) - V.show_message("\red The rune turns into red dust, reveaing the surrounding runes.", 3) - del(src) - return - if(istype(W,/obj/item/weapon/paper/talisman)) - usr.whisper("Nikt[pick("'","`")]o barada kla'atu!") - usr << "\red Your talisman turns into red dust, revealing the surrounding runes." - for (var/mob/V in orange(1,usr.loc)) - if(V!=usr) - V.show_message("\red Red dust emanates from [usr]'s hands for a moment.", 3) - return - return - if(istype(W,/obj/effect/rune)) - return fizzle() - if(istype(W,/obj/item/weapon/paper/talisman)) - call(/obj/effect/rune/proc/fizzle)() - return +/obj/effect/rune/proc/revealrunes(var/obj/W as obj) + var/go=0 + var/rad + var/S=0 + if(istype(W,/obj/effect/rune)) + rad = 6 + go = 1 + if (istype(W,/obj/item/weapon/paper/talisman)) + rad = 4 + go = 1 + if (istype(W,/obj/item/weapon/nullrod)) + rad = 1 + go = 1 + if(go) + for(var/obj/effect/rune/R in orange(rad,src)) + if(R!=src) + R:visibility=15 + S=1 + if(S) + if(istype(W,/obj/item/weapon/nullrod)) + usr << "\red Arcane markings suddenly glow from underneath a thin layer of dust!" + return + if(istype(W,/obj/effect/rune)) + usr.say("Nikt[pick("'","`")]o barada kla'atu!") + for (var/mob/V in viewers(src)) + V.show_message("\red The rune turns into red dust, reveaing the surrounding runes.", 3) + del(src) + return + if(istype(W,/obj/item/weapon/paper/talisman)) + usr.whisper("Nikt[pick("'","`")]o barada kla'atu!") + usr << "\red Your talisman turns into red dust, revealing the surrounding runes." + for (var/mob/V in orange(1,usr.loc)) + if(V!=usr) + V.show_message("\red Red dust emanates from [usr]'s hands for a moment.", 3) + return + return + if(istype(W,/obj/effect/rune)) + return fizzle() + if(istype(W,/obj/item/weapon/paper/talisman)) + call(/obj/effect/rune/proc/fizzle)() + return /////////////////////////////////////////SEVENTEENTH RUNE - wall() - usr.say("Khari[pick("'","`")]d! Eske'te tannin!") - src.density = !src.density - var/mob/living/user = usr - user.take_organ_damage(2, 0) - if(src.density) - usr << "\red Your blood flows into the rune, and you feel that the very space over the rune thickens." - else - usr << "\red Your blood flows into the rune, and you feel as the rune releases its grasp on space." - return +/obj/effect/rune/proc/wall() + usr.say("Khari[pick("'","`")]d! Eske'te tannin!") + src.density = !src.density + var/mob/living/user = usr + user.take_organ_damage(2, 0) + if(src.density) + usr << "\red Your blood flows into the rune, and you feel that the very space over the rune thickens." + else + usr << "\red Your blood flows into the rune, and you feel as the rune releases its grasp on space." + return /////////////////////////////////////////EIGHTTEENTH RUNE - freedom() - var/mob/living/user = usr - var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living/carbon)) - cultists+=H.current - var/list/mob/living/carbon/users = new - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - users+=C - if(users.len>=3) - var/mob/living/carbon/cultist = input("Choose the one who you want to free", "Followers of Geometer") as null|anything in (cultists - users) - if(!cultist) - return fizzle() - if (cultist == user) //just to be sure. - return - if(!(cultist.buckled || \ - cultist.handcuffed || \ - istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle) || \ - (istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) || \ - (istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) || \ - (istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) \ - )) - user << "\red The [cultist] is already free." - return - cultist.buckled = null - if (cultist.handcuffed) - cultist.handcuffed.loc = cultist.loc - cultist.handcuffed = null - cultist.update_inv_handcuffed() - if (cultist.legcuffed) - cultist.legcuffed.loc = cultist.loc - cultist.legcuffed = null - cultist.update_inv_legcuffed() - if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) - cultist.u_equip(cultist.wear_mask) - if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) - cultist.loc:welded = 0 - if(istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) - cultist.loc:locked = 0 - if(istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) - cultist.loc:locked = 0 - for(var/mob/living/carbon/C in users) - user.take_overall_damage(15, 0) - C.say("Khari[pick("'","`")]d! Gual'te nikka!") - del(src) +/obj/effect/rune/proc/freedom() + var/mob/living/user = usr + var/list/mob/living/carbon/cultists = new + for(var/datum/mind/H in ticker.mode.cult) + if (istype(H.current,/mob/living/carbon)) + cultists+=H.current + var/list/mob/living/carbon/users = new + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + users+=C + if(users.len>=3) + var/mob/living/carbon/cultist = input("Choose the one who you want to free", "Followers of Geometer") as null|anything in (cultists - users) + if(!cultist) return fizzle() + if (cultist == user) //just to be sure. + return + if(!(cultist.buckled || \ + cultist.handcuffed || \ + istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle) || \ + (istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) || \ + (istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) || \ + (istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) \ + )) + user << "\red The [cultist] is already free." + return + cultist.buckled = null + if (cultist.handcuffed) + cultist.handcuffed.loc = cultist.loc + cultist.handcuffed = null + cultist.update_inv_handcuffed() + if (cultist.legcuffed) + cultist.legcuffed.loc = cultist.loc + cultist.legcuffed = null + cultist.update_inv_legcuffed() + if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) + cultist.u_equip(cultist.wear_mask) + if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) + cultist.loc:welded = 0 + if(istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) + cultist.loc:locked = 0 + if(istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) + cultist.loc:locked = 0 + for(var/mob/living/carbon/C in users) + user.take_overall_damage(15, 0) + C.say("Khari[pick("'","`")]d! Gual'te nikka!") + del(src) + return fizzle() /////////////////////////////////////////NINETEENTH RUNE - cultsummon() - var/mob/living/user = usr - var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living/carbon)) - cultists+=H.current - var/list/mob/living/carbon/users = new - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - users+=C - if(users.len>=3) - var/mob/living/carbon/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - user) - if(!cultist) - return fizzle() - if (cultist == user) //just to be sure. - return - if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet))) - user << "\red You cannot summon the [cultist], for his shackles of blood are strong" - return fizzle() - cultist.loc = src.loc - cultist.lying = 1 - cultist.regenerate_icons() - for(var/mob/living/carbon/human/C in orange(1,src)) - if(iscultist(C) && !C.stat) - C.say("N'ath reth sh'yro eth d[pick("'","`")]rekkathnor!") - C.take_overall_damage(25, 0) - user.visible_message("\red Rune disappears with a flash of red light, and in its place now a body lies.", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a body.", \ - "\red You hear a pop and smell ozone.") - del(src) +/obj/effect/rune/proc/cultsummon() + var/mob/living/user = usr + var/list/mob/living/carbon/cultists = new + for(var/datum/mind/H in ticker.mode.cult) + if (istype(H.current,/mob/living/carbon)) + cultists+=H.current + var/list/mob/living/carbon/users = new + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + users+=C + if(users.len>=3) + var/mob/living/carbon/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - user) + if(!cultist) return fizzle() + if (cultist == user) //just to be sure. + return + if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet))) + user << "\red You cannot summon the [cultist], for his shackles of blood are strong" + return fizzle() + cultist.loc = src.loc + cultist.lying = 1 + cultist.regenerate_icons() + for(var/mob/living/carbon/human/C in orange(1,src)) + if(iscultist(C) && !C.stat) + C.say("N'ath reth sh'yro eth d[pick("'","`")]rekkathnor!") + C.take_overall_damage(25, 0) + user.visible_message("\red Rune disappears with a flash of red light, and in its place now a body lies.", \ + "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a body.", \ + "\red You hear a pop and smell ozone.") + del(src) + return fizzle() /////////////////////////////////////////TWENTIETH RUNES - deafen() - if(istype(src,/obj/effect/rune)) - var/affected = 0 - for(var/mob/living/carbon/C in range(7,src)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.ear_deaf += 50 - C.show_message("\red The world around you suddenly becomes quiet.", 3) - affected++ - if(prob(1)) - C.sdisabilities |= DEAF - if(affected) - usr.say("Sti[pick("'","`")] kaliedir!") - usr << "\red The world becomes quiet as the deafening rune dissipates into fine dust." - del(src) - else - return fizzle() - else - var/affected = 0 - for(var/mob/living/carbon/C in range(7,usr)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.ear_deaf += 30 - //talismans is weaker. - C.show_message("\red The world around you suddenly becomes quiet.", 3) - affected++ - if(affected) - usr.whisper("Sti[pick("'","`")] kaliedir!") - usr << "\red Your talisman turns into gray dust, deafening everyone around." - for (var/mob/V in orange(1,src)) - if(!(iscultist(V))) - V.show_message("\red Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..", 3) - return +/obj/effect/rune/proc/deafen() + if(istype(src,/obj/effect/rune)) + var/affected = 0 + for(var/mob/living/carbon/C in range(7,src)) + if (iscultist(C)) + continue + var/obj/item/weapon/nullrod/N = locate() in C + if(N) + continue + C.ear_deaf += 50 + C.show_message("\red The world around you suddenly becomes quiet.", 3) + affected++ + if(prob(1)) + C.sdisabilities |= DEAF + if(affected) + usr.say("Sti[pick("'","`")] kaliedir!") + usr << "\red The world becomes quiet as the deafening rune dissipates into fine dust." + del(src) + else + return fizzle() + else + var/affected = 0 + for(var/mob/living/carbon/C in range(7,usr)) + if (iscultist(C)) + continue + var/obj/item/weapon/nullrod/N = locate() in C + if(N) + continue + C.ear_deaf += 30 + //talismans is weaker. + C.show_message("\red The world around you suddenly becomes quiet.", 3) + affected++ + if(affected) + usr.whisper("Sti[pick("'","`")] kaliedir!") + usr << "\red Your talisman turns into gray dust, deafening everyone around." + for (var/mob/V in orange(1,src)) + if(!(iscultist(V))) + V.show_message("\red Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..", 3) + return - blind() - if(istype(src,/obj/effect/rune)) - var/affected = 0 - for(var/mob/living/carbon/C in viewers(src)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.eye_blurry += 50 - C.eye_blind += 20 - if(prob(5)) - C.disabilities |= NEARSIGHTED - if(prob(10)) - C.sdisabilities |= BLIND - C.show_message("\red Suddenly you see red flash that blinds you.", 3) - affected++ - if(affected) - usr.say("Sti[pick("'","`")] kaliesin!") - usr << "\red The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust." - del(src) - else - return fizzle() - else - var/affected = 0 - for(var/mob/living/carbon/C in view(2,usr)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.eye_blurry += 30 - C.eye_blind += 10 - //talismans is weaker. - affected++ - C.show_message("\red You feel a sharp pain in your eyes, and the world disappears into darkness..", 3) - if(affected) - usr.whisper("Sti[pick("'","`")] kaliesin!") - usr << "\red Your talisman turns into gray dust, blinding those who not follow the Nar-Sie." - return +/obj/effect/rune/proc/blind() + if(istype(src,/obj/effect/rune)) + var/affected = 0 + for(var/mob/living/carbon/C in viewers(src)) + if (iscultist(C)) + continue + var/obj/item/weapon/nullrod/N = locate() in C + if(N) + continue + C.eye_blurry += 50 + C.eye_blind += 20 + if(prob(5)) + C.disabilities |= NEARSIGHTED + if(prob(10)) + C.sdisabilities |= BLIND + C.show_message("\red Suddenly you see red flash that blinds you.", 3) + affected++ + if(affected) + usr.say("Sti[pick("'","`")] kaliesin!") + usr << "\red The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust." + del(src) + else + return fizzle() + else + var/affected = 0 + for(var/mob/living/carbon/C in view(2,usr)) + if (iscultist(C)) + continue + var/obj/item/weapon/nullrod/N = locate() in C + if(N) + continue + C.eye_blurry += 30 + C.eye_blind += 10 + //talismans is weaker. + affected++ + C.show_message("\red You feel a sharp pain in your eyes, and the world disappears into darkness..", 3) + if(affected) + usr.whisper("Sti[pick("'","`")] kaliesin!") + usr << "\red Your talisman turns into gray dust, blinding those who not follow the Nar-Sie." + return - bloodboil() //cultists need at least one DANGEROUS rune. Even if they're all stealthy. +/obj/effect/rune/proc/bloodboil() //cultists need at least one DANGEROUS rune. Even if they're all stealthy. /* - var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living/carbon)) - cultists+=H.current + var/list/mob/living/carbon/cultists = new + for(var/datum/mind/H in ticker.mode.cult) + if (istype(H.current,/mob/living/carbon)) + cultists+=H.current */ - var/culcount = 0 //also, wording for it is old wording for obscure rune, which is now hide-see-blood. + var/culcount = 0 //also, wording for it is old wording for obscure rune, which is now hide-see-blood. // var/list/cultboil = list(cultists-usr) //and for this words are destroy-see-blood. - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - culcount++ - if(culcount>=3) - for(var/mob/living/carbon/M in viewers(usr)) - if(iscultist(M)) - continue - var/obj/item/weapon/nullrod/N = locate() in M - if(N) - continue - M.take_overall_damage(51,51) - M << "\red Your blood boils!" - if(prob(5)) - spawn(5) - M.gib() - for(var/obj/effect/rune/R in view(src)) - if(prob(10)) - explosion(R.loc, -1, 0, 1, 5) - for(var/mob/living/carbon/human/C in orange(1,src)) - if(iscultist(C) && !C.stat) - C.say("Dedo ol[pick("'","`")]btoh!") - C.take_overall_damage(15, 0) - del(src) - else - return fizzle() - return + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + culcount++ + if(culcount>=3) + for(var/mob/living/carbon/M in viewers(usr)) + if(iscultist(M)) + continue + var/obj/item/weapon/nullrod/N = locate() in M + if(N) + continue + M.take_overall_damage(51,51) + M << "\red Your blood boils!" + if(prob(5)) + spawn(5) + M.gib() + for(var/obj/effect/rune/R in view(src)) + if(prob(10)) + explosion(R.loc, -1, 0, 1, 5) + for(var/mob/living/carbon/human/C in orange(1,src)) + if(iscultist(C) && !C.stat) + C.say("Dedo ol[pick("'","`")]btoh!") + C.take_overall_damage(15, 0) + del(src) + else + return fizzle() + return // WIP rune, I'll wait for Rastaf0 to add limited blood. - burningblood() - var/culcount = 0 - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - culcount++ - if(culcount >= 5) - for(var/obj/effect/rune/R in world) - if(R.blood_DNA == src.blood_DNA) - for(var/mob/living/M in orange(2,R)) - M.take_overall_damage(0,15) - if (R.invisibility>M.see_invisible) - M << "\red Aargh it burns!" - else - M << "\red Rune suddenly ignites, burning you!" - var/turf/T = get_turf(R) - T.hotspot_expose(700,125) - for(var/obj/effect/decal/cleanable/blood/B in world) - if(B.blood_DNA == src.blood_DNA) - for(var/mob/living/M in orange(1,B)) - M.take_overall_damage(0,5) - M << "\red Blood suddenly ignites, burning you!" - var/turf/T = get_turf(B) - T.hotspot_expose(700,125) - del(B) - del(src) +/obj/effect/rune/proc/burningblood() + var/culcount = 0 + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + culcount++ + if(culcount >= 5) + for(var/obj/effect/rune/R in world) + if(R.blood_DNA == src.blood_DNA) + for(var/mob/living/M in orange(2,R)) + M.take_overall_damage(0,15) + if (R.invisibility>M.see_invisible) + M << "\red Aargh it burns!" + else + M << "\red Rune suddenly ignites, burning you!" + var/turf/T = get_turf(R) + T.hotspot_expose(700,125) + for(var/obj/effect/decal/cleanable/blood/B in world) + if(B.blood_DNA == src.blood_DNA) + for(var/mob/living/M in orange(1,B)) + M.take_overall_damage(0,5) + M << "\red Blood suddenly ignites, burning you!" + var/turf/T = get_turf(B) + T.hotspot_expose(700,125) + del(B) + del(src) ////////// Rune 24 (counting burningblood, which kinda doesnt work yet.) - runestun(var/mob/living/T as mob) - if(istype(src,/obj/effect/rune)) ///When invoked as rune, flash and stun everyone around. - usr.say("Fuu ma[pick("'","`")]jin!") - for(var/mob/living/L in viewers(src)) +/obj/effect/rune/proc/runestun(var/mob/living/T as mob) + if(istype(src,/obj/effect/rune)) ///When invoked as rune, flash and stun everyone around. + usr.say("Fuu ma[pick("'","`")]jin!") + for(var/mob/living/L in viewers(src)) - if(iscarbon(L)) - var/mob/living/carbon/C = L - flick("e_flash", C.flash) - if(C.stuttering < 1 && (!(HULK in C.mutations))) - C.stuttering = 1 - C.Weaken(1) - C.Stun(1) - C.show_message("\red The rune explodes in a bright flash.", 3) + if(iscarbon(L)) + var/mob/living/carbon/C = L + flick("e_flash", C.flash) + if(C.stuttering < 1 && (!(HULK in C.mutations))) + C.stuttering = 1 + C.Weaken(1) + C.Stun(1) + C.show_message("\red The rune explodes in a bright flash.", 3) - else if(issilicon(L)) - var/mob/living/silicon/S = L - S.Weaken(5) - S.show_message("\red BZZZT... The rune has exploded in a bright flash.", 3) - del(src) - else ///When invoked as talisman, stun and mute the target mob. - usr.say("Dream sign ''Evil sealing talisman'[pick("'","`")]!") - var/obj/item/weapon/nullrod/N = locate() in T - if(N) - for(var/mob/O in viewers(T, null)) - O.show_message(text("\red [] invokes a talisman at [], but they are unaffected!", usr, T), 1) - else - for(var/mob/O in viewers(T, null)) - O.show_message(text("\red [] invokes a talisman at []", usr, T), 1) + else if(issilicon(L)) + var/mob/living/silicon/S = L + S.Weaken(5) + S.show_message("\red BZZZT... The rune has exploded in a bright flash.", 3) + del(src) + else ///When invoked as talisman, stun and mute the target mob. + usr.say("Dream sign ''Evil sealing talisman'[pick("'","`")]!") + var/obj/item/weapon/nullrod/N = locate() in T + if(N) + for(var/mob/O in viewers(T, null)) + O.show_message(text("\red [] invokes a talisman at [], but they are unaffected!", usr, T), 1) + else + for(var/mob/O in viewers(T, null)) + O.show_message(text("\red [] invokes a talisman at []", usr, T), 1) - if(issilicon(T)) - T.Weaken(15) + if(issilicon(T)) + T.Weaken(15) - else if(iscarbon(T)) - var/mob/living/carbon/C = T - flick("e_flash", C.flash) - if (!(HULK in C.mutations)) - C.silent += 15 - C.Weaken(25) - C.Stun(25) - return + else if(iscarbon(T)) + var/mob/living/carbon/C = T + flick("e_flash", C.flash) + if (!(HULK in C.mutations)) + C.silent += 15 + C.Weaken(25) + C.Stun(25) + return /////////////////////////////////////////TWENTY-FIFTH RUNE - armor() - var/mob/living/carbon/human/user = usr - if(istype(src,/obj/effect/rune)) - usr.say("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") - else - usr.whisper("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") - usr.visible_message("\red The rune disappears with a flash of red light, and a set of armor appears on [usr]...", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of armor.") +/obj/effect/rune/proc/armor() + var/mob/living/carbon/human/user = usr + if(istype(src,/obj/effect/rune)) + usr.say("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") + else + usr.whisper("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") + usr.visible_message("\red The rune disappears with a flash of red light, and a set of armor appears on [usr]...", \ + "\red You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of armor.") - user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head) - user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) - user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) - user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) - //the above update their overlay icons cache but do not call update_icons() - //the below calls update_icons() at the end, which will update overlay icons by using the (now updated) cache - user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) //put in hands or on floor + user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head) + user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) + user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) + user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) + //the above update their overlay icons cache but do not call update_icons() + //the below calls update_icons() at the end, which will update overlay icons by using the (now updated) cache + user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) //put in hands or on floor - del(src) - return + del(src) + return diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index d3f276abe0..2d86981ebd 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -262,6 +262,8 @@ /obj/machinery/door/proc/requiresID() return 1 +/* + /obj/machinery/door/proc/update_nearby_tiles(need_rebuild) if(!air_master) return 0 @@ -272,6 +274,8 @@ return 1 +*/ + /obj/machinery/door/proc/update_heat_protection(var/turf/simulated/source) if(istype(source)) if(src.density && (src.opacity || src.heat_proof)) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 056ad2d932..5664ff20d8 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -108,6 +108,7 @@ var/global/floorIsLava = 0 body += "Is an AI " else if(ishuman(M)) body += {"Make AI | + Make Mask | Make Robot | Make Alien | Make slime diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index a95b9d625e..813a0bfbd7 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1174,6 +1174,15 @@ message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(H)]!", 1) log_admin("[key_name(usr)] AIized [key_name(H)]") H.AIize() + + + else if(href_list["makemask"]) + if(!check_rights(R_SPAWN)) return + var/mob/currentMob = locate(href_list["makemask"]) + message_admins("\red Admin [key_name_admin(usr)] made [key_name_admin(currentMob)] into a Mask of Nar'Sie!", 1) + log_admin("[key_name(usr)] made [key_name(currentMob)] into a Mask of Nar'Sie!") + currentMob.make_into_mask(0,0) + else if(href_list["makealien"]) if(!check_rights(R_SPAWN)) return diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 95ebdf2011..bd7d4fe3a8 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -58,9 +58,10 @@ var/datum/organ/external/head = get_organ("head") var/mob/living/simple_animal/borer/B - for(var/I in head.implants) - if(istype(I,/mob/living/simple_animal/borer)) - B = I + if(istype(head)) + for(var/I in head.implants) + if(istype(I,/mob/living/simple_animal/borer)) + B = I if(B) if(!B.ckey && ckey && B.controlling) B.ckey = ckey diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index ddfd7d1606..828b952ece 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -327,6 +327,7 @@ return /mob/living/Move(a, b, flag) + if (buckled) return diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index 8264f705a1..d857856b7f 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -1,168 +1,14 @@ /datum/visibility_network/cameras ChunkType = /datum/visibility_chunk/camera +/datum/visibility_network/cameras/getViewpointFromMob(var/mob/currentMob) + var/mob/living/silicon/robot/currentRobot=currentMob + if(currentRobot) + return currentRobot.camera + return FALSE + /datum/visibility_network/cameras/validViewpoint(var/viewpoint) var/obj/machinery/camera/c = viewpoint if (!c) return FALSE - return c.can_use() - - - - - - - - - -/* -// CAMERA NET -// -// The datum containing all the chunks. - -var/datum/cameranet/cameranet = new() - -/datum/cameranet - // The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). - var/list/cameras = list() - // The chunks of the map, mapping the areas that the cameras can see. - var/list/chunks = list() - var/ready = 0 - -// Checks if a chunk has been Generated in x, y, z. -/datum/cameranet/proc/chunkGenerated(x, y, z) - x &= ~0xf - y &= ~0xf - var/key = "[x],[y],[z]" - return (chunks[key]) - -// Returns the chunk in the x, y, z. -// If there is no chunk, it creates a new chunk and returns that. -/datum/cameranet/proc/getCameraChunk(x, y, z) - x &= ~0xf - y &= ~0xf - var/key = "[x],[y],[z]" - if(!chunks[key]) - chunks[key] = new /datum/camerachunk(null, x, y, z) - - return chunks[key] - -// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. - -/datum/cameranet/proc/visibility(mob/aiEye/ai) - // 0xf = 15 - 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/chunk in remove) - var/datum/camerachunk/c = chunk - c.remove(ai) - - for(var/chunk in add) - var/datum/camerachunk/c = chunk - c.add(ai) - -// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. - -/datum/cameranet/proc/updateVisibility(atom/A, var/opacity_check = 1) - - if(!ticker || (opacity_check && !A.opacity)) - return - majorChunkChange(A, 2) - -/datum/cameranet/proc/updateChunk(x, y, z) - // 0xf = 15 - if(!chunkGenerated(x, y, z)) - return - var/datum/camerachunk/chunk = getCameraChunk(x, y, z) - chunk.hasChanged() - -// Removes a camera from a chunk. - -/datum/cameranet/proc/removeCamera(obj/machinery/camera/c) - if(c.can_use()) - majorChunkChange(c, 0) - -// Add a camera to a chunk. - -/datum/cameranet/proc/addCamera(obj/machinery/camera/c) - if(c.can_use()) - majorChunkChange(c, 1) - -// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. - -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) - if(c.can_use()) - majorChunkChange(c, 1) - //else - // majorChunkChange(c, 0) - -// Never access this proc directly!!!! -// This will update the chunk and all the surrounding chunks. -// It will also add the atom to the cameras list if you set the choice to 1. -// Setting the choice to 0 will remove the camera from the chunks. -// If you want to update the chunks around an object, without adding/removing a camera, use choice 2. - -/datum/cameranet/proc/majorChunkChange(atom/c, var/choice) - // 0xf = 15 - if(!c) - return - - var/turf/T = get_turf(c) - if(T) - var/x1 = max(0, T.x - 8) & ~0xf - var/y1 = max(0, T.y - 8) & ~0xf - var/x2 = min(world.maxx, T.x + 8) & ~0xf - var/y2 = min(world.maxy, T.y + 8) & ~0xf - - //world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]" - - for(var/x = x1; x <= x2; x += 16) - for(var/y = y1; y <= y2; y += 16) - if(chunkGenerated(x, y, T.z)) - var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z) - if(choice == 0) - // Remove the camera. - chunk.cameras -= c - else if(choice == 1) - // You can't have the same camera in the list twice. - chunk.cameras |= c - chunk.hasChanged() - -// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. - -/datum/cameranet/proc/checkCameraVis(mob/living/target as mob) - - // 0xf = 15 - var/turf/position = get_turf(target) - var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) - if(chunk) - if(chunk.changed) - chunk.hasChanged(1) // Update now, no matter if it's visible or not. - if(chunk.visibleTurfs[position]) - return 1 - return 0 - - -// Debug verb for VVing the chunk that the turf is in. -/* -/turf/verb/view_chunk() - set src in world - - if(cameranet.chunkGenerated(x, y, z)) - var/datum/camerachunk/chunk = cameranet.getCameraChunk(x, y, z) - usr.client.debug_variables(chunk) -*/ - -*/ \ No newline at end of file + return c.can_use() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index da1cc370f0..89c88c1aaf 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -1,4 +1,3 @@ - /datum/visibility_chunk/camera /datum/visibility_chunk/camera/validViewpoint(var/viewpoint) @@ -21,176 +20,4 @@ /datum/visibility_chunk/camera/findNearbyViewpoints() for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z))) if(c.can_use()) - viewpoints += c -/* - -#define UPDATE_BUFFER 25 // 2.5 seconds - -// CAMERA CHUNK -// -// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. -// Allows the AI Eye to stream these chunks and know what it can and cannot see. - -/datum/camerachunk - var/list/obscuredTurfs = list() - var/list/visibleTurfs = list() - var/list/obscured = list() - var/list/cameras = list() - var/list/turfs = list() - var/list/seenby = list() - var/visible = 0 - var/changed = 0 - var/updating = 0 - var/x = 0 - var/y = 0 - var/z = 0 - -// Add an AI eye to the chunk, then update if changed. - -/datum/camerachunk/proc/add(mob/aiEye/ai) - if(!ai.ai) - return - ai.visibleCameraChunks += src - if(ai.ai.client) - ai.ai.client.images += obscured - visible++ - seenby += ai - if(changed && !updating) - update() - -// Remove an AI eye from the chunk, then update if changed. - -/datum/camerachunk/proc/remove(mob/aiEye/ai) - if(!ai.ai) - return - ai.visibleCameraChunks -= src - if(ai.ai.client) - ai.ai.client.images -= obscured - seenby -= ai - if(visible > 0) - visible-- - -// Called when a chunk has changed. I.E: A wall was deleted. - -/datum/camerachunk/proc/visibilityChanged(turf/loc) - if(!visibleTurfs[loc]) - return - hasChanged() - -// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will -// instead be flagged to update the next time an AI Eye moves near it. - -/datum/camerachunk/proc/hasChanged(var/update_now = 0) - if(visible || update_now) - if(!updating) - updating = 1 - spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once - update() - updating = 0 - else - changed = 1 - -// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. - -/datum/camerachunk/proc/update() - - set background = 1 - - var/list/newVisibleTurfs = list() - - for(var/camera in cameras) - var/obj/machinery/camera/c = camera - - if(!c) - continue - - if(!c.can_use()) - continue - - var/turf/point = locate(src.x + 8, src.y + 8, src.z) - if(get_dist(point, c) > 24) - continue - - for(var/turf/t in c.can_see()) - newVisibleTurfs[t] = t - - // Removes turf that isn't in turfs. - newVisibleTurfs &= turfs - - var/list/visAdded = newVisibleTurfs - visibleTurfs - var/list/visRemoved = visibleTurfs - newVisibleTurfs - - visibleTurfs = newVisibleTurfs - obscuredTurfs = turfs - newVisibleTurfs - - for(var/turf in visAdded) - var/turf/t = turf - if(t.obscured) - obscured -= t.obscured - for(var/eye in seenby) - var/mob/aiEye/m = eye - if(!m || !m.ai) - continue - if(m.ai.client) - m.ai.client.images -= t.obscured - - for(var/turf in visRemoved) - var/turf/t = turf - if(obscuredTurfs[t]) - if(!t.obscured) - t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) - - obscured += t.obscured - for(var/eye in seenby) - var/mob/aiEye/m = eye - if(!m || !m.ai) - seenby -= m - continue - if(m.ai.client) - m.ai.client.images += t.obscured - -// Create a new camera chunk, since the chunks are made as they are needed. - -/datum/camerachunk/New(loc, x, y, z) - - // 0xf = 15 - 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.can_use()) - 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] = t - - for(var/camera in cameras) - var/obj/machinery/camera/c = camera - if(!c) - continue - - if(!c.can_use()) - continue - - for(var/turf/t in c.can_see()) - visibleTurfs[t] = t - - // Removes turf that isn't in turfs. - visibleTurfs &= turfs - - obscuredTurfs = turfs - visibleTurfs - - for(var/turf in obscuredTurfs) - var/turf/t = turf - if(!t.obscured) - t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) - obscured += t.obscured - -#undef UPDATE_BUFFER - -*/ \ No newline at end of file + viewpoints += c \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 44081bb636..69af9a18aa 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -40,7 +40,6 @@ // It will also stream the chunk that the new loc is in. /mob/aiEye/proc/setLoc(var/T) - if(ai) if(!isturf(ai.loc)) return diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index 05aa5ef317..e88d4c28eb 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -1,23 +1,5 @@ #define BORG_CAMERA_BUFFER 30 -// ROBOT MOVEMENT - -// Update the portable camera everytime the Robot moves. -// This might be laggy, comment it out if there are problems. -/mob/living/silicon/robot/var/updating = 0 - -/mob/living/silicon/robot/Move() - var/oldLoc = src.loc - . = ..() - if(.) - if(src.camera && src.camera.network.len) - if(!updating) - updating = 1 - spawn(BORG_CAMERA_BUFFER) - if(oldLoc != src.loc) - cameraNetwork.updateViewpoint(src.camera) - updating = 0 - // CAMERA // An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not. diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 8740c4a4f9..030a3db08e 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -106,6 +106,9 @@ camera.network = list("SS13","Robots") if(isWireCut(5)) // 5 = BORG CAMERA camera.status = 0 + + // hook the robot into the camera network + addToVisibilityNetwork(cameraNetwork) initialize_components() //if(!unfinished) @@ -143,6 +146,8 @@ if(T) mmi.loc = T if(mind) mind.transfer_to(mmi.brainmob) mmi = null + // remove blown up robots from the visibility network + removeFromVisibilityNetwork(cameraNetwork) ..() /mob/living/silicon/robot/proc/pick_module() diff --git a/code/modules/mob/spirit/cultnet.dm b/code/modules/mob/spirit/cultnet.dm index 9847a80b0c..df0cd57ff5 100644 --- a/code/modules/mob/spirit/cultnet.dm +++ b/code/modules/mob/spirit/cultnet.dm @@ -1,4 +1,4 @@ -/* +/* This file contains the code necessary to do the display code for cult spirits. @@ -6,3 +6,75 @@ It reuses a lot of code from the AIEye cameraNetwork. In order to work properly, */ + +/proc/isCultRune(var/viewpoint) + var/obj/effect/rune/test_rune = viewpoint + if (test_rune) + return TRUE + return FALSE + + +/proc/isCultViewpoint(var/viewpoint) + var/obj/cult_viewpoint/vp = viewpoint + if (vp) + return TRUE + return FALSE + + +/datum/visibility_chunk/cult/validViewpoint(var/atom/viewpoint) + var/turf/point = locate(src.x + 8, src.y + 8, src.z) + if(get_dist(point, viewpoint) > 24) + return FALSE + + if (isCultRune(viewpoint) || isCultViewpoint(viewpoint)) + return viewpoint:can_use() + return FALSE + + +/datum/visibility_chunk/cult/getVisibleTurfsForViewpoint(var/viewpoint) + var/obj/effect/rune/rune = viewpoint + if (rune) + return rune.can_see() + var/obj/cult_viewpoint/cvp = viewpoint + if (cvp) + return cvp.can_see() + return null + + +/datum/visibility_chunk/cult/findNearbyViewpoints() + for(var/obj/cult_viewpoint/vp in range(16, locate(x + 8, y + 8, z))) + if(vp.can_use()) + viewpoints += vp + for(var/obj/effect/rune/rune in range(16, locate(x + 8, y + 8, z))) + viewpoints += rune + + +/datum/visibility_network/cult + ChunkType = /datum/visibility_chunk/cult + + +/datum/visibility_network/cult/validViewpoint(var/viewpoint) + if (isCultRune(viewpoint) || isCultViewpoint(viewpoint)) + return viewpoint:can_use() + return FALSE + +/datum/visibility_network/cult/getViewpointFromMob(var/mob/currentMob) + for(var/obj/cult_viewpoint/currentView in currentMob) + return currentView + return FALSE + + +/datum/visibility_interface/cult + chunk_type = /datum/visibility_chunk/cult + + +/* +RUNE JUNK +*/ + +/obj/effect/rune/proc/can_use() + return TRUE + +/obj/effect/rune/proc/can_see() + return hear(view_range, get_turf(src)) + diff --git a/code/modules/mob/spirit/mask/mask.dm b/code/modules/mob/spirit/mask/mask.dm new file mode 100644 index 0000000000..87bf07cd45 --- /dev/null +++ b/code/modules/mob/spirit/mask/mask.dm @@ -0,0 +1,171 @@ +mob/spirit/mask + + +mob/spirit/mask/New() + ..() + spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman(src) + spell_list += new /obj/effect/proc_holder/spell/aoe_turf/blood_speech(src) + + +mob/spirit/mask/verb/go_to_follower() + set category = "Mask" + set name = "Go to follower" + set desc = "Select who you would like to go too." + + var/obj/cult_viewpoint/cultist = pick_cultist() + if (cultist) + follow_cultist(cultist.owner) + src << "You start following [cultist.get_display_name()]." + + +mob/spirit/mask/verb/set_specific_urge() + set category = "Mask" + set name = "Set urge on cultist" + set desc = "Set urge on target" + + var/obj/cult_viewpoint/cultist = pick_cultist() + if (cultist) + var/newUrge = stripped_input(usr, "", "Set Urge", "") + cultist.set_urge(newUrge) + src << "You urge [cultist.owner.name] to [newUrge]." + +mob/spirit/mask/verb/set_cult_name() + set category = "Mask" + set name = "Set Cult Name" + set desc = "Grant a cultist a name." + + var/obj/cult_viewpoint/cultist = pick_cultist() + if (cultist) + var/newName = stripped_input(usr, "", "Set Cult Name", "") + if (!newName) + return + cultist.set_cult_name(newName) + src << "You grant [cultist.owner.name] the secret name of [newName]." + + +mob/spirit/mask/verb/set_global_urge() + set category = "Mask" + set name = "Set global urge" + set desc = "Set urge on the entire cult." + + var/newUrge = stripped_input(usr, "Please choose an urge.", "Set Urge", "") + for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) + viewpoint.set_urge(newUrge) + src << "You urge the entire cult to [newUrge]." + + +mob/spirit/mask/verb/set_favor_for_cultist() + set category = "Mask" + set name = "Show your favor" + set desc = "Set the favor for a cultist" + + var/obj/cult_viewpoint/cultist = pick_cultist() + if (cultist) + var/list/favor = list("Pleased", "Displeased", "Indifference") + var/emotion = input("Pick your emotion", "Mask", null, null) in favor + switch(emotion) + if("Pleased") + cultist.set_favor(1) + if("Displeased") + cultist.set_favor(-1) + if("Indifference") + cultist.set_favor(0) + + +mob/spirit/mask/proc/set_name() + var/newName = stripped_input(usr, "Please pick a name.", "Pick Name for Mask", "") + name = newName ? newName : "Mask of Nar'sie" + + +mob/spirit/mask/proc/pick_cultist() + var/list/cultists = list() + for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) + cultists[viewpoint.get_display_name()]=viewpoint + var/input = input("Please, select a cultist!", "Cult", null, null) as null|anything in cultists + var/obj/cult_viewpoint/result = cultists[input] + return result + + +// SPELLS +/obj/effect/proc_holder/spell/aoe_turf/blood_speech + name = "Speak to your Acolytes" + desc = "This spell allows you to speak to your flock." + school = "unknown evil" + charge_type = "recharge" + charge_max = 300 + clothes_req = 0 + invocation = "none" + invocation_type = "none" + range = 0 + +/obj/effect/proc_holder/spell/aoe_turf/blood_speech/cast(list/targets) + var/input = stripped_input(usr, "Please choose a message to tell your acolytes.", "Voice of Blood", "") + if(!input) + revert_cast(usr) + for(var/datum/mind/H in ticker.mode.cult) + if (H.current) + H.current << "[usr.name]: [input]" + for(var/mob/spirit/spirit in spirits) + spirit << "[usr.name]: [input]" + + +/obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman + name = "Create Talisman" + desc = "This spell conjures a talisman" + + school = "conjuration" + charge_type = "recharge" + charge_max = 300 + clothes_req = 0 + invocation = "none" + invocation_type = "none" + range = 0 + summon_type = list(/obj/item/weapon/paper/talisman) + + var/list/talismans = list( "Armor"="armor", + "Blind"="blind", + "Conceal"="conceal", + "Communicate"="communicate", + "Deafen"="deafen", + "EMP"="emp", + "Teleport"="teleport", + "Tome"="newtome", + "Reveal Runes", + "Stun"="runestun", + "Soul Stone"="soulstone", + "Construct"="construct") + + +/obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman/cast(list/targets) + + var/talisman = input("Pick a talisman type", "Talisman", null, null) as null|anything in talismans + var/imbue_value = talismans[talisman] + if (!talisman) + usr << "You choose not to create a talisman." + revert_cast(usr) + return + + switch(talisman) + + if ("Teleport") + var/target_rune = input("Pick a teleport target", "Teleport Rune", null, null) as null|anything in engwords + if (!target_rune) + usr << "You choose not to create a talisman." + revert_cast(usr) + return + summon_type = list(/obj/item/weapon/paper/talisman) + newVars = list("imbue" = "[target_rune]", "info" = "[target_rune]") + + if ("Soul Stone") + summon_type = list(/obj/item/device/soulstone) + newVars = list() + + if ("Construct") + summon_type = list(/obj/structure/constructshell) + newVars = list() + + else + summon_type = list(/obj/item/weapon/paper/talisman) + newVars = list("imbue" = "[imbue_value]") + + ..() \ No newline at end of file diff --git a/code/modules/mob/spirit/movement.dm b/code/modules/mob/spirit/movement.dm index a7b05856ff..c6e6fb3a09 100644 --- a/code/modules/mob/spirit/movement.dm +++ b/code/modules/mob/spirit/movement.dm @@ -27,10 +27,30 @@ mob/spirit/proc/Spirit_Move(direct) // if we're trying to move, we want to stop following our target follow_target = null + +/mob/spirit/proc/follow_cultist(mob/living/target as mob) + if(!istype(target)) return + var/obj/cult_viewpoint/currentView = getCultViewpoint(target) + var/mob/spirit/U = usr + + if (!currentView) + U << "As a spirit, you may only track cultists." + + U.follow_target = target + U << "Now following [currentView.get_cult_name()]." + + spawn (0) + while (U.follow_target == target) + if (U.follow_target == null) + return + U.setLoc(get_turf(target)) + sleep(10) + + mob/spirit/proc/setLoc(var/T) T = get_turf(T) loc = T - //cultnet.visibility(src) + cultNetwork.visibility(src) mob/spirit/verb/toggle_acceleration() set category = "Spirit" diff --git a/code/modules/mob/spirit/spirit.dm b/code/modules/mob/spirit/spirit.dm index d03a679c57..ce85f4175f 100644 --- a/code/modules/mob/spirit/spirit.dm +++ b/code/modules/mob/spirit/spirit.dm @@ -1,13 +1,5 @@ /* This mob type is used for entities that exist within the Cult's spirit world. They share the same visibility network and are intangible. - - -NOTES - -- make chunks generic - - subclass them for camerachunks and for cultchunks -- do the same thing with visibility networks - - cultnet and cameraNetwork etc. */ mob/spirit @@ -22,7 +14,9 @@ mob/spirit canmove = 0 blinded = 0 anchored = 1 + mouse_opacity = 0 invisibility = INVISIBILITY_SPIRIT + universal_speak = 1 // pseudo-movement values var/sprint = 10 @@ -30,13 +24,53 @@ mob/spirit var/acceleration = 1 var/follow_target = null + +mob/spirit/is_active() + if (client && client.inactivity <= 10 * 60 * 10) + return TRUE + return FALSE + + mob/spirit/New() sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF see_invisible = SEE_SPIRITS see_in_dark = 100 loc = pick(latejoin) + + // hook them to the cult visibility network + visibility_interface = new /datum/visibility_interface/cult(src) // no nameless spirits if (!name) - name = "Boogyman" \ No newline at end of file + name = "Boogyman" + + spirits+=src + + ..() + +mob/spirit/Del() + spirits-=src + ..() + + +mob/spirit/Topic(href, href_list) + world << "Spirit Topic!" + usr << "Topic: usr [usr], src [src]" + src << "Topic: usr [usr], src [src]" + + if(usr != src) + return + ..() + + usr << "Spirit Href = [href]" + for (var/tempref in href_list) + usr << "Spirit href list [tempref] = [href_list[tempref]]" + + if (href_list["track"]) + usr << "Got to tracking." + var/mob/target = locate(href_list["track"]) in mob_list + var/mob/spirit/A = locate(href_list["track2"]) in spirits + if(A && target) + A.follow_cultist(target) + return \ No newline at end of file diff --git a/code/modules/mob/spirit/viewpoint.dm b/code/modules/mob/spirit/viewpoint.dm new file mode 100644 index 0000000000..56f5b154b5 --- /dev/null +++ b/code/modules/mob/spirit/viewpoint.dm @@ -0,0 +1,195 @@ +#define FAVOR_PLEASED 1 +#define FAVOR_INDIFFERENT 0 +#define FAVOR_DISPLEASED -1 + + +var/obj/cult_viewpoint/list/cult_viewpoints = list() + + +/obj/cult_viewpoint + var/view_range = 7 + var/updating = 0 + var/mob/owner = null + var/urge = "" + var/favor = FAVOR_INDIFFERENT + var/cult_name = null + + +/obj/cult_viewpoint/New(var/mob/target) + owner = target + //src.loc = owner + owner.addToVisibilityNetwork(cultNetwork) + cultNetwork.viewpoints+=src + cultNetwork.addViewpoint(src) + cult_viewpoints+=src + //handle_missing_mask() + ..() + + +/obj/cult_viewpoint/Del() + processing_objects.Remove(src) + cultNetwork.viewpoints-=src + cultNetwork.removeViewpoint(src) + cult_viewpoints-=src + owner.removeFromVisibilityNetwork(cultNetwork) + ..() + return + + +// VERBS +/obj/cult_viewpoint/verb/check_urge() + set category = "Cult" + set desc = "Discover what your god commands of you." + set name = "Check Urge" + set src in usr + if (src.urge) + owner << "\red \b You feel the urge to [src.urge]" + else + owner << "\b You feel no supernatural compulsions." + + +/obj/cult_viewpoint/verb/reach_out() + set category = "Cult" + set desc = "Reach out for your gods presence." + set name = "Reach Out" + set src in usr + + for(var/mob/spirit/mask/currentMask in spirits) + if (currentMask.is_active()) + owner << "\red \b You feel the reassuring presence of your god." + currentMask << "[get_display_name()] has reached out to you." + return + owner << "\b You feel a chilling absence." + handle_missing_mask() + + +/obj/cult_viewpoint/verb/check_favor() + set category = "Cult" + set desc = "Check your favor with your god." + set name = "Check Favor" + set src in usr + switch(favor) + if(FAVOR_PLEASED) + owner << "\red \b You bask in your gods favor." + if(FAVOR_INDIFFERENT) + owner << "\red \b You feel nothing." + if(FAVOR_DISPLEASED) + owner << "\red \b You cringe at your gods displeasure." + +/obj/cult_viewpoint/verb/pray_to_mask() + set category = "Cult" + set desc = "Pray to your god" + set name = "Pray to Nar'Sie" + set src in usr + + var/input = stripped_input(usr, "Please choose a message to say to your god.", "Pray to Nar'Sie", "") + if(!input) + return + + owner << "You pray to Nar'Sie: [input]" + + for(var/mob/spirit/spirit in spirits) + spirit << "[get_display_name()] prays : [input]" + +// PROCS +/obj/cult_viewpoint/proc/set_favor(var/newFavor) + favor = newFavor + check_favor() + + +/obj/cult_viewpoint/proc/set_urge(var/newUrge) + if (!newUrge) + src.urge = null + src.urge = copytext(newUrge, 1, MAX_MESSAGE_LEN) + check_urge() + + +/obj/cult_viewpoint/proc/can_use() + if (owner.stat != DEAD) + return TRUE + return FALSE + + +/obj/cult_viewpoint/proc/can_see() + return hear(view_range, get_turf(owner)) + + +/obj/cult_viewpoint/proc/get_cult_name() + if (cult_name) + return cult_name + return "An Unknown Servent" + + +/obj/cult_viewpoint/proc/set_cult_name(var/newName) + if (!owner) + return FALSE + if (newName) + cult_name = newName + owner << "\red \b You have been blessed with the secret name of '[newName]'." + else + cult_name = null + owner << "\red \b Your god has taken your secret name." + + +/obj/cult_viewpoint/proc/get_display_name() + if (!owner) + return + if (cult_name) + return cult_name + return owner.name + + +/obj/cult_viewpoint/proc/become_mask() + set category = "Cult" + set name = "Become Mask" + set desc = "Sacrifice your life and become a Mask of Nar'sie." + set src in usr + + if (!active_mask()) + var/transformation_type = alert(owner.client, "You are about to become a Mask. Do you want it to be subtle or violent?", "Mask", "Subtle", "Violent") + if(!active_mask()) + if (transformation_type=="Subtle") + owner.make_into_mask(0,0) + else + owner.make_into_mask(1,1) + else + owner << "\b You cannot become a mask of Nar'Sie because a Mask already exists." + mask_has_been_found() + return + + +/obj/cult_viewpoint/proc/active_mask() + for(var/mob/spirit/mask/currentMask in spirits) + if (currentMask.is_active()) + return TRUE + return FALSE + + +/obj/cult_viewpoint/proc/handle_missing_mask() + if (active_mask()) + mask_has_been_found() + else + mask_is_missing() + + +/obj/cult_viewpoint/proc/mask_has_been_found() + for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) + if (viewpoint.verbs.Find(/obj/cult_viewpoint/proc/become_mask)) + viewpoint.verbs-=/obj/cult_viewpoint/proc/become_mask + + +/obj/cult_viewpoint/proc/mask_is_missing() + for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) + if (!viewpoint.verbs.Find(/obj/cult_viewpoint/proc/become_mask)) + viewpoint.verbs+=/obj/cult_viewpoint/proc/become_mask + + +/proc/getCultViewpoint(var/mob/currentMob) + for(var/obj/cult_viewpoint/currentView in currentMob) + return currentView + return FALSE + + +#undef FAVOR_PLEASED +#undef FAVOR_INDIFFERENT +#undef FAVOR_DISPLEASED \ No newline at end of file diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index bb5ed93e2a..e5101faf89 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -133,7 +133,71 @@ . = O del(src) + +/mob/living/carbon/human/make_into_mask(var/should_gib = 0) + for(var/t in organs) + del(t) + return ..(should_gib) + +/mob/proc/make_into_mask(var/should_gib = 0, var/should_remove_items = 0) + + if (should_gib) + var/mob/spirit/mask/new_spirit = new() + + if(mind) + new_spirit.mind = mind + new_spirit.mind.assigned_role = "Mask" + new_spirit.mind.original = new_spirit + + new_spirit.key = key + new_spirit.loc=loc + + spawn(0) + src.gib() // gib the body + + new_spirit.set_name() + + // let spirits identify cultists + if(ticker.mode) + ticker.mode.reset_cult_icons_for_spirit(new_spirit) + + return new_spirit + + else + if(should_remove_items) + for(var/obj/item/W in src) + drop_from_inventory(W) + + icon = null + invisibility = 101 + + var/mob/spirit/mask/new_spirit = new() + + if(mind) + new_spirit.mind = mind + new_spirit.mind.assigned_role = "Mask" + new_spirit.mind.original = new_spirit + + new_spirit.key = key + new_spirit.loc=loc + + spawn(0)//To prevent the proc from returning null. + src.visible_message( \ + "[src] disappears into the shadows, never to be seen again.", \ + "You disappear into the shadows, never to be seen again.", \ + "You hear strange noise, you can't quite place it.") + del(src) + + new_spirit.set_name() + + // let spirits identify cultists + if(ticker.mode) + ticker.mode.reset_cult_icons_for_spirit(new_spirit) + + return new_spirit + + //human -> robot /mob/living/carbon/human/proc/Robotize() if (monkeyizing) diff --git a/code/stylesheet.dm b/code/stylesheet.dm index fda3fb64e2..9a0b8f14cf 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -63,6 +63,7 @@ h1.alert, h2.alert {color: #000000;} .skrell {color: #00CED1;} .soghun {color: #228B22;} .vox {color: #AA00AA;} +.cultspeech {color: #B20000;} .say_quote {font-family: Georgia, Verdana, sans-serif;} .interface {color: #330033;} From 923a969eaf27bcd99d8abf191668cc4ffdef6e3a Mon Sep 17 00:00:00 2001 From: jack-fractal Date: Sun, 17 Nov 2013 16:25:20 -0500 Subject: [PATCH 04/18] - removing unnecessary planning document --- code/datums/visibility_networks/NEXT THING.txt | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 code/datums/visibility_networks/NEXT THING.txt diff --git a/code/datums/visibility_networks/NEXT THING.txt b/code/datums/visibility_networks/NEXT THING.txt deleted file mode 100644 index 0d2cd53750..0000000000 --- a/code/datums/visibility_networks/NEXT THING.txt +++ /dev/null @@ -1,7 +0,0 @@ -Next Thing To Do - -- sprites! -- follow! - - can we hide inside cultists? -- cult names! -- powers \ No newline at end of file From 3eb8d1c2b9cda319b16397961cf464d6ae946449 Mon Sep 17 00:00:00 2001 From: jack-fractal Date: Fri, 22 Nov 2013 20:09:24 -0500 Subject: [PATCH 05/18] - lots of debugging - modifying how runes are called to use reflection - adding highlander code to make sure that there can only be one mask - adding Spread Shadows spell - adding cult admin investigation log - adding mask icon --- baystation12.dme | 1 + baystation12.int | 4 +- code/datums/mind.dm | 21 +- code/game/gamemodes/cult/cult.dm | 37 +--- code/game/gamemodes/cult/ritual.dm | 226 ++++++++++------------ code/game/gamemodes/cult/runes.dm | 22 ++- code/modules/admin/admin_investigate.dm | 38 ++-- code/modules/mob/mob.dm | 11 +- code/modules/mob/new_player/new_player.dm | 4 +- code/modules/mob/spirit/mask/mask.dm | 109 ++++++++--- code/modules/mob/spirit/mask/respawn.dm | 20 ++ code/modules/mob/spirit/movement.dm | 2 + code/modules/mob/spirit/viewpoint.dm | 7 + code/modules/mob/transform_procs.dm | 72 +++---- icons/mob/spirits/mask.dmi | Bin 0 -> 972 bytes 15 files changed, 307 insertions(+), 267 deletions(-) create mode 100644 code/modules/mob/spirit/mask/respawn.dm create mode 100644 icons/mob/spirits/mask.dmi diff --git a/baystation12.dme b/baystation12.dme index f64b9f8e6b..b8631a47eb 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1031,6 +1031,7 @@ #include "code\modules\mob\spirit\spirit.dm" #include "code\modules\mob\spirit\viewpoint.dm" #include "code\modules\mob\spirit\mask\mask.dm" +#include "code\modules\mob\spirit\mask\respawn.dm" #include "code\modules\nano\_JSON.dm" #include "code\modules\nano\JSON Reader.dm" #include "code\modules\nano\JSON Writer.dm" diff --git a/baystation12.int b/baystation12.int index aefda4d8d7..ac308bf822 100644 --- a/baystation12.int +++ b/baystation12.int @@ -2,8 +2,8 @@ /* MAP_ICON_TYPE: 0 LAST_COMPILE_VERSION: 501.1217 -DIR: code code\datums code\datums\visibility_networks code\defines\obj code\game code\game\gamemodes code\game\gamemodes\cult code\game\gamemodes\malfunction code\game\machinery code\game\machinery\camera code\modules code\modules\admin code\modules\mob code\modules\mob\living code\modules\mob\living\carbon code\modules\mob\living\carbon\human -LAST_COMPILE_TIME: 1384721250 +DIR: code code\_onclick code\datums code\datums\visibility_networks code\defines\obj code\game code\game\gamemodes code\game\gamemodes\blob code\game\gamemodes\blob\blobs code\game\gamemodes\cult code\game\gamemodes\events code\game\gamemodes\malfunction code\modules code\modules\mob code\modules\mob\dead code\modules\mob\dead\observer code\modules\mob\spirit code\modules\mob\spirit\mask icons icons\mob icons\mob\spirits +LAST_COMPILE_TIME: 1385167549 AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/datums/mind.dm b/code/datums/mind.dm index d41a521ac3..01f68d3ac0 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -578,14 +578,7 @@ datum/mind switch(href_list["cult"]) if("clear") if(src in ticker.mode.cult) - ticker.mode.cult -= src - ticker.mode.update_cult_icons_removed(src) - special_role = null - var/datum/game_mode/cult/cult = ticker.mode - if (istype(cult)) - cult.memoize_cult_objectives(src) - current << "\red You have been brainwashed! You are no longer a cultist!" - memory = "" + ticker.mode.remove_cultist(src) log_admin("[key_name_admin(usr)] has de-cult'ed [current].") if("cultist") if(!(src in ticker.mode.cult)) @@ -593,18 +586,6 @@ datum/mind special_role = "Cultist" current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - /* - ticker.mode.cult += src - ticker.mode.update_cult_icons_added(src) - special_role = "Cultist" - current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." - current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - var/datum/game_mode/cult/cult = ticker.mode - if (istype(cult)) - cult.memoize_cult_objectives(src) - var/obj/cult_viewpoint/viewpoint = new(current) - viewpoint.loc = current - */ log_admin("[key_name_admin(usr)] has cult'ed [current].") if("tome") var/mob/living/carbon/human/H = current diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 401644c631..26d984641f 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -8,6 +8,7 @@ /proc/iscultist(mob/living/M as mob) return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult) + /proc/is_convertable_to_cult(datum/mind/mind) if(!istype(mind)) return 0 if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0 @@ -133,7 +134,6 @@ mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." mob.mutations.Remove(CLUMSY) - var/obj/cult_viewpoint/viewpoint = new(mob) viewpoint.loc = mob world << "Spawning viewpoint on [mob]" @@ -205,7 +205,7 @@ for(var/mob/M in viewers(cult_mind.current)) M << "[cult_mind.current] looks like they just reverted to their old faith!" - + /datum/game_mode/proc/update_all_cult_icons() spawn(0) // reset the cult @@ -322,35 +322,6 @@ for(var/mob/spirit/currentSpirit in spirits) remove_cult_icon_from_spirit(currentSpirit,cult_mind) -/* -/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind) - spawn(0) - for(var/datum/mind/cultist in cult) - if(cultist.current) - if(cultist.current.client) - var/I = image('icons/mob/mob.dmi', loc = cult_mind.current, icon_state = "cult") - cultist.current.client.images += I - if(cult_mind.current) - if(cult_mind.current.client) - var/image/J = image('icons/mob/mob.dmi', loc = cultist.current, icon_state = "cult") - cult_mind.current.client.images += J - - -/datum/game_mode/proc/update_cult_icons_removed(datum/mind/cult_mind) - spawn(0) - for(var/datum/mind/cultist in cult) - if(cultist.current) - if(cultist.current.client) - for(var/image/I in cultist.current.client.images) - if(I.icon_state == "cult" && I.loc == cult_mind.current) - del(I) - - if(cult_mind.current) - if(cult_mind.current.client) - for(var/image/I in cult_mind.current.client.images) - if(I.icon_state == "cult") - del(I) -*/ /datum/game_mode/cult/proc/get_unconvertables() var/list/ucs = list() @@ -386,6 +357,10 @@ return 1 +/atom/proc/cult_log(var/message) + investigate_log(message, "cult") + + /datum/game_mode/cult/declare_completion() if(!check_cult_victory()) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 69bd5cc42b..0686a1842b 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -1,6 +1,7 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 var/cultwords = list() +var/rune_to_english = list() var/runedec = 0 var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", "self", "see", "other", "hide") @@ -16,9 +17,12 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", /proc/runerandom() //randomizes word meaning var/list/runewords=list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri") ///"orkan" and "allaq" removed. for (var/word in engwords) - cultwords[word] = pick(runewords) + var/runeword = pick(runewords) + cultwords[word] = runeword + rune_to_english[runeword] = word runewords-=cultwords[word] + /obj/effect/rune desc = "" anchored = 1 @@ -29,7 +33,6 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", unacidable = 1 layer = TURF_LAYER - var/word1 var/word2 var/word3 @@ -62,129 +65,110 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", // self other technology - Communication rune //was other hear blood // join hide technology - stun rune. Rune color: bright pink. - New() - ..() - var/image/blood = image(loc = src) - blood.override = 1 - for(var/mob/living/silicon/ai/AI in player_list) - AI.client.images += blood - cultNetwork.viewpoints+=src - cultNetwork.addViewpoint(src) + +/obj/effect/rune/New() + ..() + var/image/blood = image(loc = src) + blood.override = 1 + for(var/mob/living/silicon/ai/AI in player_list) + AI.client.images += blood + cultNetwork.viewpoints+=src + cultNetwork.addViewpoint(src) + +/obj/effect/rune/Del() + ..() + cultNetwork.viewpoints-=src + cultNetwork.removeViewpoint(src) + +/obj/effect/rune/examine() + set src in view(2) + + if(!iscultist(usr) && !isSpirit(usr)) + usr << "A strange collection of symbols drawn in blood." + return + if(!desc) + usr << "A spell circle drawn in blood. It reads: [word1] [word2] [word3]." + else + usr << "Explosive Runes inscription in blood. It reads: [desc]." + + return + + +/obj/effect/rune/attackby(I as obj, user as mob) + if(istype(I, /obj/item/weapon/tome) && iscultist(user)) + user << "You retrace your steps, carefully undoing the lines of the rune." + del(src) + return + else if(istype(I, /obj/item/weapon/nullrod)) + user << "\blue You disrupt the vile magic with the deadening field of the null rod!" + del(src) + return + return + + +/obj/effect/rune/proc/get_word_string() + if (word1 == cultwords["travel"]) + if (word2 == cultwords["self"]) + return "teleport" + if (word2 == cultwords["other"]) + return "itemport" + return "[rune_to_english[word1]]_[rune_to_english[word2]]_[rune_to_english[word3]]" + + +/obj/effect/rune + var/list/effect_dictionary = list( "teleport"=/obj/effect/rune/proc/teleportRune, + "itemport"=/obj/effect/rune/proc/itemportRune, + "see_blood_hell"=/obj/effect/rune/proc/tomesummon, + "hell_destroy_other"=/obj/effect/rune/proc/armor, + "join_blood_self"=/obj/effect/rune/proc/convert, + "hell_join_self"=/obj/effect/rune/proc/tearreality, + "destroy_see_technology"=/obj/effect/rune/proc/empRune, + "travel_blood_self"=/obj/effect/rune/proc/drain, + "see_hell_join"=/obj/effect/rune/proc/seer, + "blood_join_hell"=/obj/effect/rune/proc/raise, + "hide_see_blood"=/obj/effect/rune/proc/obscureRune, + "hell_travel_self"=/obj/effect/rune/proc/ajourney, + "blood_see_travel"=/obj/effect/rune/proc/manifest, + "hell_technology_join"=/obj/effect/rune/proc/talisman, + "hell_blood_join"=/obj/effect/rune/proc/sacrifice, + "blood_see_hide"=/obj/effect/rune/proc/revealrunesrune, + "destroy_travel_self"=/obj/effect/rune/proc/wall, + "travel_technology_other"=/obj/effect/rune/proc/freedom, + "join_other_self"=/obj/effect/rune/proc/cultsummon, + "hide_other_see"=/obj/effect/rune/proc/deafen, + "destroy_see_other"=/obj/effect/rune/proc/blind, + "destroy_see_blood"=/obj/effect/rune/proc/bloodboil, + "self_other_technology"=/obj/effect/rune/proc/communicate, + "join_hide_technology"=/obj/effect/rune/proc/runestun ) + +/obj/effect/rune/attack_hand(mob/living/user as mob) + if(!iscultist(user)) + user << "You can't mouth the arcane scratchings without fumbling over them." + return + if(istype(user.wear_mask, /obj/item/clothing/mask/muzzle)) + user << "You are unable to speak the words of the rune." + return + if(!word1 || !word2 || !word3 || prob(user.getBrainLoss())) + return fizzle() - Del() - ..() - cultNetwork.viewpoints-=src - cultNetwork.removeViewpoint(src) - - examine() - set src in view(2) - - if(!iscultist(usr) && !isSpirit(usr)) - usr << "A strange collection of symbols drawn in blood." - return - /* Explosions... really? - if(desc && !usr.stat) - usr << "It reads: [desc]." - sleep(30) - explosion(src.loc, 0, 2, 5, 5) - if(src) - del(src) - */ - if(!desc) - usr << "A spell circle drawn in blood. It reads: [word1] [word2] [word3]." - else - usr << "Explosive Runes inscription in blood. It reads: [desc]." - - return + var/word_string = get_word_string() + if (word_string in effect_dictionary) + cult_log("of type [effect_dictionary[word_string]] activated by [key_name_admin(user)].") + return call(src,effect_dictionary[word_string])() + return fizzle() - attackby(I as obj, user as mob) - if(istype(I, /obj/item/weapon/tome) && iscultist(user)) - user << "You retrace your steps, carefully undoing the lines of the rune." - del(src) - return - else if(istype(I, /obj/item/weapon/nullrod)) - user << "\blue You disrupt the vile magic with the deadening field of the null rod!" - del(src) - return - return +/obj/effect/rune/proc/fizzle() + if(istype(src,/obj/effect/rune)) + usr.say(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix.")) + else + usr.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix.")) + for (var/mob/V in viewers(src)) + V.show_message("\red The markings pulse with a small burst of light, then fall dark.", 3, "\red You hear a faint fizzle.", 2) + return - - attack_hand(mob/living/user as mob) - if(!iscultist(user)) - user << "You can't mouth the arcane scratchings without fumbling over them." - return - if(istype(user.wear_mask, /obj/item/clothing/mask/muzzle)) - user << "You are unable to speak the words of the rune." - return - if(!word1 || !word2 || !word3 || prob(user.getBrainLoss())) - return fizzle() -// if(!src.visibility) -// src.visibility=1 - if(word1 == cultwords["travel"] && word2 == cultwords["self"]) - return teleport(src.word3) - if(word1 == cultwords["see"] && word2 == cultwords["blood"] && word3 == cultwords["hell"]) - return tomesummon() - if(word1 == cultwords["hell"] && word2 == cultwords["destroy"] && word3 == cultwords["other"]) - return armor() - if(word1 == cultwords["join"] && word2 == cultwords["blood"] && word3 == cultwords["self"]) - return convert() - if(word1 == cultwords["hell"] && word2 == cultwords["join"] && word3 == cultwords["self"]) - return tearreality() - if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["technology"]) - return emp(src.loc,3) - if(word1 == cultwords["travel"] && word2 == cultwords["blood"] && word3 == cultwords["self"]) - return drain() - if(word1 == cultwords["see"] && word2 == cultwords["hell"] && word3 == cultwords["join"]) - return seer() - if(word1 == cultwords["blood"] && word2 == cultwords["join"] && word3 == cultwords["hell"]) - return raise() - if(word1 == cultwords["hide"] && word2 == cultwords["see"] && word3 == cultwords["blood"]) - return obscure(4) - if(word1 == cultwords["hell"] && word2 == cultwords["travel"] && word3 == cultwords["self"]) - return ajourney() - if(word1 == cultwords["blood"] && word2 == cultwords["see"] && word3 == cultwords["travel"]) - return manifest() - if(word1 == cultwords["hell"] && word2 == cultwords["technology"] && word3 == cultwords["join"]) - return talisman() - if(word1 == cultwords["hell"] && word2 == cultwords["blood"] && word3 == cultwords["join"]) - return sacrifice() - if(word1 == cultwords["blood"] && word2 == cultwords["see"] && word3 == cultwords["hide"]) - return revealrunes(src) - if(word1 == cultwords["destroy"] && word2 == cultwords["travel"] && word3 == cultwords["self"]) - return wall() - if(word1 == cultwords["travel"] && word2 == cultwords["technology"] && word3 == cultwords["other"]) - return freedom() - if(word1 == cultwords["join"] && word2 == cultwords["other"] && word3 == cultwords["self"]) - return cultsummon() - if(word1 == cultwords["hide"] && word2 == cultwords["other"] && word3 == cultwords["see"]) - return deafen() - if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["other"]) - return blind() - if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["blood"]) - return bloodboil() - if(word1 == cultwords["self"] && word2 == cultwords["other"] && word3 == cultwords["technology"]) - return communicate() - if(word1 == cultwords["travel"] && word2 == cultwords["other"]) - return itemport(src.word3) - if(word1 == cultwords["join"] && word2 == cultwords["hide"] && word3 == cultwords["technology"]) - return runestun() - else - return fizzle() - - - proc - fizzle() - if(istype(src,/obj/effect/rune)) - usr.say(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix.")) - else - usr.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix.")) - for (var/mob/V in viewers(src)) - V.show_message("\red The markings pulse with a small burst of light, then fall dark.", 3, "\red You hear a faint fizzle.", 2) - return - - check_icon() - icon = get_uristrune_cult(word1, word2, word3) +/obj/effect/rune/proc/check_icon() + icon = get_uristrune_cult(word1, word2, word3) /obj/item/weapon/tome name = "arcane tome" diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index d17f9022aa..e7f1e2ff26 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -2,6 +2,9 @@ var/list/sacrificed = list() /////////////////////////////////////////FIRST RUNE +/obj/effect/rune/proc/teleportRune() + return teleport(src.word3) + /obj/effect/rune/proc/teleport(var/key) var/mob/living/user = usr var/allrunesloc[] @@ -36,7 +39,8 @@ var/list/sacrificed = list() call(/obj/effect/rune/proc/fizzle)() return - +/obj/effect/rune/proc/itemportRune() + return itemport(src.word3) /obj/effect/rune/proc/itemport(var/key) // var/allrunesloc[] // allrunesloc = new/list() @@ -106,6 +110,7 @@ var/list/sacrificed = list() M.visible_message("\red [M] writhes in pain as the markings below him glow a bloody red.", \ "\red AAAAAAHHHH!.", \ "\red You hear an anguished scream.") + cult_log("[key_name_admin(usr)] tried to convert [key_name_admin(M)]") if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist"))//putting jobban check here because is_convertable uses mind as argument ticker.mode.add_cultist(M.mind) M.mind.special_role = "Cultist" @@ -130,6 +135,7 @@ var/list/sacrificed = list() M.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!") cultist_count += 1 if(cultist_count >= 9) + cult_log("THE CULT HAS SUMMONED NAR'SIE. GGNORE") new /obj/machinery/singularity/narsie/large(src.loc) if(ticker.mode.name == "cult") ticker.mode:eldergod = 0 @@ -138,7 +144,9 @@ var/list/sacrificed = list() return fizzle() /////////////////////////////////////////FIFTH RUNE - +/obj/effect/rune/proc/empRune() + emp(src.loc,3) + /obj/effect/rune/proc/emp(var/U,var/range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist if(istype(src,/obj/effect/rune)) usr.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!") @@ -161,6 +169,7 @@ var/list/sacrificed = list() if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"]) for(var/mob/living/carbon/D in R.loc) if(D.stat!=2) + cult_log("[key_name_admin(usr)] has drained blood from [key_name_admin(D)]") var/bdrain = rand(1,25) D << "\red You feel weakened." D.take_overall_damage(bdrain, 0) @@ -298,6 +307,8 @@ var/list/sacrificed = list() /////////////////////////////////////////NINETH RUNE +/obj/effect/rune/proc/obscureRune() + return obscure(4) /obj/effect/rune/proc/obscure(var/rad) var/S=0 for(var/obj/effect/rune/R in orange(rad,src)) @@ -520,6 +531,9 @@ var/list/sacrificed = list() return 0 else return 0 + + // record this + cult_log("[key_name(usr,0)] says : [input]") var/obj/cult_viewpoint/vp = getCultViewpoint(usr) if (!vp) @@ -698,6 +712,9 @@ var/list/sacrificed = list() /////////////////////////////////////////SIXTEENTH RUNE +/obj/effect/rune/proc/revealrunesrune() + revealrunes(src) + /obj/effect/rune/proc/revealrunes(var/obj/W as obj) var/go=0 var/rad @@ -940,6 +957,7 @@ var/list/sacrificed = list() var/obj/item/weapon/nullrod/N = locate() in M if(N) continue + cult_log(": Blood Boil damaged [key_name_admin(M)].") M.take_overall_damage(51,51) M << "\red Your blood boils!" if(prob(5)) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index e601f069c6..7e1e967fc5 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -22,25 +22,29 @@ F << "[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z]) || [src] [message]
" //ADMINVERBS -/client/proc/investigate_show( subject in list("hrefs","notes","singulo") ) +/client/proc/investigate_show( subject in list("hrefs","notes","singulo","cult") ) set name = "Investigate" set category = "Admin" if(!holder) return - switch(subject) - if("singulo") //general one-round-only stuff - var/F = investigate_subject2file(subject) - if(!F) - src << "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed." - return - src << browse(F,"window=investigate[subject];size=800x300") - - if("hrefs") //persistant logs and stuff - if(config && config.log_hrefs) - if(href_logfile) - src << browse(href_logfile,"window=investigate[subject];size=800x300") - else - src << "Error: admin_investigate: No href logfile found." - return + + var/list/basic_subjects = list("singulo","cult") + + if(subject in basic_subjects) + var/F = investigate_subject2file(subject) + if(!F) + src << "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed." + return + src << browse(F,"window=investigate[subject];size=800x300") + return + + + if(subject=="hrefs") //persistant logs and stuff + if(config && config.log_hrefs) + if(href_logfile) + src << browse(href_logfile,"window=investigate[subject];size=800x300") else - src << "Error: admin_investigate: Href Logging is not on." + src << "Error: admin_investigate: No href logfile found." return + else + src << "Error: admin_investigate: Href Logging is not on." + return diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 8f9623565f..0d4455b578 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -333,6 +333,9 @@ var/list/slot_equipment_priority = list( \ return */ +/mob + var/newPlayerType = /mob/new_player + /mob/verb/abandon_mob() set name = "Respawn" set category = "OOC" @@ -376,14 +379,12 @@ var/list/slot_equipment_priority = list( \ log_game("[usr.key] AM failed due to disconnect.") return - var/mob/new_player/M = new /mob/new_player() + var/mob/newPlayer = new newPlayerType() if(!client) log_game("[usr.key] AM failed due to disconnect.") - del(M) + del(newPlayer) return - - M.key = key -// M.Login() //wat + newPlayer.key = key return /client/verb/changes() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 77b4dbd884..e63ea883a6 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -299,9 +299,9 @@ data_core.manifest_inject(character) ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn AnnounceArrival(character, rank) - + return character else - character.Robotize() + return character.Robotize() del(src) proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) diff --git a/code/modules/mob/spirit/mask/mask.dm b/code/modules/mob/spirit/mask/mask.dm index 87bf07cd45..404cd15387 100644 --- a/code/modules/mob/spirit/mask/mask.dm +++ b/code/modules/mob/spirit/mask/mask.dm @@ -1,10 +1,12 @@ mob/spirit/mask - + icon = 'icons/mob/spirits/mask.dmi' + icon_state = "depressurized" mob/spirit/mask/New() ..() spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman(src) spell_list += new /obj/effect/proc_holder/spell/aoe_turf/blood_speech(src) + spell_list += new /obj/effect/proc_holder/spell/aoe_turf/shatter_lights(src) mob/spirit/mask/verb/go_to_follower() @@ -15,19 +17,22 @@ mob/spirit/mask/verb/go_to_follower() var/obj/cult_viewpoint/cultist = pick_cultist() if (cultist) follow_cultist(cultist.owner) + cult_log("[key_name_admin(src)] started following [key_name_admin(cultist)].") src << "You start following [cultist.get_display_name()]." -mob/spirit/mask/verb/set_specific_urge() +mob/spirit/mask/verb/urge_cultist() set category = "Mask" - set name = "Set urge on cultist" - set desc = "Set urge on target" + set name = "Urge cultist" + set desc = "Push your cultists to do something." var/obj/cult_viewpoint/cultist = pick_cultist() if (cultist) - var/newUrge = stripped_input(usr, "", "Set Urge", "") - cultist.set_urge(newUrge) - src << "You urge [cultist.owner.name] to [newUrge]." + if (cultist.owner) + var/newUrge = stripped_input(usr, "", "Set Urge", "") + cultist.set_urge(newUrge) + src << "You urge [cultist.owner.name] to [newUrge]." + cult_log("controlled by [key_name_admin(src)] has urged [key_name_admin(cultist.owner)] to [newUrge].") mob/spirit/mask/verb/set_cult_name() set category = "Mask" @@ -41,17 +46,20 @@ mob/spirit/mask/verb/set_cult_name() return cultist.set_cult_name(newName) src << "You grant [cultist.owner.name] the secret name of [newName]." + if (cultist.owner) + cult_log("[key_name_admin(src)] has set [key_name_admin(cultist.owner)] to \'[newName]\'") -mob/spirit/mask/verb/set_global_urge() +mob/spirit/mask/verb/urge_cult() set category = "Mask" - set name = "Set global urge" + set name = "Urge Cult" set desc = "Set urge on the entire cult." var/newUrge = stripped_input(usr, "Please choose an urge.", "Set Urge", "") for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) viewpoint.set_urge(newUrge) src << "You urge the entire cult to [newUrge]." + cult_log("[key_name_admin(src)] has urged the entire cult to [newUrge]") mob/spirit/mask/verb/set_favor_for_cultist() @@ -61,20 +69,27 @@ mob/spirit/mask/verb/set_favor_for_cultist() var/obj/cult_viewpoint/cultist = pick_cultist() if (cultist) - var/list/favor = list("Pleased", "Displeased", "Indifference") - var/emotion = input("Pick your emotion", "Mask", null, null) in favor - switch(emotion) - if("Pleased") - cultist.set_favor(1) - if("Displeased") - cultist.set_favor(-1) - if("Indifference") - cultist.set_favor(0) + if (cultist.owner) + var/list/favor = list("Pleased", "Displeased", "Indifference") + var/emotion = input("Pick your emotion", "Mask", null, null) in favor + switch(emotion) + if("Pleased") + cultist.set_favor(1) + cult_log("[key_name_admin(src)] is pleased with [key_name_admin(cultist.owner)]") + if("Displeased") + cultist.set_favor(-1) + cult_log("[key_name_admin(src)] is displeased with [key_name_admin(cultist.owner)]") + if("Indifference") + cultist.set_favor(0) + cult_log("[key_name_admin(src)] is indifferent too [key_name_admin(cultist.owner)]") mob/spirit/mask/proc/set_name() - var/newName = stripped_input(usr, "Please pick a name.", "Pick Name for Mask", "") - name = newName ? newName : "Mask of Nar'sie" + spawn(0) + var/newName = stripped_input(src, "Please pick a name.", "Pick Name for Mask", "") + name = newName ? newName : "Mask of Nar'sie" + src << "You have set your name to [name]." + return name mob/spirit/mask/proc/pick_cultist() @@ -86,13 +101,26 @@ mob/spirit/mask/proc/pick_cultist() return result +// this proc makes the mask visible very briefly +/mob/spirit/mask/proc/flicker() + spawn(0) + alpha = 127 + invisibility=0 + sleep(5) + invisibility=initial(invisibility) + alpha = 255 + +/proc/flicker_mask(mob/spirit/mask/target) + if(istype(target)) + target.flicker() + // SPELLS /obj/effect/proc_holder/spell/aoe_turf/blood_speech name = "Speak to your Acolytes" desc = "This spell allows you to speak to your flock." school = "unknown evil" charge_type = "recharge" - charge_max = 300 + charge_max = 2000 clothes_req = 0 invocation = "none" invocation_type = "none" @@ -102,20 +130,46 @@ mob/spirit/mask/proc/pick_cultist() var/input = stripped_input(usr, "Please choose a message to tell your acolytes.", "Voice of Blood", "") if(!input) revert_cast(usr) + cult_log("[key_name_admin(usr)]says : [input]") + flicker_mask(usr) for(var/datum/mind/H in ticker.mode.cult) if (H.current) H.current << "[usr.name]: [input]" for(var/mob/spirit/spirit in spirits) - spirit << "[usr.name]: [input]" + spirit << "[usr.name]: [input]" - + +/obj/effect/proc_holder/spell/aoe_turf/shatter_lights + name = "Spread Shadows" + desc = "This spell breaks lights near the mask." + school = "unknown evil" + charge_type = "recharge" + charge_max = 1000 + clothes_req = 0 + invocation = "none" + invocation_type = "none" + range = 0 + +/obj/effect/proc_holder/spell/aoe_turf/shatter_lights/cast(list/targets) + cult_log("[key_name_admin(usr)] used Spread Shadows.") + flicker_mask(usr) + spawn(0) + for(var/area/A in range(3,get_turf(usr))) + for(var/obj/machinery/light/L in A) + L.on = 1 + L.broken() + sleep(1) + for(var/obj/item/device/flashlight/F in A) + F.on = 0 + + /obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman name = "Create Talisman" desc = "This spell conjures a talisman" school = "conjuration" charge_type = "recharge" - charge_max = 300 + charge_max = 3000 clothes_req = 0 invocation = "none" invocation_type = "none" @@ -145,6 +199,9 @@ mob/spirit/mask/proc/pick_cultist() revert_cast(usr) return + cult_log("[key_name_admin(usr,0)] created a talisman of type [talisman].") + flicker_mask(usr) + switch(talisman) if ("Teleport") @@ -168,4 +225,6 @@ mob/spirit/mask/proc/pick_cultist() summon_type = list(/obj/item/weapon/paper/talisman) newVars = list("imbue" = "[imbue_value]") - ..() \ No newline at end of file + ..() + + diff --git a/code/modules/mob/spirit/mask/respawn.dm b/code/modules/mob/spirit/mask/respawn.dm new file mode 100644 index 0000000000..acfb69073c --- /dev/null +++ b/code/modules/mob/spirit/mask/respawn.dm @@ -0,0 +1,20 @@ +/proc/there_can_be_only_one_mask(var/mob/spirit/mask/target) + if(!istype(target)) + return + for(var/mob/spirit/mask/currentSpirit in spirits) + if(currentSpirit) + if(currentSpirit!=target) + // create the ghost + var/mob/dead/observer/ghost = currentSpirit.ghostize(TRUE) + // let the deposed mask respawn immediately, the poor dear + ghost.timeofdeath = world.time - 20000 + ghost.newPlayerType = /mob/new_player/cultist + // remove old mask body + del(currentSpirit) + + +/mob/new_player/cultist/AttemptLateSpawn(rank) + var/mob/newCharacter = ..(rank) + if(ticker.mode) + if(is_convertable_to_cult(newCharacter.mind)) + ticker.mode.add_cultist(newCharacter.mind) \ No newline at end of file diff --git a/code/modules/mob/spirit/movement.dm b/code/modules/mob/spirit/movement.dm index c6e6fb3a09..d8847cb480 100644 --- a/code/modules/mob/spirit/movement.dm +++ b/code/modules/mob/spirit/movement.dm @@ -18,6 +18,8 @@ mob/spirit/proc/Spirit_Move(direct) if(step) setLoc(step) + dir = direct // update our sprite + cooldown = world.timeofday + 5 if(acceleration) sprint = min(sprint + 0.5, max_sprint) diff --git a/code/modules/mob/spirit/viewpoint.dm b/code/modules/mob/spirit/viewpoint.dm index 56f5b154b5..5e06356129 100644 --- a/code/modules/mob/spirit/viewpoint.dm +++ b/code/modules/mob/spirit/viewpoint.dm @@ -76,6 +76,7 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list() if(FAVOR_DISPLEASED) owner << "\red \b You cringe at your gods displeasure." + /obj/cult_viewpoint/verb/pray_to_mask() set category = "Cult" set desc = "Pray to your god" @@ -86,6 +87,7 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list() if(!input) return + cult_log("[key_name(usr,0)](Pray):[input]") owner << "You pray to Nar'Sie: [input]" for(var/mob/spirit/spirit in spirits) @@ -145,12 +147,17 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list() set desc = "Sacrifice your life and become a Mask of Nar'sie." set src in usr + cult_log("[key_name(usr,0)] has tried to become a Mask of Nar'sie.") + if (!active_mask()) var/transformation_type = alert(owner.client, "You are about to become a Mask. Do you want it to be subtle or violent?", "Mask", "Subtle", "Violent") if(!active_mask()) + cult_log("[key_name(usr,0)] has become a Mask of Nar'sie.") if (transformation_type=="Subtle") + log_admin("[key_name_admin(owner)] has subtly become a Mask of Nar'sie") owner.make_into_mask(0,0) else + log_admin("[key_name_admin(owner)] has violently become a Mask of Nar'sie") owner.make_into_mask(1,1) else owner << "\b You cannot become a mask of Nar'Sie because a Mask already exists." diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 59917edd52..ea45eca49e 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -142,46 +142,28 @@ /mob/proc/make_into_mask(var/should_gib = 0, var/should_remove_items = 0) - if (should_gib) - var/mob/spirit/mask/new_spirit = new() - - if(mind) - new_spirit.mind = mind - new_spirit.mind.assigned_role = "Mask" - new_spirit.mind.original = new_spirit - - new_spirit.key = key - new_spirit.loc=loc - - spawn(0) - src.gib() // gib the body - - new_spirit.set_name() - - // let spirits identify cultists - if(ticker.mode) - ticker.mode.reset_cult_icons_for_spirit(new_spirit) - - return new_spirit - - else - if(should_remove_items) - for(var/obj/item/W in src) - drop_from_inventory(W) - + if(!should_gib) icon = null invisibility = 101 + + if(!should_remove_items) + for(var/obj/item/W in src) + drop_from_inventory(W) - var/mob/spirit/mask/new_spirit = new() - - if(mind) - new_spirit.mind = mind - new_spirit.mind.assigned_role = "Mask" - new_spirit.mind.original = new_spirit - - new_spirit.key = key - new_spirit.loc=loc - + var/mob/spirit/mask/new_spirit = new() + + if(mind) + new_spirit.mind = mind + new_spirit.mind.assigned_role = "Mask" + new_spirit.mind.original = new_spirit + + new_spirit.key = key + new_spirit.loc=loc + + if (should_gib) + spawn(0) + src.gib() // gib the body + else spawn(0)//To prevent the proc from returning null. src.visible_message( \ "[src] disappears into the shadows, never to be seen again.", \ @@ -189,13 +171,19 @@ "You hear strange noise, you can't quite place it.") del(src) - new_spirit.set_name() + new_spirit << "You are a Mask of Nar'sie now. You are a tiny fragment of the unknowable entity that is the god." + new_spirit << "Your job is to help your acolytes complete their goals. Be spooky. Do evil." - // let spirits identify cultists - if(ticker.mode) - ticker.mode.reset_cult_icons_for_spirit(new_spirit) + new_spirit.set_name() - return new_spirit + // let spirits identify cultists + if(ticker.mode) + ticker.mode.reset_cult_icons_for_spirit(new_spirit) + + // highlander test + there_can_be_only_one_mask(new_spirit) + + return new_spirit //human -> robot diff --git a/icons/mob/spirits/mask.dmi b/icons/mob/spirits/mask.dmi new file mode 100644 index 0000000000000000000000000000000000000000..20fe26c4bced41886718c66c2569db7bd9b7fbd7 GIT binary patch literal 972 zcmV;-12g=IP){f|1VR6J#Mc^K`AXmVMIPFJvJXTFe5%V zBsVf292pHHAs8-Ws%~RG_TXpZ00001bW%=J06^y0W&i*Ha(Yx)bVOxyV{&P5bZKvH z004NLQ&wT#GdI(F^OKlJp@5n z3+G-O)8xJHrvs6nx=Jo`A42HJ5lVMOTR3O5vEub0sZCjjSC?tfNQ;& zK6vu6ItKLD>y-nO$OcF?z(PxiVV|95=x+*0iLqo6UOE8LE>r;TS@i(;Ad*O!m#Pir z2=ZM4`!;4D*!0L{JfY_fApF3h`WmvPI3ky^yAdh?ive_(N)G~b5^;o#+Y+Ls0l*3r ziavGTw1mni7{Ijv=r48&goSN_0ulh}Cjg-V2#Glb?|5y#XYT;vyCZ$n0DbfUs87%7 zlAwartl$8!05iVJ%<490{9$YgLDCW3NTEc0DL<2AMkPjjQ|G(DltqR z7xDE_cduOM@4PNZsrJqHG*O`Th;e1lmco(_K`aU1nK3Kum%us!Fue{St#864FeEs$ zpD&LG?`D+Cm49sj=tb%;rrM1VoC|=*uIy zkP((@e#pAJ&L21{Sovcz>+MAEvlXEFs)QWi%{rZAi(NKG6p%bXv=vZ!gU%I{b$~I0 z+($$JkbKfz7Ut?A^mqe+#s+YhrQp&Pz>_2exFY~XFRlSVcQL0dBS2OFjJFNIY-XK+ zwKhNM3Wx^aZ4TH0vi?j9plK^MKnyByq5vKO)-fQT0hAM9L}<*BEAa;C^gw5zRLqfE z28TDP0PgoTplE2dA);Y^yl#M@c`^WibOGzp7t{7`TRe8R|8bBWq;2s Date: Sat, 23 Nov 2013 02:01:40 -0500 Subject: [PATCH 06/18] Removing world spam and viewport adding using the equipcultists proc. --- code/game/gamemodes/cult/cult.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 26d984641f..7f288d2dd0 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -134,10 +134,6 @@ mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." mob.mutations.Remove(CLUMSY) - var/obj/cult_viewpoint/viewpoint = new(mob) - viewpoint.loc = mob - world << "Spawning viewpoint on [mob]" - var/obj/item/weapon/paper/talisman/supply/T = new(mob) var/list/slots = list ( "backpack" = slot_in_backpack, From 4ed7c79fcc36e7dc484a2a47b271a283638337f7 Mon Sep 17 00:00:00 2001 From: jack-fractal Date: Sat, 23 Nov 2013 02:20:19 -0500 Subject: [PATCH 07/18] - making sure to add the viewpoint properly to roundstart cultists. - there are way too many ways to make someone a cultist... --- code/game/gamemodes/cult/cult.dm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 7f288d2dd0..e0e81a647e 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -134,6 +134,8 @@ mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." mob.mutations.Remove(CLUMSY) + add_cult_viewpoint(mob) // give them a viewpoint + var/obj/item/weapon/paper/talisman/supply/T = new(mob) var/list/slots = list ( "backpack" = slot_in_backpack, @@ -169,13 +171,20 @@ cult_mob.mind.store_memory("You remember that [wordexp]", 0, 0) +/datum/game_mode/proc/add_cult_viewpoint(var/mob/target) + for(var/obj/cult_viewpoint/viewpoint in target) + return + var/obj/cult_viewpoint/viewpoint = new(target) + viewpoint.loc = target + return viewpoint + + /datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE if (!istype(cult_mind)) return 0 if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind)) cult += cult_mind - var/obj/cult_viewpoint/viewpoint = new(cult_mind.current) - viewpoint.loc = cult_mind.current + add_cult_viewpoint(cult_mind.current) update_cult_icons_added(cult_mind) return 1 From 39542c776071ca2cd4a567985b0474f34ac3df4a Mon Sep 17 00:00:00 2001 From: jack-fractal Date: Sun, 24 Nov 2013 16:13:28 -0500 Subject: [PATCH 08/18] - removing 'colon' use for proc calls. Generally a bad idea. - adding a check for being silenced to use runes - adding extra slashes in front of the mask definition - re-adding the autotransfer.dm file to the include list --- baystation12.dme | 1 + .../visibility_networks/visibility_network.dm | 8 +++---- code/game/gamemodes/cult/ritual.dm | 2 ++ code/modules/mob/mob_movement.dm | 10 ++++++-- code/modules/mob/spirit/mask/mask.dm | 23 ++++++++----------- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index ad42576274..1088ce6c88 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -76,6 +76,7 @@ #include "code\ATMOSPHERICS\components\unary\vent_pump.dm" #include "code\ATMOSPHERICS\components\unary\vent_scrubber.dm" #include "code\controllers\_DynamicAreaLighting_TG.dm" +#include "code\controllers\autotransfer.dm" #include "code\controllers\configuration.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\lighting_controller.dm" diff --git a/code/datums/visibility_networks/visibility_network.dm b/code/datums/visibility_networks/visibility_network.dm index 4361d8ef14..225b6e3def 100644 --- a/code/datums/visibility_networks/visibility_network.dm +++ b/code/datums/visibility_networks/visibility_network.dm @@ -52,11 +52,11 @@ var/list/remove = targetMob.visibility_interface:visible_chunks - visibleChunks var/list/add = visibleChunks - targetMob.visibility_interface:visible_chunks - for(var/chunk in remove) - chunk:remove(targetMob) + for(var/datum/visibility_chunk/chunk in remove) + chunk.remove(targetMob) - for(var/chunk in add) - chunk:add(targetMob) + for(var/datum/visibility_chunk/chunk in add) + chunk.add(targetMob) // Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 0686a1842b..2760a66d49 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -148,6 +148,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", if(istype(user.wear_mask, /obj/item/clothing/mask/muzzle)) user << "You are unable to speak the words of the rune." return + if(user.silent) // checking if we've been muted somehow + user << "You are unable to speak at all! You cannot say the words of the rune." if(!word1 || !word2 || !word3 || prob(user.getBrainLoss())) return fizzle() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 399e7b9a73..2fda2c141d 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -177,8 +177,14 @@ if(mob.stat==2) return - if(isSpirit(mob)) return mob:Spirit_Move(direct) - if(isAI(mob)) return AIMove(n,direct,mob) + // handle possible spirit movement + var/mob/spirit/currentSpirit = mob + if(currentSpirit) + return currentSpirit.Spirit_Move(direct) + + // handle possible AI movement + if(isAI(mob)) + return AIMove(n,direct,mob) if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var diff --git a/code/modules/mob/spirit/mask/mask.dm b/code/modules/mob/spirit/mask/mask.dm index 404cd15387..6b58f201cf 100644 --- a/code/modules/mob/spirit/mask/mask.dm +++ b/code/modules/mob/spirit/mask/mask.dm @@ -1,15 +1,15 @@ -mob/spirit/mask +/mob/spirit/mask icon = 'icons/mob/spirits/mask.dmi' icon_state = "depressurized" -mob/spirit/mask/New() +/mob/spirit/mask/New() ..() spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman(src) spell_list += new /obj/effect/proc_holder/spell/aoe_turf/blood_speech(src) spell_list += new /obj/effect/proc_holder/spell/aoe_turf/shatter_lights(src) -mob/spirit/mask/verb/go_to_follower() +/mob/spirit/mask/verb/go_to_follower() set category = "Mask" set name = "Go to follower" set desc = "Select who you would like to go too." @@ -21,7 +21,7 @@ mob/spirit/mask/verb/go_to_follower() src << "You start following [cultist.get_display_name()]." -mob/spirit/mask/verb/urge_cultist() +/mob/spirit/mask/verb/urge_cultist() set category = "Mask" set name = "Urge cultist" set desc = "Push your cultists to do something." @@ -34,7 +34,7 @@ mob/spirit/mask/verb/urge_cultist() src << "You urge [cultist.owner.name] to [newUrge]." cult_log("controlled by [key_name_admin(src)] has urged [key_name_admin(cultist.owner)] to [newUrge].") -mob/spirit/mask/verb/set_cult_name() +/mob/spirit/mask/verb/set_cult_name() set category = "Mask" set name = "Set Cult Name" set desc = "Grant a cultist a name." @@ -50,7 +50,7 @@ mob/spirit/mask/verb/set_cult_name() cult_log("[key_name_admin(src)] has set [key_name_admin(cultist.owner)] to \'[newName]\'") -mob/spirit/mask/verb/urge_cult() +/mob/spirit/mask/verb/urge_cult() set category = "Mask" set name = "Urge Cult" set desc = "Set urge on the entire cult." @@ -62,7 +62,7 @@ mob/spirit/mask/verb/urge_cult() cult_log("[key_name_admin(src)] has urged the entire cult to [newUrge]") -mob/spirit/mask/verb/set_favor_for_cultist() +/mob/spirit/mask/verb/set_favor_for_cultist() set category = "Mask" set name = "Show your favor" set desc = "Set the favor for a cultist" @@ -84,15 +84,14 @@ mob/spirit/mask/verb/set_favor_for_cultist() cult_log("[key_name_admin(src)] is indifferent too [key_name_admin(cultist.owner)]") -mob/spirit/mask/proc/set_name() +/mob/spirit/mask/proc/set_name() spawn(0) var/newName = stripped_input(src, "Please pick a name.", "Pick Name for Mask", "") name = newName ? newName : "Mask of Nar'sie" src << "You have set your name to [name]." - return name -mob/spirit/mask/proc/pick_cultist() +/mob/spirit/mask/proc/pick_cultist() var/list/cultists = list() for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) cultists[viewpoint.get_display_name()]=viewpoint @@ -225,6 +224,4 @@ mob/spirit/mask/proc/pick_cultist() summon_type = list(/obj/item/weapon/paper/talisman) newVars = list("imbue" = "[imbue_value]") - ..() - - + ..() \ No newline at end of file From ffb6e2c2e8ed5b00c1292122519625884bfc2676 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Sun, 24 Nov 2013 15:47:50 -0600 Subject: [PATCH 09/18] Custom Items: Mai Yang / Yuri's Flask. Icons. --- icons/mob/items_lefthand.dmi | Bin 146202 -> 146597 bytes icons/mob/items_righthand.dmi | Bin 147115 -> 147496 bytes icons/mob/uniform.dmi | Bin 193728 -> 195450 bytes icons/obj/custom_items.dmi | Bin 50623 -> 51412 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi index af2daeb4de6a69c5a6d2361c44c821a588efeef0..b15d273426e9890e69869090ce4f0d1b2bf976ca 100644 GIT binary patch delta 6918 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 bib8Bj#@Wj*67nC+_UrX^O?0YnJ&gQ6=L*9V diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi index 287fd36614e7619749fa8750c590f58318fec011..c3c098b0a2665dc755951af514033710a4185758 100644 GIT binary patch delta 5978 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 E2icz)egFUf delta 5794 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 BW7q%y delta 14429 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�yJyF1?_ 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 From 20b803b808c508429d128ba2b2a7f517c4ab6849 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Sun, 24 Nov 2013 16:28:48 -0600 Subject: [PATCH 10/18] Custom Items Code: Yuri's Flask and Mai Yang's dres. --- code/modules/customitems/item_defines.dm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 05bb2a30dd..9a487d3ab5 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -949,3 +949,18 @@ name = "[labeled] bottle" desc = "A small bottle. Contains [labeled]" icon_state = "bottle[color]" + +/obj/item/weapon/reagent_containers/food/drinks/flask/fluff/yuri_kornienkovich_flask + name = "Yuri's Flask" + desc = "An old gold plated flask. Nothing noteworthy about it besides it being gold and the red star on the worn out leather around it. There is also an engraving on the cap that is rather hard to see but it looks like \"Kornienkovich\" " + icon = 'icons/obj/custom_items.dmi' + icon_state = "yuri_kornienkovich_flask" + +/obj/item/clothing/under/fluff/mai_yang_dress // Mai Yang's pretty pretty dress. + name = "White Cheongsam" + desc = "It is a white cheongsam dress." + icon = 'icons/obj/custom_items.dmi' + icon_state = "mai_yang" + item_state = "mai_yang" + item_color = "mai_yang" + From 1b2eaa19630ee2333c276a0f310b03bb232cb430 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Sun, 24 Nov 2013 16:47:18 -0600 Subject: [PATCH 11/18] Custom Item Icons: Sakura Hokkaido's Kimono --- icons/mob/uniform.dmi | Bin 195450 -> 196306 bytes icons/obj/custom_items.dmi | Bin 51412 -> 51696 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 4ccaca1005311dacec935fdb31abfdc8b72fdc60..6e7b9c133ec56bc4c55eec4a4e68bb3a81ce4df4 100644 GIT binary patch delta 16836 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 delta 16091 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 diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 1ecc96ec23082c8eb61f604f1db1bc8a1655a59b..8d52a549b3706b7222dfbbe595bd1280846f47d6 100644 GIT binary patch delta 13617 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 CV*!f* delta 13342 zcmY*f1ytNXx5itvNYUc%?%Lu|ph$6diWiDYXp6fRUmRK%_aci!aVfsIJ1p+J?f>MQ zw`Y?{Cdp*xX6D}eefORwAx|YB$I~MwB{1-y;o7A)kZ2_s(F3w{j@Y-I)xkb+fO%X7R~E;&h9~_aQA;#Jr9qXmjIhx6#OQ ztLljc(91C%vWrcxdud)%R0wBjXt#h~4h)apnKJi`o8(6gMvVRMqj##*_~Vp$lA`N> z&m-gN*!LCoL$unLmazU*dAwSB@&sDiA4A1S9X0Z@5rH9lOv|aoMlmYaKN|6KpFear zGyApO1jkl+CxE~y1RvuD63hqH7eva@c+G>O(T<2-l45_0wG_+z)T2zgXR*FQUv53I zAo1n;#QEAbZ`2IeW*xOuBa5QiJUCF9Hm^9H`L9a2%}i0cxksX9(5VlE~zrUeblft58O$(L?`$hGi%4&CE_!xL@!O z8w#_;;as3M<%cYPv>i(u=j)k=u7UE}C)Ys&xu&Z7UaY5AJ2exPj7Lv+pC&N{pM5`9 zK#6yv_|7knr48+AC#%hx!I4%s9ZVnb^yZnw3`hNkz|GAZ&Z_*7)IA(X@e8T zrS+$#N59M|ch(2jm|>-6?h<#E+;Dw!YEL=N1*2D4+W8H9qB=zF=Lv*t3j6+ix7+zm z*NG`b;WA}ccegTmSILJwz4+sbQT{XT5)opw5;J}{)3SA^Vh7DPGlGY3@wfaEmu5#0 zF>*jjTCR`blYXKv|0iCOtYtv{De_#wxCkl2;i@>pZp5TI9V>RXwVQMy0rh}x5M4S? z(+KLO(t-E`)o2$BtkE;R!Ci`-N-9*=?5}Gh;4r{_Sz2Gmc8hhaZjFl-61uvOJ~rN2 z4?)zW#w`0R-)|Cx%hMfwM0_t-xY>1NXezO({-#+#_mQwCP4|KIMTb&aQ27JZ0a|h9!BJ9=eNO>2Qc_r07yzgv@RajLWQm9jHZp2=6}Y**uBizI4%7=q&z|m2 z+%KnflX7w@qsH@occ(O_SB<_F6??Ab+5qx=Vs}*ApQM|d9pdUAjYnF2&KHb5w+2&6 zIR4UsbH!xr^j>Q0>SD8O4Bb3MR*raYiJa8#SdkkLVeNab%=951Ox%`&NmB~04v&VD z6ZZD@oEy1Rl$2;VIVVd~o@l-Vm&b#NNAtNw0&_6>L4OeZU~)`v;S zUm%>QUL^h@VqaIZMU%rz?BLLlU6cQPVT4}h$^07-KAHgAOlh%SqQCq0CUdbiV<-6^ z*qZq5?JdSCqq&m}dpQQ#M-8z-Pm&J|rNvByS^ERMv-D*nh~*x2lQRqSnSY>ye~5-w0$2XtkW^(K?zk&eH@uSCqCKxe8!eK$4W zMTni$@#WX^lRL>v@z2g{5We-3N63jud|>EfwM4>S>t>2P zrU)PZd2Q+Fw3*fd!MNuX$pgeP(R0i(HU1v1|#vMT}X-T^pA4f1T|P`aj1=5i)PXbUso>32GW0e?NbGI}z{Jh;$v zbUHv5N6eZ%*-UI~@7eXL-Zq|dm_l0n73Wx17sL_1vA4{bb;lN?64vq1`8; z)=}!uHyy+C*4b8?JqiDq-q)r*(lFBI}ssN6hTirNd&*a&}WXs z(L8HNUfvoNYR!a4s}Sv+Gr7Y@OTIn)TX)(kIxV$IPa7 z1;lk)kaSM5{<@Pwt&vymYaztEmVH>E*h4*528@NlV*NjxFf8___jYtO`x*&9HycIS zW|lEkIMoI2%w3N^`>WK`_0H3;wVXf<5r#7az`fN14l@X+z?9a9+pSCQOWkx@2I-Ww zP2wD{zPY;tF_fU+qkSCDM#T<}%$=vl9^ebkJ_I7f%G}LN#Ip*+I{BdK%b)mKZdBfWf|^1$9_%i-injJ?FV)o$}hMw z!z!BVF^7wP0p`-7NRQuW?u+trNv@Z#t`ia^5$9q>oD1^(KZAEU@t-z(=n+r*O0W?Y zFE;HRw@#t;jIiNo@~t2J7YQfpy-~di@7>eVtSw;cy@PvKjbVcQh$SV@-!3>tqTUSk z338dF@qfa1n5{VaQ?Dql*Zk$znUfrON-_`IC#u@SE1)`xq>w3?iE_&*K*PGembo?)d0awM{PoWqg2?a}20$M>(7BS~ZV$)Yf zAt7ByXajb^#Gib*s5DWJQg{72J3RS<1Se=iLS`oT{$P!DWf@(`xxelxIo#FcQM;J4 zy8dt$(1NrPd`_yIfI+7`p2e=W@F^)#JGw$n@JLCQeyJH%{1dLl@}^Yc1lRZQDs`b- z`QVU$$398VyUBH+9{Qrl>h7@5t=^*M@7lrzFX$Kqu!9naTVrT!7-1SzZmmtx@auR< z$)!+%v<*R4xqb*zZr(nd<|I?R=I1s5H?=k2PJ8O>W)eYCk9N1s8C=wQY`GVT=R6J} z3%7#?tA1HdLd(pPfB&Y#rTj~w95zX=4S`z{#}-&0P8(zPn-{H)?C|r^kq2u_8ut?S z`@bKgwqX5Kx>o!26W4GWO3@ zdkAwofybT?_<>kKEL^eZF5u_;`;%u01XF()DncVex(|AGX%2-`O$Ca+=Y$pc-rrAR zU8PPKz#aO-)|j8S9o}#{z20TlR@Vjad^z;ISS8=~uGK?l$aKPq;+&~Jj>`6OwUhs8 zR{`Z@uCp?h;@qJ%A>gh7@G(kqb)m4dpRWY_BYNHTeaEXxUh`ZOAef=U9NkU*%7eeZ zeYYigHJ$!{;C~0*|%&)A{yd~#R6Ng1OpkT zRorIcQsl;J+5@=8D^c4`F&NgfQ9ULJYUoKo8@DO`T!Wb^1QXCH>oY(^Q;^FkCl{3D z%{-vei>XJz`UL6EFgC&h>(u)$Y7cJXWHpXp2}`ZTY;O$;O=aWU#**-S!=sZwUG_Wq z#p^i`{Qj?$+4;bWdH=Ic93$m>VUP7xX~R(wrf7GJ?%mAs*61dlL`1r-o3V_&z*~=* zX;^JdjjWLo`4#Xx$1>+$Bt5-}W8o<)k5K%3*W>jwNP!AESP-WyH&ATNEp+x~>qca18aj~S&xfF&31n6*HZ`?U+m2#Y?*xGC|hYAa91U!P~5sXB<1lC}s{sdocR4+W*pUTwKoNI^o zH?1JYv+XiF5=S4Cqul#>xx5^~`iBA6OS5h}B&l)=S(EPU{#$ORv>w$4ZxDrr=#0G3 zy*wV^b37rnapiY*`g~1v!%4MEd$0fVqZ;f9czPNr6u%;Ampe5?(f8rtn+3g1`dsLa zs5q9%%zyjj6LEKy%{L&mf*dNqsFCu>+IY@Q%$wOe&nfy0*H!-jLBZ!V!bn{kOW-20A&BT@zk+7#SoR2Ya zy}G;DLpBWT{J}BOe|@}k;P3x*y91u}KBaDNqM-;HqV$W_E|CA+-C+t;nRma5jtoED z^Nl5(wVZE?UF!c9v`W;kZ~=|sLG$0`+V1OblT`1c`r@Lcc4MA@bD@X(UCV4F!)%Al zOml z3RnDaEo9|lC}&)rA_d97)*D!Ez^D=f7d*;+f*JLa)yrd%-0%}>d*R}1%E)|QfH6P+ zF~2LKzim^VBX87Lo4f4N?(+9&d)YHiKWj2JE47O2f;PHu=KzGTngj6`yy)&~v56LE zM+#mo(4cz}sv~--m9`D-z(C1WQxPh0GrFfNv-OSd)q#ubO=r>aJ6xtakd6J%f2UGK zJP*@$XDf5YTw>q$NPXGGEs&4d9;Z3!KN%d_*vpd<*<^P8Q?yD!*%c5t_}VqW(^mN8 z?u|%gjNs}<&M|Pc_W)|TDpi9|_h!+j*)qoON}F1{i$d|P!dP2r5lkaTbDWSZ(T)e= zOBtWKnp-1cslCkP{%F#Ie~_Wfq%GsmA4M!Q4`D@kUu8nEK08;Mv@Pf_r+R}H&&I4H zZC|jtoK4pf*Ezhh}Q^p*Lk?&sR z=T9nYo_H%q4l3?}~p4sG1kVqm+!<=(VP2 zWW-NOX1yQ}og!O$*R{L}MxWKGzz`NjB0HG6TD6aIfiadFmUw$s8MJy=>+KgADU3or z(Zp>4rhd2n$uU^dZ?XlgE}UCmaPdqvvd%3`z7glc`Zt^T--)6|0s4c3gEyz$uhJz0 znz>1^B-=&cvf^l5oZPS88cIFC7|$DZ`yFJs_kz+@vULqDj`C1)ou&DSZmPaWd6pY7 z#w9zYV6m10lx2p`jUGhjxB)s68N9+=4Lt&?zH~X!Mo2pMm(}JTUY7<5>;?M7Dfz>< zU7EFNur6lM&5d`i2y$#(T)%z2=+G^GNgE0)a;VK7lKtiRr_lnY&(&zgW3wj1A*h9g zHh8ZeC>!p=&|d+#h5-_Jd3l9}#pays)U1ULLXE5B}Rp{7UQxhiv+ zuqO={fKp-dmHp#32c4R<>1vZ7sV)rB|7I-=VV7p*ZJ%k2CkLO+uq$-ODU`i@aiQK} zEkR**S~mb4%DD3&TMsf7Gxzv@16(_fX*8(al#f%kP!26TCC*yzNbH-8YWF~t=Lk5E zkCh{p-|uF}ZzflQC@PI$f@pIhS3=8jU7P~yAc@@i^IZWV5^8?h39A2*uq+@ZiP4DX(Ge>o{#;{ z8kL~oqTliHxt_1*tIWTo zeo_HH_cz4)0>=N*KiS72J;I40i(x{)t@Pc>jhJJOi?- zH)ykh9NF$qZR2TVx@$3Ww0#W@#stOvpS~fuPH`fStY0!3JJk@(ZY(sg`CT7R2Ve|7(V?sa;5X$3eT}7392^>oh>P>G z>Db!ZDghGX07rJMB4~@3OJY(IPrAzH=BB!lk&1=}-s%L_I$Z^6726M)SQ-V&w%oP> zU9mV2X_dT@>}>mWBEihxDZLNg7eyWQ!C_z9x|9vhFgycf@Fnyy5DhtGgTT;`^K54woy|^#=1mo1f6$9^{K7>DNxP4*U8{R{CYSr*4Tf?QnL)DFQ0x0o8p!Rf2dc(fP(qjh?Dz}+%18yJva>Vi zcQkAyY9Zb76)Jwac&H`zSipkdjRNF;8H$af76>0YGowNltsrf1;W#d6MOSe?&pbM< zDh?34o7TXecw1z5yF3;3N3p)TzO)onT1xP6+PzQIf3ZFyG|O7y{;tKdYd>4DC5(Fh zNYL2j&uZikMCid`u>4Kq3;v(yQeh~%kqZVl77DN9H^c>V+fjkV_&l*SR#U*HvD_Td z=y^zrjY|P+dFY5N+X8TnWC~R-F&Y1M+X6lfeJRAaON418Q@IpY8=T5~mZ*@P8aHe; zCS9@0pmuX>U<+-bsAZK%DTq&DfIQtfP*ob)-ik8zjf+Znh6u_b}t{ z3elai;3w19c1FohCMWXXluA?mu&y73a=vl~*#K~O zZo7}j43AQ8f*0QVUX@9&@y3FlzU$o%d#;Uv#$TKlv%ZZ|ne{)j0Yb2ZLFq2ko8UFk z5(S$0{hEMWf*ps(ASm7R-@JN_FLjUC*_YZz;zrp}4|O*Zsn;!y7x!8aV~Ul#oG<;v_Gb})BT4MuHkR%JE)v5|ly z<2*RiPwa&@2hi>`8){S$dCO8?h5%cNe(iR|__%9ypZDP4aG8Fs=Jj>u zj>OmcdxUnMS=&)wt)~jL@caSY6F-Vs)z>ZK(W zSY@hog|n_A#|BV{*k)b>$UnYtgtn+!II?NoDD%7@wP{^?qet*Lpl!ry9lPxWksTdt zNeS|_Ug!SqeKXF1mdM~J4+gxOgkucjvy2HSi9#zzU^uOmlpTQW*%EVj=ukCp?|nA# z9$qY7y}!NkmlWaIi%#YGgVki1@6k6oz7WEYSet#dIIBC@X#4(rAVP`O&qJmI>f3_E zViqAgxzTjJ>}ME$14pn@8|_sLwnQ};2DAwm!s6C!TWos~iiq#&6DcDYjaf{UKFI03 zdk^RLWbqNK(2^!AX@O=g#w4Z2Oo^R39*LsYRsRS-dK?wTByO^pW>BR7`g{1(lIlk6 zvTkST0aQ8>Jt+f8OpSkV8l9JXXZ+Fn;u`Aau3tC#U-BF2eyAzwd3Gf#iv9^g zBna-+3|gvi4hsvL7&o&W10gLf#L$<+`DQLSbd?JXgt(($2xP;R>{2@*m6DP&YW@85 zi1kKr*umy7?gsSP09q-upFLQ8WGO z?oUF16+m=o`>$DPX{4f}qQk}CNpMR1O_11eQ@2ayW9h63QA|t>bL6+vvlZg}h}>N2 z46-*7k^UofoLp`M)9_@2~l!n8UpQ zElm=lH();xR|lBD1L5iGzzzjNR^7Ke3o8wde`{a$h>*Yup3g z^L+2je@#q>0LRSe*w~k>riySJWm@ZT(B2EDlSVNzNilzpZ!iGE_PQC(!{(t0r#Cz)YZ}95ZXUQhm|KYC(p))#@KJ|r9ZX|D#+G- zn4+-0bZ|iF=-e7gdl`)cksG-~<5CadzTehwhKw2W4cFE2FRLo8^>s;0DybHgR>i|B z`Ur{6oRu+x3_a>7@f|syzHu17R#%Cc)1?efsoKM+YhX$B*sgtWGmmLkBl@ zX6D?Q8qHMpy7C*)4IPAu3b3>qys-{qT}!1j*fx6JDHz3;v!_|r2J4`6fSVq#pqaFE zbcjF8%Zr+tNP@gp0%ngy%+1XUi;HXE+)iR*A_6lD3t$e1-V{$8)^LG@ZI^k3r%IlE zVqr<12{V7OFC#6cy0&pr3GcmGANrX^FWu9S57_Gqvd9m}Vx{zm=Ra&lqW67lbx zUZ|<56%_YLt76lN=%;*La_)DoyuKxCrW2!>&bKTm$cDmq9x0~@G73_|By*;48P$!P z>z4uAC4?Tf`p=#;2P=WqDFrajxO%R3y?)UI)0Lwfhe=r|StM0p6kHl2TMHTf^=`iS zZ{8fdrmi~-+G<{@UrfheA<(V~B!59pL?myJVK80ovLbnP1by+=!$W|9fk9S5AqfOJ zz9K);jW|dJ>Nha+3;x`EjcIpGRI*#AAOaSAJQ>Vfw@N>U8y?#v$u4y#j z&?^r|M2=S0N)j&MHB+t0jr1z%f1bN+imhY9d~)sivu1H!ArUzEtzTqD=4)VVe?JgJ zh0OF-(gbuKZCbI}zf+Xm5G_?~&BFdsYC}h%-reDBdT_7zv{l^VbqJwJECUM$Q`=$t zjAJo;rT@s75(;$KC0%)wol-8ei1IKhb`m}}r&npZJQ4fKQ%NbpJ?AQ_Jm{T1j|9xD?1x_-3JW_e z_9j!Sphv?X32hcmd2$gqlJ7Jbr>AxnaK~QdP*qDyVr>oYt$Pc1N2+NcSAKr<+>vc) z&}_LO(=jX_40e2^Hp%s~>f{g!WnCZBV89xobyoe8-CvK%zB!#m|50yvc4nVgr^ z%tUo{A!%y;^}gxr6~FAnuk63H$;S1j@R~+r%gFHc_m3*tu=ExCo*4vHUSnfp%TCva zhi}C^4_(D1EqY#JU|8B>nyH0x>GZvFe7Lgs zr2*`{Vz1Z~c2%n>Fi`)j-;T%Kk6LitN7?{GaX!cg$so{_!y$~l{terRx zF4QGjoEaf$Rg?4CpJIV~8uRzY*h)%DhmRGZJv}`{fHl7n*TwYvE2OGh$mq(bQq*(T zavMDZ0}NguMo0zReSvGLG|7NF{mX0QCYyFLQ+yR|ebQWvD{_TQ7o3z$^#NES>!?!X zzg250jU1m9J=x+#R$bjTS6lM-H6fw!g4ZLXBhTdt1(ol5^vTOOGD&KfDr1s+K*Pf$!ufti zt7liu%&g2j&!na%d{xq8krZQN+x;y5S(OpY?Lnf6=vtLTQS~U?|7VBKFY^}l?OoxrvYshimsh&Lzq&rY8Y&%j(SRskQV zA$g1AF3QeE*z=8RCXeVBzR(a%VpjMPOj9XtIz4suJecmwEyl7~mLC7lo zN}42(46(J~4V>*8Tl`T#4%mG|R;^lDt{J&rwU%0kZ~4xy8Se9vH(5kcI-|N3&HENx zB~lb6Dw%>Bq}&}p=NttG2i5BJMrCh(-5hV-;wBq1lql*e|IoIyfj2?ym>%dr=Nzb;lv zEX=zCf1H4HlYWt5<{wQJS0GjHS8_iOkF?5Z7aR|DF6Q9PQ5K8J+#)X{d3$eA0N z)0iA9j9YHBC|?Qbf;Jki#E%ErzMHslmK1brX{e?10&@EG_9@;w*%yvA8%i zBZCZ(k{>+x7N4>VC^F3t6%B3ytJFNFG}@nqn&`%o|?cZ!&@rZw@RFaOwc20*~bB(KV>{PdG@PPmhMj+8cUBQaQB3 zKCv4%$XnUm*-9EIz4v7*QU7>&UuIi=uEchK-CP#af#FJ#T0yY2r88_jot2}m;Oi?2 zgTcy^*-A=FBhPal-)L*!jVc!5QBWLZG3CPR($YwF0)bv}L;d(CiiQlkt^!{eFhkdl z;9B7%V9l=h9P49VBD^#BamPK@g@t}w&?7K3@S-5=OwjUX%LeNO4!N1i9AekkkpiN7 zy5Q)Q5ZL2qg@RFThnXqCN*QG#?!)DJg*W-Z6Sy)O<^y{VHc#9?*MqF-5*`BPFt92e@8 z(gmF|#_10~Fe0t^9lr56rC!0IT+BDp?R6>7G9f4PWkNm&bn5P{uqaNn2h3Euo!%gV!O z`YqDK!&f2i^?9Z&sGl0Sr(`T$jm*xhc87?F2#2WIm#x(HXsWpz{D^iR+iv;T^r##2 z%8XaoqR&RoO*+|Gn+tmYAEI^_e!zUQ2bkCA%qmY6^A_(kVJJCn;Udm=IpF7iob9Jk zp;Qs77MqTW{=Qc&(rqlYn5j!kPv(lsa8%)<%L1ni0yihZDDidEIFVQLBa#drzXia4 zF|4Qk4sZJTGVpmvYKRJysFtTHa|=BP6}x`iN*T+Fd;W4zq&3>#l5e=2IPFgEYWP<} z8O}Dq*@^YHnUR{6zjG1)5gc$vV&OZZxrE(;4c7mr9U(lc&i`X7@FNPfA9!)}Cf&!K z1!?{zDOJeXBo%i^0e;j1*vE}1u*HA*OiI@!3NLTc6>KAIDYNH~=#$j58SXB9mFPd( zdJNQK!*gEh7@_bK8;eBEmL&)Je+{2pgr`?+x8LYo&u<#YdfpZWI)wUxW}qmhZOY&1@f*Dxq+IIT`GA^Xvd-CUXEn|clFGJ&tMcmMt0?DU;r^xg}p%Cw{x zI;YF+mBa|&?`64n69t+FD*HIHhPx8tXS)plv^ml&VuZUZ&hoKYG(?)?-w!m!RsQ6Oq<>qJZf)5P% zOov#QQfg^8`0pg-xA@4UJ0&^8|9FdSPrQ5Jk_fkFNR+@%)ijSOU;+HeuktlbV&B7V zGrU@*jE6x0LA`*S71py*{S5ZFT|uXbl7}@V0=(|wdg*zO(_EczP4bs%61fxsJP@>I zZa#VmTj%}OOGiGOxsca%W`p&QH6s!Ams(|b7Wxp(>N-rRVoetu5`ssLFKuj0A^mba zpU&rD&o&_O!}cBE5{#d!JSQjio5Pybkg_#FV>>2oC=MR&>!zQ-GRH*q`#bwlK^E83 z9K~Fj&SOXDY-`m%-%n18}Vf7B?eOU0I zK()a?cA!j$?KaF!zxE2*m?10vp(Z?5koMbiIL$sCkdgN79|&!9KigD_j2fozll{l! z;VZq$?S{vxP4s>}?9F1zDSv!PCvV)-@eWzUWlr4!+Z<&cr`Bvj${+Hxui5_F2Z}BK zCz-l6<>IBrL?Nmc(2e=PA(Ba8fNsW)yQ5$xJo$$c4mOEBH&k2BWH{}pH?zFSWZ8`j zwt;g2AABmRN@Wt^zz1Qp@0~0w3kwEI8;Hq7W7=gJ4n09%KWJ%qyr7{G;OFN@hzB;g zA2k!LrfcEL{Q_5X8qEH#!wg>=lp@#tf3P8R4hf!CUq}tVIJP za*9?GmnX8_Ba)^+_ztFLV1^C2*d&toSO-Sd{^1A+$aVi>{za)4+$8?5Cee75e$mQC zF!Iv}(>&gr)jH9N`;+xY4JoRq&@-}VdqNW7vzJo31cm%Hxr+S>y>trhs04rl)azhQ zXlTsYJHl~u4j1eBk|{?r|XvR1v>^O+g)7Z;T|KQ(0a%4=a0jqno9T%@Vd-M?pRL<2Swi*K5a^5oswf z+qwf{cOrgQ1tm|hfBUx5t@F$ctgXGW09P{c^H0sQiL%Px>B7~eFH$!CzsOZ`yVP0L zjq5$rgO?vp-=CNJ`%dH%8XZGi_mXIhdCdv&eP-L&0-EM5-Fhi_gCk;mc;v(MWg_q*^xmYTGm@a zZq5V9TS|2?U;fvJe;Epy;Cw2l;R#Yw*1ZB;J;B2jcMKK(bo@op-|qNhztwl`MFwne zj|u_uc(aqA%MzX&zf8Z7S@p*9B~n?Jnxz&lF!x3Y7o#y$I>|1-t|^T$0FCF_j?!xr z=uUh`yvtt276@qA>F})V(ibnse%9ku>3Bs+P zFc%hU!f%LlrkYo}q%Ys4ERCL;L1Mt>YP*!q*h|Kuum@py8Do3@hJhK&?RRk4j@3pM%pC`EEQUsM{Hn5sA*ShJIFegdKiWkjE@A#3w0~A|kLHUXVhgX&e2phM z;{;%Lkr`eVyT2pe@3~o&ns^PTtMem;PcmJm1kI%KRO|4zU^#p_Q+b(<|AgNhP06r& z9E2!v5Yu|0Y46|=A$# Date: Sun, 24 Nov 2013 16:51:30 -0600 Subject: [PATCH 12/18] Custom Item Code: Sakura Hokkaido's Kimono (say that 3 times fast) --- code/modules/customitems/item_defines.dm | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 9a487d3ab5..a3da19f4d1 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -951,16 +951,24 @@ icon_state = "bottle[color]" /obj/item/weapon/reagent_containers/food/drinks/flask/fluff/yuri_kornienkovich_flask - name = "Yuri's Flask" - desc = "An old gold plated flask. Nothing noteworthy about it besides it being gold and the red star on the worn out leather around it. There is also an engraving on the cap that is rather hard to see but it looks like \"Kornienkovich\" " - icon = 'icons/obj/custom_items.dmi' - icon_state = "yuri_kornienkovich_flask" + name = "Yuri's Flask" + desc = "An old gold plated flask. Nothing noteworthy about it besides it being gold and the red star on the worn out leather around it. There is also an engraving on the cap that is rather hard to see but it looks like \"Kornienkovich\" " + icon = 'icons/obj/custom_items.dmi' + icon_state = "yuri_kornienkovich_flask" /obj/item/clothing/under/fluff/mai_yang_dress // Mai Yang's pretty pretty dress. - name = "White Cheongsam" - desc = "It is a white cheongsam dress." - icon = 'icons/obj/custom_items.dmi' - icon_state = "mai_yang" - item_state = "mai_yang" - item_color = "mai_yang" + name = "White Cheongsam" + desc = "It is a white cheongsam dress." + icon = 'icons/obj/custom_items.dmi' + icon_state = "mai_yang" + item_state = "mai_yang" + item_color = "mai_yang" + +/obj/item/clothing/under/fluff/sakura_hokkaido_kimono // Mai Yang's pretty pretty dress. + name = "Sakura Kimono" + desc = "A pale-pink, nearly white, kimono with a red and gold obi. There is a embroidered design of cherry blossom flowers covering the kimono." + icon = 'icons/obj/custom_items.dmi' + icon_state = "sakura_hokkaido_kimono" + item_state = "sakura_hokkaido_kimono" + item_color = "sakura_hokkaido_kimono" From cc5418b3cd10bef5715a67615bc5ae728a80ed19 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Sun, 24 Nov 2013 16:57:18 -0600 Subject: [PATCH 13/18] Requested removal. Seth Sealis - Gray Coat Ashley Rifler - Purple Glove http://baystation12.net/forums/viewtopic.php?f=33&t=9097 --- code/modules/customitems/item_defines.dm | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index a3da19f4d1..3644b7ae69 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -494,12 +494,6 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "chal_appara_1" -/obj/item/clothing/gloves/fluff/ashley_rifler_1 //Vinceluk: Ashley Rifler - name = "Purple Glove" - desc = "A single, purple glove. Initials A.R. are written on the inside of it." - icon = 'icons/obj/custom_items.dmi' - icon_state = "ashley_rifler_1" - //////////// Eye Wear //////////// /obj/item/clothing/glasses/meson/fluff/book_berner_1 //asanadas: Book Berner @@ -591,14 +585,6 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "labcoat_pink_open" -/obj/item/clothing/suit/storage/det_suit/fluff/graycoat //vinceluk: Seth Sealis - name = "gray coat" - desc = "Old, worn out coat. It's seen better days." - icon = 'icons/obj/custom_items.dmi' - icon_state = "graycoat" - item_state = "graycoat" - item_color = "graycoat" - /obj/item/clothing/suit/storage/det_suit/fluff/leatherjack //atomicdog92: Seth Sealis name = "leather jacket" desc = "A black leather coat, popular amongst punks, greasers, and other galactic scum." @@ -964,7 +950,7 @@ item_state = "mai_yang" item_color = "mai_yang" -/obj/item/clothing/under/fluff/sakura_hokkaido_kimono // Mai Yang's pretty pretty dress. +/obj/item/clothing/under/fluff/sakura_hokkaido_kimono name = "Sakura Kimono" desc = "A pale-pink, nearly white, kimono with a red and gold obi. There is a embroidered design of cherry blossom flowers covering the kimono." icon = 'icons/obj/custom_items.dmi' From d8683f2d39d894b31cacefc03dcd16688cf51bbe Mon Sep 17 00:00:00 2001 From: Mloc Date: Mon, 25 Nov 2013 11:59:57 +0000 Subject: [PATCH 14/18] Revert "Merge pull request #3965 from jack-fractal/dev" This reverts commit fa57b76f25ea9d00fb92c034464ab540e0fb387b, reversing changes made to 40ee2278ede129f09f6458370f647ec86082da92. Signed-off-by: Mloc --- baystation12.dme | 12 - .../AI_Visibility/_old_AI_Visibility.dm | 68 +- code/WorkInProgress/AI_Visibility/ai.dm | 10 +- .../WorkInProgress/AI_Visibility/cameranet.dm | 24 +- code/WorkInProgress/AI_Visibility/chunk.dm | 2 +- code/WorkInProgress/AI_Visibility/minimap.dm | 24 +- code/WorkInProgress/AI_Visibility/util.dm | 14 +- code/__HELPERS/global_lists.dm | 1 - code/controllers/verbs.dm | 8 +- code/datums/datumvars.dm | 14 +- code/datums/mind.dm | 15 +- code/datums/visibility_networks/chunk.dm | 179 -- code/datums/visibility_networks/dictionary.dm | 11 - .../visibility_networks/update_triggers.dm | 94 - .../visibility_interface.dm | 46 - .../visibility_networks/visibility_network.dm | 141 -- code/defines/obj/weapon.dm | 3 +- code/game/gamemodes/cult/cult.dm | 159 +- code/game/gamemodes/cult/ritual.dm | 206 +- code/game/gamemodes/cult/runes.dm | 1826 ++++++++--------- .../gamemodes/malfunction/Malf_Modules.dm | 6 +- code/game/machinery/camera/camera.dm | 8 +- code/game/machinery/camera/camera_assembly.dm | 2 +- code/game/machinery/camera/tracking.dm | 6 +- code/game/machinery/computer/camera.dm | 4 +- code/game/machinery/doors/door.dm | 4 - code/modules/admin/admin.dm | 1 - code/modules/admin/admin_investigate.dm | 40 +- code/modules/admin/topic.dm | 9 - code/modules/admin/verbs/mapping.dm | 4 +- code/modules/clothing/spacesuits/ert.dm | 2 +- code/modules/clothing/spacesuits/rig.dm | 2 +- code/modules/mob/living/carbon/human/death.dm | 7 +- code/modules/mob/living/living.dm | 1 - code/modules/mob/living/silicon/ai/ai.dm | 6 +- .../living/silicon/ai/freelook/cameranet.dm | 160 +- .../mob/living/silicon/ai/freelook/chunk.dm | 185 +- .../mob/living/silicon/ai/freelook/eye.dm | 11 +- .../mob/living/silicon/ai/freelook/read_me.dm | 2 +- .../silicon/ai/freelook/update_triggers.dm | 87 +- .../ai/freelook/visibility_interface.dm | 10 - .../modules/mob/living/silicon/robot/robot.dm | 7 +- code/modules/mob/mob.dm | 11 +- code/modules/mob/mob_defines.dm | 1 - code/modules/mob/mob_helpers.dm | 5 - code/modules/mob/mob_movement.dm | 11 +- code/modules/mob/new_player/new_player.dm | 4 +- code/modules/mob/spirit/cultnet.dm | 80 - code/modules/mob/spirit/mask/mask.dm | 227 -- code/modules/mob/spirit/mask/respawn.dm | 20 - code/modules/mob/spirit/movement.dm | 62 - code/modules/mob/spirit/spirit.dm | 76 - code/modules/mob/spirit/viewpoint.dm | 202 -- code/modules/mob/transform_procs.dm | 52 - code/setup.dm | 3 - code/stylesheet.dm | 1 - code/unused/AI_Visibility.dm | 30 +- icons/mob/spirits/mask.dmi | Bin 972 -> 0 bytes 58 files changed, 1590 insertions(+), 2616 deletions(-) delete mode 100644 code/datums/visibility_networks/chunk.dm delete mode 100644 code/datums/visibility_networks/dictionary.dm delete mode 100644 code/datums/visibility_networks/update_triggers.dm delete mode 100644 code/datums/visibility_networks/visibility_interface.dm delete mode 100644 code/datums/visibility_networks/visibility_network.dm delete mode 100644 code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm delete mode 100644 code/modules/mob/spirit/cultnet.dm delete mode 100644 code/modules/mob/spirit/mask/mask.dm delete mode 100644 code/modules/mob/spirit/mask/respawn.dm delete mode 100644 code/modules/mob/spirit/movement.dm delete mode 100644 code/modules/mob/spirit/spirit.dm delete mode 100644 code/modules/mob/spirit/viewpoint.dm delete mode 100644 icons/mob/spirits/mask.dmi diff --git a/baystation12.dme b/baystation12.dme index 1088ce6c88..722e05dfe7 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -155,11 +155,6 @@ #include "code\datums\spells\trigger.dm" #include "code\datums\spells\turf_teleport.dm" #include "code\datums\spells\wizard.dm" -#include "code\datums\visibility_networks\chunk.dm" -#include "code\datums\visibility_networks\dictionary.dm" -#include "code\datums\visibility_networks\update_triggers.dm" -#include "code\datums\visibility_networks\visibility_interface.dm" -#include "code\datums\visibility_networks\visibility_network.dm" #include "code\defines\obj.dm" #include "code\defines\obj\hydro.dm" #include "code\defines\obj\weapon.dm" @@ -961,7 +956,6 @@ #include "code\modules\mob\living\silicon\ai\freelook\eye.dm" #include "code\modules\mob\living\silicon\ai\freelook\read_me.dm" #include "code\modules\mob\living\silicon\ai\freelook\update_triggers.dm" -#include "code\modules\mob\living\silicon\ai\freelook\visibility_interface.dm" #include "code\modules\mob\living\silicon\decoy\death.dm" #include "code\modules\mob\living\silicon\decoy\decoy.dm" #include "code\modules\mob\living\silicon\decoy\life.dm" @@ -1030,12 +1024,6 @@ #include "code\modules\mob\new_player\preferences_setup.dm" #include "code\modules\mob\new_player\skill.dm" #include "code\modules\mob\new_player\sprite_accessories.dm" -#include "code\modules\mob\spirit\cultnet.dm" -#include "code\modules\mob\spirit\movement.dm" -#include "code\modules\mob\spirit\spirit.dm" -#include "code\modules\mob\spirit\viewpoint.dm" -#include "code\modules\mob\spirit\mask\mask.dm" -#include "code\modules\mob\spirit\mask\respawn.dm" #include "code\modules\nano\_JSON.dm" #include "code\modules\nano\JSON Reader.dm" #include "code\modules\nano\JSON Writer.dm" diff --git a/code/WorkInProgress/AI_Visibility/_old_AI_Visibility.dm b/code/WorkInProgress/AI_Visibility/_old_AI_Visibility.dm index 831d20f229..9b50c74f68 100644 --- a/code/WorkInProgress/AI_Visibility/_old_AI_Visibility.dm +++ b/code/WorkInProgress/AI_Visibility/_old_AI_Visibility.dm @@ -16,15 +16,15 @@ var/image/dim /turf/proc/visibilityChanged() - cameraNetwork.updateVisibility(src) + cameranet.updateVisibility(src) /turf/New() ..() - cameraNetwork.updateVisibility(src) + cameranet.updateVisibility(src) /* /turf/Del() ..() - cameraNetwork.updateVisibility(src) + cameranet.updateVisibility(src) */ /datum/camerachunk var/list/obscuredTurfs = list() @@ -73,7 +73,7 @@ var/mob/living/silicon/ai/ai = usr ai.freelook() ai.eyeobj.loc = locate(max(1, x - 1), max(1, y - 1), ai.eyeobj.z) - cameraNetwork.visibility(ai.eyeobj) + cameranet.visibility(ai.eyeobj) else usr.loc = locate(max(1, x - 1), max(1, y - 1), usr.z) @@ -81,26 +81,26 @@ /mob/dead/verb/Open_Minimap() set category = "Ghost" winshow(src, "minimapwindow", 1) - client.screen |= cameraNetwork.minimap + client.screen |= cameranet.minimap - if(cameraNetwork.generating_minimap) - cameraNetwork.minimap_viewers += src + 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 |= cameraNetwork.minimap + client.screen |= cameranet.minimap - if(cameraNetwork.generating_minimap) - cameraNetwork.minimap_viewers += src + if(cameranet.generating_minimap) + cameranet.minimap_viewers += src /client/proc/Open_Minimap() set category = "Admin" winshow(src, "minimapwindow", 1) - screen |= cameraNetwork.minimap + screen |= cameranet.minimap - if(cameraNetwork.generating_minimap) - cameraNetwork.minimap_viewers += src.mob + if(cameranet.generating_minimap) + cameranet.minimap_viewers += src.mob /datum/camerachunk/proc/update_minimap() if(changed && !updating) @@ -325,11 +325,11 @@ dim += t.dim - cameraNetwork.minimap += minimap_obj + cameranet.minimap += minimap_obj -var/datum/cameraNetwork/cameraNetwork = new() +var/datum/cameranet/cameranet = new() -/datum/cameraNetwork +/datum/cameranet var/list/cameras = list() var/list/chunks = list() var/network = "net1" @@ -340,7 +340,7 @@ var/datum/cameraNetwork/cameraNetwork = new() var/generating_minimap = TRUE var/list/minimap_viewers = list() -/datum/cameraNetwork/New() +/datum/cameranet/New() ..() spawn(200) @@ -356,11 +356,11 @@ var/datum/cameraNetwork/cameraNetwork = new() generating_minimap = FALSE minimap_viewers = list() -/datum/cameraNetwork/proc/chunkGenerated(x, y, z) +/datum/cameranet/proc/chunkGenerated(x, y, z) var/key = "[x],[y],[z]" return key in chunks -/datum/cameraNetwork/proc/getCameraChunk(x, y, z) +/datum/cameranet/proc/getCameraChunk(x, y, z) var/key = "[x],[y],[z]" if(!(key in chunks)) @@ -368,7 +368,7 @@ var/datum/cameraNetwork/cameraNetwork = new() return chunks[key] -/datum/cameraNetwork/proc/visibility(mob/aiEye/ai) +/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 @@ -389,14 +389,14 @@ var/datum/cameraNetwork/cameraNetwork = new() for(var/datum/camerachunk/c in add) c.add(ai) -/datum/cameraNetwork/proc/updateVisibility(turf/loc) +/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/cameraNetwork/proc/addCamera(obj/machinery/camera/c) +/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 @@ -410,7 +410,7 @@ var/datum/cameraNetwork/cameraNetwork = new() chunk.cameras += c chunk.hasChanged() -/datum/cameraNetwork/proc/removeCamera(obj/machinery/camera/c) +/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 @@ -452,18 +452,18 @@ var/datum/cameraNetwork/cameraNetwork = new() eyeobj.ai = src client.eye = eyeobj eyeobj.loc = loc - cameraNetwork.visibility(eyeobj) + cameranet.visibility(eyeobj) cameraFollow = null /mob/aiEye/Move() . = ..() if(.) - cameraNetwork.visibility(src) + 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) - cameraNetwork.visibility(user.eyeobj) + cameranet.visibility(user.eyeobj) else return ..() @@ -477,7 +477,7 @@ var/datum/cameraNetwork/cameraNetwork = new() else if(direct == DOWN && user.eyeobj.z < 4) dif = 1 user.eyeobj.loc = locate(user.eyeobj.x, user.eyeobj.y, user.eyeobj.z + dif) - cameraNetwork.visibility(user.eyeobj) + cameranet.visibility(user.eyeobj) else return ..() */ @@ -492,23 +492,23 @@ var/datum/cameraNetwork/cameraNetwork = new() /obj/machinery/door/update_nearby_tiles(need_rebuild) . = ..(need_rebuild) - cameraNetwork.updateVisibility(loc) + cameranet.updateVisibility(loc) /obj/machinery/camera/New() ..() - cameraNetwork.addViewpoint(src) + cameranet.addCamera(src) /obj/machinery/camera/Del() - cameraNetwork.removeViewpoint(src) + 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) - cameraNetwork.addViewpoint(src) + cameranet.addCamera(src) else - cameraNetwork.removeViewpoint(src) + cameranet.removeCamera(src) /proc/checkcameravis(atom/A) for(var/obj/machinery/camera/C in view(A,7)) @@ -545,7 +545,7 @@ var/datum/cameraNetwork/cameraNetwork = new() var/obj/machinery/camera/C = D[t] eyeobj.loc = C.loc - cameraNetwork.visibility(eyeobj) + cameranet.visibility(eyeobj) return @@ -570,4 +570,4 @@ var/datum/cameraNetwork/cameraNetwork = new() else eyeobj.loc = locate(src.x, src.y, src.z) - cameraNetwork.visibility(eyeobj) + cameranet.visibility(eyeobj) diff --git a/code/WorkInProgress/AI_Visibility/ai.dm b/code/WorkInProgress/AI_Visibility/ai.dm index a8c5470036..7dcbf54e67 100644 --- a/code/WorkInProgress/AI_Visibility/ai.dm +++ b/code/WorkInProgress/AI_Visibility/ai.dm @@ -29,17 +29,17 @@ eyeobj.ai = src client.eye = eyeobj eyeobj.loc = loc - cameraNetwork.visibility(eyeobj) + cameranet.visibility(eyeobj) /mob/aiEye/Move() . = ..() if(.) - cameraNetwork.visibility(src) + 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) - cameraNetwork.visibility(user.eyeobj) + cameranet.visibility(user.eyeobj) else return ..() @@ -79,7 +79,7 @@ var/obj/machinery/camera/C = D[t] eyeobj.loc = C.loc - cameraNetwork.visibility(eyeobj) + cameranet.visibility(eyeobj) return @@ -104,4 +104,4 @@ else eyeobj.loc = locate(src.x, src.y, src.z) - cameraNetwork.visibility(eyeobj) + cameranet.visibility(eyeobj) diff --git a/code/WorkInProgress/AI_Visibility/cameranet.dm b/code/WorkInProgress/AI_Visibility/cameranet.dm index d234142511..3b46844e6b 100644 --- a/code/WorkInProgress/AI_Visibility/cameranet.dm +++ b/code/WorkInProgress/AI_Visibility/cameranet.dm @@ -1,14 +1,14 @@ //------------------------------------------------------------ // -// The cameraNetwork +// The Cameranet // -// The cameraNetwork is a single global instance of a unique +// The cameranet is a single global instance of a unique // datum, which contains logic for managing the individual // chunks. // //------------------------------------------------------------ -/datum/cameraNetwork +/datum/cameranet var/list/cameras = list() var/list/chunks = list() var/network = "net1" @@ -18,18 +18,18 @@ var/generating_minimap = TRUE -var/datum/cameraNetwork/cameraNetwork = new() +var/datum/cameranet/cameranet = new() -/datum/cameraNetwork/New() +/datum/cameranet/New() ..() spawn(100) init_minimap() -/datum/cameraNetwork/proc/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) @@ -39,12 +39,12 @@ var/datum/cameraNetwork/cameraNetwork = new() generating_minimap = FALSE -/datum/cameraNetwork/proc/chunkGenerated(x, y, z) +/datum/cameranet/proc/chunkGenerated(x, y, z) var/key = "[x],[y],[z]" return key in chunks -/datum/cameraNetwork/proc/getCameraChunk(x, y, z) +/datum/cameranet/proc/getCameraChunk(x, y, z) var/key = "[x],[y],[z]" if(!(key in chunks)) @@ -71,7 +71,7 @@ var/datum/cameraNetwork/cameraNetwork = new() // have a proc called automatically every time an // object's loc changes. -/datum/cameraNetwork/proc/visibility(mob/aiEye/ai) +/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 @@ -101,7 +101,7 @@ var/datum/cameraNetwork/cameraNetwork = new() // anything else that would alter line of sight in the // general area. -/datum/cameraNetwork/proc/updateVisibility(turf/loc) +/datum/cameranet/proc/updateVisibility(turf/loc) if(!chunkGenerated(loc.x & ~0xf, loc.y & ~0xf, loc.z)) return @@ -115,7 +115,7 @@ var/datum/cameraNetwork/cameraNetwork = new() // creating a camera, allowing freelook and the minimap to // respond correctly. -/datum/cameraNetwork/proc/addCamera(obj/machinery/camera/c) +/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 @@ -137,7 +137,7 @@ var/datum/cameraNetwork/cameraNetwork = new() // deleting a camera, allowing freelook and the minimap to // respond correctly. -/datum/cameraNetwork/proc/removeCamera(obj/machinery/camera/c) +/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 diff --git a/code/WorkInProgress/AI_Visibility/chunk.dm b/code/WorkInProgress/AI_Visibility/chunk.dm index 134d6097b5..8a6886a1ad 100644 --- a/code/WorkInProgress/AI_Visibility/chunk.dm +++ b/code/WorkInProgress/AI_Visibility/chunk.dm @@ -88,7 +88,7 @@ dim += t.dim - cameraNetwork.minimap |= minimap_obj + cameranet.minimap |= minimap_obj for(var/mob/aiEye/eye in seenby) if(eye.ai.client) diff --git a/code/WorkInProgress/AI_Visibility/minimap.dm b/code/WorkInProgress/AI_Visibility/minimap.dm index e4d4f7274f..c97b01e0f8 100644 --- a/code/WorkInProgress/AI_Visibility/minimap.dm +++ b/code/WorkInProgress/AI_Visibility/minimap.dm @@ -28,24 +28,24 @@ 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) - cameraNetwork.visibility(ai.eyeobj) + 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" - cameraNetwork.show_minimap(client) + cameranet.show_minimap(client) /mob/living/silicon/ai/verb/Open_Minimap() set category = "AI Commands" - cameraNetwork.show_minimap(client) + cameranet.show_minimap(client) /client/proc/Open_Minimap() set category = "Admin" - cameraNetwork.show_minimap(src) + cameranet.show_minimap(src) /mob/verb/Open_Minimap_Z() @@ -54,26 +54,26 @@ 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 cameraNetwork.minimap + var/level = input("Select a Z level", "Z select", null) as null | anything in cameranet.minimap if(level != null) - cameraNetwork.show_minimap(client, level) + cameranet.show_minimap(client, level) -/datum/cameraNetwork/proc/show_minimap(client/client, z_level = "z-1") +/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 cameraNetwork.minimap) + if(z_level in cameranet.minimap) winshow(client, "minimapwindow", 1) - for(var/key in cameraNetwork.minimap) - client.screen -= cameraNetwork.minimap[key] + for(var/key in cameranet.minimap) + client.screen -= cameranet.minimap[key] - client.screen |= cameraNetwork.minimap[z_level] + client.screen |= cameranet.minimap[z_level] - if(cameraNetwork.generating_minimap) + if(cameranet.generating_minimap) spawn(50) show_minimap(client, z_level) diff --git a/code/WorkInProgress/AI_Visibility/util.dm b/code/WorkInProgress/AI_Visibility/util.dm index 0e32f8dec8..da576cbd40 100644 --- a/code/WorkInProgress/AI_Visibility/util.dm +++ b/code/WorkInProgress/AI_Visibility/util.dm @@ -4,31 +4,31 @@ var/image/dim /turf/proc/visibilityChanged() - cameraNetwork.updateVisibility(src) + cameranet.updateVisibility(src) /turf/New() ..() - cameraNetwork.updateVisibility(src) + cameranet.updateVisibility(src) /obj/machinery/door/update_nearby_tiles(need_rebuild) . = ..(need_rebuild) - cameraNetwork.updateVisibility(loc) + cameranet.updateVisibility(loc) /obj/machinery/camera/New() ..() - cameraNetwork.addViewpoint(src) + cameranet.addCamera(src) /obj/machinery/camera/Del() - cameraNetwork.removeViewpoint(src) + 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) - cameraNetwork.addViewpoint(src) + cameranet.addCamera(src) else - cameraNetwork.removeViewpoint(src) + cameranet.removeCamera(src) /proc/checkcameravis(atom/A) for(var/obj/machinery/camera/C in view(A,7)) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index b0d609c78e..ce8d788f25 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -7,7 +7,6 @@ var/list/directory = list() //list of all ckeys with associated client var/global/list/player_list = list() //List of all mobs **with clients attached**. Excludes /mob/new_player var/global/list/mob_list = list() //List of all mobs, including clientless -var/global/list/spirits = list() //List of all the spirits, including Masks var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 1b8324ef43..3faa6e4c80 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -28,7 +28,7 @@ return -/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller","CultNetwork")) +/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -72,14 +72,10 @@ debug_variables(paiController) feedback_add_details("admin_verb","DpAI") if("Cameras") - debug_variables(cameraNetwork) + debug_variables(cameranet) feedback_add_details("admin_verb","DCameras") if("Transfer Controller") debug_variables(transfer_controller) feedback_add_details("admin_verb","DAutovoter") - if("CultNetwork") - debug_variables(cultNetwork) - feedback_add_details("admin_verb","DCultNetwork") - message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") return diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 7c1dbb0f8c..dc3a3b36db 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -263,7 +263,6 @@ client body += "" body += "" body += "" - body += "" body += "" body += "" body += "" @@ -725,18 +724,7 @@ client usr << "Mob doesn't exist anymore" return holder.Topic(href, list("makeai"=href_list["makeai"])) - - - else if(href_list["makemask"]) - if(!check_rights(R_SPAWN)) return - var/mob/currentMob = locate(href_list["makemask"]) - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!currentMob) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makemask"=href_list["makemask"])) - - + else if(href_list["setmutantrace"]) if(!check_rights(R_SPAWN)) return diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 01f68d3ac0..7adc6a9679 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -578,14 +578,25 @@ datum/mind switch(href_list["cult"]) if("clear") if(src in ticker.mode.cult) - ticker.mode.remove_cultist(src) + ticker.mode.cult -= src + ticker.mode.update_cult_icons_removed(src) + special_role = null + var/datum/game_mode/cult/cult = ticker.mode + if (istype(cult)) + cult.memoize_cult_objectives(src) + current << "\red You have been brainwashed! You are no longer a cultist!" + memory = "" log_admin("[key_name_admin(usr)] has de-cult'ed [current].") if("cultist") if(!(src in ticker.mode.cult)) - ticker.mode.add_cultist(src) + ticker.mode.cult += src + ticker.mode.update_cult_icons_added(src) special_role = "Cultist" current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + var/datum/game_mode/cult/cult = ticker.mode + if (istype(cult)) + cult.memoize_cult_objectives(src) log_admin("[key_name_admin(usr)] has cult'ed [current].") if("tome") var/mob/living/carbon/human/H = current diff --git a/code/datums/visibility_networks/chunk.dm b/code/datums/visibility_networks/chunk.dm deleted file mode 100644 index 4abc1340b0..0000000000 --- a/code/datums/visibility_networks/chunk.dm +++ /dev/null @@ -1,179 +0,0 @@ -#define UPDATE_BUFFER 25 // 2.5 seconds - -// CAMERA CHUNK -// -// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. -// Allows the mob using this chunk to stream these chunks and know what it can and cannot see. - -/datum/visibility_chunk - var/obscured_image = 'icons/effects/cameravis.dmi' - var/obscured_sub = "black" - var/list/obscuredTurfs = list() - var/list/visibleTurfs = list() - var/list/obscured = list() - var/list/viewpoints = list() - var/list/turfs = list() - var/list/seenby = list() - var/visible = 0 - var/changed = 0 - var/updating = 0 - var/x = 0 - var/y = 0 - var/z = 0 - -/datum/visibility_chunk/proc/add(mob/new_mob) - - // if this thing doesn't use one of these visibility systems, kick it out - if (!new_mob.visibility_interface) - return - - // if the mob being added isn't a valid form of that mob, kick it out - if (!new_mob.visibility_interface:canBeAddedToChunk(src)) - return - - // add this chunk to the list of visible chunks - new_mob.visibility_interface:addChunk(src) - - visible++ - seenby += new_mob - if(changed && !updating) - update() - -/datum/visibility_chunk/proc/remove(mob/new_mob) - // if this thing doesn't use one of these visibility systems, kick it out - if (!new_mob.visibility_interface) - return - - // if the mob being added isn't a valid form of that mob, kick it out - if (!new_mob.visibility_interface:canBeAddedToChunk(src)) - return - - // remove the chunk - new_mob.visibility_interface:removeChunk(src) - - // remove the mob from out lists - seenby -= new_mob - if(visible > 0) - visible-- - -/datum/visibility_chunk/proc/visibilityChanged(turf/loc) - if(!visibleTurfs[loc]) - return - hasChanged() - -/datum/visibility_chunk/proc/hasChanged(var/update_now = 0) - if(visible || update_now) - if(!updating) - updating = 1 - spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once - update() - updating = 0 - else - changed = 1 - - -/* -This function needs to be overwritten to return True if the viewpoint object is valid, and false if it is not. -*/ -/datum/visibility_chunk/proc/validViewpoint(var/viewpoint) - return FALSE - -/* -This function needs to be overwritten to return a list of visible turfs for that viewpoint -*/ -/datum/visibility_chunk/proc/getVisibleTurfsForViewpoint(var/viewpoint) - return list() - -// returns a list of turfs which can be seen in by the chunks viewpoints -/datum/visibility_chunk/proc/getVisibleTurfs() - var/list/newVisibleTurfs = list() - for(var/viewpoint in viewpoints) - if (validViewpoint(viewpoint)) - for (var/turf/t in getVisibleTurfsForViewpoint(viewpoint)) - newVisibleTurfs[t]=t - return newVisibleTurfs - -/* -This function needs to be overwritten to find nearby viewpoint objects to the chunk center. -*/ -/datum/visibility_chunk/proc/findNearbyViewpoints() - return FALSE - -/* -This function can be overwritten to change or randomize the obscuring images -*/ -/datum/visibility_chunk/proc/setObscuredImage(var/turf/target_turf) - if(!target_turf.obscured) - target_turf.obscured = image(obscured_image, target_turf, obscured_sub, 15) - -/datum/visibility_chunk/proc/update() - - set background = 1 - - // get a list of all the turfs that our viewpoints can see - var/list/newVisibleTurfs = getVisibleTurfs() - - // Removes turf that isn't in turfs. - newVisibleTurfs &= turfs - - var/list/visAdded = newVisibleTurfs - visibleTurfs - var/list/visRemoved = visibleTurfs - newVisibleTurfs - - visibleTurfs = newVisibleTurfs - obscuredTurfs = turfs - newVisibleTurfs - - // update the visibility overlays - for(var/turf in visAdded) - var/turf/t = turf - if(t.obscured) - obscured -= t.obscured - for(var/mob/current_mob in seenby) - if (current_mob.visibility_interface) - current_mob.visibility_interface:removeObscuredTurf(t) - - for(var/turf in visRemoved) - var/turf/t = turf - if(obscuredTurfs[t]) - setObscuredImage(t) - obscured += t.obscured - for(var/mob/current_mob in seenby) - if (current_mob.visibility_interface) - current_mob.visibility_interface:addObscuredTurf(t) - else - seenby -= current_mob - - -// Create a new chunk, since the chunks are made as they are needed. -/datum/visibility_chunk/New(loc, x, y, z) - - // 0xf = 15 - x &= ~0xf - y &= ~0xf - - src.x = x - src.y = y - src.z = z - - 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] = t - - // locate all nearby viewpoints - findNearbyViewpoints() - - // get the turfs that are visible to those viewpoints - visibleTurfs = getVisibleTurfs() - - // Removes turf that isn't in turfs. - visibleTurfs &= turfs - - // create the list of turfs we can't see - obscuredTurfs = turfs - visibleTurfs - - // create the list of obscuring images to add to viewing clients - for(var/turf in obscuredTurfs) - var/turf/t = turf - setObscuredImage(t) - obscured += t.obscured - -#undef UPDATE_BUFFER \ No newline at end of file diff --git a/code/datums/visibility_networks/dictionary.dm b/code/datums/visibility_networks/dictionary.dm deleted file mode 100644 index 3dcb1bc427..0000000000 --- a/code/datums/visibility_networks/dictionary.dm +++ /dev/null @@ -1,11 +0,0 @@ -var/datum/visibility_network/cameras/cameraNetwork = new() -var/datum/visibility_network/cult/cultNetwork = new() -var/datum/visibility_network/list/visibility_networks = list("ALL_CAMERAS"=cameraNetwork, "CULT" = cultNetwork) - - -// used by turfs and objects to update all visibility networks -/proc/updateVisibilityNetworks(atom/A, var/opacity_check = 1) - var/datum/visibility_network/currentNetwork - for (var/networkName in visibility_networks) - currentNetwork = visibility_networks[networkName] - currentNetwork.updateVisibility(A, opacity_check) \ No newline at end of file diff --git a/code/datums/visibility_networks/update_triggers.dm b/code/datums/visibility_networks/update_triggers.dm deleted file mode 100644 index f1835eeeb5..0000000000 --- a/code/datums/visibility_networks/update_triggers.dm +++ /dev/null @@ -1,94 +0,0 @@ -//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. - -// TURFS - -/turf - var/image/obscured - -/turf/proc/visibilityChanged() - if(ticker) - updateVisibilityNetworks(src) - -/turf/simulated/Del() - visibilityChanged() - ..() - -/turf/simulated/New() - ..() - visibilityChanged() - - - -// STRUCTURES - -/obj/structure/Del() - if(ticker) - updateVisibilityNetworks(src) - ..() - -/obj/structure/New() - ..() - if(ticker) - updateVisibilityNetworks(src) - -// EFFECTS - -/obj/effect/Del() - if(ticker) - updateVisibilityNetworks(src) - ..() - -/obj/effect/New() - ..() - if(ticker) - updateVisibilityNetworks(src) - - -// DOORS - -// Simply updates the visibility of the area when it opens/closes/destroyed. -/obj/machinery/door/proc/update_nearby_tiles(need_rebuild) - - if(!glass) - updateVisibilityNetworks(src,0) - - if(!air_master) - return 0 - - for(var/turf/simulated/turf in locs) - update_heat_protection(turf) - air_master.AddTurfToUpdate(turf) - - return 1 - - - -#define UPDATE_VISIBILITY_NETWORK_BUFFER 30 - -/mob - var/datum/visibility_network/list/visibilityNetworks=list() - var/updatingVisibilityNetworks=FALSE - -/mob/Move(n,direct) - var/oldLoc = src.loc - . = ..() - if(.) - if(src.visibilityNetworks.len) - if(!src.updatingVisibilityNetworks) - src.updatingVisibilityNetworks = 1 - spawn(UPDATE_VISIBILITY_NETWORK_BUFFER) - if(oldLoc != src.loc) - for (var/datum/visibility_network/currentNetwork in src.visibilityNetworks) - currentNetwork.updateMob(src) - src.updatingVisibilityNetworks = 0 - return ..(n,direct) - -/mob/proc/addToVisibilityNetwork(var/datum/visibility_network/network) - if(network) - src.visibilityNetworks+=network - -/mob/proc/removeFromVisibilityNetwork(var/datum/visibility_network/network) - if(network) - src.visibilityNetworks|=network - -#undef UPDATE_VISIBILITY_NETWORK_BUFFER \ No newline at end of file diff --git a/code/datums/visibility_networks/visibility_interface.dm b/code/datums/visibility_networks/visibility_interface.dm deleted file mode 100644 index 7d8efba41d..0000000000 --- a/code/datums/visibility_networks/visibility_interface.dm +++ /dev/null @@ -1,46 +0,0 @@ -/datum/visibility_interface - var/chunk_type = null - var/mob/controller = null - var/list/visible_chunks = list() - - -/datum/visibility_interface/New(var/mob/controller) - src.controller = controller - - -/datum/visibility_interface/proc/validMob() - return getClient() - -/datum/visibility_interface/proc/getClient() - return controller.client - -/datum/visibility_interface/proc/canBeAddedToChunk(var/datum/visibility_chunk/test_chunk) - return istype(test_chunk,chunk_type) - - -/datum/visibility_interface/proc/addChunk(var/datum/visibility_chunk/test_chunk) - visible_chunks+=test_chunk - var/client/currentClient = getClient() - if(currentClient) - currentClient.images += test_chunk.obscured - - -/datum/visibility_interface/proc/removeChunk(var/datum/visibility_chunk/test_chunk) - visible_chunks-=test_chunk - var/client/currentClient = getClient() - if(currentClient) - currentClient.images -= test_chunk.obscured - - -/datum/visibility_interface/proc/removeObscuredTurf(var/turf/target_turf) - if(validMob()) - var/client/currentClient = getClient() - if(currentClient) - currentClient.images -= target_turf.obscured - - -/datum/visibility_interface/proc/addObscuredTurf(var/turf/target_turf) - if(validMob()) - var/client/currentClient = getClient() - if(currentClient) - currentClient.images -= target_turf.obscured \ No newline at end of file diff --git a/code/datums/visibility_networks/visibility_network.dm b/code/datums/visibility_networks/visibility_network.dm deleted file mode 100644 index 225b6e3def..0000000000 --- a/code/datums/visibility_networks/visibility_network.dm +++ /dev/null @@ -1,141 +0,0 @@ -/datum/visibility_network - var/list/viewpoints = list() - - // the type of chunk used by this network - var/datum/visibility_chunk/ChunkType = /datum/visibility_chunk - - // The chunks of the map, mapping the areas that the viewpoints can see. - var/list/chunks = list() - - var/ready = 0 - - -// Creates a chunk key string from x,y,z coordinates -/datum/visibility_network/proc/createChunkKey(x,y,z) - x &= ~0xf - y &= ~0xf - return "[x],[y],[z]" - - -// Checks if a chunk has been Generated in x, y, z. -/datum/visibility_network/proc/chunkGenerated(x, y, z) - return (chunks[createChunkKey(x, y, z)]) - - -// Returns the chunk in the x, y, z. -// If there is no chunk, it creates a new chunk and returns that. -/datum/visibility_network/proc/getChunk(x, y, z) - var/key = createChunkKey(x, y, z) - if(!chunks[key]) - chunks[key] = new ChunkType(null, x, y, z) - return chunks[key] - - -/datum/visibility_network/proc/visibility(var/mob/targetMob) - - // if we've got not visibility interface on the mob, we canot do this - if (!targetMob.visibility_interface) - return - - // 0xf = 15 - var/x1 = max(0, targetMob.x - 16) & ~0xf - var/y1 = max(0, targetMob.y - 16) & ~0xf - var/x2 = min(world.maxx, targetMob.x + 16) & ~0xf - var/y2 = min(world.maxy, targetMob.y + 16) & ~0xf - - var/list/visibleChunks = list() - - for(var/x = x1; x <= x2; x += 16) - for(var/y = y1; y <= y2; y += 16) - visibleChunks += getChunk(x, y, targetMob.z) - - var/list/remove = targetMob.visibility_interface:visible_chunks - visibleChunks - var/list/add = visibleChunks - targetMob.visibility_interface:visible_chunks - - for(var/datum/visibility_chunk/chunk in remove) - chunk.remove(targetMob) - - for(var/datum/visibility_chunk/chunk in add) - chunk.add(targetMob) - - -// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. -/datum/visibility_network/proc/updateVisibility(atom/A, var/opacity_check = 1) - if(!ticker || (opacity_check && !A.opacity)) - return - majorChunkChange(A, 2) - - -/datum/visibility_network/proc/updateChunk(x, y, z) - if(!chunkGenerated(x, y, z)) - return - var/datum/visibility_chunk/chunk = getChunk(x, y, z) - chunk.hasChanged() - - -/datum/visibility_network/proc/validViewpoint(var/viewpoint) - return FALSE - - -/datum/visibility_network/proc/addViewpoint(var/viewpoint) - if(validViewpoint(viewpoint)) - majorChunkChange(viewpoint, 1) - - -/datum/visibility_network/proc/removeViewpoint(var/viewpoint) - if(validViewpoint(viewpoint)) - majorChunkChange(viewpoint, 0) - -/datum/visibility_network/proc/getViewpointFromMob(var/mob/currentMob) - return FALSE - -/datum/visibility_network/proc/updateMob(var/mob/currentMob) - var/viewpoint = getViewpointFromMob(currentMob) - if(viewpoint) - updateViewpoint(viewpoint) - - -/datum/visibility_network/proc/updateViewpoint(var/viewpoint) - if(validViewpoint(viewpoint)) - majorChunkChange(viewpoint, 1) - - -// Never access this proc directly!!!! -// This will update the chunk and all the surrounding chunks. -// It will also add the atom to the cameras list if you set the choice to 1. -// Setting the choice to 0 will remove the viewpoint from the chunks. -// If you want to update the chunks around an object, without adding/removing a viewpoint, use choice 2. -/datum/visibility_network/proc/majorChunkChange(atom/c, var/choice) - // 0xf = 15 - if(!c) - return - - var/turf/T = get_turf(c) - if(T) - var/x1 = max(0, T.x - 8) & ~0xf - var/y1 = max(0, T.y - 8) & ~0xf - var/x2 = min(world.maxx, T.x + 8) & ~0xf - var/y2 = min(world.maxy, T.y + 8) & ~0xf - - for(var/x = x1; x <= x2; x += 16) - for(var/y = y1; y <= y2; y += 16) - if(chunkGenerated(x, y, T.z)) - var/datum/visibility_chunk/chunk = getChunk(x, y, T.z) - if(choice == 0) - // Remove the viewpoint. - chunk.viewpoints -= c - else if(choice == 1) - // You can't have the same viewpoint in the list twice. - chunk.viewpoints |= c - chunk.hasChanged() - -// checks if the network can see a particular atom -/datum/visibility_network/proc/checkCanSee(var/atom/target) - var/turf/position = get_turf(target) - var/datum/visibility_chunk/chunk = getChunk(position.x, position.y, position.z) - if(chunk) - if(chunk.changed) - chunk.hasChanged(1) // Update now, no matter if it's visible or not. - if(chunk.visibleTurfs[position]) - return 1 - return 0 \ No newline at end of file diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 36e5100750..b84388f583 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -422,8 +422,7 @@ /obj/item/weapon/camera_bug/attack_self(mob/usr as mob) var/list/cameras = new/list() - - for (var/obj/machinery/camera/C in cameraNetwork.viewpoints) + for (var/obj/machinery/camera/C in cameranet.cameras) if (C.bugged && C.status) cameras.Add(C) if (length(cameras) == 0) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index e0e81a647e..ee16e21a77 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -8,7 +8,6 @@ /proc/iscultist(mob/living/M as mob) return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult) - /proc/is_convertable_to_cult(datum/mind/mind) if(!istype(mind)) return 0 if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0 @@ -134,8 +133,7 @@ mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." mob.mutations.Remove(CLUMSY) - add_cult_viewpoint(mob) // give them a viewpoint - + var/obj/item/weapon/paper/talisman/supply/T = new(mob) var/list/slots = list ( "backpack" = slot_in_backpack, @@ -171,20 +169,11 @@ cult_mob.mind.store_memory("You remember that [wordexp]", 0, 0) -/datum/game_mode/proc/add_cult_viewpoint(var/mob/target) - for(var/obj/cult_viewpoint/viewpoint in target) - return - var/obj/cult_viewpoint/viewpoint = new(target) - viewpoint.loc = target - return viewpoint - - /datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE if (!istype(cult_mind)) return 0 if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind)) cult += cult_mind - add_cult_viewpoint(cult_mind.current) update_cult_icons_added(cult_mind) return 1 @@ -200,133 +189,57 @@ cult -= cult_mind cult_mind.current << "\red An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it." cult_mind.memory = "" - - // remove the cult viewpoint object - var/obj/viewpoint = getCultViewpoint(cult_mind.current) - del(viewpoint) - update_cult_icons_removed(cult_mind) if(show_message) for(var/mob/M in viewers(cult_mind.current)) M << "[cult_mind.current] looks like they just reverted to their old faith!" - /datum/game_mode/proc/update_all_cult_icons() spawn(0) - // reset the cult - for(var/datum/mind/cultist in cult) - reset_cult_icons_for_cultist(cultist) - // reset the spirits - for(var/mob/spirit/currentSpirit in spirits) - reset_cult_icons_for_spirit(currentSpirit) - - -/datum/game_mode/proc/reset_cult_icons_for_cultist(var/datum/mind/target) - if(target.current) - if(target.current.client) - remove_all_cult_icons(target) - for(var/datum/mind/cultist in cult) - if(cultist.current) - add_cult_icon(target.current.client,cultist.current) - - -/datum/game_mode/proc/reset_cult_icons_for_spirit(mob/spirit/target) - if (target.client) - remove_all_cult_icons(target) for(var/datum/mind/cultist in cult) if(cultist.current) - add_cult_icon(target.client,cultist.current) - - -/datum/game_mode/proc/add_cult_icon(client/target_client,mob/target_mob) - var/I = image('icons/mob/mob.dmi', loc = target_mob, icon_state = "cult") - target_client.images += I + if(cultist.current.client) + for(var/image/I in cultist.current.client.images) + if(I.icon_state == "cult") + del(I) - -/datum/game_mode/proc/remove_cult_icon(client/target_client,mob/target_mob) - for(var/image/I in target_client.images) - if(I.icon_state == "cult" && I.loc == target_mob) - del(I) - - -/datum/game_mode/proc/remove_all_cult_icons_from_client(client/target) - for(var/image/I in target.images) - if(I.icon_state == "cult") - del(I) - - -/datum/game_mode/proc/remove_all_cult_icons(target) - var/datum/mind/cultist = target - if(istype(cultist)) - if(cultist.current) - if(cultist.current.client) - remove_all_cult_icons_from_client(cultist.current.client) - return TRUE - var/mob/spirit/currentSpirit = target - if(istype(currentSpirit)) - if (currentSpirit.client) - remove_all_cult_icons_from_client(currentSpirit.client) - return TRUE - return FALSE - - -/datum/game_mode/proc/add_cult_icon_to_spirit(mob/spirit/currentSpirit,datum/mind/cultist) - if(!istype(currentSpirit) || !istype(cultist)) - return FALSE - if (currentSpirit.client) - if (cultist.current) - add_cult_icon(currentSpirit.client,cultist.current) - - -/datum/game_mode/proc/add_cult_icon_to_cultist(datum/mind/first_cultist,datum/mind/second_cultist) - if(first_cultist.current && second_cultist.current) - if(first_cultist.current.client) - add_cult_icon(first_cultist.current.client, second_cultist.current) - - -/datum/game_mode/proc/remove_cult_icon_from_cultist(datum/mind/first_cultist,datum/mind/second_cultist) - if(first_cultist.current && second_cultist.current) - if(first_cultist.current.client) - remove_cult_icon(first_cultist.current.client,second_cultist.current) + for(var/datum/mind/cultist in cult) + if(cultist.current) + if(cultist.current.client) + for(var/datum/mind/cultist_1 in cult) + if(cultist_1.current) + var/I = image('icons/mob/mob.dmi', loc = cultist_1.current, icon_state = "cult") + cultist.current.client.images += I - -/datum/game_mode/proc/remove_cult_icon_from_spirit(mob/spirit/currentSpirit,datum/mind/cultist) - if(!istype(currentSpirit) || !istype(cultist)) - return FALSE - if (currentSpirit.client) - if (cultist.current) - remove_cult_icon(currentSpirit.client,cultist.current) - - -/datum/game_mode/proc/cult_icon_pair_link(datum/mind/first_cultist,datum/mind/second_cultist) - if (!istype(first_cultist) || !istype(second_cultist)) - return 0 - add_cult_icon_to_cultist(first_cultist,second_cultist) - add_cult_icon_to_cultist(second_cultist,first_cultist) - -/datum/game_mode/proc/cult_icon_pair_unlink(datum/mind/first_cultist,datum/mind/second_cultist) - if (!istype(first_cultist) || !istype(second_cultist)) - return 0 - remove_cult_icon(first_cultist,second_cultist) - remove_cult_icon(second_cultist,first_cultist) - - /datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind) spawn(0) for(var/datum/mind/cultist in cult) - cult_icon_pair_link(cultist,cult_mind) - for(var/mob/spirit/currentSpirit in spirits) - add_cult_icon_to_spirit(currentSpirit,cult_mind) - - + if(cultist.current) + if(cultist.current.client) + var/I = image('icons/mob/mob.dmi', loc = cult_mind.current, icon_state = "cult") + cultist.current.client.images += I + if(cult_mind.current) + if(cult_mind.current.client) + var/image/J = image('icons/mob/mob.dmi', loc = cultist.current, icon_state = "cult") + cult_mind.current.client.images += J + + /datum/game_mode/proc/update_cult_icons_removed(datum/mind/cult_mind) spawn(0) for(var/datum/mind/cultist in cult) - cult_icon_pair_unlink(cultist,cult_mind) - for(var/mob/spirit/currentSpirit in spirits) - remove_cult_icon_from_spirit(currentSpirit,cult_mind) - + if(cultist.current) + if(cultist.current.client) + for(var/image/I in cultist.current.client.images) + if(I.icon_state == "cult" && I.loc == cult_mind.current) + del(I) + + if(cult_mind.current) + if(cult_mind.current.client) + for(var/image/I in cult_mind.current.client.images) + if(I.icon_state == "cult") + del(I) + /datum/game_mode/cult/proc/get_unconvertables() var/list/ucs = list() @@ -362,10 +275,6 @@ return 1 -/atom/proc/cult_log(var/message) - investigate_log(message, "cult") - - /datum/game_mode/cult/declare_completion() if(!check_cult_victory()) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 2760a66d49..2d408a1a4f 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -1,7 +1,6 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 var/cultwords = list() -var/rune_to_english = list() var/runedec = 0 var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", "self", "see", "other", "hide") @@ -17,22 +16,19 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", /proc/runerandom() //randomizes word meaning var/list/runewords=list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri") ///"orkan" and "allaq" removed. for (var/word in engwords) - var/runeword = pick(runewords) - cultwords[word] = runeword - rune_to_english[runeword] = word + cultwords[word] = pick(runewords) runewords-=cultwords[word] - /obj/effect/rune desc = "" anchored = 1 icon = 'icons/obj/rune.dmi' icon_state = "1" var/visibility = 0 - var/view_range = 7 unacidable = 1 layer = TURF_LAYER + var/word1 var/word2 var/word3 @@ -65,112 +61,122 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", // self other technology - Communication rune //was other hear blood // join hide technology - stun rune. Rune color: bright pink. + New() + ..() + var/image/blood = image(loc = src) + blood.override = 1 + for(var/mob/living/silicon/ai/AI in player_list) + AI.client.images += blood -/obj/effect/rune/New() - ..() - var/image/blood = image(loc = src) - blood.override = 1 - for(var/mob/living/silicon/ai/AI in player_list) - AI.client.images += blood - cultNetwork.viewpoints+=src - cultNetwork.addViewpoint(src) + examine() + set src in view(2) -/obj/effect/rune/Del() - ..() - cultNetwork.viewpoints-=src - cultNetwork.removeViewpoint(src) + if(!iscultist(usr)) + usr << "A strange collection of symbols drawn in blood." + return + /* Explosions... really? + if(desc && !usr.stat) + usr << "It reads: [desc]." + sleep(30) + explosion(src.loc, 0, 2, 5, 5) + if(src) + del(src) + */ + if(!desc) + usr << "A spell circle drawn in blood. It reads: [word1] [word2] [word3]." + else + usr << "Explosive Runes inscription in blood. It reads: [desc]." -/obj/effect/rune/examine() - set src in view(2) - - if(!iscultist(usr) && !isSpirit(usr)) - usr << "A strange collection of symbols drawn in blood." return - if(!desc) - usr << "A spell circle drawn in blood. It reads: [word1] [word2] [word3]." - else - usr << "Explosive Runes inscription in blood. It reads: [desc]." - - return -/obj/effect/rune/attackby(I as obj, user as mob) - if(istype(I, /obj/item/weapon/tome) && iscultist(user)) - user << "You retrace your steps, carefully undoing the lines of the rune." - del(src) + attackby(I as obj, user as mob) + if(istype(I, /obj/item/weapon/tome) && iscultist(user)) + user << "You retrace your steps, carefully undoing the lines of the rune." + del(src) + return + else if(istype(I, /obj/item/weapon/nullrod)) + user << "\blue You disrupt the vile magic with the deadening field of the null rod!" + del(src) + return return - else if(istype(I, /obj/item/weapon/nullrod)) - user << "\blue You disrupt the vile magic with the deadening field of the null rod!" - del(src) - return - return -/obj/effect/rune/proc/get_word_string() - if (word1 == cultwords["travel"]) - if (word2 == cultwords["self"]) - return "teleport" - if (word2 == cultwords["other"]) - return "itemport" - return "[rune_to_english[word1]]_[rune_to_english[word2]]_[rune_to_english[word3]]" - - -/obj/effect/rune - var/list/effect_dictionary = list( "teleport"=/obj/effect/rune/proc/teleportRune, - "itemport"=/obj/effect/rune/proc/itemportRune, - "see_blood_hell"=/obj/effect/rune/proc/tomesummon, - "hell_destroy_other"=/obj/effect/rune/proc/armor, - "join_blood_self"=/obj/effect/rune/proc/convert, - "hell_join_self"=/obj/effect/rune/proc/tearreality, - "destroy_see_technology"=/obj/effect/rune/proc/empRune, - "travel_blood_self"=/obj/effect/rune/proc/drain, - "see_hell_join"=/obj/effect/rune/proc/seer, - "blood_join_hell"=/obj/effect/rune/proc/raise, - "hide_see_blood"=/obj/effect/rune/proc/obscureRune, - "hell_travel_self"=/obj/effect/rune/proc/ajourney, - "blood_see_travel"=/obj/effect/rune/proc/manifest, - "hell_technology_join"=/obj/effect/rune/proc/talisman, - "hell_blood_join"=/obj/effect/rune/proc/sacrifice, - "blood_see_hide"=/obj/effect/rune/proc/revealrunesrune, - "destroy_travel_self"=/obj/effect/rune/proc/wall, - "travel_technology_other"=/obj/effect/rune/proc/freedom, - "join_other_self"=/obj/effect/rune/proc/cultsummon, - "hide_other_see"=/obj/effect/rune/proc/deafen, - "destroy_see_other"=/obj/effect/rune/proc/blind, - "destroy_see_blood"=/obj/effect/rune/proc/bloodboil, - "self_other_technology"=/obj/effect/rune/proc/communicate, - "join_hide_technology"=/obj/effect/rune/proc/runestun ) - -/obj/effect/rune/attack_hand(mob/living/user as mob) - if(!iscultist(user)) - user << "You can't mouth the arcane scratchings without fumbling over them." - return - if(istype(user.wear_mask, /obj/item/clothing/mask/muzzle)) - user << "You are unable to speak the words of the rune." - return - if(user.silent) // checking if we've been muted somehow - user << "You are unable to speak at all! You cannot say the words of the rune." - if(!word1 || !word2 || !word3 || prob(user.getBrainLoss())) - return fizzle() - - var/word_string = get_word_string() - if (word_string in effect_dictionary) - cult_log("of type [effect_dictionary[word_string]] activated by [key_name_admin(user)].") - return call(src,effect_dictionary[word_string])() - return fizzle() + attack_hand(mob/living/user as mob) + if(!iscultist(user)) + user << "You can't mouth the arcane scratchings without fumbling over them." + return + if(istype(user.wear_mask, /obj/item/clothing/mask/muzzle)) + user << "You are unable to speak the words of the rune." + return + if(!word1 || !word2 || !word3 || prob(user.getBrainLoss())) + return fizzle() +// if(!src.visibility) +// src.visibility=1 + if(word1 == cultwords["travel"] && word2 == cultwords["self"]) + return teleport(src.word3) + if(word1 == cultwords["see"] && word2 == cultwords["blood"] && word3 == cultwords["hell"]) + return tomesummon() + if(word1 == cultwords["hell"] && word2 == cultwords["destroy"] && word3 == cultwords["other"]) + return armor() + if(word1 == cultwords["join"] && word2 == cultwords["blood"] && word3 == cultwords["self"]) + return convert() + if(word1 == cultwords["hell"] && word2 == cultwords["join"] && word3 == cultwords["self"]) + return tearreality() + if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["technology"]) + return emp(src.loc,3) + if(word1 == cultwords["travel"] && word2 == cultwords["blood"] && word3 == cultwords["self"]) + return drain() + if(word1 == cultwords["see"] && word2 == cultwords["hell"] && word3 == cultwords["join"]) + return seer() + if(word1 == cultwords["blood"] && word2 == cultwords["join"] && word3 == cultwords["hell"]) + return raise() + if(word1 == cultwords["hide"] && word2 == cultwords["see"] && word3 == cultwords["blood"]) + return obscure(4) + if(word1 == cultwords["hell"] && word2 == cultwords["travel"] && word3 == cultwords["self"]) + return ajourney() + if(word1 == cultwords["blood"] && word2 == cultwords["see"] && word3 == cultwords["travel"]) + return manifest() + if(word1 == cultwords["hell"] && word2 == cultwords["technology"] && word3 == cultwords["join"]) + return talisman() + if(word1 == cultwords["hell"] && word2 == cultwords["blood"] && word3 == cultwords["join"]) + return sacrifice() + if(word1 == cultwords["blood"] && word2 == cultwords["see"] && word3 == cultwords["hide"]) + return revealrunes(src) + if(word1 == cultwords["destroy"] && word2 == cultwords["travel"] && word3 == cultwords["self"]) + return wall() + if(word1 == cultwords["travel"] && word2 == cultwords["technology"] && word3 == cultwords["other"]) + return freedom() + if(word1 == cultwords["join"] && word2 == cultwords["other"] && word3 == cultwords["self"]) + return cultsummon() + if(word1 == cultwords["hide"] && word2 == cultwords["other"] && word3 == cultwords["see"]) + return deafen() + if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["other"]) + return blind() + if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["blood"]) + return bloodboil() + if(word1 == cultwords["self"] && word2 == cultwords["other"] && word3 == cultwords["technology"]) + return communicate() + if(word1 == cultwords["travel"] && word2 == cultwords["other"]) + return itemport(src.word3) + if(word1 == cultwords["join"] && word2 == cultwords["hide"] && word3 == cultwords["technology"]) + return runestun() + else + return fizzle() -/obj/effect/rune/proc/fizzle() - if(istype(src,/obj/effect/rune)) - usr.say(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix.")) - else - usr.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix.")) - for (var/mob/V in viewers(src)) - V.show_message("\red The markings pulse with a small burst of light, then fall dark.", 3, "\red You hear a faint fizzle.", 2) - return + proc + fizzle() + if(istype(src,/obj/effect/rune)) + usr.say(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix.")) + else + usr.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix.")) + for (var/mob/V in viewers(src)) + V.show_message("\red The markings pulse with a small burst of light, then fall dark.", 3, "\red You hear a faint fizzle.", 2) + return -/obj/effect/rune/proc/check_icon() - icon = get_uristrune_cult(word1, word2, word3) + check_icon() + icon = get_uristrune_cult(word1, word2, word3) /obj/item/weapon/tome name = "arcane tome" diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index e7f1e2ff26..e5be5d60a7 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1,205 +1,197 @@ var/list/sacrificed = list() - +/obj/effect/rune /////////////////////////////////////////FIRST RUNE -/obj/effect/rune/proc/teleportRune() - return teleport(src.word3) - -/obj/effect/rune/proc/teleport(var/key) - var/mob/living/user = usr - var/allrunesloc[] - allrunesloc = new/list() - var/index = 0 -// var/tempnum = 0 - for(var/obj/effect/rune/R in world) - if(R == src) - continue - if(R.word1 == cultwords["travel"] && R.word2 == cultwords["self"] && R.word3 == key && R.z != 2) - index++ - allrunesloc.len = index - allrunesloc[index] = R.loc - if(index >= 5) - user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" - if (istype(user, /mob/living)) - user.take_overall_damage(5, 0) - del(src) - if(allrunesloc && index != 0) - if(istype(src,/obj/effect/rune)) - user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting - else - user.whisper("Sas[pick("'","`")]so c'arta forbici!") - user.visible_message("\red [user] disappears in a flash of red light!", \ - "\red You feel as your body gets dragged through the dimension of Nar-Sie!", \ - "\red You hear a sickening crunch and sloshing of viscera.") - user.loc = allrunesloc[rand(1,index)] - return - if(istype(src,/obj/effect/rune)) - return fizzle() //Use friggin manuals, Dorf, your list was of zero length. - else - call(/obj/effect/rune/proc/fizzle)() - return + proc + teleport(var/key) + var/mob/living/user = usr + var/allrunesloc[] + allrunesloc = new/list() + var/index = 0 + // var/tempnum = 0 + for(var/obj/effect/rune/R in world) + if(R == src) + continue + if(R.word1 == cultwords["travel"] && R.word2 == cultwords["self"] && R.word3 == key && R.z != 2) + index++ + allrunesloc.len = index + allrunesloc[index] = R.loc + if(index >= 5) + user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" + if (istype(user, /mob/living)) + user.take_overall_damage(5, 0) + del(src) + if(allrunesloc && index != 0) + if(istype(src,/obj/effect/rune)) + user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting + else + user.whisper("Sas[pick("'","`")]so c'arta forbici!") + user.visible_message("\red [user] disappears in a flash of red light!", \ + "\red You feel as your body gets dragged through the dimension of Nar-Sie!", \ + "\red You hear a sickening crunch and sloshing of viscera.") + user.loc = allrunesloc[rand(1,index)] + return + if(istype(src,/obj/effect/rune)) + return fizzle() //Use friggin manuals, Dorf, your list was of zero length. + else + call(/obj/effect/rune/proc/fizzle)() + return -/obj/effect/rune/proc/itemportRune() - return itemport(src.word3) -/obj/effect/rune/proc/itemport(var/key) + + itemport(var/key) // var/allrunesloc[] // allrunesloc = new/list() // var/index = 0 -// var/tempnum = 0 - var/culcount = 0 - var/runecount = 0 - var/obj/effect/rune/IP = null - var/mob/living/user = usr - for(var/obj/effect/rune/R in world) - if(R == src) - continue - if(R.word1 == cultwords["travel"] && R.word2 == cultwords["other"] && R.word3 == key) - IP = R - runecount++ - if(runecount >= 2) - user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" - if (istype(user, /mob/living)) - user.take_overall_damage(5, 0) - del(src) - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - culcount++ - if(culcount>=3) - user.say("Sas[pick("'","`")]so c'arta forbici tarem!") - user.visible_message("\red You feel air moving from the rune - like as it was swapped with somewhere else.", \ - "\red You feel air moving from the rune - like as it was swapped with somewhere else.", \ - "\red You smell ozone.") - for(var/obj/O in src.loc) - if(!O.anchored) - O.loc = IP.loc - for(var/mob/M in src.loc) - M.loc = IP.loc - return + // var/tempnum = 0 + var/culcount = 0 + var/runecount = 0 + var/obj/effect/rune/IP = null + var/mob/living/user = usr + for(var/obj/effect/rune/R in world) + if(R == src) + continue + if(R.word1 == cultwords["travel"] && R.word2 == cultwords["other"] && R.word3 == key) + IP = R + runecount++ + if(runecount >= 2) + user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" + if (istype(user, /mob/living)) + user.take_overall_damage(5, 0) + del(src) + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + culcount++ + if(culcount>=3) + user.say("Sas[pick("'","`")]so c'arta forbici tarem!") + user.visible_message("\red You feel air moving from the rune - like as it was swapped with somewhere else.", \ + "\red You feel air moving from the rune - like as it was swapped with somewhere else.", \ + "\red You smell ozone.") + for(var/obj/O in src.loc) + if(!O.anchored) + O.loc = IP.loc + for(var/mob/M in src.loc) + M.loc = IP.loc + return - return fizzle() + return fizzle() /////////////////////////////////////////SECOND RUNE -/obj/effect/rune/proc/tomesummon() - if(istype(src,/obj/effect/rune)) - usr.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") - else - usr.whisper("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") - usr.visible_message("\red Rune disappears with a flash of red light, and in its place now a book lies.", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a book.", \ - "\red You hear a pop and smell ozone.") - if(istype(src,/obj/effect/rune)) - new /obj/item/weapon/tome(src.loc) - else - new /obj/item/weapon/tome(usr.loc) - del(src) - return + tomesummon() + if(istype(src,/obj/effect/rune)) + usr.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") + else + usr.whisper("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") + usr.visible_message("\red Rune disappears with a flash of red light, and in its place now a book lies.", \ + "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a book.", \ + "\red You hear a pop and smell ozone.") + if(istype(src,/obj/effect/rune)) + new /obj/item/weapon/tome(src.loc) + else + new /obj/item/weapon/tome(usr.loc) + del(src) + return /////////////////////////////////////////THIRD RUNE -/obj/effect/rune/proc/convert() - for(var/mob/living/carbon/M in src.loc) - if(iscultist(M)) - continue - if(M.stat==2) - continue - usr.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!") - M.visible_message("\red [M] writhes in pain as the markings below him glow a bloody red.", \ - "\red AAAAAAHHHH!.", \ - "\red You hear an anguished scream.") - cult_log("[key_name_admin(usr)] tried to convert [key_name_admin(M)]") - if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist"))//putting jobban check here because is_convertable uses mind as argument - ticker.mode.add_cultist(M.mind) - M.mind.special_role = "Cultist" - M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - return 1 - else - M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "And you were able to force it out of your mind. You now know the truth, there's something horrible out there, stop it and its minions at all costs." - return 0 + convert() + for(var/mob/living/carbon/M in src.loc) + if(iscultist(M)) + continue + if(M.stat==2) + continue + usr.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!") + M.visible_message("\red [M] writhes in pain as the markings below him glow a bloody red.", \ + "\red AAAAAAHHHH!.", \ + "\red You hear an anguished scream.") + if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist"))//putting jobban check here because is_convertable uses mind as argument + ticker.mode.add_cultist(M.mind) + M.mind.special_role = "Cultist" + M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + M << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + return 1 + else + M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + M << "And you were able to force it out of your mind. You now know the truth, there's something horrible out there, stop it and its minions at all costs." + return 0 - return fizzle() + return fizzle() /////////////////////////////////////////FOURTH RUNE -/obj/effect/rune/proc/tearreality() - var/cultist_count = 0 - for(var/mob/M in range(1,src)) - if(iscultist(M) && !M.stat) - M.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!") - cultist_count += 1 - if(cultist_count >= 9) - cult_log("THE CULT HAS SUMMONED NAR'SIE. GGNORE") - new /obj/machinery/singularity/narsie/large(src.loc) - if(ticker.mode.name == "cult") - ticker.mode:eldergod = 0 - return - else - return fizzle() + tearreality() + var/cultist_count = 0 + for(var/mob/M in range(1,src)) + if(iscultist(M) && !M.stat) + M.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!") + cultist_count += 1 + if(cultist_count >= 9) + new /obj/machinery/singularity/narsie/large(src.loc) + if(ticker.mode.name == "cult") + ticker.mode:eldergod = 0 + return + else + return fizzle() /////////////////////////////////////////FIFTH RUNE -/obj/effect/rune/proc/empRune() - emp(src.loc,3) - -/obj/effect/rune/proc/emp(var/U,var/range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist - if(istype(src,/obj/effect/rune)) - usr.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!") - else - usr.whisper("Ta'gh fara[pick("'","`")]qha fel d'amar det!") - playsound(U, 'sound/items/Welder2.ogg', 25, 1) - var/turf/T = get_turf(U) - if(T) - T.hotspot_expose(700,125) - var/rune = src // detaching the proc - in theory - empulse(U, (range_red - 2), range_red) - del(rune) - return + + emp(var/U,var/range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist + if(istype(src,/obj/effect/rune)) + usr.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!") + else + usr.whisper("Ta'gh fara[pick("'","`")]qha fel d'amar det!") + playsound(U, 'sound/items/Welder2.ogg', 25, 1) + var/turf/T = get_turf(U) + if(T) + T.hotspot_expose(700,125) + var/rune = src // detaching the proc - in theory + empulse(U, (range_red - 2), range_red) + del(rune) + return /////////////////////////////////////////SIXTH RUNE -/obj/effect/rune/proc/drain() - var/drain = 0 - for(var/obj/effect/rune/R in world) - if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"]) - for(var/mob/living/carbon/D in R.loc) - if(D.stat!=2) - cult_log("[key_name_admin(usr)] has drained blood from [key_name_admin(D)]") - var/bdrain = rand(1,25) - D << "\red You feel weakened." - D.take_overall_damage(bdrain, 0) - drain += bdrain - if(!drain) - return fizzle() - usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!") - usr.visible_message("\red Blood flows from the rune into [usr]!", \ - "\red The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.", \ - "\red You hear a liquid flowing.") - var/mob/living/user = usr - if(user.bhunger) - user.bhunger = max(user.bhunger-2*drain,0) - if(drain>=50) - user.visible_message("\red [user]'s eyes give off eerie red glow!", \ - "\red ...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.", \ - "\red You hear a heartbeat.") - user.bhunger += drain - src = user - spawn() - for (,user.bhunger>0,user.bhunger--) - sleep(50) - user.take_overall_damage(3, 0) - return - user.heal_organ_damage(drain%5, 0) - drain-=drain%5 - for (,drain>0,drain-=5) - sleep(2) - user.heal_organ_damage(5, 0) - return + drain() + var/drain = 0 + for(var/obj/effect/rune/R in world) + if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"]) + for(var/mob/living/carbon/D in R.loc) + if(D.stat!=2) + var/bdrain = rand(1,25) + D << "\red You feel weakened." + D.take_overall_damage(bdrain, 0) + drain += bdrain + if(!drain) + return fizzle() + usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!") + usr.visible_message("\red Blood flows from the rune into [usr]!", \ + "\red The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.", \ + "\red You hear a liquid flowing.") + var/mob/living/user = usr + if(user.bhunger) + user.bhunger = max(user.bhunger-2*drain,0) + if(drain>=50) + user.visible_message("\red [user]'s eyes give off eerie red glow!", \ + "\red ...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.", \ + "\red You hear a heartbeat.") + user.bhunger += drain + src = user + spawn() + for (,user.bhunger>0,user.bhunger--) + sleep(50) + user.take_overall_damage(3, 0) + return + user.heal_organ_damage(drain%5, 0) + drain-=drain%5 + for (,drain>0,drain-=5) + sleep(2) + user.heal_organ_damage(5, 0) + return @@ -208,98 +200,98 @@ var/list/sacrificed = list() /////////////////////////////////////////SEVENTH RUNE -/obj/effect/rune/proc/seer() - if(usr.loc==src.loc) - if(usr.seer==1) - usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.") - usr << "\red The world beyond fades from your vision." - usr.see_invisible = SEE_INVISIBLE_LIVING - usr.seer = 0 - else if(usr.see_invisible!=SEE_INVISIBLE_LIVING) - usr << "\red The world beyond flashes your eyes but disappears quickly, as if something is disrupting your vision." - usr.see_invisible = SEE_INVISIBLE_OBSERVER - usr.seer = 0 - else - usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!") - usr << "\red The world beyond opens to your eyes." - usr.see_invisible = SEE_INVISIBLE_OBSERVER - usr.seer = 1 - return - return fizzle() + seer() + if(usr.loc==src.loc) + if(usr.seer==1) + usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.") + usr << "\red The world beyond fades from your vision." + usr.see_invisible = SEE_INVISIBLE_LIVING + usr.seer = 0 + else if(usr.see_invisible!=SEE_INVISIBLE_LIVING) + usr << "\red The world beyond flashes your eyes but disappears quickly, as if something is disrupting your vision." + usr.see_invisible = SEE_INVISIBLE_OBSERVER + usr.seer = 0 + else + usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!") + usr << "\red The world beyond opens to your eyes." + usr.see_invisible = SEE_INVISIBLE_OBSERVER + usr.seer = 1 + return + return fizzle() /////////////////////////////////////////EIGHTH RUNE -/obj/effect/rune/proc/raise() - var/mob/living/carbon/human/corpse_to_raise - var/mob/living/carbon/human/body_to_sacrifice + raise() + var/mob/living/carbon/human/corpse_to_raise + var/mob/living/carbon/human/body_to_sacrifice - var/is_sacrifice_target = 0 - for(var/mob/living/carbon/human/M in src.loc) - if(M.stat == DEAD) - if(ticker.mode.name == "cult" && M.mind == ticker.mode:sacrifice_target) - is_sacrifice_target = 1 - else - corpse_to_raise = M - if(M.key) - M.ghostize(1) //kick them out of their body - break - if(!corpse_to_raise) - if(is_sacrifice_target) - usr << "\red The Geometer of blood wants this mortal for himself." - return fizzle() - - - is_sacrifice_target = 0 - find_sacrifice: - for(var/obj/effect/rune/R in world) - if(R.word1==cultwords["blood"] && R.word2==cultwords["join"] && R.word3==cultwords["hell"]) - for(var/mob/living/carbon/human/N in R.loc) - if(ticker.mode.name == "cult" && N.mind && N.mind == ticker.mode:sacrifice_target) + var/is_sacrifice_target = 0 + for(var/mob/living/carbon/human/M in src.loc) + if(M.stat == DEAD) + if(ticker.mode.name == "cult" && M.mind == ticker.mode:sacrifice_target) is_sacrifice_target = 1 else - if(N.stat!= DEAD) - body_to_sacrifice = N - break find_sacrifice + corpse_to_raise = M + if(M.key) + M.ghostize(1) //kick them out of their body + break + if(!corpse_to_raise) + if(is_sacrifice_target) + usr << "\red The Geometer of blood wants this mortal for himself." + return fizzle() - if(!body_to_sacrifice) - if (is_sacrifice_target) - usr << "\red The Geometer of blood wants that corpse for himself." - else - usr << "\red The sacrifical corpse is not dead. You must free it from this world of illusions before it may be used." - return fizzle() - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break + is_sacrifice_target = 0 + find_sacrifice: + for(var/obj/effect/rune/R in world) + if(R.word1==cultwords["blood"] && R.word2==cultwords["join"] && R.word3==cultwords["hell"]) + for(var/mob/living/carbon/human/N in R.loc) + if(ticker.mode.name == "cult" && N.mind && N.mind == ticker.mode:sacrifice_target) + is_sacrifice_target = 1 + else + if(N.stat!= DEAD) + body_to_sacrifice = N + break find_sacrifice - if(!ghost) - usr << "\red You require a restless spirit which clings to this world. Beckon their prescence with the sacred chants of Nar-Sie." - return fizzle() + if(!body_to_sacrifice) + if (is_sacrifice_target) + usr << "\red The Geometer of blood wants that corpse for himself." + else + usr << "\red The sacrifical corpse is not dead. You must free it from this world of illusions before it may be used." + return fizzle() - corpse_to_raise.revive() + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in loc) + if(!O.client) continue + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue + ghost = O + break - corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed) - //This means, should that player leave the body, the original may re-enter - usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!") - corpse_to_raise.visible_message("\red [corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.", \ - "\red Life... I'm alive again...", \ - "\red You hear a faint, slightly familiar whisper.") - body_to_sacrifice.visible_message("\red [body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from his remains!", \ - "\red You feel as your blood boils, tearing you apart.", \ - "\red You hear a thousand voices, all crying in pain.") - body_to_sacrifice.gib() + if(!ghost) + usr << "\red You require a restless spirit which clings to this world. Beckon their prescence with the sacred chants of Nar-Sie." + return fizzle() + + corpse_to_raise.revive() + + corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed) + //This means, should that player leave the body, the original may re-enter + usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!") + corpse_to_raise.visible_message("\red [corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.", \ + "\red Life... I'm alive again...", \ + "\red You hear a faint, slightly familiar whisper.") + body_to_sacrifice.visible_message("\red [body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from his remains!", \ + "\red You feel as your blood boils, tearing you apart.", \ + "\red You hear a thousand voices, all crying in pain.") + body_to_sacrifice.gib() // if(ticker.mode.name == "cult") // ticker.mode:add_cultist(corpse_to_raise.mind) // else // ticker.mode.cult |= corpse_to_raise.mind - corpse_to_raise << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - corpse_to_raise << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - return + corpse_to_raise << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + corpse_to_raise << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + return @@ -307,113 +299,111 @@ var/list/sacrificed = list() /////////////////////////////////////////NINETH RUNE -/obj/effect/rune/proc/obscureRune() - return obscure(4) -/obj/effect/rune/proc/obscure(var/rad) - var/S=0 - for(var/obj/effect/rune/R in orange(rad,src)) - if(R!=src) - R.invisibility=INVISIBILITY_OBSERVER - S=1 - if(S) - if(istype(src,/obj/effect/rune)) - usr.say("Kla[pick("'","`")]atu barada nikt'o!") - for (var/mob/V in viewers(src)) - V.show_message("\red The rune turns into gray dust, veiling the surrounding runes.", 3) - del(src) - else - usr.whisper("Kla[pick("'","`")]atu barada nikt'o!") - usr << "\red Your talisman turns into gray dust, veiling the surrounding runes." - for (var/mob/V in orange(1,src)) - if(V!=usr) - V.show_message("\red Dust emanates from [usr]'s hands for a moment.", 3) + obscure(var/rad) + var/S=0 + for(var/obj/effect/rune/R in orange(rad,src)) + if(R!=src) + R.invisibility=INVISIBILITY_OBSERVER + S=1 + if(S) + if(istype(src,/obj/effect/rune)) + usr.say("Kla[pick("'","`")]atu barada nikt'o!") + for (var/mob/V in viewers(src)) + V.show_message("\red The rune turns into gray dust, veiling the surrounding runes.", 3) + del(src) + else + usr.whisper("Kla[pick("'","`")]atu barada nikt'o!") + usr << "\red Your talisman turns into gray dust, veiling the surrounding runes." + for (var/mob/V in orange(1,src)) + if(V!=usr) + V.show_message("\red Dust emanates from [usr]'s hands for a moment.", 3) - return - if(istype(src,/obj/effect/rune)) - return fizzle() - else - call(/obj/effect/rune/proc/fizzle)() - return + return + if(istype(src,/obj/effect/rune)) + return fizzle() + else + call(/obj/effect/rune/proc/fizzle)() + return /////////////////////////////////////////TENTH RUNE -/obj/effect/rune/proc/ajourney() //some bits copypastaed from admin tools - Urist - if(usr.loc==src.loc) - var/mob/living/carbon/human/L = usr - usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!") - usr.visible_message("\red [usr]'s eyes glow blue as \he freezes in place, absolutely motionless.", \ - "\red The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...", \ - "\red You hear only complete silence for a moment.") - usr.ghostize(1) - L.ajourn = 1 - while(L) - if(L.key) - L.ajourn=0 - return - else - L.take_organ_damage(10, 0) - sleep(100) - return fizzle() + ajourney() //some bits copypastaed from admin tools - Urist + if(usr.loc==src.loc) + var/mob/living/carbon/human/L = usr + usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!") + usr.visible_message("\red [usr]'s eyes glow blue as \he freezes in place, absolutely motionless.", \ + "\red The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...", \ + "\red You hear only complete silence for a moment.") + usr.ghostize(1) + L.ajourn = 1 + while(L) + if(L.key) + L.ajourn=0 + return + else + L.take_organ_damage(10, 0) + sleep(100) + return fizzle() /////////////////////////////////////////ELEVENTH RUNE -/obj/effect/rune/proc/manifest() - var/obj/effect/rune/this_rune = src - src = null - if(usr.loc!=this_rune.loc) - return this_rune.fizzle() - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in this_rune.loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break - if(!ghost) - return this_rune.fizzle() - if(jobban_isbanned(ghost, "cultist")) - return this_rune.fizzle() + manifest() + var/obj/effect/rune/this_rune = src + src = null + if(usr.loc!=this_rune.loc) + return this_rune.fizzle() + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in this_rune.loc) + if(!O.client) continue + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue + ghost = O + break + if(!ghost) + return this_rune.fizzle() + if(jobban_isbanned(ghost, "cultist")) + return this_rune.fizzle() - usr.say("Gal'h'rfikk harfrandid mud[pick("'","`")]gib!") - var/mob/living/carbon/human/dummy/D = new(this_rune.loc) - usr.visible_message("\red A shape forms in the center of the rune. A shape of... a man.", \ - "\red A shape forms in the center of the rune. A shape of... a man.", \ - "\red You hear liquid flowing.") - D.real_name = "Unknown" - var/chose_name = 0 - for(var/obj/item/weapon/paper/P in this_rune.loc) - if(P.info) - D.real_name = copytext(P.info, findtext(P.info,">")+1, findtext(P.info,"<",2) ) - chose_name = 1 - break - if(!chose_name) - D.real_name = "[pick(first_names_male)] [pick(last_names)]" - D.universal_speak = 1 - D.status_flags &= ~GODMODE + usr.say("Gal'h'rfikk harfrandid mud[pick("'","`")]gib!") + var/mob/living/carbon/human/dummy/D = new(this_rune.loc) + usr.visible_message("\red A shape forms in the center of the rune. A shape of... a man.", \ + "\red A shape forms in the center of the rune. A shape of... a man.", \ + "\red You hear liquid flowing.") + D.real_name = "Unknown" + var/chose_name = 0 + for(var/obj/item/weapon/paper/P in this_rune.loc) + if(P.info) + D.real_name = copytext(P.info, findtext(P.info,">")+1, findtext(P.info,"<",2) ) + chose_name = 1 + break + if(!chose_name) + D.real_name = "[pick(first_names_male)] [pick(last_names)]" + D.universal_speak = 1 + D.status_flags &= ~GODMODE - D.key = ghost.key + D.key = ghost.key - if(ticker.mode.name == "cult") - ticker.mode:add_cultist(D.mind) - else - ticker.mode.cult+=D.mind + if(ticker.mode.name == "cult") + ticker.mode:add_cultist(D.mind) + else + ticker.mode.cult+=D.mind - D.mind.special_role = "Cultist" - D << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - D << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + D.mind.special_role = "Cultist" + D << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + D << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - var/mob/living/user = usr - while(this_rune && user && user.stat==CONSCIOUS && user.client && user.loc==this_rune.loc) - user.take_organ_damage(1, 0) - sleep(30) - if(D) - D.visible_message("\red [D] slowly dissipates into dust and bones.", \ - "\red You feel pain, as bonds formed between your soul and this homunculus break.", \ - "\red You hear faint rustle.") - D.dust() - return + var/mob/living/user = usr + while(this_rune && user && user.stat==CONSCIOUS && user.client && user.loc==this_rune.loc) + user.take_organ_damage(1, 0) + sleep(30) + if(D) + D.visible_message("\red [D] slowly dissipates into dust and bones.", \ + "\red You feel pain, as bonds formed between your soul and this homunculus break.", \ + "\red You hear faint rustle.") + D.dust() + return @@ -421,649 +411,629 @@ var/list/sacrificed = list() /////////////////////////////////////////TWELFTH RUNE -/obj/effect/rune/proc/talisman()//only hide, emp, teleport, deafen, blind and tome runes can be imbued atm - var/obj/item/weapon/paper/newtalisman - var/unsuitable_newtalisman = 0 - for(var/obj/item/weapon/paper/P in src.loc) - if(!P.info) - newtalisman = P - break - else - unsuitable_newtalisman = 1 - if (!newtalisman) - if (unsuitable_newtalisman) - usr << "\red The blank is tainted. It is unsuitable." - return fizzle() + talisman()//only hide, emp, teleport, deafen, blind and tome runes can be imbued atm + var/obj/item/weapon/paper/newtalisman + var/unsuitable_newtalisman = 0 + for(var/obj/item/weapon/paper/P in src.loc) + if(!P.info) + newtalisman = P + break + else + unsuitable_newtalisman = 1 + if (!newtalisman) + if (unsuitable_newtalisman) + usr << "\red The blank is tainted. It is unsuitable." + return fizzle() - var/obj/effect/rune/imbued_from - var/obj/item/weapon/paper/talisman/T - for(var/obj/effect/rune/R in orange(1,src)) - if(R==src) - continue - if(R.word1==cultwords["travel"] && R.word2==cultwords["self"]) //teleport - T = new(src.loc) - T.imbue = "[R.word3]" - T.info = "[R.word3]" - imbued_from = R - break - if(R.word1==cultwords["see"] && R.word2==cultwords["blood"] && R.word3==cultwords["hell"]) //tome - T = new(src.loc) - T.imbue = "newtome" - imbued_from = R - break - if(R.word1==cultwords["destroy"] && R.word2==cultwords["see"] && R.word3==cultwords["technology"]) //emp - T = new(src.loc) - T.imbue = "emp" - imbued_from = R - break - if(R.word1==cultwords["blood"] && R.word2==cultwords["see"] && R.word3==cultwords["destroy"]) //conceal - T = new(src.loc) - T.imbue = "conceal" - imbued_from = R - break - if(R.word1==cultwords["hell"] && R.word2==cultwords["destroy"] && R.word3==cultwords["other"]) //armor - T = new(src.loc) - T.imbue = "armor" - imbued_from = R - break - if(R.word1==cultwords["blood"] && R.word2==cultwords["see"] && R.word3==cultwords["hide"]) //reveal - T = new(src.loc) - T.imbue = "revealrunes" - imbued_from = R - break - if(R.word1==cultwords["hide"] && R.word2==cultwords["other"] && R.word3==cultwords["see"]) //deafen - T = new(src.loc) - T.imbue = "deafen" - imbued_from = R - break - if(R.word1==cultwords["destroy"] && R.word2==cultwords["see"] && R.word3==cultwords["other"]) //blind - T = new(src.loc) - T.imbue = "blind" - imbued_from = R - break - if(R.word1==cultwords["self"] && R.word2==cultwords["other"] && R.word3==cultwords["technology"]) //communicat - T = new(src.loc) - T.imbue = "communicate" - imbued_from = R - break - if(R.word1==cultwords["join"] && R.word2==cultwords["hide"] && R.word3==cultwords["technology"]) //communicat - T = new(src.loc) - T.imbue = "runestun" - imbued_from = R - break - if (imbued_from) - for (var/mob/V in viewers(src)) - V.show_message("\red The runes turn into dust, which then forms into an arcane image on the paper.", 3) - usr.say("H'drak v[pick("'","`")]loso, mir'kanas verbot!") - del(imbued_from) - del(newtalisman) - else - return fizzle() + var/obj/effect/rune/imbued_from + var/obj/item/weapon/paper/talisman/T + for(var/obj/effect/rune/R in orange(1,src)) + if(R==src) + continue + if(R.word1==cultwords["travel"] && R.word2==cultwords["self"]) //teleport + T = new(src.loc) + T.imbue = "[R.word3]" + T.info = "[R.word3]" + imbued_from = R + break + if(R.word1==cultwords["see"] && R.word2==cultwords["blood"] && R.word3==cultwords["hell"]) //tome + T = new(src.loc) + T.imbue = "newtome" + imbued_from = R + break + if(R.word1==cultwords["destroy"] && R.word2==cultwords["see"] && R.word3==cultwords["technology"]) //emp + T = new(src.loc) + T.imbue = "emp" + imbued_from = R + break + if(R.word1==cultwords["blood"] && R.word2==cultwords["see"] && R.word3==cultwords["destroy"]) //conceal + T = new(src.loc) + T.imbue = "conceal" + imbued_from = R + break + if(R.word1==cultwords["hell"] && R.word2==cultwords["destroy"] && R.word3==cultwords["other"]) //armor + T = new(src.loc) + T.imbue = "armor" + imbued_from = R + break + if(R.word1==cultwords["blood"] && R.word2==cultwords["see"] && R.word3==cultwords["hide"]) //reveal + T = new(src.loc) + T.imbue = "revealrunes" + imbued_from = R + break + if(R.word1==cultwords["hide"] && R.word2==cultwords["other"] && R.word3==cultwords["see"]) //deafen + T = new(src.loc) + T.imbue = "deafen" + imbued_from = R + break + if(R.word1==cultwords["destroy"] && R.word2==cultwords["see"] && R.word3==cultwords["other"]) //blind + T = new(src.loc) + T.imbue = "blind" + imbued_from = R + break + if(R.word1==cultwords["self"] && R.word2==cultwords["other"] && R.word3==cultwords["technology"]) //communicat + T = new(src.loc) + T.imbue = "communicate" + imbued_from = R + break + if(R.word1==cultwords["join"] && R.word2==cultwords["hide"] && R.word3==cultwords["technology"]) //communicat + T = new(src.loc) + T.imbue = "runestun" + imbued_from = R + break + if (imbued_from) + for (var/mob/V in viewers(src)) + V.show_message("\red The runes turn into dust, which then forms into an arcane image on the paper.", 3) + usr.say("H'drak v[pick("'","`")]loso, mir'kanas verbot!") + del(imbued_from) + del(newtalisman) + else + return fizzle() /////////////////////////////////////////THIRTEENTH RUNE -/obj/effect/rune/proc/mend() - var/mob/living/user = usr - src = null - user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!") - user.take_overall_damage(200, 0) - runedec+=10 - user.visible_message("\red [user] keels over dead, his blood glowing blue as it escapes his body and dissipates into thin air.", \ - "\red In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.", \ - "\red You hear faint rustle.") - for(,user.stat==2) - sleep(600) - if (!user) + mend() + var/mob/living/user = usr + src = null + user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!") + user.take_overall_damage(200, 0) + runedec+=10 + user.visible_message("\red [user] keels over dead, his blood glowing blue as it escapes his body and dissipates into thin air.", \ + "\red In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.", \ + "\red You hear faint rustle.") + for(,user.stat==2) + sleep(600) + if (!user) + return + runedec-=10 return - runedec-=10 - return /////////////////////////////////////////FOURTEETH RUNE -// returns 0 if the rune is not used. returns 1 if the rune is used. -/obj/effect/rune/proc/communicate() - . = 1 // Default output is 1. If the rune is deleted it will return 1 - var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input) - if (istype(src)) - fizzle() - return 0 - else - return 0 - - // record this - cult_log("[key_name(usr,0)] says : [input]") + // returns 0 if the rune is not used. returns 1 if the rune is used. + communicate() + . = 1 // Default output is 1. If the rune is deleted it will return 1 + var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") + if(!input) + if (istype(src)) + fizzle() + return 0 + else + return 0 + if(istype(src,/obj/effect/rune)) + usr.say("O bidai nabora se[pick("'","`")]sma!") + else + usr.whisper("O bidai nabora se[pick("'","`")]sma!") - var/obj/cult_viewpoint/vp = getCultViewpoint(usr) - if (!vp) - return 0 - - var/displayName = vp.get_display_name() - var/cultName = vp.get_cult_name() - - if(istype(src,/obj/effect/rune)) - usr.say("O bidai nabora se[pick("'","`")]sma!") - else - usr.whisper("O bidai nabora se[pick("'","`")]sma!") - - if(istype(src,/obj/effect/rune)) - usr.say("[input]") - else - usr.whisper("[input]") - - for(var/datum/mind/H in ticker.mode.cult) - if (H.current) - H.current << "[cultName]: [input]" - - for(var/mob/spirit/spirit in spirits) - spirit << "[displayName]: [input]" - - del(src) - return 1 + if(istype(src,/obj/effect/rune)) + usr.say("[input]") + else + usr.whisper("[input]") + for(var/datum/mind/H in ticker.mode.cult) + if (H.current) + H.current << "\red \b [input]" + del(src) + return 1 /////////////////////////////////////////FIFTEENTH RUNE -/obj/effect/rune/proc/sacrifice() - var/list/mob/living/carbon/human/cultsinrange = list() - var/list/mob/living/carbon/human/victims = list() - for(var/mob/living/carbon/human/V in src.loc)//Checks for non-cultist humans to sacrifice - if(ishuman(V)) - if(!(iscultist(V))) - victims += V//Checks for cult status and mob type - for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards - if(istype(I,/obj/item/brain)) - var/obj/item/brain/B = I - victims += B.brainmob - else if(istype(I,/obj/item/device/mmi)) - var/obj/item/device/mmi/B = I - victims += B.brainmob - else if(istype(I,/obj/item/device/aicard)) - for(var/mob/living/silicon/ai/A in I) - victims += A - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - cultsinrange += C - C.say("Barhah hra zar[pick("'","`")]garis!") - for(var/mob/H in victims) - if (ticker.mode.name == "cult") - if(H.mind == ticker.mode:sacrifice_target) - if(cultsinrange.len >= 3) - sacrificed += H.mind - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining + sacrifice() + var/list/mob/living/carbon/human/cultsinrange = list() + var/list/mob/living/carbon/human/victims = list() + for(var/mob/living/carbon/human/V in src.loc)//Checks for non-cultist humans to sacrifice + if(ishuman(V)) + if(!(iscultist(V))) + victims += V//Checks for cult status and mob type + for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards + if(istype(I,/obj/item/brain)) + var/obj/item/brain/B = I + victims += B.brainmob + else if(istype(I,/obj/item/device/mmi)) + var/obj/item/device/mmi/B = I + victims += B.brainmob + else if(istype(I,/obj/item/device/aicard)) + for(var/mob/living/silicon/ai/A in I) + victims += A + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + cultsinrange += C + C.say("Barhah hra zar[pick("'","`")]garis!") + for(var/mob/H in victims) + if (ticker.mode.name == "cult") + if(H.mind == ticker.mode:sacrifice_target) + if(cultsinrange.len >= 3) + sacrificed += H.mind + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." + else + usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." else - H.gib() - usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." + if(cultsinrange.len >= 3) + if(H.stat !=2) + if(prob(80)) + usr << "\red The Geometer of Blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, this soul was not enough to gain His favor." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + else + if(H.stat !=2) + usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." + else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() else - usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." - else - if(cultsinrange.len >= 3) - if(H.stat !=2) - if(prob(80)) - usr << "\red The Geometer of Blood accepts this sacrifice." + if(cultsinrange.len >= 3) + if(H.stat !=2) + if(prob(80)) + usr << "\red The Geometer of Blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, this soul was not enough to gain His favor." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + else + if(H.stat !=2) + usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." + else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + if(isrobot(H)) + H.dust()//To prevent the MMI from remaining + else + H.gib() + for(var/mob/living/carbon/monkey/M in src.loc) + if (ticker.mode.name == "cult") + if(M.mind == ticker.mode:sacrifice_target) + if(cultsinrange.len >= 3) + sacrificed += M.mind + usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." + else + usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." + continue + else + if(prob(20)) + usr << "\red The Geometer of Blood accepts your meager sacrifice." ticker.mode:grant_runeword(usr) else usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, this soul was not enough to gain His favor." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - else - if(prob(40)) - usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere dead body is not enough to satisfy Him." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() + usr << "\red However, a mere monkey is not enough to satisfy Him." else - if(H.stat !=2) - usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." - else - if(prob(40)) - usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere dead body is not enough to satisfy Him." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - else - if(cultsinrange.len >= 3) - if(H.stat !=2) - if(prob(80)) - usr << "\red The Geometer of Blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, this soul was not enough to gain His favor." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - else - if(prob(40)) - usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere dead body is not enough to satisfy Him." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - else - if(H.stat !=2) - usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." - else - if(prob(40)) - usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere dead body is not enough to satisfy Him." - if(isrobot(H)) - H.dust()//To prevent the MMI from remaining - else - H.gib() - for(var/mob/living/carbon/monkey/M in src.loc) - if (ticker.mode.name == "cult") - if(M.mind == ticker.mode:sacrifice_target) - if(cultsinrange.len >= 3) - sacrificed += M.mind - usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." - else - usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." - continue - else - if(prob(20)) usr << "\red The Geometer of Blood accepts your meager sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere monkey is not enough to satisfy Him." - else - usr << "\red The Geometer of Blood accepts your meager sacrifice." - if(prob(20)) - ticker.mode.grant_runeword(usr) - M.gib() + if(prob(20)) + ticker.mode.grant_runeword(usr) + M.gib() /* for(var/mob/living/carbon/alien/A) - for(var/mob/K in cultsinrange) - K.say("Barhah hra zar'garis!") - A.dust() /// A.gib() doesnt work for some reason, and dust() leaves that skull and bones thingy which we dont really need. - if (ticker.mode.name == "cult") - if(prob(75)) - usr << "\red The Geometer of Blood accepts your exotic sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of Blood accepts your exotic sacrifice." - usr << "\red However, this alien is not enough to gain His favor." - else - usr << "\red The Geometer of Blood accepts your exotic sacrifice." - return - return fizzle() */ + for(var/mob/K in cultsinrange) + K.say("Barhah hra zar'garis!") + A.dust() /// A.gib() doesnt work for some reason, and dust() leaves that skull and bones thingy which we dont really need. + if (ticker.mode.name == "cult") + if(prob(75)) + usr << "\red The Geometer of Blood accepts your exotic sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of Blood accepts your exotic sacrifice." + usr << "\red However, this alien is not enough to gain His favor." + else + usr << "\red The Geometer of Blood accepts your exotic sacrifice." + return + return fizzle() */ /////////////////////////////////////////SIXTEENTH RUNE -/obj/effect/rune/proc/revealrunesrune() - revealrunes(src) - -/obj/effect/rune/proc/revealrunes(var/obj/W as obj) - var/go=0 - var/rad - var/S=0 - if(istype(W,/obj/effect/rune)) - rad = 6 - go = 1 - if (istype(W,/obj/item/weapon/paper/talisman)) - rad = 4 - go = 1 - if (istype(W,/obj/item/weapon/nullrod)) - rad = 1 - go = 1 - if(go) - for(var/obj/effect/rune/R in orange(rad,src)) - if(R!=src) - R:visibility=15 - S=1 - if(S) - if(istype(W,/obj/item/weapon/nullrod)) - usr << "\red Arcane markings suddenly glow from underneath a thin layer of dust!" - return - if(istype(W,/obj/effect/rune)) - usr.say("Nikt[pick("'","`")]o barada kla'atu!") - for (var/mob/V in viewers(src)) - V.show_message("\red The rune turns into red dust, reveaing the surrounding runes.", 3) - del(src) - return - if(istype(W,/obj/item/weapon/paper/talisman)) - usr.whisper("Nikt[pick("'","`")]o barada kla'atu!") - usr << "\red Your talisman turns into red dust, revealing the surrounding runes." - for (var/mob/V in orange(1,usr.loc)) - if(V!=usr) - V.show_message("\red Red dust emanates from [usr]'s hands for a moment.", 3) - return - return - if(istype(W,/obj/effect/rune)) - return fizzle() - if(istype(W,/obj/item/weapon/paper/talisman)) - call(/obj/effect/rune/proc/fizzle)() - return + revealrunes(var/obj/W as obj) + var/go=0 + var/rad + var/S=0 + if(istype(W,/obj/effect/rune)) + rad = 6 + go = 1 + if (istype(W,/obj/item/weapon/paper/talisman)) + rad = 4 + go = 1 + if (istype(W,/obj/item/weapon/nullrod)) + rad = 1 + go = 1 + if(go) + for(var/obj/effect/rune/R in orange(rad,src)) + if(R!=src) + R:visibility=15 + S=1 + if(S) + if(istype(W,/obj/item/weapon/nullrod)) + usr << "\red Arcane markings suddenly glow from underneath a thin layer of dust!" + return + if(istype(W,/obj/effect/rune)) + usr.say("Nikt[pick("'","`")]o barada kla'atu!") + for (var/mob/V in viewers(src)) + V.show_message("\red The rune turns into red dust, reveaing the surrounding runes.", 3) + del(src) + return + if(istype(W,/obj/item/weapon/paper/talisman)) + usr.whisper("Nikt[pick("'","`")]o barada kla'atu!") + usr << "\red Your talisman turns into red dust, revealing the surrounding runes." + for (var/mob/V in orange(1,usr.loc)) + if(V!=usr) + V.show_message("\red Red dust emanates from [usr]'s hands for a moment.", 3) + return + return + if(istype(W,/obj/effect/rune)) + return fizzle() + if(istype(W,/obj/item/weapon/paper/talisman)) + call(/obj/effect/rune/proc/fizzle)() + return /////////////////////////////////////////SEVENTEENTH RUNE -/obj/effect/rune/proc/wall() - usr.say("Khari[pick("'","`")]d! Eske'te tannin!") - src.density = !src.density - var/mob/living/user = usr - user.take_organ_damage(2, 0) - if(src.density) - usr << "\red Your blood flows into the rune, and you feel that the very space over the rune thickens." - else - usr << "\red Your blood flows into the rune, and you feel as the rune releases its grasp on space." - return + wall() + usr.say("Khari[pick("'","`")]d! Eske'te tannin!") + src.density = !src.density + var/mob/living/user = usr + user.take_organ_damage(2, 0) + if(src.density) + usr << "\red Your blood flows into the rune, and you feel that the very space over the rune thickens." + else + usr << "\red Your blood flows into the rune, and you feel as the rune releases its grasp on space." + return /////////////////////////////////////////EIGHTTEENTH RUNE -/obj/effect/rune/proc/freedom() - var/mob/living/user = usr - var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living/carbon)) - cultists+=H.current - var/list/mob/living/carbon/users = new - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - users+=C - if(users.len>=3) - var/mob/living/carbon/cultist = input("Choose the one who you want to free", "Followers of Geometer") as null|anything in (cultists - users) - if(!cultist) + freedom() + var/mob/living/user = usr + var/list/mob/living/carbon/cultists = new + for(var/datum/mind/H in ticker.mode.cult) + if (istype(H.current,/mob/living/carbon)) + cultists+=H.current + var/list/mob/living/carbon/users = new + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + users+=C + if(users.len>=3) + var/mob/living/carbon/cultist = input("Choose the one who you want to free", "Followers of Geometer") as null|anything in (cultists - users) + if(!cultist) + return fizzle() + if (cultist == user) //just to be sure. + return + if(!(cultist.buckled || \ + cultist.handcuffed || \ + istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle) || \ + (istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) || \ + (istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) || \ + (istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) \ + )) + user << "\red The [cultist] is already free." + return + cultist.buckled = null + if (cultist.handcuffed) + cultist.handcuffed.loc = cultist.loc + cultist.handcuffed = null + cultist.update_inv_handcuffed() + if (cultist.legcuffed) + cultist.legcuffed.loc = cultist.loc + cultist.legcuffed = null + cultist.update_inv_legcuffed() + if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) + cultist.u_equip(cultist.wear_mask) + if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) + cultist.loc:welded = 0 + if(istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) + cultist.loc:locked = 0 + if(istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) + cultist.loc:locked = 0 + for(var/mob/living/carbon/C in users) + user.take_overall_damage(15, 0) + C.say("Khari[pick("'","`")]d! Gual'te nikka!") + del(src) return fizzle() - if (cultist == user) //just to be sure. - return - if(!(cultist.buckled || \ - cultist.handcuffed || \ - istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle) || \ - (istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) || \ - (istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) || \ - (istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) \ - )) - user << "\red The [cultist] is already free." - return - cultist.buckled = null - if (cultist.handcuffed) - cultist.handcuffed.loc = cultist.loc - cultist.handcuffed = null - cultist.update_inv_handcuffed() - if (cultist.legcuffed) - cultist.legcuffed.loc = cultist.loc - cultist.legcuffed = null - cultist.update_inv_legcuffed() - if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) - cultist.u_equip(cultist.wear_mask) - if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) - cultist.loc:welded = 0 - if(istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) - cultist.loc:locked = 0 - if(istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) - cultist.loc:locked = 0 - for(var/mob/living/carbon/C in users) - user.take_overall_damage(15, 0) - C.say("Khari[pick("'","`")]d! Gual'te nikka!") - del(src) - return fizzle() /////////////////////////////////////////NINETEENTH RUNE -/obj/effect/rune/proc/cultsummon() - var/mob/living/user = usr - var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living/carbon)) - cultists+=H.current - var/list/mob/living/carbon/users = new - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - users+=C - if(users.len>=3) - var/mob/living/carbon/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - user) - if(!cultist) + cultsummon() + var/mob/living/user = usr + var/list/mob/living/carbon/cultists = new + for(var/datum/mind/H in ticker.mode.cult) + if (istype(H.current,/mob/living/carbon)) + cultists+=H.current + var/list/mob/living/carbon/users = new + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + users+=C + if(users.len>=3) + var/mob/living/carbon/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - user) + if(!cultist) + return fizzle() + if (cultist == user) //just to be sure. + return + if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet))) + user << "\red You cannot summon the [cultist], for his shackles of blood are strong" + return fizzle() + cultist.loc = src.loc + cultist.lying = 1 + cultist.regenerate_icons() + for(var/mob/living/carbon/human/C in orange(1,src)) + if(iscultist(C) && !C.stat) + C.say("N'ath reth sh'yro eth d[pick("'","`")]rekkathnor!") + C.take_overall_damage(25, 0) + user.visible_message("\red Rune disappears with a flash of red light, and in its place now a body lies.", \ + "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a body.", \ + "\red You hear a pop and smell ozone.") + del(src) return fizzle() - if (cultist == user) //just to be sure. - return - if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet))) - user << "\red You cannot summon the [cultist], for his shackles of blood are strong" - return fizzle() - cultist.loc = src.loc - cultist.lying = 1 - cultist.regenerate_icons() - for(var/mob/living/carbon/human/C in orange(1,src)) - if(iscultist(C) && !C.stat) - C.say("N'ath reth sh'yro eth d[pick("'","`")]rekkathnor!") - C.take_overall_damage(25, 0) - user.visible_message("\red Rune disappears with a flash of red light, and in its place now a body lies.", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a body.", \ - "\red You hear a pop and smell ozone.") - del(src) - return fizzle() /////////////////////////////////////////TWENTIETH RUNES -/obj/effect/rune/proc/deafen() - if(istype(src,/obj/effect/rune)) - var/affected = 0 - for(var/mob/living/carbon/C in range(7,src)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.ear_deaf += 50 - C.show_message("\red The world around you suddenly becomes quiet.", 3) - affected++ - if(prob(1)) - C.sdisabilities |= DEAF - if(affected) - usr.say("Sti[pick("'","`")] kaliedir!") - usr << "\red The world becomes quiet as the deafening rune dissipates into fine dust." - del(src) - else - return fizzle() - else - var/affected = 0 - for(var/mob/living/carbon/C in range(7,usr)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.ear_deaf += 30 - //talismans is weaker. - C.show_message("\red The world around you suddenly becomes quiet.", 3) - affected++ - if(affected) - usr.whisper("Sti[pick("'","`")] kaliedir!") - usr << "\red Your talisman turns into gray dust, deafening everyone around." - for (var/mob/V in orange(1,src)) - if(!(iscultist(V))) - V.show_message("\red Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..", 3) - return + deafen() + if(istype(src,/obj/effect/rune)) + var/affected = 0 + for(var/mob/living/carbon/C in range(7,src)) + if (iscultist(C)) + continue + var/obj/item/weapon/nullrod/N = locate() in C + if(N) + continue + C.ear_deaf += 50 + C.show_message("\red The world around you suddenly becomes quiet.", 3) + affected++ + if(prob(1)) + C.sdisabilities |= DEAF + if(affected) + usr.say("Sti[pick("'","`")] kaliedir!") + usr << "\red The world becomes quiet as the deafening rune dissipates into fine dust." + del(src) + else + return fizzle() + else + var/affected = 0 + for(var/mob/living/carbon/C in range(7,usr)) + if (iscultist(C)) + continue + var/obj/item/weapon/nullrod/N = locate() in C + if(N) + continue + C.ear_deaf += 30 + //talismans is weaker. + C.show_message("\red The world around you suddenly becomes quiet.", 3) + affected++ + if(affected) + usr.whisper("Sti[pick("'","`")] kaliedir!") + usr << "\red Your talisman turns into gray dust, deafening everyone around." + for (var/mob/V in orange(1,src)) + if(!(iscultist(V))) + V.show_message("\red Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..", 3) + return -/obj/effect/rune/proc/blind() - if(istype(src,/obj/effect/rune)) - var/affected = 0 - for(var/mob/living/carbon/C in viewers(src)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.eye_blurry += 50 - C.eye_blind += 20 - if(prob(5)) - C.disabilities |= NEARSIGHTED - if(prob(10)) - C.sdisabilities |= BLIND - C.show_message("\red Suddenly you see red flash that blinds you.", 3) - affected++ - if(affected) - usr.say("Sti[pick("'","`")] kaliesin!") - usr << "\red The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust." - del(src) - else - return fizzle() - else - var/affected = 0 - for(var/mob/living/carbon/C in view(2,usr)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.eye_blurry += 30 - C.eye_blind += 10 - //talismans is weaker. - affected++ - C.show_message("\red You feel a sharp pain in your eyes, and the world disappears into darkness..", 3) - if(affected) - usr.whisper("Sti[pick("'","`")] kaliesin!") - usr << "\red Your talisman turns into gray dust, blinding those who not follow the Nar-Sie." - return + blind() + if(istype(src,/obj/effect/rune)) + var/affected = 0 + for(var/mob/living/carbon/C in viewers(src)) + if (iscultist(C)) + continue + var/obj/item/weapon/nullrod/N = locate() in C + if(N) + continue + C.eye_blurry += 50 + C.eye_blind += 20 + if(prob(5)) + C.disabilities |= NEARSIGHTED + if(prob(10)) + C.sdisabilities |= BLIND + C.show_message("\red Suddenly you see red flash that blinds you.", 3) + affected++ + if(affected) + usr.say("Sti[pick("'","`")] kaliesin!") + usr << "\red The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust." + del(src) + else + return fizzle() + else + var/affected = 0 + for(var/mob/living/carbon/C in view(2,usr)) + if (iscultist(C)) + continue + var/obj/item/weapon/nullrod/N = locate() in C + if(N) + continue + C.eye_blurry += 30 + C.eye_blind += 10 + //talismans is weaker. + affected++ + C.show_message("\red You feel a sharp pain in your eyes, and the world disappears into darkness..", 3) + if(affected) + usr.whisper("Sti[pick("'","`")] kaliesin!") + usr << "\red Your talisman turns into gray dust, blinding those who not follow the Nar-Sie." + return -/obj/effect/rune/proc/bloodboil() //cultists need at least one DANGEROUS rune. Even if they're all stealthy. + bloodboil() //cultists need at least one DANGEROUS rune. Even if they're all stealthy. /* - var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living/carbon)) - cultists+=H.current + var/list/mob/living/carbon/cultists = new + for(var/datum/mind/H in ticker.mode.cult) + if (istype(H.current,/mob/living/carbon)) + cultists+=H.current */ - var/culcount = 0 //also, wording for it is old wording for obscure rune, which is now hide-see-blood. + var/culcount = 0 //also, wording for it is old wording for obscure rune, which is now hide-see-blood. // var/list/cultboil = list(cultists-usr) //and for this words are destroy-see-blood. - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - culcount++ - if(culcount>=3) - for(var/mob/living/carbon/M in viewers(usr)) - if(iscultist(M)) - continue - var/obj/item/weapon/nullrod/N = locate() in M - if(N) - continue - cult_log(": Blood Boil damaged [key_name_admin(M)].") - M.take_overall_damage(51,51) - M << "\red Your blood boils!" - if(prob(5)) - spawn(5) - M.gib() - for(var/obj/effect/rune/R in view(src)) - if(prob(10)) - explosion(R.loc, -1, 0, 1, 5) - for(var/mob/living/carbon/human/C in orange(1,src)) - if(iscultist(C) && !C.stat) - C.say("Dedo ol[pick("'","`")]btoh!") - C.take_overall_damage(15, 0) - del(src) - else - return fizzle() - return + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + culcount++ + if(culcount>=3) + for(var/mob/living/carbon/M in viewers(usr)) + if(iscultist(M)) + continue + var/obj/item/weapon/nullrod/N = locate() in M + if(N) + continue + M.take_overall_damage(51,51) + M << "\red Your blood boils!" + if(prob(5)) + spawn(5) + M.gib() + for(var/obj/effect/rune/R in view(src)) + if(prob(10)) + explosion(R.loc, -1, 0, 1, 5) + for(var/mob/living/carbon/human/C in orange(1,src)) + if(iscultist(C) && !C.stat) + C.say("Dedo ol[pick("'","`")]btoh!") + C.take_overall_damage(15, 0) + del(src) + else + return fizzle() + return // WIP rune, I'll wait for Rastaf0 to add limited blood. -/obj/effect/rune/proc/burningblood() - var/culcount = 0 - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - culcount++ - if(culcount >= 5) - for(var/obj/effect/rune/R in world) - if(R.blood_DNA == src.blood_DNA) - for(var/mob/living/M in orange(2,R)) - M.take_overall_damage(0,15) - if (R.invisibility>M.see_invisible) - M << "\red Aargh it burns!" - else - M << "\red Rune suddenly ignites, burning you!" - var/turf/T = get_turf(R) - T.hotspot_expose(700,125) - for(var/obj/effect/decal/cleanable/blood/B in world) - if(B.blood_DNA == src.blood_DNA) - for(var/mob/living/M in orange(1,B)) - M.take_overall_damage(0,5) - M << "\red Blood suddenly ignites, burning you!" - var/turf/T = get_turf(B) - T.hotspot_expose(700,125) - del(B) - del(src) + burningblood() + var/culcount = 0 + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C) && !C.stat) + culcount++ + if(culcount >= 5) + for(var/obj/effect/rune/R in world) + if(R.blood_DNA == src.blood_DNA) + for(var/mob/living/M in orange(2,R)) + M.take_overall_damage(0,15) + if (R.invisibility>M.see_invisible) + M << "\red Aargh it burns!" + else + M << "\red Rune suddenly ignites, burning you!" + var/turf/T = get_turf(R) + T.hotspot_expose(700,125) + for(var/obj/effect/decal/cleanable/blood/B in world) + if(B.blood_DNA == src.blood_DNA) + for(var/mob/living/M in orange(1,B)) + M.take_overall_damage(0,5) + M << "\red Blood suddenly ignites, burning you!" + var/turf/T = get_turf(B) + T.hotspot_expose(700,125) + del(B) + del(src) ////////// Rune 24 (counting burningblood, which kinda doesnt work yet.) -/obj/effect/rune/proc/runestun(var/mob/living/T as mob) - if(istype(src,/obj/effect/rune)) ///When invoked as rune, flash and stun everyone around. - usr.say("Fuu ma[pick("'","`")]jin!") - for(var/mob/living/L in viewers(src)) + runestun(var/mob/living/T as mob) + if(istype(src,/obj/effect/rune)) ///When invoked as rune, flash and stun everyone around. + usr.say("Fuu ma[pick("'","`")]jin!") + for(var/mob/living/L in viewers(src)) - if(iscarbon(L)) - var/mob/living/carbon/C = L - flick("e_flash", C.flash) - if(C.stuttering < 1 && (!(HULK in C.mutations))) - C.stuttering = 1 - C.Weaken(1) - C.Stun(1) - C.show_message("\red The rune explodes in a bright flash.", 3) + if(iscarbon(L)) + var/mob/living/carbon/C = L + flick("e_flash", C.flash) + if(C.stuttering < 1 && (!(HULK in C.mutations))) + C.stuttering = 1 + C.Weaken(1) + C.Stun(1) + C.show_message("\red The rune explodes in a bright flash.", 3) - else if(issilicon(L)) - var/mob/living/silicon/S = L - S.Weaken(5) - S.show_message("\red BZZZT... The rune has exploded in a bright flash.", 3) - del(src) - else ///When invoked as talisman, stun and mute the target mob. - usr.say("Dream sign ''Evil sealing talisman'[pick("'","`")]!") - var/obj/item/weapon/nullrod/N = locate() in T - if(N) - for(var/mob/O in viewers(T, null)) - O.show_message(text("\red [] invokes a talisman at [], but they are unaffected!", usr, T), 1) - else - for(var/mob/O in viewers(T, null)) - O.show_message(text("\red [] invokes a talisman at []", usr, T), 1) + else if(issilicon(L)) + var/mob/living/silicon/S = L + S.Weaken(5) + S.show_message("\red BZZZT... The rune has exploded in a bright flash.", 3) + del(src) + else ///When invoked as talisman, stun and mute the target mob. + usr.say("Dream sign ''Evil sealing talisman'[pick("'","`")]!") + var/obj/item/weapon/nullrod/N = locate() in T + if(N) + for(var/mob/O in viewers(T, null)) + O.show_message(text("\red [] invokes a talisman at [], but they are unaffected!", usr, T), 1) + else + for(var/mob/O in viewers(T, null)) + O.show_message(text("\red [] invokes a talisman at []", usr, T), 1) - if(issilicon(T)) - T.Weaken(15) + if(issilicon(T)) + T.Weaken(15) - else if(iscarbon(T)) - var/mob/living/carbon/C = T - flick("e_flash", C.flash) - if (!(HULK in C.mutations)) - C.silent += 15 - C.Weaken(25) - C.Stun(25) - return + else if(iscarbon(T)) + var/mob/living/carbon/C = T + flick("e_flash", C.flash) + if (!(HULK in C.mutations)) + C.silent += 15 + C.Weaken(25) + C.Stun(25) + return /////////////////////////////////////////TWENTY-FIFTH RUNE -/obj/effect/rune/proc/armor() - var/mob/living/carbon/human/user = usr - if(istype(src,/obj/effect/rune)) - usr.say("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") - else - usr.whisper("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") - usr.visible_message("\red The rune disappears with a flash of red light, and a set of armor appears on [usr]...", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of armor.") + armor() + var/mob/living/carbon/human/user = usr + if(istype(src,/obj/effect/rune)) + usr.say("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") + else + usr.whisper("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") + usr.visible_message("\red The rune disappears with a flash of red light, and a set of armor appears on [usr]...", \ + "\red You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of armor.") - user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head) - user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) - user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) - user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) - //the above update their overlay icons cache but do not call update_icons() - //the below calls update_icons() at the end, which will update overlay icons by using the (now updated) cache - user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) //put in hands or on floor + user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head) + user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) + user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) + user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) + //the above update their overlay icons cache but do not call update_icons() + //the below calls update_icons() at the end, which will update overlay icons by using the (now updated) cache + user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) //put in hands or on floor - del(src) - return + del(src) + return diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 60bb93912e..104fbf1cdb 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -122,7 +122,7 @@ rcd light flash thingy on matter drain mod_pick_name = "recam" uses = 10 -/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameraNetwork.viewpoints) +/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras) set name = "Reactivate Camera" set category = "Malfunction" if (istype (C, /obj/machinery/camera)) @@ -143,7 +143,7 @@ rcd light flash thingy on matter drain mod_pick_name = "upgradecam" uses = 10 -/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameraNetwork.viewpoints) +/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras) set name = "Upgrade Camera" set category = "Malfunction" if(istype(C)) @@ -156,7 +156,7 @@ rcd light flash thingy on matter drain if(!C.isXRay()) C.upgradeXRay() //Update what it can see. - cameraNetwork.updateVisibility(C) + cameranet.updateVisibility(C) upgraded = 1 if(!C.isEmpProof()) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 38dc530fb0..daea3219d6 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -39,7 +39,7 @@ assembly = new(src) assembly.state = 4 /* // Use this to look for cameras that have the same c_tag. - for(var/obj/machinery/camera/C in cameraNetwork.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) var/list/tempnetwork = C.network&src.network if(C != src && C.c_tag == src.c_tag && tempnetwork.len) world.log << "[src.c_tag] [src.x] [src.y] [src.z] conflicts with [C.c_tag] [C.x] [C.y] [C.z]" @@ -59,7 +59,7 @@ icon_state = "[initial(icon_state)]emp" var/list/previous_network = network network = list() - cameraNetwork.removeViewpoint(src) + cameranet.removeCamera(src) stat |= EMPED SetLuminosity(0) triggerCameraAlarm() @@ -69,7 +69,7 @@ stat &= ~EMPED cancelCameraAlarm() if(can_use()) - cameraNetwork.addViewpoint(src) + cameranet.addCamera(src) for(var/mob/O in mob_list) if (istype(O.machine, /obj/machinery/computer/security)) var/obj/machinery/computer/security/S = O.machine @@ -92,7 +92,7 @@ /obj/machinery/camera/proc/setViewRange(var/num = 7) src.view_range = num - cameraNetwork.updateVisibility(src, 0) + cameranet.updateVisibility(src, 0) /obj/machinery/camera/proc/shock(var/mob/living/user) if(!istype(user)) diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index c4afc34edf..d5408d3330 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -100,7 +100,7 @@ C.network = uniquelist(tempnetwork) tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS) if(!tempnetwork.len)//Camera isn't on any open network - remove its chunk from AI visibility. - cameraNetwork.removeViewpoint(C) + cameranet.removeCamera(C) C.c_tag = input diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index b745cd37f8..e088103fab 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -4,7 +4,7 @@ return var/list/L = list() - for (var/obj/machinery/camera/C in cameraNetwork.viewpoints) + for (var/obj/machinery/camera/C in cameranet.cameras) L.Add(C) camera_sort(L) @@ -168,9 +168,9 @@ return 0 if(isrobot(M)) var/mob/living/silicon/robot/R = M - if(!(R.camera && R.camera.can_use()) && !cameraNetwork.checkCanSee(M)) + if(!(R.camera && R.camera.can_use()) && !cameranet.checkCameraVis(M)) return 0 - else if(!cameraNetwork.checkCanSee(M)) + else if(!cameranet.checkCameraVis(M)) return 0 return 1 diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 46b9b22d2a..05d0ccea8d 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -36,7 +36,7 @@ user.set_machine(src) var/list/L = list() - for (var/obj/machinery/camera/C in cameraNetwork.viewpoints) + for (var/obj/machinery/camera/C in cameranet.cameras) L.Add(C) camera_sort(L) @@ -206,4 +206,4 @@ name = "Mission Monitor" desc = "Used to access the built-in cameras in helmets." icon_state = "syndicam" - network = list("NUKE") + network = list("NUKE") \ No newline at end of file diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 2d86981ebd..d3f276abe0 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -262,8 +262,6 @@ /obj/machinery/door/proc/requiresID() return 1 -/* - /obj/machinery/door/proc/update_nearby_tiles(need_rebuild) if(!air_master) return 0 @@ -274,8 +272,6 @@ return 1 -*/ - /obj/machinery/door/proc/update_heat_protection(var/turf/simulated/source) if(istype(source)) if(src.density && (src.opacity || src.heat_proof)) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 018d0fe882..e2bf6f7be2 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -108,7 +108,6 @@ var/global/floorIsLava = 0 body += "Is an AI " else if(ishuman(M)) body += {"Make AI | - Make Mask | Make Robot | Make Alien | Make slime diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 7e1e967fc5..e601f069c6 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -22,29 +22,25 @@ F << "[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z]) || [src] [message]
" //ADMINVERBS -/client/proc/investigate_show( subject in list("hrefs","notes","singulo","cult") ) +/client/proc/investigate_show( subject in list("hrefs","notes","singulo") ) set name = "Investigate" set category = "Admin" if(!holder) return - - var/list/basic_subjects = list("singulo","cult") - - if(subject in basic_subjects) - var/F = investigate_subject2file(subject) - if(!F) - src << "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed." - return - src << browse(F,"window=investigate[subject];size=800x300") - return - - - if(subject=="hrefs") //persistant logs and stuff - if(config && config.log_hrefs) - if(href_logfile) - src << browse(href_logfile,"window=investigate[subject];size=800x300") - else - src << "Error: admin_investigate: No href logfile found." + switch(subject) + if("singulo") //general one-round-only stuff + var/F = investigate_subject2file(subject) + if(!F) + src << "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed." + return + src << browse(F,"window=investigate[subject];size=800x300") + + if("hrefs") //persistant logs and stuff + if(config && config.log_hrefs) + if(href_logfile) + src << browse(href_logfile,"window=investigate[subject];size=800x300") + else + src << "Error: admin_investigate: No href logfile found." + return + else + src << "Error: admin_investigate: Href Logging is not on." return - else - src << "Error: admin_investigate: Href Logging is not on." - return diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index b5aa11c6e9..66de256c9e 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1192,15 +1192,6 @@ message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(H)]!", 1) log_admin("[key_name(usr)] AIized [key_name(H)]") H.AIize() - - - else if(href_list["makemask"]) - if(!check_rights(R_SPAWN)) return - var/mob/currentMob = locate(href_list["makemask"]) - message_admins("\red Admin [key_name_admin(usr)] made [key_name_admin(currentMob)] into a Mask of Nar'Sie!", 1) - log_admin("[key_name(usr)] made [key_name(currentMob)] into a Mask of Nar'Sie!") - currentMob.make_into_mask(0,0) - else if(href_list["makealien"]) if(!check_rights(R_SPAWN)) return diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 19edf26e77..76f1b42046 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -58,7 +58,7 @@ var/intercom_range_display_status = 0 del(C) if(camera_range_display_status) - for(var/obj/machinery/camera/C in cameraNetwork.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) new/obj/effect/debugging/camera_range(C.loc) feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -74,7 +74,7 @@ var/intercom_range_display_status = 0 var/list/obj/machinery/camera/CL = list() - for(var/obj/machinery/camera/C in cameraNetwork.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) CL += C var/output = {"CAMERA ANNOMALITIES REPORT


diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index efbee3cfd6..90ae7667dd 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -13,7 +13,7 @@ else camera = new /obj/machinery/camera(src) camera.network = list("ERT") - cameraNetwork.removeViewpoint(camera) + cameranet.removeCamera(camera) camera.c_tag = user.name user << "\blue User scanned as [camera.c_tag]. Camera activated." diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index 2e9c5185a6..05411337bc 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -96,7 +96,7 @@ else camera = new /obj/machinery/camera(src) camera.network = list("NUKE") - cameraNetwork.removeViewpoint(camera) + cameranet.removeCamera(camera) camera.c_tag = user.name user << "\blue User scanned as [camera.c_tag]. Camera activated." diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index bd7d4fe3a8..95ebdf2011 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -58,10 +58,9 @@ var/datum/organ/external/head = get_organ("head") var/mob/living/simple_animal/borer/B - if(istype(head)) - for(var/I in head.implants) - if(istype(I,/mob/living/simple_animal/borer)) - B = I + for(var/I in head.implants) + if(istype(I,/mob/living/simple_animal/borer)) + B = I if(B) if(!B.ckey && ckey && B.controlling) B.ckey = ckey diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a677bd2445..baceaa2073 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -326,7 +326,6 @@ return /mob/living/Move(a, b, flag) - if (buckled) return diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 937ed92874..42c4b0745b 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -318,7 +318,7 @@ var/list/ai_list = list() unset_machine() src << browse(null, t1) if (href_list["switchcamera"]) - switchCamera(locate(href_list["switchcamera"])) in cameraNetwork.viewpoints + switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras if (href_list["showalerts"]) ai_alerts() //Carn: holopad requests @@ -548,7 +548,7 @@ var/list/ai_list = list() var/mob/living/silicon/ai/U = usr - for (var/obj/machinery/camera/C in cameraNetwork.viewpoints) + for (var/obj/machinery/camera/C in cameranet.cameras) if(!C.can_use()) continue @@ -566,7 +566,7 @@ var/list/ai_list = list() if(isnull(network)) network = old_network // If nothing is selected else - for(var/obj/machinery/camera/C in cameraNetwork.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) if(!C.can_use()) continue if(network in C.network) diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index d857856b7f..7d52fbd7a2 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -1,14 +1,148 @@ -/datum/visibility_network/cameras - ChunkType = /datum/visibility_chunk/camera +// CAMERA NET +// +// The datum containing all the chunks. -/datum/visibility_network/cameras/getViewpointFromMob(var/mob/currentMob) - var/mob/living/silicon/robot/currentRobot=currentMob - if(currentRobot) - return currentRobot.camera - return FALSE - -/datum/visibility_network/cameras/validViewpoint(var/viewpoint) - var/obj/machinery/camera/c = viewpoint - if (!c) - return FALSE - return c.can_use() \ No newline at end of file +var/datum/cameranet/cameranet = new() + +/datum/cameranet + // The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). + var/list/cameras = list() + // The chunks of the map, mapping the areas that the cameras can see. + var/list/chunks = list() + var/ready = 0 + +// Checks if a chunk has been Generated in x, y, z. +/datum/cameranet/proc/chunkGenerated(x, y, z) + x &= ~0xf + y &= ~0xf + var/key = "[x],[y],[z]" + return (chunks[key]) + +// Returns the chunk in the x, y, z. +// If there is no chunk, it creates a new chunk and returns that. +/datum/cameranet/proc/getCameraChunk(x, y, z) + x &= ~0xf + y &= ~0xf + var/key = "[x],[y],[z]" + if(!chunks[key]) + chunks[key] = new /datum/camerachunk(null, x, y, z) + + return chunks[key] + +// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. + +/datum/cameranet/proc/visibility(mob/aiEye/ai) + // 0xf = 15 + 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/chunk in remove) + var/datum/camerachunk/c = chunk + c.remove(ai) + + for(var/chunk in add) + var/datum/camerachunk/c = chunk + c.add(ai) + +// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. + +/datum/cameranet/proc/updateVisibility(atom/A, var/opacity_check = 1) + + if(!ticker || (opacity_check && !A.opacity)) + return + majorChunkChange(A, 2) + +/datum/cameranet/proc/updateChunk(x, y, z) + // 0xf = 15 + if(!chunkGenerated(x, y, z)) + return + var/datum/camerachunk/chunk = getCameraChunk(x, y, z) + chunk.hasChanged() + +// Removes a camera from a chunk. + +/datum/cameranet/proc/removeCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 0) + +// Add a camera to a chunk. + +/datum/cameranet/proc/addCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 1) + +// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. + +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 1) + //else + // majorChunkChange(c, 0) + +// Never access this proc directly!!!! +// This will update the chunk and all the surrounding chunks. +// It will also add the atom to the cameras list if you set the choice to 1. +// Setting the choice to 0 will remove the camera from the chunks. +// If you want to update the chunks around an object, without adding/removing a camera, use choice 2. + +/datum/cameranet/proc/majorChunkChange(atom/c, var/choice) + // 0xf = 15 + if(!c) + return + + var/turf/T = get_turf(c) + if(T) + var/x1 = max(0, T.x - 8) & ~0xf + var/y1 = max(0, T.y - 8) & ~0xf + var/x2 = min(world.maxx, T.x + 8) & ~0xf + var/y2 = min(world.maxy, T.y + 8) & ~0xf + + //world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]" + + for(var/x = x1; x <= x2; x += 16) + for(var/y = y1; y <= y2; y += 16) + if(chunkGenerated(x, y, T.z)) + var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z) + if(choice == 0) + // Remove the camera. + chunk.cameras -= c + else if(choice == 1) + // You can't have the same camera in the list twice. + chunk.cameras |= c + chunk.hasChanged() + +// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. + +/datum/cameranet/proc/checkCameraVis(mob/living/target as mob) + + // 0xf = 15 + var/turf/position = get_turf(target) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + if(chunk) + if(chunk.changed) + chunk.hasChanged(1) // Update now, no matter if it's visible or not. + if(chunk.visibleTurfs[position]) + return 1 + return 0 + + +// Debug verb for VVing the chunk that the turf is in. +/* +/turf/verb/view_chunk() + set src in world + + if(cameranet.chunkGenerated(x, y, z)) + var/datum/camerachunk/chunk = cameranet.getCameraChunk(x, y, z) + usr.client.debug_variables(chunk) +*/ \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 89c88c1aaf..33dbfd0966 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -1,23 +1,168 @@ -/datum/visibility_chunk/camera +#define UPDATE_BUFFER 25 // 2.5 seconds + +// CAMERA CHUNK +// +// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. +// Allows the AI Eye to stream these chunks and know what it can and cannot see. + +/datum/camerachunk + var/list/obscuredTurfs = list() + var/list/visibleTurfs = list() + var/list/obscured = list() + var/list/cameras = list() + var/list/turfs = list() + var/list/seenby = list() + var/visible = 0 + var/changed = 0 + var/updating = 0 + var/x = 0 + var/y = 0 + var/z = 0 + +// Add an AI eye to the chunk, then update if changed. + +/datum/camerachunk/proc/add(mob/aiEye/ai) + if(!ai.ai) + return + ai.visibleCameraChunks += src + if(ai.ai.client) + ai.ai.client.images += obscured + visible++ + seenby += ai + if(changed && !updating) + update() + +// Remove an AI eye from the chunk, then update if changed. + +/datum/camerachunk/proc/remove(mob/aiEye/ai) + if(!ai.ai) + return + ai.visibleCameraChunks -= src + if(ai.ai.client) + ai.ai.client.images -= obscured + seenby -= ai + if(visible > 0) + visible-- + +// Called when a chunk has changed. I.E: A wall was deleted. + +/datum/camerachunk/proc/visibilityChanged(turf/loc) + if(!visibleTurfs[loc]) + return + hasChanged() + +// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will +// instead be flagged to update the next time an AI Eye moves near it. + +/datum/camerachunk/proc/hasChanged(var/update_now = 0) + if(visible || update_now) + if(!updating) + updating = 1 + spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once + update() + updating = 0 + else + changed = 1 + +// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. + +/datum/camerachunk/proc/update() + + set background = 1 + + var/list/newVisibleTurfs = list() + + for(var/camera in cameras) + var/obj/machinery/camera/c = camera + + if(!c) + continue + + if(!c.can_use()) + continue + + var/turf/point = locate(src.x + 8, src.y + 8, src.z) + if(get_dist(point, c) > 24) + continue + + for(var/turf/t in c.can_see()) + newVisibleTurfs[t] = t + + // Removes turf that isn't in turfs. + newVisibleTurfs &= turfs + + var/list/visAdded = newVisibleTurfs - visibleTurfs + var/list/visRemoved = visibleTurfs - newVisibleTurfs + + visibleTurfs = newVisibleTurfs + obscuredTurfs = turfs - newVisibleTurfs + + for(var/turf in visAdded) + var/turf/t = turf + if(t.obscured) + obscured -= t.obscured + for(var/eye in seenby) + var/mob/aiEye/m = eye + if(!m || !m.ai) + continue + if(m.ai.client) + m.ai.client.images -= t.obscured + + for(var/turf in visRemoved) + var/turf/t = turf + if(obscuredTurfs[t]) + if(!t.obscured) + t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) + + obscured += t.obscured + for(var/eye in seenby) + var/mob/aiEye/m = eye + if(!m || !m.ai) + seenby -= m + continue + if(m.ai.client) + m.ai.client.images += t.obscured + +// Create a new camera chunk, since the chunks are made as they are needed. + +/datum/camerachunk/New(loc, x, y, z) + + // 0xf = 15 + x &= ~0xf + y &= ~0xf + + src.x = x + src.y = y + src.z = z -/datum/visibility_chunk/camera/validViewpoint(var/viewpoint) - var/obj/machinery/camera/c = viewpoint - if(!c) - return FALSE - if(!c.can_use()) - return FALSE - var/turf/point = locate(src.x + 8, src.y + 8, src.z) - if(get_dist(point, c) > 24) - return FALSE - return TRUE - - -/datum/visibility_chunk/camera/getVisibleTurfsForViewpoint(var/viewpoint) - var/obj/machinery/camera/c = viewpoint - return c.can_see() - - -/datum/visibility_chunk/camera/findNearbyViewpoints() for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z))) if(c.can_use()) - viewpoints += c \ No newline at end of file + 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] = t + + for(var/camera in cameras) + var/obj/machinery/camera/c = camera + if(!c) + continue + + if(!c.can_use()) + continue + + for(var/turf/t in c.can_see()) + visibleTurfs[t] = t + + // Removes turf that isn't in turfs. + visibleTurfs &= turfs + + obscuredTurfs = turfs - visibleTurfs + + for(var/turf in obscuredTurfs) + var/turf/t = turf + if(!t.obscured) + t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) + obscured += t.obscured + +#undef UPDATE_BUFFER \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 69af9a18aa..c82fbb7c76 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -6,16 +6,13 @@ /mob/aiEye name = "Inactive AI Eye" icon = 'icons/obj/status_display.dmi' // For AI friend secret shh :o + var/list/visibleCameraChunks = list() var/mob/living/silicon/ai/ai = null density = 0 status_flags = GODMODE // You can't damage it. mouse_opacity = 0 see_in_dark = 7 -/mob/aiEye/New() - ..() - visibility_interface = new /datum/visibility_interface/ai_eye(src) - // Movement code. Returns 0 to stop air movement from moving it. /mob/aiEye/Move() return 0 @@ -40,12 +37,13 @@ // It will also stream the chunk that the new loc is in. /mob/aiEye/proc/setLoc(var/T) + if(ai) if(!isturf(ai.loc)) return T = get_turf(T) loc = T - cameraNetwork.visibility(src) + cameranet.visibility(src) if(ai.client) ai.client.eye = src //Holopad @@ -138,8 +136,7 @@ if(client && client.eye) client.eye = src - - for(var/datum/visibility_chunk/camera/c in eyeobj.visibility_interface.visible_chunks) + for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks) c.remove(eyeobj) /mob/living/silicon/ai/verb/toggle_acceleration() diff --git a/code/modules/mob/living/silicon/ai/freelook/read_me.dm b/code/modules/mob/living/silicon/ai/freelook/read_me.dm index aa3d99bdba..53e68ff137 100644 --- a/code/modules/mob/living/silicon/ai/freelook/read_me.dm +++ b/code/modules/mob/living/silicon/ai/freelook/read_me.dm @@ -43,7 +43,7 @@ WHERE IS EVERYTHING? - cameraNetwork.dm = Everything about the cameraNetwork datum. + cameranet.dm = Everything about the cameranet datum. chunk.dm = Everything about the chunk datum. eye.dm = Everything about the AI and the AIEye. updating.dm = Everything about triggers that will update chunks. diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index e88d4c28eb..c1f6331372 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -1,5 +1,80 @@ #define BORG_CAMERA_BUFFER 30 +//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. + +// TURFS + +/turf + var/image/obscured + +/turf/proc/visibilityChanged() + if(ticker) + cameranet.updateVisibility(src) + +/turf/simulated/Del() + visibilityChanged() + ..() + +/turf/simulated/New() + ..() + visibilityChanged() + + + +// STRUCTURES + +/obj/structure/Del() + if(ticker) + cameranet.updateVisibility(src) + ..() + +/obj/structure/New() + ..() + if(ticker) + cameranet.updateVisibility(src) + +// EFFECTS + +/obj/effect/Del() + if(ticker) + cameranet.updateVisibility(src) + ..() + +/obj/effect/New() + ..() + if(ticker) + cameranet.updateVisibility(src) + + +// DOORS + +// Simply updates the visibility of the area when it opens/closes/destroyed. +/obj/machinery/door/update_nearby_tiles(need_rebuild) + . = ..(need_rebuild) + // Glass door glass = 1 + // don't check then? + if(!glass && cameranet) + cameranet.updateVisibility(src, 0) + + +// ROBOT MOVEMENT + +// Update the portable camera everytime the Robot moves. +// This might be laggy, comment it out if there are problems. +/mob/living/silicon/robot/var/updating = 0 + +/mob/living/silicon/robot/Move() + var/oldLoc = src.loc + . = ..() + if(.) + if(src.camera && src.camera.network.len) + if(!updating) + updating = 1 + spawn(BORG_CAMERA_BUFFER) + if(oldLoc != src.loc) + cameranet.updatePortableCamera(src.camera) + updating = 0 + // CAMERA // An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not. @@ -7,23 +82,23 @@ /obj/machinery/camera/deactivate(user as mob, var/choice = 1) ..(user, choice) if(src.can_use()) - cameraNetwork.addViewpoint(src) + cameranet.addCamera(src) else src.SetLuminosity(0) - cameraNetwork.removeViewpoint(src) + cameranet.removeCamera(src) /obj/machinery/camera/New() ..() - cameraNetwork.viewpoints += src //Camera must be added to global list of all cameras no matter what... + cameranet.cameras += src //Camera must be added to global list of all cameras no matter what... var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles. if(open_networks.len) //If there is at least one open network, chunk is available for AI usage. - cameraNetwork.addViewpoint(src) + cameranet.addCamera(src) /obj/machinery/camera/Del() - cameraNetwork.viewpoints -= src + cameranet.cameras -= src var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) if(open_networks.len) - cameraNetwork.removeViewpoint(src) + cameranet.removeCamera(src) ..() #undef BORG_CAMERA_BUFFER \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm b/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm deleted file mode 100644 index b55598c609..0000000000 --- a/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm +++ /dev/null @@ -1,10 +0,0 @@ -/datum/visibility_interface/ai_eye - chunk_type = /datum/visibility_chunk/camera - -/datum/visibility_interface/ai_eye/getClient() - var/mob/aiEye/eye = controller - if (!eye) - return FALSE - if (!eye.ai) - return FALSE - return eye.ai.client diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 030a3db08e..611243f654 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -106,9 +106,6 @@ camera.network = list("SS13","Robots") if(isWireCut(5)) // 5 = BORG CAMERA camera.status = 0 - - // hook the robot into the camera network - addToVisibilityNetwork(cameraNetwork) initialize_components() //if(!unfinished) @@ -146,8 +143,6 @@ if(T) mmi.loc = T if(mind) mind.transfer_to(mmi.brainmob) mmi = null - // remove blown up robots from the visibility network - removeFromVisibilityNetwork(cameraNetwork) ..() /mob/living/silicon/robot/proc/pick_module() @@ -1206,7 +1201,7 @@ //Disconnect it's camera so it's not so easily tracked. if(src.camera) src.camera.network = list() - cameraNetwork.removeViewpoint(src.camera) + cameranet.removeCamera(src.camera) /mob/living/silicon/robot/proc/ResetSecurityCodes() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 66f7d58bbc..c82489cf35 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -333,9 +333,6 @@ var/list/slot_equipment_priority = list( \ return */ -/mob - var/newPlayerType = /mob/new_player - /mob/verb/abandon_mob() set name = "Respawn" set category = "OOC" @@ -384,12 +381,14 @@ var/list/slot_equipment_priority = list( \ log_game("[usr.key] AM failed due to disconnect.") return - var/mob/newPlayer = new newPlayerType() + var/mob/new_player/M = new /mob/new_player() if(!client) log_game("[usr.key] AM failed due to disconnect.") - del(newPlayer) + del(M) return - newPlayer.key = key + + M.key = key +// M.Login() //wat return /client/verb/changes() diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index f8d8228718..dc984663dd 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -203,7 +203,6 @@ var/obj/control_object //Used by admins to possess objects. All mobs should have this var - var/datum/visibility_interface/visibility_interface = null // used by the visibility system to provide an interface for the visibility networks //Whether or not mobs can understand other mobtypes. These stay in /mob so that ghosts can hear everything. var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 66c665644f..314a4026ab 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -114,11 +114,6 @@ proc/isobserver(A) if(istype(A, /mob/dead/observer)) return 1 return 0 - -/proc/isSpirit(A) - if(istype(A, /mob/spirit)) - return 1 - return 0 proc/isorgan(A) if(istype(A, /datum/organ/external)) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 2fda2c141d..1ea768d005 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -176,15 +176,8 @@ return if(mob.stat==2) return - - // handle possible spirit movement - var/mob/spirit/currentSpirit = mob - if(currentSpirit) - return currentSpirit.Spirit_Move(direct) - - // handle possible AI movement - if(isAI(mob)) - return AIMove(n,direct,mob) + + if(isAI(mob)) return AIMove(n,direct,mob) if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 380a6dfe9a..6237803638 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -303,9 +303,9 @@ data_core.manifest_inject(character) ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn AnnounceArrival(character, rank) - return character + else - return character.Robotize() + character.Robotize() del(src) proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) diff --git a/code/modules/mob/spirit/cultnet.dm b/code/modules/mob/spirit/cultnet.dm deleted file mode 100644 index df0cd57ff5..0000000000 --- a/code/modules/mob/spirit/cultnet.dm +++ /dev/null @@ -1,80 +0,0 @@ -/* - -This file contains the code necessary to do the display code for cult spirits. - -It reuses a lot of code from the AIEye cameraNetwork. In order to work properly, some of those files needed to be modified as well. - -*/ - - -/proc/isCultRune(var/viewpoint) - var/obj/effect/rune/test_rune = viewpoint - if (test_rune) - return TRUE - return FALSE - - -/proc/isCultViewpoint(var/viewpoint) - var/obj/cult_viewpoint/vp = viewpoint - if (vp) - return TRUE - return FALSE - - -/datum/visibility_chunk/cult/validViewpoint(var/atom/viewpoint) - var/turf/point = locate(src.x + 8, src.y + 8, src.z) - if(get_dist(point, viewpoint) > 24) - return FALSE - - if (isCultRune(viewpoint) || isCultViewpoint(viewpoint)) - return viewpoint:can_use() - return FALSE - - -/datum/visibility_chunk/cult/getVisibleTurfsForViewpoint(var/viewpoint) - var/obj/effect/rune/rune = viewpoint - if (rune) - return rune.can_see() - var/obj/cult_viewpoint/cvp = viewpoint - if (cvp) - return cvp.can_see() - return null - - -/datum/visibility_chunk/cult/findNearbyViewpoints() - for(var/obj/cult_viewpoint/vp in range(16, locate(x + 8, y + 8, z))) - if(vp.can_use()) - viewpoints += vp - for(var/obj/effect/rune/rune in range(16, locate(x + 8, y + 8, z))) - viewpoints += rune - - -/datum/visibility_network/cult - ChunkType = /datum/visibility_chunk/cult - - -/datum/visibility_network/cult/validViewpoint(var/viewpoint) - if (isCultRune(viewpoint) || isCultViewpoint(viewpoint)) - return viewpoint:can_use() - return FALSE - -/datum/visibility_network/cult/getViewpointFromMob(var/mob/currentMob) - for(var/obj/cult_viewpoint/currentView in currentMob) - return currentView - return FALSE - - -/datum/visibility_interface/cult - chunk_type = /datum/visibility_chunk/cult - - -/* -RUNE JUNK -*/ - -/obj/effect/rune/proc/can_use() - return TRUE - -/obj/effect/rune/proc/can_see() - return hear(view_range, get_turf(src)) - diff --git a/code/modules/mob/spirit/mask/mask.dm b/code/modules/mob/spirit/mask/mask.dm deleted file mode 100644 index 6b58f201cf..0000000000 --- a/code/modules/mob/spirit/mask/mask.dm +++ /dev/null @@ -1,227 +0,0 @@ -/mob/spirit/mask - icon = 'icons/mob/spirits/mask.dmi' - icon_state = "depressurized" - -/mob/spirit/mask/New() - ..() - spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman(src) - spell_list += new /obj/effect/proc_holder/spell/aoe_turf/blood_speech(src) - spell_list += new /obj/effect/proc_holder/spell/aoe_turf/shatter_lights(src) - - -/mob/spirit/mask/verb/go_to_follower() - set category = "Mask" - set name = "Go to follower" - set desc = "Select who you would like to go too." - - var/obj/cult_viewpoint/cultist = pick_cultist() - if (cultist) - follow_cultist(cultist.owner) - cult_log("[key_name_admin(src)] started following [key_name_admin(cultist)].") - src << "You start following [cultist.get_display_name()]." - - -/mob/spirit/mask/verb/urge_cultist() - set category = "Mask" - set name = "Urge cultist" - set desc = "Push your cultists to do something." - - var/obj/cult_viewpoint/cultist = pick_cultist() - if (cultist) - if (cultist.owner) - var/newUrge = stripped_input(usr, "", "Set Urge", "") - cultist.set_urge(newUrge) - src << "You urge [cultist.owner.name] to [newUrge]." - cult_log("controlled by [key_name_admin(src)] has urged [key_name_admin(cultist.owner)] to [newUrge].") - -/mob/spirit/mask/verb/set_cult_name() - set category = "Mask" - set name = "Set Cult Name" - set desc = "Grant a cultist a name." - - var/obj/cult_viewpoint/cultist = pick_cultist() - if (cultist) - var/newName = stripped_input(usr, "", "Set Cult Name", "") - if (!newName) - return - cultist.set_cult_name(newName) - src << "You grant [cultist.owner.name] the secret name of [newName]." - if (cultist.owner) - cult_log("[key_name_admin(src)] has set [key_name_admin(cultist.owner)] to \'[newName]\'") - - -/mob/spirit/mask/verb/urge_cult() - set category = "Mask" - set name = "Urge Cult" - set desc = "Set urge on the entire cult." - - var/newUrge = stripped_input(usr, "Please choose an urge.", "Set Urge", "") - for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) - viewpoint.set_urge(newUrge) - src << "You urge the entire cult to [newUrge]." - cult_log("[key_name_admin(src)] has urged the entire cult to [newUrge]") - - -/mob/spirit/mask/verb/set_favor_for_cultist() - set category = "Mask" - set name = "Show your favor" - set desc = "Set the favor for a cultist" - - var/obj/cult_viewpoint/cultist = pick_cultist() - if (cultist) - if (cultist.owner) - var/list/favor = list("Pleased", "Displeased", "Indifference") - var/emotion = input("Pick your emotion", "Mask", null, null) in favor - switch(emotion) - if("Pleased") - cultist.set_favor(1) - cult_log("[key_name_admin(src)] is pleased with [key_name_admin(cultist.owner)]") - if("Displeased") - cultist.set_favor(-1) - cult_log("[key_name_admin(src)] is displeased with [key_name_admin(cultist.owner)]") - if("Indifference") - cultist.set_favor(0) - cult_log("[key_name_admin(src)] is indifferent too [key_name_admin(cultist.owner)]") - - -/mob/spirit/mask/proc/set_name() - spawn(0) - var/newName = stripped_input(src, "Please pick a name.", "Pick Name for Mask", "") - name = newName ? newName : "Mask of Nar'sie" - src << "You have set your name to [name]." - - -/mob/spirit/mask/proc/pick_cultist() - var/list/cultists = list() - for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) - cultists[viewpoint.get_display_name()]=viewpoint - var/input = input("Please, select a cultist!", "Cult", null, null) as null|anything in cultists - var/obj/cult_viewpoint/result = cultists[input] - return result - - -// this proc makes the mask visible very briefly -/mob/spirit/mask/proc/flicker() - spawn(0) - alpha = 127 - invisibility=0 - sleep(5) - invisibility=initial(invisibility) - alpha = 255 - -/proc/flicker_mask(mob/spirit/mask/target) - if(istype(target)) - target.flicker() - -// SPELLS -/obj/effect/proc_holder/spell/aoe_turf/blood_speech - name = "Speak to your Acolytes" - desc = "This spell allows you to speak to your flock." - school = "unknown evil" - charge_type = "recharge" - charge_max = 2000 - clothes_req = 0 - invocation = "none" - invocation_type = "none" - range = 0 - -/obj/effect/proc_holder/spell/aoe_turf/blood_speech/cast(list/targets) - var/input = stripped_input(usr, "Please choose a message to tell your acolytes.", "Voice of Blood", "") - if(!input) - revert_cast(usr) - cult_log("[key_name_admin(usr)]says : [input]") - flicker_mask(usr) - for(var/datum/mind/H in ticker.mode.cult) - if (H.current) - H.current << "[usr.name]: [input]" - for(var/mob/spirit/spirit in spirits) - spirit << "[usr.name]: [input]" - - -/obj/effect/proc_holder/spell/aoe_turf/shatter_lights - name = "Spread Shadows" - desc = "This spell breaks lights near the mask." - school = "unknown evil" - charge_type = "recharge" - charge_max = 1000 - clothes_req = 0 - invocation = "none" - invocation_type = "none" - range = 0 - -/obj/effect/proc_holder/spell/aoe_turf/shatter_lights/cast(list/targets) - cult_log("[key_name_admin(usr)] used Spread Shadows.") - flicker_mask(usr) - spawn(0) - for(var/area/A in range(3,get_turf(usr))) - for(var/obj/machinery/light/L in A) - L.on = 1 - L.broken() - sleep(1) - for(var/obj/item/device/flashlight/F in A) - F.on = 0 - - -/obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman - name = "Create Talisman" - desc = "This spell conjures a talisman" - - school = "conjuration" - charge_type = "recharge" - charge_max = 3000 - clothes_req = 0 - invocation = "none" - invocation_type = "none" - range = 0 - summon_type = list(/obj/item/weapon/paper/talisman) - - var/list/talismans = list( "Armor"="armor", - "Blind"="blind", - "Conceal"="conceal", - "Communicate"="communicate", - "Deafen"="deafen", - "EMP"="emp", - "Teleport"="teleport", - "Tome"="newtome", - "Reveal Runes", - "Stun"="runestun", - "Soul Stone"="soulstone", - "Construct"="construct") - - -/obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman/cast(list/targets) - - var/talisman = input("Pick a talisman type", "Talisman", null, null) as null|anything in talismans - var/imbue_value = talismans[talisman] - if (!talisman) - usr << "You choose not to create a talisman." - revert_cast(usr) - return - - cult_log("[key_name_admin(usr,0)] created a talisman of type [talisman].") - flicker_mask(usr) - - switch(talisman) - - if ("Teleport") - var/target_rune = input("Pick a teleport target", "Teleport Rune", null, null) as null|anything in engwords - if (!target_rune) - usr << "You choose not to create a talisman." - revert_cast(usr) - return - summon_type = list(/obj/item/weapon/paper/talisman) - newVars = list("imbue" = "[target_rune]", "info" = "[target_rune]") - - if ("Soul Stone") - summon_type = list(/obj/item/device/soulstone) - newVars = list() - - if ("Construct") - summon_type = list(/obj/structure/constructshell) - newVars = list() - - else - summon_type = list(/obj/item/weapon/paper/talisman) - newVars = list("imbue" = "[imbue_value]") - - ..() \ No newline at end of file diff --git a/code/modules/mob/spirit/mask/respawn.dm b/code/modules/mob/spirit/mask/respawn.dm deleted file mode 100644 index acfb69073c..0000000000 --- a/code/modules/mob/spirit/mask/respawn.dm +++ /dev/null @@ -1,20 +0,0 @@ -/proc/there_can_be_only_one_mask(var/mob/spirit/mask/target) - if(!istype(target)) - return - for(var/mob/spirit/mask/currentSpirit in spirits) - if(currentSpirit) - if(currentSpirit!=target) - // create the ghost - var/mob/dead/observer/ghost = currentSpirit.ghostize(TRUE) - // let the deposed mask respawn immediately, the poor dear - ghost.timeofdeath = world.time - 20000 - ghost.newPlayerType = /mob/new_player/cultist - // remove old mask body - del(currentSpirit) - - -/mob/new_player/cultist/AttemptLateSpawn(rank) - var/mob/newCharacter = ..(rank) - if(ticker.mode) - if(is_convertable_to_cult(newCharacter.mind)) - ticker.mode.add_cultist(newCharacter.mind) \ No newline at end of file diff --git a/code/modules/mob/spirit/movement.dm b/code/modules/mob/spirit/movement.dm deleted file mode 100644 index d8847cb480..0000000000 --- a/code/modules/mob/spirit/movement.dm +++ /dev/null @@ -1,62 +0,0 @@ -// spirits are not moved by airflow -mob/spirit/Move() - return 0 - -// this is the main move proc for spirits, it uses their 'setLoc' function to handle all the visibility shenanigans -// this, like most movement code for these guys, is cribbed from the AIEye movement code -mob/spirit/proc/Spirit_Move(direct) - - var/initial = initial(sprint) - var/max_sprint = 50 - - // if we haven't moved in a while, we stop sprinting - if(cooldown && cooldown < world.timeofday) // 3 seconds - sprint = initial - - for(var/i = 0; i < max(sprint, initial); i += 20) - var/turf/step = get_turf(get_step(src, direct)) - if(step) - setLoc(step) - - dir = direct // update our sprite - - cooldown = world.timeofday + 5 - if(acceleration) - sprint = min(sprint + 0.5, max_sprint) - else - sprint = initial - - // if we're trying to move, we want to stop following our target - follow_target = null - - -/mob/spirit/proc/follow_cultist(mob/living/target as mob) - if(!istype(target)) return - var/obj/cult_viewpoint/currentView = getCultViewpoint(target) - var/mob/spirit/U = usr - - if (!currentView) - U << "As a spirit, you may only track cultists." - - U.follow_target = target - U << "Now following [currentView.get_cult_name()]." - - spawn (0) - while (U.follow_target == target) - if (U.follow_target == null) - return - U.setLoc(get_turf(target)) - sleep(10) - - -mob/spirit/proc/setLoc(var/T) - T = get_turf(T) - loc = T - cultNetwork.visibility(src) - -mob/spirit/verb/toggle_acceleration() - set category = "Spirit" - set name = "Toggle Acceleration" - - acceleration = !acceleration - usr << "Acceleration has been toggled [acceleration ? "on" : "off"]." \ No newline at end of file diff --git a/code/modules/mob/spirit/spirit.dm b/code/modules/mob/spirit/spirit.dm deleted file mode 100644 index ce85f4175f..0000000000 --- a/code/modules/mob/spirit/spirit.dm +++ /dev/null @@ -1,76 +0,0 @@ -/* -This mob type is used for entities that exist within the Cult's spirit world. They share the same visibility network and are intangible. -*/ - -mob/spirit - name = "spirit" - desc = "A spirit" - icon = 'icons/mob/mob.dmi' - icon_state = "ghost" - layer = 4 - stat = CONSCIOUS - status_flags = GODMODE // spirits cannot be killed - density = 0 - canmove = 0 - blinded = 0 - anchored = 1 - mouse_opacity = 0 - invisibility = INVISIBILITY_SPIRIT - universal_speak = 1 - - // pseudo-movement values - var/sprint = 10 - var/cooldown = 0 - var/acceleration = 1 - var/follow_target = null - - -mob/spirit/is_active() - if (client && client.inactivity <= 10 * 60 * 10) - return TRUE - return FALSE - - -mob/spirit/New() - sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF - see_invisible = SEE_SPIRITS - see_in_dark = 100 - - loc = pick(latejoin) - - // hook them to the cult visibility network - visibility_interface = new /datum/visibility_interface/cult(src) - - // no nameless spirits - if (!name) - name = "Boogyman" - - spirits+=src - - ..() - -mob/spirit/Del() - spirits-=src - ..() - - -mob/spirit/Topic(href, href_list) - world << "Spirit Topic!" - usr << "Topic: usr [usr], src [src]" - src << "Topic: usr [usr], src [src]" - - if(usr != src) - return - ..() - - usr << "Spirit Href = [href]" - for (var/tempref in href_list) - usr << "Spirit href list [tempref] = [href_list[tempref]]" - - if (href_list["track"]) - usr << "Got to tracking." - var/mob/target = locate(href_list["track"]) in mob_list - var/mob/spirit/A = locate(href_list["track2"]) in spirits - if(A && target) - A.follow_cultist(target) - return \ No newline at end of file diff --git a/code/modules/mob/spirit/viewpoint.dm b/code/modules/mob/spirit/viewpoint.dm deleted file mode 100644 index 5e06356129..0000000000 --- a/code/modules/mob/spirit/viewpoint.dm +++ /dev/null @@ -1,202 +0,0 @@ -#define FAVOR_PLEASED 1 -#define FAVOR_INDIFFERENT 0 -#define FAVOR_DISPLEASED -1 - - -var/obj/cult_viewpoint/list/cult_viewpoints = list() - - -/obj/cult_viewpoint - var/view_range = 7 - var/updating = 0 - var/mob/owner = null - var/urge = "" - var/favor = FAVOR_INDIFFERENT - var/cult_name = null - - -/obj/cult_viewpoint/New(var/mob/target) - owner = target - //src.loc = owner - owner.addToVisibilityNetwork(cultNetwork) - cultNetwork.viewpoints+=src - cultNetwork.addViewpoint(src) - cult_viewpoints+=src - //handle_missing_mask() - ..() - - -/obj/cult_viewpoint/Del() - processing_objects.Remove(src) - cultNetwork.viewpoints-=src - cultNetwork.removeViewpoint(src) - cult_viewpoints-=src - owner.removeFromVisibilityNetwork(cultNetwork) - ..() - return - - -// VERBS -/obj/cult_viewpoint/verb/check_urge() - set category = "Cult" - set desc = "Discover what your god commands of you." - set name = "Check Urge" - set src in usr - if (src.urge) - owner << "\red \b You feel the urge to [src.urge]" - else - owner << "\b You feel no supernatural compulsions." - - -/obj/cult_viewpoint/verb/reach_out() - set category = "Cult" - set desc = "Reach out for your gods presence." - set name = "Reach Out" - set src in usr - - for(var/mob/spirit/mask/currentMask in spirits) - if (currentMask.is_active()) - owner << "\red \b You feel the reassuring presence of your god." - currentMask << "[get_display_name()] has reached out to you." - return - owner << "\b You feel a chilling absence." - handle_missing_mask() - - -/obj/cult_viewpoint/verb/check_favor() - set category = "Cult" - set desc = "Check your favor with your god." - set name = "Check Favor" - set src in usr - switch(favor) - if(FAVOR_PLEASED) - owner << "\red \b You bask in your gods favor." - if(FAVOR_INDIFFERENT) - owner << "\red \b You feel nothing." - if(FAVOR_DISPLEASED) - owner << "\red \b You cringe at your gods displeasure." - - -/obj/cult_viewpoint/verb/pray_to_mask() - set category = "Cult" - set desc = "Pray to your god" - set name = "Pray to Nar'Sie" - set src in usr - - var/input = stripped_input(usr, "Please choose a message to say to your god.", "Pray to Nar'Sie", "") - if(!input) - return - - cult_log("[key_name(usr,0)](Pray):[input]") - owner << "You pray to Nar'Sie: [input]" - - for(var/mob/spirit/spirit in spirits) - spirit << "[get_display_name()] prays : [input]" - -// PROCS -/obj/cult_viewpoint/proc/set_favor(var/newFavor) - favor = newFavor - check_favor() - - -/obj/cult_viewpoint/proc/set_urge(var/newUrge) - if (!newUrge) - src.urge = null - src.urge = copytext(newUrge, 1, MAX_MESSAGE_LEN) - check_urge() - - -/obj/cult_viewpoint/proc/can_use() - if (owner.stat != DEAD) - return TRUE - return FALSE - - -/obj/cult_viewpoint/proc/can_see() - return hear(view_range, get_turf(owner)) - - -/obj/cult_viewpoint/proc/get_cult_name() - if (cult_name) - return cult_name - return "An Unknown Servent" - - -/obj/cult_viewpoint/proc/set_cult_name(var/newName) - if (!owner) - return FALSE - if (newName) - cult_name = newName - owner << "\red \b You have been blessed with the secret name of '[newName]'." - else - cult_name = null - owner << "\red \b Your god has taken your secret name." - - -/obj/cult_viewpoint/proc/get_display_name() - if (!owner) - return - if (cult_name) - return cult_name - return owner.name - - -/obj/cult_viewpoint/proc/become_mask() - set category = "Cult" - set name = "Become Mask" - set desc = "Sacrifice your life and become a Mask of Nar'sie." - set src in usr - - cult_log("[key_name(usr,0)] has tried to become a Mask of Nar'sie.") - - if (!active_mask()) - var/transformation_type = alert(owner.client, "You are about to become a Mask. Do you want it to be subtle or violent?", "Mask", "Subtle", "Violent") - if(!active_mask()) - cult_log("[key_name(usr,0)] has become a Mask of Nar'sie.") - if (transformation_type=="Subtle") - log_admin("[key_name_admin(owner)] has subtly become a Mask of Nar'sie") - owner.make_into_mask(0,0) - else - log_admin("[key_name_admin(owner)] has violently become a Mask of Nar'sie") - owner.make_into_mask(1,1) - else - owner << "\b You cannot become a mask of Nar'Sie because a Mask already exists." - mask_has_been_found() - return - - -/obj/cult_viewpoint/proc/active_mask() - for(var/mob/spirit/mask/currentMask in spirits) - if (currentMask.is_active()) - return TRUE - return FALSE - - -/obj/cult_viewpoint/proc/handle_missing_mask() - if (active_mask()) - mask_has_been_found() - else - mask_is_missing() - - -/obj/cult_viewpoint/proc/mask_has_been_found() - for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) - if (viewpoint.verbs.Find(/obj/cult_viewpoint/proc/become_mask)) - viewpoint.verbs-=/obj/cult_viewpoint/proc/become_mask - - -/obj/cult_viewpoint/proc/mask_is_missing() - for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints) - if (!viewpoint.verbs.Find(/obj/cult_viewpoint/proc/become_mask)) - viewpoint.verbs+=/obj/cult_viewpoint/proc/become_mask - - -/proc/getCultViewpoint(var/mob/currentMob) - for(var/obj/cult_viewpoint/currentView in currentMob) - return currentView - return FALSE - - -#undef FAVOR_PLEASED -#undef FAVOR_INDIFFERENT -#undef FAVOR_DISPLEASED \ No newline at end of file diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index ea45eca49e..0015620cc5 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -133,59 +133,7 @@ . = O del(src) - -/mob/living/carbon/human/make_into_mask(var/should_gib = 0) - for(var/t in organs) - del(t) - return ..(should_gib) - -/mob/proc/make_into_mask(var/should_gib = 0, var/should_remove_items = 0) - - if(!should_gib) - icon = null - invisibility = 101 - - if(!should_remove_items) - for(var/obj/item/W in src) - drop_from_inventory(W) - - var/mob/spirit/mask/new_spirit = new() - - if(mind) - new_spirit.mind = mind - new_spirit.mind.assigned_role = "Mask" - new_spirit.mind.original = new_spirit - - new_spirit.key = key - new_spirit.loc=loc - - if (should_gib) - spawn(0) - src.gib() // gib the body - else - spawn(0)//To prevent the proc from returning null. - src.visible_message( \ - "[src] disappears into the shadows, never to be seen again.", \ - "You disappear into the shadows, never to be seen again.", \ - "You hear strange noise, you can't quite place it.") - del(src) - - new_spirit << "You are a Mask of Nar'sie now. You are a tiny fragment of the unknowable entity that is the god." - new_spirit << "Your job is to help your acolytes complete their goals. Be spooky. Do evil." - - new_spirit.set_name() - - // let spirits identify cultists - if(ticker.mode) - ticker.mode.reset_cult_icons_for_spirit(new_spirit) - - // highlander test - there_can_be_only_one_mask(new_spirit) - - return new_spirit - - //human -> robot /mob/living/carbon/human/proc/Robotize() if (monkeyizing) diff --git a/code/setup.dm b/code/setup.dm index 46800d409f..68b7552b40 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -529,9 +529,6 @@ var/list/liftable_structures = list(\ #define SEE_INVISIBLE_LEVEL_TWO 45 //Used by some other stuff in code. It's really poorly organized. #define INVISIBILITY_LEVEL_TWO 45 //Used by some other stuff in code. It's really poorly organized. -#define INVISIBILITY_SPIRIT 50 -#define SEE_SPIRITS 50 - #define INVISIBILITY_OBSERVER 60 #define SEE_INVISIBLE_OBSERVER 60 diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 9a0b8f14cf..fda3fb64e2 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -63,7 +63,6 @@ h1.alert, h2.alert {color: #000000;} .skrell {color: #00CED1;} .soghun {color: #228B22;} .vox {color: #AA00AA;} -.cultspeech {color: #B20000;} .say_quote {font-family: Georgia, Verdana, sans-serif;} .interface {color: #330033;} diff --git a/code/unused/AI_Visibility.dm b/code/unused/AI_Visibility.dm index 0769f8ca87..d218f4409b 100644 --- a/code/unused/AI_Visibility.dm +++ b/code/unused/AI_Visibility.dm @@ -5,7 +5,7 @@ var/image/dim /turf/proc/visibilityChanged() - cameraNetwork.updateVisibility(src) + cameranet.updateVisibility(src) /datum/camerachunk var/list/obscuredTurfs = list() @@ -180,22 +180,22 @@ dim += t.dim -var/datum/cameraNetwork/cameraNetwork = new() +var/datum/cameranet/cameranet = new() -/datum/cameraNetwork +/datum/cameranet var/list/cameras = list() var/list/chunks = list() var/network = "net1" var/ready = 0 -/datum/cameraNetwork/New() +/datum/cameranet/New() ..() -/datum/cameraNetwork/proc/chunkGenerated(x, y, z) +/datum/cameranet/proc/chunkGenerated(x, y, z) var/key = "[x],[y],[z]" return key in chunks -/datum/cameraNetwork/proc/getCameraChunk(x, y, z) +/datum/cameranet/proc/getCameraChunk(x, y, z) var/key = "[x],[y],[z]" if(!(key in chunks)) @@ -203,7 +203,7 @@ var/datum/cameraNetwork/cameraNetwork = new() return chunks[key] -/datum/cameraNetwork/proc/visibility(mob/aiEye/ai) +/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 @@ -224,14 +224,14 @@ var/datum/cameraNetwork/cameraNetwork = new() for(var/datum/camerachunk/c in add) c.add(ai) -/datum/cameraNetwork/proc/updateVisibility(turf/loc) +/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/cameraNetwork/proc/addCamera(obj/machinery/camera/c) +/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 @@ -265,17 +265,17 @@ var/datum/cameraNetwork/cameraNetwork = new() else client.eye = eyeobj eyeobj.loc = loc - cameraNetwork.visibility(eyeobj) + cameranet.visibility(eyeobj) cameraFollow = null /mob/aiEye/Move() . = ..() if(.) - cameraNetwork.visibility(src) + 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) - cameraNetwork.visibility(user.eyeobj) + cameranet.visibility(user.eyeobj) else return ..() @@ -289,7 +289,7 @@ var/datum/cameraNetwork/cameraNetwork = new() else if(direct == DOWN && user.eyeobj.z < 4) dif = 1 user.eyeobj.loc = locate(user.eyeobj.x, user.eyeobj.y, user.eyeobj.z + dif) - cameraNetwork.visibility(user.eyeobj) + cameranet.visibility(user.eyeobj) else return ..() */ @@ -303,8 +303,8 @@ var/datum/cameraNetwork/cameraNetwork = new() /obj/machinery/door/update_nearby_tiles(need_rebuild) . = ..(need_rebuild) - cameraNetwork.updateVisibility(loc) + cameranet.updateVisibility(loc) /obj/machinery/camera/New() ..() - cameraNetwork.addViewpoint(src) \ No newline at end of file + cameranet.addCamera(src) \ No newline at end of file diff --git a/icons/mob/spirits/mask.dmi b/icons/mob/spirits/mask.dmi deleted file mode 100644 index 20fe26c4bced41886718c66c2569db7bd9b7fbd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 972 zcmV;-12g=IP){f|1VR6J#Mc^K`AXmVMIPFJvJXTFe5%V zBsVf292pHHAs8-Ws%~RG_TXpZ00001bW%=J06^y0W&i*Ha(Yx)bVOxyV{&P5bZKvH z004NLQ&wT#GdI(F^OKlJp@5n z3+G-O)8xJHrvs6nx=Jo`A42HJ5lVMOTR3O5vEub0sZCjjSC?tfNQ;& zK6vu6ItKLD>y-nO$OcF?z(PxiVV|95=x+*0iLqo6UOE8LE>r;TS@i(;Ad*O!m#Pir z2=ZM4`!;4D*!0L{JfY_fApF3h`WmvPI3ky^yAdh?ive_(N)G~b5^;o#+Y+Ls0l*3r ziavGTw1mni7{Ijv=r48&goSN_0ulh}Cjg-V2#Glb?|5y#XYT;vyCZ$n0DbfUs87%7 zlAwartl$8!05iVJ%<490{9$YgLDCW3NTEc0DL<2AMkPjjQ|G(DltqR z7xDE_cduOM@4PNZsrJqHG*O`Th;e1lmco(_K`aU1nK3Kum%us!Fue{St#864FeEs$ zpD&LG?`D+Cm49sj=tb%;rrM1VoC|=*uIy zkP((@e#pAJ&L21{Sovcz>+MAEvlXEFs)QWi%{rZAi(NKG6p%bXv=vZ!gU%I{b$~I0 z+($$JkbKfz7Ut?A^mqe+#s+YhrQp&Pz>_2exFY~XFRlSVcQL0dBS2OFjJFNIY-XK+ zwKhNM3Wx^aZ4TH0vi?j9plK^MKnyByq5vKO)-fQT0hAM9L}<*BEAa;C^gw5zRLqfE z28TDP0PgoTplE2dA);Y^yl#M@c`^WibOGzp7t{7`TRe8R|8bBWq;2s Date: Mon, 25 Nov 2013 21:16:09 +0000 Subject: [PATCH 15/18] Implements hooks, an easier way to write code to be called at startup/roundstart/roundend. Current hooks are "startup", "roundstart", and "roundend". Most stuff in world/New() has been moved over to the startup hook. Roundstart and roundend have no hooks yet. Removed the unused "newbanjob.dm" file and associated verbs/topics. Bumped RECOMMENDED_VERSION up to 501. Signed-off-by: Mloc-Argent --- baystation12.dme | 2 +- code/ZAS/FEA_gas_mixture.dm | 14 ++++ code/__HELPERS/global_lists.dm | 4 +- code/datums/datacore.dm | 3 + code/datums/sun.dm | 4 + code/game/area/Space Station 13 areas.dm | 29 ++----- code/game/communications.dm | 4 + .../gamemodes/events/holidays/Holidays.dm | 4 + code/game/gamemodes/gameticker.dm | 3 + code/game/jobs/whitelist.dm | 14 +++- code/modules/admin/NewBan.dm | 3 + code/modules/admin/admin.dm | 8 -- code/modules/admin/admin_investigate.dm | 4 + code/modules/admin/admin_ranks.dm | 4 + code/modules/admin/admin_verbs.dm | 4 +- code/modules/admin/banjob.dm | 13 +-- code/modules/admin/topic.dm | 13 --- code/modules/ext_scripts/irc.dm | 13 ++- .../modules/mob/living/silicon/pai/recruit.dm | 4 + code/modules/power/power.dm | 5 ++ code/world.dm | 84 +++++++------------ 21 files changed, 119 insertions(+), 117 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index 35a7237aa1..2f11011c1f 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -77,6 +77,7 @@ #include "code\controllers\_DynamicAreaLighting_TG.dm" #include "code\controllers\configuration.dm" #include "code\controllers\failsafe.dm" +#include "code\controllers\hooks.dm" #include "code\controllers\lighting_controller.dm" #include "code\controllers\master_controller.dm" #include "code\controllers\shuttle_controller.dm" @@ -650,7 +651,6 @@ #include "code\modules\admin\holder2.dm" #include "code\modules\admin\IsBanned.dm" #include "code\modules\admin\NewBan.dm" -#include "code\modules\admin\newbanjob.dm" #include "code\modules\admin\player_notes.dm" #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\topic.dm" diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm index 3eccad7e91..9a829633e2 100644 --- a/code/ZAS/FEA_gas_mixture.dm +++ b/code/ZAS/FEA_gas_mixture.dm @@ -14,6 +14,20 @@ What are the archived variables for? #define QUANTIZE(variable) (round(variable,0.0001)) #define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer +/hook/startup/proc/createGasOverlays() + plmaster = new /obj/effect/overlay() + plmaster.icon = 'icons/effects/tile_effects.dmi' + plmaster.icon_state = "plasma" + plmaster.layer = FLY_LAYER + plmaster.mouse_opacity = 0 + + slmaster = new /obj/effect/overlay() + slmaster.icon = 'icons/effects/tile_effects.dmi' + slmaster.icon_state = "sleeping_agent" + slmaster.layer = FLY_LAYER + slmaster.mouse_opacity = 0 + return 1 + /datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy. /datum/gas/oxygen_agent_b/specific_heat = 300 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index ce8d788f25..07a22f5693 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -42,7 +42,7 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al /////Initial Building///// ////////////////////////// -/proc/make_datum_references_lists() +/hook/startup/proc/makeDatumRefLists() var/list/paths //Hair - Initialise all /datum/sprite_accessory/hair into an list indexed by hair-style name @@ -97,6 +97,8 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al if(S.flags & WHITELISTED) whitelisted_species += S.name + return 1 + /* // Uncomment to debug chemical reaction list. /client/verb/debug_chemical_list() diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 1a7d97e99c..2be4c6e82a 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -1,3 +1,6 @@ +/hook/startup/proc/createDatacore() + data_core = new /obj/effect/datacore() + return 1 /obj/effect/datacore/proc/manifest(var/nosleep = 0) spawn() diff --git a/code/datums/sun.dm b/code/datums/sun.dm index 9ce8a73cb7..82acfa0cff 100644 --- a/code/datums/sun.dm +++ b/code/datums/sun.dm @@ -14,6 +14,10 @@ if(prob(50)) rate = -rate +/hook/startup/proc/createSun() + sun = new /datum/sun() + return 1 + // calculate the sun's position given the time of day /datum/sun/proc/calc_position() diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 9ba221c64d..9ff5a6e0cd 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -56,7 +56,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ var/list/teleportlocs = list() -proc/process_teleport_locs() +/hook/startup/proc/setupTeleportLocs() for(var/area/AR in world) if(istype(AR, /area/shuttle) || istype(AR, /area/syndicate_station) || istype(AR, /area/wizard_station)) continue if(teleportlocs.Find(AR.name)) continue @@ -65,20 +65,13 @@ proc/process_teleport_locs() teleportlocs += AR.name teleportlocs[AR.name] = AR - var/not_in_order = 0 - do - not_in_order = 0 - if(teleportlocs.len <= 1) - break - for(var/i = 1, i <= (teleportlocs.len - 1), i++) - if(sorttext(teleportlocs[i], teleportlocs[i+1]) == -1) - teleportlocs.Swap(i, i+1) - not_in_order = 1 - while(not_in_order) + teleportlocs = sortAssoc(teleportlocs) + + return 1 var/list/ghostteleportlocs = list() -proc/process_ghost_teleport_locs() +/hook/startup/proc/setupGhostTeleportLocs() for(var/area/AR in world) if(ghostteleportlocs.Find(AR.name)) continue if(istype(AR, /area/turret_protected/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome)) @@ -89,17 +82,9 @@ proc/process_ghost_teleport_locs() ghostteleportlocs += AR.name ghostteleportlocs[AR.name] = AR - var/not_in_order = 0 - do - not_in_order = 0 - if(ghostteleportlocs.len <= 1) - break - for(var/i = 1, i <= (ghostteleportlocs.len - 1), i++) - if(sorttext(ghostteleportlocs[i], ghostteleportlocs[i+1]) == -1) - ghostteleportlocs.Swap(i, i+1) - not_in_order = 1 - while(not_in_order) + ghostteleportlocs = sortAssoc(ghostteleportlocs) + return 1 /*-----------------------------------------------------------------------------*/ diff --git a/code/game/communications.dm b/code/game/communications.dm index 32d8ca6934..3bc3ee7009 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -140,6 +140,10 @@ var/const/RADIO_MAGNETS = "9" var/global/datum/controller/radio/radio_controller +/hook/startup/proc/createRadioController() + radio_controller = new /datum/controller/radio() + return 1 + datum/controller/radio var/list/datum/radio_frequency/frequencies = list() diff --git a/code/game/gamemodes/events/holidays/Holidays.dm b/code/game/gamemodes/events/holidays/Holidays.dm index d2481eae44..2cd06199bd 100644 --- a/code/game/gamemodes/events/holidays/Holidays.dm +++ b/code/game/gamemodes/events/holidays/Holidays.dm @@ -12,6 +12,10 @@ var/global/Holiday = null ////////////////////////////////////////////////////////////////////////////////////////////////////////// // ~Carn +/hook/startup/proc/updateHoliday() + Get_Holiday() + return 1 + //sets up the Holiday global variable. Shouldbe called on game configuration or something. /proc/Get_Holiday() if(!Holiday) return // Holiday stuff was not enabled in the config! diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index a03068371f..73d61637f8 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -131,6 +131,7 @@ var/global/datum/controller/gameticker/ticker data_core.manifest() current_state = GAME_STATE_PLAYING + callHook("roundstart") //here to initialize the random events nicely at round start setup_economy() @@ -323,6 +324,8 @@ var/global/datum/controller/gameticker/ticker declare_completion() spawn(50) + callHook("roundend") + if (mode.station_was_nuked) feedback_set_details("end_proper","nuke") if(!delay_end) diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm index f28de56dc4..98efaf9273 100644 --- a/code/game/jobs/whitelist.dm +++ b/code/game/jobs/whitelist.dm @@ -2,6 +2,11 @@ var/list/whitelist = list() +/hook/startup/proc/loadWhitelist() + if(config.usewhitelist) + load_whitelist() + return 1 + /proc/load_whitelist() whitelist = file2list(WHITELISTFILE) if(!whitelist.len) whitelist = null @@ -11,9 +16,14 @@ var/list/whitelist = list() return 0 return ("[M.ckey]" in whitelist) -var/list/alien_whitelist = list() +/var/list/alien_whitelist = list() -proc/load_alienwhitelist() +/hook/startup/proc/loadAlienWhitelist() + if(config.usealienwhitelist) + load_alienwhitelist() + return 1 + +/proc/load_alienwhitelist() var/text = file2text("config/alienwhitelist.txt") if (!text) diary << "Failed to load config/alienwhitelist.txt\n" diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm index 83447d1a23..035b2d2309 100644 --- a/code/modules/admin/NewBan.dm +++ b/code/modules/admin/NewBan.dm @@ -58,6 +58,9 @@ var/savefile/Banlist CMinutes = (world.realtime / 10) / 60 return 1 +/hook/startup/proc/loadBans() + return LoadBans() + /proc/LoadBans() Banlist = new("data/banlist.bdb") diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index e2bf6f7be2..c6dcc662a6 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1014,14 +1014,6 @@ var/global/floorIsLava = 0 message_admins("\blue [key_name_admin(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.", 1) feedback_add_details("admin_verb","TGU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/unjobban_panel() - set name = "Unjobban Panel" - set category = "Admin" - if (src.holder) - src.holder.unjobbanpanel() - feedback_add_details("admin_verb","UJBP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - /datum/admins/proc/output_ai_laws() var/ai_number = 0 for(var/mob/living/silicon/S in mob_list) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index e601f069c6..a062788438 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -11,6 +11,10 @@ /proc/investigate_subject2file(var/subject) return file("[INVESTIGATE_DIR][subject].html") +/hook/startup/proc/resetInvestigate() + investigate_reset() + return 1 + /proc/investigate_reset() if(fdel(INVESTIGATE_DIR)) return 1 return 0 diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 115fafba82..86624e0bd2 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -53,6 +53,10 @@ var/list/admin_ranks = list() //list of all ranks with associated rights #endif +/hook/startup/proc/loadAdmins() + load_admins() + return 1 + /proc/load_admins() //clear the datums references admin_datums.Cut() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 606a6e82ff..8a74a48317 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -74,9 +74,7 @@ var/list/admin_verbs_admin = list( ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, - /client/proc/jobbans, - /client/proc/unjobban_panel, - // /client/proc/DB_ban_panel + /client/proc/jobbans ) var/list/admin_verbs_sounds = list( /client/proc/play_local_sound, diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm index b6d1ea53b6..42326711d3 100644 --- a/code/modules/admin/banjob.dm +++ b/code/modules/admin/banjob.dm @@ -50,6 +50,10 @@ DEBUG jobban_loadbanfile() */ +/hook/startup/proc/loadJobBans() + jobban_loadbanfile() + return 1 + /proc/jobban_loadbanfile() if(config.ban_legacy_system) var/savefile/S=new("data/job_full.ban") @@ -101,15 +105,6 @@ DEBUG text2file(formatted_log,"data/ban_unban_log.txt") -/proc/jobban_updatelegacybans() - if(!jobban_runonce) - log_admin("Updating jobbanfile!") - // Updates bans.. Or fixes them. Either way. - for(var/T in jobban_keylist) - if(!T) continue - jobban_runonce++ //don't run this update again - - /proc/jobban_remove(X) for (var/i = 1; i <= length(jobban_keylist); i++) if( findtext(jobban_keylist[i], "[X]") ) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index f1c911488a..671908259c 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -874,19 +874,6 @@ if("Cancel") return - else if(href_list["unjobbanf"]) - if(!check_rights(R_BAN)) return - - var/banfolder = href_list["unjobbanf"] - Banlist.cd = "/base/[banfolder]" - var/key = Banlist["key"] - if(alert(usr, "Are you sure you want to unban [key]?", "Confirmation", "Yes", "No") == "Yes") - if (RemoveBanjob(banfolder)) - unjobbanpanel() - else - alert(usr,"This ban has already been lifted / does not exist.","Error","Ok") - unjobbanpanel() - else if(href_list["mute"]) if(!check_rights(R_MOD,0) && !check_rights(R_ADMIN)) return diff --git a/code/modules/ext_scripts/irc.dm b/code/modules/ext_scripts/irc.dm index f4e94f3ffc..3976904efb 100644 --- a/code/modules/ext_scripts/irc.dm +++ b/code/modules/ext_scripts/irc.dm @@ -4,11 +4,16 @@ return /proc/send2mainirc(var/msg) - if(config.use_irc_bot && config.main_irc && config.irc_bot_host) - ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [config.main_irc] [msg]") + if(config.main_irc) + send2irc(config.main_irc, msg) return /proc/send2adminirc(var/msg) - if(config.use_irc_bot && config.admin_irc && config.irc_bot_host) - ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [config.admin_irc] [msg]") + if(config.admin_irc) + send2irc(config.admin_irc, msg) return + + +/hook/startup/proc/ircNotify() + send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]") + return 1 diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index 93271aadaf..87d6a169b6 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -13,6 +13,10 @@ var/datum/paiController/paiController // Global handler for pAI candidates var/ready = 0 +/hook/startup/proc/paiControllerSetup() + paiController = new /datum/paiController() + return 1 + /datum/paiController var/list/pai_candidates = list() diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index b94901a637..986f81d6c8 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -79,6 +79,9 @@ // rebuild all power networks from scratch +/hook/startup/proc/buildPowernets() + return makepowernets() + /proc/makepowernets() for(var/datum/powernet/PN in powernets) del(PN) @@ -101,6 +104,8 @@ if(!M.powernet) continue // APCs have powernet=0 so they don't count as network nodes directly M.powernet.nodes[M] = M + return 1 + // returns a list of all power-related objects (nodes, cable, junctions) in turf, // excluding source, that match the direction d diff --git a/code/world.dm b/code/world.dm index abc4997699..9545324343 100644 --- a/code/world.dm +++ b/code/world.dm @@ -7,7 +7,7 @@ -#define RECOMMENDED_VERSION 495 +#define RECOMMENDED_VERSION 501 /world/New() //logs var/date_string = time2text(world.realtime, "YYYY/MM-Month/DD-Day") @@ -22,59 +22,13 @@ if(byond_version < RECOMMENDED_VERSION) world.log << "Your server's byond version does not meet the recommended requirements for this server. Please update BYOND" - make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) - load_configuration() - load_mode() - load_motd() - load_admins() - load_mods() - LoadBansjob() - if(config.usewhitelist) - load_whitelist() - if(config.usealienwhitelist) - load_alienwhitelist() - jobban_loadbanfile() - jobban_updatelegacybans() - LoadBans() if(config && config.server_name != null && config.server_suffix && world.port > 0) // dumb and hardcoded but I don't care~ config.server_name += " #[(world.port % 1000) / 100]" - investigate_reset() - Get_Holiday() //~Carn, needs to be here when the station is named so :P - - src.update_status() - - makepowernets() - - sun = new /datum/sun() - radio_controller = new /datum/controller/radio() - data_core = new /obj/effect/datacore() - paiController = new /datum/paiController() - - if(!setup_database_connection()) - world.log << "Your server failed to establish a connection with the feedback database." - else - world.log << "Feedback database connection established." - - if(!setup_old_database_connection()) - world.log << "Your server failed to establish a connection with the SQL database." - else - world.log << "SQL database connection established." - - plmaster = new /obj/effect/overlay() - plmaster.icon = 'icons/effects/tile_effects.dmi' - plmaster.icon_state = "plasma" - plmaster.layer = FLY_LAYER - plmaster.mouse_opacity = 0 - - slmaster = new /obj/effect/overlay() - slmaster.icon = 'icons/effects/tile_effects.dmi' - slmaster.icon_state = "sleeping_agent" - slmaster.layer = FLY_LAYER - slmaster.mouse_opacity = 0 + callHook("startup") src.update_status() @@ -82,15 +36,10 @@ sleep_offline = 1 - send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]") - master_controller = new /datum/controller/game_controller() spawn(1) master_controller.setup() - process_teleport_locs() //Sets up the wizard teleport locations - process_ghost_teleport_locs() //Sets up ghost teleport locations. - spawn(3000) //so we aren't adding to the round-start lag if(config.ToRban) ToRban_autoupdate() @@ -184,6 +133,10 @@ #undef INACTIVITY_KICK +/hook/startup/proc/loadMode() + world.load_mode() + return 1 + /world/proc/load_mode() var/list/Lines = file2list("data/mode.txt") if(Lines.len) @@ -196,9 +149,15 @@ fdel(F) F << the_mode + +/hook/startup/proc/loadMOTD() + world.load_motd() + return 1 + /world/proc/load_motd() join_motd = file2text("config/motd.txt") + /world/proc/load_configuration() config = new /datum/configuration() config.load("config/config.txt") @@ -208,6 +167,11 @@ // apply some settings from config.. abandon_allowed = config.respawn + +/hook/startup/proc/loadMods() + world.load_mods() + return 1 + /world/proc/load_mods() if(config.admin_legacy_system) var/text = file2text("config/moderators.txt") @@ -290,6 +254,13 @@ var/failed_db_connections = 0 var/failed_old_db_connections = 0 +/hook/startup/proc/connectDB() + if(!setup_database_connection()) + world.log << "Your server failed to establish a connection with the feedback database." + else + world.log << "Feedback database connection established." + return 1 + proc/setup_database_connection() if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore. @@ -325,7 +296,12 @@ proc/establish_db_connection() return 1 - +/hook/startup/proc/connectOldDB() + if(!setup_old_database_connection()) + world.log << "Your server failed to establish a connection with the SQL database." + else + world.log << "SQL database connection established." + return 1 //These two procs are for the old database, while it's being phased out. See the tgstation.sql file in the SQL folder for more information. proc/setup_old_database_connection() From 5e34c0e0564129865a196faf64701483959931ae Mon Sep 17 00:00:00 2001 From: Mloc-Argent Date: Mon, 25 Nov 2013 21:19:58 +0000 Subject: [PATCH 16/18] Hmm hmm, it could help to actually commit the hooks.dm file, couldn't it? Signed-off-by: Mloc-Argent --- code/controllers/hooks.dm | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 code/controllers/hooks.dm diff --git a/code/controllers/hooks.dm b/code/controllers/hooks.dm new file mode 100644 index 0000000000..5045da7592 --- /dev/null +++ b/code/controllers/hooks.dm @@ -0,0 +1,39 @@ +/** + * @file hooks.dm + * Implements hooks, a simple way to run code on pre-defined events. + */ + +/** @page hooks Code hooks + * @section hooks Hooks + * A hook is defined under /hook in the type tree. + * + * To add some code to be called by the hook, define a proc under the type, as so: + * @code + /hook/foo/proc/bar() + if(1) + return 1 //Sucessful + else + return 0 //Error, or runtime. + * @endcode + * All hooks must return nonzero on success, as runtimes will force return null. + */ + +/** + * Calls a hook, executing every piece of code that's attached to it. + * @param hook Identifier of the hook to call. + * @returns 1 if all hooked code runs successfully, 0 otherwise. + */ +/proc/callHook(hook) + var/hook_path = text2path("/hook/[hook]") + if(!hook_path) + error("Invalid hook '/hook/[hook]' called.") + return 0 + + var/caller = new hook_path + var/status = 1 + for(var/P in typesof("[hook_path]/proc")) + if(!call(caller, P)()) + error("Hook '[P]' failed or runtimed.") + status = 0 + + return status From 83d1924b83d07bf75b9674d13856d2249cae6c94 Mon Sep 17 00:00:00 2001 From: Chinsky Date: Wed, 27 Nov 2013 04:10:06 +0400 Subject: [PATCH 17/18] Commiting SueTheCake's detective things. -New set of clothes spawning in the closet. -Replacement of revolver by semiauto gun, with update to autolathe recipies. --- code/game/machinery/autolathe.dm | 3 ++- .../crates_lockers/closets/secure/security.dm | 10 ++++++--- code/modules/clothing/suits/jobs.dm | 3 +++ code/modules/clothing/under/jobs/security.dm | 20 ++++++++++++++++++ code/modules/projectiles/ammunition/boxes.dm | 19 +++++++++++++++++ .../modules/projectiles/ammunition/bullets.dm | 4 ++++ .../projectiles/guns/projectile/revolver.dm | 20 ++++++++++++++++++ icons/mob/head.dmi | Bin 120155 -> 120273 bytes icons/mob/suit.dmi | Bin 236516 -> 237218 bytes icons/mob/uniform.dmi | Bin 193728 -> 194814 bytes icons/obj/ammo.dmi | Bin 4377 -> 4190 bytes icons/obj/clothing/hats.dmi | Bin 58103 -> 58223 bytes icons/obj/clothing/suits.dmi | Bin 79516 -> 79767 bytes icons/obj/clothing/uniforms.dmi | Bin 51072 -> 51308 bytes icons/obj/gun.dmi | Bin 38954 -> 39786 bytes 15 files changed, 75 insertions(+), 4 deletions(-) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 477fd67cab..9826505fd0 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -35,7 +35,7 @@ var/global/list/autolathe_recipes = list( \ new /obj/item/weapon/reagent_containers/syringe(), \ new /obj/item/ammo_casing/shotgun/blank(), \ new /obj/item/ammo_casing/shotgun/beanbag(), \ - new /obj/item/ammo_magazine/c38(), \ + new /obj/item/ammo_magazine/c45r(), \ new /obj/item/device/taperecorder(), \ new /obj/item/device/assembly/igniter(), \ new /obj/item/device/assembly/signaler(), \ @@ -57,6 +57,7 @@ var/global/list/autolathe_recipes_hidden = list( \ new /obj/item/weapon/weldingtool/largetank(), \ new /obj/item/weapon/handcuffs(), \ new /obj/item/ammo_magazine/a357(), \ + new /obj/item/ammo_magazine/c45(), \ new /obj/item/ammo_casing/shotgun(), \ new /obj/item/ammo_casing/shotgun/dart(), \ /* new /obj/item/weapon/shield/riot(), */ \ diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 011f19f198..e44847f137 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -247,20 +247,24 @@ ..() sleep(2) new /obj/item/clothing/under/det(src) + new /obj/item/clothing/under/det/black(src) + new /obj/item/clothing/under/det/slob(src) new /obj/item/clothing/suit/storage/det_suit(src) + new /obj/item/clothing/suit/storage/det_suit/black(src) new /obj/item/clothing/suit/storage/forensics/blue(src) new /obj/item/clothing/suit/storage/forensics/red(src) new /obj/item/clothing/gloves/black(src) new /obj/item/clothing/head/det_hat(src) + new /obj/item/clothing/head/det_hat/black(src) new /obj/item/clothing/shoes/brown(src) new /obj/item/weapon/storage/box/evidence(src) new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/device/detective_scanner(src) new /obj/item/clothing/suit/armor/det_suit(src) - new /obj/item/ammo_magazine/c38(src) - new /obj/item/ammo_magazine/c38(src) + new /obj/item/ammo_magazine/c45r(src) + new /obj/item/ammo_magazine/c45r(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/gun/projectile/detective(src) + new /obj/item/weapon/gun/projectile/detective/semiauto(src) new /obj/item/clothing/tie/holster/armpit(src) return diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index fd525eacdb..f3c960cc3d 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -77,6 +77,9 @@ allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) armor = list(melee = 50, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) +/obj/item/clothing/suit/storage/det_suit/black + icon_state = "detective2" + //Forensics /obj/item/clothing/suit/storage/forensics name = "jacket" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index b279a2fd35..c35910d060 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -71,6 +71,22 @@ flags = FPRINT | TABLEPASS siemens_coefficient = 0.9 +/obj/item/clothing/under/det/black + icon_state = "detective2" + item_color = "detective2" + +/obj/item/clothing/under/det/slob + icon_state = "polsuit" + item_color = "polsuit" + +/obj/item/clothing/under/det/slob/verb/rollup() + set name = "Roll suit sleevels" + set category = "Object" + set src in usr + item_color = item_color == "polsuit" ? "polsuit_rolled" : "polsuit" + if (ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_w_uniform(1) /obj/item/clothing/head/det_hat name = "hat" @@ -80,6 +96,10 @@ armor = list(melee = 50, bullet = 5, laser = 25,energy = 10, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0.9 +/obj/item/clothing/head/det_hat/black + icon_state = "detective2" + + /* * Head of Security */ diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index fa7567bcb2..87fa97ef69 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -14,6 +14,25 @@ multiple_sprites = 1 +/obj/item/ammo_magazine/c45 + name = "magazine (.45)" + icon_state = "45" + ammo_type = "/obj/item/ammo_casing/c45" + max_ammo = 7 + multiple_sprites = 1 + +/obj/item/ammo_magazine/c45/empty + max_ammo = 0 + +/obj/item/ammo_magazine/c45r + name = "magazine (.45 rubber)" + icon_state = "45" + ammo_type = "/obj/item/ammo_casing/c45r" + max_ammo = 7 + multiple_sprites = 1 + +/obj/item/ammo_magazine/c45r/empty + max_ammo = 0 /obj/item/ammo_magazine/a418 name = "ammo box (.418)" diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm index 41443469d3..a2b11b7ffc 100644 --- a/code/modules/projectiles/ammunition/bullets.dm +++ b/code/modules/projectiles/ammunition/bullets.dm @@ -43,6 +43,10 @@ caliber = ".45" projectile_type = "/obj/item/projectile/bullet/midbullet" +/obj/item/ammo_casing/c45r + desc = "A .45 rubber bullet casing." + caliber = ".45" + projectile_type = "/obj/item/projectile/bullet/weakbullet" /obj/item/ammo_casing/a12mm desc = "A 12mm bullet casing." diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 0f6fca68b2..b6a305cbf7 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -70,6 +70,26 @@ user << "You remove the modifications on [src]! Now it will fire .38 rounds." +/obj/item/weapon/gun/projectile/detective/semiauto + desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds." + name = "\improper Colt M1911" + icon_state = "colt" + max_shells = 7 + caliber = ".45" + ammo_type = "/obj/item/ammo_casing/c45r" + load_method = 2 + +/obj/item/weapon/gun/projectile/detective/semiauto/New() + ..() + empty_mag = new /obj/item/ammo_magazine/c45r/empty(src) + return + +/obj/item/weapon/gun/projectile/detective/semiauto/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) + ..() + if(!loaded.len && empty_mag) + empty_mag.loc = get_turf(src.loc) + empty_mag = null + return /obj/item/weapon/gun/projectile/mateba diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 0396dd6ce08438191b0f096532f70825604407f2..97794bab71848d6bca2132b8c47c53dbbf4c3f41 100644 GIT binary patch delta 4412 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 diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index cafdb88f336331aaaaa772f3fc9094ab0da0f099..52ee7b48a62e0620d61b5714ab0987c35c04f190 100644 GIT binary patch delta 22378 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

gS_BQoVm~-}%M$|E+g9 zqUEz)3im_7`2+m%)cFpBqsja0*Qd(n*}ZojM>L^<<-lOOZh9|r}=uN7?TrE^IL+-zqY1U-yP1r*_wy6?6!8D_KqJA0N{r0sf~f1 zNs)g8;6K@rlc0sDR1Qg5%$?>*N2R4i2vYHZfUjS^3^` z@rNOPlVoDs%ve;;#D(hT0}^t!#(^*|b=haHJZX!zi}{I*ana5~?CRe~sg%WkvTLt2 zR}PVd!jOIeR4ngocdJ@87S@RF1Yd8MfefrQRn#@_T|m{{R&NTw(XZeup>HCbjGSH#)j#cVZWCz;@j6W$%@~ zWq$d98r0_X(dcq-kjfQj>!AS$luVH7b$|IBB4xb{xzH3&(Kb+}5nA-mYTY8RBcY7~zuPUs?GUn#ACZ?v0rpt7jBH>_8|K_C5$SJCT z1xA7)%1Xn%Gf6d<{gR2|4sWNBEAwrdqAif^kte>(5F4ov*ZUefC2LLU%9%wOESkBt#wBv2|Ket(xbu$P55B6@@~Hg_qWWrID}-yz`Z>i zz;}r=$NvGEj>qpIEsYFFUW)x;1}HZ-7hp32_8XWB3kxHQi&y|oUvOUbguwz0T}s5! zHA}L&!_QjJJuenfz##``=Z?WaEc2l>A6fdGantntY+-m12P6nHWb0ynF?Y~)Xac>= zq7qT%7q6APo@U9!6^l{Rl%z$>gAJUVpWC#Ngt~#wTX-<>r3S<5YDk+?Xd)v11OXs$ zJ%A4aP=U0Z=uTVv5xSR`uC#=Co_-dkg z?fPN7rAqYcXsIp+4i1iDDj$~ERiDb?ta+v(n62pO=u}%zu&4GdHvT5!!19{Xhi=QK zcIvxe_xwyKV)L~TwZWGk)Sv#IO5ae*R3~8Q=`B-3*Tm>JbiJJ(tEQqNsu+9?4B(N3 z$rOS<#yRNL+qE+~(%Hqd%?QZY? zC>B6hRA*q*(jV$~_dX?}e=Ej-ho&Uf*C-b73NECaqx9>}o*?x&c51C2Va&HQlRFBZ zg+%#$fqT1*;5%~j>VIb)`WbSC&fVSJV=aD=$xHI*gdO=Uxs^|H-)U*d$903*8$h~W z%C;>qlarGjnlnc&s!4F#{(TnHXbAySQM>-9euBlbK2OC*-1*x#RaI5-xJ#)pLK=2< z?8(W=%Ud5P)XV-8!rJPpPhG5@vm3e1T|5ev35bX*fS>`Bi^u7xjLYR}P)sxw?cLrk zvE?8{-ssFxcx^Kk|Iwt=h|6ps$p;ia>hIqh+1Wj*G8_DL;B_HVr|mAQ)8(&ZhL-BO8$FgRtlrIV8V2yAPz67obr+fq|-*K#6u(<<-(#5JR+ z&ItfA;3l!D3FVPAiUUOu3S|>jCggVh|-otmN6xF5oP{tyJc%_N|-f0&>EvBk;*n7CJ z1mOPWH~XxNrTRgGlvA_M_8h%|Nn4oq2JBk9G~5?Db#mUE5q^^zFkd>Ph8X~406<=a zN;qWa5UIQxYF7&fmEiLFXLzE`jIBf&X+sGc5w`kQ1Ij?HfLBTC+TnNlIrg_;Nvo(# z*ON6FOhREaR$u^D(3&9ZG=UlhuhFLn>LA7PBpoY>dnykW{7^-{u50dNlS_XRIhxN)s` z2M96BCZ==u#$K<6ef?0GL`i|AAA%SmM4{JuSDqH-Qwjm4R*HnKF&(c6Fv_%T{54R} z8?oJTf4b-HPHhnu!U4hnAkzt)-c|V)gEzBD2@4GkEkdJb6NY^nu=Cjeh{+`)4dvp3 zqM%xZYF7H2-Lypf)y#r zVvy*gOs$V8bEN}EtP==ZLQyDPU>`qzyu98mKbpO}ahX(6sVlgvsi^_x7zC0db@iuz z*4B>dTJNxA-czldk&3vlNq-b#gY<##}*ZMbh_o4sAFc%;=d9cVyD(@>V zPER{C;~sjqiSPB-2pNTF$(?b;*yY{mQetjGxJ08 zJ_PqKi)+>9qbtnc!oNQ$j8yHIF#I#&oiT^o@jB=^?zusB@S;YP;u+l}KUz3Hs>EjE{S*9Z`+ZYAa}WqGF}dLKm<(pRzF76v-;an9 zbYcQ(KLDcP3aJgCrn+z7@jiDuXB=6&J^IW()169Q*o+JRT{@|WBV7=s)8QNMXH7b) zY{s~1Zv&z^nu@xEX>AuS@4e~PIpSVTIc|Wa<#H|By?6bxDAYuGCY(y-=DE?IlQ`wd z>D+X89?`OZHHu_if`IXzG5Wi6MFpiZgGpCBqBper9`@l)yJOGYVas1kE)5`HT73EP zF=@xsM`Ja^NKct98mD8|iNXjU`^&X8Tk*_wAIp`d_KppqFWL*@At2v1}{Sp(9G zl?^9J7W7Z@nTmo=0BMCFF?t9OO-M)xOyMiBULKJ0eXd2<{euA^tEM-YeqG$$aw4v$Cy} z)!j9TI)t{xj;OG^#P*yYo%uw%F&s+?YTJt-1QP8;zx6Y?%!-894Ifew=I`zeldt131KrH4I+Rg5Opc%!c zCE8FCs%>th&(&7%$i?~O`escO@E(!1jY zN`5=idV7pCW#!MIKrhyGxX;WxWf%i=vQrxZm_?SXnV{ix6|qSe(6Wc?6-%FV$@31%pM zEb}+k=IgziGH;7Ycl<`ROrTj+h+vZQ*FhUKiSn}r^AdGpKR`~s6A}o?Z)VMNz#7Q= z#n}^$4Gh{Cu0eXt#>RGex_l9=rKR;a_UY5kpQ7y`7K5~WYip|w2x6nZu6uOsk}*7g zj+V%-`$|Rz<*^vu--m{NZW#AZB;g9CE}3T@ki=9S&2ZnN8#cL$#?h2>oc~a64jX?> z%S`)q39?B}8UL0Usfsvr9}yOzyk2v4qYh{*YCfS+v(&qpdNZKoR>OQb;UB|z2;k{F zVmE>9pU%8L=8%EZ+p1~`1Gbnj$=6#V%K7HfUr`JTNQQWzk#`lmvu_Qqo{7Gi8Q=E7 zt4twmfnyxtl)DEZQg5mimrc!~*Nc?V6|*8GHutls!>h)i{uPLh^YcD>p6oHk+tsQY zLZ_?ow0#r;N#>yNLH&9?f4XZdO~g{`{WXuYOiwfbrw1wJ5c@<;gs0>A#endjdVfYT zyw4;@NJy7%Vh5G@RH>pu{vMx>IQzZvcrsJ+ZZdY`_CTB>PDupH{ORmlP<*d{{VF%F z^mcEUcjL$liZmcoZ?l5$`<%p9EB!fc`+5kA462J5JCnJaF(L}DiIxZXUu}a+((oTfW&-dXx^+IxJwJEeTTddff@;I zHz+)weJ7VzfBo!HwW_sc4isrZ1aUZznG-%GWh4;5^3>J->R7~jL2KSIcl=9y8le&1 zdbyP}uc#SrKw7t>&OzP^q@#}~besvj=Dz!^QiuX(j1m6o?7HP^nis6xsGO$;5gv&1 z&gNV?DiVmA<4+Wnb0I)&$Wf0!eA{vu!8+l2Y*M(qe6nwG&6Mocr@yGtEe*G}yVpxhX-Ofa=I2ONHvDj+LWN&By{44+@m&#>3dO9Y zL36vy+fDBzMwWNfA4qRp{)2^`Ggc1y++EAGP)o;^c2Po6cbcUSDFTGh- zSY*VDG8oy?iLiLepQ_zhW9l=?);Y0-uUWH$ZUSU6F|j6gaAdPITTw*?CmmaUO0qum zcd53e=_~ddY~`*;wD_YIMt4sS3b49h=*m>j;ZgK1r!40alu8D&Dq{zSaOE)iXkJ%; z2y`aMG5WL2jB~?Tj{^4zOd@Z11(!TPMOZ}=A0Hna71dg{T{La&FWV@irt0*EB>R2t zn;wV*sQmm*ds^wQr^#Px zL=D{8@0$oPVbyhY_GVrhEzZKZ?`1}wM@ModD;~zn>LhpwLSwDM?nt^sN&m$^^Ytxm z^`e@1d8L)gJxUC5xqR0BGW$$?fzZP&%rus34Z)~!5*JrJ?2hK^?&&0@3>A;AWfOSb zoQ6VubHZ&}NnMjt2C#W}0gpeR`~x}%OdOoGKV4zfuu#wr12n6Cot>{iVlnp5V~dD@ z0Fq!O%q=SFm0lioYB5Y*s;uO?1zi&1EMaYr3P3;@*K`~mwl8bkzdbdJada~U@G@>U zCJ>Q_bDEWG`=N;wNheuqK-sD5b@u4RUbze~Ab1$D_#Ofq<*(J*$bW)ixeKIDk&s(YJkppw% z03YP|0siv+*ltc5w0swdhKcD9AUkX-(eQ{?&7h7T97*s{K)1oafB(|z^r&r8&q6K6 zd$dUa6$^?UxoeQsbo5X`1MXzV@bjneb~CB59KnS1(Ldo!M&YH2UjR8CKoMWt_8G6P z-lwHTnX4>{-PbX}VBcSg4mMwIq}o1tN@|!p{O-CJ+W%XKs%ntcnpu03j7uOD<^J%T zPFlK0^;oC0UzF&phz5(iyF!Oc{ZAThBT{hTkCYcjxEy3kDpK8g_}8_fxuTy}AgbN^d1CS# zdGA3Ni$IxA^L%r8vtcb}M_wrMvEd6Ks<$s^C>qR5*_h>p(#5)qE0hr^B-j~MuoytD zP~_1v!Kqpa&j+hF>1jHGSVuH#_z9`Vxxh?FQBnAlMnHkMQ!t5CN{NRX) z8WM!%+dmWK$qNfQteO=tP$k!IX1K#(7Yp_{j~{Q)4!;g{I>83 z1;t>A*%;ZVVs1-dN^8r#D1bzOY>7rhgq$v%AHINTd?tcOn z-#T|GvatAs_z9|%H$3B86c3N@fd?ZhVNxGI{v+NxD3mg+uc!PVOvFv$TrkS>tXM)J z0>$#x(r0s0(D+x3w*E(R8W2-JMF$C;+21B4iAmWTamEOI7%&A9{g!$iKYG3NzSWXpmJ<$bGI3w6kMlW1PsP4TZ$oP%!uFoDN1RTR6JvV1e<6_h0`cYv29~|fsA%RU> zdb;gI0z6kt%QFK`;*p67MBQBMATKS}FtN!gJe~b8~asf=rC6(?xzzmyv{{ zW6j%XI?&`MO+bPOdxmk+0c37KZ*4u?+DX4Rt*uIE#)e%KiunqFXXYU@kssY~lQ()= zcJ&bx%GUKT9!oFdrp* zW^%|YD3mv-czNBkjc>knXAYOn?VqN^E8BFl3jti5*8_C3jF4pEr97t!;`DfrEIQx2 z{H=qMmX~0TmjwD1pf^x}P5H8V)U_F|t*!Zixn%CTeSCbp;3Ym)(v9pdLEoVap~l5I zoM`14Z<_~>$P>!_(uag;3tNiposj+Qa=dZ=JqJvYN} zSJP7dRzY&VqiAbHX07L5!M9AUiKUmz==~}K zT2R5XY|Y)LB|-t)YDgw@Ejjy_{JrNJ<+sh&C()kQa-k~=dpzoIF0k(*AB@MIXpf8N zQk>>V$^UMgw&Maf?NJ`|xIp0bfA>{Cxs3V$b#?#04mgE-dbxB|?`M{JU_Wso{Xc!y zD?tMnW3V!316aM4$8%^U>5=w!8#+4Mcdio2$Thlu%OC-|FVB$anmt8ix=)Z|5@5hUW5N#puDjIh;FI?TM4Tu97ixU^m>G6#P!h@ z3m0wLqc5I;S{z_@a4>-L{p}35Sx)Z)H0KkFg4f{MUuC3efUbECN-$#$j*$86$k3cQ zk=6BI?VmtsBgpTwXAh@290Xc}K+giuv#rg%DAX|$dhA68j1di+AQo_y414dNC(6`4 zw_~$f{%rk$l_mJVsa^;8zuM-=bXY!=66Lkj(S6`O#syuamk+0ew}tY)cWxLHDFWcT zfF5K>5;R1E9&t|*A;l2D3N?A4iGzmyU5vogE`l|;KkHh^F!-lmnz(M>eXBZ}e=rhK zOow@2?7IXxdvYVgk8Wr`1O?l8Zk1B{{`cJpYxo97zdgnr|Nqr+9Z*dzUH1~22uKrY zA{{9zMYnNWEMGc;K{dqm_Qya9whD!MpWX_l zAf7ikU@j@#)0jNHQo7bm2EiXI@xy`l2+#F(uHvF$1+}Ll}X{TP2rnP}Vbo^*?^R#u+D-!{cpB*@R2qJDF z9SlvVA-An0jOK%Yi|tDHzz*x6seQEP1p^wG=sJHs4YbY7G?CH_Jv)1KY6^lf+ZN?H z41+gf9_ro9uQYC#BSz#jiYBK#b^Ee-e_$MboG zP6(CH?uj-36M75OFLdp%gQ{q^-1;H3m*_a_*7*Hel`wU@Jw0H46gZbF!ySPz>z4a! zWjO13$x`4uj81c#`YRIW$u5}!ja05cgl>g}y$h5JV*TFC@FU1OjiI(T$xPkipz6IAGh5Eg$1Ik*i=1^I9&?;OswLNpTdr;rI%XrQ>Ya7O*!6l%kxx__09hWPGXZyZr-hKO>%niVVwtgfwL6~@|=xA8_I6mKR zu#8rO-1y+|62yHI+6979C4qA{A^iS0-%CteRQueL2%PNw88F?b(o~YlYppnxS0a7A zPj(#FEv>mRA~VE0WgnCfA+MO~z#4Ncm(z-9FuID7{nKWXOIw+v_U(pnkCHrdy|U=( z+fXl6cJ1?gLWjb-W*?pn>_NjmYj?I?b+gbKyaIVprO^=Nmc3O8PU$VgotTpKNz#-y zQW&;~=AJxAwXzRmC3JQA)J~*mHM6VApUG@Hfl3*1J6S3%INs4U$%j*{5&T);=g{iv z{2z?}eH1W2Qx3v603HBfQ~(G92URLI7WClE?COh}vPV~JEFu9PZ*^&#l8Jy)EcWHB zD3!}fa@3e5D<6wP0HPiS3fc8`+|_hYutX?6b~x!;mpnf>g;QD)-V+|S&@ok!r%lME z=y8X~?h5$@$C)DcJzqnG-yP3mpj)>03$fYRD7~ z=2t5;!{O>QwQND0rk=l1{X0F=EzRWK@8PSWaV&v!b4lVbXcN@9Ik$^yJJ!u?(Q;3}t6JAew|qR}g5z z2*Aa^a_QD`mvfX)+GzR(vjUrp`mcg|)ornuQd30s`~G=D`PGAI#Q>M{U~eIVWrQV1 zYf-*iK=dO-y`dNu$X&o#MB4ROW z&u2EkIFkuVhh5=s`6j0gemt^zgYZHsPqZp)}VuOR! zqzv2PYly;gGPO=e!U6#7tj!Y+#h@lBiH1i zk|BLqG|cnTY~^lQlL(1F-^7u(kTPMy7)&ebvMXE4&#bHBB(N1%wGE9Bmn3ydkkB_L z5hOAMeKSc&Z_jhjCU$%aR1JNTg|78VXa>1o9`dhV?@vYFa`w@=B2Fw~I|M>qlcmW- zHC<}mH>Vri`<9e$Fl5(0W2`Bv$bXqL>L0J80M_MN_Kdnt?04L^5ko5PKEdln_25(+ zGxp>`@g!J@MQkrtona0LKbu>*1UU8C&F3IVgqhY0sApvbNLd&uP!9~1TU3w4fNn+9 zUic_uS5zsE&$R32YoS|pQlXRxt9c@5e*H^?DIjS9;xJeRQPxwd=%rI2F~AhMFGM4# zgkI?wsKnu!7(V#5DY@#rwJc=@HGblfUJjQX&~Mu>-l>PevcCeoXYb(&iin|e?@JJ|nuSA)< z0*F0j>{NTK5GtJGh7jEC?|Of4rb%7t{~L13LJ`wp%UT8N692~EG4LTmWk7+$tG)kI zg}SKnOZuxA0LUP^QnaamSkACgxuLxri5!grcR)gsD6s#w7D|-9{!(jBt~ZD$g(H9D^v|1T|vNxb-*E(^a7m zyXlT%^Nd7sw*WOp4E$SY4$`QVpG#ReS%(A~P^} z(to?#QLItm#gSV#hkm9*iDw~GyDa$l&Ea{pLQM@ggg7Fi2ZLk~sS2|_qTpL?@`L&K z!Uo!Y-RP0}wp)7Pp>?=!*z}L1tW@kIZ>o&^b%yrS8o>%;1P1+*jRkdfIKs-c_SI|r z#~AjGZjZZfIXOf&RYjRNa<12mg*eU9rv-qkkE|q_Y!tDrnj1@h|4!nTx7fx z?u(J89gT)xUHHZ6!{12HX*@T3gyc)^N13w5d2|qF@j*$!@iuHGPzE1X;mLtA1~146 z&t>t8LK{B2&lMS5-mj`3-+F7~5}5URSyyRG?|r9xwG;Rk%x{RB^u%M=YWPF4khA)S zin4>%1r_}&JN4q(xN)iO5ANw2@9w~t%~txJxO$Dt_5b{B_(zfs9*Fb~Q2Mp>yZ6ec zUt(hjn-CQz00`KqK%<8}1Vt#u3O`}l? zyE&OA6$%+q?(d=(oei1+YP?p538n@ zxy{40eXu+2KUK#l7i+(?$8u`VFu+Z&xCw$1rI`&;uxqFIV=<{d9L$19txiA>y?2x5 zC?*{gMPZo*DHS|8o(MeYaWO#iTWbKjT&w_rZ)L$zw9g>>cTsibqlYzQv)Sa{1-683 z(}qemzWemoXT7$)Z&!FZoe!)IU)ok~?2B+0wp`}m(Ng@u zB5@ObmX{fBHp{~^;MKO7n0GKO?LjA{0ec}+GXBtD%*q13YmoULB5>#k=~zjTzQRwE ziMthDt&~B~U(i>Zk3lS~4o(I&`uxxvAIk$^M>twrgsY}y;E#GF>uR%obQWqZ;H_tsWBw1^mcH49iKCYcHW~~ zqd(Pf_jLQ`ZuHM_y;wG1?j5c~TV;j%^8k0Gc%<}{2KB_`UnyO&RyR3xAU6#pbg-zW zZM74-ExEt#J;ZQ9!(P`Tgm!ngww3e^yUoEEzrz*d0#T`Wwx z%4-!HLLzUi@Y7OGVX$BF#IuJBzh8=POs~{E??q=no;z>E(5~la!PQUgySTP|N3u>V zfC<0`wW*nwsrHT8|CujDBr(4Q6*JP3+^V;t8;&;qx~nXcw0NA+yYNY%Aiicvy}2a> zTc9QXFI?GF`cj`rs?q?yV;Nd2Wo$u?ewOE6k}_p!0jE)kQsBpDtmO4&8`O=UUu@L~ zk;7oNO&4}3DeaxLzEO-eiq79h*wT<&{O-Pq84^P)_}Yj&zmnb9s>P1(7DzJZE#tv` z+r5d)^owHG5G>UszCE-b6g_tK-?uYWaZV~>MxStAvYcos;EA=v-B{BMt%*5Ar?Fjv zEe+A-Ul==GHQ^qr31Rn5v1zvGNc+g@> z`7c@469{ihnQ-|g*HK&}v0N)|Gaj5>d9NO?x&O-f<620cRQXzgN~yRhuIYjG-rmpq z8JDi1k|*jU++8v+=(VKX%%cxPZ?iDA#13(&;G_;I-_X2MeA?w&B<6VQ*)ZtE3hPi^C|DQ?5ahd-PvN| zbMIydlo6x0q>BujU0s?Y2nWo@ww#N)oQ-z0xFBHNVy6z3@Am_kH%);xNABhsk#cp# zWgSx{9{sR22Qq%j=whnknM@rS#_nekzAN$*O_S0 zVPKElaofz5UV-#%PkHsF4M@0Wr*Xc*j68lQj0qg;#cGNFCAmkdH2s1FZ_h%~JpqaE sECe9ru!>hAp-;0J0_y+1Z7X_9;JhzlJJd9&0s@!8H50uu9f!yN2ZB29!T^W{HyoMP;vc*u4|%cGaSW|uhh)J;a93Y}ZoxPJWi?Q2RYx z9j;5yN1}`oU#0M7miATlubX1Ar5bif4&T*{jAx~k&wKkXVvXj)%3#^D@WTa(amwDna-xcHV2DZL6brgeXG6h!Vd@h zUtPU2Zqjq0n(yCTi$8{rdU4@oe#TyQ#Z?NEL5gRsvQ||ejusR>f=dsy$+gX{U(!#` z{3zF8SyGlGX*F5RYjlmmT>J~|Q~Y8;aRm3>TH@V_PEKp1*p07K&cz*Dy;C8&GgM&8 zYSnqtKamg|HI4SX-puVurIMHnd{txrilMThUQ8rKiEP`F*t25#BGc<5BDvYKpF61; zOk1``icr2V`?v9T!m3SPW@}O=I>{mK@3f4`1it57A+26SiWxV@rM8)uUET=WWhuwR ze?rlgEA4rG7;gxfB4!=L4#V2Jqm?!04ssaidhs75pMI7IjtjowgR4JSqA_FhkUC0kwh%TtoQ~2RSQNf_ z?R|)P^JiE;2g&Cytb#G7N6D|38>*zWX!}7#+q(kY>j{6Fu z5BE6+-kM{)vv+FjDK9Ig#~mvQ*vut1I#<;OhM*_Ajy0%#gIgy{!aHhJS#gwQg0UM# zOl}4rM&>7Y51LbF5#LcU*>;SkpYT_UD@?!O*JiimB*pB$NT*2KRQ~ofaS7=zVs`YJ zIf!vf25S@BAy18$YL2dk-301?Ej)8Zk~8Oir?sfKDfRMYPg+()GDbAL@JH7d?N`$M zT_emE)M#tXGu9MtZN-inIu?}Ci$|HWeDk_ck2*54QK^_y0! zRH3y&Fd45@G5_n;bXyZ{b6>=A2ZK@RxO*@$fZq|L+;AY^a@!i&Vj+5K5pMFKv_)U{Fd9%l7jA(nOh%BckUTuRDN9EAM?mGZhQU9jbYBm(KQh7QRFVE^~3kB1^rwZofLxn={14XBU%|IY@i-T}YG+t`Gbt}xSsz3<)}OyUohORfA&M{j3$Sl_<?ogMZeh%Et$0;d#$SD0y zt%{3I$XxXD-~E&N_m#&U{m)I-B=e&>WY+bjXLfyY9A{yUbxmpBTe)GJyY`d|$A4ZY z&G*niAE%32_mUI7ul##EG(Jv{z^vBY)&>g=4Ry>o55f_%_GF*$dt7>dcjMImzAj6o z!Sjy*!qG}8!vplMXAnkjoIS**_ZUBS^S{0I;k9oWXhFd2Zsin|J6vPu zdr!-=hyng6U6J*YEMG{amA5!+o{M$eKSW7;#H5dJ{f(QlYP;Q2S{-s-sUa1~?^TPLI-tHz*DgkR%@Hc5K-s#>bOdeEJP0#eK5cN{G{=U4zXQzw z2TPgO&!1j5KI|o`IIxkezc2}0hVJQ2lZUZ~61a_bZPWM#_m=4kXC#Uyqt)phKj2N- z!=hby;-{=&ust4qIGCu-wwr;kR{oqaEvx^_xRgvp*f;Hd7z}(UFLeAceAwV(Ec28q zy?=QuK#6dfH$zhF0s^GN)Z#H(f`XT$v3|kBVmFwcj(-C8J(r@BlZk!qPIdFL5c8nJ z;(;mADZH>`&e0zlKM<5A^q*$E7#4f&EPRldyI$XRX?7ZCoVAc zL?fo13sd^6-RfZ-@bRc#w3@cV`_ye!xIM&Ddq?&U4;RlxnstV^7_x`S=C^l6k#Jdb zV_w^Gl8%gzGo-gz7_`{E)!KV;_jlri5>`-9usmPydRZa7lz229zYg1*LMyA7-o+z> z$Ra#99g4}tIsB5pR#b$&`bwno5T-gbDlC}v4jug|^62E`o0Nt(2dRCmgy@#t-tF^# zI)n`8<1eG?JCEqTNEHfbnNi%hF5f?^duY>!wNV|zaq^$71oja;G#g$b{*C^bmRW!I zRQosUjFxFZzfyKZOW9I&6~FuG#lMa;TPW_uea|=e_F0*+tSx7v9~IZ1s~dX`-g+LN zUm3>bP|g*d=1o~6s(WU-P(g$3TO!IsY*zu>e&94N4|g__p)=IID+|0ZYsJ?5C+=BcY-7U5NN6at*EjV$-UyzNbliLNwmZ z?ZS%vui?UyZq*-<~dcN~~!|q?9EGw=g=K7V%p8hT`kG`t576HZw zt%?4TMfJ6Epd%zA(ul^f?YH4XXIzGmm|0vxgl9kZEo+|47B0VEx z`~AVz_XSjPOk`_b^5Ed$$INyjv5-%|KGkBt@C&towDB+S`YmpR0}^ z1_$5HarlfeaValzsER_v`}6e#Bpk+_eF@CD)4RtLz53;?tu%{^i(kHe?Z^~#{qC`^ zKak3WpeB09dog`li)e>pA}%aU0p0DI9JdAGyi+X1-{0S#X@$g-*$iaQpyL6aOg*Nf z<69Hw!`25eYUtKQIgJ|$HZnOG^7`jnvzJ>Zj`jBye9e7XqTUcOdI&ts`D{mLZ?+mk zP2?ESgYA+-V*m$+h@v9-RzzJrS7IY3?NnHPz{GikFm5_JAtRAB1 zQl}jWYc+*Q^cUBY9)-ifDA}u*7qwwq9g(fWtJwE-dYpIsLvP>Vh~CmRkh6dO)&PfN zRa#lxhFVe!)n>uDrjV`KDK79vlU0}t zBmH})bzp055%(cz^F$;V(u(Ipv;UP46xW7-NlEZnC z6=LY*!~xvtb8RgN8XDRR5lyT%EaTbJ$EiGB^mO2Mj;=CDnr1xtV0yV$q4$N}w^x>y zmb45E2*h8Lm>kJf7{j+Kn;}_Eo{dYg+%q_d67AV1{)&a4961WW@p*ZprmB#O%%jd8 z(rzm8?j5(vRwu260e(tmCT38(zeIf^xz-r5A4NzYX?9bSh~9JJ#N=dnSZQe~r`^qd%pjptMNhD?%WyUT$PKE${C~XJ=DC2l4jpPcjID__>6d8ctJlvrWoK z<3WQGCve;C{e2`@K~a%Z*{crw7Zy|BUVC&aKi}A^%gErfBOZ9mGhxf8sig%sSQQ{7BwPkp_EZdi zBWS{6)UmZ`j?}j!eeT-^vWIZ(9@DOQTD@z3eaMbfU*BOaZLR{n6zUoY4>GC!H9rw{ z_7$P>U|U<6x+S=C-aS>s2W>Z7wd;B^;4!u=PnXr1dD^rZ-R&l61u zOGRW&lMFc35r!6RuNro}cIXclws&f}L2d{{{ zL#p3qD!~^-k@S1_fdP9)`3S+gCsu_d9p#*TQ+@{=6>&N92e$;Se|JuiIxpi+llJ&a zRAaNN+%DM%rPTC=RA>~g`yVpDUNb^AtA}=vyD!`_+&WI$K0aPk(dP7t8bxn8C-q<7 z-U*RE|0jy^r7YyPxIgfzdR&AbPUiRUwsvs-#uR=OSyVwh<#w>8A?($$lapLhD$nsh zebWF2z+UrqIKRnlze^Z z>?c+;F_{b84tR_n1x>6iU03-_KL6_cjf$qG`EnJhw6@1Uk}2+qEh8ht`^L`6DXhy@ zM#`K%d>buMDLyV$z%c`aAh6&dxse|KuH$`}DL46c3!FMu4`Q6X1vj~iz+s%y_0a4u zak0Ft`1pYL`B0yMx3{p$rs1SpFsb9aZzo<%DG>GS+#HgyqZIIQVC5S6`ifX#47X>U zv}j!s1k9$DdNBVYYB4b}z3--QK0ZEs$p+7fGX-3v)P1dh)BLjL1>aJInsgi-YHli0 z#>UjzPl+aTw$f3%Oz!`Y7&f?}q2N$UfA}EO&c6qjErYGCt@J2!++k{17)mm` zQKYE%xv8Zk;&Fa6r)9n81X*eYac6AT3J~!o0iS>T1$9hc-)1Z$-@G< ztYy5_)+Rfe`pNSdJ&9gs99!oLp_8aE0+9|fqi0)Ja@ zdbis+7k8t|3eu{&@9ZQ`*9q5Jv?8ZHYeyZxbl^4tHVJ>81tZ~Oy1qO@3;SGMM#Pod zQO6(#>*p?7%?+a=oJ9P@`0h2-?KY1`M8S9Gf#U%uh>;(u#QE;begY-4sgg_t znj1;yZ5cN7Jx%zXL-_G}hQxinOE=aN{~!!vQ{F!zt*zqVoK1fIIxsvO_4(@`h;M(U zk$-O)-46+_So-q^?dPA5!NG{q($cgb1ALrQ=Q>3j{zzWdj)Z}mnG?IXXl&SQ>pi6qrJ~jDO7aXp3(?wQ0JBZ^~&Xah3ah(JxVvsQAOJ7m>lxI%NLu;NQr5N7^s)-;Rn$I7^rUTwPTT1q-u-O3U^k(<) zoE-#oOmMhZ+t{=p9dUk2NPvSueSLkT)YP&{N*MU~_|AJXTyE~}W|o%H-(TR~f%}kW z#P@ptKKf4lyZ*}hI#PsmAQ&v=K(4xoY86LENB{ilD;L(^Ef7dccXaJ7ALBm26`KKJ#{YB*go{&urQ1~ zwaeJoNcj0(I9dgoAP9NA|BzeJO4Fi=!~449F*E$JgY3pmTke@$hH#Va>Rabx!2r84+idIRB40Y*p*J0Pgz-kN zB)Q%mo~lRq*hLw36=$i6N|4&{74GZCpxo<3kIXBKR`s`@Vjw^ew8Y4ggn=tol}%qK z5ylxg0-0eFEwfo!SrfrXI}xG|nOn3+@-rtKYmXREKPxyK)M=H%|Zu`1XDk;`ce_* zv7?>I(ko}6mScMDBWCC>{SL~brRhOe`#azDwCe11We(#Fue$-S_yT(&A%d0uk}=Cm z12vi3}l6s)}!>c+!5u%bm`E$ddetbHYpn$)_*4_ zNPI17S%&?6>+b-L8xO<5k2tAFmZq1qvSR+0kMm^honW?5{Z!$}LzLFAD|gz*9UN@z zze&2rk`4}R`UVCr0LE0+)a2FF5LYz)Lq|qIDQQt=B50!c(r5XLKusiIf3DWT*%=oA zQ&KXrfRvP!IEb4+I3=H`|Yn4P1Z%IZ&%Jpw_v#;xS?FWDPcOcqfoOnqu>ky zCS7Xr`3OtK^TyxwLs2IqAa+&+F33!kns`fb(`AoYqsGj0M$xs*KlM8R%G3WCjW#Dj zd9_Ua+6(cVm;|tNvFpZ*9!YX=1{X7c^V4ti-V(&ac-NvZsWmp4yi^2cfonk)AVw*n zEn^H*CLIw}0fRHI&Sz$}tRgq7qN_%2#J7jsYI_U%!L3+W;|J9R!q2&i0r4c1mk&1+*#&!H z!CrvINaTD)PBl8p5)ava*JR7@QR+6@$S&_*3JtCFw2S9NGiCPIgn^^-=;9&_L?S*P z;AC#ErKI2$7Q(H)JwlZn95PouEK@7(2|WtoF74{DifW#x zksjh_o-J2wj||j&(?`q?CrB`Wd{hb77zCdngF=#{WgnQ`Wpv&w1L&6OL5rm;8=&a>9PFGAu$2mMI9iA`?d; z0eYe82y^Kct?W=9L?Lr?bLZ<*8(U>3U3k=)frIVwVw=WbCSG1b5Nrgz9;hQmt)hhg8BUp%vg+*l8T3=5ll!g6pyD6@rr4r)v7Ga8%j_nU#c~}3b#`~tKYfaxz@#DtVi4d=op&Z!F)=aQ#!o`+N*B1Zv$IJ_ zN!tLB;^gHG23(+WIxm`rhDIQS(^~c|clytmFrvFN%Yn*%eu;^ZE~5&&6HQX$7y$(=MgU}MfIR12#g?6^h`w@ZX zz%c@QERnzhQ|`2pMW($V0ksGYP2T-e6j+Rjb&#SUl4mE%h=&Sw3*#4dnja79X=q?T zqA)XXmBil2M4?gjzJN5;^Ecvl4f}kOMW5|==-`w;_P^Zj29T~IBGolOt&b6KWXUy)`dJX#Z zYh8tfN&lSpA50f0sQ_cEcd+i@X~>8-%RBKrb-Ri9x=7ZZ+_oqJXJx1bP9M!3tn%B~ zUeSb?kNmy{jQjvw&GsIogJxIsIM1L-?r$0S9Uw(Z=J+>~kgTe*{5X$zl_c%->LDgw zHBrW9rI8l{Y#R6ekVz4?+134WX##br@U;NXAdTmQ+u{$g(bs2E$Ww0@-|J-zq-1# z9VGwuXNpCmM4NY?A%cP{2zVUGYxI7WY5beq+QhUo{HkCB))v2ew|9DXcW1+u8XAi1 z=HZbC5Yzqry~j0}F`R0}18EE{DJd#|R+yNm7pD&N$jHdchljCkZ4z;%U(7pb=A=H= zttAp(zx>2+H3wmo;rORZ{B!+ww8mFU0uOS)gT~DV^_PmgvmdV8-Yb}KPP~NH(T8%x zJ+nj?gf@qBg6@A4kz$@LHx-;_Cb*~r?yK%F`vE~b#5oq8QmYl1+#~i87pIZU#{+x{ zcoV0xE_uUfg=!7&@d@Mya#jZ`)URV6VNeP?^vCfZKu12lzD@@4Tf4hTU*rDGJz)gQ zL`O#l%)Zqd1d-!51f1o|<5iZYPk$Y+_B_5cb#{)szo($4E)tavp4t?^?oVdxATjX? zaG0xEiQ;H!`|+l~%_WoN+UKJz!|d#=eP}^Gg1fu>BX1CwogD*ivY`y6_s>trDjvLi z|XXbJ&Pw7^p|(X{5>_TsBb_~vO*5% zxpWS*Hippj+^H$q#4@NN$<6JeUF$D~T0{lyCf(*%mSJQOmE~;~Ag!r~v=LxKWQhWX zPYWGrbriZx!G+WhAZ`tj*)QDno#Lz+@>6>nJp(W)p5nEI5k`!d0gKK4L2l?~5H8N% z%@W74WH<^RgXITQFbSJe*)3zD^YMLmceTr`2tm;VN4jikzr75cMg3BA*ly!4ri_4gbmC`QMa zuR$Okk(zw3c>i5B`Sa~p%Adqti`nkdS>PCVW2XsMfg`1yDZpR8S}d*-?c6hH>FvmE z_bWw%L39cBCK~s=q*9XS3cRqnW3WlsdQ_7O4$|W9n~5{Tqv~xArMFqp32}l4Ew}&r z?U?*c{H_YehZmk!s6em(3A@K+iNU`7`gQa-#pG|i9Cdq?i65FyYFQM_B1%*Q}d!0V)l1%aA4u!ko$8|%xG7`r});jKziVQP!RM%iyiROV8q;AFHV)v3TSWxbwqjyM@tR=l~v}}+?2=jIuNmaWv(3Ami43f(tkn8>#GU?CCYw#PuW zdcIXzTn9)wp~V=J5CWLdJ$Nl}f5}Vt2z(C2FHxt*$AjYHa0jwQGt%2iOP_)#6m)cS zTie_1cPKO~+E0@}LJ6G6W^4+q>`&nszbL?sBAt{&vs?mMp!UVT^?tB8_t4ijq<;Ge zz*OH1>+xI1TcO{BS;8cb+1jGdiHb927-0RuPyQtzg2%y)p{%H-ZIks^<%X=*@XDto z?1teg887Gr1<8g*FDS>x#*XG)haX>Nym0vSD+B{+dNW_MWMpLIKh$4a0K&+&+hhE? zI@vtF+ROn?jnG==D^s=mFgL3!fP(|!_}pJ@3PATF;F$V6zU{o+2B(}QM1+NfJ8JQ8$QzAJgY^yi(Y5|!~mMRef;&};{))9o#+%!9!K(5x4zUVc{XA7ccuNZ z1;+y40gDX+*X4F@*F1p|pWD-L78y}o{2=fXJ4G=UJ?U>mAw+(AI%3W)D3(^_CPn;a z+qTaCk)b;Xr+Id%uHzlx0Visu{@16AEO)KjrR6UsUuG^hL8)y|H|3`n)tT3bD4~Z0 zmYB3;O4alI8RR8ub+WTa2f+7c@Ae3WlKtLnei8f>SSLjNach{{odNjilgaIp_WDf; zl2?NnvEJCwOv7!tc7L39u^cF3-jql^3m5a>Ewb(;43EE7me$WPGlbv5)a`)*_Ii&O z)MNiNGh2+n=H7qziMP5i4uAT&6A}J%$SV+;bnf9u|LuL=Py>UEaFhzl!GH(xEAG7* zbiw{zB^G3jMq7Wt7{RnHd?k)YRUQcVM}`O};uoWTjEJ#@1b4rW<^aYxov(X9E@tX2L%PWY>m(j2vP7KkUT4q-(;6R6P9~)QA!~< z)b{pvb~~TCo$!J$Ur<+U`9Ol!Gt!ItDM1T1gBcbJ;oi}`Wf2radda|`$16?+fhCcV zk%p!4JIXoQG?Ui6r(xO*M4AviAv#nr5Z;w{wGFeMHZIZ5YZwaO5n^DAp+g3kU0be1 zd+e|c%*vG=u=cGg_`Zd!#H$wHI+nzgM*-o zl&e5HYUAjL3KzxD)3`|VOl9G~vyCg(J zkF?&=zkh)_IW+hL1S^}HC>$Id&kgHv0fia3dqM`0l1eBlq8s}h%fM<{(X58Ey8;kU zzPqf-8rC_(!NL923Bo`{Z41F5c^sn@aE5^;g{`|L-~v!pMV-ZX(l$&Y-pmo7&Z-$# z2)twS*^mTYeE12GmAX@tG)4uk-v<-=7R@_knUd-B5L@#|&805g(xs0E_uJcMq>w?n zGa%gdjvhp@{T9$IlnBH`MU`t6MynW}4AH>({Sv{XBbei_t{y?#EDmP-Rpd?qgQcX4 zY^62c0)x&%N>92 z=IJS{QrFnnNSD$dpOO*=0?C$}kVZp5QBe_O-X4flg=Je!&c(%bdb!a4?e$M!=Lpra zQ&?r7xCP2XxIRMR{{FDFwYBAg#>4K}YCA6PbNg>5t<>-8GsS|_x!<4zVqmJmBo@FR zi~ZT^x|@T>_=JSjA1zY3pRWZ41px^G+(=4R78xvTx!Rxr@#nD?_Uu_dw0$ncEh2&m zh&8QZRkN`Ig{_^Pz}Q$EYOiHD7_7%7Plp!Ceo|d<=-lKc0EOBgOaW4d(`Jk@Q^*}1 zKO)#8#XSjNcaf}hEWoN6$)bP7#KtlQ8ri%eSUD^Ul6ksgrTC^VpcOQi?~qycZWzRT8t9^X_^jNk2C)%wK-0!mH;X4rzc=Su^X_JVlRPbP_=cwXDs8EhiM_0v%lF_bFF5B{SaZQn~%DkeV zmS_5Nb()CXE=!j8!lw2b8~1seyDn^kB0KuEpKl}fP(0%ocJ}K*v%df0H>zb)~M;V zOWo-X(RsK3;QSM7$Lb$O=O}9l+a7?KFdNj2u+sbGP5zyqO~~6$D9u|Vz0y&HGcY6N zihcNy9_oTBUoCDT}-y2sr;%%KZ$Y8!&3}UFq-!oXe=ZII?YP&QZ zvY#O%-pt^?x}QKPptn-0K+92^L@he(oyv-;uM$Ie@nQBu{!tHHc}9MI65Xbi3I6&u ziDT5tIa!%@RO;}{pgWkq%F98Pcw5Nug{aS^1&ab5VbA-k-YceEG^tGQJQL!=uBI6; zedmzWEd2yBz@Gu}-1r$|lBGR|>j&Iti`7_m8vsylvjuHa<#K9f=es(XXsU%5@A zC^NQMYmrw%>=*{;mU17erREY(j`jT2v+{{4Kn_>_B4On*=i(D0Z{a4}!9s5G*fc?M zLNIx_t#_TkB;VOBS?TNT#Z}HBZ3WQYU?oN4B!x?8yYc4>}b)Mh2_ zRW>LX9q{IE1#1F6%B*?b5dOpxpKXoI5cXsTna}ZY4~@lixsliHanJF{OPt)oLL?LD zj!(?nx#G+9_I6EGYeNIMudi>MV&RBwb$D!S&(i%lKc#WC$pmC~G=G&MzZp|0wX0sCGl7PI0n^%FN=Z6Gr_$xYF&dRf0L3I4fDiucdUyEoGM>K zCT$C^xzjKqz7L}1=dq~e!<+GH$2%cm@fJ5i6%5{zRv#;QDF{tIg- zj909qIg)>_^(D`)>=)`&8JPSB&`AAqKaz9jI$bkEfvEw2^yPfQG-^ZFJJ=eBJfbl? ziYSyW&NYOznKw^f78l9AWI^UiM#*mF1C2+}~GB zB9FcLgo&T9^-YC8OD9{ek+{MJvZ&1m(#+>q3;JpY<+Y0qe-;)9v%agin}!S`emcf} zwfF(@l#(^h7HU5oom_~PIT@!rNou#P94k*dLq?$IBL~V& zGUl}z;TAEj4?ZX0u*EAG9XUN5y*8L0Zf?qEkc~|hiJA3RpM5<;8V!n7a!2Yuq#G`>aV4ACmEES(Nz3KGasi!CRM-xpx@ zpU)3ZPETtQ>|mcL6^U8f+Wwj-(K^0djkVaBD0w_~3ltJS_5f1Hx+lJ4>yX!D%CWl} zq|EdZ@IIghvcOHVl#}ql^19`4ss8=RhMAWasj;y!IN&{Z&mJBXjL+v>#cP2a5)&Ky z7r?V!U0niI|7KT39YcVPDYj*7`Z@QWZ$#$eNsyM4lCSKpDx@H^H3z9F(vEPF%K4Vm z^4p$%0Ai8PQ{>1{n?HFoHPDY3?jI5uF5%su;%8GQd@pVb2TClUSnP!AN=O7u#>Xx2 zLqp}dt5sMiRT71sk|tDq_>AeVAVgM{k8E%Hn^XP_)SNLGrJ{q~CYTqLw^OTj6cYt~ zWaWM3!jEbDEOxgpC9GVZM9Pqvxbh+uIuMvW&tqFB{{;c&^G3Fq48{Ssk@2f?KjaB0 zaO1$%rlQ%N#oJnsA;GqeLg7}mDk(xp#r-0?IouFtV%UUCeawiWCkSrJ&8iIF%n|1Y zJ1H~UB0MxaD!r)6e;sHrD2WX_Evejfy+ZIPEWaWsQ_B`1+sXLzhfQiAhNy-)r*`f( zzNU@>YAHG@6z`sK-eLU^eHAeVpdtW%fCo`V=3ugX05-9r=uo!M0D>UMcx|M5oGzl{ zyx)rgWu@rmvxIg~Y)&+(Gqt*h&A4+sDKV`Rf(Pd1<@JH?W!rm{EXj}G!-`363GY#L zJU(sf)S_M68s5S|{eF&e&B+kQ^*YeIGhCqd)72XXRp6 zJy4KPWU=h59TI3v6Gec;v++%g13~&@eTmCmi$Ins0I1;TyC&Fro4lvZU6jN@uIXXX z3>$e9WpEA2Ormt7=foWp11(WHasx&SQ!B8804>w!Ma*D!Y9=o-zFZ>$z3Erq7ySHl4a?n)GU-wqa*X@9bGMK6 z7w@eVl*(@_@WxA`1OTRwyN~BVZ_V#^Bv|N)m!n0~GWCq;baFKxAqWU#)(jnwdiW73 z@n;*zqvfgQN4?BSbwCXQ#C^Gy^}=K_-b35|Bnsp`+g!yXA_)I^x64V6Ns5UPPE`$q6VAnH*AU2>*0 zDAy~{E<8N7@f>k?b?XJ45$5y3!n^kh4aSkW7n6c3B)`8f*neyp!V{aaM?4aVE8U09&zo}2_GWsfQs7+&^2qnMSRyFMN13-aXb{JKJGfio)m*!6#*EvTY!L`@YXTS zzibPG75SyIs=p>$$S;~#QAk8YL?Cx*%{}^z$O^y`cmsgM?35 zTgQ{YI47p(nn_$K>05UhOnKhK^mnd#>=N|O2;Y-Rc)r^nds52Qok$Y%C~kDTfzJ0& zMc=1>2NijdlK~!!InkTv7b(K;kRI+uO=<$X51TKJ{zh^9RRe|6tb0(|kWUf6T1&_r z=`zV|=WjN@8)_s5q$u>sJ=++< zPK5KY-~>!23-VTGyi_cl8)cBZF;!1Tyqz?)ER6pZ+Ntc^?w*&E2Tl2RhbWC7plu_@ z1QrgdP}Vjt-aF2~gn0O4`tO%HU#QD7aqABEcziWq^$QMcmbhK1|4)NMwKLzsaX zu_s9Y+#beqctmkAGpJ{A2?&H^kg$)yvt(yO*#ho6gpbtV`npU?RIZ7(He!i(Bp`T% zeXaVtLY+Ry$;uu*$}J9_!zX}JmC4!=Mk44O|5basMcsnVhEfwJENP&GaT7A2mpC0%Ns(dglqzxu8mO*z8WJUFY;nS6 ztxgNjsC z#DCEFlR52N4Qh_q7~!|sSMwI2Yl2c?LA|&~vF_p!hx66@gdEueGAia8#~3?>J%G*x z&DUJHUX*x~`$y}v0fYrLvWoW_zRw6v51@n5e}rQ^8l+i5giq>Sce1ABSu-yjgY89@ z)e&%u9gkSc%o=nxm)(=JQL!!!N)Wt;Q~B}}vCqXmW71r*x!rX7ZY)b+yp`Xso+Y96 zWFIHt1^0biRlw4VO5TWV=j58>l!!OMj+9S~>%5)xE{x3`i%R`Lfk z6$_>O{O$$r9x0OiSTTHGa%A|WQ+Q_~{z5%mwiY^1lo$C(m@dRXs`oiJH=yN{J09MB zU`FgFIt}IB97KQ$s}U4q6Md9s<5Cja6mw`__vZAgk$vf$Y!MS$80IZYroL#A;sNQO z`ahrQxdRNv?26=q=8{zrQ6{>l@3?`wY;Wr3Ql3lZX|*u2Zbg^{UgVErHM0~0WY&A0AD4~KI<_v9pV1BWtANL}T{X3%OZ4iXXZ{bf_ zyU^guC8s%rv*EQ|S&BXz(>1s03M$x_w4Dg`#SU89iEed%9|_EMk%fW{KOT}RHnc@* zpe20=MfuExZUf*tA}yN- zH8)cM8A!T+)_-Na;2>+8&5uPD!hP`AHNi3OogYO?Of~jos=(t=+XQOd_@pEwUfj1Z z7}46Jn1Ii0%<@GB7z~-1&~6M?w7vsPBcK*ATgKeqIp&GX1%Xm>Wo4x!n-oJzKhOl) zO(R!cyx;(Z7C4*)KE@RkYp<0o}&D(5e4c^ZoViOoRI~bPNnU zDk`?pw`04bhRw(Ld=QW_eb+DB+TWFtmPQ2r3Tjr)YdJ^|kow`;bDt7HIX&BMLO^^- z$NQWx*DQCd@^o2q@`+)S{WG-QX|)fcvu}*J7jZ~=AjUgypx@1mjU@yJwL0=sJVH`L zwOEBb<$J%f^YHkQ?NT)xJ2 za+D2A4AQXft3`$!Vd<*rH_$fl|9GA(hdI{ z7)~weFyIAUJ7LBD>3xXGhTT85AT(br0_hnjx!Ty+@P_Q{@5|`xlfNC##)5f0#^+t0 zT|`lwT7#u{An$o@)Iiw!aCcbgclW{4%8Ef$l&V$WtZ8dH$L(QYXsG-8Z1?zP>46#u zybCRsyCB-_GwT@Tvq!Pb$O!CZGaL$J_?&Bk;_+2NUvPV_)3?*ac&Yx|w+SUab6G7fKW{VPh3=3EV-D@XwieLvT6T>dRVES{ewnx4Dbp z(|SD(OdvV=73mI^wSyfJELE8a93cdE&~-65NqQ@5YO2T1tE;NUTve4n=Yrn-$w7mNfO9t+#zjFpFdIr5{l8`c1RB3a7jFrUi(}kk5?KU1XA)m zH0yz88Dr0krY5Lqu85=PTsn2|ZEdV5<9zQKF21<9`0aUZD-!36E5Wo-b09S-XJDO? zPReVoxQmt-ct(Mc`fiaEsppRVh(eqXoFV>s>a`h0l$hSiAr zWf-(@!1Uk7a8u5C)Lr=B|I;Q89>j5h^ZoA}=|>vW|F6*+vl|ETEexm_{nEhOh^6Ikq@w-b8!8{fB5NxXCYd8E-{?iX<=XZA@bgY{ zk-$*iH)z4?(cVn?SEZNKjnH7A`8Q@RG*v2^UDeswN+@{FL1bYxdykT@R+A0tND#C= zP)sD2%VA4=4h(ST(}mXV>1C^J+A>pI&gGq140e6-*GhID`#WIrP-_0qxtKJ`|9#&U zBA?0~qNnF+0hlSv$VY(f9UOJmJBur~>;%x7kS!EVns>D&nic#9YoWs8yc_g!c^;Ei z_OfAr&~N$KLV!hg@g0qHhS ztvv?UQ7eoEb0K1|15emVKQNGGqx65x-}?>iW$;uFLygGv~a|Irn>> z^W67AS8nL>weHpQ4<52iq49E{1K$YbqpEW!C06Pdq7IGa{hJ%Df0%C!Mq? zdQr^mXQfjC7gTV=+jx={_Ds-?zVe@P-2_nWE;x)`N-Hj8CH)2iEXKzVnB-`tMdXIw zC!=iYd0lv0K-uWL1%3Q+?f?QZQ3#R>`dykd-a@s=z>vYI!Kv{@E%V4e3WFAOOo3mN zuP)Pjl$?{tLICS(zUzL)&=G@`w}7v7M=G3zpz;mfDJ?xDWdF$y+5LC!Knrt}iwS~M z-h8%~{29o1DWE4Zcrit~U0crv;LvQ2Oa^$MC7zekBafH@rM%auKkF|oF_!&yZE$<` zR}&tt_hT=2OBUO%|6~W03wWK)$TR3ZdE-WHfU-kDF_9K-j5CR1_sY|yYH%TbWZ4*Y zel2g23HD7uyZ%vHHbuooK4M1_Kh~*&vF=Lep+rb)N;plg(9GT;NgoP1AB2x~mt|kU zjzFwOkeXWYuajTMQ*^1*pSAS*ye^7M-yCq!2g4GSWyGa3GTi%)sEky%#;-zuG7t`) zj&^y7I8ARZh7;z)7^esbe9U1)7rkZ#>|)2QL~DEil}Y%E5;psk`YL&jX!3E*O$CJ2 zCB#HcCu(GS!4c^=UO!|sPR9W%hs@ zQ~BvRvxTFA9ONnevYAuOr`k+44Q2ai;)#Y}(X9%KDZij9#Zz+^`7A6v6GEarjA^8V z)ZVV{CxcM{T)|cNWFbHWALFHdJEWU5$z(#N{`gvnx}Med7|Q8^PbUREVF0wzFi)`) zQ~^}5fE>gxE*A;X$=qnnO|~q{n$LoDUMDq-Pel$IuY3y%tlz|Nm0~|~*ZX0WOCyiK zVb;LyC5tbS73<2mv~MRyRVg0mJH?0^0}-EYt6Ka3O^F}@<7q!#*p;uVg?eb(?U32L6`07eFeMMC%Oa=Uarpg5g(3Ao;xeP!U zcs6^>c)T?r=8uoP|MNcF4)o}vW`R;tyMV;siqi3(nALv_Ijc8P+7R(W4rs4Z2~sbp zT!BjFzw;nh#}O$M8UQPsdgUW zngNAGsWxQ#{FZn0vl$2TAfwSGjCL!4hgfO@z~vaQV4^U-ui>Q(1hT>V8(jEK%b+3S)Gv}Hi`Xa|Qoo#N7RFzed5?wX5HiVfowW%h21w9#@Jq{n9PpYcAQSN#{ zD`Lk>x_$+CIAUggRafpLpgKtfsTtoFEKJGaKXci0LWwr^=-9OSSj+#7)i9SqoR&!> zp0WcS-rnhRfa&1@au5Ui_-TZ{SQ^?;nLkHdKP%x|s(X7+<{&HyP-kU-;<7@L#BHKK zWdG~U$Xgh{a3sP6ysClhQlWHkj1-*H!%>a%qnOlo6a}gzpuKDc0f4nm1baRsXRzck zzqQQ$3&Q3XtY&L8biROGra*9BmOXLB`K=OMYR~UuN+r!CWeYmgx~lD4Y9{=34nyam z8KFF(cA*_H29Fh?`%9^gYlfyZ;ZTn2t-mGdi8yapm)bA1b`!mzAQJpD_yD7RQaN)NLT+2=1%mV2tZME8 zIM}bS-l?S~6hVy1bpMcDRJ)Z<+C(!mZAAqx?=17BbdPySE*sc|TfhQ;L#Kf;V|bh} zp%X6$?+k_B;ZwLkUsU^@|Lg_&@k)-_huw8TvoR$(fy=RsCqrI*0L$tzjC%p0qqx6(p3^!o?!)(R)FNbw=n_K!GDdT##a+M8Xu(}h#Iqn-w5 zy$^Xiwzxbx@5W<(@oe>08?HAis*x%5ylWM1K1o+=P_(g(Cc#QOe#`j#$5N|ZHMfX{ z2JxE%=BWp$>D?Qrxwn69%FVW}{y6yc-FW)JsFba*@|dS7$3`AAfoh3q@z7}E1iahv zHry#KP4KnF=6QNS(96nxQJBv!0m-lQ-@ zDIPfPycw+5yp;0K1GAAsEn;)Q2TqB8RL9>XZ7~pypv>i+1Ib%u1`183N^om+M4%ZK zQ#Si>av?}$-H%@`GB@#YxfCNbpfs$u%yRr4r}X^``fU0#m@v}X+z~OD^1Hov#c&Ar z=Wm{*HEBwOZCXK2(ARemfwN`Wv8W!iS$NHTs;AIwWM`gbfuywOBg%Mh`-+ju=yl%R zm)N5|S~%0!+!ZB@GKd=bI|KW|L?-VsH)J4+?0HP*sm_S1pnS;twbCbruVz{kRD9w? zcE5iJZJE4xsJ*Abb{%#U4?NgprmRf-Bp38CKOp?ziUOBg>nn|L!t%K%qx%@pxYRgC zu0mGsRoY*raa7_YuwS?!V|eLhMC7Iw+L+*728pQ@bM^b8^ow;1Ebe$oUT&;|-N)RV zqr|W2yH#j;9Bz-Kzdj73J#Ew+D!rTFc_3b-dnhQn0$jB zEq=~}*>b|Yef7L+($i7oB5&Kqx8{JNL46P!r>cMY=|MrhWe%HPS$(&djrxp#+1WZA zKrbvGDOSN1r7$F7%y;1Tx-v48e%uK(LRAeYI_`R#IO3K#ekk>1o^y@?(&_6P1>m9;oQp5o??b6 z_rMJz&Fk{PRY~8NM>9hmU7lR2mTZ>lOQqe0N;m1Ab;pGY>eP@-(CZGhQ6*G`lWOAC(F!D-R7xYp(hBpa0Fj4u@0S@q1%2&IW-G N=CYnfv6|KW{{b)8%<2FD diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 90bf359dc3060e5c7c18a00c3fdb00f99e9ba874..27b36512ca91d4e6f6accf729fd6cb3daf061e36 100644 GIT binary patch delta 15455 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 diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 86d6829d138918009a86b1aea4993a634fa05240..1796d4bf1b215b1ac715a0302659ae47d73dc0b5 100644 GIT binary patch delta 3808 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 ZivlN!-u8m6oSpwC;Arn+SAGId`9IHGYR&)v delta 3996 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 Up>-%;Lqu3Qn)(_IYIf282Y*62EdT%j diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 6a72147f32caf74af93ce3754657b7bc3e1f374e..5678e44ec706407da92d4286bdbf79374367719d 100644 GIT binary patch delta 5515 zcmX9=bzD@>*S-r&cPmoTU0=FW>F(|jq@~#$_?)0e_^}hB%pR-Oe#Su%1}dS{`JPS#d=uztqZUk$h8y*8SIp z3)RGCj=y7tr^S)x!reTiC}ZuiQnJg zG$`CollN6Q-e?e6;~%ZU#o&;v@f*3qPJ-gF4!iTJ7RVOd@f^)HsGKPmVU{J~Aqg)& zs}Re|dZ~T{^crW7uFf=RMr(gcKpo_x&FG}{%HR)`&hLopxz{R0b#wFQ_@Hr`gvn%x z>Y;zZZWZ$Ocj;B&Rmh|GdC1ik!uIO=uk#hH_jx7?cGvpn2t6=d4-6WogXVT!B*s+z6O~Ezn7bfKNx2UO55k7OeJuQFFsfoV z%f4urt*h*_cqr&cWNPkguwUvrWiRZk)b!;&`7Y&)O`EzxnS=>dSFx+1>*s@m9f46D z_fo0$+n*fo5^M)7AM@6-hoGAvU_|)9LuA{GWKXi=a>>Q)-MgmWR|su={eezua$bJ` zAZ}Gwkkz}GGnI35io|7B#P-2{~S`WxG$QbkAEm*lvdA78w zoZhRE=J96&K=XsT_0*Z}HgT|Y180Qqz`=pA6xWTJQGh_nyt}jWx`~NNi)tn}T1d>* z(Q04w+vRZ1p0~@*&(;^GlrpieC@svafIt{ba4D!PxNs;ZjN zV|)FVjGpnHK{`Ta8ee_5SKg(Z>K7ap4cMf3!ET|qw^Q@;(R+K&YMPpxgNZM6x+sBj zBTf}A+V`)vcktk7724AT=F^L@A3oqKpNAT&))f_@lCcLrjGv;?G4-N;vHVy5bx!#~ z>LYHg(B|gmGg{i{<-f1|{DfEB-~!E*3W|!>PEMHA)YQWxBeIH$XkK1kQ`6I7g@rGj zDP)|X$RusK`fD!I{Xz~T9bRpUqI_-I{3Vn&?5zFe3gVJ`>2N<7eLhJKXKTbJnN~Hy z(SE8PWoT>UL2(A(0OjmHW3Mq4Gb#_B-L6$SgFa!2J$Bn@GgQhev=Cp;2E!Cue#rU! zIkiew5O#5)62@b3#rlANXNuGY`3TXKYOX?q{F4t%s|`BNf2bzUKY|@dw&37z>pQAx zM%?RQPPUgs%2=^Vs+vRUezdApVJEab{X$RMk$qXV6C zgsXmmHx&Su%}s?34Z1L5r*$PYwVbpU!-ED9<>hRQEG)M7w-+8_xgr6lj5|JJFvxx2 z(_)vzs?rU-jb!C3^nqikZE(s#GtBZIosbYYq&Gq+2phTdZ!iB5yZg7ceaJ@>Edl4( zVe*aFpU|%1`0zgwwrA_Ez)`$Hv8B*N^@TmkuJQg;I-0WeQOC_xJza z%CsD0$qx=kTpe!~t+w~(OX5(86bzeGy?D>ej@?O)cj2BDX(l5f;$k;NV}DZJczk z)Gd~~Fo5lJvE{t<#Kx~UeR;a!@f18>WMpJWAwLSI7m*MEL)Co*+S=QRmbm1wh%wN4 zpDRTu-Jk2$(Oo$Mr^RWH`gORuIU66zkB(9HsA;Li(bsCsvqXGxA3ZKP0XmaH%&E40 zm9U+LX%|?}CZ4-?LP7$aY$e`4P{>?p{_+-q0L7#fh~?t9wzkG3B^fs2D6rz;;eFei z`C4Lo`ODHDx{gLA8K_5DTV76-HL1nMK6ZsYqU@}E zIx*O<_6Hy62}AwSkec;|SG)Wy zNJJKgI_Po2ucfHl|FscZgEOi+9W&|xM&aBFd+i)Dhdcj#aCE8pt?7a%lQo{FIdpF@ zj46QwkEC~CyUZV_%&>KEw{JKyt+e3iU$C#xVMs_S8WJ{OgM2+Qjd}fI^IhD7ICNy@ zh1|_XJWu#GTWd|u=%~ukU-%lij;<~dEp1Y1Df8iC0|v4{#>B_VtE%EeMMoFfowGzV ziK5&+dv^s89^}_c$Owu;cI$djESKt2tsbRevnkHS7+>=zUT?1Y24Bg;{)K9E%aReT zq-U_r(Q=tZM67Nkg*e3iIy}Pt31zy7>*}!w=S7qCh=w=gg3>tqgx3N#x>$eO!A6;@ z7&?ATcs!TBS*?v+NM~#b!q`ri%%-A@Z1)3TY|3%MeRzs*!x*-|1p-G4FoxlMTXpYF z8iMOX*AbSo!RE3NyVPbGP=TUrATF@bc%qtA z8=Qi=PDeQwV73??7Cd>-hX6f&eJo^06}Kuc;!;y{nas;48b&3BT6%j{@tAKV3IV2S zg@Geafy*Gis^>#>zkr3GC!GzuGq>UnKglVrJ#p#s-^F6;K|nyfCFh5UZF4CdF3yi& zf~o=r3E1uMz~q~z@6g3943A3rc)qFf%Y)m8v=voyrlt~4i}C%Z>S=%M;BbdWY+oay^33+^-m%ka2YY9jn> z@X|7E7GWm}4LyAb13vm#GKPX>36ogWz#t{LmL>WYHV)m8TS*KH!Lwy_1LRVKJPwgJ##Cv%BR&T|(V+IK5aFXdT z!()Kf-SRDh9QReFc?J+8a*I4AR_t?7pIi%8IFv4CHZu6>?0ym~EIL_2@QH#PiV`7M zRwAWp7~{HTuUfRQM!H(J7VkA{H#W%|1W)C&5QQiEE$0YI2c+1i1Dy!lgz{FN|CD!x>v94(mooV(#PxP$X$^$Jz{Ag zLr4fCFQ{wkSaB||legIMcLmg)GU^=nNt%3enjCq!!Eq(2Oi%7}_J1KS=%5z{%8#;F zSD5tIw-W;}g;{>IdARVIK892jm;Ys z%A};kNXdV{Dxr6q_SLV+k)iF6u-1O6wy7qXyw=|K?*0DSd{E90pacrCzKl+y%-4bo z=^0ouD-Vs??WC}8as!je+`eUw8^XNI&AWWXjy?NS{XGk;%{y+rvh!-isu-TzKiR@2 zN5QoINhdJa4^%?Ml*!R_g;XTy{w>B@0LSO-R^Lw0rs9CpQ)isGN%kPE@3;Q;a&3Ab6#pBGOn3)L$ z=+aOgMEXi>>i%-gAyQ|$pl~?{U`$Cf4F#Yc4eh$bicHDz`9quL9yLRoOhm{O^;a;` z0{(7u>-`NO>)<1pWr2L>jU&c)Re;aV3$d)!#r=+`Z>5 zi>tB0+4?4^p^RRIdzF@d|S*?VnJuL{9&7k0kSUd&p@L)umk!N`O)g`@9yJ2t{vxVCxg^?gdOTp zo&o?OCzbh?6t6hF>a%Jv(u#~up7b5fjZh`&1RGp# zOS|we;Hve%oVzxqBkS)_Ni-BIi;oA4>T} zwIdah^>ZTzRx)MoGb0b2v%RLVHaT8TyPa91{1OEy&>Kz>=<0{dSxLkCq`yd!7@=N& zV(x$rw!dxOo3}CSpR+{`Lfh584s`7{ErcB5!g&I#Nl(f@Uh^@RmKOh2zx3PXd-Bk! z&JJW32?OzoZ26ku0>6FD5=dRY=z$Jz=5`VTbUL*~6Ynj|XlB7Bs%5=?3`N&&3Q*iO zw#S_as-X9I3{NOS$Z^9{bf;Iw&82m?%xK6IC+l9~0agpiQOok&R(g#mOr?tet)`N$YrXuj_9DlnP4fgE^x2{K3mK)fxmH3At> zjH!OiZWKhO{!XL#s97d%r8i->vT4!i?GxLOCqtWMkTUag?8EW}y4o;jkC^(>;iY4D zz!8oDFeYiY;eza3sU>zC{8-c=6rA`cEfO3g7fehjZ=;EkJDkB7L1s!y-}59Z+lGfZ z+5s7U$uR9qHy{cTVFfR TAC-{;ARlE#4TTyxtMLB=kPLp6 delta 5262 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 T&rHq-054rFgIiS^cG&*|1f>WZ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 769d8ac9a381d3d2692e00bb1caf3a20998d5e65..157a78e440f8c3b1571da897048600916bee4297 100644 GIT binary patch delta 15020 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 From 6afa23a62e4c70a8e35fb011733be1b7715dbaad Mon Sep 17 00:00:00 2001 From: Jeremy Liberman Date: Thu, 28 Nov 2013 03:42:11 -0600 Subject: [PATCH 18/18] Adds tofurkey and stuffing food items --- code/modules/food/recipes_microwave.dm | 17 ++++++++++++++++- .../reagent_containers/food/snacks.dm | 18 ++++++++++++++++++ icons/obj/food.dmi | Bin 87357 -> 89145 bytes 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index ec4ccf50f5..a297cb6183 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -1142,4 +1142,19 @@ I said no! /datum/recipe/cracker reagents = list("flour" = 5, "sodiumchloride" = 1) - result = /obj/item/weapon/reagent_containers/food/snacks/cracker \ No newline at end of file + result = /obj/item/weapon/reagent_containers/food/snacks/cracker + +/datum/recipe/stuffing + reagents = list("water" = 5, "sodiumchloride" = 1, "blackpepper" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/stuffing + +/datum/recipe/tofurkey + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/stuffing, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tofurkey diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 771d49a2da..5d22bdf8a0 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -542,6 +542,24 @@ reagents.add_reagent("nutriment", 3) src.bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/tofurkey + name = "Tofurkey" + desc = "A fake turkey made from tofu." + icon_state = "tofurkey" + New() + ..() + reagents.add_reagent("nutriment", 12) + reagents.add_reagent("stoxin", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/stuffing + name = "Stuffing" + desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" + icon_state = "stuffing" + New() + ..() + reagents.add_reagent("nutriment", 3) + bitesize = 1 /obj/item/weapon/reagent_containers/food/snacks/carpmeat name = "carp fillet" diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index 9c31373db126b801d15789e4852f3b8edcdaecab..96f50c2df305d580d744a8098e74a257006251d3 100644 GIT binary patch delta 17203 zcmYIPWmptpyI#7x1?iOTl9Z4x1*E%6QmLW4yHiRU1f{zh>F$=0TG)j>_zuX=B=uWMu zB%E|z4j}vYZKpG1AL~FQBw&6J57_b8pYyz?FA9+CCx~&amrnH0`9IEg7aQj_6p)em z-&7@<`%e?k`_j9lzuMOfKh;_SjX-1Dt5n*2e+f6)h3*PUMoU%06)Y8|1r9-g`2n#( zTeH%+b?No+Cxz-xq=DO(#8L%265h$f&PFVTHqQ!X+k^QZfhb>p1sJ9LMfyVW5spp> z+14+r49(Q&uvGY_Y1h_UEF>&&lz2ymMI~c6^<4szbbaH%?;E|5GPsmierNV}3=^Nm z$DatBlk{HiZPO_md5sK|*?!|A0~T?!k-vgLu20e~JC97z{tkqe`*Q#CAV07CUz?KW zUI`Ec{%=(K^0*%SZ*V93{3jhOB)rL&r@~{;vO5wb75fcz=tdrgD*%gPz{F=T5F#JM zK8LBkJ^LAHG&(tIB)jF+Vnc}kYk!%xHH0ss9~rhL9e0l){H?=L%lgc7z>bX-d!qEw z-%K~FSaHM{PR(=O!%owSWQr8uE3_jdUNZ5yfwE-;#+s4G;6kz^9tN-v@#fDlp@W@= zE&7Qn6L}A=qNk-yYNax!4s_awwz3t;kp%eM)OgI&Z=c6Qu_pXDQE0|I3o;$k6hA(C zbIoJ+tI?v=G~v+p#+c6&0W@yZ`P9F$DilMfQB;Fgp6Kt?gHR^_elkx0qBy{k7T<$; zZtcxe>rM9#@M0*LHE3gUZ4= z&IkIS-u&N780TMi6yKSgVZjFKbyAeAu>4J`D;;;i$tX2mI%x>iFR_|!><|8mFQ1rH z>pnyS{e}Vs(;xTU0?84l>#2WtlApHu_W4;C=`@2Gba#C(hwtH#5Pf(mpR|83c=o&vh}#;nhFv{el58}NIsK->3bK%-&l$Ja}} z+!CUbg8V)cssN9)U)dN8ZC`c+I06+dec-4n(B11k4svs~zpYrypWpb5YESg0n>g@8 ziP>wV8#rDTtqONnxY-Zei;{`+=+mVs$^?rmU5ElMxKsgwPY;s;`#MHT#GmT_E;F7i z3Pc4fUb%1f%A5evGujjdQ0Y{D*91h$xU^549P_#56=~^ZeN) z{;Pz7kaE=VYe)yJCn7+)+QJ~}4-nS3#A~R-renH4Z z)`WlBD9w>nIbVkhfz7f|kX7_MWZLa1*i+0{Yk*tqaU%T3#h=cwHGluB9a#yA6t^wK z6~VE3>`-{X#VI0M2eYGWi#^N=c#Ho7v^M;1PxEm#mzRSKj1wGt?kpwP(6zcY{M>m{ zWnc0fxVH6dx5%9NP?Q>%++UfvL}kY6PN~K~(Ms&vxKP&l@Nuw|_nx3&P9P3OcQyZf zy{HCJGj{TV!C!sRw=@tScLIT^K?*WbAHL+A<$eurK>FE$1gA#^Y|7-qVAgSrwzH7Z z6e9}ueR0{hlAlNji3TuqbUqvQc%Kz(2=U4Hg;W2t$-9b~$_cDG5?Hv31=3qb6~D>(z7@yDV*>j0zgC z^r-rE7;XgIe{Hfy3fOrk(URhW?~7*a4V^{ouEFeXu4O_aiMhP+G?w+yPQNdStsaLh zZ(rX%rk8iM84o`oz zcp;{^Rz*fg^;n@J=I7N;1O)iWP8e|Y<`;>u(n<4icto94r3f_dIN{5MNE+U;Nv&8J zYq)ih26-G~h&s-vsX>Z1pYQ3njq5FtvIQK?p1hI9(t45@euB``*a?zxUIuJM z(9I;Fl-ept!(&vQQBMy_nx>d1vZ7 zS{*qh?j7LOf8~E*NszcPm9;E5l<+R7AgYPmUM8maCor?5o^FZj^Ng>r%7khgSp&JU zvf0|rf?wbOV=UiG>>aIV3s!}HvW*+@qd5_fawT}E=rUNCL1iv5wMN$P7fHD)+ygcs zq5>cCPNL%nXr3!7xC1hfjxdxP2Sw8$c5jXG0pkSafDrn#fAOq$h3m7}c{D@+e(WXE ztydS5LpHKNUOinduC$;QB+IylL^N*7)4Nm}m-AcE=q~Uxg5)^zi=9dRZ;od666n5| z!y|7N2k^qM`pOUrKCoP*Cr9T@<#M%|bv!kN7_C@`rx>bHjN)-PyW?yo=FBr6EIkV>~WZDV@0TP*bvW zLs06WyHO%f(6?>)V~=Q- ziq+i=D*Uk?*mE?H@^Q+fewm^J@?*@|Gop3-Z|0As)eFSw@AJC;LcR4s$HblGnC(1j zoa1;KcA*9{+3n*Ps;tM{N)=ly#eC(|4hid!kR~h%Tvj@WOG41gsU3GbZ(Y6VL-@2& z4C+_Oo2lGQaUlkbho0|=_(jv?Lu?FYpKXuSrFWud@&I1)X<*0t2ndJexrm+d{7 zB59AfuC*W@k}DJn%gI}goSY@g=5F${=(FCSvf|e}ICT~yNzEx;r}=!CFH3w$J~+US zLF1_A&$S3bLgDJ(?T9iz=W+ct%TiZuj_p zltvN5Yg+Mi`b#`~Li!-!xYbE6Gm~xuHAV7qT*Sr4-!uP~H;|vndPX(^1c$dOvK(`mukGkf-f0YJV@z%18J%&l_e|F2A%Uh@#}ePmyr&rkfI? z&)vt*Ge|p?weJvcpm%ac53BMPHU2@;Pmno)b>oS5yFxh|Lc^eoT3d#(i*RiE2*sC?XwI%qCni)&JoL3v(E^a zM&GN%ZudtvV4or*bVk9T`LDIV&@EvReL|EiNo+>Eb6hzYCVbD>vrPD}ZnmC%l72sG zlwTvJ0L>jR67prL_&tC*5{UrFi#e5L++b5@!H*!`&=XL51UM<-^6&lZdSVA4tD8$d zY_-x?g=^!{)y?@{akKHD=2}XLc9^Y^w?`9i%9@x^$HvA|8s{!QPU@vQb~xfX>SQ7{ zOZ8+Yzt0dRpr@%3W!SLB`6Jhj5ELM^a85CS3onbpvh)~87xt)>JG2X2y?OEaVr&s7 zQlply?9^_XITtA^Huj)6Oe==TUq$i+GwY2WDo$97mO&`&CVM1@@`<>Gh6WL1XJ~V7 zPR8B+kl>3qfkZd90-jI<71F4Ms$hrg@NyK)UT2%rMikZ=C4svL=m_0ETO%@>ItnD8 z(m%hHSkDUVJ3H6q4dBTwWVzlQ_rck7-}R8FZ-A$OUW$)A5e?U*(q>cY43qgOvh-LZ zMP0=*F>r*=eSC7A=2hU68=|v{BsQA#g6-CiLAOxml6RM~XYXwR7P_q@G7zz|!5P>{ z0OslzzKhyr^JYPtd@(GJ+I&?44^cFA6N)N%xki@r_-qc+0}w^OvQmD=`$~u|*KvoB z3eWB-iV7b#X03UDYee}A#^_&vY3D?jI!J}>*50y_9p6o-B9J}iqW~4Fz9u@n0i0db z9w4*VUV?Dv9gj|A+38et$6@9CRqs=^eJEPi{lMpq2(I$)fqNLTG{nu((rjXm zQ%3?d7N~HBtLesu+qg!5{oT(h3lwEbZ?&zyYkzqg2L#4lD0}KPbD8!cj$85W@9)no zE}BEXS2N{wGmAA5DWckD*j`q&$3L)v5!o%y8 zSI!gI@o;l)=x}rX7PehyYUqsNa5QkcNpx-wgG0ws30e|L1Czjav|*U+t`;Mz(RLlT z@SL}s0YU>-uao7Em=(&2WhFe3d%T(8v}NGbogE0)XY*||0~heK0P6Cb+xRGIG@}d6FO6C=zB8qKSvK`$A2s`Q|6ZQ ztQKnw=jP_V5W?owCh!iz`)Lb6h-ObW4&`qLfR4q@_fIvL>8&KZYCtF0hXH_5P z>-=+z1&GHzJLDxU3aYA<9iTx$k^$Y+sDvhua6*!+r+gWC9GzuHZ1%y|5m%o@~Gz6k!spg5) zQ*f}B6Mh8*#V@v?w`j#=nxk0zT5C3F5@uSUzlse@Ng;fR8Q~~S@ToCz9dw0s)RS|- z*Nh30OoB&wo~51A2|hb>sM3DvlBX)Zvjawe(_eA~{I2#tP&ddWbiEda0t5wRoc!>2 zIC&qJKkU&SuN+mv(=}JmF*`f17iwQl6m-AXCHTJLnXzYusTb$ZjpOr5*x*q%nw37{;~41 z-DBoicnjAZ1@lFWkOo#}Wwyqz#@9CyCBG{1&bQ6hqgU%Xuya5TPBrtzG1Sh)U0xlo zf*|lO{XfGh)~nt7oiRpN2>p_#fMnK<4)|`YfAdxp{{GCwd1k>MzyolZE~{6Y)qi>3 z5;-#DYeFN#e*F?k_nzD_HZT}(s;rI^C@$N{!S$Z?e! zB(+5~B{9NJlY8$Euv!zM$Fp|?>*(mdCnZM?ES8bNQv8g{%Ks1--usI>HI$(Vqv?m^ zE(?0xq6KNR$}xc^eiOw@J2ayBvoBXEFsW5D2*v6ELaX7<7^Jil*!;Eq1x7 z0WWU-&bDLmZ4|0Wn{4)a41dxxi6ufgib4AHf(w(i{ns~{!yb}~-D$U4kM9>r)yU~t^RIaV(dB*(C{Ce2M5JM@LlVi@XZUy=Vc@k|~G*&$I z(vjx@t=~c!{_W(!50-9lHg6MT6Gm~QaHl8V6O7ScIh`(}O8)k*zakkEU6}d)RJWvu z3$m}As0S{n$XUIg*4cgDOzi6&sazQMieYTAAWSdEJU@H?iihNY)Vz@0<<*?g4AMK* zNyTU*A}+b)KdIjwsh$d^915jXezzZHu{%l@{g!c0UQ)-QRc{m|z;EgRMKKaQ9y0T)}1{EYSYXB?dyTO7R~`3)Ksr}72b zm270_PimoJQ*fkP;B^{9RFT}tUGK)_wX$AO!WZkpMoPNej<-dl+f&dk>7hxc38T&X z=?(p3r$E8di#6dyNFG$CQiTzHZ+>l$#}TPW>nKwe?*8uch;wYm1CE|;0ZqNGHW6T} z1FTf#Zx`n>G36fyBE669g15mt3y|#o@tO2@Bkq84Abj8@2BW#HW8sx#+K`AyD1M`f z{LF$XvNF}w-9;z)4;%+qf8qe!g)g4I*P9%t`LRroU$Y38)`NpYc#*|2QIDKJ?IoO8 z0W!c3;5BAJrna;7C#4e0$oDQ1U^Sv255ndZxnH--zdI=!r8PWZC#@?oCEIeF< zN!DNe(U8`mg-z5LgeM?ygh_gP$bZN9!tfj|$U)rsuo`c;@bzB*wU>d@c{31KyMt2% z_lt{bRJLwHfV?z@ExkfDtiqhzibB5lLs4E1JoDRydP)mOC*$K5wG(45Nvh7j0@7BDHh@oA~8k9-?N1KQWy`)e;r$=hY`_0>lx zLw{kw81qVYV7_#uX#*JM^fo2d-xYoE-7+a-89aP*pRg{HPnm}U5UysHk#(?iA7|Kx z+yut4%2AQ@+I`MDIyL}}fIvo>0pIODcP0ldBT62k{W0c#hbstV{gOIyOb8(JropVd}VC&c;j{n%SyqT}F< zH=_o~Y>dDDHg-M^a+vy2d0Wtq% z9M|IV=~cmh)-lRmbmSnif09WP;Q+GukAzV-z$GO96SAOTWXXTG0pzSuY5)I9?*g3v zd@N^Go|N2PV@w&k{<`=&jnx8yn(m+Qg7#wk)ZVM=ZC!g_JX@8HK}3yKFMJ#p(EbJo z{P!Wq0f8q^O2cIT`}9Cba!Hw^VO5>7Dg&9jMtzZXwNEXm-Ilq$KIh)y#(<$Yjn7qs z>b>DdPhEe)y8mh-nZSD|X1bU0HMgd=_N|JGMbWO`c!NSpwS=3LQOV1}OW z;3WKoh*I3{(*Pi{OgGGleGlpRiX!a&5{8m*&65&LKx!3Jds6+kKJYPumLOKS5EMx3~2Dx{nH9f$We+qiqfh2tU6vyM0obYt$W!O(Osew?pb$s;k z+)_WE!DQqLj%y5T2y z9t12`amVeaKi9{iT;xr$`WT)Lhe;k7&|6-6gGSR}c%|&_DfyTf1x}kBB!%h!5E=^# z@yg8plIlNUw2-L_{59>v93D{8C2Z59X1`H$ySLfn$r3Sy#ThLs$Q?S@s(SikX&e>p zw>kv?o&RL(9>qCMyyLG-R)_rW-5B`N7tzjpCEiZlQki~vm15y1Z8_<(lcX0C0G+$u zX-f<-#)pQ?BvYI!GZKKBny7Gvefb18xw1x+D25)%jo#yd#ElZynet^7tdi7M%skuU zZ`~Ym!qkQ(IK|yE;jAv4GCa7at>9M@WPr66FHW?sl*ja8f6wT5N20qqnTWssnJzB` zxIkNMfIWP3RteyG)R59x-@|>DE5-vgt%s;o$U6!OpFE<-!8^)PzXi!oUO&x}%CI{V zy^0MaOw}=e!%6=0fZ+2t~-=NFJgXPpco+4?K7-+etZ6_Z~gdfD6JUqF!L)u6p0JN*MaIMkYO-f(bHf*Kq z)E?-d2xw`0E?qr;pUQWwNX~8+xIgml95x)On!#f`zsy;Od zr7QAWzGJp+EF)(>8>>2q$)^d0)v(lOCj_ZS~{DqgQ|p zwedf-n*NU&YFgJF&R#GS12K9Es`q zhB%q3Exh&Ja?VCe@}BCB{)g~#wo!)n#$G$)S47L5Ac~ewK{UngP4!u^{GeDLP}iP306R0;jS@n0rXEUfM2kHw;MpUzBj3}UXhq~rM>%6seIUt(L(Grl)-M>&*SBYJ=8xErV8 z038eijxpJ~3@2KFmFY0)$u^You0w2r=Q9-X74zM}=sBqCBui0Edw5h7`l#aHWkbgE z-`S^ijbJ)2hrwoU0(kfGTB_JT`+sorL+Xy5MxV2XL-{$)AZpkrr}D|7)}L#41GWWWpu>%nRTc&0~&Yx^Od=GGz%?9e?-Lwk9iQbIG`#jDn_q; zB?FeO`AIP)FJijwEq9il(-yZUGw%M5sJc<-$ii}Yblo|jjHT9OAk&*->EU77xeEZm zX{#q}+9;9qk>u~s3g2Sf)SJ}z1R-@yf%g2bN#Lk&>y0(Mn90rk(F*T5K1Ukg%-M&? z54r6@)+x%_X{4y4<~K$SyVjSOV1NU=={xryDK1GVcU?~xg2XaFe7F24BtBYIbY zYz856RT)g7|34!-WQP@>TbXOXB=)(FFV$KvWJe$`0)*81ye(?=F71 zSenvK3|Y$0AFU2r+DY+EXQNJt5h4_m4T37 z&k{ivfXI+$hmoq{A40CD{-)m)q@=|5KJty2WUs8*r!V+?*`Fi!zZKkr>e5~x{}pwO z1GcZ$i?$YX0_#k13xXLNPa(a&dd$s?HFZ?HgpfCsp zuzI!ZdmWOrQ%W520AF0%3kws&>aI4H_#*`1PTkjJ3D1#Fw41I1Ls>^?*w?t^uVwqO z)Vzsc4!>W_pjF#h>2YrBfAmNOH?4x)-8szR&IC1P&&KRdJ;iBBXNvaZP(@3iRzD?pi3Hia^gj8Vy2-V>fS->*k@T~mOp9TYq0%+=G| zLK70B%kS&8%!~mG5?ve_S#`+oaNJB~=-Jm4YYAz|ZH1Q(qsO*Su?|7l|5OlVM*@pL zEzi|wMMOclUkX@$VP87o43&i}_3sO!BTc}!=~_P>Nn}O6@P*Cj1(LZ+PaXF1hb{N2 z=ohyGgcyMEW~j{Qkp{==!!z0s0DJO+&Nfom**sdW`ki%#{0fEHk(;0-ln%vokinB}{tsEeD5Jzq zk)v*w-oU<)=zyi7Yg}`|eK@uKAwihv?gt~9tKY!ZosRWRZE%nnE+NC*)$Y{2tZ?3lR7}=*UCylwjC!3b?q62ZQ06t)JnPm4bSGL#Xl!kDHDW zfpajHfdJ0x*lG)-18M$~XW-)1>q9DdjcXY?x9gtJ>C#j+X5xl4&X=T7oIvF288a0v zuOX30{ef43LqV1?jON^KRg`9_+6Yy#4XPDAGPmC%?vqf?diUi!2b39tgdWF zb+IMgqe(160(s6BS@Ps5J>4sh=4c!Q2obzyFD><kM!e~^C8Nrh3D!5+!!3R7Ov>|>kyQ?4@3zRxPxSF2z~BS zIoyI=V(vmTfbL2qcrr!Mh#IjZPTo{ea+*Zl?TntCq2?(U}4G zKeFu;m5qpM4-^@*nV#xw{vF@toHj5B6nGQ%m_vbY9liw7vje(pM)*M4HXB zH*tN8I=JC|V(!t%mifPoBLBkZ&vP!NWh?bf(#K@=Z{L8-R^(_^Uk7g? zO4upsF;^0gNka?aBbtuL?ksAi7CUcVzy0;_>84NS3Srn>WRO&>wz=dH<4#htiunt5 zX)mj1#4^Y{Ca>jLv|mPRScF>e}Oi1@OEyU<`!eOxfae5WGIGKC-Ks^6OxnrfDkl-h`6}(IYf5`D0Nhq zY8f3bZ!)2#w{Jm(*m4s@d#e_Toa^piX1TOlI@|6?059NH-0WJBZtJ}*CEO{_`6 z@BL9s_Unt1l+LU;#)8I;u8*%{2er>LSPLB4@q8}V_O7oooHi9UBshswBpr#r8AO%x z#Mf@TOst`40MNo>Fb=r@W=X^SZjZ*)ru;@R!1NMTsZjtqc0kuA~ZpSVp~-~<9dLV^K2?MvztEcK*U_rP(&$!ew&HhzGh z7n2@LX>GfM5w(77ADY3!s}PmflQ{kqqYzbAScM35lq8Z}*Ay@d=KqcQjc7Occ^&#? z!yhI#TQpS2TtP$cE!4Ut3H{xl_iLH?l}>6izWpc5_0T<8p*z|4FOmJ(5%LDhZT+eUDmB-oG|s1$kL2gYX@QX@#?3OzXCQBISC-{nEWzTBM?b)GJ723&jC?>}3d z`XDM(4nR*!3(G6RzL|=}G4V^H@c7emDfW<=K6%SrcH^e$X?(JVv z@uPwN!_*AxhYu->#rC!(%{6h;3F`hUZOip)#;>|3Q6nO0-&m0nSz2$^3AIn#@Zgm% z5|l3nqZKi#6&0OfTE~?t0Wd}*w>P!ZFT*e0^;aT;ulb7|2%g9F2z09T!}fJJHMLB? zo&6oESocB6Huj0>duVA_O)hpCnF9^m?D#chts)h!&eaMUSb*E$w~8t{R^vJQACFNn zxJ^l9IxtW}GkGOejC zwfpPAI>H$ipI@N1>*Mnb*ywj2`fu(SyIvwl$49^S1c8Xa|EBJ~{g9Gy8|lGm=Yeao ztohl-@=+u{=pv>Am|rt(o6eY1J@xS*H+dmq`%u5UGe+wQxpoYQcXV`~?_BILaD)8a zXz`#}VVy)f8gUG0t{m?jk%%Pe`KH9lcr)7dZvH;y{CPYPEy1OWp!;iwA=&%0fknxF z1G}!)_&!lD1g?X6-#O!x_DAK0-wmN?1dKv4I`7^gRO>rg0JF@Z0-|SA;9{+wb555DP5Oa z)F8}QLQ30yHXGDmFL z5NA*Z-!7wj8la~Z-03TwN;R-FJ412k5Rwnp#8%{xqb zIxE8nB)2|jpk4E1P1ln6d=9qVNfi{r30&FCn8?Uv1Qf4n-lGs%)$s=!f|`g^6xCS^ zOC3Kn)WBV8;d>d&)rLuy*sI$NOXAI)dk4|V;5n7Q@h~u++@HKTSRqHhDxrCS$(f-) zIw?!lP}zx3zF#l%@27EugWlfWF}z^u)???lVws@)d<1GTxZKI>z|4sQaUy@~f2VHb zpl|>-YAre%Z!N>!HJO=nTM@b@hX*NKKtnFfb^Ow6kmhj<*T2C_3DX?iA`U2U}TcdkzH!tm&4~LviR6s2AMy(vrsj*G!cn*)_Y)lMivX@PmOa2fPSxo zvZs+Cbh_4Z)RSxvaCl_f5B;p}0=jW0I-vNy{NM&HK7L=z;rA+|A$RA1Z#u^01^Jz@ zQZ>ZOwm|?*XA;sPk1)Naeld*Pet$f)CVp@)7Ugv)QHpAISG=Gh;JDm~P3Pj!9!G^> znyGhjbiDY@5G9w`L^;Mp*3ouukGI?tB}&HoaYd8ihLgL#tZ`^jD-D;7kX8oF>;l= zAeyRkqy`kh{b)j=RYDg)LvOqJy+*qHc6+o4+SbN4(ekzH%`W2W2sGLbRB)rH9+ht=9(Gk`_P~uT{Vd z7N+UK0a~k8%gTJHABjWMp0;#AA|F@Y7E4 zImb>mAQAMgAGMRf|FSpZ308|K`pE0S0c)Xcjc7p|cXwhm|K(*eY1Gv6rx(qCz^yNS z?j|0s*#u(B7q5yf$xF!j(S3-u`4oFv)h}vv>b+11FuCe74KqqIT322C?74ZRlwDpblG6!vmAO8CU9wDSEK z_yB=zZ#E>@=XS-@Hw&rv5U*Fcc>7Pct^Q*BwZ@B_LxfFl6^BPhY0Y%{0}O_GF#K^t z4m4kRt}(-?MskudUm;L)&uMl8e{qLfRBXqoLYEqtCP%GFo8Iar^i$@jbo1(>=k;q| zQWd2cGu&7+Qj5?jW;BmO9*^1R9ye~Kjk8`r>EZ}lc6O{;Tmk2e@qtv5{L~96eE$g9 zZ7QY9AgU0~**|`io6X=`@ng~-&CNyYfAt?=2BiqWlORmXJ(>i!=-CWF0-eVEP+bw0 z1-j=3a0g%x1i5$&ToXSXOI3nzEd9*kU$_kP=!>t&0Y855{d>;NK=jDysM*!d0I2ss zu)i=d`VZ?P6!H&bV}m}pg9xANe=NL~CE}qhY)J|IZ5H_QBF$7s$>1b#c<4Z&7S8&HRN0?KJt3+}NHl2M{R*3%KwtqALeL8wt4i5k1+yjGg}^d>i@V z)bLBCOwh4k8_lIgp^u~v-t2D($E4G~-Vn?Z`a_m2?=i;QP)Z6enuN2opg?jQ{zpAH z&zhNyqoA%xl396khxsCsx^2jqRD8W&)rP|(qN`V8L8J5X@HdN&%JD~E1!!<^IL*?I zdifi5$N*5FoqBcNS*z<|N$)=@Gq>Wp@pR=g7&3@U?vGbKwgmpIU6cP|Z2Vhgy@rgI z7Jpa(=;USCEB`+FffM~%1mM%d@-ljmHw&LCzPWxU6Z>6K>C;^RD`kQ&%+@GI2Vd-H+-?zgF*2%A3g%U>I0 z$5z4+b2gR6#H8>yz_vS6`Es(dcvR_3H{9c-d#!^iz`5E2n8|_bcuU>r@)@aR*=*G>1K2+;YSdH5G_p4P) zAJ)p3kfK1h_RDbWnzG9LpLj~cbYI220!)5kb=i-9IJ0NGOF;U~_S#YbkB<^h{j7$T z;Z0xz4-j=0iSb;owuK6kqYn{IYpUOUoI`w1@C-`N>+*SoIbfr_--R7JjZK~=b@@{Qrt8I^ zD&rax;SHvxf2o#qshTg+XSsg-yG+<0DuhAIR!~p?!o>=(Kn5L*XYT68#Vb*ZbHJ5O zZe35U+!;4(A1Q{c@9LwA!^zbD)VJ%_+&y{-wgKhvg1#qQ1%O%YXR1*m^SyJ`u1Yq# z6cZII|I#bU^1PYwf4!R;ppadfbWAmk!UH))%guYoW@o z#4-F#SaAHnJd4U%gKHW;&3@*ev*pM``CfVY=_}cPWp}d@goX5;@$vyq zRtL8Pb+C;vOGCVg5Q3(<#81}Lmy6~PcP)Jsf_*S0ez)aWR&JsXMSxI7fL!s_v5>_h z)$P&lPZn1;gnM&Ige3p_fSe$zFO!efMOa6jaRizxR9kzA$uaLyi^~hbxC!VeE+B6R zwiKZ2>A9QvvCFUxm*0z1*GI*FcDfvLyZ`QQI0J8L6Tr5Ab~ta(z0Q_;a)jLsLa1C) zytEk|fm?pT>j!Hp*MHYU6LiGCT$4KlDHKDXPHjs+W@@o=Y>&m+s=ewnn~f!g>7 z7j9))(pE6PoggTH1&$*FWlugpB=JnGi^lTggL<&pV;B5dxMV0bexvIX8Q zh>qLBwp=@I?`I`{T^R+Ngr*>v$0yT3%l(Hp^w8Djd!& zAyksfX((FUxe+o|(!2{LDt`_U0~5r4MUTeTo@ zub_1Jb`rSo9n0qqE)wYO32n&bz}>7yTLc3)d+LJtnCYIiF? zD$e=ajZf?&B3YU@h6Tbt>p3EyEx7B2a1mzF=>k=7<@{7;yz;Xr_u`D^q;Rct8P$PH zdP*A91-Duz+^;m=+VKfn9QW4yasu|9LFiZ3;DHOY z>0`!(sSWfMS2mUne-ml8J1J%=A3rhyuDVPz3t>kMdNM;o8ZrBulGhTsSypbWVFBoR zR_1M-w;$bZ4B1@FF{N?-g#rRFLP6`5J15aNNm3WzPa3E*QXph{Uz?1 zHs$%3Me91%^zMZ*58QK)8)+i0+)E!74!^&t0Jq(r7pKW%Op*ok$dv8C8s%4+P{IF! zJN^&tm^T7H31UmBMgrZt4L6ki4KI6tJVHFBcOO|Ux^4w7*8HX`FNU;y4@oz6+SA-U_Ki3H zLK^W0^txu5!r!T;4cOO@zn-2vblJ7FtMvwWVGztp9f?1>_W<e?_DDrWb;0=2Z=$5trtNQ?CL5$qUjg&oxY zz$H_+(?$f}y)w4&CMR8NKD86}ePzw*{`BpK>G}JM`OfBAJoEd6mmMCV4=cc_-0rTC ze-9PYsIM^qX#VXrfWhlDj)5)`HWgo~`fYZNkkBy97gX|4mxPd}besIU;%oR*gYy{r z&h?TF6eZt|E(t3w1mr%lm;=+Jx%~{bLNG+o%oaCbZ4x^~ElPqAm zpkhwI!h|Q%F+#C|x*LW`tQ5jo7B^!fQ#`N!!2pQa*uv@V2@a2p!1Su{y3r+mQ!-l7 zAGhv=uqCs=ZDwX(ucr@Ee?x@YTVQ8rNs5RJLgsi;-Gj=C>6Z7f4>yAT?)*ZO0El$E zh2+maS`TdGc9A^lLm7~xkCblG!AkFG-@XyfJJ#Y=M^uru87_dsebs+|`!(N(jpP-N z5RjlTR?#kvqYpc6rDHI;cPglR9`r8Z%Fyv+&bE%yY6%vXl+A#yM5o5e~Pev|`fP@4^ zQsXmseWFGTRr+9;1T^5~yj=ePoFee!)r=5nP>`(y&+M$(=QE|cF=UfEZe~mnraJnU zgwHiNf$oeqteyHa?$+>=^A|9ONSH}+*MPCv3#5*IRwrs+4ch#X>V5BB?-yFsMs^>} z-Z`sQFtes?Gfb8h!+iv0wQUY7x~&{=z>=zT?6$*}uB<3qrY(I!fYwS?F9A^nip8nH z-SjD=exxe!$cDlPX{7maJx(NF+@8F(Yd^h9o-gR)rW&vpcb&- z)eGa~&aZ+_{{s{ea|2jn-G>+UYm+V)Pi?QIJI4nTjesDjASEH)CEbFwAl;qP9S4=}5NS#22Bo<)N+Td8-Q9438{hT+ zJm34ScP|!q)>(7TnX~tvJ+tSxTU#(YD=?E7!G6h1j6l{8Y_mm-a4kmvFwEB*aeHa< zAAb9ZKU_&T+a5FHTnPu&e^_;cGR4T<&mw9ykbgrK09a6ayIp0WKhOvu53f%gpRD#G zY>_9&Cv0`91-Zzwc*;}P8*U29p`X{=C&RI`@G->LiKD=qAOyVkoe9IPPe$A;-+i7@ zp?dFDpht=CXTX?e;Pk+W^tjX4B_mDaJSvB*CU0Jf;;Yfb z7D43$rvpLS*fxe+?RnHI@(F3pFWOYNQc9CAfUVxRd4at?SGqZF47(bjcjB*DQefgi zB-_02ZRP{@76Q~Nr6qT-g}^GTQN--^pP$H#KYH!T@Nid`9NZ{OtQ4)Ycpwm{ob&Kn z=ok6}-s8Vgl)>K?z+_x`y7?U#E*TvR!W27&^=6Tf0+SPPM{d>=x83ng7C5De_rOs# zKx#zbWnCFpawDaoR`|SNsMmphq@=&?PyDw7Xw0@Rf)tnn{Ub zt6f@`2^Wvvy4+-tHM&^EC+)+baRn1miT!svoU0OogrBLOO&Ta$@-Ug0*BtH5-+Jg= z9AS$#a4(iQm=TufhC&@SepX-0$Y9U-TTadt!U$^MnBn0BGIPhbBX51+L)_W4aU$Gp)*IX&*Z3Q$NneFDBjVZ+R8U3tSh>Ti?}s&NTdcFTo0?ObA`q`t1tLCBCTf)f;3m$Rp zsH<(W-1huhX12saQ1WgsB!MIo(6RF*2))1){L!z)?@ zu;O#n7$+Cw{aBScgCGqkPt1Gq^mniL`5(N(Rkdi!8wH;s-WoS>+vZa}9=Gpq)yenX z+Z%k&85f_ic8Rr!S;P-goUG88eRj#HgdR4E=gaJ;Nd=CyuxCiJndw{|0eyGLbWv^X zQY`De!ujv*)z>|o+vaDQ??)J{bB!EoFz_A6`7^}nNmiTw4E~T^p;nt`h+zi*;MAU6 zoZRov8P?(xAnMGwU%lqkUAy9QQ~jhPjK^cYc)+w_LSbK!vqO2WciR1zt^few_ov6D z6x^m)eKOzV-&+SaqAh8%+M?}7w8U8KNhq8@HQe%gVGnLej_m(_(=0||jCV$hMYX*8 z@x3+B+?osz-dC7Ygrm3iz-MdtJ%;S6y*}ES=9VCcmhvzCxYj4XYucVNA!lHE4;p5Y zCsH9@%W!NQYq>X-4$F$4>M@(^F~N4v02+m~6QqW(sB&pzq%+1(EPDDQBBCc4GT5YK z*uu|+XV}Y%;-s#pw01W@0Qap;a_iaDpqn8ld`d0DAe|NaHqi^&hcCsuYt^= zOvKfy(h`E6jxyXTuLBP)G-BsQcje(gB@$Bkoyr!Ep${D-qHR2O&L>1P z>enRr!M6i`UQbM`5Tx>!>~LQ$2#*=Mn__mNIP)Q~J<8mEWQpfhieavpznxXI`WU^P z*yq{4>$zTE?6w65ss0HmDwP?;bB~b$D1TAG3~pk7-7AD}y?nCV`=PrD0LK2g##0<& zE>DbTJ=Xr^P)_&9>gg*^vR#FM101Q(?hK9#{xoMevV)cY+DP6-WWHU zIMK)e>x=^Hk}Xc(bJ}iY20N}PPYgL_EjasX+oO9E&f!qOiR2$}xkh@h!+X%j(6d7= z0Sa|Gm+62ovqV0ZF|(;K;2|ks)iF|vP#ISA8Y?61l_eVExiBNG%~sX3e_Ag1+QsxE zMylJjG#jN}iqcA>r(|muy1QQ9cnaRf`dMLGV9nfDDoH=?j=i)YPd|E>tF*by>Z&1s ztRik1*UdVE1ha)*ZQ%g~?0UTy+rns+x;3QpKU}B?#m_>`6Q2N2gRtn#SGW{bY-9A;Eg{K%_<0a&m515mkBUVy?eCUK@upXxtbOLTJpCLWVV~;#IG(LR z^J05x(YGMfv5~;1U8$%3JLUepQ6)+SS5^`cV4_3bI0KhtbVoGR6+#?VDeC0ai4JSx z-wy`-xt{n2^0@DxxQtSgaoyf0;b!$?9$j~l3EBG#xYC4aG~SCxg~aQ9Km)EQ~fuvUg!M+(C$ zl}As?HRDK+Pk7X9IA;(cy>O@(1A!v6rAM()YJMuo#g)L(fMKNCy%tF7b`PM(1qcTs*z=g0-BEykXn1xkv*E1s*4=k25!Dh$PWjM%jT zHs-`%dm3f`ZPze%`^0guf@k~N@t}jGTf4OAE}h}|160DN%2=U2lFrrYuO|*+{1;x= z&Iq@*tcoAxx?yqddyUY(RIBY72;)EF#o-gK5o#oO?==cB(hejAk%lH~+lqMQ5WhKZ z_B}#2Ppe&Alz|8vn}Cgr0hmwQFI51>8HveAVty;*TgT-c?Y92eUKaiO!ptY6J`;-W zk=d{ku3Z>7NMM&Ti+5!dDh0v-v>|_hUkN zqXL^3l45zV&!mOSE}>7TF~hN~89?2>+)=f|E6tXz+Xr^;t}eZ=(esIb)hEhZt`DDA z6w}+{T|1uka$&*W*Bd)}7K?$3p$z1&NLN#y`2rJPYiqYIvcG7WEyifTRGDXrld_XF z4B(0~_ri>@FgNuamXn6} zJm$4f?zXGCLGqp&&arN8f#m+}v!xvuj}mD<+&9{8JuKW6{C2qD^ItwDfhkb-0aKA6 zFFfjvfaE2bWh?Hr`iQFFiPo{rLV}#<{(hrH=Yy^{eX4XeJ%5 z`!(yiWZ<3vnl2GWf4z^5z$r*1I0@#GH_Yp`x?fF`2&kRMQ)Ii6`tUv_I~NR2bd7Fq z7DgZt8RWqVebLC?mljyp->UI1Bk#1w!lh1+^)EJ7n8fHnfD8B@CPL~bS{%8H?M-eq zY<&j&dyjD1qG00^3#e2Mryidrj(AK_i4@wD=5s=4iA8!`D#`j;mW@U1c~GiTL$pc03Mb3vuKKEXG~9q$X+m0n&`}wC-s0f z#eWTPc-NQ0-kOPV5b|pDyoAz760LHk`Fmz3DlRXI25OZcseAagT{R|Fe`Dz1954he z|D5lL@8AB@+&qf&^AdcN7sABwylc5609Tnr#9g|I{TcZ6+0BjZZ)DK86$w6U(;i>| z)j|-WsMQcecXN~WvDWzZ)*!^V?LFbj%8JC`o(Dzf%o%4_@OJ}-xyeas=-ImEpv;}O zkN@gyw@aW|j@puuT*mJ%-Hg5SXpwQM=NQ{*M1ch?{k@O1qP~?L3+l(Q`(uZ8ZI0Bk zq=l#Fm~97dr?)4sc#!Zf>l#Ts)&qw0QZh4GRdYn16iq29E8_|Z3JL_RPLYhO_T1h- zmp(c#{caMgSkyBy(J@CwP99-e`%*$87aHf+9#+r{m8^f|vAj&sjwKl~bT=n<2McUN zAO(Z`CYI2ss9O+$y&gxauQz2n>4Xx(O)*2Qe8J8Eu5spSTfz{{(c|>^H6TuF0%g}n zMQrj@i5VXtGW6Y9njl9?QTb+jsp~dPal)1gtpKjVX?^tU_ z8hm-dZ#NEdyXNO~UPa_dj$zh0BSZ8B(<4(|s5Y{NjQawY9xu!wGHpP=ud>4jnrlm1 zTJ)V^FqkyROzMn`ZXfhKf74r(@mtL4ev4Pi+x1YzX@^JsR0sM&?IM@ns4x-!m9pn3 zbwTyBs=fa=79i&pM0Om*eM4_W=q#4v6qoicjAdA{{=BG=RDD<0g;}1P8F}fwBU=;2 z>-l#ru9i`f!8BF9ZEbyBCMZZ;u_&2itQiIeC>jqA++uEPy8SGLS?g7v35|+Zvjm@K zW@a`uHO+H&{pf%B?&#WX=)IdVEG6M`!e`^o$P`Hk1@3s&>O+is?Gy5Tep!v|m)HDa z#8`{x@ZPd|P<+O*=jL#gyjTb5oZKK?k5oUGvYH{mw|zl4P{_(sS<*48wBX>HLGtL^ z9T6pFD8#p}gBv(Cf8?nxLopl$vmip-&U`)JS~^){#bteG{<#?}iY|AdMQNv&WaiSd z(92Da`{Oe~5;L5vw^Rcy-L|tM#HAK{^3Rq!>bbijh0=K8nxOklQx2OU&=j&dme| z`kD8&p~bJ`+Yt$Pv5wYWPmn<>8(SBTiQHSZVoQW6ANFK@JQfkgivKycG1+ABX*1xg z_~C4qtoeNKz_xG@^TX*=Elv1_jm0-Uy%3hTXKxKORZBHhmj2|vK>9J=)?RP9Qc2NS z1I4peZr-qypQ@vuxiLb6&8micuQ-_1vaCD1(0j!`Z>r2e8cL5ZF1;$@E2t;1(4z5(pE5lG}Jpd^KHH; zmv40HNnU}3*^qY|V&%6#gTt@gXh&Xw|D53O#doa`x1hFXM8d;~YZfvdnP&RN&DTyU z4O`n6F>e~w=R~*FK_fS{bN4sGY_?$q!6k zg~`@)tfAD!BPJ_=E5U2?`D^WCy^*E)7l_G+X+&{Th^u$E4{)CD_b>Z-mu?yZ5-5&> zpv`k+fWUeCn+{52(xdMMrZww#U)pUNadFq7$ z2$itZIqd=gRZ>J6SB*lfbUUaG}P3M4F3E#l)eaW&{s2HvoFT`%GM`RyoJVV=` zB`)VOPla+XHL1?uC7K0RUG^jfyf-pG`kv6a0T32~TPB5PRO{khTm(vNGSs{;z6vEo zG;R9Xf8Q(VN2jdxHhi2bKW%{(ltNtoMtN6SZXjO}H0gj=6%DDRSzpp72L+5{h}@g! zcV&bkh>(chgQ8GKjVU`vi<>}Jemzdw%PEZbZF$Fvw6W?`o@JPWh!_OEax!DL5Qjz& zIL*E8xLon!GU3T|VlF01TU%|%nX^p+3M04^$G0MB2|eeiW23Tt8k9-#`1x=@ z57XBOxlBI|We~>VW4oyr8Ew_mK2XLLV48S4_;j(+PBRv1uIPXkKy}-!Xts-{gaxYm zh4EQ0>aug(0Uh**s^`R%lNTdKwN!zhRpQ4E|hbg?P9s0Lt-Lxo*hB_+c?(U6hJ&>j{mm)Q(1tH z`_ugNoI_I+ZVAnypOg1hD_4vV25^-QheYG#4z-eWMXM|!@76{ORmH*`>l zN)FCBek$#6DBY@ZpZGD7edNfP!`X)N4Zbt{l0!3_H7)hFqcQwRtv`NSj1kIK%J6DW zv|KjWuH+Zye6ew+a{yZmAej78T2M~#b@(nO08VJaaoW8{@a}3NxGnH=tsp~^w_(R? zq%kq@G)xM+s_>uiJ*~U;N9<;usgz+!EBq5196o3Wf#!d0g>S1`1feniWSB@^5XAPM z$Pvwg%Kj6486EWe|9K9E7Vv+2?jE3PYWgt~r3KlsyBH{U>^B`*Ln;dng-7wSFGm zZT9h}MQ*(XHG03fSw5HaHJw%6X#moePue@6b@wdh|9exC;0c4p)qMDJO)cw4pA@5E z2yK@K-@qZEw)Pin^B?0WXWkm1q*mu|#@w)k*k3{W=rFm$U+SwBE13WLRT(&hd4CmP z;FvjDW+@xb=H9%#hD_M!u}~J+mkmN95@DofXHit?v2vEKl)!>0^7C>^q$97o2Q%q6Dw0mb}-kG z{+yYjbjE#6{x6LIlhV^4>Q32D=p99~KKVXYD)QXv1yn7zYR|cx){LnEmi794!#YyL zljt2J4g+xk&!)<7gCY-K$-A>(Y9icSRLW4Mp2V1Jj#?*YXN>%c18rHwe)qob?w`qQ ze;w8azcK|ugS<<$C1ZQ9o)(nNvOp5ugk1?0RYxVbB|XU~QadPY$H1bh(%30c?18r_ zXDa0Y5RGz-VcAvc-BHHw0gcG&dS=+Km!l(y)%0;euVIoZx+~741xCbO{;z;~Gs;hs?~Y|nK5>_-u-S94(p~)Qj;TXwT2P!^2k*5HoH-Wq z77BTQnJ_2f@v*ayLWw7K7C4IFfn&pQ-I=Ku*CA|=qQwzq3qFIX5c4QDcW9tno)-Oc z!}bqrQTASvSeCS%zZ`>VtII*3DYk(p&!4Ex_G~g5U&c)%apA5GB#!DK@yu=<#|oz# z66-cuY=rb{D$+^Zto8$ zOoN#}xKiAf+Zh%{Y!SwB^QHi37BV<%XU|(7M>k^OlH`CuHnK}c53EaFzq{Z_6C)xL zR$N{ExUb2(?-W6!;ikkPHVXyTLsl(RNzJkyur8!Wze!1V(M@)WU-x(&3 z{_5_s_K0<26L+X@q^ZA#BIxyaaX}#_vR+TiGYIc1@2z>&sC22zz}7QWH3QK!nOd9` z5}JO`Td&Ak36-97%AWTC6`cZl%WdGLOYSl#`1Y>d*!?)S0U9_IS4e-`l!+@so74{s zRJ_E&$6vb>bT>Iboup_;K477yg>4@wfseWTNd?^`ByFcqclcl#_uOH7^cT5oP=4J^ zZqlUg_@5SjzA1Fac-3hB>sMdBmJLi@vwh+%rpJXSCweQ4ysChQI)Vx5pZ9AZLEqKE z5*1**G1$e}H#xy*H}}QWMLR1e=eHJ~^v;0|Ntf2g?Xgk;bL5Lc-##VMET3-L2fAR( z57Iez#cm+wJuSA`n}URjCB=|Ewsi+YD8I1qOJb4`EEI z#vgw9f%W!5}FY*I&&DkQ+(HInC z`8e$D)hc(yx7+T{_23Z@j(Z|5xG4QC%56#_UZ@(H0Zk>MsGr5Ai1*E@5ok@1Qu768 z3$7Eoft@iOJJ(}v=I%~LRS=F&2B=v@XmUoEb?$ur@@Z3=hu5m)8@_HL@R&=TU;XB@ z(4$-=JBSf>r;c)z-$_PFYZ4=48+joIY7yZI9$UMe&&${thl!M8%X7sLEx%Zi&ebxv zI9Y%uz;^4xXuaaO$H0X}OM6h6u&IlXI036T%=k^G+|u_bCr;)-5=W0+NoYHYG|t)JCMs}dRa#}|QlAoo|hsQ{!; zEsx01E3_=Ozrlic(psK;)yG=}nRx)nG- z?#!FYJZ^1v!PWIXiVms z>Kt&w45XsV`-`Eb71&1fgiKDwo2vC?!!rr?!5|Uy;xBSWw*U#P@SwBUgVcxd37NZ) z{oDynZS7AG2#~HPEG*o*@`V6!H{97oZ3P7%C{IWj>Gdc-R8%;A_1{t)e$-f2&Xzu> z?9KH22@qPS%TVyuZHsO+!>O>fkRM$W<(NO~gt88o2DX!#QJaNdqKh#-cre4ZJf6SQ zr5=x>avnE#0K6pJ5?iOACim;Er!^Ikm%Lt*mm;1GQ454-@fxA_7!9vGe%er^4{w;A zU4s{E+9GlL2zf&2t59*X?~Ka-?l#YZtu*x2ROe9M`A_7BNE$wE`VdhEl@+UvY9M_x z(ePa3EE=3A{aaXKv`H=2A^@Ls>jmuM`L!$adi$X%&|*#RQhU5sk-r`U9~uxEN}rGd z$x_59?nHc2$(Li#o8++IT-|tvqYb^mtN?|y2CLF%kC+`W5yAhMdww|%^!s`OX}#+(11AN2MVQe6CiFXM|P zt*j4ZWMuisV{8Cj=4vb6mbHq24Z)x*taS@P=?_PF^T_s89_HJivaBp@{)f+CoX(?F z*~TTDS8#5NMDS$R!PXr}l-mquw-RR;NdFDly0SAN&1XK#9Z&D$__~iG11GcHA+zyg z-5z5X{18q`g9c|gn~ClvEQDr%2~i6Q0>llg$x)HJT?$}D6c{08oqt=$4Ul1|Mwi}e zGOx#Szc7CzZnk>4dc;2Q^3Tht#zDh~L%4`j6%(r)1{m4dTL69Y=75U`M$DY=5GTvC zrR{&jSRKC5^g4hq;P>?m1zb_C^+_Le;rWAL-kuVJokxsv%$r8BoxzURVVHALfb{T^ zhUFP;-xeN)MHRQ=?tZMDy+}AVA+eO*W7?2wai(wnThH0;_G!N~9zW3fpPZ*Vh-$~6 z`Un~r$WIVyr(83&K9_LEsx4c$hFuV_7n=QeXbGu!&~G_`oD{Z}RgJW@HPj%Bq?k`F zEkfbGMM}L=$i>LEC^*8RFW@iWlRWvIdZ|I?$p4ik#*N_Lm&G=^mYh`Ptk5^l$$;s% zsY&-UI4Q)cP2c6F4C=*auzST6U#L@~BUyYa9vQLL5RIU9-m2-)v?;&^lx<;U_kzMyM@?6#?hH3>U&S1 zUv^!eKE4%<>4b3>g)jiL9elGLrAT2H(RjOoIMC$bon8Ecl8Df0!OG)uv!{?vgR`rG z(wE?ymlC$1hK7a=5qIE)g@wg(R_NC-TKV(2!|USGQWA}zJVF8b)~tbF8@E3Q08+H{QL96u&ib9M^ODP;m?iJDk!ljO`koRgp!F36Fq+| z(`ov3n3}%2c5HX%1-Vz>P`;RvitVDL_*EY(ml&Sb&5*$pc!RC$fgyd+fvRP%tsA36 zcs+0O3^|3ReGOnW*gGPUo2#PiK+{FD*=noBcp7~1B-&zgid2`FNC>SH!fhIDsquH7 zj#5u}g3mB!?s_PbMP$Q93B<)5Nls{Z{5@*hs38k_)F1kB+=!aZ7jDrw`pBe(J5 z6maCqVx|N;$mUgxyg86&gaqPWGvpo*1{&ldZa*?kOQleetoqqJR&6ptfDz zq^^DXh{O-;w`v=gFF%IT*;nmp2aR0b{_Y#G^NsGKjoL+K(dTw2d_^2Pv7aqs^Wv>H ztIY=^JPAV<59?ojlF)WNn)Z1&@N%*((=JW*co5*S>HLOB^Kt@h@NWq27vs^;(DV-t zSqV@Ej$*MShe`4Cr+)cDzQO;zU9DPe@84DEQv9(dv-GW z9JmcpYVo;Z7Xrvpzz=$NrxiHz9=dOdL#8I3FZAdWcT1qp4J?uXeLbrd7Z*>ia<*`K zzpS=4ou4OICT1e`)*=Ybezo3LCiyvfB0~$~>#O*5^~lIS@vuR*63jR{`>{v8IZw?B z&-`d)w6q;6SW4u^y|zi^*X%XXI@*M+@{3IR}&)E1v2bli;4wQh7xU zGY?%7{Fl*I@ZvPcClckN1?zpRoRWBv1MA^!gNi`}Sg1eyuu0Zb)YXxNBB1;?Bzi1o zm^EoY3M?WdGXX79Y@+VXGoAfOcBuP1XqR2*i;!l=ntMfxtJO$0u;cb#$W@Dbjx%Qm z-QhZ@aN0eV?kem4dw6UIvK-uEpJnw>ABp2DAp?%jz|cAkLbKTM;`uJ^Ch;_AO?9Z~ znP`dRlr6EETv!i+9u#_e3W%01Ko=N#)qGdz(>vKXRp064IG!)!44H;obuTsU@>wBd zVILXFIJq}ceOEW(?T;5{ZuDc3tsSHVWzVb;i~2G(2xX6n?p=+w8R(C%NWhn4H5d|n zzDolezogd!fe3N_)e?LLvARr7j7mVu)tK`u=3zd<)!8c*YwQ5;cdB-0il<*EU4paU zqmQD1N_;4%hzgVm1(6W`Ms}4qjWjz{V(F>7dY&u>IV6+mOQ5A1o<}c{%%&Kr++XF^ zwvk~Md8~^M-*a%2>N-fITUUy&nJmZO5sBwjoStr;opgfY;GSGwHgh{O91yfY?SQdYveT8Ur(R~o27Xn zFaGAg^pWL&P_JNmxr9F7hojFZmf)p;aR?{~61E#^d!$jJE(DW=It%p5YC1dPMkgyX zG}|%Gc*A7_(EU4Du8;`gv3(dZMoi6BQDpHRmv3RLiK*%I<}?N19}bxQHP7<1!5gO6 zoQ_zC19BIXw78)A1v5A<*XG31ySRp&drg`Pyle(0cr8xP{LQlDLGH+x*vvh55dcMK^B_1Sw zev-KT4DrT#3flns>o4bN>E1AWt29U`s9QnTsnrq`^`Y;yNQ za%=cAH>>bfeb1@#f~dG%(J|9(JlY^q8|({t#Oy6op^^d_SG&n@4Zwd`sSc8;z{)g!Fv; z1{QM3P;>BPuqu*1q>ll-<3%tu4Hzha4+o10@nZe7bZl(H^ynSDr%x1`8Gf+VQy z_=35hq9YD~2jiw=eCGFmi-XZ0TYjs2E9W<7lmcQQf64HU+FvfGN-y`^aw`8iWu5M{<^?v5$>w`5od!E*DVVa@2fH4@5AvPN;ft?){_519OmpVPH zS#;*GIf8*;a%bW(KeN#9^3K(~14(iaml;&7`!6WyDlMbzxDu-3l@6~Xv$K;l4*v%J z5(kn_zB&T?UOJf_T#GFMpruP9He5SX-(4qIk1dE}`gRUU_<1TJ0`T^{WrVdHUa-Bq)0_C1b9--Ji`b zdlUGh=253_gmxrepcZONhW2V-wo+-+6OHvH19%O{?MIU*c?VF`TWekGQ_W+A=#{jS z%E`QQ6Re>@d$%uzRRrEEza>N+nkX&h3S*hmCB;dPcTG&T9sUyakNNpzL!>!!<#o-R zC23xurl!8~-+A5)!}xwvuiWV{Glc;%rB1HEM%uT7Ye7T+Q_XYKBWba+!J#Wd$Pe#_ z;MHU3Nk8g^FaS4oIOUpj(Zh-gi7cbBS1yR>I)|xAwLO9~)t+enLoWad(j?hV%ur!3e+uOYZ*Rx__~YiL zx`6UOhLT3FVU{;JXD1#UP+QbZW6@0ZzYqssc_U%9%7VgY)w1Q5>2j4Y<8qJv<~YCA zG>*X90-5;a)$=^l5PYTofY5f(?nq#7SmmR)0acgYTdM6h4kL&ff0ZEHXm((;@_%qm z8oip!^#aY@gjhqGN$Qsy{nrM~&2WM*P{;oe(||(Q@+LIVro8NmY!_}?`HwE4hW_f) z|4)Y^=tM)S=DmF;WWBK5UscXv$Ndj&Y5|%2A8Z8e>D*}~b`5OYHHiH4(=s}yDWcfg01Z|= z_~|gKxi^mdfUc}wI4B7 zMXa8{k0u_}58Ma^qO6#*W$)a3px8s5&mKRtUsDBKDMz;}q_7SEWG`a!o+eH3c)iP@ zi-H4bMTYOdxN%Ip!zc4HLs3t+xPP;BSlWS^>o$1g4JuP?gPvanbn;H5f&)C8<$RqIPj+Q(!3pBzD z5DftNxGH#L8SjBrq3Ke&gEzYwp`DB0dmGyG(CK)2lR1rk)HyHkp+x_O^Rv)8n@=JF zd_zr(`>R8y$EXUA(-aWuZIhDZnL5-_uO;r-}+nub;fo^LD_ebYvz^^(+|J+F(##qQ8yDXR4 zMLXl0za^qfT`_L}{w-8s);?Ra(iNDAkmh)HG=yCU4OEQ7Uh@iJDk|L5BgxM>E0uqR z0Ju9(Z=*xY>mVakszE4uUI9UDbf43D55@qvMSoe@((a9nL6 zpC-QlKVR!|HO_5mk4>3;I+0yYA5viF4q0Cro9()RHkCqxAIjq4UilgAPAll;T3|L5%z$9@iCd z|5qN?q{$3L=8O1UcWqY40aW>w{5)TXCn7zR<)&ok4PamMIS@fd39`ZJ<}^p6Lkt`0 zKghf&HL=nQB1`)qPvHx*Rnu)e48i}&wC~Ga#_Bi6zm^wWs&VQ~s^kEKroL9^V`Gb& zzDtYCCFOwl>N0m{L5;ZBR|)%%0HYQ}B!&M`z52OXtGf9t+fuVsnzr=TmHK&lz-_zF zvE@n!;BVVY_;Y(XO?k=8f0iKV@){zNrrn)mzqF~+8My5yaziJuAfM7mg(t~z2 ziwe!?MmS`sQQ}X1gf*JOtl1BoM`o5d&dbf=z!u<)vmJMx{s-xqhFZ=H!=Qe-{x zR+}T>9KNSCQ?SW@Du4yT0v-YS-;ib1l1rQS{;z*DIHkB`R-hU;ZBqFYs}O6n4%jX) z%Dg369u1FAJu9F_Hz#ta7&wgIZC+?}4!Noy$3^owLzrL-Qb`5Mx9pFLiQ)k(tau(l zJi6)MZt1>^Wk84^YdDT0vCysMTR&vYC!t`eKO5{;^KZ;HE6eZ!QZ8YT`;hCOx{(9} zS!xjm%;&za9T|RXnT?>QFZAKlj$rd+CMUsR8z=8?r;rY|_Bl9PMUSIuLgsJA#aU9@x8HU76Z6Xh=qrPBxguhmy9h{ts=?rp{feHEUNJ5Fct0tFr8 z-1@40|2ENRl^lTHi|E?U@_(f*TF-Ed--EinS=U;ck1}#+CUOYn=u+m5x=z($Oyjes zfbN4z*4A?3BRD65_>;mF)4d9eiSY>y36=8iCINwvX(GqzGR!c;^I)}cVcn7NMS;iv z?H=+tRA?X?2rZFwrzWSaXvdIwG8^g${Tt!MpBh8B-17?;AS0j|F zb;2&yAThBwE`hmLhSly~gPoNqWnI1e)C-DRy^e8lFnU=U`fJ}%auVhDgdgUqn#DK* zkvBXUT|nB(GnR9`jf22l6KXSsZ&FW5vCMgjLrpS2(&F!)vUFab1#Se1APYXS_nRpw zd;lC$csC!3c_pui**G%jH5ovbc8NWLAn_PyB1*ogzCF=Vy|5E)pI?ZYZ`VD5~B)Te}9qa-%L|@3+s`?O-urjRtKva>+ z#+w;>kRT%8yetpdD*dbJt(txoUDU))GsAIh3?ybaUtaq{H`?iK9o>YiulFOrvLRnV zIXLWH1Q%-4GLUBfW`)h&|B-IIRFn4F|6H#CYq~RC5TVwFI!9PRE*dS(!EWupike9n YAo^3f;THDr4TKV91$FrvS@VzoAE=L18UO$Q