holy jesus that's a commit

This commit is contained in:
Jordach 2021-12-07 02:03:57 +00:00
parent 0fd40b82bc
commit 6066e566d1
56 changed files with 773 additions and 265 deletions

View File

@ -2,6 +2,7 @@
"Lua.diagnostics.globals": [
"minetest",
"invector",
"vector"
"vector",
"Raycast"
]
}

9
mods/invector/ai.lua Normal file
View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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
})

View File

@ -1,18 +1,47 @@
-- Invector, License MIT, Author Jordach
minetest.override_item("", {
wield_scale = {x=1,y=1,z=1},
range = 1,
tool_capabilities = {
full_punch_interval = 1,
max_drop_level = 0,
groupcaps = {},
damage_groups = {},
}
})
-- 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 = {
full_punch_interval = 1,
max_drop_level = 0,
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")
exec("karts/sam2")

View File

@ -2,13 +2,21 @@
invector.karts = {}
function invector.functions.register_kart(name, def)
invector.karts[name] = def
minetest.register_entity("invector:"..name, def)
invector.karts[name] = def
minetest.register_entity("invector:"..name, def)
end
-- This is fixed in code due to this not being a multiplayer release.
minetest.register_on_joinplayer(function(player)
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)
end)
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 = {}

View File

@ -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,160 +127,241 @@ 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
local control = solarsail.controls.player[self.attached_player:get_player_name()]
if control == nil then return end
-- 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 control.aux1 then
self.attached_player:set_detach()
self.attached_player = nil
return
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
-- 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
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)
-- 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
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 and self._dvel < 0.2 then
self._dvel = 0
elseif self._dvel < 0 and self._dvel > -0.2 then
self._dvel = 0
end
-- Handle controls;
-- Accel braking;
if control.up or self._boost_timer > 0 then
local boost_multi = 1
if self._boost_timer > 0 then
self._boost_timer = self._boost_timer - dtime
boost_multi = 3
end
--self.object:set_animation({x=0, y=159}, 60, 0)
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
self._dvel = self._dvel + ((forwards_accel * boost_multi) * tick_scaling)
elseif control.down then
-- Reversing
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
if velocity.y == 0 then
-- Handle node frictive types here;
-- Handle friction
if self._dvel > 1 then
self._dvel = self._dvel - 1
else
self._dvel = self._dvel * 0.96
end
end
-- Round down numbers when percentages exponentialise movement:
if self._dvel < 0.1 and self._dvel > 0 then
self._dvel = 0
elseif self._dvel > -0.1 and self._dvel < 0 then
self._dvel = 0
end
-- Handle controls;
-- Accel braking;
if control.up then
self._dvel = self._dvel + forwards_accel
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
end
-- Drifting;
if control.jump and self._dvel > 5.5 then
-- Direction of drifting
if self._is_drifting == 0 then
if control.left then
self._is_drifting = 1
elseif control.right then
self._is_drifting = -1
end
end
-- Drift steering
-- Drifting;
if control.jump and self._dvel > 5.5 then
-- Direction of drifting
if self._is_drifting == 0 then
if control.left then
if self._is_drifting == 1 then --Left
yaw_offset = drifting_radius_greater
elseif self._is_drifting == -1 then
yaw_offset = -drifting_radius_lesser
end
self._is_drifting = 1
elseif control.right then
if self._is_drifting == 1 then --Left adds, right removes
yaw_offset = drifting_radius_lesser
elseif self._is_drifting == -1 then
yaw_offset = -drifting_radius_greater
end
else
if self._is_drifting == 1 then --Left
yaw_offset = drifting_radius
elseif self._is_drifting == -1 then
yaw_offset = -drifting_radius
end
self._is_drifting = -1
end
elseif control.left then
-- Fowards
if self._dvel > 0.5 then
yaw_offset = turning_radius
-- Reversing
elseif self._dvel < -0.1 then
cam_rot_offset = 3.142
yaw_offset = -reverse_radius
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 * tick_scaling
elseif self._is_drifting == -1 then
yaw_offset = -drifting_radius_lesser * tick_scaling
end
elseif control.right then
-- Fowards
if self._dvel > 0.5 then
yaw_offset = -turning_radius
-- Reversing
elseif self._dvel < -0.1 then
cam_rot_offset = 3.142
yaw_offset = reverse_radius
end
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
-- Medium boost
elseif self._drift_timer >=3 then
self._boost_timer = 2
-- Small boost
elseif self._drift_timer >=1.5 then
self._boost_timer = 1
end
end
-- Do not give a boost if falling under the drifting speed
if self._dvel <= 5 then
self._is_drifting = 0
self._drift_timer = 0
end
-- Use Item/Boost;
if control.LMB then
elseif control.RMB then
end
local xv, zv = solarsail.util.functions.yaw_to_vec(rotation+yaw_offset, self._dvel, false)
local new_vel = vector.new(xv, 0, zv)
new_vel = vector.normalize(new_vel)
new_vel.y = velocity.y
-- Limit velocity based on boost status
if self._boost_timer > 0 then
if self._dvel > max_speed_boost then
self._dvel = max_speed_boost
elseif self._dvel < -max_speed_boost then
self._dvel = -max_speed_boost
if self._is_drifting == 1 then --Left adds, right removes
yaw_offset = drifting_radius_lesser * tick_scaling
elseif self._is_drifting == -1 then
yaw_offset = -drifting_radius_greater * tick_scaling
end
else
if self._dvel > max_speed_norm then
self._dvel = max_speed_norm
elseif self._dvel < -max_speed_norm then
self._dvel = -max_speed_norm
if self._is_drifting == 1 then --Left
yaw_offset = drifting_radius * tick_scaling
elseif self._is_drifting == -1 then
yaw_offset = -drifting_radius * tick_scaling
end
end
elseif control.left then
-- Fowards
if self._dvel > 0.25 then
yaw_offset = turning_radius * tick_scaling
-- Reversing
elseif self._dvel < -0.1 then
yaw_offset = -reverse_radius * tick_scaling
end
elseif control.right then
-- Fowards
if self._dvel > 0.5 then
yaw_offset = -turning_radius * tick_scaling
-- Reversing
elseif self._dvel < -0.1 then
yaw_offset = reverse_radius * tick_scaling
end
end
-- Animation and camera handler:
local frange, fspeed, fblend, floop = self.object:get_animation()
local new_frames = {x=0, y=0}
local new_fps = 60
if control.up then
-- 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 >= big_drift_time then
self._boost_timer = big_boost_time
self._boost_type = 3
self._drift_timer = 0
-- Medium boost
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 >= 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 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;
if control.LMB then
elseif control.RMB then
end
local xv, zv = solarsail.util.functions.yaw_to_vec(rotation+yaw_offset, self._dvel, false)
local new_vel = vector.new(xv, 0, zv)
new_vel = vector.normalize(new_vel)
new_vel.y = velocity.y
-- Limit velocity based on boost status
if self._boost_timer > 0 then
if self._dvel > max_speed_boost then
self._dvel = max_speed_boost
elseif self._dvel < -max_speed_boost then
self._dvel = -max_speed_boost
end
else
if self._dvel > max_speed_norm then
self._dvel = max_speed_norm
elseif self._dvel < -max_speed_norm then
self._dvel = -max_speed_norm
end
end
-- Animation and camera handler:
local frange, fspeed, fblend, floop = self.object:get_animation()
local new_frames = {x=0, y=0}
local new_fps = 60
if control.up then
if control.left then
new_frames.x = 60
new_frames.y = 79
elseif control.right then
new_frames.x = 120
new_frames.y = 139
else
new_frames.x = 0
new_frames.y = 19
end
elseif control.down then -- Reversing
if self._dvel > 0.5 then
if control.left then
new_frames.x = 60
new_frames.y = 79
@ -247,94 +372,194 @@ function kart:on_step(dtime)
new_frames.x = 0
new_frames.y = 19
end
elseif control.down then -- Reversing
if self._dvel > 1.5 then
if control.left then
new_frames.x = 60
new_frames.y = 79
elseif control.right then
new_frames.x = 120
new_frames.y = 139
else
new_frames.x = 0
new_frames.y = 19
end
elseif self._dvel < -1.5 then
if control.left then
new_frames.x = 90
new_frames.y = 109
elseif control.right then
new_frames.x = 150
new_frames.y = 169
else
new_frames.x = 30
new_frames.y = 49
end
end
else -- Coming to a stop or idle
if self._dvel > 1.5 then
if control.left then
new_frames.x = 60
new_frames.y = 79
elseif control.right then
new_frames.x = 120
new_frames.y = 139
else
new_frames.x = 0
new_frames.y = 19
end
elseif self._dvel < -1.5 then
if control.left then
new_frames.x = 90
new_frames.y = 109
elseif control.right then
new_frames.x = 150
new_frames.y = 169
else
new_frames.x = 30
new_frames.y = 49
end
else -- Idle
if control.left then
new_frames.x = 79
new_frames.y = 79
elseif control.right then
new_frames.x = 139
new_frames.y = 139
else
new_frames.x = 19
new_frames.y = 19
end
elseif self._dvel < -0.5 then
if control.left then
new_frames.x = 90
new_frames.y = 109
elseif control.right then
new_frames.x = 150
new_frames.y = 169
else
new_frames.x = 30
new_frames.y = 49
end
end
if frange.x ~= new_frames.x then
if frange.y ~= new_frames.y then
self.object:set_animation(new_frames, 60, 0.1, true)
else -- Coming to a stop or idle
if self._dvel > 0.5 then
if control.left then
new_frames.x = 60
new_frames.y = 79
elseif control.right then
new_frames.x = 120
new_frames.y = 139
else
new_frames.x = 0
new_frames.y = 19
end
elseif self._dvel < -0.5 then
if control.left then
new_frames.x = 90
new_frames.y = 109
elseif control.right then
new_frames.x = 150
new_frames.y = 169
else
new_frames.x = 30
new_frames.y = 49
end
else -- Idle
if control.left then
new_frames.x = 79
new_frames.y = 79
elseif control.right then
new_frames.x = 139
new_frames.y = 139
else
new_frames.x = 19
new_frames.y = 19
end
end
-- Reversing camera mode if required
if self._dvel < -1 and control.down then
cam_rot_offset = 3.142
end
-- Set camera rotation
if not control.sneak then
if self.attached_player:get_look_vertical() ~= 0 then
self.attached_player:set_look_vertical(0)
end
if self.attached_player:get_look_horizontal() ~= rotation+cam_rot_offset then
self.attached_player:set_look_horizontal(rotation+cam_rot_offset)
end
end
-- Set object rotation and speed
self.object:set_velocity({x=xv, y=velocity.y, z=zv})
self.object:set_yaw(rotation+yaw_offset)
end
-- Compare against frame table to avoid re-applying the animation
if frange.x ~= new_frames.x then
self.object:set_animation(new_frames, 60, 0.1, true)
end
-- Reversing camera mode if required
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
if self.attached_player:get_look_vertical() ~= 0 then
self.attached_player:set_look_vertical(0)
end
if self.attached_player:get_look_horizontal() ~= rotation+cam_rot_offset then
self.attached_player:set_look_horizontal(rotation+cam_rot_offset)
end
end
-- Set object rotation and speed
self.object:set_velocity({x=xv, y=velocity.y, z=zv})
self.object:set_rotation(vector.new(kart_rot_offsets.x, rotation+yaw_offset, 0))
else -- Self destruct
--self.object:remove()
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -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")

View File

@ -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