aboutsummaryrefslogtreecommitdiff
path: root/advtrains/wagons.lua
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains/wagons.lua')
-rw-r--r--advtrains/wagons.lua364
1 files changed, 227 insertions, 137 deletions
diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua
index 536c8d4..52ce577 100644
--- a/advtrains/wagons.lua
+++ b/advtrains/wagons.lua
@@ -7,6 +7,9 @@
-- An entity is ONLY spawned by update_trainpart_properties when it finds it useful.
-- Only data that are only important to the entity itself are stored in the luaentity
+-- Get current translator
+local S = advtrains.translate
+
-- TP delay when getting off wagon
local GETOFF_TP_DELAY = 0.5
@@ -16,15 +19,8 @@ advtrains.wagons = {}
advtrains.wagon_alias = {}
advtrains.wagon_prototypes = setmetatable({}, {
__index = function(t, k)
- local rtn_val = rawget(t, k)
- if rtn_val ~= nil then
- return rtn_val
- end
- local alias = advtrains.wagon_alias[k]
- if alias then
- return rawget(t, alias)
- end
- return nil
+ local _, proto = advtrains.resolve_wagon_alias(k)
+ return proto
end
})
advtrains.wagon_objects = {}
@@ -161,12 +157,12 @@ function wagon:ensure_init()
end
end
if not self.noninitticks then
- atwarn("wagon",self.id,"uninitialized init=",self.initialized)
+ atwarn("Wagon",self.id,"Uninitialized init=",self.initialized)
self.noninitticks=0
end
self.noninitticks=self.noninitticks+1
if self.noninitticks>20 then
- atwarn("wagon",self.id,"uninitialized, removing")
+ atwarn("Wagon",self.id,S("Uninitialized, removing"))
self:destroy()
else
self.object:set_velocity({x=0,y=0,z=0})
@@ -189,7 +185,7 @@ function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direct
return
end
if data.owner and puncher:get_player_name()~=data.owner and (not minetest.check_player_privs(puncher, {train_admin = true })) then
- minetest.chat_send_player(puncher:get_player_name(), attrans("This wagon is owned by @1, you can't destroy it.", data.owner));
+ minetest.chat_send_player(puncher:get_player_name(), S("This wagon is owned by @1, you can't destroy it.", data.owner));
return
end
@@ -208,25 +204,25 @@ function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direct
if self.has_inventory then
local inv=minetest.get_inventory({type="detached", name="advtrains_wgn_"..self.id})
if not inv then -- inventory is not initialized when wagon was never loaded - should never happen
- atwarn("Destroying wagon with inventory, but inventory is not found? Shouldn't happen!")
+ atwarn(S("Destroying wagon with inventory, but inventory is not found? Shouldn't happen!"))
return
end
for listname, _ in pairs(inv:get_lists()) do
if not inv:is_empty(listname) then
- minetest.chat_send_player(puncher:get_player_name(), attrans("The wagon's inventory is not empty!"));
+ minetest.chat_send_player(puncher:get_player_name(), S("The wagon's inventory is not empty."));
return
end
end
end
if #(self:train().trainparts)>1 then
- minetest.chat_send_player(puncher:get_player_name(), attrans("Wagon needs to be decoupled from other wagons in order to destroy it."));
+ minetest.chat_send_player(puncher:get_player_name(), S("Wagon needs to be decoupled from other wagons in order to destroy it."));
return
end
local pc=puncher:get_player_control()
if not pc.sneak then
- minetest.chat_send_player(puncher:get_player_name(), attrans("Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon."))
+ minetest.chat_send_player(puncher:get_player_name(), S("Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon."))
return
end
@@ -247,7 +243,7 @@ function wagon:destroy()
if self.id then
local data = advtrains.wagons[self.id]
if not data then
- atwarn("wagon:destroy(): data is not set!")
+ atwarn(" wagon:destroy(): data is not set!")
return
end
@@ -293,7 +289,7 @@ function wagon:on_step(dtime)
local data = advtrains.wagons[self.id]
if not pos then
- --atdebug("["..self.id.."][fatal] missing position (object:getpos() returned nil)")
+ --atdebug("["..self.id.."][fatal] missing position (object:get_pos() returned nil)")
return
end
@@ -374,15 +370,15 @@ function wagon:on_step(dtime)
--show off-track information in outside text instead of notifying the whole server about this
if train.off_track then
- outside = outside .."\n!!! Train off track !!!"
+ outside = outside .."\n"..S("!!! Train off track !!!")
end
-- liquid container: display liquid contents in infotext
if self.techage_liquid_capacity then
if data.techage_liquid and data.techage_liquid.name then
- outside = outside .."\nLiquid: "..data.techage_liquid.name..", "..data.techage_liquid.amount.." units"
+ outside = outside .."\n"..S("Liquid: ")..data.techage_liquid.name..", "..data.techage_liquid.amount..S(" units")
else
- outside = outside .."\nLiquid: empty"
+ outside = outside .."\n"..S("Liquid: empty")
end
end
@@ -468,26 +464,34 @@ function wagon:on_step(dtime)
--needs to know index and path
if train.velocity==0 and self.door_entry and train.door_open and train.door_open~=0 then
--using the mapping created by the trainlogic globalstep
+ local platform_offset = math.floor(self.wagon_width / 2)
for i, ino in ipairs(self.door_entry) do
--fct is the flipstate flag from door animation above
local aci = advtrains.path_get_index_by_offset(train, index, ino*fct)
local ix1, ix2 = advtrains.path_get_adjacent(train, aci)
-- the two wanted positions are ix1 and ix2 + (2nd-1st rotated by 90deg)
-- (x z) rotated by 90deg is (-z x) (http://stackoverflow.com/a/4780141)
- local add = { x = (ix2.z-ix1.z)*train.door_open, y = 0, z = (ix1.x-ix2.x)*train.door_open }
- local pts1=vector.round(vector.add(ix1, add))
- local pts2=vector.round(vector.add(ix2, add))
- if minetest.get_item_group(minetest.get_node(pts1).name, "platform")>0 then
- local ckpts={
- pts1,
- pts2,
- vector.add(pts1, {x=0, y=1, z=0}),
- vector.add(pts2, {x=0, y=1, z=0}),
- }
- for _,ckpos in ipairs(ckpts) do
- local cpp=minetest.pos_to_string(ckpos)
- if advtrains.playersbypts[cpp] then
- self:on_rightclick(advtrains.playersbypts[cpp])
+ local add = {
+ x = atround((ix2.z-ix1.z)*train.door_open),
+ y = 0,
+ z = atround((ix1.x-ix2.x)*train.door_open)
+ }
+ for offset = (platform_offset == 0 and 0 or 1), platform_offset do
+ local scaled_add = vector.multiply(add, offset)
+ local pts1=vector.add(ix1, scaled_add)
+ local pts2=vector.add(ix2, scaled_add)
+ if minetest.get_item_group(minetest.get_node(pts1).name, "platform")>0 then
+ local ckpts={
+ pts1,
+ pts2,
+ vector.add(pts1, {x=0, y=1, z=0}),
+ vector.add(pts2, {x=0, y=1, z=0}),
+ }
+ for _,ckpos in ipairs(ckpts) do
+ local cpp=minetest.pos_to_string(ckpos)
+ if advtrains.playersbypts[cpp] then
+ self:on_rightclick(advtrains.playersbypts[cpp])
+ end
end
end
end
@@ -668,21 +672,21 @@ function wagon:on_rightclick(clicker)
end
end
if self.has_inventory and self.get_inventory_formspec and advtrains.check_driving_couple_protection(pname, data.owner, data.whitelist) then
- poss[#poss+1]={name=attrans("Show Inventory"), key="inv"}
+ poss[#poss+1]={name=S("Show Inventory"), key="inv"}
end
if self.seat_groups[sgr].driving_ctrl_access and advtrains.check_driving_couple_protection(pname, data.owner, data.whitelist) then
- poss[#poss+1]={name=attrans("Onboard Computer"), key="bordcom"}
+ poss[#poss+1]={name=S("Onboard Computer"), key="bordcom"}
end
if data.owner==pname then
- poss[#poss+1]={name=attrans("Wagon properties"), key="prop"}
+ poss[#poss+1]={name=S("Wagon properties"), key="prop"}
end
if not self.seat_groups[sgr].require_doors_open or self:train().door_open~=0 then
- poss[#poss+1]={name=attrans("Get off"), key="off"}
+ poss[#poss+1]={name=S("Get off"), key="off"}
else
if clicker:get_player_control().sneak then
- poss[#poss+1]={name=attrans("Get off (forced)"), key="off"}
+ poss[#poss+1]={name=S("Get off (forced)"), key="off"}
else
- poss[#poss+1]={name=attrans("(Doors closed)"), key="dcwarn"}
+ poss[#poss+1]={name=S("(Doors closed)"), key="dcwarn"}
end
end
if #poss==0 then
@@ -692,7 +696,7 @@ function wagon:on_rightclick(clicker)
else
local form = "size[5,"..1+(#poss).."]"
for pos,ent in ipairs(poss) do
- form = form .. "button_exit[0.5,"..(pos-0.5)..";4,1;"..ent.key..";"..ent.name.."]"
+ form = form.. "button_exit[0.5,"..(pos-0.5)..";4,1;"..ent.key..";"..ent.name.."]"
end
minetest.show_formspec(pname, "advtrains_seating_"..self.id, form)
end
@@ -711,7 +715,7 @@ function wagon:on_rightclick(clicker)
end
local doors_open = self:train().door_open~=0 or clicker:get_player_control().sneak
- local allow, rsn=false, "Wagon has no seats!"
+ local allow, rsn=false, S("This wagon has no seats.")
for _,sgr in ipairs(self.assign_to_seat_group) do
allow, rsn = self:check_seat_group_access(pname, sgr)
if allow then
@@ -722,16 +726,16 @@ function wagon:on_rightclick(clicker)
self:get_on(clicker, seatid)
return
else
- rsn="Wagon is full."
+ rsn=S("This wagon is full.")
end
else
- rsn="Doors are closed! (try holding sneak key!)"
+ rsn=S("Doors are closed! (Try holding sneak key!)")
end
end
end
end
end
- minetest.chat_send_player(pname, attrans("Can't get on: "..rsn))
+ minetest.chat_send_player(pname, rsn or S("You can't get on this wagon."))
else
self:show_get_on_form(pname)
end
@@ -827,8 +831,8 @@ function wagon:get_off(seatno)
end
--if not door_entry, or paths missing, fall back to old method
--atdebug("using fallback")
- local objpos=advtrains.round_vector_floor_y(self.object:getpos())
- local yaw=self.object:getyaw()
+ local objpos=advtrains.round_vector_floor_y(self.object:get_pos())
+ local yaw=self.object:get_yaw()
local isx=(yaw < math.pi/4) or (yaw > 3*math.pi/4 and yaw < 5*math.pi/4) or (yaw > 7*math.pi/4)
local offp
--abuse helper function
@@ -857,7 +861,7 @@ function wagon:show_get_on_form(pname)
end
return
end
- local form, comma="size[5,8]label[0.5,0.5;"..attrans("Select seat:").."]textlist[0.5,1;4,6;seat;", ""
+ local form, comma="size[5,8]label[0.5,0.5;"..S("Select seat:").."]textlist[0.5,1;4,6;seat;", ""
for seatno, seattbl in ipairs(self.seats) do
local addtext, colorcode="", ""
if data.seatp and data.seatp[seatno] then
@@ -869,7 +873,7 @@ function wagon:show_get_on_form(pname)
end
form=form..";0,false]"
if self.has_inventory and self.get_inventory_formspec then
- form=form.."button_exit[1,7;3,1;inv;"..attrans("Show Inventory").."]"
+ form=form.."button_exit[1,7;3,1;inv;"..S("Show Inventory").."]"
end
minetest.show_formspec(pname, "advtrains_geton_"..self.id, form)
end
@@ -881,32 +885,32 @@ function wagon:show_wagon_properties(pname)
]]
local data = advtrains.wagons[self.id]
local form="size[5,5]"
- form=form.."label[0.2,0;"..attrans("This Wagon ID")..": "..self.id.."]"
- form = form .. "field[0.5,1;4.5,1;whitelist;Allow these players to access your wagon:;"..minetest.formspec_escape(data.whitelist or "").."]"
- form = form .. "field[0.5,2;4.5,1;roadnumber;Wagon road number:;"..minetest.formspec_escape(data.roadnumber or "").."]"
+ form=form.."label[0.2,0;"..S("This Wagon ID")..": "..self.id.." ("..data.owner..")]"
+ form = form.."field[0.5,1;4.5,1;whitelist;"..S("Allow these players to access your wagon:")..";"..minetest.formspec_escape(data.whitelist or "").."]"
+ form = form.."field[0.5,2;4.5,1;roadnumber;"..S("Wagon road number:")..";"..minetest.formspec_escape(data.roadnumber or "").."]"
local fc = ""
if data.fc then
fc = table.concat(data.fc, "!")
end
- form = form .. "field[0.5,3;4.5,1;fc;Freight Code:;"..fc.."]"
+ form = form.. "field[0.5,3;4.5,1;fc;"..S("Freight Code:")..";"..fc.."]"
if data.fc then
if not data.fcind then data.fcind = 1 end
if data.fcind > 1 then
- form=form.."button[0.5,3.5;1,1;fcp;prev FC]"
+ form=form.."button[0.5,3.5;1,1;fcp;"..S("Prev FC").."]"
end
- form=form.."label[1.5,3.5;Current FC:]"
+ form=form.."label[1.5,3.5;"..S("Current FC: ").."]"
local cur = data.fc[data.fcind] or ""
form=form.."label[1.5,3.75;"..minetest.formspec_escape(cur).."]"
- form=form.."button[3.5,3.5;1,1;fcn;next FC]"
+ form=form.."button[3.5,3.5;1,1;fcn;"..S("Next FC:").."]"
end
- form=form.."button_exit[0.5,4.5;4,1;save;"..attrans("Save wagon properties").."]"
+ form=form.."button_exit[0.5,4.5;4,1;save;"..S("Save wagon properties").."]"
minetest.show_formspec(pname, "advtrains_prop_"..self.id, form)
end
--BordCom
local function checkcouple(ent)
- if not ent or not ent:getyaw() then
+ if not ent or not ent:get_yaw() then
return nil
end
local le = ent:get_luaentity()
@@ -985,30 +989,30 @@ function wagon:show_bordcom(pname)
local linhei
local form = "size[11,9]label[0.5,0;AdvTrains Boardcom v0.1]"
- form=form.."textarea[7.5,0.05;10,1;;"..attrans("Train ID")..": "..(minetest.formspec_escape(train.id or ""))..";]"
- form=form.."textarea[0.5,1.5;7,1;text_outside;"..attrans("Text displayed outside on train")..";"..(minetest.formspec_escape(train.text_outside or "")).."]"
- form=form.."textarea[0.5,3;7,1;text_inside;"..attrans("Text displayed inside train")..";"..(minetest.formspec_escape(train.text_inside or "")).."]"
- form=form.."field[7.5,1.75;3,1;line;"..attrans("Line")..";"..(minetest.formspec_escape(train.line or "")).."]"
- form=form.."field[7.5,3.25;3,1;routingcode;"..attrans("Routingcode")..";"..(minetest.formspec_escape(train.routingcode or "")).."]"
+ form=form.."textarea[7.5,0.05;10,1;;"..S("Train ID")..": "..(minetest.formspec_escape(train.id or ""))..";]"
+ form=form.."textarea[0.5,1.5;7,1;text_outside;"..S("Text displayed outside on train")..";"..(minetest.formspec_escape(train.text_outside or "")).."]"
+ form=form.."textarea[0.5,3;7,1;text_inside;"..S("Text displayed inside train")..";"..(minetest.formspec_escape(train.text_inside or "")).."]"
+ form=form.."field[7.5,1.75;3,1;line;"..S("Line")..";"..(minetest.formspec_escape(train.line or "")).."]"
+ form=form.."field[7.5,3.25;3,1;routingcode;"..S("Routingcode")..";"..(minetest.formspec_escape(train.routingcode or "")).."]"
--row 5 : train overview and autocoupling
if train.velocity==0 then
- form=form.."label[0.5,4;Train overview /coupling control:]"
+ form=form.."label[0.5,4;"..S("Train overview /coupling control:").."])"
linhei=5
local pre_own, pre_wl, owns_any = nil, nil, minetest.check_player_privs(pname, "train_admin")
for i, tpid in ipairs(train.trainparts) do
local ent = advtrains.wagons[tpid]
if ent then
local roadnumber = ent.roadnumber or ""
- form = form .. string.format("button[%d,%d;%d,%d;%s;%s]", i, linhei, 1, 0.2, "wgprp"..i, roadnumber)
+ form = form.. string.format("button[%d,%d;%d,%d;%s;%s]", i, linhei, 1, 0.2, "wgprp"..i, roadnumber)
local ename = ent.type
- form = form .. "item_image["..i..","..(linhei+0.5)..";1,1;"..ename.."]"
+ form = form.. "item_image["..i..","..(linhei+0.5)..";1,1;"..ename.."]"
if i~=1 then
if checklock(pname, ent.owner, pre_own, ent.whitelist, pre_wl) then
- form = form .. "image_button["..(i-0.5)..","..(linhei+1.5)..";1,1;advtrains_discouple.png;dcpl_"..i..";]"
+ form = form.. "image_button["..(i-0.5)..","..(linhei+1.5)..";1,1;advtrains_discouple.png;dcpl_"..i..";]"
end
end
if i == data.pos_in_trainparts then
- form = form .. "box["..(i-0.1)..","..(linhei+0.4)..";1,1;green]"
+ form = form.. "box["..(i-0.1)..","..(linhei+0.4)..";1,1;green]"
end
pre_own = ent.owner
pre_wl = ent.whitelist
@@ -1017,24 +1021,24 @@ function wagon:show_bordcom(pname)
end
if train.movedir==1 then
- form = form .. "label["..(#train.trainparts+1)..","..(linhei)..";-->]"
+ form = form.. "label["..(#train.trainparts+1)..","..(linhei)..";-->]"
else
- form = form .. "label[0.5,"..(linhei)..";<--]"
+ form = form.. "label[0.5,"..(linhei)..";<--]"
end
--check cpl_eid_front and _back of train
local couple_front = checkcouple(train.cpl_front)
local couple_back = checkcouple(train.cpl_back)
if couple_front then
- form = form .. "image_button[0.5,"..(linhei+1)..";1,1;advtrains_couple.png;cpl_f;]"
+ form = form.. "image_button[0.5,"..(linhei+1)..";1,1;advtrains_couple.png;cpl_f;]"
end
if couple_back then
- form = form .. "image_button["..(#train.trainparts+0.5)..","..(linhei+1)..";1,1;advtrains_couple.png;cpl_b;]"
+ form = form.. "image_button["..(#train.trainparts+0.5)..","..(linhei+1)..";1,1;advtrains_couple.png;cpl_b;]"
end
else
- form=form.."label[0.5,4.5;Train overview / coupling control is only shown when the train stands.]"
+ form=form.."label[0.5,4.5;"..S("Train overview / coupling control is only shown when the train stands.").."]"
end
- form = form .. "button[0.5,8;3,1;save;Save]"
+ form = form.. "button[0.5,8;3,1;save;"..S("Save").."]"
-- Interlocking functionality: If the interlocking module is loaded, you can set the signal aspect
-- from inside the train
@@ -1044,14 +1048,14 @@ function wagon:show_bordcom(pname)
local oci = train.lzb.checkpoints[i]
if oci.udata and oci.udata.signal_pos then
if advtrains.interlocking.db.get_sigd_for_signal(oci.udata.signal_pos) then
- form = form .. "button[4.5,8;5,1;ilrs;Remote Routesetting]"
+ form = form.. "button[4.5,8;5,1;ilrs;"..S("Remote Routesetting").."]"
break
end
end
i=i+1
end
if train.ars_disable then
- form = form .. "button[4.5,7;5,1;ilarsenable;Clear 'Disable ARS' flag]"
+ form = form.. "button[4.5,7;5,1;ilarsenable;"..S("Clear 'Disable ARS' flag").."]"
end
end
@@ -1103,12 +1107,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 +1157,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 +1220,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
@@ -1262,7 +1272,7 @@ function wagon:seating_from_key_helper(pname, fields, no)
self:show_bordcom(pname)
end
if fields.dcwarn then
- minetest.chat_send_player(pname, attrans("Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!"))
+ minetest.chat_send_player(pname, S("Doors are closed. Use Sneak+rightclick to ignore the closed doors and get off."))
end
if fields.off then
self:get_off(no)
@@ -1271,10 +1281,10 @@ end
function wagon:check_seat_group_access(pname, sgr)
local data = advtrains.wagons[self.id]
if self.seat_groups[sgr].driving_ctrl_access and not (advtrains.check_driving_couple_protection(pname, data.owner, data.whitelist)) then
- return false, "Not allowed to access a driver stand!"
+ return false, S("You are not allowed to access the driver stand.")
end
if self.seat_groups[sgr].driving_ctrl_access then
- advtrains.log("Drive", pname, self.object:getpos(), self:train().text_outside)
+ advtrains.log("Drive", pname, self.object:get_pos(), self:train().text_outside)
end
return true
end
@@ -1291,7 +1301,7 @@ end
function advtrains.safe_decouple_wagon(w_id, pname, try_run)
if not minetest.check_player_privs(pname, "train_operator") then
- minetest.chat_send_player(pname, "Missing train_operator privilege")
+ minetest.chat_send_player(pname, S("Missing train_operator privilege"))
return false
end
local data = advtrains.wagons[w_id]
@@ -1309,7 +1319,7 @@ function advtrains.safe_decouple_wagon(w_id, pname, try_run)
end
if not checklock(pname, data.owner, owdata.owner, data.whitelist, owdata.whitelist) then
- minetest.chat_send_player(pname, "Not allowed to do this.")
+ minetest.chat_send_player(pname, S("Not allowed to do this."))
return false
end
@@ -1332,17 +1342,35 @@ function advtrains.get_wagon_prototype(data)
data.type = data.entity_name
data.entity_name = nil
end
- if not wt or not advtrains.wagon_prototypes[wt] then
- atwarn("Unable to load wagon type",wt,", using placeholder")
- wt="advtrains:wagon_placeholder"
+ local rt, proto = advtrains.resolve_wagon_alias(wt)
+ if not rt then
+ --atwarn(S("Unable to load wagon type"),wt,S(", using placeholder"))
+ rt = "advtrains:wagon_placeholder"
+ proto = advtrains.wagon_prototypes[rt]
end
- return wt, advtrains.wagon_prototypes[wt]
+ return rt, proto
end
function advtrains.register_wagon_alias(src, dst)
advtrains.wagon_alias[src] = dst
end
+local function recursive_resolve_alias(name, seen)
+ local prototype = rawget(advtrains.wagon_prototypes, name)
+ if prototype then
+ return name, prototype
+ end
+ local resolved = advtrains.wagon_alias[name]
+ if resolved and not seen[resolved] then
+ seen[name] = true
+ return recursive_resolve_alias(resolved, seen)
+ end
+end
+
+function advtrains.resolve_wagon_alias(name)
+ return recursive_resolve_alias(name, {})
+end
+
function advtrains.standard_inventory_formspec(self, pname, invname)
--[[minetest.chat_send_player(pname, string.format("self=%s, pname=%s, invname=%s", self, pname, invname))
for k,v in pairs(self) do
@@ -1353,7 +1381,7 @@ function advtrains.standard_inventory_formspec(self, pname, invname)
local r = "size[8,11]"..
"list["..invname..";box;0,0;8,3;]"
if data.owner==pname then
- r = r .. "button_exit[0,9;4,1;prop;"..attrans("Wagon properties").."]"
+ r = r .. "button_exit[0,9;4,1;prop;"..S("Wagon properties").."]"
end
r = r .. "list[current_player;main;0,5;8,4;]"..
"listring[]"
@@ -1387,38 +1415,48 @@ function advtrains.register_wagon(sysname_p, prototype, desc, inv_img, nincreati
groups = wagon_groups,
on_place = function(itemstack, placer, pointed_thing)
- if not pointed_thing.type == "node" then
+ if pointed_thing.type ~= "node" then
return
end
+
+ local pos = pointed_thing.under
+ local node = minetest.get_node(pos)
+ local pointed_def = minetest.registered_nodes[node.name]
+ if pointed_def and pointed_def.on_rightclick then
+ local controls = placer:get_player_control()
+ if not controls.sneak then
+ return pointed_def.on_rightclick(pos, node, placer, itemstack, pointed_thing)
+ end
+ end
+
local pname = placer:get_player_name()
- local node=minetest.get_node_or_nil(pointed_thing.under)
- if not node then atprint("[advtrains]Ignore at placer position") return itemstack end
+ if node.name == "ignore" then atprint("[advtrains]Ignore at placer position") return itemstack end
local nodename=node.name
- if(not advtrains.is_track_and_drives_on(nodename, prototype.drives_on)) then
+ if(not advtrains.is_track(nodename)) then
atprint("no track here, not placing.")
return itemstack
end
if not minetest.check_player_privs(placer, {train_operator = true }) then
- minetest.chat_send_player(pname, "You don't have the train_operator privilege.")
+ minetest.chat_send_player(pname, S("You don't have the train_operator privilege."))
return itemstack
end
- if not minetest.check_player_privs(placer, {train_admin = true }) and minetest.is_protected(pointed_thing.under, placer:get_player_name()) then
+ if not minetest.check_player_privs(placer, {train_admin = true }) and minetest.is_protected(pos, placer:get_player_name()) then
return itemstack
end
local tconns=advtrains.get_track_connections(node.name, node.param2)
local yaw = placer:get_look_horizontal()
local plconnid = advtrains.yawToClosestConn(yaw, tconns)
- local prevpos = advtrains.get_adjacent_rail(pointed_thing.under, tconns, plconnid, prototype.drives_on)
+ local prevpos = advtrains.get_adjacent_rail(pos, tconns, plconnid)
if not prevpos then
- minetest.chat_send_player(pname, "The track you are trying to place the wagon on is not long enough!")
+ minetest.chat_send_player(pname, S("The track you are trying to place the wagon on is not long enough!"))
return
end
local wid = advtrains.create_wagon(sysname, pname)
- local id=advtrains.create_new_train_at(pointed_thing.under, plconnid, 0, {wid})
+ local id=advtrains.create_new_train_at(pos, plconnid, 0, {wid})
if not advtrains.is_creative(pname) then
itemstack:take_item()
@@ -1435,7 +1473,6 @@ advtrains.register_wagon("advtrains:wagon_placeholder", {
collisionbox = {-0.3,-0.3,-0.3, 0.3,0.3,0.3},
visual_size = {x=0.7, y=0.7},
initial_sprite_basepos = {x=0, y=0},
- drives_on = advtrains.all_tracktypes,
max_speed = 5,
seats = {
},
@@ -1444,7 +1481,7 @@ advtrains.register_wagon("advtrains:wagon_placeholder", {
assign_to_seat_group = {},
wagon_span=1,
drops={},
-}, "Wagon placeholder", "advtrains_wagon_placeholder.png", true)
+}, S("Wagon placeholder"), "advtrains_wagon_placeholder.png", true)
@@ -1507,3 +1544,56 @@ 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.trainparts[i + 1]
+ if wagon_id then
+ local wagon = advtrains.get_wagon_entity(wagon_id)
+ if wagon then
+ return i + 1, wagon
+ end
+ 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
+
+minetest.register_chatcommand("at_chown", {
+ params = "<wagon_id> <player_name>",
+ description = "Change the owner of an advtrains wagon",
+ privs = {train_admin=true},
+ func = function(name, param)
+ local params = string.split(param," ")
+ local wid = params[1]
+ local new_owner = params[2]
+ if not wid then return false end --no params added
+ --player name checks
+ if not new_owner then return false, S("Please specify a player name to transfer ownership to.") end --no player name argument
+ if not core.player_exists(new_owner) then return false, S("That player does not exist!") end --is a valid player
+ --wagon id checks
+ if not wid:match("%d%d%d%d%d%d") then return false, S("Not a valid wagon id.") end -- invalid wagon id
+ local w_data = advtrains.wagons[wid]
+ if not w_data then return false, S("That wagon does not exist!") end
+ -- actually chown the wagon
+ local curr_owner = w_data.owner
+ w_data.owner = new_owner
+ advtrains.wagons[wid] = w_data
+ advtrains.log("Chown", name, core.get_player_by_name(name):get_pos(), "wid="..wid..", from="..curr_owner..", to="..new_owner)
+
+ if name ~= new_owner then
+ core.chat_send_player(new_owner, S("You have been given ownership of wagon @1", wid))
+ end
+ return true, S("Wagon @1 ownership changed from @2 to @3", wid, curr_owner, new_owner)
+ end
+})