~gpcf/advtrains-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
5 2

[Discussion] [API] advtrains.get_wagon_at_pos(pos)

Details
Message ID
<f34bf13b-5c97-0d69-525b-ac19b9685117@gmail.com>
DKIM signature
missing
Download raw message
Is there an easy way to check whether there's a wagon at <pos>?
I'm currently looking to make the freight tracks more into a loading 
ramp than (un)loading the entire train at once.

My current plan is an ABM/nodetimer/globalstep that raycasts to 1m above 
the track to check for pointed_thing.type=="entity", getting the wagon 
id and subsequent detatched inventory from the entity's id field.
After (un)loading the wagon, the 
:set_textures(advtrains.wagons[wagon_id]) method would be called to 
automagically update the model/texture on a per-wagon basis.

Of course this would be very laggy, so checking 
advtrains.is_node_loaded(pos) would return functionality to the current 
method of (un)loading if the area isn't loaded.
I know there's advtrains.get_train_at_pos(pos) but I need a little more 
granularity for this than the entire train...

Example function:
function advtrains.get_wagon_at_pos(pos)
     if wagon_at_pos then return wagon_id end
     return nil
end

Just a thought :)
Details
Message ID
<0e6eb230-e673-8c29-4842-5397f4f862d1@forksworld.de>
In-Reply-To
<f34bf13b-5c97-0d69-525b-ac19b9685117@gmail.com> (view parent)
DKIM signature
missing
Download raw message
> Is there an easy way to check whether there's a wagon at <pos>?

You can check for the trains at a position using 
advtrains.occ.get_trains_at(pos). The returned value is in the form of 
{[id] = path_index}, so you can probably find the specific wagon by 
iterating through train.trainparts until you find the wagon whose offset 
(range) includes the particular index. Something along the lines of:

function get_wagon_at(pos)
	local t = {}
	for id, idx in pairs(advtrains.occ.get_trains_at(pos)) do
		local bp, p
		for _, wid in ipairs(advtrains.trains[id].trainparts) do
			local w = advtrains.wagons[wid]
			local wp = advtrains.wagon_prototypes[w.type]
			p, bp = bp, bp+wp.wagon_span
			if idx <= bp then
				t[wid] = idx-p
				break
			end
		end
	end
	return t
end

(Note: I have not yet tested the above code.)

[PATCH] Add API to get wagons at a specific position

Details
Message ID
<20230527083408.16568-1-yw05@forksworld.de>
In-Reply-To
<0e6eb230-e673-8c29-4842-5397f4f862d1@forksworld.de> (view parent)
DKIM signature
missing
Download raw message
Patch: +31 -0
---
 advtrains/occupation.lua | 14 ++++++++++++++
 advtrains/trainlogic.lua | 17 +++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/advtrains/occupation.lua b/advtrains/occupation.lua
index db39991..18e3f2b 100644
--- a/advtrains/occupation.lua
+++ b/advtrains/occupation.lua
@@ -186,6 +186,20 @@ function o.get_trains_at(ppos)
	return r
end

-- Gets a mapping of wagon id's to offsets of wagons that stand or drive over;
-- the offset is relative to the center of the wagon
-- returns (table with wagon_id->offset)
function o.get_wagons_at(pos)
	local r = {}
	for id, idx in pairs(o.get_trains_at(pos)) do
		local w, offset = advtrains.get_wagon_at_index(id, idx)
		if w then
			r[w.id] = offset
		end
	end
	return r
end

-- Gets a mapping of train id's to indexes of trains that have a path
-- generated over this node
-- returns (table with train_id->index)
diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua
index 288e224..186a7ff 100644
--- a/advtrains/trainlogic.lua
+++ b/advtrains/trainlogic.lua
@@ -1238,6 +1238,23 @@ function advtrains.get_train_at_pos(pos)
	end
end

function advtrains.get_wagon_at_index(train, index)
	if train == nil then
		return
	elseif type(train) ~= "table" then
		return advtrains.get_wagon_at_index(advtrains.trains[train], index)
	end
	local offset = train.index - index
	local p0, p1 = 0, 0
	for _, wid in ipairs(train.trainparts) do
		local wagon = advtrains.wagons[wid]
		local wp = advtrains.wagon_prototypes[wagon.type] or advtrains.wagon_prototypes["advtrains:wagon_placeholder"]
		p0, p1 = p1, p1+2*wp.wagon_span
		if offset <= p1 then
			return wagon, wagon.pos_in_train - offset
		end
	end
end

-- ehm... I never adapted this function to the new path system ?!
function advtrains.invalidate_all_paths(pos)
-- 
2.40.1
Details
Message ID
<20230527121305.000068ba@bleipb.de>
In-Reply-To
<0e6eb230-e673-8c29-4842-5397f4f862d1@forksworld.de> (view parent)
DKIM signature
missing
Download raw message
Hi,

yes, generally this is the right way to do. However you need to be
careful because the index does not necessarily match the real position
(an index of 1 can be a distance greater than 1)

Since I have some time today, I added such a function in 283efc4. You
should be able to use it right away.

Regards,
orwell
Details
Message ID
<20230527121713.0000421d@bleipb.de>
In-Reply-To
<0e6eb230-e673-8c29-4842-5397f4f862d1@forksworld.de> (view parent)
DKIM signature
missing
Download raw message
Hi again,

Just noticed you added a patch here an hour ago... Which means we were
working in parallel.

My remark still holds though, and I believe my implementation is
correct.

Regards,
orwell
Details
Message ID
<2eaccb2c-059c-37e8-574e-cc9d7adac6e4@forksworld.de>
In-Reply-To
<20230527121713.0000421d@bleipb.de> (view parent)
DKIM signature
missing
Download raw message
> Just noticed you added a patch here an hour ago... Which means we were
> working in parallel.
> 
> My remark still holds though, and I believe my implementation is
> correct.

Agreed. I put together that patch based on reading some existing code 
and my (limited) knowledge of the path system.

Anyway, I wrote that function as an auxiliary function for 
occ.get_wagon_at(pos) since Maverick2797 wanted to get the wagon at a 
speicific position; the idea is to use occ.get_trains_at(pos) and remap 
the returned table to wagons (instead of trains).

A function to return a _single_ wagon at the position should IMO not be 
necessary as a occ.get_trains_at(pos)-like function would allow you to 
get it using next(occ.get_wagons_at(pos)).
Reply to thread Export thread (mbox)