mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 12:35:33 +01:00
[MIRROR] Redoes how merger datums store directions to neighboring members [MDB IGNORE] (#11238)
* Redoes how merger datums store directions to neighboring members (#64535) The old logic broke down if A: there were more then one eligable member on a tile Or B: if the members were in anything but a line The old code made the assumption that if a location had been talked to ever, it was done talking forever. This isn't the case. Also it kinda pissed me off that cost scaled with objects, not tiles. So I changed how things were tracked to fix those things. Makes me happy inside * Redoes how merger datums store directions to neighboring members Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
// Defines relating to merger datums
|
||||
|
||||
// Indexes for the turf packet list
|
||||
#define MERGE_TURF_PACKET_DIR 1
|
||||
#define MERGE_TURF_PACKET_ATOMS 2
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/// The arbitrary "owner" member of the merge group
|
||||
var/atom/origin
|
||||
/// A list of all members in the group
|
||||
/// Assoc list of all members in the group -> dirs from them to their connected nighbors
|
||||
var/list/members = list()
|
||||
|
||||
#if MERGERS_DEBUG
|
||||
@@ -83,56 +83,78 @@
|
||||
addtimer(CALLBACK(src, .proc/Refresh), 1, TIMER_UNIQUE)
|
||||
|
||||
/datum/merger/proc/Refresh()
|
||||
var/list/tips = list()
|
||||
var/list/checked_turfs = list()
|
||||
var/list/new_members = list()
|
||||
// List of turf -> list(interesting dir, found matching atoms)
|
||||
var/list/found_turfs = list()
|
||||
if(origin)
|
||||
tips[origin] = NORTH|EAST|SOUTH|WEST
|
||||
new_members[origin] = NONE
|
||||
while(length(tips))
|
||||
var/atom/focus = tips[length(tips)]
|
||||
var/dirs_to_check = tips[focus]
|
||||
tips.len--
|
||||
var/turf/starting = get_turf(origin)
|
||||
check_turf(starting, found_turfs, NONE)
|
||||
for(var/i = 1; i <= length(found_turfs), i++)
|
||||
var/turf/focus = found_turfs[i]
|
||||
var/list/focus_packet = found_turfs[focus]
|
||||
var/dirs_checked = focus_packet[MERGE_TURF_PACKET_DIR]
|
||||
for(var/dir in GLOB.cardinals)
|
||||
if(!(dirs_to_check & dir))
|
||||
if(dirs_checked & dir)
|
||||
continue
|
||||
var/turf/location = get_step(focus, dir)
|
||||
if(!location || checked_turfs[location])
|
||||
if(!location)
|
||||
continue
|
||||
checked_turfs[location] = TRUE
|
||||
for(var/i in location)
|
||||
var/atom/movable/thing = i
|
||||
if(!merged_typecache[thing.type])
|
||||
continue
|
||||
if(attempt_merge_proc && !call(thing, attempt_merge_proc)(src, new_members))
|
||||
continue
|
||||
if(thing.mergers && thing.mergers[id] != src)
|
||||
var/datum/merger/existing = thing.mergers[id]
|
||||
qdel(src)
|
||||
existing.Refresh()
|
||||
if(!check_turf(location, found_turfs, dir))
|
||||
if(QDELETED(src))
|
||||
return
|
||||
new_members[focus] |= dir // This is not a list, value of the members list is a bitfield of dirs
|
||||
var/next_dirs = turn(dir, 180)
|
||||
new_members[thing] |= next_dirs
|
||||
next_dirs = ~next_dirs
|
||||
var/existing = tips[thing] || (NORTH|EAST|SOUTH|WEST)
|
||||
tips[thing] = existing & next_dirs
|
||||
continue
|
||||
focus_packet[MERGE_TURF_PACKET_DIR] |= dir
|
||||
|
||||
var/list/leaving_members = members - new_members
|
||||
// Now that we have an idea of our connecting directions, build the fresh members list
|
||||
var/list/fresh_members = list()
|
||||
for(var/turf/location as anything in found_turfs)
|
||||
var/list/turf_packet = found_turfs[location]
|
||||
var/connected_dirs = turf_packet[MERGE_TURF_PACKET_DIR]
|
||||
for(var/datum/member as anything in turf_packet[MERGE_TURF_PACKET_ATOMS])
|
||||
fresh_members[member] = connected_dirs
|
||||
|
||||
var/list/leaving_members = members - fresh_members
|
||||
for(var/atom/thing as anything in leaving_members)
|
||||
RemoveMember(thing)
|
||||
|
||||
var/list/joining_members = new_members - members
|
||||
var/list/joining_members = fresh_members - members
|
||||
for(var/atom/thing as anything in joining_members)
|
||||
AddMember(thing, joining_members[thing])
|
||||
|
||||
// They may not need a full update but the connected dirs could change
|
||||
for(var/atom/thing as anything in new_members)
|
||||
members[thing] = new_members[thing]
|
||||
for(var/atom/thing as anything in fresh_members)
|
||||
members[thing] = fresh_members[thing]
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MERGER_REFRESH_COMPLETE, leaving_members, joining_members)
|
||||
|
||||
if(!length(members))
|
||||
qdel(src)
|
||||
|
||||
// Checks to see if the passed in location contains something interesting to us. If it does, return TRUE, otherwise return false
|
||||
// If it is interesting, we add it to our processing list
|
||||
/datum/merger/proc/check_turf(turf/location, list/found_turfs, asking_from)
|
||||
var/found_something = FALSE
|
||||
// if asking_from is invalid (like if it's 0), we get a random output. that's bad, let's check for falsyness
|
||||
var/us_to_them = asking_from && turn(asking_from, 180)
|
||||
|
||||
if(found_turfs[location])
|
||||
found_turfs[location][MERGE_TURF_PACKET_DIR] |= us_to_them
|
||||
return TRUE
|
||||
|
||||
for(var/atom/movable/thing as anything in location)
|
||||
if(!merged_typecache[thing.type])
|
||||
continue
|
||||
if(attempt_merge_proc && !call(thing, attempt_merge_proc)(src, found_turfs))
|
||||
continue
|
||||
if(thing.mergers && thing.mergers[id] != src)
|
||||
var/datum/merger/existing = thing.mergers[id]
|
||||
qdel(src)
|
||||
existing.Refresh()
|
||||
return FALSE
|
||||
if(!found_turfs[location])
|
||||
found_turfs[location] = list(us_to_them, list())
|
||||
found_turfs[location][MERGE_TURF_PACKET_ATOMS] += thing
|
||||
found_something = TRUE
|
||||
|
||||
return found_something
|
||||
|
||||
#undef MERGERS_DEBUG
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
#include "code\__DEFINES\mecha.dm"
|
||||
#include "code\__DEFINES\melee.dm"
|
||||
#include "code\__DEFINES\memory_defines.dm"
|
||||
#include "code\__DEFINES\mergers.dm"
|
||||
#include "code\__DEFINES\mob_spawn.dm"
|
||||
#include "code\__DEFINES\mobs.dm"
|
||||
#include "code\__DEFINES\mod.dm"
|
||||
|
||||
Reference in New Issue
Block a user