master
Alexsandro Percy 2020-05-23 20:12:08 -03:00
parent a31c5acd01
commit 5895ba7098
24 changed files with 897 additions and 1 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 APercy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

22
README.md Normal file → Executable file
View File

@ -1 +1,21 @@
# minekart
Minetest 5.2 mod: MineKart
========================================
This is the "MineKart", a mod that provides a little race car.
It can be painted using dye of any color you want, you must punch the seat with the dye.
like explaned at checkpoints mod:
Your kart starts with no fuel. If you are not in a race or your car was reseted by the black white flag, you can put biofuel on it. You need to attach himself to the car with the right button and punch the car with the biofuel gallon. Ok. But when you are in a race, you can only refuel at a refuel zone, marked by the fuel pistol icon. This zones have a radius of 5 blocks. To refuel you need stop, turn the engine off and punch the gallon against the kart. So you turn engine running again and go to the victory... or not!
-----------------------
It uses some code from Sailing Kit (by TheTermos)
License of source code:
MIT (see file LICENSE)
License of media (textures and sounds):
---------------------------------------
engine.ogg, drift.ogg and collision.ogg by APercy. See License file
Kart model by APercy. See License file

2
depends.txt Normal file
View File

@ -0,0 +1,2 @@
default
biofuel

672
init.lua Executable file
View File

