Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -----------------‐---------------------------------------------------------------------------------
- -- Advanced Vehicles II API by Andrey01
- -----‐---------------------------------------------------------------------------------------------
- vehicles = {}
- gravity = -9.8
- local showed_seats_fspecs = {} -- pair: ["playername"] and objectref
- -----‐---------------------------------------------------------------------
- -- API functions
- ---------------------------------------------------------------------------
- vehicles.set_gravity = function(self)
- local obj = self.object
- local acc = obj:get_acceleration()
- local vel = obj:get_velocity()
- local m = minetest.registered_entities[self.name].mass
- 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
- end
- vehicles.register_vehicle = function(name, veh_props, spawner_item_props)
- minetest.register_entity(MOD_NAME .. ":" .. name, {
- vehicle_type = veh_props.vehicle_type,
- physical = true,
- mass = veh_props.mass, -- in kgs
- collide_with_objects = true,
- collisionbox = veh_props.bounding_box or {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
- selectionbox = veh_props.bounding_box or {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
- visual = veh_props.visual,
- visual_size = veh_props.visual_size or {x=1, y=1, z=1},
- mesh = veh_props.visual == "mesh" and veh_props.model,
- textures = veh_props.textures or {},
- seats = veh_props.seats,
- on_activate = function(self, staticdata, dtime_s)
- local props = minetest.registered_entities[self.name]
- self.seats = props.seats
- end,
- on_step = function(self, dtime)
- vehicles.set_gravity(self)
- end,
- on_death = function(self, killer)
- for i, sdata in ipairs(self.seats) do
- vehicles.get_out(self, i)
- end
- for n, obj in pairs(showed_seats_fspecs) do
- if obj == self.object then
- vehicles.close_seats_formspec(self, n, MOD_NAME .. ":vehicle_seats")
- end
- end
- end,
- on_rightclick = function(self, clicker)
- vehicles.show_seats_formspec(self, MOD_NAME .. ":vehicle_seats", clicker:get_player_name())
- end
- })
- minetest.register_craftitem(MOD_NAME .. ":" .. name, {
- description = spawner_item_props.description or "",
- inventory_image = spawner_item_props.inv_image or "",
- on_place = function(itemstack, placer, pointed_thing)
- if pointed_thing.type =="node" and pointed_thing.above.y >= pointed_thing.under.y then
- minetest.add_entity(pointed_thing.above, itemstack:get_name())
- end
- end
- })
- end
- vehicles.show_seats_formspec = function(self, formspec_name, playername)
- local seats_n = #self.seats
- minetest.debug(seats_n)
- local buts_space_w, buts_space_h = 0.2, 0.3 -- space between buttons along width and height
- local int = math.modf(seats_n/8)
- local columns_n = (seats_n % 8 == 0 and int) or int + 1
- local w_sbut, h_sbut = 2, 0.5
- local fspec_size_w = columns_n * w_sbut + (columns_n + 1) * buts_space_w
- local fspec_size_h = 8 * h_sbut + 9 * buts_space_h + 2 -- + 2 is a space for label text
- local is_player_sit = vehicles.is_player_sit(minetest.get_player_by_name(playername))
- 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
- local fspec_t = {
- "formspec_version[3]",
- "size[" .. fspec_size_w .. "," .. fspec_size_h .. "]",
- "real_coordinates[true]",
- "label[2,1;" .. minetest.formspec_escape("Select a vacant seat inside the vehicle below:") .. "]"
- }
- local formspec = table.concat(fspec_t)
- local bpos_x, bpos_y = buts_space_w, buts_space_h
- for i = 1, seats_n do
- formspec = formspec .. "button[" .. bpos_x .. "," .. bpos_y .. ";" .. w_sbut .. "," .. h_sbut .. ";seat_" .. i .. ";" .. minetest.formspec_escape("Seat #" .. i) .. "]"
- bpos_x = ((i - 1) % 8 == 0) and bpos_x + w_sbut + buts_space_w
- bpos_y = (((i - 1) % 8 == 0) and buts_space_h) or bpos_y + h_sbut + buts_space_h
- end
- 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
- minetest.debug(formspec)
- showed_seats_fspecs[playername] = self.object
- minetest.show_formspec(playername, formspec_name, formspec)
- end
- vehicles.sit = function(self, player, seat_id, seat_anim) -- seat_id is an id of a seat table of 'self.seats'
- local sel_seat = self.seats[seat_id]
- local plname = player:get_player_name()
- if type(sel_seat.is_busy) == "string" and sel_seat.is_busy ~= plname then
- minetest.chat_send_player(plname, "Seat #" .. seat_id .. " is busy by " .. sel_seat.is_busy .. "!")
- return
- end
- if sel_seat.type == "driver" and seat_anim then
- local plmeta = player:get_meta()
- plmeta:set_string("previous_anim", minetest.serialize(player:get_animation()))
- player:set_animation(seat_anim.frange, seat_anim.fspeed, seat_anim.fblend, seat_anim.floop)
- end
- local vrot = self.object:get_rotation()
- player:set_attach(self, "", sel_seat.pos, {x=0, y=0, z=0})
- sel_seat.is_busy = plname
- end
- vehicles.get_out = function(self, seat_id)
- local seat = self.seats[seat_id]
- if not seat.is_busy then return end
- player:set_detach()
- if seat.type == "driver" then
- local player = minetest.get_player_by_name(self.is_busy)
- local plmeta = player:get_meta()
- local saved_anim = minetest.deserialize(plmeta:get_string("previous_anim"))
- if saved_anim then
- player:set_animation(saved_anim.frame_range, seat_anim.frame_speed, seat_anim.frame_blend, seat_anim.frame_loop)
- plmeta:set_string("previous_anim", "")
- end
- end
- seat.is_busy = nil
- end
- vehicles.on_formspec_event = function(player, formname, fields)
- if formname ~= MOD_NAME .. ":vehicle_seats" then
- return
- end
- local plname = player:get_player_name()
- local obj = showed_seats_fspecs[plname]
- local self = obj:get_luaentity()
- if self then
- for i, sdata in ipairs(self.seats) do
- local but_name = "seat_" .. i
- if fields[but_name] then
- vehicles.close_seats_formspec(self, plname, formname, i, "sit")
- return true
- end
- end
- if fields["get_out"] then
- vehicles.close_seats_formspec(self, plname, formname, i, "get_out")
- return true
- end
- else -- supposed that vehicle is died while the player is viewing the formspec
- vehicles.close_seats_formspec(self, plname, formname)
- end
- end
- -------‐---------------------------------------------------------------------
- -- Helper functions
- -----------------------------------------------------------------------------
- vehicles.is_player_sit = function(player)
- local self = player:get_attach()
- if not self then return false end
- local name = player:get_player_name()
- for i, sdata in ipairs(self.seats) do
- if sdata.is_busy == name then
- return true
- end
- end
- return false
- end
- -- 'seat_id' is optional
- -- 'action' is supposed what to do with the player after closing (sit or go out off the vehicle) [optional]
- vehicles.close_seats_formspec = function(self, playername, formname, seat_id, action)
- minetest.close_formspec(playername, formname)
- showed_seats_fspecs[playername] = nil
- local player = minetest.get_player_by_name(playername)
- if action == "sit" then
- vehicles.sit(self, player, seat_id)
- elseif action == "get_out" then
- vehicles.get_out(self, seat_id)
- end
- end
- -----------------------------------------------------------------------------
- -- Callback Registrations
- -----------------------------------------------------------------------------
- minetest.register_on_player_receive_fields(vehicles.on_formspec_event)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement