holy jesus that's a commit
3
.vscode/settings.json
vendored
@ -2,6 +2,7 @@
|
||||
"Lua.diagnostics.globals": [
|
||||
"minetest",
|
||||
"invector",
|
||||
"vector"
|
||||
"vector",
|
||||
"Raycast"
|
||||
]
|
||||
}
|
9
mods/invector/ai.lua
Normal file
@ -0,0 +1,9 @@
|
||||
-- Invector, License MIT, Author Jordach
|
||||
|
||||
-- AI handling routines.
|
||||
|
||||
invector.ai = {}
|
||||
|
||||
function invector.ai.chase_player(ai_kart, target_kart)
|
||||
|
||||
end
|
BIN
mods/invector/blends/boost_pad.blend
Normal file
BIN
mods/invector/blends/boost_pad.blend1
Normal file
BIN
mods/invector/blends/invector_pad.blend
Normal file
BIN
mods/invector/blends/invector_pad.blend1
Normal file
BIN
mods/invector/blends/invector_pad_mega.blend
Normal file
BIN
mods/invector/blends/item_pad.blend
Normal file
BIN
mods/invector/blends/item_pad.blend1
Normal file
BIN
mods/invector/blends/item_pad1.blend
Normal file
BIN
mods/invector/blends/item_pad1.blend1
Normal file
@ -1,25 +1,194 @@
|
||||
-- Invector, License MIT, Author Jordach
|
||||
|
||||
local mega_pad = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.5, -0.5, -1.5, 1.5, 0.5, 1.5}
|
||||
}
|
||||
}
|
||||
|
||||
minetest.register_node("invector:smoke_node", {
|
||||
description = "don't use me",
|
||||
tiles = {"invector_smoke.png"},
|
||||
drawtype = "glasslike"
|
||||
drawtype = "glasslike",
|
||||
groups = {not_in_builder_inv=1},
|
||||
})
|
||||
|
||||
minetest.register_node("invector:boost_1_node", {
|
||||
description = "don't use me",
|
||||
tiles = {"invector_boost_small.png"},
|
||||
drawtype = "glasslike"
|
||||
drawtype = "glasslike",
|
||||
groups = {not_in_builder_inv=1},
|
||||
})
|
||||
|
||||
minetest.register_node("invector:boost_2_node", {
|
||||
description = "don't use me",
|
||||
tiles = {"invector_boost_medium.png"},
|
||||
drawtype = "glasslike"
|
||||
drawtype = "glasslike",
|
||||
groups = {not_in_builder_inv=1},
|
||||
})
|
||||
|
||||
minetest.register_node("invector:boost_3_node", {
|
||||
description = "don't use me",
|
||||
tiles = {"invector_boost_large.png"},
|
||||
drawtype = "glasslike"
|
||||
tiles = {"invector_boost_big.png"},
|
||||
drawtype = "glasslike",
|
||||
groups = {not_in_builder_inv=1},
|
||||
})
|
||||
|
||||
minetest.register_node("invector:boost_pad", {
|
||||
description = "Boost Pad",
|
||||
tiles = {
|
||||
"invector_pad_top.png",
|
||||
"invector_pad_bottom.png",
|
||||
"invector_pad_side.png",
|
||||
{
|
||||
name = "boost_pad_holo_anim.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1.5,
|
||||
type = "vertical_frames"
|
||||
},
|
||||
}
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
light_source = 14,
|
||||
use_texture_alpha = "blend",
|
||||
drawtype = "mesh",
|
||||
mesh = "invector_pad.b3d",
|
||||
groups = {invector = 1, booster = 1, track = 1},
|
||||
on_place = solarsail.util.functions.sensible_facedir_simple
|
||||
})
|
||||
|
||||
minetest.register_node("invector:boost_pad_mega", {
|
||||
description = "Boost Pad Mega [3x3]",
|
||||
tiles = {
|
||||
"invector_pad_top.png",
|
||||
"invector_pad_bottom.png",
|
||||
"invector_pad_side.png",
|
||||
{
|
||||
name = "boost_pad_holo_anim.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1.5,
|
||||
type = "vertical_frames"
|
||||
},
|
||||
}
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
light_source = 14,
|
||||
use_texture_alpha = "blend",
|
||||
drawtype = "mesh",
|
||||
mesh = "invector_pad_mega.b3d",
|
||||
selection_box = mega_pad,
|
||||
collision_box = mega_pad,
|
||||
groups = {invector = 1, booster = 2, track = 1},
|
||||
on_place = solarsail.util.functions.sensible_facedir_simple
|
||||
})
|
||||
|
||||
local function reset_item_pad_small(pos, elapsed)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:stop()
|
||||
minetest.swap_node(pos, {name="invector:item_pad_online"})
|
||||
end
|
||||
|
||||
minetest.register_node("invector:item_pad_offline", {
|
||||
description = "Item Pad Offline",
|
||||
tiles = {
|
||||
"invector_pad_top.png",
|
||||
"invector_pad_bottom.png",
|
||||
"invector_pad_side.png",
|
||||
"transparent.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
use_texture_alpha = "clip",
|
||||
drawtype = "mesh",
|
||||
mesh = "invector_pad.b3d",
|
||||
groups = {invector = 1, not_in_builder_inv=1, track = 1},
|
||||
on_place = solarsail.util.functions.sensible_facedir_simple,
|
||||
on_timer = reset_item_pad_small
|
||||
})
|
||||
|
||||
minetest.register_node("invector:item_pad_online", {
|
||||
description = "Item Pad Online",
|
||||
tiles = {
|
||||
"invector_pad_top.png",
|
||||
"invector_pad_bottom.png",
|
||||
"invector_pad_side.png",
|
||||
{
|
||||
name = "item_pad_holo_anim.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
type = "vertical_frames"
|
||||
},
|
||||
}
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
light_source = 14,
|
||||
use_texture_alpha = "blend",
|
||||
drawtype = "mesh",
|
||||
mesh = "invector_pad.b3d",
|
||||
groups = {invector = 1, item = 1},
|
||||
_swap_to = "invector:item_pad_offline",
|
||||
on_place = solarsail.util.functions.sensible_facedir_simple
|
||||
})
|
||||
|
||||
local function reset_item_pad_mega(pos, elapsed)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:stop()
|
||||
minetest.swap_node(pos, {name="invector:item_pad_mega_online"})
|
||||
end
|
||||
|
||||
minetest.register_node("invector:item_pad_mega_offline", {
|
||||
description = "Item Pad Mega Offline [3x3]",
|
||||
tiles = {
|
||||
"invector_pad_top.png",
|
||||
"invector_pad_bottom.png",
|
||||
"invector_pad_side.png",
|
||||
"transparent.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
use_texture_alpha = "clip",
|
||||
drawtype = "mesh",
|
||||
mesh = "invector_pad_mega.b3d",
|
||||
selection_box = mega_pad,
|
||||
collision_box = mega_pad,
|
||||
groups = {invector = 1, not_in_builder_inv=1},
|
||||
on_place = solarsail.util.functions.sensible_facedir_simple,
|
||||
on_timer = reset_item_pad_mega
|
||||
})
|
||||
|
||||
minetest.register_node("invector:item_pad_mega_online", {
|
||||
description = "Item Pad Mega [3x3]",
|
||||
tiles = {
|
||||
"invector_pad_top.png",
|
||||
"invector_pad_bottom.png",
|
||||
"invector_pad_side.png",
|
||||
{
|
||||
name = "item_pad_holo_anim.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
type = "vertical_frames"
|
||||
},
|
||||
}
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
light_source = 14,
|
||||
use_texture_alpha = "blend",
|
||||
drawtype = "mesh",
|
||||
mesh = "invector_pad_mega.b3d",
|
||||
selection_box = mega_pad,
|
||||
collision_box = mega_pad,
|
||||
groups = {invector = 1, item = 1},
|
||||
_swap_to = "invector:item_pad_mega_offline",
|
||||
on_place = solarsail.util.functions.sensible_facedir_simple
|
||||
})
|
@ -1,6 +1,9 @@
|
||||
-- Invector, License MIT, Author Jordach
|
||||
|
||||
minetest.override_item("", {
|
||||
-- Disable the hand if in survival mode or play game mode, while
|
||||
-- creative mode acts as the built in track editor
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
minetest.override_item("", {
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
range = 1,
|
||||
tool_capabilities = {
|
||||
@ -9,10 +12,36 @@ minetest.override_item("", {
|
||||
groupcaps = {},
|
||||
damage_groups = {},
|
||||
}
|
||||
})
|
||||
})
|
||||
else
|
||||
minetest.override_item("", {
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
range = 5,
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 1,
|
||||
max_drop_level = 0,
|
||||
groupcaps = {
|
||||
debug = {times={[1]=1,[2]=0.5,[3]=0.25}, uses=0},
|
||||
invector = {times={[1]=1,[2]=0.5,[3]=0.25}, uses=0},
|
||||
},
|
||||
damage_groups = {},
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
invector = {}
|
||||
invector.functions = {}
|
||||
-- Racers are numerically indexed as .racers[1-12]
|
||||
-- with fields being generally as'
|
||||
-- .racers[1] = {
|
||||
-- player = player_ref,
|
||||
-- pname = player:get_player_name(),
|
||||
-- kart = kart_ref, should be set at race start.
|
||||
-- is_ai = false, or true, depending on if they
|
||||
-- have an AI mind and can be replaced by a player
|
||||
-- ai_difficulty = 0-10, requires is_ai set.
|
||||
--}
|
||||
invector.racers = {}
|
||||
|
||||
invector.path = minetest.get_modpath("invector")
|
||||
|
||||
@ -20,5 +49,6 @@ local function exec(file)
|
||||
dofile(invector.path.."/"..file..".lua")
|
||||
end
|
||||
|
||||
exec("blocks")
|
||||
exec("kart")
|
||||
exec("karts/sam2")
|
@ -8,7 +8,15 @@ end
|
||||
|
||||
-- This is fixed in code due to this not being a multiplayer release.
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
solarsail.player.set_model(player, "invector:sam2", {x=0, y=159}, 60,
|
||||
invector.karts.sam2._geo, invector.karts.sam2._geo3r, "",
|
||||
invector.karts.sam2._prel, invector.karts.sam2._prot)
|
||||
else
|
||||
end
|
||||
end)
|
||||
|
||||
-- Items and how to shuffle them based on positions;
|
||||
|
||||
invector.items = {}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
-- Fake third person but works like third person
|
||||
local default_eye_offset = vector.new(0,0,0)
|
||||
local ground_eye_offset = vector.new(0,1.8,-30)
|
||||
local ground_eye_offset = vector.new(0,1.7,-30)
|
||||
local ground_eye_offset_3r = vector.new(0,-10,0)
|
||||
local player_relative = vector.new(0,0,0)
|
||||
local player_rot = vector.new(0,0,0)
|
||||
@ -17,29 +17,60 @@ local kart_root_rot = vector.new(0,0,0)
|
||||
-- Particle effect things
|
||||
local front_left_tyre_pos = vector.new(0,0,0)
|
||||
local front_right_tyre_pos = vector.new(0,0,0)
|
||||
local rear_left_tyre_pos = vector.new(0,0,0)
|
||||
local rear_right_tyre_pos = vector.new(0,0,0)
|
||||
local rear_left_exhaust_pos = vector.new(0,0,0)
|
||||
local rear_right_exhaust_pos = vector.new(0,0,0)
|
||||
local rear_left_tyre_pos_min = vector.new(-0.55,0.1,-0.7)
|
||||
local rear_left_tyre_pos_max = vector.new(-0.4,0.2,-0.7)
|
||||
local rear_right_tyre_pos_min = vector.new(0.4,0.1,-0.7)
|
||||
local rear_right_tyre_pos_max = vector.new(0.55,0.2,-0.7)
|
||||
local rear_left_exhaust_pos_min = vector.new(-0.35,0.65,-1.05)
|
||||
local rear_left_exhaust_pos_max = vector.new(-0.4, 0.65,-1.05)
|
||||
local rear_right_exhaust_pos_min = vector.new(0.35, 0.65,-1.05)
|
||||
local rear_right_exhaust_pos_max = vector.new(0.4, 0.65,-1.05)
|
||||
|
||||
-- Handling specs
|
||||
local turning_radius = 0.0472665
|
||||
local drifting_radius = turning_radius * 1.75
|
||||
local drifting_radius_lesser = drifting_radius * 0.5
|
||||
local drifting_radius_greater = drifting_radius * 1.5
|
||||
local reverse_radius = 0.0174533
|
||||
local reverse_radius = 0.0204533
|
||||
|
||||
-- Speed specs
|
||||
local max_speed_boost = 8
|
||||
local max_speed_norm = 6
|
||||
local max_speed_boost = 13
|
||||
local max_speed_norm = 7
|
||||
local forwards_accel = 3
|
||||
local reverse_accel = -0.25
|
||||
local reverse_accel = -0.55
|
||||
local braking_factor = 0.75
|
||||
|
||||
-- Friction settings
|
||||
local friction_track = 0.92
|
||||
local friction_off_track = 0.50
|
||||
local friction_air = 0
|
||||
|
||||
-- Drift time needed to boost
|
||||
local small_drift_time = 1
|
||||
local med_drift_time = 2
|
||||
local big_drift_time = 3
|
||||
|
||||
-- Boost specs
|
||||
local small_boost_time = 1.5
|
||||
local med_boost_time = 3
|
||||
local big_boost_time = 5
|
||||
local small_boost_time = 0.25
|
||||
local med_boost_time = 0.5
|
||||
local big_boost_time = 1.25
|
||||
|
||||
local drift_particle_def = {
|
||||
amount = 50,
|
||||
vertical = false,
|
||||
collisiondetection = false,
|
||||
minexptime = 0.25,
|
||||
maxexptime = 0.5,
|
||||
glow = 14
|
||||
}
|
||||
|
||||
local exhause_particle_def = {
|
||||
amount = 50,
|
||||
vertical = false,
|
||||
collisiondetection = false,
|
||||
minexptime = 0.15,
|
||||
maxexptime = 0.35
|
||||
}
|
||||
|
||||
local kart = {
|
||||
visual = "mesh",
|
||||
@ -62,18 +93,31 @@ local kart = {
|
||||
_timer = 0,
|
||||
_boost_timer = 0,
|
||||
_drift_timer = 0,
|
||||
_stun_timer = 0,
|
||||
_immune_timer = 0,
|
||||
_xvel = 0,
|
||||
_zvel = 0,
|
||||
_dvel = 0,
|
||||
_yvel = 0,
|
||||
_last_cam_offset = 0,
|
||||
_is_drifting = 0, -- 1 = left, -1 = right
|
||||
_drift_level = 0, -- 0 = not drifting, 1 = small, 2 = medium, 3 = big / infinite
|
||||
_boost_type = 0, -- 0 = regular smoke, 1 = small boost, 2 = medium boost, 3 = big boost/boost pad
|
||||
_is_kart = true,
|
||||
_is_ai_capable = false,
|
||||
_held_item = nil,
|
||||
_held_item_uses = nil,
|
||||
_shields = true, -- Can take an extra hit without being stunned
|
||||
_position = -1, -- Set at race start and during a race
|
||||
_course_node = -1, -- Similar purpose to _position
|
||||
_track_sector = -1, -- Lap / track sector for non circuits
|
||||
_racer_id = -1, -- Set on game startup since it's likely singleplayer.
|
||||
|
||||
-- Particle ID holders
|
||||
_rear_left_tyre_spawner = 0,
|
||||
_rear_right_tyre_spawner = 0,
|
||||
_exhaust_left_spawner = 0,
|
||||
_exhaust_right_spawner = 0,
|
||||
_rear_left_tyre_spawner = nil,
|
||||
_rear_right_tyre_spawner = nil,
|
||||
_exhaust_left_spawner = nil,
|
||||
_exhaust_right_spawner = nil,
|
||||
|
||||
_deo = default_eye_offset,
|
||||
_geo = ground_eye_offset,
|
||||
@ -83,58 +127,110 @@ local kart = {
|
||||
}
|
||||
|
||||
function kart:on_step(dtime)
|
||||
if self.attached_player ~= nil then
|
||||
self._timer = self._timer + dtime
|
||||
if self._timer > tick_speed then
|
||||
self._timer = 0
|
||||
-- Avoid the kart logic over or underscaling things due to framerate variability.
|
||||
local tick_scaling = solarsail.util.functions.remap(dtime, tick_speed/4, tick_speed*4, 0.25, 4)
|
||||
-- Add kart stun
|
||||
if self._stun_timer > 0 then
|
||||
self._stun_timer = self._stun_timer - dtime
|
||||
end
|
||||
if self._immune_timer > 0 then
|
||||
self._immune_timer = self._immune_timer - dtime
|
||||
end
|
||||
|
||||
if self.attached_player ~= nil and self._stun_timer <= 0 then
|
||||
local control = solarsail.controls.player[self.attached_player:get_player_name()]
|
||||
if control == nil then return end
|
||||
|
||||
--[[ if control.aux1 then
|
||||
-- Allow exiting the kart while in creative mode to test changes;
|
||||
if control.aux1 and minetest.settings:get_bool("creative_mode") then
|
||||
self.attached_player:set_detach()
|
||||
self.attached_player:hud_set_flags({
|
||||
crosshair = true,
|
||||
hotbar = true,
|
||||
healthbar = true,
|
||||
wielditem = true,
|
||||
breathbar = true
|
||||
})
|
||||
self.attached_player:set_eye_offset()
|
||||
self.attached_player = nil
|
||||
return
|
||||
end ]]
|
||||
|
||||
if self._boost_timer > 0 then
|
||||
self._boost_timer = self._boost_timer - dtime
|
||||
end
|
||||
--self.object:set_animation({x=0, y=159}, 60, 0)
|
||||
|
||||
local ratio_tick = solarsail.util.functions.remap(tick_scaling, 0.25, 4, 0, 1)
|
||||
local velocity = self.object:get_velocity()
|
||||
local accel = self.object:get_acceleration()
|
||||
local rotation = self.object:get_yaw()
|
||||
local cam_rot_offset = 0
|
||||
local yaw_offset = 0
|
||||
local last_rot_offsets = self.object:get_rotation()
|
||||
local kart_rot_offsets = vector.new(0,0,0)
|
||||
|
||||
if velocity.y == 0 then
|
||||
-- Handle node frictive types here;
|
||||
|
||||
-- Handle friction
|
||||
if self._dvel > 1 then
|
||||
self._dvel = self._dvel - 1
|
||||
-- Identify the node under the kart for physics and boost/item detection
|
||||
local kart_phys_pos = self.object:get_pos()
|
||||
local kart_node_pos = table.copy(kart_phys_pos)
|
||||
kart_node_pos.y = kart_node_pos.y - 1.5
|
||||
local node_detector = Raycast(kart_phys_pos, kart_node_pos, false, false)
|
||||
local node_pos
|
||||
for pointed in node_detector do
|
||||
if pointed == nil then
|
||||
else
|
||||
self._dvel = self._dvel * 0.96
|
||||
if pointed.type == "node" then
|
||||
node_pos = table.copy(pointed.under)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
local node_data = minetest.get_node_or_nil(node_pos)
|
||||
local node = minetest.registered_nodes[node_data.name]
|
||||
|
||||
if node.groups.booster ~= nil then
|
||||
if self._boost_timer <= 0 then
|
||||
self._boost_timer = node.groups.booster
|
||||
self._boost_type = 3
|
||||
end
|
||||
end
|
||||
|
||||
if node.groups.item ~= nil then
|
||||
minetest.swap_node(node_pos, {name=node._swap_to})
|
||||
local timer = minetest.get_node_timer(node_pos)
|
||||
timer:start(3)
|
||||
end
|
||||
|
||||
-- Handle node frictive types here;
|
||||
-- Handle friction on ground
|
||||
if velocity.y == 0 then
|
||||
local frictive = 0
|
||||
if node.groups.track == nil then
|
||||
frictive = friction_off_track
|
||||
else
|
||||
frictive = friction_track
|
||||
end
|
||||
self._dvel = solarsail.util.functions.lerp(self._dvel, self._dvel * (frictive * tick_speed), ratio_tick)
|
||||
else -- In air
|
||||
self._dvel = solarsail.util.functions.lerp(self._dvel, self._dvel * (friction_air * tick_speed), ratio_tick)
|
||||
end
|
||||
|
||||
-- Round down numbers when percentages exponentialise movement:
|
||||
if self._dvel < 0.1 and self._dvel > 0 then
|
||||
if self._dvel > 0 and self._dvel < 0.2 then
|
||||
self._dvel = 0
|
||||
elseif self._dvel > -0.1 and self._dvel < 0 then
|
||||
elseif self._dvel < 0 and self._dvel > -0.2 then
|
||||
self._dvel = 0
|
||||
end
|
||||
|
||||
-- Handle controls;
|
||||
-- Accel braking;
|
||||
if control.up then
|
||||
self._dvel = self._dvel + forwards_accel
|
||||
if control.up or self._boost_timer > 0 then
|
||||
local boost_multi = 1
|
||||
if self._boost_timer > 0 then
|
||||
boost_multi = 3
|
||||
end
|
||||
self._dvel = self._dvel + ((forwards_accel * boost_multi) * tick_scaling)
|
||||
elseif control.down then
|
||||
-- Reversing
|
||||
if self._dvel < 0.1 then
|
||||
self._dvel = self._dvel + reverse_accel
|
||||
else
|
||||
self._dvel = self._dvel * braking_factor
|
||||
end
|
||||
local racc_div = 1
|
||||
-- Make braking half as effective compared to reversing
|
||||
if self._dvel > 0 then racc_div = 2 end
|
||||
self._dvel = self._dvel + ((reverse_accel/racc_div) * tick_scaling)
|
||||
end
|
||||
|
||||
-- Drifting;
|
||||
@ -147,64 +243,81 @@ function kart:on_step(dtime)
|
||||
self._is_drifting = -1
|
||||
end
|
||||
end
|
||||
-- Increment timer for boost
|
||||
self._drift_timer = self._drift_timer + dtime
|
||||
|
||||
-- Drift steering
|
||||
if control.left then
|
||||
if self._is_drifting == 1 then --Left
|
||||
yaw_offset = drifting_radius_greater
|
||||
yaw_offset = drifting_radius_greater * tick_scaling
|
||||
elseif self._is_drifting == -1 then
|
||||
yaw_offset = -drifting_radius_lesser
|
||||
yaw_offset = -drifting_radius_lesser * tick_scaling
|
||||
end
|
||||
elseif control.right then
|
||||
if self._is_drifting == 1 then --Left adds, right removes
|
||||
yaw_offset = drifting_radius_lesser
|
||||
yaw_offset = drifting_radius_lesser * tick_scaling
|
||||
elseif self._is_drifting == -1 then
|
||||
yaw_offset = -drifting_radius_greater
|
||||
yaw_offset = -drifting_radius_greater * tick_scaling
|
||||
end
|
||||
else
|
||||
if self._is_drifting == 1 then --Left
|
||||
yaw_offset = drifting_radius
|
||||
yaw_offset = drifting_radius * tick_scaling
|
||||
elseif self._is_drifting == -1 then
|
||||
yaw_offset = -drifting_radius
|
||||
yaw_offset = -drifting_radius * tick_scaling
|
||||
end
|
||||
end
|
||||
elseif control.left then
|
||||
-- Fowards
|
||||
if self._dvel > 0.5 then
|
||||
yaw_offset = turning_radius
|
||||
if self._dvel > 0.25 then
|
||||
yaw_offset = turning_radius * tick_scaling
|
||||
-- Reversing
|
||||
elseif self._dvel < -0.1 then
|
||||
cam_rot_offset = 3.142
|
||||
yaw_offset = -reverse_radius
|
||||
yaw_offset = -reverse_radius * tick_scaling
|
||||
end
|
||||
elseif control.right then
|
||||
-- Fowards
|
||||
if self._dvel > 0.5 then
|
||||
yaw_offset = -turning_radius
|
||||
yaw_offset = -turning_radius * tick_scaling
|
||||
-- Reversing
|
||||
elseif self._dvel < -0.1 then
|
||||
cam_rot_offset = 3.142
|
||||
yaw_offset = reverse_radius
|
||||
yaw_offset = reverse_radius * tick_scaling
|
||||
end
|
||||
end
|
||||
|
||||
-- Tick down the level of boost until it completes
|
||||
if self._boost_timer > 0 then
|
||||
self._boost_timer = self._boost_timer - dtime
|
||||
elseif self._boost_type > 0 then
|
||||
self._boost_type = 0
|
||||
end
|
||||
|
||||
-- Give the boost
|
||||
if not control.jump then
|
||||
self._is_drifting = 0
|
||||
-- Maximum boost
|
||||
if self._drift_timer >=5 then
|
||||
self._boost_timer = 3
|
||||
if self._drift_timer >= big_drift_time then
|
||||
self._boost_timer = big_boost_time
|
||||
self._boost_type = 3
|
||||
self._drift_timer = 0
|
||||
-- Medium boost
|
||||
elseif self._drift_timer >=3 then
|
||||
self._boost_timer = 2
|
||||
elseif self._drift_timer >= med_drift_time then
|
||||
self._boost_timer = med_boost_time
|
||||
self._boost_type = 2
|
||||
self._drift_timer = 0
|
||||
-- Small boost
|
||||
elseif self._drift_timer >=1.5 then
|
||||
self._boost_timer = 1
|
||||
elseif self._drift_timer >= small_drift_time then
|
||||
self._boost_timer = small_boost_time
|
||||
self._boost_type = 1
|
||||
self._drift_timer = 0
|
||||
end
|
||||
end
|
||||
-- Do not give a boost if falling under the drifting speed
|
||||
if self._dvel <= 5 then
|
||||
|
||||
-- Do not give a boost if falling under the drifting speed or while in air
|
||||
if self._dvel <= 5 or velocity.y ~= 0 then
|
||||
self._is_drifting = 0
|
||||
self._drift_timer = 0
|
||||
self._boost_type = 0
|
||||
self._boost_timer = 0
|
||||
end
|
||||
|
||||
-- Use Item/Boost;
|
||||
@ -248,7 +361,7 @@ function kart:on_step(dtime)
|
||||
new_frames.y = 19
|
||||
end
|
||||
elseif control.down then -- Reversing
|
||||
if self._dvel > 1.5 then
|
||||
if self._dvel > 0.5 then
|
||||
if control.left then
|
||||
new_frames.x = 60
|
||||
new_frames.y = 79
|
||||
@ -259,7 +372,7 @@ function kart:on_step(dtime)
|
||||
new_frames.x = 0
|
||||
new_frames.y = 19
|
||||
end
|
||||
elseif self._dvel < -1.5 then
|
||||
elseif self._dvel < -0.5 then
|
||||
if control.left then
|
||||
new_frames.x = 90
|
||||
new_frames.y = 109
|
||||
@ -272,7 +385,7 @@ function kart:on_step(dtime)
|
||||
end
|
||||
end
|
||||
else -- Coming to a stop or idle
|
||||
if self._dvel > 1.5 then
|
||||
if self._dvel > 0.5 then
|
||||
if control.left then
|
||||
new_frames.x = 60
|
||||
new_frames.y = 79
|
||||
@ -283,7 +396,7 @@ function kart:on_step(dtime)
|
||||
new_frames.x = 0
|
||||
new_frames.y = 19
|
||||
end
|
||||
elseif self._dvel < -1.5 then
|
||||
elseif self._dvel < -0.5 then
|
||||
if control.left then
|
||||
new_frames.x = 90
|
||||
new_frames.y = 109
|
||||
@ -308,18 +421,131 @@ function kart:on_step(dtime)
|
||||
end
|
||||
end
|
||||
|
||||
-- Compare against frame table to avoid re-applying the animation
|
||||
if frange.x ~= new_frames.x then
|
||||
if frange.y ~= new_frames.y then
|
||||
self.object:set_animation(new_frames, 60, 0.1, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Reversing camera mode if required
|
||||
if self._dvel < -1 and control.down then
|
||||
if self._dvel < -0.5 and control.down then
|
||||
cam_rot_offset = 3.142
|
||||
end
|
||||
|
||||
-- Particlespawner handler
|
||||
-- Exhausts;
|
||||
local exhaust_particle = table.copy(exhause_particle_def)
|
||||
exhaust_particle.attached = self.object
|
||||
exhaust_particle.minvel = vector.new((-new_vel.x/4)-0.05, (-new_vel.y/4)+0.5, (-new_vel.z/4)-0.25)
|
||||
exhaust_particle.maxvel = vector.new((-new_vel.x/2)-0.15, (-new_vel.y/2)+1.2, (-new_vel.z/2)-0.5)
|
||||
exhaust_particle.minpos = rear_left_exhaust_pos_min
|
||||
exhaust_particle.maxpos = rear_left_exhaust_pos_max
|
||||
if self._boost_type == 0 and self._exhaust_left_spawner == nil then
|
||||
exhaust_particle.time = 0
|
||||
exhaust_particle.glow = 0
|
||||
exhaust_particle.node = {name = "invector:smoke_node"}
|
||||
exhaust_particle.minsize = 1
|
||||
exhaust_particle.maxsize = 1.15
|
||||
self._exhaust_left_spawner = minetest.add_particlespawner(exhaust_particle)
|
||||
exhaust_particle.minpos = rear_right_exhaust_pos_min
|
||||
exhaust_particle.maxpos = rear_right_exhaust_pos_max
|
||||
exhaust_particle.minvel.x = (-new_vel.x/4)+0.05
|
||||
exhaust_particle.maxvel.x = (-new_vel.x/2)+0.15
|
||||
self._exhaust_right_spawner = minetest.add_particlespawner(exhaust_particle)
|
||||
elseif self._boost_type == 1 then
|
||||
exhaust_particle.time = self._boost_timer
|
||||
exhaust_particle.glow = 14
|
||||
exhaust_particle.node = {name = "invector:boost_1_node"}
|
||||
exhaust_particle.minsize = 1.15
|
||||
exhaust_particle.maxsize = 1.4
|
||||
minetest.add_particlespawner(exhaust_particle)
|
||||
exhaust_particle.minpos = rear_right_exhaust_pos_min
|
||||
exhaust_particle.maxpos = rear_right_exhaust_pos_max
|
||||
exhaust_particle.minvel.x = (-new_vel.x/4)+0.05
|
||||
exhaust_particle.maxvel.x = (-new_vel.x/2)+0.15
|
||||
minetest.add_particlespawner(exhaust_particle)
|
||||
elseif self._boost_type == 2 then
|
||||
exhaust_particle.time = self._boost_timer
|
||||
exhaust_particle.glow = 14
|
||||
exhaust_particle.node = {name = "invector:boost_2_node"}
|
||||
exhaust_particle.minsize = 1.4
|
||||
exhaust_particle.maxsize = 1.65
|
||||
minetest.add_particlespawner(exhaust_particle)
|
||||
exhaust_particle.minpos = rear_right_exhaust_pos_min
|
||||
exhaust_particle.maxpos = rear_right_exhaust_pos_max
|
||||
exhaust_particle.minvel.x = (-new_vel.x/4)+0.05
|
||||
exhaust_particle.maxvel.x = (-new_vel.x/2)+0.15
|
||||
minetest.add_particlespawner(exhaust_particle)
|
||||
elseif self._boost_type == 3 then
|
||||
exhaust_particle.time = self._boost_timer
|
||||
exhaust_particle.glow = 14
|
||||
exhaust_particle.node = {name = "invector:boost_3_node"}
|
||||
exhaust_particle.minsize = 1.65
|
||||
exhaust_particle.maxsize = 1.95
|
||||
minetest.add_particlespawner(exhaust_particle)
|
||||
exhaust_particle.minpos = rear_right_exhaust_pos_min
|
||||
exhaust_particle.maxpos = rear_right_exhaust_pos_max
|
||||
exhaust_particle.minvel.x = (-new_vel.x/4)+0.05
|
||||
exhaust_particle.maxvel.x = (-new_vel.x/2)+0.15
|
||||
minetest.add_particlespawner(exhaust_particle)
|
||||
end
|
||||
|
||||
-- Disable regular smoke when boosting
|
||||
if self._boost_type > 0 and self._exhaust_left_spawner ~= nil then
|
||||
minetest.delete_particlespawner(self._exhaust_left_spawner)
|
||||
minetest.delete_particlespawner(self._exhaust_right_spawner)
|
||||
self._exhaust_left_spawner = nil
|
||||
self._exhaust_right_spawner = nil
|
||||
end
|
||||
|
||||
-- Rear Tyres;
|
||||
local drift_particle = table.copy(drift_particle_def)
|
||||
drift_particle.attached = self.object
|
||||
drift_particle.minvel = vector.new(-new_vel.x/2, (-new_vel.y/2)+0.5, -new_vel.z/2)
|
||||
drift_particle.maxvel = vector.new(-new_vel.x, (-new_vel.y)+0.75, -new_vel.z)
|
||||
if self._drift_timer >= big_drift_time and self._rear_left_tyre_spawner == nil then
|
||||
self._drift_level = 3
|
||||
drift_particle.time = 0
|
||||
drift_particle.texture = "invector_drift_big.png"
|
||||
drift_particle.minsize = 3
|
||||
drift_particle.maxsize = 4
|
||||
drift_particle.minpos = rear_left_tyre_pos_min
|
||||
drift_particle.maxpos = rear_left_tyre_pos_max
|
||||
self._rear_left_tyre_spawner = minetest.add_particlespawner(drift_particle)
|
||||
drift_particle.minpos = rear_right_tyre_pos_min
|
||||
drift_particle.maxpos = rear_right_tyre_pos_max
|
||||
self._rear_right_tyre_spawner = minetest.add_particlespawner(drift_particle)
|
||||
elseif self._drift_timer >= med_drift_time and self._drift_level == 1 then
|
||||
self._drift_level = 2
|
||||
drift_particle.time = 1.35
|
||||
drift_particle.texture = "invector_drift_medium.png"
|
||||
drift_particle.minsize = 2
|
||||
drift_particle.maxsize = 3
|
||||
drift_particle.minpos = rear_left_tyre_pos_min
|
||||
drift_particle.maxpos = rear_left_tyre_pos_max
|
||||
minetest.add_particlespawner(drift_particle)
|
||||
drift_particle.minpos = rear_right_tyre_pos_min
|
||||
drift_particle.maxpos = rear_right_tyre_pos_max
|
||||
minetest.add_particlespawner(drift_particle)
|
||||
elseif self._drift_timer >= small_drift_time and self._drift_level == 0 then
|
||||
self._drift_level = 1
|
||||
drift_particle.time = 1.35
|
||||
drift_particle.texture = "invector_drift_small.png"
|
||||
drift_particle.minsize = 1
|
||||
drift_particle.maxsize = 2
|
||||
drift_particle.minpos = rear_left_tyre_pos_min
|
||||
drift_particle.maxpos = rear_left_tyre_pos_max
|
||||
minetest.add_particlespawner(drift_particle)
|
||||
drift_particle.minpos = rear_right_tyre_pos_min
|
||||
drift_particle.maxpos = rear_right_tyre_pos_max
|
||||
minetest.add_particlespawner(drift_particle)
|
||||
elseif self._rear_left_tyre_spawner ~= nil then
|
||||
-- Clear max boost particles
|
||||
minetest.delete_particlespawner(self._rear_left_tyre_spawner)
|
||||
minetest.delete_particlespawner(self._rear_right_tyre_spawner)
|
||||
self._rear_left_tyre_spawner = nil
|
||||
self._rear_right_tyre_spawner = nil
|
||||
self._drift_level = 0
|
||||
end
|
||||
|
||||
-- Set camera rotation
|
||||
if not control.sneak then
|
||||
@ -333,8 +559,7 @@ function kart:on_step(dtime)
|
||||
|
||||
-- Set object rotation and speed
|
||||
self.object:set_velocity({x=xv, y=velocity.y, z=zv})
|
||||
self.object:set_yaw(rotation+yaw_offset)
|
||||
end
|
||||
self.object:set_rotation(vector.new(kart_rot_offsets.x, rotation+yaw_offset, 0))
|
||||
else -- Self destruct
|
||||
--self.object:remove()
|
||||
end
|
||||
|
BIN
mods/invector/models/invector_pad.b3d
Normal file
BIN
mods/invector/models/invector_pad_mega.b3d
Normal file
BIN
mods/invector/src_textures/boost_pad/0001.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
mods/invector/src_textures/boost_pad/0002.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
mods/invector/src_textures/boost_pad/0003.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
mods/invector/src_textures/boost_pad/0004.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
mods/invector/src_textures/boost_pad/0005.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
BIN
mods/invector/src_textures/boost_pad/0006.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
mods/invector/src_textures/boost_pad/0007.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
mods/invector/src_textures/boost_pad/0008.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
mods/invector/src_textures/boost_pad/0009.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
mods/invector/src_textures/boost_pad/0010.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
mods/invector/src_textures/boost_pad/0011.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
mods/invector/src_textures/boost_pad/0012.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
mods/invector/src_textures/boost_pad/0013.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
mods/invector/src_textures/boost_pad/0014.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
BIN
mods/invector/src_textures/boost_pad/0015.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
mods/invector/src_textures/boost_pad/0016.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
mods/invector/src_textures/boost_pad/0017.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
mods/invector/src_textures/item_pad/0001.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
mods/invector/src_textures/item_pad/0002.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
mods/invector/src_textures/item_pad/0003.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
mods/invector/src_textures/item_pad/0004.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
mods/invector/textures/invector_pad/boost_pad_holo_anim.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
mods/invector/textures/invector_pad/invector_pad_bottom.png
Normal file
After Width: | Height: | Size: 260 B |
BIN
mods/invector/textures/invector_pad/invector_pad_side.png
Normal file
After Width: | Height: | Size: 232 B |
BIN
mods/invector/textures/invector_pad/invector_pad_top.png
Normal file
After Width: | Height: | Size: 281 B |
BIN
mods/invector/textures/invector_pad/item_pad_holo_anim.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
mods/invector/textures/misc/invector_boost_big.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
mods/invector/textures/misc/invector_boost_medium.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
mods/invector/textures/misc/invector_boost_small.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
mods/invector/textures/misc/invector_drift_big.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
mods/invector/textures/misc/invector_drift_medium.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
mods/invector/textures/misc/invector_drift_small.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.1 KiB |
@ -130,11 +130,77 @@ function solarsail.util.functions.pos_to_dist(pos_1, pos_2)
|
||||
return math.sqrt(res.x*res.x + res.y*res.y + res.z*res.z)
|
||||
end
|
||||
|
||||
function solarsail.util.sensible_facedir(itemstack, placer, pointed_thing)
|
||||
local rpos
|
||||
|
||||
if minetest.registered_nodes[minetest.get_node(pointed_thing.under).name].buildable_to == true then
|
||||
rpos = pointed_thing.under
|
||||
else
|
||||
rpos = pointed_thing.above
|
||||
end
|
||||
|
||||
local hor_rot = math.deg(placer:get_look_horizontal()) -- convert radians to degrees
|
||||
local deg_to_fdir = math.floor(((hor_rot * 4 / 360) + 0.5) % 4) -- returns 0, 1, 2 or 3; checks between 90 degrees in a pacman style angle check, it's quite magical.
|
||||
|
||||
local fdir = 0 -- get initialised, and if we don't ever assign an fdir, then it's safe to ignore?! (probably not a good idea to do so)
|
||||
local px = math.abs(placer:get_pos().x - rpos.x) -- measure the distance from the player to the placed nodes position
|
||||
local pz = math.abs(placer:get_pos().z - rpos.z)
|
||||
|
||||
if px < 2 and pz < 2 then -- if the node is being placed 1 block away from us, then lets place it either upright or upside down
|
||||
local pY = 0
|
||||
if placer:get_pos().y < 0 then
|
||||
pY = math.abs(placer:get_pos().y - 1.14) -- we invert this Y value since we need to go UPWARDS to compare properly.
|
||||
else
|
||||
pY = math.abs(placer:get_pos().y + 2.14) -- we measure the y distance by itself as it may not be needed for wall placed blocks.
|
||||
end
|
||||
|
||||
if pY - math.abs(rpos.y) > 1.5 then -- are we being placed on the floor? let's be upright then.
|
||||
if deg_to_fdir == 0 then fdir = 0 -- north
|
||||
elseif deg_to_fdir == 1 then fdir = 3 --east
|
||||
elseif deg_to_fdir == 2 then fdir = 2 -- south
|
||||
elseif deg_to_fdir == 3 then fdir = 1 end -- west
|
||||
return minetest.item_place_node(itemstack, placer, pointed_thing, fdir)
|
||||
else -- if not, let's be upside down.
|
||||
if deg_to_fdir == 0 then fdir = 20 -- north
|
||||
elseif deg_to_fdir == 1 then fdir = 21 -- east
|
||||
elseif deg_to_fdir == 2 then fdir = 22 -- south
|
||||
elseif deg_to_fdir == 3 then fdir = 23 end -- west
|
||||
return minetest.item_place_node(itemstack, placer, pointed_thing, fdir)
|
||||
end
|
||||
end
|
||||
-- since we couldn't find a place that isn't either on a ceiling or floor, let's place it onto it's side.
|
||||
if deg_to_fdir == 0 then fdir = 9 -- north
|
||||
elseif deg_to_fdir == 1 then fdir = 12 -- east
|
||||
elseif deg_to_fdir == 2 then fdir = 7 -- south
|
||||
elseif deg_to_fdir == 3 then fdir = 18 end -- west
|
||||
return minetest.item_place_node(itemstack, placer, pointed_thing, fdir)
|
||||
end
|
||||
|
||||
function solarsail.util.sensible_facedir_simple(itemstack, placer, pointed_thing)
|
||||
local hor_rot = math.deg(placer:get_look_horizontal())
|
||||
local deg_to_fdir = math.floor(((hor_rot * 4 / 360) + 0.5) % 4)
|
||||
local fdir = 0
|
||||
|
||||
if deg_to_fdir == 0 then fdir = 0
|
||||
elseif deg_to_fdir == 1 then fdir = 3
|
||||
elseif deg_to_fdir == 2 then fdir = 2
|
||||
elseif deg_to_fdir == 3 then fdir = 1 end
|
||||
|
||||
return minetest.item_place_node(itemstack, placer, pointed_thing, fdir)
|
||||
end
|
||||
|
||||
|
||||
-- from and to are two positions where it returns whether
|
||||
-- it is left or to the right of the from variable.
|
||||
function solarsail.util.functions.left_or_right(from, to)
|
||||
|
||||
end
|
||||
|
||||
solarsail.avg_dtime = 0
|
||||
solarsail.last_dtime = {}
|
||||
|
||||
local dtime_steps = 0
|
||||
local num_steps = 30*2
|
||||
local num_steps = 60
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if dtime_steps == num_steps then
|
||||
@ -159,7 +225,7 @@ if true then
|
||||
minetest.register_node("solarsail:wireframe", {
|
||||
description = "Wireframe, prototyping node",
|
||||
tiles = {"solarsail_wireframe.png"},
|
||||
groups = {debug=1}
|
||||
groups = {debug=1, track = 1}
|
||||
})
|
||||
|
||||
minetest.register_alias("mapgen_stone", "solarsail:wireframe")
|
||||
|
@ -90,7 +90,7 @@ function solarsail.player.set_model(player_ref, model_name, anim, framerate,
|
||||
})
|
||||
|
||||
-- Set the eye offset for the "player camera"
|
||||
player_ref:set_eye_offset(eye_offset, eye_offset_3r)
|
||||
player_ref:set_eye_offset(eye_offset, eye_offset_3rv)
|
||||
-- Attach the "Minetest player" to the "solarsail player"
|
||||
player_ref:set_attach(entity_lua.object, attach_bone, relative_pos, relative_rotation)
|
||||
end
|
||||
|