Skip to content

Commit

Permalink
Fixes xeno tunnel tracking (#5536)
Browse files Browse the repository at this point in the history
# About the pull request

I swear I do actually test my PRs 😢.

Fixes #5529 by refactoring the 'Queen locator' to track targets with
`/datum/weakref`s, rather than their index in a global list.

# Explain why it's good for the game

Bugfix. (Honestly no idea how I missed this one)

It makes the code much simpler and easier to understand (arguably).

# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>


https://github.com/cmss13-devs/cmss13/assets/57483089/97552c21-c28a-49a8-a4aa-6ff03209062e

</details>


# Changelog
:cl:
fix: Fixed the xeno 'queen locator' giving the wrong location when a
tunnel was selected.
/:cl:
  • Loading branch information
SabreML committed Jan 26, 2024
1 parent 66bebba commit 7e13948
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 65 deletions.
38 changes: 23 additions & 15 deletions code/_onclick/hud/screen_objects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,11 @@
name = "queen locator"
icon = 'icons/mob/hud/alien_standard.dmi'
icon_state = "trackoff"
var/list/track_state = list(TRACKER_QUEEN, 0)
/// A weak reference to the atom currently being tracked.
/// (Note: This is null for `TRACKER_QUEEN` and `TRACKER_HIVE`, as those are accessed through the user's hive datum.)
var/datum/weakref/tracking_ref = null
/// The 'category' of the atom currently being tracked. (Defaults to `TRACKER_QUEEN`)
var/tracker_type = TRACKER_QUEEN

/atom/movable/screen/queen_locator/clicked(mob/living/carbon/xenomorph/user, mods)
if(!istype(user))
Expand All @@ -520,35 +524,39 @@
if(mods["alt"])
var/list/options = list()
if(user.hive.living_xeno_queen)
options["Queen"] = list(TRACKER_QUEEN, 0)
// Don't need weakrefs to this or the hive core, since there's only one possible target.
options["Queen"] = list(null, TRACKER_QUEEN)

if(user.hive.hive_location)
options["Hive Core"] = list(TRACKER_HIVE, 0)
options["Hive Core"] = list(null, TRACKER_HIVE)

var/xeno_leader_index = 1
for(var/xeno in user.hive.xeno_leader_list)
var/mob/living/carbon/xenomorph/xeno_lead = user.hive.xeno_leader_list[xeno_leader_index]
if(xeno_lead)
options["Xeno Leader [xeno_lead]"] = list(TRACKER_LEADER, xeno_leader_index)
xeno_leader_index++
for(var/mob/living/carbon/xenomorph/leader in user.hive.xeno_leader_list)
options["Xeno Leader [leader]"] = list(leader, TRACKER_LEADER)

var/list/sorted_tunnels = sort_list_dist(user.hive.tunnels, get_turf(user))
var/tunnel_index = 1
for(var/obj/structure/tunnel/tunnel in sorted_tunnels)
options["Tunnel [tunnel.tunnel_desc]"] = list(TRACKER_TUNNEL, tunnel_index)
tunnel_index++
for(var/obj/structure/tunnel/tunnel as anything in sorted_tunnels)
options["Tunnel [tunnel.tunnel_desc]"] = list(tunnel, TRACKER_TUNNEL)

var/selected = tgui_input_list(user, "Select what you want the locator to track.", "Locator Options", options)
var/list/selected = tgui_input_list(user, "Select what you want the locator to track.", "Locator Options", options)
if(selected)
track_state = options[selected]
var/selected_data = options[selected]
tracking_ref = WEAKREF(selected_data[1]) // Weakref to the tracked atom (or null)
tracker_type = selected_data[2] // Tracker category
return

if(!user.hive.living_xeno_queen)
to_chat(user, SPAN_WARNING("Our hive doesn't have a living queen!"))
return FALSE
if(HAS_TRAIT(user, TRAIT_ABILITY_BURROWED) || user.is_mob_incapacitated() || user.buckled)
return FALSE
user.overwatch(user.hive.living_xeno_queen)

// Reset to the defaults
/atom/movable/screen/queen_locator/proc/reset_tracking()
icon_state = "trackoff"
tracking_ref = null
tracker_type = TRACKER_QUEEN

/atom/movable/screen/xenonightvision
icon = 'icons/mob/hud/alien_standard.dmi'
name = "toggle night vision"
Expand Down
77 changes: 27 additions & 50 deletions code/modules/mob/living/carbon/xenomorph/life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -391,75 +391,52 @@ Make sure their actual health updates immediately.*/
hud_set_plasma() //update plasma amount on the plasma mob_hud

/mob/living/carbon/xenomorph/proc/queen_locator()
if(!hud_used || !hud_used.locate_leader)
if(!hud_used?.locate_leader)
return

var/atom/movable/screen/queen_locator/QL = hud_used.locate_leader
if(!loc)
QL.icon_state = "trackoff"
var/atom/movable/screen/queen_locator/locator = hud_used.locate_leader
if(!loc || !hive)
locator.reset_tracking()
return

var/atom/tracking_atom
switch(QL.track_state[1])
switch(locator.tracker_type)
if(TRACKER_QUEEN)
if(!hive || !hive.living_xeno_queen)
QL.icon_state = "trackoff"
return
tracking_atom = hive.living_xeno_queen
if(TRACKER_HIVE)
if(!hive || !hive.hive_location)
QL.icon_state = "trackoff"
return
tracking_atom = hive.hive_location
if(TRACKER_LEADER)
if(!QL.track_state[2])
QL.icon_state = "trackoff"
return

var/leader_tracker = QL.track_state[2]

if(!hive || !hive.xeno_leader_list)
QL.icon_state = "trackoff"
return
if(leader_tracker > hive.xeno_leader_list.len)
QL.icon_state = "trackoff"
return
if(!hive.xeno_leader_list[leader_tracker])
QL.icon_state = "trackoff"
return
tracking_atom = hive.xeno_leader_list[leader_tracker]
var/atom/leader = locator.tracking_ref?.resolve()
// If the leader exists, and is actually in the leader list.
if(leader && (leader in hive.xeno_leader_list))
tracking_atom = leader
if(TRACKER_TUNNEL)
if(!QL.track_state[2])
QL.icon_state = "trackoff"
return
tracking_atom = locator.tracking_ref?.resolve()

var/tunnel_tracker = QL.track_state[2]
// If the atom can't be found/has been deleted.
if(!tracking_atom)
var/already_tracking_queen = (locator.tracker_type == TRACKER_QUEEN)

if(!hive || !hive.tunnels)
QL.icon_state = "trackoff"
return
if(tunnel_tracker > hive.tunnels.len)
QL.icon_state = "trackoff"
return
if(!hive.tunnels[tunnel_tracker])
QL.icon_state = "trackoff"
return
tracking_atom = hive.tunnels[tunnel_tracker]
// Reset the tracker back to the queen.
locator.reset_tracking()

if(!tracking_atom)
QL.icon_state = "trackoff"
// If it wasn't the queen that couldn't be found above, try again with her as the target.
// This is just to avoid the tracker going blank for one life tick.
// (There's no risk of an infinite loop here since `locator.tracker_type` just got set to `TRACKER_QUEEN`.)
if(!already_tracking_queen)
queen_locator()
return

if(tracking_atom.loc.z != loc.z || get_dist(src, tracking_atom) < 1 || src == tracking_atom)
QL.icon_state = "trackondirect"
locator.icon_state = "trackondirect"
else
var/area/A = get_area(loc)
var/area/QA = get_area(tracking_atom.loc)
if(A.fake_zlevel == QA.fake_zlevel)
QL.setDir(Get_Compass_Dir(src, tracking_atom))
QL.icon_state = "trackon"
var/area/our_area = get_area(loc)
var/area/target_area = get_area(tracking_atom.loc)
if(our_area.fake_zlevel == target_area.fake_zlevel)
locator.setDir(Get_Compass_Dir(src, tracking_atom))
locator.icon_state = "trackon"
else
QL.icon_state = "trackondirect"
locator.icon_state = "trackondirect"

/mob/living/carbon/xenomorph/proc/mark_locator()
if(!hud_used || !hud_used.locate_marker || !tracked_marker.loc || !loc)
Expand Down

0 comments on commit 7e13948

Please sign in to comment.