@ -0,0 +1,672 @@
--
-- constants
--
minekart={}
minekart.LONGIT_DRAG_FACTOR = 0.16*0.16
minekart.LATER_DRAG_FACTOR = 30.0
minekart.gravity = (tonumber(minetest.settings:get("movement_gravity")) or 9.8)
--two variables to control sound event
minekart.last_time_collision_snd = 0
minekart.last_time_drift_snd =0
minekart.last_fuel_display =0
--kart colors
minekart.colors ={
black='#2b2b2b',
blue='#0063b0',
brown='#8c5922',
cyan='#07B6BC',
dark_green='#567a42',
dark_grey='#6d6d6d',
green='#4ee34c',
grey='#9f9f9f',
magenta='#ff0098',
orange='#ff8b0e',
pink='#ff62c6',
red='#dc1818',
violet='#a437ff',
white='#FFFFFF',
yellow='#ffe400',
}
dofile(minetest.get_modpath("minekart") .. DIR_DELIM .. "minekart_control.lua")
dofile(minetest.get_modpath("minekart") .. DIR_DELIM .. "minekart_fuel_management.lua")
--
-- helpers and co.
--
local creative_exists = minetest.global_exists("creative")
function minekart.get_hipotenuse_value(point1, point2)
return math.sqrt((point1.x - point2.x) ^ 2 + (point1.y - point2.y) ^ 2 + (point1.z - point2.z) ^ 2)
end
function minekart.dot(v1,v2)
return (v1.x*v2.x)+(v1.y*v2.y)+(v1.z*v2.z)
end
function minekart.sign(n)
return n>=0 and 1 or -1
end
function minekart.minmax(v,m)
return math.min(math.abs(v),m)*minekart.sign(v)
end
--painting
function minekart.paint(self, colstr)
if colstr then
self._color = colstr
local l_textures = self.initial_properties.textures
for _, texture in ipairs(l_textures) do
local i,indx = texture:find('kart_painting.png')
if indx then
l_textures[_] = "kart_painting.png^[multiply:".. colstr
end
end
self.object:set_properties({textures=l_textures})
end
end
-- destroy the kart
function minekart.destroy(self, puncher)
if self.sound_handle then
minetest.sound_stop(self.sound_handle)
self.sound_handle = nil
end
if self.driver_name then
-- detach the driver first (puncher must be driver)
puncher:set_detach()
puncher:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
player_api.player_attached[self.driver_name] = nil
-- player should stand again
player_api.set_animation(puncher, "stand")
self.driver_name = nil
end
local pos = self.object:get_pos()
if self.l_wheel then self.l_wheel:remove() end
if self.r_wheel then self.r_wheel:remove() end
if self.steering_base then self.steering_base:remove() end
if self.steering then self.steering:remove() end
if self.dir_bar then self.dir_bar:remove() end
self.object:remove()
pos.y=pos.y+2
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'minekart:kart')
end
--
-- entity
--
minetest.register_entity('minekart:left_wheel',{
initial_properties = {
physical = false,
collide_with_objects=false,
pointable=false,
visual = "mesh",
mesh = "kart_left_wheel.b3d",
textures = {"kart_black.png", "kart_black.png", "kart_metal.png",},
},
on_activate = function(self,std)
self.sdata = minetest.deserialize(std) or {}
if self.sdata.remove then self.object:remove() end
end,
get_staticdata=function(self)
self.sdata.remove=true
return minetest.serialize(self.sdata)
end,
})
minetest.register_entity('minekart:right_wheel',{
initial_properties = {
physical = false,
collide_with_objects=false,
pointable=false,
visual = "mesh",
mesh = "kart_right_wheel.b3d",
textures = {"kart_black.png", "kart_black.png", "kart_metal.png",},
},
on_activate = function(self,std)
self.sdata = minetest.deserialize(std) or {}
if self.sdata.remove then self.object:remove() end
end,
get_staticdata=function(self)
self.sdata.remove=true
return minetest.serialize(self.sdata)
end,
})
minetest.register_entity('minekart:steering_wheel_axis',{
initial_properties = {
physical = false,
collide_with_objects=false,
pointable=false,
visual = "mesh",
mesh = "kart_steering_base.b3d",
textures = {"kart_black.png",},
},
on_activate = function(self,std)
self.sdata = minetest.deserialize(std) or {}
if self.sdata.remove then self.object:remove() end
end,
get_staticdata=function(self)
self.sdata.remove=true
return minetest.serialize(self.sdata)
end,
})
minetest.register_entity('minekart:steering_wheel',{
initial_properties = {
physical = false,
collide_with_objects=false,
pointable=false,
visual = "mesh",
mesh = "kart_steering.b3d",
textures = {"kart_u_black.png",},
},
on_activate = function(self,std)
self.sdata = minetest.deserialize(std) or {}
if self.sdata.remove then self.object:remove() end
end,
get_staticdata=function(self)
self.sdata.remove=true
return minetest.serialize(self.sdata)
end,
})
minetest.register_entity('minekart:dir_bar',{
initial_properties = {
physical = false,
collide_with_objects=false,
pointable=false,
visual = "mesh",
mesh = "kart_dir_bar.b3d",
textures = {"kart_black.png",},
},
on_activate = function(self,std)
self.sdata = minetest.deserialize(std) or {}
if self.sdata.remove then self.object:remove() end
end,
get_staticdata=function(self)
self.sdata.remove=true
return minetest.serialize(self.sdata)
end,
})
minetest.register_entity("minekart:kart", {
initial_properties = {
physical = true,
collide_with_objects = true,
collisionbox = {-0.6, 0.0, -0.6, 0.6, 1, 0.6},
selectionbox = {-0.8, 0.0, -0.8, 0.8, 0.1, 0.8},
stepheight = 0.5,
visual = "mesh",
mesh = "kart_body.b3d",
textures = {"kart_black.png", "kart_painting.png", "kart_painting.png", "kart_red.png", "kart_black.png", "kart_white.png", "kart_black.png", "kart_black.png", "kart_black.png", "kart_black.png", "kart_metal.png", "kart_black.png", "kart_black.png", "kart_metal.png", "kart_black.png", "kart_metal.png",},
},
--textures = {},
driver_name = nil,
sound_handle = nil,
owner = "",
static_save = true,
infotext = "A very nice kart!",
hp = 50,
_lastvelocity = vector.new(),
_color = "#FFFFFF",
_steering_angle = 0,
_engine_running = false,
_last_checkpoint = "",
_total_laps = -1,
_race_id = "",
_energy = 0.001,
get_staticdata = function(self) -- unloaded/unloads ... is now saved
return minetest.serialize({
--stored_owner = self.owner,
stored_hp = self.hp,
stored_color = self._color,
stored_steering = self._steering_angle,
stored_energy = self._energy,
--race data
stored_last_checkpoint = self._last_checkpoint,
stored_total_laps = self._total_laps,
stored_race_id = self._race_id,
})
end,
on_activate = function(self, staticdata, dtime_s)
if staticdata ~= "" and staticdata ~= nil then
local data = minetest.deserialize(staticdata) or {}
--self.owner = data.stored_owner
self.hp = data.stored_hp
self._color = data.stored_color
self._steering_angle = data.stored_steering
self._energy = data.stored_energy
--minetest.debug("loaded: ", self.energy)
--race data
self._last_checkpoint = data.stored_last_checkpoint
self._total_laps = data.stored_total_laps
self._race_id = data.stored_race_id
end
self.object:set_animation({x = 1, y = 8}, 0, 0, true)
minekart.paint(self, self._color)
local pos = self.object:get_pos()
local l_wheel=minetest.add_entity(pos,'minekart:left_wheel')
l_wheel:set_attach(self.object,'',{x=-6,y=2.1,z=10.7},{x=0,y=0,z=0})
-- set the animation once and later only change the speed
l_wheel:set_animation({x = 1, y = 8}, 0, 0, true)
self.l_wheel = l_wheel
local r_wheel=minetest.add_entity(pos,'minekart:right_wheel')
r_wheel:set_attach(self.object,'',{x=6,y=2.1,z=10.7},{x=0,y=0,z=0})
-- set the animation once and later only change the speed
r_wheel:set_animation({x = 1, y = 8}, 0, 0, true)
self.r_wheel = r_wheel
local steering_axis=minetest.add_entity(pos,'minekart:steering_wheel_axis')
steering_axis:set_attach(self.object,'',{x=0,y=7.49,z=7},{x=45,y=0,z=0})
self.steering_axis = steering_axis
local steering=minetest.add_entity(self.steering_axis:get_pos(),'minekart:steering_wheel')
steering:set_attach(self.steering_axis,'',{x=0,y=0,z=0},{x=0,y=0,z=0})
self.steering = steering
local dir_bar=minetest.add_entity(self.object:get_pos(),'minekart:dir_bar')
dir_bar:set_attach(self.object,'',{x=0,y=0,z=-4},{x=0,y=0,z=0})
self.dir_bar = dir_bar
self.object:set_armor_groups({immortal=1})
self.object:set_acceleration(vector.multiply(minekart.vector_up, -minekart.gravity))
end,
on_step = function(self, dtime)
--[[sound play control]]--
minekart.last_time_collision_snd = minekart.last_time_collision_snd + dtime
if minekart.last_time_collision_snd > 1 then minekart.last_time_collision_snd = 1 end
minekart.last_time_drift_snd = minekart.last_time_drift_snd + dtime
if minekart.last_time_drift_snd > 1 then minekart.last_time_drift_snd = 1 end
--[[end sound control]]--
local accel_y = self.object:get_acceleration().y
local rotation = self.object:get_rotation()
local yaw = rotation.y
local newyaw=yaw
local pitch = rotation.x
local newpitch = pitch
local roll = rotation.z
local newroll=roll
local hull_direction = minetest.yaw_to_dir(yaw)
local nhdir = {x=hull_direction.z,y=0,z=-hull_direction.x} -- lateral unit vector
local velocity = self.object:get_velocity()
local longit_speed = minekart.dot(velocity,hull_direction)
local fuel_weight_factor = (5 - self._energy)/5000
local longit_drag = vector.multiply(hull_direction,(longit_speed*longit_speed) * (minekart.LONGIT_DRAG_FACTOR - fuel_weight_factor) * -1 * minekart.sign(longit_speed))
local later_speed = minekart.dot(velocity,nhdir)
local later_drag = vector.multiply(nhdir,later_speed*later_speed*minekart.LATER_DRAG_FACTOR*-1*minekart.sign(later_speed))
local accel = vector.add(longit_drag,later_drag)
local vel = self.object:get_velocity()
local player = nil
local is_attached = false
if self.driver_name then
player = minetest.get_player_by_name(self.driver_name)
if player then
local player_attach = player:get_attach()
if player_attach then
if player_attach == self.object then is_attached = true end
end
end
end
if is_attached then --and self.driver_name == self.owner then
local curr_pos = self.object:get_pos()
local impact = minekart.get_hipotenuse_value(vel, self._lastvelocity)
if impact > 1 then
--self.damage = self.damage + impact --sum the impact value directly to damage meter
if minekart.last_time_collision_snd > 0.3 then
minekart.last_time_collision_snd = 0
minetest.sound_play("collision", {
to_player = self.driver_name,
--pos = curr_pos,
--max_hear_distance = 5,
gain = 1.0,
fade = 0.0,
pitch = 1.0,
})
end
--[[if self.damage > 100 then --if acumulated damage is greater than 100, adieu
minekart.destroy(self)
end]]--
end
local min_later_speed = 0.9
if (later_speed > min_later_speed or later_speed < -min_later_speed) and minekart.last_time_drift_snd > 0.6 then
minekart.last_time_drift_snd = 0
minetest.sound_play("drifting", {
to_player = self.driver_name,
pos = curr_pos,
max_hear_distance = 5,
gain = 1.0,
fade = 0.0,
pitch = 1.0,
ephemeral = true,
})
end
--control
accel = minekart.kart_control(self, dtime, hull_direction, longit_speed, longit_drag, later_drag, accel) or vel
else
if self.sound_handle ~= nil then
minetest.sound_stop(self.sound_handle)
self.sound_handle = nil
end
end
local angle_factor = self._steering_angle / 10
self.object:set_animation_frame_speed(longit_speed * 10)
self.l_wheel:set_animation_frame_speed(longit_speed * (10 - angle_factor))
self.r_wheel:set_animation_frame_speed(longit_speed * (10 + angle_factor))
self.steering:set_attach(self.steering_axis,'',{x=0,y=0,z=0},{x=0,y=0,z=self._steering_angle*2})
self.l_wheel:set_attach(self.object,'',{x=-6,y=2.1,z=10.7},{x=0,y=-self._steering_angle-angle_factor,z=0})
self.dir_bar:set_attach(self.object,'',{x=(-1*(self._steering_angle / 25)),y=0,z=-4},{x=0,y=0,z=0})
self.r_wheel:set_attach(self.object,'',{x= 6,y=2.1,z=10.7},{x=0,y=-self._steering_angle+angle_factor,z=0})
if math.abs(self._steering_angle)>5 then
local turn_rate = math.rad(60)
newyaw = yaw + dtime*(1 - 1 / (math.abs(longit_speed) + 1)) * self._steering_angle / 30 * turn_rate * minekart.sign(longit_speed)
end
--[[if player and is_attached then
player:set_look_horizontal(newyaw)
end]]--
newpitch = velocity.y * math.rad(6)
--add gravity accell
accel = vector.add(accel, vector.multiply(minekart.vector_up, -minekart.gravity)) -- * dtime))
--[[
accell correction
under some circunstances the acceleration exceeds the max value accepted by set_acceleration and
the game crashes with an overflow, so limiting the max acceleration in each axis prevents the crash
]]--
local max_factor = 25
local acc_adjusted = 10
if accel.x > max_factor then accel.x = acc_adjusted end
if accel.x < -max_factor then accel.x = -acc_adjusted end
if accel.z > max_factor then accel.z = acc_adjusted end
if accel.z < -max_factor then accel.z = -acc_adjusted end
-- end correction
self.object:set_acceleration(accel)
if newyaw~=yaw or newpitch~=pitch then self.object:set_rotation({x=newpitch,y=newyaw,z=0}) end
--saves last velocity for collision detection (abrupt stop)
self._lastvelocity = self.object:get_velocity()
-- calculate energy consumption --
----------------------------------
if self._energy > 0 and self._engine_running then
local zero_reference = vector.new()
local acceleration = minekart.get_hipotenuse_value(accel, zero_reference)
local consumed_power = acceleration/200000
self._energy = self._energy - consumed_power;
--report fuel
if self._energy < 0.75 and minekart.last_fuel_display == 0 then
minekart.last_fuel_display = 50
minetest.chat_send_player(self.driver_name, "fuel now bellow 75%")
end
if self._energy < 0.5 and minekart.last_fuel_display == 50 then
minekart.last_fuel_display = 25
minetest.chat_send_player(self.driver_name, "fuel now bellow 50%")
end
if self._energy < 0.25 and minekart.last_fuel_display == 25 then
minekart.last_fuel_display = 10
minetest.chat_send_player(self.driver_name, "fuel now bellow 25%")
end
if self._energy < 0.1 and minekart.last_fuel_display == 10 then
minekart.last_fuel_display = 0
minetest.chat_send_player(self.driver_name, "Danger! Fuel now bellow 10%")
end
end
if self._energy <= 0 and self._engine_running then
self._engine_running = false
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
minetest.chat_send_player(self.driver_name, "Out of fuel")
end
----------------------------
-- end energy consumption --
end,
on_punch = function(self, puncher, ttime, toolcaps, dir, damage)
if not puncher or not puncher:is_player() then
return
end
local name = puncher:get_player_name()
--[[if self.owner and self.owner ~= name and self.owner ~= "" then return end
if self.owner == nil then
self.owner = name
end]]--
if self.driver_name and self.driver_name ~= name then
-- do not allow other players to remove the object while there is a driver
return
end
local is_attached = false
if puncher:get_attach() == self.object then is_attached = true end
local itmstck=puncher:get_wielded_item()
local item_name = ""
if itmstck then item_name = itmstck:get_name() end
--refuel procedure
--[[
refuel works in 2 situations:
1- if my car doesn't have a race_id, ok, punch it anywhere with bio fuel while player attached and ok
2- if it have a race_id, you must stop near a "checkpoints:refuel" node to punch with the biofuel
]]--
local velocity = self.object:get_velocity()
local speed = minekart.get_hipotenuse_value(vector.new(), velocity)
if is_attached == true and item_name == "biofuel:biofuel" and self._engine_running == false and speed <= 0.1 then
local pos = self.object:get_pos()
if minetest.find_node_near(pos, 5, {"checkpoints:refuel"}) ~= nil then
minekart_load_fuel(self, puncher:get_player_name())
else
if self._race_id == "" then
minekart_load_fuel(self, puncher:get_player_name())
end
end
end
-- end refuel
if is_attached == false then
-- deal with painting or destroying
if itmstck then
--race status restart
if item_name == "checkpoints:status_restarter" and self._engine_running == false then
--restart race current status
self._last_checkpoint = ""
self._total_laps = -1
self._race_id = ""
return
end
--painting
local _,indx = item_name:find('dye:')
if indx then
--lets paint!!!!
local color = item_name:sub(indx+1)
local colstr = minekart.colors[color]
--minetest.chat_send_all(color ..' '.. dump(colstr))
if colstr then
minekart.paint(self, colstr)
itmstck:set_count(itmstck:get_count()-1)
puncher:set_wielded_item(itmstck)
end
-- end painting
else -- deal damage
if not self.driver and toolcaps and toolcaps.damage_groups and toolcaps.damage_groups.fleshy then
self.hp = self.hp - 10
minetest.sound_play("collision", {
object = self.object,
max_hear_distance = 5,
gain = 1.0,
fade = 0.0,
pitch = 1.0,
})
end
end
end
if self.hp <= 0 then
minekart.destroy(self)
end
end
end,
on_rightclick = function(self, clicker)
if not clicker or not clicker:is_player() then
return
end
local name = clicker:get_player_name()
--[[if self.owner and self.owner ~= name and self.owner ~= "" then return end
if self.owner == "" then
self.owner = name
end]]--
if name == self.driver_name then
self._engine_running = false
-- driver clicked the object => driver gets off the vehicle
self.driver_name = nil
-- sound and animation
if self.sound_handle then
minetest.sound_stop(self.sound_handle)
self.sound_handle = nil
end
self.object:set_animation_frame_speed(0)
-- detach the player
clicker:set_detach()
player_api.player_attached[name] = nil
clicker:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
player_api.set_animation(clicker, "stand")
self.driver = nil
self.object:set_acceleration(vector.multiply(minekart.vector_up, -minekart.gravity))
elseif not self.driver_name then
-- no driver => clicker is new driver
self.driver_name = name
-- temporary------
self.hp = 50 -- why? cause I can desist from destroy
------------------
-- attach the driver
clicker:set_attach(self.object, "", {x = 0, y = 3, z = 2}, {x = 0, y = 0, z = 0})
clicker:set_eye_offset({x = 0, y = 0, z = 2.5}, {x = 0, y = 0, z = -14})
player_api.player_attached[name] = true
-- make the driver sit
minetest.after(0.2, function()
local player = minetest.get_player_by_name(name)
if player then
player_api.set_animation(player, "sit")
end
end)
self.object:set_acceleration(vector.multiply(minekart.vector_up, -minekart.gravity))
end
end,
})
--
-- items
--
-- Kart
minetest.register_craftitem("minekart:kart", {
description = "Kart",
inventory_image = "motorboat_inv.png",
liquids_pointable = false,
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
local pointed_pos = pointed_thing.above
local node_below = minetest.get_node(pointed_pos).name
local nodedef = minetest.registered_nodes[node_below]
--pointed_pos.y=pointed_pos.y+0.2
local kart = minetest.add_entity(pointed_pos, "minekart:kart")
if kart and placer then
--[[local ent = kart:get_luaentity()
local owner = placer:get_player_name()
ent.owner = owner]]--
kart:set_yaw(placer:get_look_horizontal())
itemstack:take_item()
end
return itemstack
end,
})
--
-- crafting
--
if minetest.get_modpath("default") then
minetest.register_craft({
output = "minekart:kart",
recipe = {
{"default:obsidian_block", "default:steel_ingot", "default:obsidian_block"},
{"default:steel_ingot", "default:mese_block", "default:steel_ingot"},
{"default:obsidian_block", "default:steel_ingot", "default:obsidian_block"},
}
})
end

