Basic kart implementation
7
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"Lua.diagnostics.globals": [
|
||||||
|
"minetest",
|
||||||
|
"invector",
|
||||||
|
"vector"
|
||||||
|
]
|
||||||
|
}
|
2
game.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
name = invector
|
||||||
|
disallowed_mapgens = v6, v7, valleys, carpathian, v5, fractal
|
BIN
menu/header.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
menu/icon.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
menu/intro_title.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
9
minetest.conf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#time_speed = 4
|
||||||
|
dedicated_server_step = 0.03
|
||||||
|
item_entity_ttl = 1
|
||||||
|
active_object_send_range_blocks = 32
|
||||||
|
active_block_range = 32
|
||||||
|
ask_reconnect_on_crash = true
|
||||||
|
player_transfer_distance = 0
|
||||||
|
max_objects_per_block = 1024
|
||||||
|
max_packets_per_iteration = 2048
|
BIN
mods/invector/blends/sam2.blend
Normal file
BIN
mods/invector/blends/sam2.blend1
Normal file
25
mods/invector/blocks.lua
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
-- Invector, License MIT, Author Jordach
|
||||||
|
|
||||||
|
minetest.register_node("invector:smoke_node", {
|
||||||
|
description = "don't use me",
|
||||||
|
tiles = {"invector_smoke.png"},
|
||||||
|
drawtype = "glasslike"
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_node("invector:boost_1_node", {
|
||||||
|
description = "don't use me",
|
||||||
|
tiles = {"invector_boost_small.png"},
|
||||||
|
drawtype = "glasslike"
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_node("invector:boost_2_node", {
|
||||||
|
description = "don't use me",
|
||||||
|
tiles = {"invector_boost_medium.png"},
|
||||||
|
drawtype = "glasslike"
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_node("invector:boost_3_node", {
|
||||||
|
description = "don't use me",
|
||||||
|
tiles = {"invector_boost_large.png"},
|
||||||
|
drawtype = "glasslike"
|
||||||
|
})
|
24
mods/invector/init.lua
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
-- 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 = {},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
invector = {}
|
||||||
|
invector.functions = {}
|
||||||
|
|
||||||
|
invector.path = minetest.get_modpath("invector")
|
||||||
|
|
||||||
|
local function exec(file)
|
||||||
|
dofile(invector.path.."/"..file..".lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
exec("kart")
|
||||||
|
exec("karts/sam2")
|
14
mods/invector/kart.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-- Invector, License MIT, Author Jordach
|
||||||
|
invector.karts = {}
|
||||||
|
|
||||||
|
function invector.functions.register_kart(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)
|
343
mods/invector/karts/sam2.lua
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
-- Invector, License MIT, Author Jordach
|
||||||
|
|
||||||
|
-- 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_3r = vector.new(0,-10,0)
|
||||||
|
local player_relative = vector.new(0,0,0)
|
||||||
|
local player_rot = vector.new(0,0,0)
|
||||||
|
|
||||||
|
-- Update rate, don't touch me
|
||||||
|
local tick_speed = 0.03
|
||||||
|
|
||||||
|
-- Bone rotation things;
|
||||||
|
local kart_root_pos = vector.new(0,0,0)
|
||||||
|
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)
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
|
||||||
|
-- Speed specs
|
||||||
|
local max_speed_boost = 8
|
||||||
|
local max_speed_norm = 6
|
||||||
|
local forwards_accel = 3
|
||||||
|
local reverse_accel = -0.25
|
||||||
|
local braking_factor = 0.75
|
||||||
|
|
||||||
|
-- Boost specs
|
||||||
|
local small_boost_time = 1.5
|
||||||
|
local med_boost_time = 3
|
||||||
|
local big_boost_time = 5
|
||||||
|
|
||||||
|
local kart = {
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "sam2.b3d",
|
||||||
|
use_texture_alpha = true,
|
||||||
|
backface_culling = false,
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
textures = {
|
||||||
|
"sam2_kart_neo.png",
|
||||||
|
"sam2_skin.png",
|
||||||
|
},
|
||||||
|
visual_size = {x=1, y=1},
|
||||||
|
collisionbox = {-0.61, 0.0, -0.61, 0.61, 1.4, 0.61},
|
||||||
|
physical = true,
|
||||||
|
collide_with_objects = true,
|
||||||
|
pointable = false,
|
||||||
|
stepheight = 0.5/16,
|
||||||
|
|
||||||
|
-- Custom fields:
|
||||||
|
_timer = 0,
|
||||||
|
_boost_timer = 0,
|
||||||
|
_drift_timer = 0,
|
||||||
|
_xvel = 0,
|
||||||
|
_zvel = 0,
|
||||||
|
_dvel = 0,
|
||||||
|
_yvel = 0,
|
||||||
|
_last_cam_offset = 0,
|
||||||
|
_is_drifting = 0, -- 1 = left, -1 = right
|
||||||
|
|
||||||
|
-- Particle ID holders
|
||||||
|
_rear_left_tyre_spawner = 0,
|
||||||
|
_rear_right_tyre_spawner = 0,
|
||||||
|
_exhaust_left_spawner = 0,
|
||||||
|
_exhaust_right_spawner = 0,
|
||||||
|
|
||||||
|
_deo = default_eye_offset,
|
||||||
|
_geo = ground_eye_offset,
|
||||||
|
_geo3r = ground_eye_offset_3r,
|
||||||
|
_prel = player_relative,
|
||||||
|
_prot = player_rot
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
--[[ if control.aux1 then
|
||||||
|
self.attached_player:set_detach()
|
||||||
|
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 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
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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 > 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
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
else -- Self destruct
|
||||||
|
--self.object:remove()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
invector.functions.register_kart("sam2", kart)
|
2
mods/invector/mod.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
name = invector
|
||||||
|
depends = solarsail
|
BIN
mods/invector/models/player_test.b3d
Normal file
BIN
mods/invector/models/sam2.b3d
Normal file
BIN
mods/invector/textures/blocks/core_azan_leaves.png
Normal file
After Width: | Height: | Size: 456 B |
BIN
mods/invector/textures/blocks/core_azan_log.png
Normal file
After Width: | Height: | Size: 562 B |
BIN
mods/invector/textures/blocks/core_azan_log_top.png
Normal file
After Width: | Height: | Size: 717 B |
BIN
mods/invector/textures/blocks/core_block_health_1.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
mods/invector/textures/blocks/core_block_health_2.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
mods/invector/textures/blocks/core_block_health_3.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
mods/invector/textures/blocks/core_cobble.png
Normal file
After Width: | Height: | Size: 910 B |
BIN
mods/invector/textures/blocks/core_cobble_mossy.png
Normal file
After Width: | Height: | Size: 921 B |
BIN
mods/invector/textures/blocks/core_dirt.png
Normal file
After Width: | Height: | Size: 614 B |
BIN
mods/invector/textures/blocks/core_grass.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
mods/invector/textures/blocks/core_grass_side.png
Normal file
After Width: | Height: | Size: 571 B |
BIN
mods/invector/textures/blocks/core_gravel.png
Normal file
After Width: | Height: | Size: 377 B |
BIN
mods/invector/textures/blocks/core_ice.png
Normal file
After Width: | Height: | Size: 476 B |
BIN
mods/invector/textures/blocks/core_lamp_blue.png
Normal file
After Width: | Height: | Size: 274 B |
BIN
mods/invector/textures/blocks/core_lamp_red.png
Normal file
After Width: | Height: | Size: 271 B |
BIN
mods/invector/textures/blocks/core_long_grass_1.png
Normal file
After Width: | Height: | Size: 345 B |
BIN
mods/invector/textures/blocks/core_long_grass_2.png
Normal file
After Width: | Height: | Size: 489 B |
BIN
mods/invector/textures/blocks/core_long_grass_3.png
Normal file
After Width: | Height: | Size: 324 B |
BIN
mods/invector/textures/blocks/core_neutral.png
Normal file
After Width: | Height: | Size: 582 B |
BIN
mods/invector/textures/blocks/core_neutral_lamp.png
Normal file
After Width: | Height: | Size: 390 B |
BIN
mods/invector/textures/blocks/core_reiz_log.png
Normal file
After Width: | Height: | Size: 484 B |
BIN
mods/invector/textures/blocks/core_reiz_log_top.png
Normal file
After Width: | Height: | Size: 643 B |
BIN
mods/invector/textures/blocks/core_reiz_needles.png
Normal file
After Width: | Height: | Size: 379 B |
BIN
mods/invector/textures/blocks/core_reiz_needles_snowy.png
Normal file
After Width: | Height: | Size: 553 B |
BIN
mods/invector/textures/blocks/core_sand.png
Normal file
After Width: | Height: | Size: 565 B |
BIN
mods/invector/textures/blocks/core_sandstone.png
Normal file
After Width: | Height: | Size: 705 B |
BIN
mods/invector/textures/blocks/core_snow.png
Normal file
After Width: | Height: | Size: 434 B |
BIN
mods/invector/textures/blocks/core_snow_side.png
Normal file
After Width: | Height: | Size: 653 B |
BIN
mods/invector/textures/blocks/core_stone.png
Normal file
After Width: | Height: | Size: 749 B |
BIN
mods/invector/textures/blocks/core_team_blue.png
Normal file
After Width: | Height: | Size: 595 B |
BIN
mods/invector/textures/blocks/core_team_red.png
Normal file
After Width: | Height: | Size: 503 B |
BIN
mods/invector/textures/blocks/core_water.png
Normal file
After Width: | Height: | Size: 534 B |
BIN
mods/invector/textures/blocks/core_water_flowing_animated.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
mods/invector/textures/blocks/core_water_source_animated.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
mods/invector/textures/blocks/core_zeith_ore.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
mods/invector/textures/kart_texture_neo.xcf
Normal file
BIN
mods/invector/textures/misc/invector_smoke.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
mods/invector/textures/misc/transparent.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
mods/invector/textures/sam2_kart_neo.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
mods/invector/textures/sam2_skin.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
34
mods/solarsail/control.lua
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
-- SolarSail Engine Control Handler:
|
||||||
|
-- Author: Jordach
|
||||||
|
-- License: Reserved
|
||||||
|
|
||||||
|
--[[ solarsail.controls.focus[player_name]
|
||||||
|
Valid values, should be read only (but set by a authoritive script):
|
||||||
|
|
||||||
|
"talk" all controls are used to handle talking to NPCs, ie dialog options
|
||||||
|
"world" all controls are used to control the player when in the world
|
||||||
|
"menu" all controls are used to change the cursor in a menu
|
||||||
|
"battle" all controls are used to handle battle, behaves like "menu"
|
||||||
|
"cutscene" all controls aren't used, but pressing jump can skip things
|
||||||
|
|
||||||
|
--]]
|
||||||
|
solarsail.controls.focus = {}
|
||||||
|
|
||||||
|
--[[ solarsail.controls.player[player_name]
|
||||||
|
Read only:
|
||||||
|
Gets the player:get_player_control() result for [player_name]
|
||||||
|
]]--
|
||||||
|
solarsail.controls.player = {}
|
||||||
|
|
||||||
|
local function update_controls()
|
||||||
|
for _, player in ipairs(minetest.get_connected_players()) do
|
||||||
|
solarsail.controls.player[player:get_player_name()] = player:get_player_control()
|
||||||
|
end
|
||||||
|
minetest.after(0.03, update_controls)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
solarsail.controls.focus[player:get_player_name()] = "world"
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.after(0.03, update_controls)
|
206
mods/solarsail/init.lua
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
-- SolarSail Engine
|
||||||
|
-- Author: Jordach
|
||||||
|
-- License: Reserved
|
||||||
|
|
||||||
|
-- Primary Namespaces:
|
||||||
|
|
||||||
|
solarsail = {}
|
||||||
|
|
||||||
|
solarsail.skybox = {}
|
||||||
|
solarsail.camera = {}
|
||||||
|
solarsail.controls = {}
|
||||||
|
solarsail.player = {}
|
||||||
|
solarsail.util = {}
|
||||||
|
solarsail.util.functions = {}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
solarsail.util.function.normalize_pos()
|
||||||
|
|
||||||
|
pos_a = vector.new(); considered the zero point
|
||||||
|
pos_b = vector.new(); considered the space around the zero point
|
||||||
|
returns pos_b localised by pos_a.
|
||||||
|
]]
|
||||||
|
|
||||||
|
function solarsail.util.functions.get_local_pos(pos_a, pos_b)
|
||||||
|
local pa = table.copy(pos_a)
|
||||||
|
local pb = table.copy(pos_b)
|
||||||
|
local res = vector.new(
|
||||||
|
pb.x - pa.x,
|
||||||
|
pb.y - pa.y,
|
||||||
|
pb.z - pa.z
|
||||||
|
)
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
solarsail.util.functions.convert_from_hex()
|
||||||
|
|
||||||
|
input = ColorSpec
|
||||||
|
returns three variables red, green and blue in base 10 values.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
function solarsail.util.functions.convert_from_hex(input)
|
||||||
|
local r, g, b = input:match("^#(%x%x)(%x%x)(%x%x)")
|
||||||
|
return tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
solarsail.util.functions.lerp()
|
||||||
|
|
||||||
|
var_a = input number to blend from. (at ratio 0)
|
||||||
|
var_b = input number to blend to. (at ratio 1)
|
||||||
|
returns the blended value depending on ratio.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
function solarsail.util.functions.lerp(var_a, var_b, ratio)
|
||||||
|
return (1-ratio)*var_a + (ratio*var_b)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
solarsail.util.functions.remap()
|
||||||
|
|
||||||
|
val = Input value
|
||||||
|
min_val = minimum value of your expected range
|
||||||
|
max_val = maximum value of your expected range
|
||||||
|
min_map = minimum value of your remapped range
|
||||||
|
max_map = maximum value of your remapped range
|
||||||
|
returns a value between min_map and max_map based on where val is relative to min_val and max_val.
|
||||||
|
]]
|
||||||
|
|
||||||
|
function solarsail.util.functions.remap(val, min_val, max_val, min_map, max_map)
|
||||||
|
return (val-min_val)/(max_val-min_val) * (max_map-min_map) + min_map
|
||||||
|
end
|
||||||
|
|
||||||
|
function solarsail.util.functions.blend_colours(val, min_val, max_val, min_col, max_col)
|
||||||
|
if val <= min_val then
|
||||||
|
return min_col
|
||||||
|
elseif val >= max_val then
|
||||||
|
return max_col
|
||||||
|
end
|
||||||
|
|
||||||
|
local min_r, min_g, min_b = solarsail.util.functions.convert_from_hex(min_col)
|
||||||
|
local max_r, max_g, max_b = solarsail.util.functions.convert_from_hex(max_col)
|
||||||
|
|
||||||
|
local blend = solarsail.util.functions.remap(val, min_val, max_val, 0, 1)
|
||||||
|
local res_r = solarsail.util.functions.lerp(min_r, max_r, blend)
|
||||||
|
local res_g = solarsail.util.functions.lerp(min_g, max_g, blend)
|
||||||
|
local res_b = solarsail.util.functions.lerp(min_b, max_b, blend)
|
||||||
|
return minetest.rgba(res_r, res_g, res_b)
|
||||||
|
end
|
||||||
|
|
||||||
|
function solarsail.util.functions.y_direction(rads, recoil)
|
||||||
|
return math.sin(rads) * recoil
|
||||||
|
end
|
||||||
|
|
||||||
|
function solarsail.util.functions.xz_amount(rads)
|
||||||
|
local pi = math.pi
|
||||||
|
return math.sin(rads+(pi/2))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Takes vector based velocities or positions (as vec_a to vec_b)
|
||||||
|
function solarsail.util.functions.get_3d_angles(vector_a, vector_b)
|
||||||
|
-- Does the usual Pythagoras bullshit:
|
||||||
|
local x_dist = vector_a.x - vector_b.x + 1
|
||||||
|
local z_dist = vector_a.z - vector_b.z + 1
|
||||||
|
local hypo = math.sqrt(x_dist^2 + z_dist^2)
|
||||||
|
|
||||||
|
-- But here's the kicker: we're using arctan to get the cotangent of the angle,
|
||||||
|
-- but also applies to *negative* numbers. In such cases where the positions
|
||||||
|
-- are northbound (positive z); the angle is 180 degrees off.
|
||||||
|
local xz_angle = -math.atan(x_dist/z_dist)
|
||||||
|
|
||||||
|
-- For the pitch angle we do it very similar, but use the
|
||||||
|
-- Hypotenuse as the Adjacent side, and the Y distance as the
|
||||||
|
-- Opposite, so arctangents are needed.
|
||||||
|
local y_dist = vector_a.y - vector_b.y
|
||||||
|
local y_angle = math.atan(y_dist/hypo)
|
||||||
|
|
||||||
|
-- Fixes radians using south facing (-Z) radians when heading north (+Z)
|
||||||
|
if z_dist < 0 then
|
||||||
|
xz_angle = xz_angle - math.rad(180)
|
||||||
|
end
|
||||||
|
return xz_angle, y_angle
|
||||||
|
end
|
||||||
|
|
||||||
|
function solarsail.util.functions.pos_to_dist(pos_1, pos_2)
|
||||||
|
local res = {}
|
||||||
|
res.x = (pos_1.x - pos_2.x)
|
||||||
|
res.y = (pos_1.y - pos_2.y)
|
||||||
|
res.z = (pos_1.z - pos_2.z)
|
||||||
|
return math.sqrt(res.x*res.x + res.y*res.y + res.z*res.z)
|
||||||
|
end
|
||||||
|
|
||||||
|
solarsail.avg_dtime = 0
|
||||||
|
solarsail.last_dtime = {}
|
||||||
|
|
||||||
|
local dtime_steps = 0
|
||||||
|
local num_steps = 30*2
|
||||||
|
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
if dtime_steps == num_steps then
|
||||||
|
local avg = 0
|
||||||
|
for i=1, num_steps do
|
||||||
|
avg = avg + solarsail.last_dtime[i]
|
||||||
|
end
|
||||||
|
solarsail.avg_dtime = avg / num_steps
|
||||||
|
dtime_steps = 0
|
||||||
|
solarsail.last_dtime[1] = dtime
|
||||||
|
--print(string.format("%.4f", tostring(solarsail.avg_dtime)))
|
||||||
|
--minetest.chat_send_all(string.format("%.4f", tostring(solarsail.avg_dtime)))
|
||||||
|
else
|
||||||
|
dtime_steps = dtime_steps + 1
|
||||||
|
solarsail.last_dtime[dtime_steps] = dtime
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if true then
|
||||||
|
-- Handle flat mapgen, for building a world
|
||||||
|
|
||||||
|
minetest.register_node("solarsail:wireframe", {
|
||||||
|
description = "Wireframe, prototyping node",
|
||||||
|
tiles = {"solarsail_wireframe.png"},
|
||||||
|
groups = {debug=1}
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_alias("mapgen_stone", "solarsail:wireframe")
|
||||||
|
minetest.register_alias("mapgen_grass", "solarsail:wireframe")
|
||||||
|
minetest.register_alias("mapgen_water_source", "solarsail:wireframe")
|
||||||
|
minetest.register_alias("mapgen_river_water_source", "solarsail:wireframe")
|
||||||
|
|
||||||
|
-- Sava data handling (per-player):
|
||||||
|
|
||||||
|
--dofile(minetest.get_modpath("solarsail").."/save.lua")
|
||||||
|
|
||||||
|
-- HSVA->RGBA->HSVA handling:
|
||||||
|
|
||||||
|
--dofile(minetest.get_modpath("solarsail").."/colour.lua")
|
||||||
|
|
||||||
|
-- HUD rendering and formspec handling:
|
||||||
|
|
||||||
|
--dofile(minetest.get_modpath("solarsail").."/hud.lua")
|
||||||
|
|
||||||
|
-- Cameras used in dialog, cutscenes or when controlled by the player:
|
||||||
|
|
||||||
|
--dofile(minetest.get_modpath("solarsail").."/camera.lua")
|
||||||
|
|
||||||
|
-- Start skybox engine:
|
||||||
|
|
||||||
|
dofile(minetest.get_modpath("solarsail").."/skybox.lua")
|
||||||
|
|
||||||
|
-- Control handling for HUDs, player entity, etc:
|
||||||
|
|
||||||
|
dofile(minetest.get_modpath("solarsail").."/control.lua")
|
||||||
|
|
||||||
|
-- Third person player camera handling + third person model:
|
||||||
|
|
||||||
|
dofile(minetest.get_modpath("solarsail").."/player.lua")
|
||||||
|
|
||||||
|
-- Basic, advanced NPC AI;
|
||||||
|
|
||||||
|
--dofile(minetest.get_modpath("solarsail").."/npc.lua")
|
||||||
|
|
||||||
|
-- Player menus:
|
||||||
|
|
||||||
|
--dofile(minetest.get_modpath("solarsail").."/menu.lua")
|
||||||
|
end
|
||||||
|
|
142
mods/solarsail/player.lua
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
-- SolarSail Engine Player Handling:
|
||||||
|
-- Author: Jordach
|
||||||
|
-- License: Reserved
|
||||||
|
|
||||||
|
solarsail.player.model = {}
|
||||||
|
|
||||||
|
--[[ solarsail.player.model.entity_name[player_name]
|
||||||
|
Read only, set only by authoritative content.
|
||||||
|
|
||||||
|
Example values:
|
||||||
|
solarsail.player.model.entity_name[player_name] = "solarplains:starsuit"
|
||||||
|
solarsail.player.model.entity_name[player_name] = "anathema:model"
|
||||||
|
]]
|
||||||
|
solarsail.player.model.entity_name = {}
|
||||||
|
|
||||||
|
solarsail.player.model.entity_ref = {}
|
||||||
|
--[[ solarsail.player.set_model(player_ref, model_name, anim, framerate,
|
||||||
|
eye_offset, eye_offset_3r, attach_bone,
|
||||||
|
attach_relative, attach_rotation)
|
||||||
|
|
||||||
|
model_name = "model:name"
|
||||||
|
(See minetest.register_entity() for more information.)
|
||||||
|
|
||||||
|
anim:
|
||||||
|
anim.x = 123, The start position of the animation loop
|
||||||
|
anim.y = 456, The end position of the animation loop
|
||||||
|
Setting anim = nil will result in anim.x, anim.y = 0
|
||||||
|
|
||||||
|
framerate = 60, Sets the framerate of the animation,
|
||||||
|
can be configured upto about 300fps.
|
||||||
|
framerate = nil will default to 60.
|
||||||
|
|
||||||
|
eye_offset and eye_offset_3r:
|
||||||
|
x = 1, Position on the X axis where the "player's camera" will sit
|
||||||
|
y = 2, Position on the Y axis where the "player's camera" will sit
|
||||||
|
z = 3, Position on the Z axis where the "player's camera" will sit
|
||||||
|
|
||||||
|
Setting either table to nil will default to x, y, z = 0.
|
||||||
|
|
||||||
|
attach_bone = "bonename", Make sure the bone exists in the exported model.
|
||||||
|
(Can include . : , etc)
|
||||||
|
Setting attach_bone to nil will default to ""
|
||||||
|
|
||||||
|
attach_relative:
|
||||||
|
x = 1, Position on the X axis where the
|
||||||
|
"Minetest Player Entity" is attached
|
||||||
|
y = 2, Position on the Y axis where the
|
||||||
|
"Minetest Player Entity" is attached
|
||||||
|
z = 3, Position on the Z axis where the
|
||||||
|
"Minetest Player Entity" is attached
|
||||||
|
Setting attach_relative = nil will default to x, y, z = 0.
|
||||||
|
|
||||||
|
attach_rotation:
|
||||||
|
x = 1, Rotation on the X axis in degrees
|
||||||
|
(of either the entity or player, documentation unclear)
|
||||||
|
y = 2, Rotation on the Y axis in degrees
|
||||||
|
(of either the entity or player, documentation unclear)
|
||||||
|
z = 3, Rotation on the Z axis in degrees
|
||||||
|
(of either the entity or player, documentation unclear)
|
||||||
|
Setting attach_rotation = nil will default to x, y, z = 0.
|
||||||
|
]]
|
||||||
|
|
||||||
|
function solarsail.player.set_model(player_ref, model_name, anim, framerate,
|
||||||
|
eye_offset, eye_offset_3rv, attach_bone, relative_pos, relative_rotation)
|
||||||
|
-- Prevent impossible situations where the model may not exist.
|
||||||
|
if model_name == nil or type(model_name) ~= "string" then
|
||||||
|
error("model_name must be a string.")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Construct a player entity at the player's position:
|
||||||
|
local pos = player_ref:get_pos()
|
||||||
|
solarsail.player.model.entity_ref[player_ref:get_player_name()] = minetest.add_entity(pos, model_name)
|
||||||
|
|
||||||
|
-- Get LuaObject:
|
||||||
|
local entity_lua = solarsail.player.model.entity_ref[player_ref:get_player_name()]:get_luaentity()
|
||||||
|
|
||||||
|
-- Add the player_ref to the model, as it may be needed to ensure they player is still attached.
|
||||||
|
-- Set this to nil to detach the "player camera" from the "player model"
|
||||||
|
entity_lua.attached_player = player_ref
|
||||||
|
|
||||||
|
-- Set the idle animation:
|
||||||
|
solarsail.player.model.entity_ref[player_ref:get_player_name()]:set_animation(anim, framerate, 0)
|
||||||
|
-- Remove all normal MT HUD from the player:
|
||||||
|
player_ref:hud_set_flags({
|
||||||
|
crosshair = false,
|
||||||
|
hotbar = false,
|
||||||
|
healthbar = false,
|
||||||
|
wielditem = false,
|
||||||
|
breathbar = false
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Set the eye offset for the "player camera"
|
||||||
|
player_ref:set_eye_offset(eye_offset, eye_offset_3r)
|
||||||
|
-- Attach the "Minetest player" to the "solarsail player"
|
||||||
|
player_ref:set_attach(entity_lua.object, attach_bone, relative_pos, relative_rotation)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Wrapper for Lua_SAO:set_properties()
|
||||||
|
function solarsail.player.set_properties(player_name, changes)
|
||||||
|
solarsail.player.model.entity_ref[player_name]:set_properties(changes)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Wrapper for Lua_SAO:get_properties()
|
||||||
|
function solarsail.player.get_properties(player_name)
|
||||||
|
return solarsail.player.model.entity_ref[player_name]:get_properties()
|
||||||
|
end
|
||||||
|
|
||||||
|
--store PI for quicker use:
|
||||||
|
local pi = math.pi
|
||||||
|
|
||||||
|
-- Supply a boolean value to go backwards, otherwise, forwards
|
||||||
|
function solarsail.util.functions.yaw_to_vec(rads, mult, backwards)
|
||||||
|
local z = math.cos(rads) * mult
|
||||||
|
local x = (math.sin(rads) * -1) * mult
|
||||||
|
|
||||||
|
if backwards then
|
||||||
|
return -x, -z
|
||||||
|
else
|
||||||
|
return x, z
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get left or right direction, supply a boolean to go left.
|
||||||
|
function solarsail.util.functions.yaw_to_vec_side(rads, mult, left)
|
||||||
|
local nrads = rads + pi/2
|
||||||
|
if left then
|
||||||
|
nrads = rads - pi/2
|
||||||
|
end
|
||||||
|
local x = (math.cos(nrads) * -1) * mult
|
||||||
|
local z = math.sin(nrads) * mult
|
||||||
|
return z, x
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Convert our x, z vectors to a nice radian:
|
||||||
|
function solarsail.util.functions.vec_to_rad(x, z)
|
||||||
|
return math.atan2(z, x)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Quickly convert degrees to radians:
|
||||||
|
function solarsail.util.functions.deg_to_rad(deg)
|
||||||
|
return deg * (pi/180)
|
||||||
|
end
|
291
mods/solarsail/skybox.lua
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
-- SolarSail Engine Skybox Handler:
|
||||||
|
-- Author: Jordach
|
||||||
|
-- License: Reserved
|
||||||
|
|
||||||
|
-- Pre-Init:
|
||||||
|
|
||||||
|
solarsail.skybox.is_paused = false
|
||||||
|
|
||||||
|
solarsail.skybox.regions = {}
|
||||||
|
solarsail.skybox.regions.pos_1 = {}
|
||||||
|
solarsail.skybox.regions.pos_2 = {}
|
||||||
|
solarsail.skybox.regions.skybox = {}
|
||||||
|
|
||||||
|
solarsail.skybox.skybox_defs = {}
|
||||||
|
solarsail.skybox.cloud_defs = {}
|
||||||
|
|
||||||
|
--[[ solarsail.skybox.register_skybox(skybox_name, skybox_defs, cloud_defs, pos_1, pos_2)
|
||||||
|
|
||||||
|
API spec for registering clouds based on position:
|
||||||
|
|
||||||
|
skybox_defs table:
|
||||||
|
skybox_defs.textures = {1, 2, 3, 4, 5, 6}
|
||||||
|
skybox_defs.type = "regular", "bgcolor", "skybox"
|
||||||
|
skybox_defs.bgcolor = "#rrggbb"
|
||||||
|
skybox_defs.clouds = true, false
|
||||||
|
|
||||||
|
cloud_defs table:
|
||||||
|
cloud_defs.density: 0 to 1
|
||||||
|
cloud_defs.color: "#rrggbbaa"
|
||||||
|
cloud_defs.ambient: "#rrggbb"
|
||||||
|
cloud_defs.height: -31000 to 31000
|
||||||
|
cloud_defs.thickness: 0.01 to 31000
|
||||||
|
cloud_defs.x = -128 to 128
|
||||||
|
cloud_defs.y = -128 to 128
|
||||||
|
|
||||||
|
position_1 = {x = 1, y = 0, z = 0}
|
||||||
|
position_2 = {x = -1, y = 1, z = 10}
|
||||||
|
|
||||||
|
Note: Preferrably as game_skyboxname or mod_skyboxname
|
||||||
|
]]--
|
||||||
|
|
||||||
|
function solarsail.skybox.register_skybox(skybox_name, skybox_defs, cloud_defs, pos_1, pos_2)
|
||||||
|
solarsail.skybox.skybox_defs[skybox_name] = skybox_defs
|
||||||
|
solarsail.skybox.cloud_defs[skybox_name] = cloud_defs
|
||||||
|
solarsail.skybox.regions.pos_1[skybox_name] = pos_1
|
||||||
|
solarsail.skybox.regions.pos_2[skybox_name] = pos_2
|
||||||
|
solarsail.skybox.regions.skybox[skybox_name] = skybox_name
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ solarsail.skybox.override_skybox(skybox_defs, cloud_defs, player)
|
||||||
|
|
||||||
|
API spec for temporarily overriding skyboxes:
|
||||||
|
|
||||||
|
skybox_defs table:
|
||||||
|
skybox_defs.textures = {"1", "2", "3", "4", "5", "6"}
|
||||||
|
skybox_defs.type = "regular", "bgcolor", "skybox"
|
||||||
|
skybox_defs.bgcolor = "#rrggbb"s
|
||||||
|
skybox_defs.clouds = true, false
|
||||||
|
|
||||||
|
cloud_defs table:
|
||||||
|
cloud_defs.density: 0 to 1
|
||||||
|
cloud_defs.color: "#rrggbbaa"
|
||||||
|
cloud_defs.ambient: "#rrggbb"
|
||||||
|
cloud_defs.height: -31000 to 31000
|
||||||
|
cloud_defs.thickness: 0.01 to 31000
|
||||||
|
cloud_defs.x = -128 to 128
|
||||||
|
cloud_defs.y = -128 to 128
|
||||||
|
|
||||||
|
player is a PlayerRef created by the Minetest Engine.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
function solarsail.skybox.override_skybox(skybox_defs, cloud_defs, player)
|
||||||
|
solarsail.skybox.is_paused = true
|
||||||
|
player:set_sky(
|
||||||
|
skybox_defs.bgcolor,
|
||||||
|
skybox_defs.type,
|
||||||
|
skybox_defs.textures,
|
||||||
|
skybox_defs.clouds
|
||||||
|
)
|
||||||
|
player:set_clouds({
|
||||||
|
density = cloud_defs.density,
|
||||||
|
color = cloud_defs.color,
|
||||||
|
ambient = cloud_defs.ambient,
|
||||||
|
height = cloud_defs.height,
|
||||||
|
thickness = cloud_defs.thickness,
|
||||||
|
speed = {x = cloud_defs.x, cloud_defs.y}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[ solarsail.skybox.restore_skybox()
|
||||||
|
Resume paused skybox functionality from overrides
|
||||||
|
]]--
|
||||||
|
|
||||||
|
function solarsail.skybox.restore_skybox()
|
||||||
|
solarsail.skybox.is_paused = false
|
||||||
|
solarsail_render_sky()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Simplified inbetween check:
|
||||||
|
|
||||||
|
local function inbetween(lower, upper, val)
|
||||||
|
if val >= lower and val <= upper then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Compare skybox settings against the new ones:
|
||||||
|
|
||||||
|
local function compare_sky(skybox_defs, one, two, three)
|
||||||
|
-- Compare bgcolor to supplied bgcolor:
|
||||||
|
local bgcolor = minetest.rgba(one.r, one.g, one.b)
|
||||||
|
if bgcolor ~= skybox_defs.bgcolor then return true end
|
||||||
|
|
||||||
|
-- Compare skybox types:
|
||||||
|
if two ~= skybox_defs.type then return true end
|
||||||
|
|
||||||
|
-- If we happen to be now using "skybox" do so here - otherwise we ignore it and flag it as changed
|
||||||
|
if skybox_defs.type == "skybox" and three == "skybox" then
|
||||||
|
for k, v in pairs(three) do
|
||||||
|
if v ~= skybox_defs.textures[k] then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false -- if somehow we get here by mistake
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Compare cloud settings against the new ones:
|
||||||
|
|
||||||
|
local function compare_clouds(cloud_defs, player_clouds) -- Speed of clouds aren't changed as they're considered a changing value, eg wind
|
||||||
|
-- Compare cloud densities:
|
||||||
|
if cloud_defs.density ~= player_clouds.density then return true end
|
||||||
|
|
||||||
|
-- Compare base color:
|
||||||
|
if cloud_defs.color ~= minetest.rgba(
|
||||||
|
player_clouds.color.r,
|
||||||
|
player_clouds.color.g,
|
||||||
|
player_clouds.color.b,
|
||||||
|
player_clouds.color.a
|
||||||
|
) then return true end
|
||||||
|
|
||||||
|
-- Compare "ambiance colour"
|
||||||
|
if cloud_defs.ambient ~= minetest.rgba(
|
||||||
|
player_clouds.ambient.r,
|
||||||
|
player_clouds.ambient.g,
|
||||||
|
player_clouds.ambient.b,
|
||||||
|
player_clouds.ambient.a
|
||||||
|
) then return true end
|
||||||
|
|
||||||
|
-- Compare height
|
||||||
|
if cloud_defs.height ~= player_clouds.height then return true end
|
||||||
|
|
||||||
|
-- Compare thiccness
|
||||||
|
if cloud_defs.thickness ~= player_clouds.thickness then return true end
|
||||||
|
|
||||||
|
return false -- if somehow none of these values are considered changed
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Change skybox for "connected players here":
|
||||||
|
|
||||||
|
local function solarsail_render_sky()
|
||||||
|
if solarsail.skybox.is_paused then
|
||||||
|
else
|
||||||
|
for _, player in ipairs(minetest.get_connected_players()) do
|
||||||
|
local ppos = player:get_pos()
|
||||||
|
local isx, isy, isz = false
|
||||||
|
-- Iterate over a table full of names
|
||||||
|
for k, v in pairs(solarsail.skybox.regions.skybox) do
|
||||||
|
if inbetween(solarsail.skybox.regions.pos_1[v].x, solarsail.skybox.regions.pos_2[v].x, ppos.x) then
|
||||||
|
isx = true
|
||||||
|
end
|
||||||
|
if inbetween(solarsail.skybox.regions.pos_1[v].y, solarsail.skybox.regions.pos_2[v].y, ppos.y) then
|
||||||
|
isy = true
|
||||||
|
end
|
||||||
|
if inbetween(solarsail.skybox.regions.pos_1[v].z, solarsail.skybox.regions.pos_2[v].z, ppos.z) then
|
||||||
|
isz = true
|
||||||
|
end
|
||||||
|
if isx and isy and isz then
|
||||||
|
local sky_1, sky_2, sky_3 = player:get_sky()
|
||||||
|
if compare_sky(solarsail.skybox.skybox_defs[v], sky_1, sky_2, sky_3) then
|
||||||
|
player:set_sky(
|
||||||
|
solarsail.skybox.skybox_defs[v].bgcolor,
|
||||||
|
solarsail.skybox.skybox_defs[v].type,
|
||||||
|
solarsail.skybox.skybox_defs[v].textures,
|
||||||
|
solarsail.skybox.skybox_defs[v].clouds
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if compare_clouds(solarsail.skybox.cloud_defs[v], player:get_clouds()) then
|
||||||
|
player:set_clouds({
|
||||||
|
density = solarsail.skybox.cloud_defs[v].density,
|
||||||
|
color = solarsail.skybox.cloud_defs[v].color,
|
||||||
|
ambient = solarsail.skybox.cloud_defs[v].ambient,
|
||||||
|
height = solarsail.skybox.cloud_defs[v].height,
|
||||||
|
thickness = solarsail.skybox.cloud_defs[v].thickness,
|
||||||
|
speed = {x = solarsail.skybox.cloud_defs[v].x, solarsail.skybox.cloud_defs[v].y}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
break
|
||||||
|
else
|
||||||
|
isx, isy, isz = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.after(0.1, solarsail_render_sky)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_count = 0
|
||||||
|
--[[
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
-- magic values to make comparisons work, as MT does not provide defaults
|
||||||
|
player:set_sky("#ffffff", "regular", {"eror.png"}, true)
|
||||||
|
solarsail_render_sky()
|
||||||
|
|
||||||
|
-- Prevent player handling freaking out; but this may change in future
|
||||||
|
player_count = player_count + 1
|
||||||
|
if player_count > 1 then
|
||||||
|
--minetest.kick_player(player:get_player_name(), "[SolarSail]: Singleplayer only, multiplayer disallowed.")
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
player_count = player_count - 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
solarsail.skybox.register_skybox("default",
|
||||||
|
{
|
||||||
|
-- ["top"] = "#676891", ["bottom"] = "#c79161", ["base"] = "#a17268", ["light"] = 0.15} sunrise = #ffae5f horizon = #404164
|
||||||
|
bgcolor = "#a17268",
|
||||||
|
type = "regular",
|
||||||
|
clouds = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
density = 0.34
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x = -31000,
|
||||||
|
y = -31000,
|
||||||
|
z = -31000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x = 31000,
|
||||||
|
y = 31000,
|
||||||
|
z = 31000
|
||||||
|
}
|
||||||
|
)
|
||||||
|
]]
|
||||||
|
|
||||||
|
local day_sky = "#c5b7ea"
|
||||||
|
local day_horizon = "#f0ecff"
|
||||||
|
local dawn_sky = "#bf9bb4"
|
||||||
|
local dawn_horizon = "#dec6d7"
|
||||||
|
local night_sky = "#030015"
|
||||||
|
local night_horizon = "#100033"
|
||||||
|
local sun_tint = "#dbbae7"
|
||||||
|
local moon_tint = "#d37dff"
|
||||||
|
|
||||||
|
local cloud_color = "#f3eaf8e7"
|
||||||
|
local star_color = "#c0c7ffaa"
|
||||||
|
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
player:set_sky({
|
||||||
|
type = "regular",
|
||||||
|
clouds = true,
|
||||||
|
sky_color = {
|
||||||
|
day_sky = day_sky,
|
||||||
|
day_horizon = day_horizon,
|
||||||
|
dawn_sky = dawn_sky,
|
||||||
|
dawn_horizon = dawn_horizon,
|
||||||
|
night_sky = night_sky,
|
||||||
|
night_horizon = night_horizon,
|
||||||
|
fog_sun_tint = sun_tint,
|
||||||
|
fog_moon_tint = moon_tint,
|
||||||
|
fog_tint_type = "custom"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
player:set_clouds({
|
||||||
|
color = cloud_color
|
||||||
|
})
|
||||||
|
|
||||||
|
player:set_stars({
|
||||||
|
count = 2000,
|
||||||
|
star_color = star_color,
|
||||||
|
scale = 0.65
|
||||||
|
})
|
||||||
|
end)
|
BIN
mods/solarsail/textures/solarsail_hsv_spectrum.png
Normal file
After Width: | Height: | Size: 240 B |
BIN
mods/solarsail/textures/solarsail_ui_gradient.png
Normal file
After Width: | Height: | Size: 221 B |
BIN
mods/solarsail/textures/solarsail_ui_gradient_flip.png
Normal file
After Width: | Height: | Size: 220 B |
BIN
mods/solarsail/textures/solarsail_wireframe.png
Normal file
After Width: | Height: | Size: 326 B |