diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 9d74c4338cf..c52fc67684e 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -137,6 +137,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_ALARM 16 // Must initialize before atoms. #define INIT_ORDER_TRANSCORE 15 #define INIT_ORDER_ATOMS 14 +#define INIT_ORDER_POIS 13 #define INIT_ORDER_MACHINES 10 #define INIT_ORDER_SHUTTLES 3 #define INIT_ORDER_TIMER 1 @@ -180,6 +181,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_AI 10 #define FIRE_PRIORITY_GARBAGE 15 #define FIRE_PRIORITY_ASSETS 20 +#define FIRE_PRIORITY_POIS 20 #define FIRE_PRIORITY_ALARM 20 #define FIRE_PRIORITY_CHARSETUP 25 #define FIRE_PRIORITY_AIRFLOW 30 diff --git a/code/controllers/subsystems/pois.dm b/code/controllers/subsystems/pois.dm new file mode 100644 index 00000000000..e5bfbbecf0d --- /dev/null +++ b/code/controllers/subsystems/pois.dm @@ -0,0 +1,87 @@ +GLOBAL_LIST_EMPTY(global_used_pois) +SUBSYSTEM_DEF(points_of_interest) + name = "Points of Interest" + wait = 1 SECONDS + priority = FIRE_PRIORITY_POIS + init_order = INIT_ORDER_POIS + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT //POIs can be loaded mid-round. + var/list/obj/effect/landmark/poi_loader/poi_queue = list() + +/datum/controller/subsystem/points_of_interest/Initialize() + while (poi_queue.len) + load_next_poi() + to_world_log("Initializing POIs") + admin_notice(span_danger("Initializing POIs"), R_DEBUG) + return SS_INIT_SUCCESS + +/datum/controller/subsystem/points_of_interest/fire(resumed = FALSE) + while (poi_queue.len) + load_next_poi() + + if (MC_TICK_CHECK) + return + +/// We select and fire the next PoI in the list. +/datum/controller/subsystem/points_of_interest/proc/load_next_poi() + var/obj/effect/landmark/poi_loader/poi_to_load = poi_queue[1] + poi_queue -= poi_to_load + //We then fire it! + load_poi(poi_to_load) + +/datum/controller/subsystem/points_of_interest/proc/get_turfs_to_clean(obj/effect/landmark/poi_loader/poi_to_load) + return block(locate(poi_to_load.x, poi_to_load.y, poi_to_load.z), locate((poi_to_load.x + poi_to_load.size_x - 1), (poi_to_load.y + poi_to_load.size_y - 1), poi_to_load.z)) + +/datum/controller/subsystem/points_of_interest/proc/annihilate_bounds(obj/effect/landmark/poi_loader/poi_to_load) + //var/deleted_atoms = 0 + //admin_notice(span_danger("Annihilating objects in poi loading location."), R_DEBUG) + var/list/turfs_to_clean = get_turfs_to_clean(poi_to_load) + if(turfs_to_clean.len) + for(var/x in 1 to 2) // Requires two passes to get everything. + for(var/turf/T in turfs_to_clean) + for(var/atom/movable/AM in T) + //++deleted_atoms + qdel(AM) + //admin_notice(span_danger("Annihilated [deleted_atoms] objects."), R_DEBUG) + +/datum/controller/subsystem/points_of_interest/proc/load_poi(obj/effect/landmark/poi_loader/poi_to_load) + if(!poi_to_load) + return + var/turf/T = get_turf(poi_to_load) + if(!isturf(T)) + to_world_log("[log_info_line(poi_to_load)] not on a turf! Cannot place poi template.") + return + + // Choose a poi + if(!poi_to_load.poi_type) + return + + if(!(GLOB.global_used_pois.len) || !(GLOB.global_used_pois[poi_to_load.poi_type])) + GLOB.global_used_pois[poi_to_load.poi_type] = list() + var/list/poi_list = GLOB.global_used_pois[poi_to_load.poi_type] + for(var/map in SSmapping.map_templates) + var/template = SSmapping.map_templates[map] + if(istype(template, poi_to_load.poi_type)) + poi_list += template + + var/datum/map_template/template_to_use = null + + var/list/our_poi_list = GLOB.global_used_pois[poi_to_load.poi_type] + + if(!our_poi_list.len) + return + else + template_to_use = pick(our_poi_list) + + if(!template_to_use) + return + + //admin_notice(span_danger("Chosen Predefined PoI Map: [chosen_type.name]"), R_DEBUG) + + if(poi_to_load.remove_from_pool) + GLOB.global_used_pois[poi_to_load.poi_type] -= template_to_use + + // Annihilate movable atoms + annihilate_bounds(poi_to_load) + // Actually load it + template_to_use.load(T) + qdel(poi_to_load) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 7e3ecc2e4b1..9f2a9b7a5e7 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -92,6 +92,7 @@ // Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE // Must return an Initialize hint. Defined in code/__defines/subsystems.dm /atom/proc/Initialize(mapload, ...) + SHOULD_NOT_SLEEP(TRUE) SHOULD_CALL_PARENT(TRUE) if(QDELETED(src)) stack_trace("GC: -- [type] had initialize() called after qdel() --") diff --git a/code/game/objects/effects/landmarks_poi_vr.dm b/code/game/objects/effects/landmarks_poi_vr.dm index 9f037220b02..389bd28a7b7 100644 --- a/code/game/objects/effects/landmarks_poi_vr.dm +++ b/code/game/objects/effects/landmarks_poi_vr.dm @@ -1,7 +1,3 @@ -var/global/list/global_used_pois = list() - - - /obj/effect/landmark/poi_loader name = "PoI Loader" var/size_x @@ -12,61 +8,5 @@ var/global/list/global_used_pois = list() INITIALIZE_IMMEDIATE(/obj/effect/landmark/poi_loader) /obj/effect/landmark/poi_loader/Initialize(mapload) - src.load_poi() + SSpoints_of_interest.poi_queue += src return ..() - -/obj/effect/landmark/poi_loader/proc/get_turfs_to_clean() - return block(locate(src.x, src.y, src.z), locate((src.x + size_x - 1), (src.y + size_y - 1), src.z)) - -/obj/effect/landmark/poi_loader/proc/annihilate_bounds() - //var/deleted_atoms = 0 - //admin_notice(span_danger("Annihilating objects in poi loading location."), R_DEBUG) - var/list/turfs_to_clean = get_turfs_to_clean() - if(turfs_to_clean.len) - for(var/x in 1 to 2) // Requires two passes to get everything. - for(var/turf/T in turfs_to_clean) - for(var/atom/movable/AM in T) - //++deleted_atoms - qdel(AM) - //admin_notice(span_danger("Annihilated [deleted_atoms] objects."), R_DEBUG) - -/obj/effect/landmark/poi_loader/proc/load_poi() - var/turf/T = get_turf(src) - if(!isturf(T)) - to_world_log("[log_info_line(src)] not on a turf! Cannot place poi template.") - return - - // Choose a poi - if(!poi_type) - return - - if(!(global_used_pois.len) || !(global_used_pois[poi_type])) - global_used_pois[poi_type] = list() - var/list/poi_list = global_used_pois[poi_type] - for(var/map in SSmapping.map_templates) - var/template = SSmapping.map_templates[map] - if(istype(template, poi_type)) - poi_list += template - - var/datum/map_template/template_to_use = null - - var/list/our_poi_list = global_used_pois[poi_type] - - if(!our_poi_list.len) - return - else - template_to_use = pick(our_poi_list) - - if(!template_to_use) - return - - //admin_notice(span_danger("Chosen Predefined PoI Map: [chosen_type.name]"), R_DEBUG) - - if(remove_from_pool) - global_used_pois[poi_type] -= template_to_use - - // Annihilate movable atoms - annihilate_bounds() - //CHECK_TICK //Don't let anything else happen for now - // Actually load it - template_to_use.load(T) diff --git a/code/modules/mob/living/carbon/human/species/station/prommie_blob.dm b/code/modules/mob/living/carbon/human/species/station/prommie_blob.dm index fc852b91f21..8ab66fa08a0 100644 --- a/code/modules/mob/living/carbon/human/species/station/prommie_blob.dm +++ b/code/modules/mob/living/carbon/human/species/station/prommie_blob.dm @@ -107,12 +107,16 @@ return INITIALIZE_HINT_QDEL humanform = H - updatehealth() + calculate_health() /mob/living/simple_mob/slime/promethean/updatehealth() if(!humanform) return ..() + calculate_health() + if((stat < DEAD) && (health <= 0)) + death() +/mob/living/simple_mob/slime/promethean/proc/calculate_health() //Set the max maxHealth = humanform.getMaxHealth()*2 //HUMANS, and their 'double health', bleh. //Set us to their health, but, human health ignores robolimbs so we do it 'the hard way' @@ -120,10 +124,6 @@ human_burn = humanform.getActualFireLoss() health = maxHealth - humanform.getOxyLoss() - humanform.getToxLoss() - humanform.getCloneLoss() - human_brute - human_burn - //Alive, becoming dead - if((stat < DEAD) && (health <= 0)) - death() - //Overhealth if(health > getMaxHealth()) health = getMaxHealth() diff --git a/code/modules/mob/living/carbon/human/species/station/protean/protean_blob.dm b/code/modules/mob/living/carbon/human/species/station/protean/protean_blob.dm index fdd01144aa8..daa2c399c6d 100644 --- a/code/modules/mob/living/carbon/human/species/station/protean/protean_blob.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean/protean_blob.dm @@ -74,7 +74,7 @@ return INITIALIZE_HINT_QDEL humanform = H - updatehealth() + calculate_health() refactory = locate() in humanform.internal_organs add_verb(src,/mob/living/proc/ventcrawl) add_verb(src,/mob/living/proc/usehardsuit) @@ -205,19 +205,21 @@ return if(humanform.nano_dead_check(src)) return + calculate_health() + //Alive, becoming dead + if((stat < DEAD) && (health <= 0)) + humanform.death() +/mob/living/simple_mob/protean_blob/proc/calculate_health() //Set the max maxHealth = humanform.getMaxHealth()*2 //HUMANS, and their 'double health', bleh. human_brute = humanform.getActualBruteLoss() human_burn = humanform.getActualFireLoss() health = maxHealth - humanform.getOxyLoss() - humanform.getToxLoss() - humanform.getCloneLoss() - humanform.getBruteLoss() - humanform.getFireLoss() - //Alive, becoming dead - if((stat < DEAD) && (health <= 0)) - humanform.death() - nutrition = humanform.nutrition + //Overhealth if(health > getMaxHealth()) health = getMaxHealth() diff --git a/vorestation.dme b/vorestation.dme index 949d7ae595f..1dd0e06de7b 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -399,6 +399,7 @@ #include "code\controllers\subsystems\planets.dm" #include "code\controllers\subsystems\plants.dm" #include "code\controllers\subsystems\player_tips.dm" +#include "code\controllers\subsystems\pois.dm" #include "code\controllers\subsystems\radiation.dm" #include "code\controllers\subsystems\robot_sprites.dm" #include "code\controllers\subsystems\runechat.dm"