ofs | hex dump | ascii |
---|
0000 | 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01 00 00 00 01 00 08 06 00 00 00 5c 72 a8 | .PNG........IHDR.............\r. |
0020 | 66 00 00 00 06 62 4b 47 44 00 ff 00 ff 00 ff a0 bd a7 93 00 00 00 09 70 48 59 73 00 00 0e c3 00 | f....bKGD..............pHYs..... |
0040 | 00 0e c3 01 c7 6f a8 64 00 00 00 07 74 49 4d 45 07 e0 06 09 13 13 34 76 e3 a3 06 00 00 20 00 49 | .....o.d....tIME......4v.......I |
0060 | 44 41 54 78 da ec bd 69 94 5d e7 59 26 fa 7c d3 9e ce 50 55 a7 06 cd 52 55 69 b4 64 c9 83 64 9b | DATx...i.].Y&.|...PU...RUi.d..d. |
0080 | 28 b6 93 38 b1 89 21 40 47 31 61 c8 8d 3b ac 40 e8 0b 84 6e ba ef 5d b9 eb 76 37 69 58 ac 06 3a | (..8..!@G1a..;.@...n..]..v7iX..: |
00a0 | ac 6e 20 74 26 9a d0 04 72 49 c7 40 80 0c 24 74 4c 70 70 06 0f b2 3c c4 92 27 a9 4a b6 64 4b aa | .n.t&...rI.@..$tLpp...<..'.J.dK. |
00c0 | e1 9c aa 3a 67 9f bd f7 37 dd 1f fb 7c bb 4e 95 25 8f 72 82 9d fd 7a 9d 55 52 e9 c8 a5 b3 f7 7e | ...:g...7...|.N.%.r...z.UR.....~ |
00e0 | de ef 1d 9e f7 79 81 d2 4a 2b ad b4 d2 4a 2b ad b4 d2 4a 2b ad b4 d2 4a 2b ad b4 d2 4a 2b ad b4 | .....y..J+...J+...J+...J+...J+.. |
0100 | d2 4a 2b ad b4 d2 4a 2b ad b4 d2 4a 2b ad b4 d2 4a 2b ad b4 d2 4a 2b ad b4 d2 4a 2b ad b4 d2 4a | .J+...J+...J+...J+...J+...J+...J |
0120 | 2b ad b4 d2 5e 8b 46 ae be fa 6a 5e 5e 86 d7 d8 4d 2d 2f 41 69 2f c0 d8 35 d7 5c 3e e9 79 d1 a5 | +...^.F...j^^...M-/Ai/..5.\>.y.. |
0140 | 46 9a 6f 49 63 e6 00 d0 bb ef be 3b 2d 2f cd ab fc c6 96 97 a0 b4 e7 7b 46 ae be fc f2 9d dc 0f | F.oIc......;-/.........{F....... |
0160 | 7e c2 5a fc 58 26 b3 ab bb ed ce 91 28 0c 3b 63 f5 3a 7f 66 66 46 97 97 a8 74 00 a5 bd 46 9f 8f | ~.Z.X&......(.;c.:.ffF...t...F.. |
0180 | bd 7b 77 6e f3 7c ef 1d 20 f8 f1 2c 53 7b b2 2c 1b a3 8c 6f 27 94 de d5 4d d3 85 91 d1 51 6f 76 | .{wn.|.....,S{.,...o'...M....Qov |
01a0 | 76 b6 74 02 a5 03 28 ed b5 f6 6c ec dc b9 73 9b e7 89 43 20 e4 1d 4a 99 5d 52 ea 0a a5 2c ac 54 | v.t...(...l...s...C...J.]R...,.T |
01c0 | 2a 83 61 18 ee 18 1e 19 b9 c7 18 d3 de bc 79 73 78 ea d4 29 05 c0 96 97 ad 74 00 a5 bd 16 c0 3f | *.a...........ysx..).....t.....? |
01e0 | 3e be 4d 84 fe 21 4a c8 2d c6 d8 dd c6 20 e0 5c 90 28 8a 58 18 86 61 14 45 83 8d 46 63 fb e6 cd | >.M..!J.-......\.(.X..a.E..Fc... |
0200 | 9b 0f 67 59 46 f6 ed db 17 1d 3b 76 ac 5b 3a 81 d2 01 94 f6 2a 7f 26 c6 c7 c7 b7 89 40 1c 22 84 | ..gYF.....;v.[:.....*.&.....@.". |
0220 | de 42 40 76 13 c2 02 21 3c 84 61 88 28 8a 48 14 45 6c 70 70 30 1c 1e 1e 1e ac d5 6a db 82 20 98 | .B@v...!<.a.(.H.Elpp0......j.... |
0240 | 1e 18 18 d8 70 dd 75 d7 c9 6f 7d eb 5b 4b a5 13 28 1d 40 69 af 66 f0 33 76 88 10 72 0b 65 6c 37 | ....p.u..o}.[K..(.@i.f.3v..r.el7 |
0260 | a5 3c f0 3c 0f 41 10 20 08 02 44 51 84 c1 c1 41 d2 68 34 58 a5 52 09 39 e7 83 94 d2 4b 7c df 6f | .<.<.A....DQ...A.h4X.R.9....K|.o |
0280 | f8 be ef 5f 75 d5 55 ad d2 09 94 0e a0 b4 ef a1 7d f0 83 a0 63 33 bb f9 b5 9b 37 d3 c3 cf 3c 63 | ..._u.U.........}...c3....7...<c |
02a0 | 5f 0c f8 03 c1 0e 81 d2 5b 28 a5 bb 39 17 81 ef fb 70 af 30 0c 31 30 30 80 46 a3 81 5a ad 46 18 | _.......[(..9....p.0.100.F..Z.F. |
02c0 | 63 4c 4a 19 02 18 e5 9c ef 55 4a 55 b2 2c 4b f6 ec d9 d3 3c 72 e4 48 e9 04 4a 07 50 da 77 db de | cLJ......UJU.,K....<r.H..J.P.w.. |
02e0 | ff fe b7 7a 03 c9 81 ca da c9 4d 21 5b 17 d1 75 13 03 ea e8 d1 53 cf fb 1c ec dd b9 73 5b 10 fa | ...z......M![..u.....S......s[.. |
0300 | 87 2c 21 b7 10 42 76 73 ce 03 df f7 11 04 01 dc 57 07 fe 4a a5 02 ce 39 a4 94 44 4a c9 38 e7 a1 | .,!..Bvs........W..J...9..DJ.8.. |
0320 | b5 36 ca b2 6c 93 94 d2 67 8c 75 f7 ed db 57 3a 81 d2 01 94 f6 dd b4 2f fe cf df 20 dd b6 --clipboard = {trainlen = number, [n] = {type = string, flipped = bool, }
-- Yaw is in radians. There are 2pi rad in a circle. North is the 0 point and the angle increases anticlockwise.
-- 4.712389 = 1.5pi; sin(1.5pi) = -1
-- 7.853981 = 2.5pi; sin(2.5pi) = 1
minetest.register_tool("advtrains:copytool", {
description = attrans("Train copy/paste tool\n\nLeft-click: copy train\nRight-click: paste train"),
inventory_image = "advtrains_copytool.png",
wield_image = "advtrains_copytool.png",
stack_max = 1,
-- Paste: Take the clipboard and the player yaw, and attempt to place a new train in the world.
-- The front of the train is used as the start of the new train and it proceeds backwards from
-- the direction of travel.
on_place = function(itemstack, placer, pointed_thing)
if ((not pointed_thing.type == "node") or (not placer.get_player_name)) then
return
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
local nodename=node.name
if(not advtrains.is_track_and_drives_on(nodename, {default=true})) 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.")
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
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, {default=true})
if not prevpos then
minetest.chat_send_player(pname, "The track you are trying to place the wagon on is not long enough!")
return
end
local meta = itemstack:get_meta()
if not meta then
minetest.chat_send_player(pname, attrans("The clipboard couldn't access the metadata. Paste failed."))
return
end
local clipboard = meta:get_string("clipboard")
if (clipboard == "") then
minetest.chat_send_player(pname, "The clipboard is empty.");
return
end
clipboard = minetest.deserialize(clipboard)
if (clipboard.wagons == nil) then
minetest.chat_send_player(pname, "The clipboard is empty.");
return
end
local wagons = {}
local n = 1
for _, wagonProto in pairs(clipboard.wagons) do
local wagon = advtrains.create_wagon(wagonProto.type, pname)
advtrains.wagons[wagon].wagon_flipped = wagonProto.wagon_flipped
wagons[n] = wagon
n = n + 1
end
local id=advtrains.create_new_train_at(pointed_thing.under, plconnid, 0, wagons)
local train = advtrains.trains[id]
train.off_track = train.end_index<train.path_trk_b
if (train.off_track) then
minetest.chat_send_player(pname, "Back of train would end up off track, cancelling.")
advtrains.remove_train(id)
return
end
train.text_outside = clipboard.text_outside
train.text_inside = clipboard.text_inside
train.routingcode = clipboard.routingcode
train.line = clipboard.line
return
end,
-- Copy: Take the pointed-at train and put it on the clipboard
on_use = function(itemstack, user, pointed_thing)
if not user:get_player_name() then return end
if (pointed_thing.type ~= "object") then return end
local le = pointed_thing.ref:get_luaentity()
if (le == nil) then
minetest.chat_send_player(user:get_player_name(), "No such lua entity!")
return
end
local wagon = advtrains.wagons[le.id]
if (not (le.id and advtrains.wagons[le.id])) then
minetest.chat_send_player(user:get_player_name(), string.format("No such wagon: %s", le.id))
return
end
local train = advtrains.trains[wagon.train_id]
if (not train) then
minetest.chat_send_player(user:get_player_name(), string.format("No such train: %s", wagon.train_id))
return
end
-- Record the train length. The paste operation should require this much free space.
local clipboard = {
trainlen = math.ceil(train.trainlen),
text_outside = train.text_outside,
text_inside = train.text_inside,
routingcode = train.routingcode,
line = train.line,
wagons = {}
}
local trainLength = math.ceil(train.trainlen)
local n = 1
for _, wagonid in pairs(train.trainparts) do
local wagon = advtrains.wagons[wagonid]
clipboard.wagons[n] = {
wagon_flipped = wagon.wagon_flipped,
type = wagon.type
}
n = n + 1
end
local function flip_clipboard(wagon_clipboard)
local flipped = {}
local numWagons = #wagon_clipboard
for k, v in ipairs(wagon_clipboard) do
local otherSide = (numWagons-k)+1
flipped[otherSide] = v
local wagon = flipped[otherSide]
wagon.wagon_flipped = not wagon.wagon_flipped
end
return flipped
end
local function is_loco(wagon_id)
local wagon = advtrains.wagons[wagon_id]
if (not wagon) then return false end
local wagon_proto = advtrains.wagon_prototypes[wagon.type or wagon.entity_name]
if wagon_proto and wagon_proto.is_locomotive then
return true
end
return false
end
-- Decide on a new 'front of train' and possibly flip the train.
-- Locomotive on one end = loco-hauled, that end is front;
-- if (advtrains.wagons[train.trainparts[1]].is_locomotive) then -- do nothing, train is already in right order
local numWagons = #train.trainparts
local backLoco = train.trainparts[numWagons]
backLoco = is_loco(backLoco)
local frontLoco = train.trainparts[1]
frontLoco = is_loco(frontLoco)
if ((backLoco) and (not frontLoco)) then
clipboard.wagons = flip_clipboard(clipboard.wagons)
--minetest.chat_send_player(user:get_player_name(), "Flipped train: Loco-hauled")
end
-- locomotives on both ends = train is push-pull / multi-unit, has no front, do nothing
-- no locomotives on ends = rake of wagons, front is end closest to where player copied.
if ((not frontLoco) and (not backLoco)) then
if (wagon.pos_in_trainparts / numWagons > 0.5) then -- towards the end of the rain
clipboard.wagons = flip_clipboard(clipboard.wagons)
--minetest.chat_send_player(user:get_player_name(), "Flipped train: Rake")
end
end
local meta = itemstack:get_meta()
if not meta then
minetest.chat_send_player(pname, attrans("The clipboard couldn't access the metadata. Copy failed."))
return
end
meta:set_string("clipboard", minetest.serialize(clipboard))
minetest.chat_send_player(user:get_player_name(), attrans("Train copied!"))
return itemstack
end
})
|