From 60f7c1df3f69ee37af96e03a32c93a72fb5ed407 Mon Sep 17 00:00:00 2001 From: coiax Date: Thu, 9 Mar 2017 20:42:02 +0000 Subject: [PATCH] Atoms can now be stationloving (#24748) * Objects can now be stationloving Stationloving objects are objects that love the station so much, they will relocate back to the station if spaced or if destroyed. Yes, this does sound a lot like the behaviour of the nuke disk. Except made more generic. Currently the only stationloving object is the nuke disk. * Moved from /obj to /atom/movable * Remie fix --- code/__DEFINES/flags.dm | 2 + code/__DEFINES/misc.dm | 2 +- .../subsystem/processing/inbounds.dm | 32 +++++++ code/game/atoms_movable.dm | 96 ++++++++++++++++++- code/game/gamemodes/nuclear/nuclearbomb.dm | 58 ++--------- code/game/objects/objs.dm | 4 +- tgstation.dme | 1 + 7 files changed, 140 insertions(+), 55 deletions(-) create mode 100644 code/controllers/subsystem/processing/inbounds.dm diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index ba816ade982..bcdef181b1e 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -35,6 +35,8 @@ #define NO_EMP_WIRES "no_emp_wires" #define HOLOGRAM "hologram" #define FROZEN "frozen" +#define STATIONLOVING "stationloving" +#define INFORM_ADMINS_ON_RELOCATE "inform_admins_on_relocate" //turf-only flags #define NOJAUNT 1 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 78b70bc4c7b..83e4d4e5505 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -392,4 +392,4 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define TURF_DECAL_DIRT "dirt" //Error handler defines -#define ERROR_USEFUL_LEN 2 \ No newline at end of file +#define ERROR_USEFUL_LEN 2 diff --git a/code/controllers/subsystem/processing/inbounds.dm b/code/controllers/subsystem/processing/inbounds.dm new file mode 100644 index 00000000000..d43a2d6074e --- /dev/null +++ b/code/controllers/subsystem/processing/inbounds.dm @@ -0,0 +1,32 @@ +var/datum/controller/subsystem/objects/SSinbounds +/datum/controller/subsystem/inbounds + name = "Inbounds" + priority = 40 + flags = SS_NO_INIT + + var/list/processing = list() + var/list/currentrun = list() + +/datum/controller/subsystem/inbounds/New() + NEW_SS_GLOBAL(SSinbounds) +/datum/controller/subsystem/inbounds/stat_entry() + ..("P:[processing.len]") + +/datum/controller/subsystem/inbounds/fire(resumed = 0) + if (!resumed) + src.currentrun = processing.Copy() + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + + while(currentrun.len) + var/atom/movable/thing = currentrun[currentrun.len] + currentrun.len-- + if(thing) + thing.check_in_bounds(wait) + else + SSinbounds.processing -= thing + if(MC_TICK_CHECK) + return + +/datum/controller/subsystem/inbounds/Recover() + processing = SSinbounds.processing diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index cfc699d3070..ed07b8a77e7 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -101,7 +101,26 @@ orbiting.Check() return 1 -/atom/movable/Destroy() +/atom/movable/Destroy(force) + var/inform_admins = HAS_SECONDARY_FLAG(src, INFORM_ADMINS_ON_RELOCATE) + var/stationloving = HAS_SECONDARY_FLAG(src, STATIONLOVING) + + if(inform_admins && force) + var/turf/T = get_turf(src) + message_admins("[src] has been !!force deleted!! in [ADMIN_COORDJMP(T)].") + log_game("[src] has been !!force deleted!! in [COORD(T)].") + + if(stationloving && !force) + var/turf/currentturf = get_turf(src) + var/turf/targetturf = relocate() + log_game("[src] has been destroyed in [COORD(currentturf)]. Moving it to [COORD(targetturf)].") + if(inform_admins) + message_admins("[src] has been destroyed in [ADMIN_COORDJMP(currentturf)]. Moving it to [ADMIN_COORDJMP(targetturf)].") + return QDEL_HINT_LETMELIVE + + if(stationloving && force) + STOP_PROCESSING(SSinbounds, src) + . = ..() if(loc) loc.handle_atom_del(src) @@ -420,3 +439,78 @@ else if (!on && floating) animate(src, pixel_y = initial(pixel_y), time = 10) floating = FALSE + +/* Stationloving +* +* A stationloving atom will always teleport back to the station +* if it ever leaves the station z-levels or Centcom. It will also, +* when Destroy() is called, will teleport to a random turf on the +* station. +* +* The turf is guaranteed to be "safe" for normal humans, probably. +* If the station is SUPER SMASHED UP, it might not work. +* +* Here are some important procs: +* relocate() +* moves the atom to a safe turf on the station +* +* check_in_bounds() +* regularly called and checks if `in_bounds()` returns true. If false, it +* triggers a `relocate()`. +* +* in_bounds() +* By default, checks that the atom's z is the station z or centcom. +*/ + +/atom/movable/proc/set_stationloving(state, inform_admins=FALSE) + var/currently = HAS_SECONDARY_FLAG(src, STATIONLOVING) + + if(inform_admins) + SET_SECONDARY_FLAG(src, INFORM_ADMINS_ON_RELOCATE) + else + CLEAR_SECONDARY_FLAG(src, INFORM_ADMINS_ON_RELOCATE) + + if(state == currently) + return + else if(!state) + STOP_PROCESSING(SSinbounds, src) + CLEAR_SECONDARY_FLAG(src, STATIONLOVING) + else + START_PROCESSING(SSinbounds, src) + SET_SECONDARY_FLAG(src, STATIONLOVING) + +/atom/movable/proc/relocate() + var/targetturf = find_safe_turf(ZLEVEL_STATION) + if(!targetturf) + if(blobstart.len > 0) + targetturf = get_turf(pick(blobstart)) + else + throw EXCEPTION("Unable to find a blobstart landmark") + + if(ismob(loc)) + var/mob/M = loc + M.transferItemToLoc(src, targetturf, TRUE) //nodrops disks when? + else if(istype(loc, /obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = loc + S.remove_from_storage(src, targetturf) + else + forceMove(targetturf) + // move the disc, so ghosts remain orbiting it even if it's "destroyed" + return targetturf + +/atom/movable/proc/check_in_bounds() + if(in_bounds()) + return + else + var/turf/currentturf = get_turf(src) + get(src, /mob) << "You can't help but feel that you just lost something back there..." + var/turf/targetturf = relocate() + log_game("[src] has been moved out of bounds in [COORD(currentturf)]. Moving it to [COORD(targetturf)].") + if(HAS_SECONDARY_FLAG(src, INFORM_ADMINS_ON_RELOCATE)) + message_admins("[src] has been moved out of bounds in [ADMIN_COORDJMP(currentturf)]. Moving it to [ADMIN_COORDJMP(targetturf)].") + +/atom/movable/proc/in_bounds() + . = FALSE + var/turf/currentturf = get_turf(src) + if(currentturf && (currentturf.z == ZLEVEL_CENTCOM || currentturf.z == ZLEVEL_STATION)) + . = TRUE diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 1e18e830645..9f0dc5ae796 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -502,7 +502,7 @@ This is here to make the tiles around the station mininuke change when it's arme /obj/item/weapon/disk/nuclear/New() ..() poi_list |= src - START_PROCESSING(SSobj, src) + set_stationloving(TRUE, inform_admins=TRUE) /obj/item/weapon/disk/nuclear/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/weapon/claymore/highlander)) @@ -518,6 +518,12 @@ This is here to make the tiles around the station mininuke change when it's arme return 1 return ..() +/obj/item/weapon/disk/nuclear/Destroy(force=FALSE) + // respawning is handled in /obj/Destroy() + if(force) + poi_list -= src + . = ..() + /obj/item/weapon/disk/nuclear/suicide_act(mob/user) user.visible_message("[user] is going delta! It looks like [user.p_theyre()] trying to commit suicide!") playsound(user.loc, 'sound/machines/Alarm.ogg', 50, -1, 1) @@ -536,56 +542,6 @@ This is here to make the tiles around the station mininuke change when it's arme user.visible_message("[user] was destroyed by the nuclear blast!") return OXYLOSS -/obj/item/weapon/disk/nuclear/process() - var/turf/diskturf = get_turf(src) - if(diskturf && (diskturf.z == ZLEVEL_CENTCOM || diskturf.z == ZLEVEL_STATION)) - return - else - get(src, /mob) << "You can't help but feel that you just lost something back there..." - var/turf/targetturf = relocate() - message_admins("[src] has been moved out of bounds in \ - [ADMIN_COORDJMP(diskturf)]. Moving it to \ - [ADMIN_COORDJMP(targetturf)].") - log_game("[src] has been moved out of bounds in [COORD(diskturf)]. \ - Moving it to [COORD(targetturf)].") - -/obj/item/weapon/disk/nuclear/proc/relocate() - var/targetturf = find_safe_turf(ZLEVEL_STATION) - if(!targetturf) - if(blobstart.len > 0) - targetturf = get_turf(pick(blobstart)) - else - throw EXCEPTION("Unable to find a blobstart landmark") - - if(ismob(loc)) - var/mob/M = loc - M.transferItemToLoc(src, targetturf, TRUE) //nodrops disks when? - else if(istype(loc, /obj/item/weapon/storage)) - var/obj/item/weapon/storage/S = loc - S.remove_from_storage(src, targetturf) - else - forceMove(targetturf) - // move the disc, so ghosts remain orbiting it even if it's "destroyed" - return targetturf - -/obj/item/weapon/disk/nuclear/Destroy(force) - var/turf/diskturf = get_turf(src) - - if(force) - message_admins("[src] has been !!force deleted!! in \ - [ADMIN_COORDJMP(diskturf)].") - log_game("[src] has been !!force deleted!! in [COORD(diskturf)].") - poi_list -= src - STOP_PROCESSING(SSobj, src) - return ..() - - var/turf/targetturf = relocate() - message_admins("[src] has been destroyed in [ADMIN_COORDJMP(diskturf)]. \ - Moving it to [ADMIN_COORDJMP(targetturf)].") - log_game("[src] has been destroyed in [COORD(diskturf)]. Moving it to \ - [COORD(targetturf)].") - return QDEL_HINT_LETMELIVE //Cancel destruction unless forced - /obj/item/weapon/disk/fakenucleardisk name = "cheap plastic imitation of the nuclear authentication disk" desc = "Broken dreams and a faint odor of cheese." diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 14ea548379c..8a854d98766 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -38,11 +38,11 @@ else T.add_blueprints_preround(src) -/obj/Destroy() +/obj/Destroy(force=FALSE) if(!istype(src, /obj/machinery)) STOP_PROCESSING(SSobj, src) // TODO: Have a processing bitflag to reduce on unnecessary loops through the processing lists SStgui.close_uis(src) - return ..() + . = ..() /obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) ..() diff --git a/tgstation.dme b/tgstation.dme index 15863b63d78..fcfdefc1d59 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -189,6 +189,7 @@ #include "code\controllers\subsystem\weather.dm" #include "code\controllers\subsystem\processing\fastprocess.dm" #include "code\controllers\subsystem\processing\flightpacks.dm" +#include "code\controllers\subsystem\processing\inbounds.dm" #include "code\controllers\subsystem\processing\objects.dm" #include "code\controllers\subsystem\processing\overlays.dm" #include "code\controllers\subsystem\processing\processing.dm"