152
minekart_control.lua Normal file
View File

@ -0,0 +1,152 @@
--global constants
minekart.karttest_last_time_command = 0
minekart.vector_up = vector.new(0, 1, 0)
minekart.max_acc_factor = 8.5
minekart.max_speed = 25
function minekart.check_road_is_ok(obj)
local pos_below = obj:get_pos()
pos_below.y = pos_below.y - 0.1
local node_below = minetest.get_node(pos_below).name
--minetest.chat_send_all(node_below)
local nodedef = minetest.registered_nodes[node_below]
if nodedef.liquidtype == "none" then
local slow_nodes = {['default:dirt'] = 0.3,
['default:dirt_with_rainforest_litter'] = 0.3,
['default:dirt_with_coniferous_litter'] = 0.3,
['default:permafrost'] = 0.3,
['default:permafrost_with_moss'] = 0.3,
['default:permafrost_with_stones'] = 0.3,
['default:dirt_with_grass'] = 0.2,
['farming:soil'] = 0.2,
['farming:soil_wet'] = 0.2,
['farming:desert_sand_soil'] = 0.2,
['farming:desert_sand_soil_wet'] = 0.2,
['farming:dry_soil'] = 0.2,
['farming:dry_soil_wet'] = 0.2,
['default:sand'] = 0.1,
['default:desert_sand'] = 0.1,
['default:silver_sand'] = 0.1,
['default:snow'] = 0.07,
['default:dirt_with_snow'] = 0.07,
['default:ice '] = 0.01,
['default:cave_ice'] = 0.01,
}
local acc = slow_nodes[node_below]
if acc == nil then acc = minekart.max_acc_factor end
return acc
else
return 0
end
return minekart.max_acc_factor
end
function minekart.kart_control(self, dtime, hull_direction, longit_speed, longit_drag, later_drag, accel)
minekart.karttest_last_time_command = minekart.karttest_last_time_command + dtime
if minekart.karttest_last_time_command > 1 then minekart.karttest_last_time_command = 1 end
local player = minetest.get_player_by_name(self.driver_name)
local retval_accel = accel;
local zero = vector.new()
-- player control
if player then
local ctrl = player:get_player_control()
local acc = 0
if self._engine_running then
--running
if longit_speed < minekart.max_speed and ctrl.up then
--get acceleration factor
acc = minekart.check_road_is_ok(self.object)
--minetest.chat_send_all('engineacc: '.. engineacc)
if acc > 1 and acc < minekart.max_acc_factor and longit_speed > 0 then
--improper road will reduce speed
acc = -1
end
end
else
--slow maneuver
if longit_speed < 1.0 and ctrl.up then
--get acceleration factor
acc = minekart.check_road_is_ok(self.object)
--minetest.chat_send_all('engineacc: '.. engineacc)
if acc > 1 and acc < minekart.max_acc_factor and longit_speed > 0 then
--improper road will reduce speed
acc = -1
end
end
end
--reversing
if ctrl.sneak and longit_speed <= 1.0 and longit_speed > -1.0 then
acc = -1
end
--break
if longit_speed > 0 and ctrl.down then
acc = -5 / (longit_speed / 2) -- lets set a brake efficience based on speed
end
--total stop
if longit_speed <= 0.1 and ctrl.down then
-- do not like it here, but worked better
acc = 0
self.object:set_velocity(zero)
--self.object:set_acceleration(zero)
end
if acc then retval_accel=vector.add(accel,vector.multiply(hull_direction,acc)) end
if ctrl.jump then
--sets the engine running - but sets a delay also, cause keypress
if minekart.karttest_last_time_command > 0.3 then
minekart.karttest_last_time_command = 0
if self._engine_running then
self._engine_running = false
-- sound and animation
if self.sound_handle then
minetest.sound_stop(self.sound_handle)
self.sound_handle = nil
end
--self.engine:set_animation_frame_speed(0)
elseif self._engine_running == false and self._energy > 0 then
self._engine_running = true
-- sound and animation
self.sound_handle = minetest.sound_play({name = "engine"},
{object = self.object, gain = 2.0, max_hear_distance = 32, loop = true,})
--self.engine:set_animation_frame_speed(30)
end
end
end
-- steering
local steering_limit = 30
if ctrl.right then
self._steering_angle = math.max(self._steering_angle-80*dtime,-steering_limit)
elseif ctrl.left then
self._steering_angle = math.min(self._steering_angle+80*dtime,steering_limit)
else
--center steering
if longit_speed > 0 then
local factor = 1
if self._steering_angle > 0 then factor = -1 end
local correction = (steering_limit*(longit_speed/100)) * factor
self._steering_angle = self._steering_angle + correction
end
end
local angle_factor = self._steering_angle / 60
if angle_factor < 0 then angle_factor = angle_factor * -1 end
local deacc_on_curve = longit_speed * angle_factor
deacc_on_curve = deacc_on_curve * -1
if deacc_on_curve then retval_accel=vector.add(retval_accel,vector.multiply(hull_direction,deacc_on_curve)) end
end
return retval_accel
end

View File

@ -0,0 +1,24 @@
--
-- fuel
--
function minekart_load_fuel(self, player_name)
if self._energy < 0.90 then
local player = minetest.get_player_by_name(player_name)
local inv = player:get_inventory()
local inventory_fuel = "biofuel:biofuel"
if inv:contains_item("main", inventory_fuel) then
local stack = ItemStack(inventory_fuel .. " 1")
local taken = inv:remove_item("main", stack)
self._energy = self._energy + 1
if self._energy > 1 then self._energy = 1 end
minekart.last_fuel_display = 0
minetest.chat_send_player(player_name, "Full tank!")
end
else
minetest.chat_send_player(player_name, "No refuel for you! You have more than 90% of fuel in the tank.")
end
end

5
mod.conf Normal file
View File

@ -0,0 +1,5 @@
name = minekart
depends = default,biofuel
author = APercy
description = Adds a craftable kart
title = MineKart

BIN
models/kart_body.b3d Executable file

Binary file not shown.

BIN
models/kart_dir_bar.b3d Executable file

Binary file not shown.

BIN
models/kart_left_wheel.b3d Executable file

Binary file not shown.

BIN
models/kart_right_wheel.b3d Executable file

Binary file not shown.

BIN
models/kart_steering.b3d Executable file

Binary file not shown.

Binary file not shown.

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
sounds/collision.ogg Normal file

Binary file not shown.

BIN
sounds/drifting.ogg Normal file

Binary file not shown.

BIN
sounds/engine.ogg Normal file

Binary file not shown.

BIN
textures/kart_black.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

BIN
textures/kart_metal.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
textures/kart_painting.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
textures/kart_red.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
textures/kart_u_black.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
textures/kart_white.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
textures/motorboat_inv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB