Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2020
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.84 KB | None | 0 0
  1. -----------------‐---------------------------------------------------------------------------------
  2. -- Advanced Vehicles II API by Andrey01
  3. -----‐---------------------------------------------------------------------------------------------
  4.  
  5. vehicles = {}
  6.  
  7. gravity = -9.8
  8.  
  9. local showed_seats_fspecs = {} -- pair: ["playername"] and objectref
  10.  
  11.  
  12. -----‐---------------------------------------------------------------------
  13. -- API functions
  14. ---------------------------------------------------------------------------
  15. vehicles.set_gravity = function(self)
  16. local obj = self.object
  17. local acc = obj:get_acceleration()
  18. local vel = obj:get_velocity()
  19. local m = minetest.registered_entities[self.name].mass
  20. obj:set_acceleration({x=acc.x, y=acc.y+(m*gravity-vel.y^2)/m, z=acc.z}) -- vel.y^2 is an air resistance
  21. end
  22.  
  23. vehicles.register_vehicle = function(name, veh_props, spawner_item_props)
  24. minetest.register_entity(MOD_NAME .. ":" .. name, {
  25. vehicle_type = veh_props.vehicle_type,
  26. physical = true,
  27. mass = veh_props.mass, -- in kgs
  28. collide_with_objects = true,
  29. collisionbox = veh_props.bounding_box or {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
  30. selectionbox = veh_props.bounding_box or {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
  31. visual = veh_props.visual,
  32. visual_size = veh_props.visual_size or {x=1, y=1, z=1},
  33. mesh = veh_props.visual == "mesh" and veh_props.model,
  34. textures = veh_props.textures or {},
  35. seats = veh_props.seats,
  36. on_activate = function(self, staticdata, dtime_s)
  37. local props = minetest.registered_entities[self.name]
  38. self.seats = props.seats
  39. end,
  40. on_step = function(self, dtime)
  41. vehicles.set_gravity(self)
  42. end,
  43. on_death = function(self, killer)
  44. for i, sdata in ipairs(self.seats) do
  45. vehicles.get_out(self, i)
  46. end
  47. for n, obj in pairs(showed_seats_fspecs) do
  48. if obj == self.object then
  49. vehicles.close_seats_formspec(self, n, MOD_NAME .. ":vehicle_seats")
  50. end
  51. end
  52. end,
  53. on_rightclick = function(self, clicker)
  54. vehicles.show_seats_formspec(self, MOD_NAME .. ":vehicle_seats", clicker:get_player_name())
  55. end
  56.  
  57. })
  58.  
  59. minetest.register_craftitem(MOD_NAME .. ":" .. name, {
  60. description = spawner_item_props.description or "",
  61. inventory_image = spawner_item_props.inv_image or "",
  62. on_place = function(itemstack, placer, pointed_thing)
  63. if pointed_thing.type =="node" and pointed_thing.above.y >= pointed_thing.under.y then
  64. minetest.add_entity(pointed_thing.above, itemstack:get_name())
  65. end
  66. end
  67. })
  68. end
  69.  
  70. vehicles.show_seats_formspec = function(self, formspec_name, playername)
  71. local seats_n = #self.seats
  72. minetest.debug(seats_n)
  73. local buts_space_w, buts_space_h = 0.2, 0.3 -- space between buttons along width and height
  74. local int = math.modf(seats_n/8)
  75. local columns_n = (seats_n % 8 == 0 and int) or int + 1
  76. local w_sbut, h_sbut = 2, 0.5
  77. local fspec_size_w = columns_n * w_sbut + (columns_n + 1) * buts_space_w
  78. local fspec_size_h = 8 * h_sbut + 9 * buts_space_h + 2 -- + 2 is a space for label text
  79. local is_player_sit = vehicles.is_player_sit(minetest.get_player_by_name(playername))
  80. fspec_size_h = (is_player_sit and fspec_size_h + 2) or fspec_size_h -- if player sits the vehicle, heighten the formspec window still at 2 units
  81. local fspec_t = {
  82. "formspec_version[3]",
  83. "size[" .. fspec_size_w .. "," .. fspec_size_h .. "]",
  84. "real_coordinates[true]",
  85. "label[2,1;" .. minetest.formspec_escape("Select a vacant seat inside the vehicle below:") .. "]"
  86. }
  87. local formspec = table.concat(fspec_t)
  88.  
  89. local bpos_x, bpos_y = buts_space_w, buts_space_h
  90. for i = 1, seats_n do
  91. formspec = formspec .. "button[" .. bpos_x .. "," .. bpos_y .. ";" .. w_sbut .. "," .. h_sbut .. ";seat_" .. i .. ";" .. minetest.formspec_escape("Seat #" .. i) .. "]"
  92. bpos_x = ((i - 1) % 8 == 0) and bpos_x + w_sbut + buts_space_w
  93. bpos_y = (((i - 1) % 8 == 0) and buts_space_h) or bpos_y + h_sbut + buts_space_h
  94. end
  95.  
  96. formspec = (is_player_sit and (formspec .. "button[" .. fspec_size_w / 2 - w_sbut / 2 .. ", " .. fspec_size_h - 1.5 .. ";" .. w_sbut .. ", " .. h_sbut .. ";get_out;" .. minetest.formspec_escape("Get out") .. "]")) or formspec
  97. minetest.debug(formspec)
  98. showed_seats_fspecs[playername] = self.object
  99. minetest.show_formspec(playername, formspec_name, formspec)
  100. end
  101.  
  102. vehicles.sit = function(self, player, seat_id, seat_anim) -- seat_id is an id of a seat table of 'self.seats'
  103. local sel_seat = self.seats[seat_id]
  104. local plname = player:get_player_name()
  105. if type(sel_seat.is_busy) == "string" and sel_seat.is_busy ~= plname then
  106. minetest.chat_send_player(plname, "Seat #" .. seat_id .. " is busy by " .. sel_seat.is_busy .. "!")
  107. return
  108. end
  109.  
  110. if sel_seat.type == "driver" and seat_anim then
  111. local plmeta = player:get_meta()
  112. plmeta:set_string("previous_anim", minetest.serialize(player:get_animation()))
  113. player:set_animation(seat_anim.frange, seat_anim.fspeed, seat_anim.fblend, seat_anim.floop)
  114. end
  115.  
  116. local vrot = self.object:get_rotation()
  117. player:set_attach(self, "", sel_seat.pos, {x=0, y=0, z=0})
  118.  
  119. sel_seat.is_busy = plname
  120. end
  121.  
  122. vehicles.get_out = function(self, seat_id)
  123. local seat = self.seats[seat_id]
  124. if not seat.is_busy then return end
  125.  
  126. player:set_detach()
  127.  
  128. if seat.type == "driver" then
  129. local player = minetest.get_player_by_name(self.is_busy)
  130. local plmeta = player:get_meta()
  131. local saved_anim = minetest.deserialize(plmeta:get_string("previous_anim"))
  132. if saved_anim then
  133. player:set_animation(saved_anim.frame_range, seat_anim.frame_speed, seat_anim.frame_blend, seat_anim.frame_loop)
  134. plmeta:set_string("previous_anim", "")
  135. end
  136. end
  137.  
  138. seat.is_busy = nil
  139. end
  140.  
  141. vehicles.on_formspec_event = function(player, formname, fields)
  142. if formname ~= MOD_NAME .. ":vehicle_seats" then
  143. return
  144. end
  145.  
  146. local plname = player:get_player_name()
  147. local obj = showed_seats_fspecs[plname]
  148. local self = obj:get_luaentity()
  149. if self then
  150. for i, sdata in ipairs(self.seats) do
  151. local but_name = "seat_" .. i
  152. if fields[but_name] then
  153. vehicles.close_seats_formspec(self, plname, formname, i, "sit")
  154. return true
  155. end
  156. end
  157.  
  158. if fields["get_out"] then
  159. vehicles.close_seats_formspec(self, plname, formname, i, "get_out")
  160. return true
  161. end
  162. else -- supposed that vehicle is died while the player is viewing the formspec
  163. vehicles.close_seats_formspec(self, plname, formname)
  164. end
  165. end
  166.  
  167.  
  168.  
  169.  
  170. -------‐---------------------------------------------------------------------
  171. -- Helper functions
  172. -----------------------------------------------------------------------------
  173. vehicles.is_player_sit = function(player)
  174. local self = player:get_attach()
  175. if not self then return false end
  176.  
  177. local name = player:get_player_name()
  178. for i, sdata in ipairs(self.seats) do
  179. if sdata.is_busy == name then
  180. return true
  181. end
  182. end
  183.  
  184. return false
  185. end
  186.  
  187. -- 'seat_id' is optional
  188. -- 'action' is supposed what to do with the player after closing (sit or go out off the vehicle) [optional]
  189. vehicles.close_seats_formspec = function(self, playername, formname, seat_id, action)
  190. minetest.close_formspec(playername, formname)
  191. showed_seats_fspecs[playername] = nil
  192.  
  193. local player = minetest.get_player_by_name(playername)
  194. if action == "sit" then
  195. vehicles.sit(self, player, seat_id)
  196. elseif action == "get_out" then
  197. vehicles.get_out(self, seat_id)
  198. end
  199. end
  200.  
  201.  
  202. -----------------------------------------------------------------------------
  203. -- Callback Registrations
  204. -----------------------------------------------------------------------------
  205. minetest.register_on_player_receive_fields(vehicles.on_formspec_event)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement