-
Notifications
You must be signed in to change notification settings - Fork 10
Technic compatibility with fully contained network move capability #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
S-S-X
wants to merge
7
commits into
master
Choose a base branch
from
technic-compat
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+135
−2
Draft
Changes from 4 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
c48237f
Technic network-ng compatibility with fully contained network move ca…
74f51b0
Full edge network detection, fix typos
9b75a2b
Luacheck, check for technic mod
aee3514
Also check for technic name space
2087759
Reassign moved network for new id key
6c19307
Merge branch 'master' into technic-compat
BuckarooBanzay 84fa15c
fix luacheck
BuckarooBanzay File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
|
||
local vecadd = vector.add | ||
local poshash = minetest.hash_node_position | ||
local get_node = minetest.get_node | ||
local cables = technic and technic.cables | ||
local machines = technic and technic.machine_tiers | ||
|
||
-- Check for technic mod compatibility, compatible with technic plus | ||
if not technic or not technic.remove_network or not technic.networks or not cables or not machines then | ||
minetest.log("warning", "[jumpdrive] Incompatible technic mod loaded") | ||
jumpdrive.technic_network_compat = function() end | ||
return | ||
end | ||
|
||
-- Function to move technic network to another position | ||
local network_node_arrays = {"PR_nodes","BA_nodes","RE_nodes"} | ||
local function move_network(net, delta) | ||
for _,tblname in ipairs(network_node_arrays) do | ||
local tbl = net[tblname] | ||
for i=#tbl,1,-1 do | ||
tbl[i] = vecadd(tbl[i], delta) | ||
end | ||
end | ||
local new_net_id = poshash(vecadd(technic.network2pos(net.id), delta)) | ||
local new_all_nodes = {} | ||
local all_nodes = net.all_nodes | ||
for old_node_id, old_pos in pairs(all_nodes) do | ||
local new_pos = vecadd(old_pos, delta) | ||
local node_id = poshash(new_pos) | ||
cables[old_node_id] = nil | ||
cables[node_id] = new_net_id | ||
new_all_nodes[node_id] = new_pos | ||
end | ||
net.all_nodes = new_all_nodes | ||
end | ||
|
||
local function vecadd2(a, b, c) | ||
return { | ||
x = a.x + b.x + c.x, | ||
y = a.y + b.y + c.y, | ||
z = a.z + b.z + c.z, | ||
} | ||
end | ||
|
||
local function add_edge_cable_net(pos, size, delta, t) | ||
-- Find connected positions outside edge of box from given position | ||
-- NOTE: At source position first found would be enough but not at target | ||
local x = pos.x == 0 and -1 or (pos.x == size.x and 1) | ||
local y = pos.y == 0 and -1 or (pos.y == size.y and 1) | ||
local z = pos.z == 0 and -1 or (pos.z == size.z and 1) | ||
if x then | ||
local v = vecadd2(pos, {x=x,y=0,z=0}, delta) | ||
local net_id = cables[poshash(v)] | ||
if net_id then t[net_id] = true end | ||
end | ||
if y then | ||
local v = vecadd2(pos, {x=0,y=y,z=0}, delta) | ||
local net_id = cables[poshash(v)] | ||
if net_id then t[net_id] = true end | ||
end | ||
if z then | ||
local v = vecadd2(pos, {x=0,y=0,z=z}, delta) | ||
local net_id = cables[poshash(v)] | ||
if net_id then t[net_id] = true end | ||
end | ||
return x, y, z | ||
end | ||
|
||
jumpdrive.technic_network_compat = function(source_pos1, source_pos2, target_pos1, delta_vector) | ||
|
||
-- search results | ||
local jump_networks = {} -- jumped fully contained networks | ||
local edge_networks = {} -- networks crossing jumped area edge | ||
|
||
-- search for networks in area | ||
local size = vector.apply(vector.subtract(source_pos1, source_pos2),math.abs) | ||
for x=0,size.x do | ||
for y=0,size.y do | ||
for z=0,size.z do | ||
local local_pos = {x=x,y=y,z=z} | ||
local src_pos = vecadd(source_pos1, local_pos) | ||
local net_id = cables[poshash(src_pos)] | ||
if net_id then | ||
-- Add to (dirty) jumped fully contained networks | ||
jump_networks[net_id] = true | ||
end | ||
if x==0 or x==size.x or y==0 or y==size.y or z==0 or z==size.z then | ||
-- Candidate for border crossing network, check neighbors across border | ||
if net_id then | ||
-- Inside network is active, check outside for active and inactive | ||
local dir_x, dir_y, dir_z = add_edge_cable_net(local_pos, size, source_pos1, edge_networks) | ||
if dir_x then | ||
local name = get_node(vecadd2(local_pos, target_pos1, {x=dir_x,y=0,z=0})).name | ||
if machines[name] or technic.get_cable_tier(name) then edge_networks[net_id] = true end | ||
end | ||
if dir_y then | ||
local name = get_node(vecadd2(local_pos, target_pos1, {x=0,y=dir_y,z=0})).name | ||
if machines[name] or technic.get_cable_tier(name) then edge_networks[net_id] = true end | ||
end | ||
if dir_z then | ||
local name = get_node(vecadd2(local_pos, target_pos1, {x=0,y=0,z=dir_z})).name | ||
if machines[name] or technic.get_cable_tier(name) then edge_networks[net_id] = true end | ||
end | ||
else | ||
-- Inside is inactive, check outside for active | ||
add_edge_cable_net(local_pos, size, target_pos1, edge_networks) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
for net_id, _ in pairs(edge_networks) do | ||
-- Remove edge networks to create contained networks list | ||
jump_networks[net_id] = nil | ||
-- And clean up network crossing jumped area edges | ||
technic.remove_network(net_id) | ||
end | ||
for net_id, _ in pairs(jump_networks) do | ||
-- Move fully contained networks with jumpdrive | ||
local net = technic.networks[net_id] | ||
if net then | ||
move_network(net, delta_vector) | ||
end | ||
end | ||
end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem here is when large areas are jumped, this most probably is not even near most efficient method to check nodes in area.
Any suggestions for better way?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to find_nodes_in_area and include cable groups and machine group, if that is significantly faster way to get nodes then loop here could be a lot shorter especially for large areas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uhm, this does not sound really efficient, would that be another use-case in that #47 could help with. It would need to be defined on every cable-definition (and possibly on the switching station):
This way the nested for-loops could be replaced with some logic within the jumpdrive mod (one nested for-loop is better than 2 of them, right?).
Let me know if something like that would help and if the parameters are enough (from- and to-position) i think i have some time to implement this and rewrite the jump-compatibility functions (or even move it to the external mods)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, thing is with R15 it is still well over 50% faster than rebuilding network. I think mostly because it is very rare to read any nodes from world (only around edges of box when there is also active network at location) but other than that it is pure math.
But also can clearly see how performance degrades when area gets bigger, that is because of looping over all locations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Node move cannot be used alone, did you notice that this loop also checks taget and source around jumped area for possible network connections at target and cable cutting at source.
It could be used if there's information about location in jumped area so that connections across edge can be checked.
But it would work yes with few additions and possibly better than blindly looping through whole area.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would provide a way to react on single nodes and to process/finalize the whole after a jump:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so
additional_info.edge
would contain 1-3 edge directions / vector representing directions, that would work yes.Most of logic from this PR could be moved to finalization and if
edge
provides vector for 90 degree directions relative to edge wall then that could also be skipped in node move implementation for networks.I think that could be useful for some other things too that can depend on nearby stuff outside of source or target area.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, tried with following. Removed nested loops and used 254 nodes instead of 29791 nodes.
those nested loops were about 8 times faster...
actually after testing more hoping to get caches warmed those nested loops seem to be over 10 times faster on average
tested this with R15
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, it does not (yet) only a boolean value if it is on the edge 😋
But i guess returning a vector for the edge-position should be fairly easy, something along the lines of this:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could put up some simple test for this and if it still seems that nested loops using just pure math is better then maybe good option would be to implement actual network moving in technic mod instead and just call some
technic.move_network(source1, source2, target1)
from here.But seems that needs some testing, and possibility to register move callback for nodes will be useful no matter how network data moving will be actually implemented.