Added initial media and code

master
Andrey 2020-06-25 23:00:39 +03:00
parent 0c4b04f0db
commit e7ddf5e94e
21 changed files with 5893 additions and 0 deletions

594
api.lua Normal file
View File

@ -0,0 +1,594 @@
--------------------------------------------------------------------------------------------------
-- Advanced Vehicles II API by Andrey01
--------------------------------------------------------------------------------------------------
vehicles = {}
gravity = -9.8
local showed_seats_fspecs = {} -- pair: ["playername"] and objectref
local ngroups_friction_coefs = { -- friction coefficients of some groups of nodes.
["sand"] = 1.5,
["soil"] = 0.6,
["snowy"] = 0.9,
["slippery"] = 0.1,
["default"] = 0.8
}
-- Air resistance force is calculated for now only along the horizontal plane!
local air_rcoef = 0.3 -- air resistance coefficient
--------------------------------------------------------------------------
-- 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=gravity, z=acc.z})
end
--[[ Registers new vehicle (base and wheel)
base_props and wheel_props should contain def props for entity ('obj') and its item ('item')
]]
vehicles.register_vehicle = function(name, base_props, wheel_props)
minetest.register_entity(MOD_NAME .. ":" .. name .. "_base", {
vehicle_type = base_props.obj.vehicle_type,
physical = true,
mass = base_props.obj.mass or 2000, -- in kgs
collide_with_objects = true,
collisionbox = base_props.obj.bounding_box or {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
selectionbox = base_props.obj.bounding_box or {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
visual = base_props.obj.visual,
visual_size = base_props.obj.visual_size or {x=1, y=1, z=1},
mesh = (base_props.obj.visual == "mesh" and base_props.obj.mesh),
textures = base_props.obj.textures or {""},
use_texture_alpha = base_props.obj.use_texture_alpha,
seats = base_props.obj.seats, -- table fields: {["is_busy"] = playername, ["pos"] = position, ["rot"] = rotation, ["type"] = ("driver" or "passenger"), ["model"] = <name>}
--ctrl_vals = base_props.ctrl_vals, -- table fields: {["move"] = float (acc_len), ["turn"] = float (degs)}
traction_force = base_props.obj.traction_force or 5000, -- in Neutons
wheels = base_props.obj.wheels, -- table fields: {["type"] = ("front" or "rear"), ["pos"] = position, ["rot"] = rotation, ["radius"] = wheel radius}
max_speed = base_props.obj.max_speed or 25000, -- in m/s
stepheight = base_props.obj.stepheight or 0.5,
on_activate = function(self, staticdata, dtime_s)
self.seats = table.copy(base_props.obj.seats)
for i, seat in ipairs(self.seats) do
seat.rot = seat.rot or {x=0, y=0, z=0}
seat.radius = seat.radius or 0.5
end
self.wheels = {}
self.tracf_dir = 0 -- specifies a modulo and direction of the vehicle traction force (> 0 on forward, < 0 on backward, = 0 on stay)
--[[if base_props.obj.player_model_def then
self.player_models = {}
if base_props.obj.player_model_def.driver then
player_api.register_model(base_props.obj.player_model_def.driver.name, table.derive_elems(base_props.obj.player_model_def.driver, 2, #base_props.obj.player_model_def.driver))
self.player_models.driver = base_props.obj.player_model_def.driver.name
end
if base_props.obj.player_model_def.passenger then
player_api.register_model(base_props.obj.player_model_def.passenger.name, table.derive_elems(base_props.obj.player_model_def.passenger, 2, #base_props.obj.player_model_def.passenger))
self.player_models.passenger = base_props.obj.player_model_def.passenger.name
end
end]]
local rel_vehpos = self.object:get_pos()
local vehrot = self.object:get_rotation()
for i, whl in ipairs(base_props.obj.wheels) do
local whl_obj = minetest.add_entity({x=rel_vehpos.x+whl.pos.x, y=rel_vehpos.y+whl.pos.y, z=rel_vehpos.z+whl.pos.z}, MOD_NAME .. ":" .. name .. "_wheel")
whl_obj:set_attach(self.object, "", whl.pos, whl.rot or {0, 0, 0})
self.wheels[i] = {object=whl_obj, type=whl.type, pos=whl.pos, rot=whl.rot or {0, 0, 0}, radius=whl.radius}
end
vehicles.set_gravity(self)
--self.acc_v2d = vehicles.v2d_coords(base_props.traction_force/base_props.mass, vehrot.y) -- keep own vehicle 2d acceleration along horizontal plane that doesn`t depend to external impacts
end,
on_step = function(self, dtime)
local max_fcoef = vehicles.max_fric_coef(self)
local edef = minetest.registered_entities[self.name]
local acc = self.object:get_acceleration()
local sf_fforce = vehicles.surface_fric_force(max_fcoef, edef.mass, acc.y*edef.mass)
local vel = self.object:get_velocity()
local v2d_vl = vehicles.v2d_length(vel)
local air_rforce = vehicles.air_resist_force(v2d_vl)
vehicles.on_move(self)
if v2d_vl == 0 then self.tracf_dir = 0 sf_fforce = 0 end
if self.tracf_dir > 0 then sf_fforce = -sf_fforce air_rforce = -air_rforce end
local acc_sum = (self.tracf_dir + sf_fforce + air_rforce)/edef.mass
local acc2d = vehicles.v2d_coords(acc_sum, self.object:get_yaw())
minetest.debug(dump(acc2d))
self.object:set_acceleration({x=acc2d.x, y=acc.y, z=acc2d.z})
for i, d in ipairs(self.wheels) do
d.object:set_rotation(vehicles.calc_angle_vel(vel, d.radius))
end
end,
on_death = function(self, killer)
for i, sdata in ipairs(self.seats) do
vehicles.get_out(self, sdata.is_busy and minetest.get_player_by_name(sdata.is_busy))
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
for i, whl in ipairs(self.wheels) do
whl.object:remove()
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 .. "_base", {
description = base_props.item.description or "",
inventory_image = base_props.item.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
})
minetest.register_entity(MOD_NAME .. ":" .. name .. "_wheel", {
visual_size = wheel_props.obj.visual_size or {x=1, y=1, z=1},
pointable = false,
visual = wheel_props.obj.visual,
mesh = (wheel_props.obj.visual == "mesh" and wheel_props.obj.mesh),
textures = wheel_props.obj.textures or {""},
use_texture_alpha = wheel_props.obj.use_texture_alpha
})
minetest.register_craftitem(MOD_NAME .. ":" .. name .. "_wheel", {
description = wheel_props.item.description or "",
inventory_image = wheel_props.item.inventory_image or ""
})
if base_props.obj.player_mdefs then
if base_props.obj.player_mdefs.driver then
player_api.register_model(base_props.obj.player_mdefs.driver.model_name, base_props.obj.player_mdefs.driver.def)
elseif base_props.obj.player_mdefs.passenger then
player_api.register_model(base_props.obj.player_mdefs.passenger.model_name, base_props.obj.player_mdefs.passenger.def)
end
end
end
vehicles.show_seats_formspec = function(self, formspec_name, playername)
local seats_n = #self.seats
local sbut_size = {x=4, y=1.5}
local pad = 0.5
local visible_cbuts_n = (seats_n <= 4 and seats_n or 4)
local scontainer_size = {x=2*0.3 + sbut_size.x, y=visible_cbuts_n*sbut_size.y + (visible_cbuts_n+1)*0.3}
local wsize_x = pad*2 + scontainer_size.x
local is_player_sit = vehicles.is_player_sit(minetest.get_player_by_name(playername))
local wsize_y = 2 + scontainer_size.y + (is_player_sit and 2.5 or pad) -- + 2.5 units for 'Get Up' button placement
local formspec = "formspec_version[3]size[" .. wsize_x .. ", " .. wsize_y .. "]" ..
"label[" .. pad + 0.2 .. "," .. pad + 0.5 .. ";" .. minetest.formspec_escape("Select a seat to sit down or press to get up:") .. "]" ..
"box[" .. pad .. ",2;" .. scontainer_size.x .. "," .. scontainer_size.y .. ";#000]" ..
"scrollbaroptions[thumbsize=1000]" ..
"scrollbar[" .. scontainer_size.x + pad .. ",2;0.3," .. scontainer_size.y .. ";vertical;vseats_scrollbar;0]" ..
"scroll_container[" .. pad .. ",2;" .. scontainer_size.x .. "," .. scontainer_size.y .. ";vseats_scrollbar;vertical;]"
local butpos_y = 0.3
for i, sdata in ipairs(self.seats) do
local i_busy = sdata.is_busy
formspec = formspec .. (i_busy and "style[seat_" .. i .. ";bgcolor=#FF0000]" or "") .. "button[0.3," .. butpos_y .. ";" .. sbut_size.x .. "," .. sbut_size.y ..
";seat_" .. i .. ";" .. minetest.formspec_escape("#" .. i .. ((i_busy and "\n(busy by " .. playername .. ")") or "")) .. "]"
butpos_y = butpos_y + sbut_size.y + 0.3
end
formspec = formspec .. "scroll_container_end[]" ..
(is_player_sit and "button[" .. wsize_x/2 - sbut_size.x/2 .. "," .. (wsize_y - (2.5/4*3)) .. ";4,1.5;get_up;" .. minetest.formspec_escape("Get up") .. "]" or "")
showed_seats_fspecs[playername] = self.object
minetest.show_formspec(playername, formspec_name, formspec)
end
--[[vehicles.show_seats_formspec = function(self, formspec_name, playername)
local seats_n = #self.seats
local min_sbut_s = {x=1, y=0.5} -- min seat button size
local max_sbut_s = {x=4, y=2}
local buts_space_w = 0.3 -- space button size doesn`t depend on buttons` sizes
local buts_space_h = 0.2
local w_sbut, h_sbut = 0.5, 0.5 -- distance between window edge and button doesn`t depend on buttons` sizes
local sizedowns_n = math.ceil(math.sqrt(seats_n)) -- number of button sizedowns
local but_new_x_s = max_sbut_s.x-0.5*sizedowns_n
local but_new_y_s = max_sbut_s.y-0.5*sizedowns_n
local wsize_chx = 0
local wsize_chy = 0
if but_new_x_s < min_sbut_s.x or but_new_y_s < min_sbut_s.y then
but_new_x_s = min_sbut_s.x
but_new_y_s = min_sbut_s.y
wsize_chx = 1.5*sizedowns_n-(max_sbut_s.x-min_sbut_s.x)
wsize_chy = 1.5*sizedowns_n-(max_sbut_s.y-min_sbut_s.y)
end
local wsize_x = sizedowns_n*but_new_x_s + 2*w_sbut + (sizedowns_n-1)*buts_space_w + wsize_chx
local wsize_y = sizedowns_n*but_new_y_s + 2*h_sbut + (sizedowns_n-1)*buts_space_h + wsize_chy + 2 -- '+ 2' is a space for label text
local is_player_sit = vehicles.is_player_sit(minetest.get_player_by_name(playername))
wsize_y = is_player_sit and wsize_y + 2 or wsize_y
local formspec = "formspec_version[3]size[" .. wsize_x .. ", " .. wsize_y .. "]label[" .. wsize_x/4 .. ",1;" .. minetest.formspec_escape("Select a seat to sit down or press to get up:") .. "]"
local bpos_x = w_sbut
local bpos_y = 2
for i = 1, seats_n do
minetest.debug(i)
bpos_x = ((i <= sizedowns_n or i > (math.pow(sizedowns_n, 2)-sizedowns_n)) and bpos_x + w_sbut) or bpos_x + buts_space_w
bpos_y = ((i%sizedowns_n == 0) and bpos_y + h_sbut) or (((i-1)%sizedowns_n == 0) and 2 + h_sbut) or bpos_y + buts_space_h
local i_busy = self.seats[i].is_busy
formspec = formspec .. ((i_busy and "style[seat_" .. i .. ";bgcolor=#FF0000]") or "")
formspec = formspec .. "button[" ..
bpos_x .. "," .. bpos_y .. ";" ..
but_new_x_s .. "," .. but_new_y_s ..
";seat_" .. i .. ";" .. minetest.formspec_escape("#" .. i .. ((i_busy and "\n" .. playername) or "")) .. "]"
bpos_x = (i ~= 1 and (i-1)%sizedowns_n == 0 and bpos_x + but_new_x_s) or bpos_x
bpos_y = bpos_y + but_new_y_s
bpos_x = i == (math.pow(sizedowns_n, 2)-sizedowns_n+1) and bpos_x + w_sbut or (i-1)%sizedowns_n == 0 and bpos_x + buts_space_w
bpos_y = i%sizedowns_n == 0 and 2 or bpos_y + buts_space_h
end
formspec = (is_player_sit and (formspec .. "button[" ..
wsize_x/2 - ((but_new_x_s+2)/2) .. "," .. bpos_y .. ";" ..
but_new_x_s+2 .. "," .. wsize_y - bpos_y - (buts_space_h + 0.5 + h_sbut) ..
";get_up;" .. minetest.formspec_escape("Get up") .. "]")) or formspec
showed_seats_fspecs[playername] = self.object
minetest.show_formspec(playername, formspec_name, formspec)
end]]
--[[vehicles.show_seats_formspec = function(self, formspec_name, playername)
local seats_n = #self.seats
--minetest.debug(seats_n)
local buts_space_w = 0.2
local buts_space_h = 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 max_col_cells_n = (seats_n >= 8 and 8) or seats_n
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 = max_col_cells_n * h_sbut + (max_col_cells_n+1) * 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 formspec = "size[" .. fspec_size_w .. ", " .. fspec_size_h .. "]label[2,1;" .. minetest.formspec_escape("Select a vacant seat inside the vehicle below:") .. "]"
local bpos_x = buts_space_w
minetest.debug(bpos_x)
local bpos_y = buts_space_h+2
for i = 1, seats_n do
formspec = formspec .. "button[" ..
tostring(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+2) 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_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
local cur_seat = vehicles.is_player_sit(player)
if cur_seat then
self.seats[cur_seat.seat_id].is_busy = nil
end
sel_seat.is_busy = player:get_player_name()
local plmeta = player:get_meta()
local anim = player_api.get_animation(player)
local pl_mdefs = minetest.registered_entities[self.name].player_mdefs
local pl_data = {}
if pl_mdefs then
if sel_seat.type == "driver" and pl_mdefs.driver then
pl_data.prev_model = anim.model
pl_data.prev_anim = anim.animation
player_api.set_model(player, pl_mdefs.driver.model_name)
elseif sel_seat.type == "passenger" and pl_mdefs.passenger then
pl_data.prev_model = anim.model
pl_data.prev_anim = anim.animation
player_api.set_model(player, pl_mdefs.passenger.model_name)
end
end
pl_data.prev_pos = player:get_pos()
pl_data.prev_rot = player:get_rotation()
pl_data.seat_id = seat_id
plmeta:set_string("prev_data", minetest.serialize(pl_data))
player:set_attach(self.object, "", sel_seat.pos, sel_seat.rot)
player:set_eye_offset(sel_seat.pos, sel_seat.pos)
player:set_look_horizontal(self.object:get_yaw()+180)
player_api.player_attached[player:get_player_name()] = true
end
vehicles.get_out = function(self, player)
if not player or not self.object:get_luaentity() then
return
end
player:set_detach()
local plmeta = player:get_meta()
local pl_data = minetest.deserialize(plmeta:get_string("prev_data"))
if pl_data.prev_model then
player_api.set_model(player, pl_data.prev_model)
end
if pl_data.prev_anim then
player_api.set_animation(player, pl_data.prev_anim)
end
local seat = self.seats[pl_data.seat_id]
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, "sit", i)
return true
end
end
if fields["get_up"] then
vehicles.close_seats_formspec(self, plname, formname, "get_up")
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
-- Returns traction force along according direction or nil if no player as a driver or any driving keys are not pressed
vehicles.on_move = function(self)
local drv_name = self.seats[vehicles.get_driver_i(self)].is_busy
if not drv_name then return end
minetest.debug("Driver is available!")
local player = minetest.get_player_by_name(drv_name)
local ctrls = player:get_player_control()
local entity_def = minetest.registered_entities[self.name]
if ctrls.up then
self.tracf_dir = entity_def.traction_force
end
if ctrls.down then
self.tracf_dir = -entity_def.traction_force
end
end
--[[if ctrls.up and vehicles.v2d_length(self.acc_v2d) == 0 then
local new_acc = vector.add(acc, {x=self.acc_v2d.x, y=0, z=self.acc_v2d.z})
self.object:set_acceleration(new_acc)
else
self.acc_v2d = {x=0, z=0}
end
if ctrls.down and vehicles.v2d_length(self.acc_v2d) == 0 then
local new_acc = vector.add(acc, {x=-self.acc_v2d.x, y=0, z=-self.acc_v2d.z})
self.object:set_acceleration(new_acc)
else
self.acc_v2d = {x=0, z=0}
end]]
--[[ local acc_len = vector.length(acc)
if acc_len <= ctrl_vals.up then
new_acc.x = acc.x
new_acc.z = acc.z
local v_and_a_codir = vehicles.are_horiz_codirectional(acc, vel)
if type(v_and_a_codir) == "number" then]]
--[[vehicles.force_brake = function(self)
local max_fcoef = vehicles.max_fric_coef(self)
local edef = minetest.registered_entities[self.name]
local fric_force = vehicles.friction_force(max_fcoef, edef.mass, math.abs(self.object:get_acceleration().y))
local acc = self.object:get_acceleration()
local tracforce = edef.mass*vehicles.v2d_length({x=acc.x, z=acc.z})
local new_acc_len = (tracforce-fric_force)/edef.mass
local new_acc_coords = vector
local brake_vec = vehicles.get_acc_vect(vehicles.v2d_length({x=acc.x, z=acc.z})/max_fcoef, acc.y, self.object:get_yaw()+math.rad(180))]]
----------------------------------------------------------------------------
-- Helper functions
-----------------------------------------------------------------------------
-- Derives the elements from range 'i1' up to 'i2' of 't' table into new one
-- i1 and i2 can be only positive
-- NOTE: table keys can be not only integral
table.derive_elems = function(t, i1, i2)
local new_t = {}
local elem_c = 0
for k, v in pairs(t) do
elem_c = elem_c + 1
if elem_c > i2 then
return new_t
end
new_t[k] = v
end
return new_t
end
vehicles.is_player_sit = function(player)
local obj = player:get_attach()
if not obj then return false end
local prev_data = minetest.deserialize(player:get_meta():get_string("prev_data"))
return prev_data
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, action, seat_id)
local player = minetest.get_player_by_name(playername)
if action == "sit" then
local is_busy = self.seats[seat_id].is_busy
if is_busy then return end
vehicles.sit(self, player, seat_id)
elseif action == "get_up" then
vehicles.get_out(self, player)
local pl_meta = player:get_meta()
local pl_data = minetest.deserialize(pl_meta:get_string("prev_data"))
player:set_pos(pl_data.prev_pos)
player:set_rotation(pl_data.prev_rot)
pl_data = nil
pl_meta:set_string("prev_data", "")
end
minetest.close_formspec(playername, formname)
showed_seats_fspecs[playername] = nil
end
-- Returns index in seats table where driver data is.
vehicles.get_driver_i = function(self)
if not self then return end
for i, sdata in ipairs(self.seats) do
if sdata.type == "driver" then
return i
end
end
return
end
-- checks if given vectors are co-directional along the horizontal plane; returns true, if they are, otherwise angle between them
--[[vehicles.are_horiz_codirectional = function(acc, vel)
local vec1 = vector.new(acc.x, 0, acc.z)
local vec2 = vector.new(vel.x, 0, vel.z)
local angle = math.deg(vector.angle(vec1, vec2))
return (angle == 0) or (angle
end]]
-- Calculates an angle speed (in rads) of the wheel
vehicles.calc_angle_vel = function(vel, radius)
return {x=vel.x/radius, y=vel.y/radius, z=vel.z/radius}
end
--vehicles.rotate_acc_vect = function(old_acc, turn_ang)
-- Calculates new (relative) coords of the acceleration vector
vehicles.v2d_coords = function(a_len, yaw)
local x = -a_len * math.sin(yaw)
local z = a_len * math.cos(yaw)
return {x=x, z=z}
end
vehicles.v2d_length = function(v2d)
return math.sqrt(v2d.x^2 + v2d.z^2)
end
-- Find out max friction coefficient of nodes locating beneath the entity
vehicles.max_fric_coef = function(self)
local max_friction_coef = 0
local vehpos = self.object:get_pos()
for i, whl in ipairs(self.wheels) do
local pos = whl.object:get_pos()
pos = vehicles.convert_pos_to_absolute(vehpos, pos)
local undernode = minetest.get_node({x=pos.x, y=pos.y-whl.radius-0.1, z=pos.z})
local group = vehicles.get_node_groupname(undernode.name)
if max_friction_coef < ngroups_friction_coefs[group] then
max_friction_coef = ngroups_friction_coefs[group]
end
end
return max_friction_coef
end
-- Calculates a modulo of a friction force of the surface under the vehicle
vehicles.surface_fric_force = function(fric_coef, mass, g)
return fric_coef*mass*-g
end
-- Convert the relative pos coords to absolute
vehicles.convert_pos_to_absolute = function(origin, pos)
return {x=origin.x+pos.x, y=origin.y+pos.y, z=origin.z+pos.z}
end
-- Convert the absolute pos coords to relative (relatively to 'origin')
vehicles.convert_pos_to_relative = function(origin, pos)
return {x=pos.x-origin.x, y=pos.y-origin.y, z=pos.z-origin.z}
end
-- Returns a node group that associated with its certain type (e.g. sand/desert sand are "sand" group, snow block/snow with grass are "snowy" group)
vehicles.get_node_groupname = function(name)
local groups = minetest.registered_nodes[name].groups
--minetest.debug("nodename:" .. name)
--minetest.debug("nodegroups:" .. dump(groups))
for group, coef in pairs(ngroups_friction_coefs) do
if groups[group] then
return group
end
end
return "default"
end
-- Calculates a modulo of an air resistance force (only along horizontal plane currently)
vehicles.air_resist_force = function(v_l)
return air_rcoef * math.abs(v_l)^2
end
-----------------------------------------------------------------------------
-- Callback Registrations
-----------------------------------------------------------------------------
minetest.register_on_player_receive_fields(vehicles.on_formspec_event)
minetest.register_on_leaveplayer(function(obj, timed_out)
local is_player_sit = vehicles.is_player_sit(obj:get_luaentity())
if is_player_sit then
local parent = obj:get_attach()
local self = parent:get_luaentity()
self.seats[is_player_sit.seat_id].is_busy = nil
end
end)

0
depends.txt Normal file
View File

117
init.lua Normal file
View File

@ -0,0 +1,117 @@
MOD_NAME = "adv_vehicles2" -- global macro
local modpath = minetest.get_modpath(MOD_NAME)
dofile(modpath .. "/api.lua")
--[[minetest.register_entity("cars_api:car", {
mass = 2000, -- in kg
physical = true,
visual = "cube",
on_activate = function(self, staticdata, dtime_s)
self.mass = 2000
self.step = function(self, dtime)
cars.set_gravity(self)
end
end
})
minetest.register_craftitem("cars_api:car", {
description = "Car",
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type == "node" then
minetest.add_entity(pointed_thing.above, "cars_api:car")
end
end
})
minetest.register_globalstep(function(dtime)
minetest.debug(dump(minetest.luaentities))
for i, self in pairs(minetest.luaentities) do
minetest.debug(i .. ": " .. dump(self))
if self.step then
self.step(self, dtime)
end
end
end)]]
-- Test car
--[[vehicles.register_vehicle("cube_car", {
vehicle_type = "ground",
visual = "cube",
mass = 2000,
bounding_box = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
seats = {{type = "driver", pos = {0, 0.3, 0}}}
}, {
description = "Cube car"
}
)]]
vehicles.register_vehicle("bmw", {
obj = {
vehicle_type = "ground",
mass = 2000,
bounding_box = {-1.7, -0.5, -4.5, 1.6, 2.2, 2.7},
visual = "mesh",
visual_size = {x=3.5, y=3.5, z=3.5},
mesh = "bmw_fw.b3d",
textures = {"bmw.png"},
seats = {
{
["pos"] = {x=-2.5, y=-1.5, z=-3.0},
["type"] = "driver"
},
{
["pos"] = {x=2.5, y=-1.5, z=-3.0},
["type"] = "passenger"
},
{
["pos"] = {x=0.0, y=-1.5, z=5.5},
["type"] = "passenger"
}
},
traction_force = 5000,
wheels = {
{
["type"] = "front",
["pos"] = {x=-3.1, y=-0.05, z=-7.55},
["radius"] = 0.5
},
{
["type"] = "front",
["pos"] = {x=2.9, y=-0.05, z=-7.55},
["rot"] = {x=0, y=180, z=0},
["radius"] = 0.5
},
{
["type"] = "rear",
["pos"] = {x=-3.1, y=-0.05, z=4.85},
["radius"] = 0.5
},
{
["type"] = "rear",
["pos"] = {x=2.9, y=-0.05, z=4.85},
["rot"] = {x=0, y=180, z=0},
["radius"] = 0.5
}
},
max_speed = 50000,
stepheight = 0.5
},
item = {
description = "BMW Spawner",
inv_image = "bmw_inv.png"
}
}, {
obj = {
visual = "mesh",
visual_size = {x=1, y=1, z=1},
mesh = "bmw_wheel.b3d",
textures = {"bmw.png"}
},
item = {
description = "BMW wheel",
inventory_image = "bmw_wheel.png"
}
}
)

BIN
models/bmw_fw.b3d Normal file

Binary file not shown.

BIN
models/bmw_fw.blend Normal file

Binary file not shown.

BIN
models/bmw_fw.blend1 Normal file

Binary file not shown.

13
models/bmw_fw.mtl Normal file
View File

@ -0,0 +1,13 @@
# Blender MTL File: 'bmw_fw.blend'
# Material Count: 1
newmtl bmw
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.000000 0.000000 0.000000
Ke 0.0 0.0 0.0
Ni 1.450000
d 1.000000
illum 1
map_Kd /home/andrey/minetest-5.3.0-dev_built/mods/adv_vehicles2/textures/bmw.png

4918
models/bmw_fw.obj Normal file

File diff suppressed because it is too large Load Diff

BIN
models/bmw_fw.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
models/bmw_wheel.b3d Normal file

Binary file not shown.

BIN
models/bmw_wheel.blend Normal file

Binary file not shown.

BIN
models/bmw_wheel.blend1 Normal file

Binary file not shown.

13
models/bmw_wheel.mtl Normal file
View File

@ -0,0 +1,13 @@
# Blender MTL File: 'bmw_wheel.blend'
# Material Count: 1
newmtl bmw
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.000000 0.000000 0.000000
Ke 0.0 0.0 0.0
Ni 1.450000
d 1.000000
illum 1
map_Kd /home/andrey/minetest-5.3.0-dev_built/mods/adv_vehicles2/textures/bmw.png

238
models/bmw_wheel.obj Normal file
View File

@ -0,0 +1,238 @@
# Blender v2.80 (sub 75) OBJ File: 'bmw_wheel.blend'
# www.blender.org
mtllib bmw_wheel.mtl
o BMW_wheel_Cube.001
v 0.455955 -0.000000 1.446572
v -0.806332 0.000000 1.446572
v 0.455955 0.850273 1.170301
v -0.806332 0.850274 1.170302
v 0.455955 1.375771 0.447015
v -0.806332 1.375771 0.447015
v 0.455955 1.375771 -0.447015
v -0.806332 1.375771 -0.447015
v 0.455955 0.850273 -1.170301
v -0.806332 0.850274 -1.170300
v 0.455955 -0.000000 -1.446571
v -0.806332 -0.000000 -1.446571
v 0.455955 -0.850274 -1.170301
v -0.806332 -0.850273 -1.170300
v 0.455955 -1.375772 -0.447016
v -0.806332 -1.375771 -0.447015
v 0.455955 -1.375772 0.447015
v -0.806332 -1.375771 0.447016
v 0.455954 -0.850273 1.170301
v -0.806332 -0.850273 1.170302
v 0.455955 -0.000000 1.168653
v 0.455955 0.686917 0.945460
v 0.455955 1.111455 0.361134
v 0.455955 1.111455 -0.361134
v 0.455955 0.686917 -0.945459
v 0.455955 -0.000000 -1.168653
v 0.455955 -0.686917 -0.945459
v 0.455955 -1.111455 -0.361134
v 0.455955 -1.111455 0.361134
v 0.455955 -0.686917 0.945460
v 0.368532 0.000000 1.076892
v 0.368532 0.632981 0.871225
v 0.368532 1.024185 0.332778
v 0.368532 1.024185 -0.332778
v 0.368532 0.632981 -0.871223
v 0.368532 0.000000 -1.076890
v 0.368532 -0.632980 -0.871223
v 0.368532 -1.024184 -0.332778
v 0.368532 -1.024184 0.332778
v 0.368532 -0.632980 0.871225
v -1.518813 -0.197756 -0.197756
v -1.518813 0.197756 -0.197756
v -1.518813 -0.197756 0.197756
v -1.518813 0.197756 0.197756
v -0.806332 -0.197755 -0.197756
v -0.806332 0.197756 -0.197756
v -0.806332 -0.197755 0.197756
v -0.806332 0.197756 0.197756
v 0.455955 0.000000 1.076892
v 0.455955 0.632981 0.871225
v 0.455955 1.024185 0.332778
v 0.455955 1.024185 -0.332778
v 0.455955 0.632981 -0.871223
v 0.455955 0.000000 -1.076890
v 0.455955 -0.632980 -0.871223
v 0.455955 -1.024184 -0.332778
v 0.455955 -1.024184 0.332778
v 0.455955 -0.632980 0.871225
vt 0.638389 0.748982
vt 0.638389 0.718726
vt 0.681107 0.718726
vt 0.681107 0.748982
vt 0.638389 0.688470
vt 0.681107 0.688470
vt 0.638389 0.991026
vt 0.638389 0.960771
vt 0.681107 0.960771
vt 0.681107 0.991026
vt 0.638389 0.930515
vt 0.681107 0.930515
vt 0.638389 0.900260
vt 0.681107 0.900260
vt 0.638389 0.870004
vt 0.681107 0.870004
vt 0.638389 0.839748
vt 0.681107 0.839748
vt 0.638389 0.809493
vt 0.681107 0.809493
vt 0.462868 0.753337
vt 0.479261 0.775900
vt 0.479261 0.803789
vt 0.462868 0.826352
vt 0.436344 0.834970
vt 0.409820 0.826352
vt 0.393428 0.803789
vt 0.393428 0.775900
vt 0.409820 0.753338
vt 0.436344 0.744719
vt 0.638389 0.779237
vt 0.681107 0.779237
vt 0.531421 0.742461
vt 0.531329 0.754142
vt 0.509564 0.761019
vt 0.502769 0.751514
vt 0.559923 0.751978
vt 0.552980 0.761372
vt 0.577387 0.776431
vt 0.566247 0.779947
vt 0.577143 0.806478
vt 0.566062 0.802772
vt 0.502130 0.830180
vt 0.509079 0.820777
vt 0.530730 0.828007
vt 0.530632 0.839697
vt 0.559284 0.830644
vt 0.552495 0.821130
vt 0.484666 0.805727
vt 0.495812 0.802202
vt 0.484910 0.775680
vt 0.495997 0.779376
vt 0.616807 0.714659
vt 0.616807 0.680148
vt 0.610058 0.680148
vt 0.610058 0.714659
vt 0.616807 0.956237
vt 0.616807 0.921726
vt 0.610058 0.921726
vt 0.610058 0.956237
vt 0.616807 0.852704
vt 0.616807 0.818193
vt 0.610058 0.818193
vt 0.610058 0.852704
vt 0.616807 0.749170
vt 0.610058 0.749170
vt 0.616807 0.990749
vt 0.610058 0.990749
vt 0.616807 0.887215
vt 0.610058 0.887215
vt 0.616807 0.783681
vt 0.610058 0.783681
vt 0.616807 0.645637
vt 0.610058 0.645637
vt 0.491076 0.697958
vt 0.491076 0.666712
vt 0.497469 0.668793
vt 0.497469 0.695886
vt 0.558413 0.938188
vt 0.558435 0.891375
vt 0.530937 0.853490
vt 0.486422 0.839003
vt 0.441894 0.853449
vt 0.414360 0.891308
vt 0.414338 0.938121
vt 0.441836 0.976006
vt 0.486351 0.990493
vt 0.530880 0.976048
vt 0.741486 0.858324
vt 0.708724 0.858324
vt 0.708724 0.840137
vt 0.741486 0.840137
vt 0.708724 0.803763
vt 0.741486 0.803763
vt 0.741486 0.821950
vt 0.708724 0.821950
vt 0.741486 0.785576
vt 0.708724 0.785576
vt 0.509442 0.641433
vt 0.513394 0.646876
vt 0.539159 0.631778
vt 0.539160 0.638505
vt 0.568876 0.641434
vt 0.564926 0.646877
vt 0.587242 0.666713
vt 0.580850 0.668794
vt 0.587242 0.697959
vt 0.580850 0.695886
vt 0.568877 0.723237
vt 0.564926 0.717804
vt 0.539159 0.732893
vt 0.539160 0.726176
vt 0.509442 0.723237
vt 0.513394 0.717804
vn 0.0000 0.3090 0.9511
vn 0.0000 0.8090 0.5878
vn 0.0000 1.0000 0.0000
vn -0.0000 0.8090 -0.5878
vn -0.0000 0.3090 -0.9511
vn -0.0000 -0.3090 -0.9511
vn -0.0000 -0.8090 -0.5878
vn -0.0000 -1.0000 0.0000
vn -1.0000 -0.0000 -0.0000
vn 0.0000 -0.8090 0.5878
vn 0.0000 -0.3090 0.9511
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 -1.0000
usemtl bmw
s off
f 1/1/1 3/2/1 4/3/1 2/4/1
f 3/2/2 5/5/2 6/6/2 4/3/2
f 5/7/3 7/8/3 8/9/3 6/10/3
f 7/8/4 9/11/4 10/12/4 8/9/4
f 9/11/5 11/13/5 12/14/5 10/12/5
f 11/13/6 13/15/6 14/16/6 12/14/6
f 13/15/7 15/17/7 16/18/7 14/16/7
f 15/17/8 17/19/8 18/20/8 16/18/8
f 4/21/9 6/22/9 8/23/9 10/24/9 12/25/9 14/26/9 16/27/9 18/28/9 20/29/9 2/30/9
f 17/19/10 19/31/10 20/32/10 18/20/10
f 19/31/11 1/1/11 2/4/11 20/32/11
f 13/33/12 27/34/12 28/35/12 15/36/12
f 11/37/12 26/38/12 27/34/12 13/33/12
f 9/39/12 25/40/12 26/38/12 11/37/12
f 7/41/12 24/42/12 25/40/12 9/39/12
f 1/43/12 21/44/12 22/45/12 3/46/12
f 5/47/12 23/48/12 24/42/12 7/41/12
f 3/46/12 22/45/12 23/48/12 5/47/12
f 19/49/12 30/50/12 21/44/12 1/43/12
f 17/51/12 29/52/12 30/50/12 19/49/12
f 15/36/12 28/35/12 29/52/12 17/51/12
f 31/53/6 32/54/6 50/55/6 49/56/6
f 34/57/10 35/58/10 53/59/10 52/60/10
f 37/61/2 38/62/2 56/63/2 55/64/2
f 40/65/5 31/53/5 49/56/5 58/66/5
f 33/67/8 34/57/8 52/60/8 51/68/8
f 36/69/1 37/61/1 55/64/1 54/70/1
f 39/71/4 40/65/4 58/66/4 57/72/4
f 32/54/7 33/73/7 51/74/7 50/55/7
f 35/58/11 36/69/11 54/70/11 53/59/11
f 25/75/12 24/76/12 52/77/12 53/78/12
f 31/79/12 40/80/12 39/81/12 38/82/12 37/83/12 36/84/12 35/85/12 34/86/12 33/87/12 32/88/12
f 38/62/3 39/71/3 57/72/3 56/63/3
f 43/89/13 47/90/13 48/91/13 44/92/13
f 45/93/14 41/94/14 42/95/14 46/96/14
f 43/97/8 41/94/8 45/93/8 47/98/8
f 48/91/3 46/96/3 42/95/3 44/92/3
f 24/76/12 23/99/12 51/100/12 52/77/12
f 23/99/12 22/101/12 50/102/12 51/100/12
f 22/101/12 21/103/12 49/104/12 50/102/12
f 21/103/12 30/105/12 58/106/12 49/104/12
f 30/105/12 29/107/12 57/108/12 58/106/12
f 29/107/12 28/109/12 56/110/12 57/108/12
f 28/109/12 27/111/12 55/112/12 56/110/12
f 27/111/12 26/113/12 54/114/12 55/112/12
f 26/113/12 25/75/12 53/78/12 54/114/12

BIN
models/car.blend Normal file

Binary file not shown.

BIN
models/car.blend1 Normal file

Binary file not shown.

BIN
models/car_updated.blend1 Normal file

Binary file not shown.

BIN
textures/bmw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
textures/bmw_inv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
textures/bmw_wheel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB