From c9fad5cfbfdb4b661703fba259b1d7dfff468e68 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Thu, 12 May 2022 00:20:27 +0100 Subject: [PATCH 01/16] Unified flock annotations --- code/datums/flock/flock.dm | 209 ++++++++---------- code/mob/living/critter/flock/flockdrone.dm | 10 +- code/mob/living/intangible/flock/flockmind.dm | 2 - .../mob/living/intangible/flock/flocktrace.dm | 1 - code/mob/living/intangible/flockmob_parent.dm | 2 - 5 files changed, 103 insertions(+), 121 deletions(-) diff --git a/code/datums/flock/flock.dm b/code/datums/flock/flock.dm index fe634727d0..2565e76869 100644 --- a/code/datums/flock/flock.dm +++ b/code/datums/flock/flock.dm @@ -18,12 +18,10 @@ var/datum/mind/flockmind_mind = null var/list/units = list() var/list/enemies = list() - var/list/annotation_viewers = list() - var/list/annotations_busy_tiles = list() // key is atom ref, value is image - var/list/annotations_priority_tiles = list() - var/list/annotations_deconstruct_targets = list() - var/list/annotations_enemies = list() - var/list/annotations_control_icons = list() + ///Associative list of objects to lists of their annotations + var/list/annotations = list() + ///Static cache of annotation images + var/static/list/annotation_imgs = null var/list/obj/flock_structure/structures = list() var/list/datum/unlockable_flock_structure/unlockableStructures = list() ///list of strings that lets flock record achievements for structure unlocks @@ -40,6 +38,8 @@ processing_items |= src for(var/DT in childrentypesof(/datum/unlockable_flock_structure)) src.unlockableStructures += new DT(src) + if (!annotation_imgs) + annotation_imgs = build_annotation_imgs() /datum/flock/ui_status(mob/user) // only flockminds and admins allowed @@ -228,6 +228,7 @@ if(!T) return src.traces -= T + hideAnnotations(T) var/datum/abilityHolder/flockmind/aH = src.flockmind.abilityHolder aH?.updateCompute() @@ -312,44 +313,87 @@ animate(time = duration/9, alpha = 100) // ANNOTATIONS +///Init some annotation images to copy +/datum/flock/proc/build_annotation_imgs() + . = list() + + var/image/hazard = image('icons/misc/featherzone.dmi', icon_state = "hazard") + hazard.blend_mode = BLEND_ADD + hazard.plane = PLANE_ABOVE_LIGHTING + hazard.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + hazard.pixel_y = 16 + .["hazard"] = .["deconstruct"] = hazard + + var/image/priority = image('icons/misc/featherzone.dmi', icon_state = "frontier") + priority.appearance_flags = RESET_ALPHA | RESET_COLOR + priority.alpha = 180 + priority.plane = PLANE_ABOVE_LIGHTING + priority.mouse_opacity = FALSE + .["priority"] = priority + + var/image/reserved = image('icons/misc/featherzone.dmi', icon_state = "frontier") + reserved.appearance_flags = RESET_ALPHA | RESET_COLOR + reserved.alpha = 80 + reserved.plane = PLANE_ABOVE_LIGHTING + reserved.mouse_opacity = FALSE + .["reserved"] = reserved + + var/image/flock_face = image('icons/misc/featherzone.dmi', icon_state = "flockmind_face") + flock_face.blend_mode = BLEND_ADD + flock_face.plane = PLANE_ABOVE_LIGHTING + flock_face.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + flock_face.pixel_y = 16 + .["flockmind_face"] = flock_face + + var/image/trace_face = image('icons/misc/featherzone.dmi', icon_state = "flocktrace_face") + trace_face.blend_mode = BLEND_ADD + trace_face.plane = PLANE_ABOVE_LIGHTING + trace_face.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + trace_face.pixel_y = 16 + .["flocktrace_face"] = trace_face + +///internal proc to get the indexed list of annotations on a particular mob +/datum/flock/proc/_getAnnotations(atom/target) + var/active = src.annotations[target] + if(!islist(active)) + active = list() + src.annotations[target] = active + return active + +///Toggle a named annotation +/datum/flock/proc/toggleAnnotation(atom/target, var/annotation) + var/active = _getAnnotations(target) + if (annotation in active) + removeAnnotation(target, annotation) + else + addAnnotation(target, annotation) + +///Add a named annotation +/datum/flock/proc/addAnnotation(atom/target, var/annotation) + var/active = _getAnnotations(target) + if(!(annotation in active)) + var/image/icon = image(src.annotation_imgs[annotation], loc=target) + if (isturf(target)) + var/turf/T = target + icon.loc = T.RL_MulOverlay ? T.RL_MulOverlay : T + active[annotation] = icon + get_image_group(src).add_image(icon) + +///Remove a named annotation +/datum/flock/proc/removeAnnotation(atom/target, var/annotation) + var/active = _getAnnotations(target) + var/image/image = active[annotation] + if (image) + get_image_group(src).remove_image(image) + active -= annotation + qdel(image) + // currently both flockmind and player units get the same annotations: what tiles are marked for conversion, and who is shitlisted /datum/flock/proc/showAnnotations(var/mob/M) - if(!M) - return - src.annotation_viewers |= M - var/client/C = M.client - if(C) - for(var/atom/key in src.annotations_priority_tiles) - C.images |= src.annotations_priority_tiles[key] - for(var/atom/key in src.annotations_busy_tiles) - C.images |= src.annotations_busy_tiles[key] - for(var/atom/key in src.annotations_enemies) - C.images |= src.annotations_enemies[key] - for(var/atom/key in src.annotations_control_icons) - C.images |= src.annotations_control_icons[key] + get_image_group(src).add_mob(M) /datum/flock/proc/hideAnnotations(var/mob/M) - if(!M) - return - src.annotation_viewers -= M - var/client/C = M.client - if(C) - for(var/atom/key in src.annotations_priority_tiles) - C.images -= src.annotations_priority_tiles[key] - for(var/atom/key in src.annotations_busy_tiles) - C.images -= src.annotations_busy_tiles[key] - for(var/atom/key in src.annotations_enemies) - C.images -= src.annotations_enemies[key] - for(var/atom/key in src.annotations_control_icons) - C.images -= src.annotations_control_icons[key] - -/datum/flock/proc/addClientImage(image/I) - for (var/mob/M in src.annotation_viewers) - M.client?.images += I - -/datum/flock/proc/removeClientImage(image/I) - for (var/mob/M in src.annotation_viewers) - M.client?.images -= I + get_image_group(src).remove_mob(M) // UNITS @@ -399,37 +443,8 @@ return count /datum/flock/proc/toggleDeconstructionFlag(var/atom/target) - var/image/I - if(target in src.deconstruct_targets) - src.deconstruct_targets -= target - - I = src.annotations_deconstruct_targets[target] - src.annotations_deconstruct_targets -= target - src.removeClientImage(I) - else - src.deconstruct_targets += target - - I = add_overhead_image('icons/misc/featherzone.dmi', target, "hazard") - src.annotations_deconstruct_targets[target] = I - -/// Just because this was duplicated a bunch -/datum/flock/proc/add_overhead_image(icon, target, icon_state) - var/image/I = image(icon, target, icon_state) - I.blend_mode = BLEND_ADD - I.pixel_y = 16 - I.plane = PLANE_ABOVE_LIGHTING - I.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - src.addClientImage(I) - return I - -/datum/flock/proc/add_control_icon(var/mob/living/critter/flock/flockthing, var/mob/living/intangible/flock/sentient) - var/image/icon = src.add_overhead_image('icons/misc/featherzone.dmi', flockthing, sentient.control_icon) - src.annotations_control_icons[flockthing] = icon - -/datum/flock/proc/remove_control_icon(var/mob/living/critter/flock/flockthing) - var/image/I = src.annotations_control_icons[flockthing] - src.annotations_control_icons -= flockthing - src.removeClientImage(I) + toggleAnnotation(target, "deconstruct") + src.deconstruct_targets ^= target // ENEMIES @@ -451,12 +466,10 @@ enemy_deets["mob"] = M enemy_deets["last_seen"] = enemy_area src.enemies[enemy_name] = enemy_deets + addAnnotation(M, "hazard") else enemy_deets = src.enemies[enemy_name] enemy_deets["last_seen"] = get_area(M) - if (!(M in src.annotations_enemies)) - var/image/I = add_overhead_image('icons/misc/featherzone.dmi', M, "hazard") - src.annotations_enemies[M] = I /datum/flock/proc/removeEnemy(atom/M) // call off all drones attacking this guy @@ -464,9 +477,7 @@ return src.enemies -= M - var/image/I = src.annotations_enemies[M] - src.annotations_enemies -= M - src.removeClientImage(I) + removeAnnotation(M, "hazard") /datum/flock/proc/isEnemy(atom/M) var/enemy_name = M @@ -480,14 +491,12 @@ hideAnnotations(src.flockmind) for(var/mob/M in src.units) hideAnnotations(M) + qdel(get_image_group(src)) all_owned_tiles = null busy_tiles = null priority_tiles = null units = null enemies = null - annotations_busy_tiles = null - annotations_priority_tiles = null - annotations_enemies = null flockmind = null //while this is neat cleanup, we still need the flock datum for tracking flocktrace mind connections // qdel(src) @@ -500,22 +509,12 @@ if(name in src.busy_tiles) return src.busy_tiles[name] = T - - var/image/I = image('icons/misc/featherzone.dmi', T.RL_MulOverlay ? T.RL_MulOverlay : T, "frontier") - I.appearance_flags = RESET_ALPHA | RESET_COLOR - I.alpha = 80 - I.plane = PLANE_ABOVE_LIGHTING - I.mouse_opacity = FALSE - src.annotations_busy_tiles[T] = I - src.addClientImage(I) + addAnnotation(T, "reserve") /datum/flock/proc/unreserveTurf(var/name) var/turf/simulated/T = src.busy_tiles[name] src.busy_tiles -= name - - var/image/I = src.annotations_busy_tiles[T] - src.annotations_busy_tiles -= T - src.removeClientImage(I) + removeAnnotation(T, "reserve") /datum/flock/proc/claimTurf(var/turf/simulated/T) src.all_owned_tiles |= T @@ -528,10 +527,7 @@ var/obj/flock_structure/structure = O structure.flock = src src.registerStructure(structure) - - var/image/I = src.annotations_priority_tiles[T] - src.annotations_priority_tiles -= T - src.removeClientImage(I) + removeAnnotation(T, "priority") /datum/flock/proc/isTurfFree(var/turf/simulated/T, var/queryName) // provide the drone's name here: if they own the turf it's free _to them_ for(var/name in src.busy_tiles) @@ -542,25 +538,10 @@ return 1 /datum/flock/proc/togglePriorityTurf(var/turf/T) - if(!T) + if (!T) return TRUE - var/image/I - if(T in priority_tiles) - priority_tiles -= T - - I = src.annotations_priority_tiles[T] - src.annotations_priority_tiles -= T - src.removeClientImage(I) - else - priority_tiles |= T - - I = image('icons/misc/featherzone.dmi', T.RL_MulOverlay ? T.RL_MulOverlay : T, "frontier") - I.appearance_flags = RESET_ALPHA | RESET_COLOR - I.alpha = 180 - I.plane = PLANE_ABOVE_LIGHTING - I.mouse_opacity = FALSE - src.annotations_priority_tiles[T] = I - src.addClientImage(I) + toggleAnnotation(T, "priority") + priority_tiles ^= T // get closest unclaimed tile to requester /datum/flock/proc/getPriorityTurfs(var/mob/living/critter/flock/drone/requester) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 51d3f4c8b3..9786c99fb5 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -139,7 +139,10 @@ controller = pilot src.client?.color = null // stop being all fucked up and weird aaaagh src.hud?.update_intent() - flock.add_control_icon(src, pilot) + if (istype(pilot, /mob/living/intangible/flock/flockmind)) + flock.addAnnotation(src, "flockmind_face") + else + flock.addAnnotation(src, "flocktrace_face") if (give_alert) boutput(src, "\[SYSTEM: Control of drone [src.real_name] established.\]") @@ -170,7 +173,10 @@ controller.mind.key = key controller.mind.current = controller ticker.minds += controller.mind - flock.remove_control_icon(src) + if (istype(controller, /mob/living/intangible/flock/flockmind)) + flock.removeAnnotation(src, "flockmind_face") + else + flock.removeAnnotation(src, "flocktrace_face") if (give_alerts) flock_speak(null, "Control of drone [src.real_name] surrended.", src.flock) // clear refs diff --git a/code/mob/living/intangible/flock/flockmind.dm b/code/mob/living/intangible/flock/flockmind.dm index bb789213a5..67bbd998ce 100644 --- a/code/mob/living/intangible/flock/flockmind.dm +++ b/code/mob/living/intangible/flock/flockmind.dm @@ -7,7 +7,6 @@ desc = "The collective machine consciousness of a bunch of glass peacock things." icon = 'icons/misc/featherzone.dmi' icon_state = "flockmind" - control_icon = "flockmind_face" layer = NOLIGHT_EFFECTS_LAYER_BASE var/started = 0 @@ -26,7 +25,6 @@ src.name = src.real_name src.update_name_tag() src.flock.registerFlockmind(src) - src.flock.showAnnotations(src) if (!F) src.addAbility(/datum/targetable/flockmindAbility/spawnEgg) src.addAbility(/datum/targetable/flockmindAbility/ping) diff --git a/code/mob/living/intangible/flock/flocktrace.dm b/code/mob/living/intangible/flock/flocktrace.dm index 797d23b665..a75655f2b1 100644 --- a/code/mob/living/intangible/flock/flocktrace.dm +++ b/code/mob/living/intangible/flock/flocktrace.dm @@ -9,7 +9,6 @@ desc = "The representation of a partition of the will of the flockmind." icon = 'icons/misc/featherzone.dmi' icon_state = "flocktrace" - control_icon = "flocktrace_face" layer = NOLIGHT_EFFECTS_LAYER_BASE compute = -100 //it is expensive to run more threads diff --git a/code/mob/living/intangible/flockmob_parent.dm b/code/mob/living/intangible/flockmob_parent.dm index 62ff362e47..2d7c57e7ec 100644 --- a/code/mob/living/intangible/flockmob_parent.dm +++ b/code/mob/living/intangible/flockmob_parent.dm @@ -16,7 +16,6 @@ var/compute = 0 var/datum/flock/flock = null var/wear_id = null // to prevent runtimes from AIs tracking down radio signals - var/control_icon = "flocktrace_face" /mob/living/intangible/flock/New() ..() @@ -48,7 +47,6 @@ plane.alpha = 255 /mob/living/intangible/flock/Logout() - src.flock?.hideAnnotations(src) if(src.client) var/atom/plane = src.client.get_plane(PLANE_LIGHTING) if (plane) From e95fd1e53457d37bc9df41691cd7550c1806006d Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Thu, 12 May 2022 11:12:33 +0100 Subject: [PATCH 02/16] Update code/datums/flock/flock.dm Co-authored-by: Ryan <53062374+FlameArrow57@users.noreply.github.com> --- code/datums/flock/flock.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/flock/flock.dm b/code/datums/flock/flock.dm index 2565e76869..15025ab39e 100644 --- a/code/datums/flock/flock.dm +++ b/code/datums/flock/flock.dm @@ -18,7 +18,7 @@ var/datum/mind/flockmind_mind = null var/list/units = list() var/list/enemies = list() - ///Associative list of objects to lists of their annotations + ///Associative list of objects to an associative list of their annotation names to images var/list/annotations = list() ///Static cache of annotation images var/static/list/annotation_imgs = null From dec82aa958aed9c3ed0b6a575c879126ac033dd0 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Thu, 12 May 2022 12:01:54 +0100 Subject: [PATCH 03/16] Refactored drone control release procs --- code/mob/living/critter/flock/flockdrone.dm | 74 +++++---------------- 1 file changed, 18 insertions(+), 56 deletions(-) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 9786c99fb5..8387794869 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -146,43 +146,17 @@ if (give_alert) boutput(src, "\[SYSTEM: Control of drone [src.real_name] established.\]") +///Release control of a drone normally /mob/living/critter/flock/drone/proc/release_control(give_alerts = TRUE) - src.flock?.hideAnnotations(src) - src.is_npc = 1 if (give_alerts) emote("beep") say(pick_string("flockmind.txt", "flockdrone_player_kicked")) - if(src.client && !controller) - // don't know how this happened but you need a controller right now - controller = new/mob/living/intangible/flock/trace(src, src.flock) - if(controller) - if (src.floorrunning) - src.end_floorrunning(TRUE) - // move controller out - controller.set_loc(get_turf(src)) - // move us over to the controller - var/datum/mind/mind = src.mind - if (mind) - mind.transfer_to(controller) - else - if (src.client) - var/key = src.client.key - src.client.mob = controller - controller.mind = new /datum/mind() - controller.mind.ckey = ckey - controller.mind.key = key - controller.mind.current = controller - ticker.minds += controller.mind - if (istype(controller, /mob/living/intangible/flock/flockmind)) - flock.removeAnnotation(src, "flockmind_face") - else - flock.removeAnnotation(src, "flocktrace_face") - if (give_alerts) - flock_speak(null, "Control of drone [src.real_name] surrended.", src.flock) - // clear refs - controller = null + release_control_abrupt(FALSE) + if (give_alerts) + flock_speak(null, "Control of drone [src.real_name] surrended.", src.flock) -/mob/living/critter/flock/drone/proc/release_control_abrupt() +///Release control of a drone without blocking calls, so it can be used in ghostize etc. +/mob/living/critter/flock/drone/proc/release_control_abrupt(give_alerts = TRUE) src.flock?.hideAnnotations(src) src.is_npc = TRUE if(src.client && !controller) @@ -203,7 +177,12 @@ controller.mind.key = key controller.mind.current = controller ticker.minds += controller.mind - boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") + if (istype(controller, /mob/living/intangible/flock/flockmind)) + flock.removeAnnotation(src, "flockmind_face") + else + flock.removeAnnotation(src, "flocktrace_face") + if (give_alerts) + boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") controller = null /mob/living/critter/flock/drone/dormantize() @@ -215,30 +194,18 @@ return src.flock.hideAnnotations(src) - + //hold a ref to the controller so we can put them back with the flock + var/mob/living/intangible/flock/old_controller = src.controller if (src.controller) + src.release_control() + if (old_controller) if (src.flock.getComplexDroneCount()) for (var/mob/living/critter/flock/drone/F in src.flock.units) if (istype(F) && F != src) - src.controller.set_loc(get_turf(F)) + old_controller.set_loc(get_turf(F)) break else - src.controller.set_loc(pick_landmark(LANDMARK_LATEJOIN)) - - var/datum/mind/mind = src.mind - if (mind) - mind.transfer_to(controller) - else - if (src.client) - var/key = src.client.key - src.client.mob = controller - controller.mind = new /datum/mind() - controller.mind.ckey = ckey - controller.mind.key = key - controller.mind.current = controller - ticker.minds += controller.mind - boutput(controller, "\[SYSTEM: Connection to drone [src.real_name] lost.\]") - controller = null + old_controller.set_loc(pick_landmark(LANDMARK_LATEJOIN)) src.is_npc = TRUE // to ensure right flock_speak message if (src.z != Z_LEVEL_NULL) flock_speak(src, "Error: Out of signal range. Disconnecting.", src.flock) @@ -295,11 +262,6 @@ if(src.flock) src.flock.showAnnotations(src) -/mob/living/critter/flock/drone/Logout() - ..() - if(src.flock) - src.flock.hideAnnotations(src) - /mob/living/critter/flock/drone/is_spacefaring() return 1 /mob/living/critter/flock/drone/Cross(atom/movable/mover) From 43a1181365b3ae6cc4daf2030d504172fd7658e0 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Thu, 12 May 2022 13:52:08 +0100 Subject: [PATCH 04/16] macros --- _std/macros/flock.dm | 8 ++++++++ code/datums/flock/flock.dm | 20 ++++++++++---------- code/mob/living/critter/flock/flockdrone.dm | 8 ++++---- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/_std/macros/flock.dm b/_std/macros/flock.dm index 519cd11f8d..1c40abb95f 100644 --- a/_std/macros/flock.dm +++ b/_std/macros/flock.dm @@ -3,3 +3,11 @@ #define isflock(x) (istype(x, /mob/living/intangible/flock) || istype(x, /mob/living/critter/flock)) #define isflockstructure(x) (istype(x, /obj/flock_structure)) #define isflockdeconimmune(x) (istype(target, /obj/flock_structure/ghost) || istype(target, /mob/living/critter/flock) || istype(target, /turf/simulated/floor/feather) || istype(target, /obj/flock_structure/rift) || istype(target, /obj/flock_structure/egg) || istype(target, /obj/flock_structure/relay)) + +//annotation name macros +#define FLOCK_ANNOTATION_HAZARD "hazard" +#define FLOCK_ANNOTATION_DECONSTRUCT "deconstruct" +#define FLOCK_ANNOTATION_PRIORITY "priority" +#define FLOCK_ANNOTATION_RESERVED "reserved" +#define FLOCK_ANNOTATION_FLOCKMIND_CONTROL "flockmind_face" +#define FLOCK_ANNOTATION_FLOCKTRACE_CONTROL "flocktrace_face" diff --git a/code/datums/flock/flock.dm b/code/datums/flock/flock.dm index 15025ab39e..bbcb250ef1 100644 --- a/code/datums/flock/flock.dm +++ b/code/datums/flock/flock.dm @@ -322,35 +322,35 @@ hazard.plane = PLANE_ABOVE_LIGHTING hazard.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM hazard.pixel_y = 16 - .["hazard"] = .["deconstruct"] = hazard + .[FLOCK_ANNOTATION_HAZARD] = .[FLOCK_ANNOTATION_DECONSTRUCT] = hazard var/image/priority = image('icons/misc/featherzone.dmi', icon_state = "frontier") priority.appearance_flags = RESET_ALPHA | RESET_COLOR priority.alpha = 180 priority.plane = PLANE_ABOVE_LIGHTING priority.mouse_opacity = FALSE - .["priority"] = priority + .[FLOCK_ANNOTATION_PRIORITY] = priority var/image/reserved = image('icons/misc/featherzone.dmi', icon_state = "frontier") reserved.appearance_flags = RESET_ALPHA | RESET_COLOR reserved.alpha = 80 reserved.plane = PLANE_ABOVE_LIGHTING reserved.mouse_opacity = FALSE - .["reserved"] = reserved + .[FLOCK_ANNOTATION_RESERVED] = reserved var/image/flock_face = image('icons/misc/featherzone.dmi', icon_state = "flockmind_face") flock_face.blend_mode = BLEND_ADD flock_face.plane = PLANE_ABOVE_LIGHTING flock_face.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM flock_face.pixel_y = 16 - .["flockmind_face"] = flock_face + .[FLOCK_ANNOTATION_FLOCKMIND_CONTROL] = flock_face var/image/trace_face = image('icons/misc/featherzone.dmi', icon_state = "flocktrace_face") trace_face.blend_mode = BLEND_ADD trace_face.plane = PLANE_ABOVE_LIGHTING trace_face.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM trace_face.pixel_y = 16 - .["flocktrace_face"] = trace_face + .[FLOCK_ANNOTATION_FLOCKTRACE_CONTROL] = trace_face ///internal proc to get the indexed list of annotations on a particular mob /datum/flock/proc/_getAnnotations(atom/target) @@ -443,7 +443,7 @@ return count /datum/flock/proc/toggleDeconstructionFlag(var/atom/target) - toggleAnnotation(target, "deconstruct") + toggleAnnotation(target, FLOCK_ANNOTATION_DECONSTRUCT) src.deconstruct_targets ^= target // ENEMIES @@ -466,7 +466,7 @@ enemy_deets["mob"] = M enemy_deets["last_seen"] = enemy_area src.enemies[enemy_name] = enemy_deets - addAnnotation(M, "hazard") + addAnnotation(M, FLOCK_ANNOTATION_HAZARD) else enemy_deets = src.enemies[enemy_name] enemy_deets["last_seen"] = get_area(M) @@ -477,7 +477,7 @@ return src.enemies -= M - removeAnnotation(M, "hazard") + removeAnnotation(M, FLOCK_ANNOTATION_HAZARD) /datum/flock/proc/isEnemy(atom/M) var/enemy_name = M @@ -527,7 +527,7 @@ var/obj/flock_structure/structure = O structure.flock = src src.registerStructure(structure) - removeAnnotation(T, "priority") + removeAnnotation(T, FLOCK_ANNOTATION_PRIORITY) /datum/flock/proc/isTurfFree(var/turf/simulated/T, var/queryName) // provide the drone's name here: if they own the turf it's free _to them_ for(var/name in src.busy_tiles) @@ -540,7 +540,7 @@ /datum/flock/proc/togglePriorityTurf(var/turf/T) if (!T) return TRUE - toggleAnnotation(T, "priority") + toggleAnnotation(T, FLOCK_ANNOTATION_PRIORITY) priority_tiles ^= T // get closest unclaimed tile to requester diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 8387794869..ded8705b33 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -140,9 +140,9 @@ src.client?.color = null // stop being all fucked up and weird aaaagh src.hud?.update_intent() if (istype(pilot, /mob/living/intangible/flock/flockmind)) - flock.addAnnotation(src, "flockmind_face") + flock.addAnnotation(src, FLOCK_ANNOTATION_FLOCKMIND_CONTROL) else - flock.addAnnotation(src, "flocktrace_face") + flock.addAnnotation(src, FLOCK_ANNOTATION_FLOCKTRACE_CONTROL) if (give_alert) boutput(src, "\[SYSTEM: Control of drone [src.real_name] established.\]") @@ -178,9 +178,9 @@ controller.mind.current = controller ticker.minds += controller.mind if (istype(controller, /mob/living/intangible/flock/flockmind)) - flock.removeAnnotation(src, "flockmind_face") + flock.removeAnnotation(src, FLOCK_ANNOTATION_FLOCKMIND_CONTROL) else - flock.removeAnnotation(src, "flocktrace_face") + flock.removeAnnotation(src, FLOCK_ANNOTATION_FLOCKTRACE_CONTROL) if (give_alerts) boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") controller = null From f4067f0d8536095e67521a8f9f3b3ba7bb82aa65 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Thu, 12 May 2022 18:43:27 +0100 Subject: [PATCH 05/16] Some message changes --- code/mob/living/critter/flock/flockdrone.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index ded8705b33..5ceea27881 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -188,17 +188,18 @@ /mob/living/critter/flock/drone/dormantize() src.icon_state = "drone-dormant" src.remove_simple_light("drone_light") + emote("beep") if (!src.flock) ..() return - src.flock.hideAnnotations(src) //hold a ref to the controller so we can put them back with the flock var/mob/living/intangible/flock/old_controller = src.controller if (src.controller) - src.release_control() + src.release_control_abrupt(FALSE) if (old_controller) + boutput(old_controller, "\[SYSTEM: Connection to drone [src.real_name] lost.\]") if (src.flock.getComplexDroneCount()) for (var/mob/living/critter/flock/drone/F in src.flock.units) if (istype(F) && F != src) From 3565317adbee154d65b211162a458b33f3b73757 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Thu, 12 May 2022 22:51:13 +0100 Subject: [PATCH 06/16] cursed use of || Co-authored-by: stonepillars <65367576+stonepillars@users.noreply.github.com> --- code/datums/flock/flock.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/flock/flock.dm b/code/datums/flock/flock.dm index bbcb250ef1..d25534704d 100644 --- a/code/datums/flock/flock.dm +++ b/code/datums/flock/flock.dm @@ -375,7 +375,7 @@ var/image/icon = image(src.annotation_imgs[annotation], loc=target) if (isturf(target)) var/turf/T = target - icon.loc = T.RL_MulOverlay ? T.RL_MulOverlay : T + icon.loc = T.RL_MulOverlay || T active[annotation] = icon get_image_group(src).add_image(icon) From d7372221eb68d3ba67b2268fe9c1f4d9f566e31c Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Tue, 17 May 2022 12:52:31 +0100 Subject: [PATCH 07/16] Flame review --- code/datums/flock/flock.dm | 3 ++- code/mob/living/critter/flock/flockdrone.dm | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/code/datums/flock/flock.dm b/code/datums/flock/flock.dm index 3619ced1b8..d71c2684b0 100644 --- a/code/datums/flock/flock.dm +++ b/code/datums/flock/flock.dm @@ -352,7 +352,7 @@ trace_face.pixel_y = 16 .[FLOCK_ANNOTATION_FLOCKTRACE_CONTROL] = trace_face - var/image/health = image('icons/misc/featherzone.dmi', src, "hp-100") + var/image/health = image('icons/misc/featherzone.dmi', src, icon_state = "hp-100") health.blend_mode = BLEND_ADD health.pixel_x = 10 health.pixel_y = 16 @@ -500,6 +500,7 @@ for(var/mob/M in src.units) hideAnnotations(M) qdel(get_image_group(src)) + annotations = null all_owned_tiles = null busy_tiles = null priority_tiles = null diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 0476338eec..1b2d7e0699 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -143,7 +143,6 @@ flock.addAnnotation(src, FLOCK_ANNOTATION_FLOCKMIND_CONTROL) else flock.addAnnotation(src, FLOCK_ANNOTATION_FLOCKTRACE_CONTROL) - src.update_health_icon() if (give_alert) boutput(src, "\[SYSTEM: Control of drone [src.real_name] established.\]") @@ -152,12 +151,18 @@ if (give_alerts) emote("beep") say(pick_string("flockmind.txt", "flockdrone_player_kicked")) - release_control_abrupt(FALSE) + _drop_control() if (give_alerts) flock_speak(null, "Control of drone [src.real_name] surrended.", src.flock) ///Release control of a drone without blocking calls, so it can be used in ghostize etc. /mob/living/critter/flock/drone/proc/release_control_abrupt(give_alerts = TRUE) + _drop_control() + if (give_alerts) + boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") + +///internal proc +/mob/living/critter/flock/drone/proc/_drop_control() src.flock?.hideAnnotations(src) src.is_npc = TRUE if(src.client && !controller) @@ -182,15 +187,12 @@ flock.removeAnnotation(src, FLOCK_ANNOTATION_FLOCKMIND_CONTROL) else flock.removeAnnotation(src, FLOCK_ANNOTATION_FLOCKTRACE_CONTROL) - if (give_alerts) - boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") controller = null src.update_health_icon() /mob/living/critter/flock/drone/dormantize() src.icon_state = "drone-dormant" src.remove_simple_light("drone_light") - emote("beep") if (!src.flock) ..() From 0462f2db68d9196b7af6d71c9b29a89003b769ea Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Wed, 18 May 2022 03:51:13 +0100 Subject: [PATCH 08/16] flame review 3 --- code/datums/flock/flock.dm | 2 +- code/mob/living/critter/flock/flockdrone.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/datums/flock/flock.dm b/code/datums/flock/flock.dm index d71c2684b0..9847b140d1 100644 --- a/code/datums/flock/flock.dm +++ b/code/datums/flock/flock.dm @@ -352,7 +352,7 @@ trace_face.pixel_y = 16 .[FLOCK_ANNOTATION_FLOCKTRACE_CONTROL] = trace_face - var/image/health = image('icons/misc/featherzone.dmi', src, icon_state = "hp-100") + var/image/health = image('icons/misc/featherzone.dmi', icon_state = "hp-100") health.blend_mode = BLEND_ADD health.pixel_x = 10 health.pixel_y = 16 diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 1b2d7e0699..25bd3de313 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -159,7 +159,7 @@ /mob/living/critter/flock/drone/proc/release_control_abrupt(give_alerts = TRUE) _drop_control() if (give_alerts) - boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") + flock_speak(null, "Control of drone [src.real_name] ended abruptly.", src.flock) ///internal proc /mob/living/critter/flock/drone/proc/_drop_control() From accdd6e81ba69ffcb7572cbeb2f965b018b4ff17 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Wed, 18 May 2022 04:31:28 +0100 Subject: [PATCH 09/16] Flame review 4 --- code/mob/living/critter/flock/flockdrone.dm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 25bd3de313..489aae7ef7 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -151,15 +151,14 @@ if (give_alerts) emote("beep") say(pick_string("flockmind.txt", "flockdrone_player_kicked")) - _drop_control() - if (give_alerts) flock_speak(null, "Control of drone [src.real_name] surrended.", src.flock) + _drop_control() ///Release control of a drone without blocking calls, so it can be used in ghostize etc. /mob/living/critter/flock/drone/proc/release_control_abrupt(give_alerts = TRUE) - _drop_control() if (give_alerts) flock_speak(null, "Control of drone [src.real_name] ended abruptly.", src.flock) + _drop_control() ///internal proc /mob/living/critter/flock/drone/proc/_drop_control() @@ -201,7 +200,7 @@ //hold a ref to the controller so we can put them back with the flock var/mob/living/intangible/flock/old_controller = src.controller if (src.controller) - src.release_control_abrupt(FALSE) + src.release_control(FALSE) if (old_controller) boutput(old_controller, "\[SYSTEM: Connection to drone [src.real_name] lost.\]") if (src.flock.getComplexDroneCount()) From 3e3447440bb5ba8bf1c78ecf81a3c8106d73c541 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Wed, 18 May 2022 04:47:53 +0100 Subject: [PATCH 10/16] Flame review 5 --- code/mob/living/critter/flock/flockdrone.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 489aae7ef7..793573f8ac 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -155,9 +155,8 @@ _drop_control() ///Release control of a drone without blocking calls, so it can be used in ghostize etc. -/mob/living/critter/flock/drone/proc/release_control_abrupt(give_alerts = TRUE) - if (give_alerts) - flock_speak(null, "Control of drone [src.real_name] ended abruptly.", src.flock) +/mob/living/critter/flock/drone/proc/release_control_abrupt() + flock_speak(null, "Control of drone [src.real_name] ended abruptly.", src.flock) _drop_control() ///internal proc From d27dfc1d56d3fdac09cd25f5e11010465ff4a5f1 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Wed, 18 May 2022 05:09:23 +0100 Subject: [PATCH 11/16] Flame review 6 --- code/mob/living/critter/flock/flockdrone.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 793573f8ac..876a9d5cb8 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -196,11 +196,10 @@ ..() return src.flock.hideAnnotations(src) - //hold a ref to the controller so we can put them back with the flock - var/mob/living/intangible/flock/old_controller = src.controller if (src.controller) + //hold a ref to the controller so we can put them back with the flock + var/mob/living/intangible/flock/old_controller = src.controller src.release_control(FALSE) - if (old_controller) boutput(old_controller, "\[SYSTEM: Connection to drone [src.real_name] lost.\]") if (src.flock.getComplexDroneCount()) for (var/mob/living/critter/flock/drone/F in src.flock.units) From d580246346c1ebb6781442bf78cf9d8470d04f25 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Wed, 18 May 2022 06:10:11 +0100 Subject: [PATCH 12/16] Flame review 7 --- code/mob/living/critter/flock/flockdrone.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 876a9d5cb8..84534a337c 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -156,7 +156,7 @@ ///Release control of a drone without blocking calls, so it can be used in ghostize etc. /mob/living/critter/flock/drone/proc/release_control_abrupt() - flock_speak(null, "Control of drone [src.real_name] ended abruptly.", src.flock) + boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") _drop_control() ///internal proc From 65e7fa5f50c2b133cf12632cfd62fb2b13fa90bc Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Wed, 18 May 2022 16:58:01 +0100 Subject: [PATCH 13/16] Update code/datums/flock/flock.dm Co-authored-by: stonepillars <65367576+stonepillars@users.noreply.github.com> --- code/datums/flock/flock.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/flock/flock.dm b/code/datums/flock/flock.dm index 9847b140d1..0131fadaa7 100644 --- a/code/datums/flock/flock.dm +++ b/code/datums/flock/flock.dm @@ -518,7 +518,7 @@ if(name in src.busy_tiles) return src.busy_tiles[name] = T - addAnnotation(T, "reserve") + addAnnotation(T, FLOCK_ANNOTATION_RESERVED) /datum/flock/proc/unreserveTurf(var/name) var/turf/simulated/T = src.busy_tiles[name] From 3bb95a4a4fa9fc96a11e14db9bed69965344ee3f Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Wed, 18 May 2022 17:32:43 +0100 Subject: [PATCH 14/16] Revert release_control changes because atomized PRs --- code/mob/living/critter/flock/flockdrone.dm | 65 ++++++++++++++++----- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index 84534a337c..cc768de141 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -148,19 +148,44 @@ ///Release control of a drone normally /mob/living/critter/flock/drone/proc/release_control(give_alerts = TRUE) + src.flock?.hideAnnotations(src) + src.is_npc = 1 if (give_alerts) emote("beep") say(pick_string("flockmind.txt", "flockdrone_player_kicked")) - flock_speak(null, "Control of drone [src.real_name] surrended.", src.flock) - _drop_control() + if(src.client && !controller) + // don't know how this happened but you need a controller right now + controller = new/mob/living/intangible/flock/trace(src, src.flock) + if(controller) + if (src.floorrunning) + src.end_floorrunning(TRUE) + // move controller out + controller.set_loc(get_turf(src)) + // move us over to the controller + var/datum/mind/mind = src.mind + if (mind) + mind.transfer_to(controller) + else + if (src.client) + var/key = src.client.key + src.client.mob = controller + controller.mind = new /datum/mind() + controller.mind.ckey = ckey + controller.mind.key = key + controller.mind.current = controller + ticker.minds += controller.mind + if (istype(controller, /mob/living/intangible/flock/flockmind)) + flock.removeAnnotation(src, FLOCK_ANNOTATION_FLOCKMIND_CONTROL) + else + flock.removeAnnotation(src, FLOCK_ANNOTATION_FLOCKTRACE_CONTROL) + if (give_alerts) + flock_speak(null, "Control of drone [src.real_name] surrended.", src.flock) + // clear refs + controller = null + src.update_health_icon() -///Release control of a drone without blocking calls, so it can be used in ghostize etc. /mob/living/critter/flock/drone/proc/release_control_abrupt() boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") - _drop_control() - -///internal proc -/mob/living/critter/flock/drone/proc/_drop_control() src.flock?.hideAnnotations(src) src.is_npc = TRUE if(src.client && !controller) @@ -181,6 +206,7 @@ controller.mind.key = key controller.mind.current = controller ticker.minds += controller.mind + boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") if (istype(controller, /mob/living/intangible/flock/flockmind)) flock.removeAnnotation(src, FLOCK_ANNOTATION_FLOCKMIND_CONTROL) else @@ -195,19 +221,32 @@ if (!src.flock) ..() return + src.flock.hideAnnotations(src) + if (src.controller) - //hold a ref to the controller so we can put them back with the flock - var/mob/living/intangible/flock/old_controller = src.controller - src.release_control(FALSE) - boutput(old_controller, "\[SYSTEM: Connection to drone [src.real_name] lost.\]") if (src.flock.getComplexDroneCount()) for (var/mob/living/critter/flock/drone/F in src.flock.units) if (istype(F) && F != src) - old_controller.set_loc(get_turf(F)) + src.controller.set_loc(get_turf(F)) break else - old_controller.set_loc(pick_landmark(LANDMARK_LATEJOIN)) + src.controller.set_loc(pick_landmark(LANDMARK_LATEJOIN)) + + var/datum/mind/mind = src.mind + if (mind) + mind.transfer_to(controller) + else + if (src.client) + var/key = src.client.key + src.client.mob = controller + controller.mind = new /datum/mind() + controller.mind.ckey = ckey + controller.mind.key = key + controller.mind.current = controller + ticker.minds += controller.mind + boutput(controller, "\[SYSTEM: Connection to drone [src.real_name] lost.\]") + controller = null src.is_npc = TRUE // to ensure right flock_speak message if (src.z != Z_LEVEL_NULL) flock_speak(src, "Error: Out of signal range. Disconnecting.", src.flock) From 96d90bfdea8568d839744c6524f4fa52a0d47210 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Wed, 18 May 2022 17:34:21 +0100 Subject: [PATCH 15/16] Missed a couple of lines --- code/mob/living/critter/flock/flockdrone.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/mob/living/critter/flock/flockdrone.dm b/code/mob/living/critter/flock/flockdrone.dm index cc768de141..a5f5d3f93b 100644 --- a/code/mob/living/critter/flock/flockdrone.dm +++ b/code/mob/living/critter/flock/flockdrone.dm @@ -146,7 +146,6 @@ if (give_alert) boutput(src, "\[SYSTEM: Control of drone [src.real_name] established.\]") -///Release control of a drone normally /mob/living/critter/flock/drone/proc/release_control(give_alerts = TRUE) src.flock?.hideAnnotations(src) src.is_npc = 1 @@ -185,7 +184,6 @@ src.update_health_icon() /mob/living/critter/flock/drone/proc/release_control_abrupt() - boutput(controller, "\[SYSTEM: Control of drone [src.real_name] ended abruptly.\]") src.flock?.hideAnnotations(src) src.is_npc = TRUE if(src.client && !controller) From 0654572be81332b68204c2a83ad006e6dde2effd Mon Sep 17 00:00:00 2001 From: stonepillars <65367576+stonepillars@users.noreply.github.com> Date: Wed, 18 May 2022 20:30:18 -0400 Subject: [PATCH 16/16] Update code/datums/flock/flock.dm --- code/datums/flock/flock.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/flock/flock.dm b/code/datums/flock/flock.dm index 0131fadaa7..e43ee78a16 100644 --- a/code/datums/flock/flock.dm +++ b/code/datums/flock/flock.dm @@ -523,7 +523,7 @@ /datum/flock/proc/unreserveTurf(var/name) var/turf/simulated/T = src.busy_tiles[name] src.busy_tiles -= name - removeAnnotation(T, "reserve") + removeAnnotation(T, FLOCK_ANNOTATION_RESERVED) /datum/flock/proc/claimTurf(var/turf/simulated/T) src.all_owned_tiles |= T