init.lua 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. local modname = minetest.get_current_modname()
  2. local function trans(st,...)
  3. return minetest.translate(modname,st,...)
  4. end
  5. local function show_formspec(itemstack,pname)
  6. local formspec = ""
  7. formspec = formspec.."formspec_version[3]"
  8. formspec = formspec.."size[10.5,7.5]"
  9. formspec = formspec.."label[0.2,0.4;"..trans("Advanced Trains Remote Control v1").."]"
  10. formspec = formspec.."button_exit[6.6,0.2;3.7,0.8;bind_train;"..trans("Bind To New Train").."]"
  11. local item_meta = itemstack:get_meta()
  12. local loco_id = item_meta:get("bound_loco")
  13. if not loco_id then
  14. formspec = formspec.."label[0.2,1;"..trans("Remote Control: Not Bound").."]"
  15. formspec = formspec.."label[0.2,1.4;"..trans("Punch a locomotive with the controller to bind it").."]"
  16. else
  17. local train_id = advtrains.wagons[loco_id].train_id --ref to train for atc controls etc
  18. local train = advtrains.trains[train_id] -- train object
  19. formspec = formspec.."label[0.2,1;"..trans("Roadnumber")..": %s]"
  20. formspec = formspec.."label[0.2,1.4;"..trans("Remote Control: Train").." %s]"
  21. formspec = formspec.."label[0.2,1.8;"..trans("Train Length")..": %s wagon(s)]"
  22. formspec = formspec.."label[0.2,2.2;"..trans("Train Length")..": %sm]"
  23. formspec = formspec.."textarea[0.2,2.9;5.8,0.8;ext_disp;"..trans("External Display")..";%s]"
  24. formspec = formspec.."textarea[0.2,4.1;5.8,0.8;int_disp;"..trans("Internal Display")..";%s]"
  25. formspec = formspec.."field[0.2,6.5;2.8,0.8;line;"..trans("Line")..";%s]"
  26. formspec = formspec.."field[0.2,5.3;5.8,0.8;rc;"..trans("Routing Code")..";%s]"
  27. formspec = formspec.."button[3.2,6.5;2.8,0.8;update_info;"..trans("Update Train Info").."]"
  28. formspec = formspec.."label[6.6,1.6;"..trans("Maximum Speed")..": %s m/s]"
  29. formspec = formspec.."field[6.6,2.9;1.9,0.8;speed_input;"..trans("Set Speed")..";%d]"
  30. formspec = formspec.."button[8.8,2.9;1.5,0.8;send_speed;"..trans("Confirm").."]"
  31. formspec = formspec.."field[6.6,4.1;1.9,0.8;atc_input;"..trans("Send ATC Command")..";]"
  32. formspec = formspec.."button[8.8,4.1;1.5,0.8;send_atc;"..trans("Send").."]"
  33. formspec = formspec.."button[6.6,5.3;3.7,0.8;reverse;"..trans("Reverse").."]"
  34. formspec = formspec.."label[6.6,2;"..trans("Door Control").."]"
  35. formspec = formspec.."scrollbaroptions[min=1;max=3;smallstep=1;largestep=1;thumbsize=1;arrows=hide]scrollbar[6.6,2.2;3.7,0.2;horizontal;door;%d]"
  36. formspec = formspec.."checkbox[6.6,6.6;ars_disable;"..trans("Disable ARS")..";%s]"
  37. formspec = formspec.."checkbox[6.6,7.1;autocouple;"..trans("Autocouple")..";%s]"
  38. formspec = formspec.."button[9.1,6.5;1.2,0.8;estop;"..trans("STOP!").."]"
  39. formspec = string.format(formspec,
  40. minetest.formspec_escape(item_meta:get("roadnumber") or trans("Unidentified Locomotive")),
  41. train_id,
  42. #train.trainparts,
  43. train.trainlen,
  44. minetest.formspec_escape(train.text_outside or ""),
  45. minetest.formspec_escape(train.text_inside or ""),
  46. minetest.formspec_escape(train.line or ""),
  47. minetest.formspec_escape(train.routingcode or ""),
  48. train.max_speed,
  49. train.velocity,
  50. ((train.door_open or 0) + 2),
  51. tostring(train.ars_disable),
  52. tostring(train.autocouple or train.atc_wait_autocouple)
  53. )
  54. end
  55. minetest.show_formspec(pname,modname..":controller",formspec)
  56. end
  57. minetest.register_on_player_receive_fields(function(player,formname,fields)
  58. if formname ~= modname..":controller" then return end
  59. local pname = player:get_player_name()
  60. if not pname then return end
  61. local itemstack = player:get_wielded_item()
  62. if itemstack:get_name() ~= modname..":remote_control" then return end
  63. local item_meta = itemstack:get_meta()
  64. --bind train
  65. if fields.bind_train then
  66. item_meta:set_string("bound_loco","")
  67. item_meta:set_string("roadnumber","")
  68. item_meta:set_string("description",trans("Unbound Controller"))
  69. player:set_wielded_item(itemstack)
  70. minetest.chat_send_player(pname,trans("Punch a locomotive with the controller to bind it"))
  71. return
  72. end
  73. local loco_id = item_meta:get("bound_loco")
  74. if loco_id then
  75. --[[list of fields:
  76. active fields:
  77. bind_train
  78. update_info
  79. send_speed
  80. send_atc
  81. reverse
  82. door
  83. ars_disable
  84. autocouple
  85. estop
  86. data fields:
  87. ext_disp
  88. int_disp
  89. line
  90. rc
  91. speed_input
  92. atc_input
  93. --]]
  94. local wagon = advtrains.wagons[loco_id] -- wagon_object for potential use later
  95. local train_id = wagon.train_id
  96. local train = advtrains.trains[train_id]
  97. --update info
  98. local door_scroll = minetest.explode_scrollbar_event(fields.door)
  99. if fields.update_info then
  100. train.text_outside = fields.ext_disp or ""
  101. train.text_inside = fields.int_disp or ""
  102. train.line = fields.line or ""
  103. train.routingcode = fields.rc or ""
  104. minetest.after(0, advtrains.invalidate_path, train_id)
  105. return
  106. --send speed command
  107. elseif fields.send_speed then
  108. local current_v,speed_input = train.velocity,tonumber(fields.speed_input)
  109. if not tonumber(speed_input) then
  110. minetest.chat_send_player(pname,trans("Speed must be a number"))
  111. return
  112. end
  113. local command
  114. local acc
  115. speed_input = tonumber(speed_input)
  116. if current_v == speed_input then
  117. minetest.chat_send_player(pname,trans("Speed unchanged"))
  118. return
  119. elseif current_v < speed_input then
  120. command = "S"..speed_input
  121. acc = "accelerating"
  122. elseif current_v > speed_input then
  123. command = "B"..speed_input
  124. acc = "braking"
  125. end
  126. advtrains.atc.train_set_command(train,command,true)
  127. minetest.chat_send_player(pname,trans("Train "..acc.." to "..speed_input))
  128. return
  129. --send atc command
  130. elseif fields.send_atc then
  131. if fields.atc_input == "" then
  132. minetest.chat_send_player(pname,trans("No ATC command to send"))
  133. return
  134. end
  135. advtrains.atc.train_set_command(train,fields.atc_input,true)
  136. return
  137. -- send reverse command
  138. elseif fields.reverse then
  139. if train.velocity ~= 0 then
  140. minetest.chat_send_player(pname,trans("Please stop the train before reversing"))
  141. return
  142. end
  143. advtrains.invert_train(train_id)
  144. advtrains.train_ensure_init(train_id,train)
  145. -- advtrains.atc.train_reset_command(train)
  146. minetest.chat_send_player(pname,trans("Train reversed"))
  147. return
  148. --door control
  149. elseif door_scroll.type == "CHG" then
  150. train.door_open = door_scroll.value-2
  151. return
  152. -- ars_disable
  153. elseif fields.ars_disable then
  154. if not advtrains.interlocking then
  155. return
  156. end
  157. advtrains.interlocking.ars_set_disable(train,minetest.is_yes(fields.ars_disable))
  158. return
  159. -- autocouple
  160. elseif fields.autocouple == "true" then
  161. train.autocouple = true
  162. return
  163. elseif fields.autocouple == "false" then
  164. train.autocouple = nil
  165. return
  166. -- emergency stop button
  167. elseif fields.estop then
  168. advtrains.atc.train_set_command(train,"BB",true)
  169. minetest.chat_send_player(pname,trans("Emergency Brake applied"))
  170. return
  171. end
  172. end
  173. end)
  174. minetest.register_craftitem(modname..":remote_control",{
  175. description = trans("Unbound Controller"),
  176. short_description = trans("Unbound Train Controller"),
  177. groups = {},
  178. inventory_image = "advtrains_rc_controller.png",
  179. wield_image = "advtrains_rc_controller.png",
  180. stack_max = 1,
  181. on_use = function(itemstack, user, pointed_thing)
  182. local pname = user:get_player_name()
  183. if not pname or pname == "" then
  184. return
  185. end
  186. if not minetest.check_player_privs(pname, {train_admin=true}) then
  187. minetest.chat_send_player(pname, trans("Insufficient privileges to use this!"))
  188. return
  189. end
  190. local meta = itemstack:get_meta()
  191. local bound_loco = meta:get_string("bound_loco") -- set to nil to enable bind-mode
  192. if bound_loco == "" then bound_loco = nil end
  193. if not bound_loco then -- start the search for a locomotive
  194. if pointed_thing.type == "object" then
  195. local object = pointed_thing.ref:get_luaentity()
  196. if not object.id then
  197. return
  198. end
  199. local data = advtrains.wagons[object.id]
  200. if not data then
  201. minetest.chat_send_player(pname,trans("This isn't even a train."))
  202. return
  203. else
  204. local wagon = advtrains.wagon_prototypes[data.type or data.entity_name]
  205. if not wagon then
  206. minetest.chat_send_player(pname,trans("Wagon '@1' couldn't be found.",data.type))
  207. return
  208. else
  209. if wagon.is_locomotive then -- bind to this locomotive
  210. meta:set_string("bound_loco",object.id)
  211. meta:set_string("roadnumber",data.roadnumber or "")
  212. meta:set_string("description",trans("Bound Controller"))
  213. else
  214. minetest.chat_send_player(pname,trans("You can only bind the controller to locomotives"))
  215. return
  216. end
  217. end
  218. end
  219. end
  220. else
  221. if not advtrains.wagons[bound_loco] then --loco has been removed from the world. set to unbound
  222. meta:set_string("bound_loco","")
  223. meta:set_string("roadnumber","")
  224. meta:set_string("description",trans("Unbound Controller"))
  225. minetest.chat_send_player(pname,trans("The locomotive has been removed from the world. Controller is unbound"))
  226. return itemstack
  227. end
  228. if meta:get("roadnumber") ~= advtrains.wagons[bound_loco].roadnumber then --update roadnumber for item description
  229. meta:set_string("roadnumber",advtrains.wagons[bound_loco].roadnumber)
  230. end
  231. end
  232. show_formspec(itemstack,pname)
  233. return itemstack
  234. end,
  235. })
  236. minetest.register_craft({
  237. output = modname..":remote_control",
  238. recipe = {
  239. {"default:mese_crystal_fragment","default:diamond","default:copper_ingot"},
  240. {"steel_ingot","advtrains_luaautomation:oppanel","steel_ingot"},
  241. {"","default:steel_ingot",""},
  242. }
  243. })