~gpcf/advtrains-devel

Wagon iterator, lookup by id, and use them in code v7 SUPERSEDED

1F616EMO: 1
 Wagon iterator, lookup by id, and use them in code

 2 files changed, 72 insertions(+), 52 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~gpcf/advtrains-devel/patches/55040/mbox | git am -3
Learn more about email & git

[PATCH v7] Wagon iterator, lookup by id, and use them in code Export this patch

From: 1F616EMO <root@1f616emo.xyz>

---
After observing the Linux mailing list, I figured out I should open a new thread for new patch... oops.

 advtrains/trainlogic.lua |  19 +++----
 advtrains/wagons.lua     | 105 ++++++++++++++++++++++++---------------
 2 files changed, 72 insertions(+), 52 deletions(-)

diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua
index f136577..ce646da 100644
--- a/advtrains/trainlogic.lua
+++ b/advtrains/trainlogic.lua
@@ -142,13 +142,8 @@ minetest.register_on_joinplayer(function(player)
		local pname = player:get_player_name()
		local id=advtrains.player_to_train_mapping[pname]
		if id then
			for _,wagon in pairs(minetest.luaentities) do
				if wagon.is_wagon and wagon.initialized and wagon.id then
					local wdata = advtrains.wagons[wagon.id]
					if wdata and wdata.train_id == id then
						wagon:reattach_all()
					end
				end
			for _, wagon in advtrains.wagon_entity_pairs_in_train(id) do
				wagon:reattach_all()
			end
		end
end)
@@ -160,12 +155,10 @@ minetest.register_on_dieplayer(function(player)
		if id then
			local train=advtrains.trains[id]
			if not train then advtrains.player_to_train_mapping[pname]=nil return end
			for _,wagon in pairs(minetest.luaentities) do
				if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
					--when player dies, detach him from the train
					--call get_off_plr on every wagon since we don't know which one he's on.
					wagon:get_off_plr(pname)
				end
			for _, wagon in advtrains.wagon_entity_pairs_in_train(id) do
				--when player dies, detach him from the train
				--call get_off_plr on every wagon since we don't know which one he's on.
				wagon:get_off_plr(pname)
			end
			-- just in case no wagon felt responsible for this player: clear train mapping
			advtrains.player_to_train_mapping[pname] = nil
diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua
index 536c8d4..a7ebeea 100644
--- a/advtrains/wagons.lua
+++ b/advtrains/wagons.lua
@@ -1103,12 +1103,11 @@ function wagon:handle_bordcom_fields(pname, formname, fields)
	for i, tpid in ipairs(train.trainparts) do
		if fields["dcpl_"..i] then
			advtrains.safe_decouple_wagon(tpid, pname)
		elseif fields["wgprp"..i] then
			for _,wagon in pairs(minetest.luaentities) do
				if wagon.is_wagon and wagon.initialized and wagon.id==tpid and data.owner==pname then
					wagon:show_wagon_properties(pname)
					return
				end
		elseif fields["wgprp"..i] and data.owner==pname then
			local wagon = advtrains.get_wagon_entity(tpid)
			if wagon then
				wagon:show_wagon_properties(pname)
				return
			end
		end
	end
@@ -1154,44 +1153,48 @@ end
minetest.register_on_player_receive_fields(function(player, formname, fields)
		local uid=string.match(formname, "^advtrains_geton_(.+)$")
		if uid then
			for _,wagon in pairs(minetest.luaentities) do
				if wagon.is_wagon and wagon.initialized and wagon.id==uid then
					local data = advtrains.wagons[wagon.id]
					if fields.inv then
						if wagon.has_inventory and wagon.get_inventory_formspec then
							minetest.show_formspec(player:get_player_name(), "advtrains_inv_"..uid, wagon:get_inventory_formspec(player:get_player_name(), make_inv_name(uid)))
						end
					elseif fields.seat then
						local val=minetest.explode_textlist_event(fields.seat)
						if val and val.type~="INV" and not data.seatp[player:get_player_name()] then
						--get on
							wagon:get_on(player, val.index)
							--will work with the new close_formspec functionality. close exactly this formspec.
							minetest.show_formspec(player:get_player_name(), formname, "")
						end
			local wagon = advtrains.get_wagon_entity(uid)
			if wagon then
				local data = advtrains.wagons[wagon.id]
				if fields.inv then
					if wagon.has_inventory and wagon.get_inventory_formspec then
						minetest.show_formspec(player:get_player_name(), "advtrains_inv_"..uid, wagon:get_inventory_formspec(player:get_player_name(), make_inv_name(uid)))
					end
				elseif fields.seat then
					local val=minetest.explode_textlist_event(fields.seat)
					if val and val.type~="INV" and not data.seatp[player:get_player_name()] then
					--get on
						wagon:get_on(player, val.index)
						--will work with the new close_formspec functionality. close exactly this formspec.
						minetest.show_formspec(player:get_player_name(), formname, "")
					end
				end
			end
			return true
		end

		uid=string.match(formname, "^advtrains_seating_(.+)$")
		if uid then
			for _,wagon in pairs(minetest.luaentities) do
				if wagon.is_wagon and wagon.initialized and wagon.id==uid then
					local pname=player:get_player_name()
					local no=wagon:get_seatno(pname)
					if no then
						if wagon.seat_groups then
							wagon:seating_from_key_helper(pname, fields, no)
						end
			local wagon = advtrains.get_wagon_entity(uid)
			if wagon then
				local pname=player:get_player_name()
				local no=wagon:get_seatno(pname)
				if no then
					if wagon.seat_groups then
						wagon:seating_from_key_helper(pname, fields, no)
					end
				end
			end
			return true
		end

		uid=string.match(formname, "^advtrains_prop_(.+)$")
		if uid then
			local pname=player:get_player_name()
			local data = advtrains.wagons[uid]
			if pname~=data.owner and not minetest.check_player_privs(pname, {train_admin = true}) then
			if not data then
				return true
			elseif pname~=data.owner and not minetest.check_player_privs(pname, {train_admin = true}) then
				return true
			end
			if fields.save or not fields.quit then
@@ -1213,29 +1216,32 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
					wagon.show_wagon_properties({id=uid}, pname)
				end
			end
			return true
		end
		uid=string.match(formname, "^advtrains_bordcom_(.+)$")
		if uid then
			for _,wagon in pairs(minetest.luaentities) do
				if wagon.is_wagon and wagon.initialized and wagon.id==uid then
					wagon:handle_bordcom_fields(player:get_player_name(), formname, fields)
				end
			local wagon = advtrains.get_wagon_entity(uid)
			if wagon then
				wagon:handle_bordcom_fields(player:get_player_name(), formname, fields)
			end
			return true
		end

		uid=string.match(formname, "^advtrains_inv_(.+)$")
		if uid then
			local pname=player:get_player_name()
			local data = advtrains.wagons[uid]
			if fields.prop and data.owner==pname then
				for _,wagon in pairs(minetest.luaentities) do
					if wagon.is_wagon and wagon.initialized and wagon.id==uid and data.owner==pname then
						wagon:show_wagon_properties(pname)
						--wagon:handle_bordcom_fields(player:get_player_name(), formname, fields)
					end
				local wagon = advtrains.get_wagon_entity(uid)
				if wagon then
					wagon:show_wagon_properties(pname)
					--wagon:handle_bordcom_fields(player:get_player_name(), formname, fields)
				end
			end
			return true
		end
end)

function wagon:seating_from_key_helper(pname, fields, no)
	local data = advtrains.wagons[self.id]
	local sgr=self.seats[no].group
@@ -1507,3 +1513,24 @@ function advtrains.get_wagon_at_index(train_id, w_index)
	-- nothing found, dist must be further back
	return nil
end

function advtrains.get_wagon_entity(wagon_id)
	if not advtrains.wagons[wagon_id] then return end
	local object = advtrains.wagon_objects[wagon_id]
	if object then
		return object:get_luaentity()
	end
end

function advtrains.next_wagon_entity_in_train(train, i)
	local wagon_id = train[i + 1]
	if wagon_id then
		return i + 1, advtrains.get_wagon_entity(wagon_id)
	end
end

function advtrains.wagon_entity_pairs_in_train(train_id)
	local train = advtrains.trains[train_id]
	if not train then return function() end end
	return advtrains.next_wagon_entity_in_train, train, 0
end
-- 
2.46.0
Oops... I forgot to add some of my changes. See v8 for the full patch.