Initial commit

fps_game
Jordan Snelling 2019-12-28 01:23:05 +00:00
commit 16a6fa8006
27 changed files with 648 additions and 0 deletions

30
.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
### macOS ###
*.DS_Store
.AppleDouble
.LSOverride
mods/test
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
.vs/slnx.sqlite
.vs

2
game.conf Normal file
View File

@ -0,0 +1,2 @@
name = SolarSail
disallowed_mapgens = v5,v6,carpathian,v7,fractal,valleys

BIN
menu/header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
menu/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
menu/intro_title.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

2
minetest.conf Normal file
View File

@ -0,0 +1,2 @@
time_speed = 4
dedicated_server_step = 0.03

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

121
mods/solarsail/hud.lua Normal file
View File

@ -0,0 +1,121 @@
-- SolarSail Engine HUD/UI Renderer:
-- Author: Jordach
-- License: Reserved
solarsail.hud.formspec = {}
solarsail.hud.theme = {}
solarsail.hud.active_chat = {}
solarsail.hud.active_chat.theme = {}
solarsail.hud.active_chat.message = {}
solarsail.hud.active_chat.name = {}
solarsail.hud.active_chat.portrait = {}
solarsail.hud.active_chat.formname = {}
--[[ solarsail.hud.render_chat(player_ref, state, hud_theme, portrait, name, message, formname):
API Spec for defining screen sized text boxes:
SolarSail uses a keyframe or timeline based theming system; in which it allows
multiple messages, characters and text box themes. In which it's designed so
that mods can just re-use solarsail.hud.render_chat() to update what's on
screen at any time, or when a formspec is received.
Use the whole arguments to set up a long conversation chain with if statements or loops.
Use solarsail.hud.render_chat(player_ref, state) to change the
state = 0 - 65535, controls what is displayed in the text box and portrait.
Textures and settings to define the appearance of the chat box and theming:
hud_theme.text_box[6] = "texture.png"
hud_theme.name_box[475] = "texture.png"
hud_theme.portrait_box[14] = "texture.png"
hud_theme.portrait_type[141] = (See below)
"retro", Behaves as a small square portrait at the right edge of the chat box.
"modern", Makes the portrait cover almost the entire screen, unstretched (not flipped)
"indie_left" Makes the portrait the same size as the text box, and sits on the left.
"indie_right" Does the above, but sits on the right edge.
portrait:
portrait[1] = "texture.png"
portrait[26] = "bacon.png"
name:
name[1] = "Some name"
name[76] = "someone""
message, see https://github.com/minetest/minetest/blob/master/doc/lua_api.txt#L2585 :
message[1] = "this is a single line message!"
message[26] = "multi\n line messages are also supported!"
message[38] = "test"
formname:
formname[4] = "mod_yourformname", used by minetest.register_on_player_receive_fields()
formname[7] = "mod_yourresponse", used by minetest.register_on_player_receive_fields()
--]]
function solarsail.hud.render_chat(player_ref, state, hud_theme, portrait, name, message, formname)
-- Keep a copy of last used in case of nil arguments
if hud_theme ~= nil then solarsail.hud.active_chat.theme[player_ref:get_player_name()] = hud_theme end
if message ~= nil then solarsail.hud.active_chat.message[player_ref:get_player_name()] = message end
if name ~= nil then solarsail.hud.active_chat.name[player_ref:get_player_name()] = name end
if portrait ~= nil then solarsail.hud.active_chat.portrait[player_ref:get_player_name()] = portrait end
if formname ~= nil then solarsail.hud.active_chat.formname[player_ref:get_player_name()] = formname end
-- Build initial formspec:
local formspec = "formspec_version[1]"..
"size[8, 2;false]"..
"position[0.5, 0.8]"..
"container[1.25,0]" ..
"bgcolor[#00000000;neither]"..
"real_coordinates[true]"
-- Decode theming:
if solarsail.hud.active_chat.theme[player_ref:get_player_name()] ~= nil then
if solarsail.hud.active_chat.theme[player_ref:get_player_name()].text_box[state] ~= nil then
formspec = formspec .. "background9[0, 1;8, 2;" ..
solarsail.hud.active_chat.theme[player_ref:get_player_name()].text_box[state] .. ";false;2,2]"
end
if solarsail.hud.active_chat.name[player_ref:get_player_name()][state] ~= nil then
if solarsail.hud.active_chat.theme[player_ref:get_player_name()].name_box[state] ~= nil then
formspec = formspec .. "background9[0.2, 0.4;2, 0.75;" ..
solarsail.hud.active_chat.theme[player_ref:get_player_name()].name_box[state] .. ";false;2,2]"
formspec = formspec .. "hypertext[0.2, 0.5;2, 1;solarsail_name;<global halign=justify valign=center><center><big>" ..
solarsail.hud.active_chat.name[player_ref:get_player_name()][state] .. "</big></center>]"
end
end
if solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_type[state] == "retro" then
if solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_box[state] ~= nil then
formspec = formspec .. "background9[7.1, 0.4;0.75, 0.75;"..
solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_box[state] ..";false;2,2]"
formspec = formspec .. "image[7.1, 0.4;0.75, 0.75;"..
solarsail.hud.active_chat.portrait[player_ref:get_player_name()][state] .."]"
end
elseif solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_type[state] == "indie_left" then
if solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_box[state] then
formspec = formspec .. "background9[-1.95, 1;2, 2;" ..
solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_box[state] .. ";false;2,2]"
formspec = formspec .. "image[-1.95, 1;2, 2;" ..
solarsail.hud.active_chat.portrait[player_ref:get_player_name()][state] .. "]"
end
elseif solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_type[state] == "indie_right" then
if solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_box[state] ~= nil then
formspec = formspec .. "background9[7.95, 1;2, 2;" ..
solarsail.hud.active_chat.theme[player_ref:get_player_name()].portrait_box[state] .. ";false;2,2]"
formspec = formspec .. "image[7.95, 1;2, 2;" ..
solarsail.hud.active_chat.portrait[player_ref:get_player_name()][state] .. "]"
end
end
end
-- Render hypertext chat to the main formspec
formspec = formspec .. "hypertext[0.15, 1.35;8, 2;solarsail_chat;" ..
minetest.formspec_escape(solarsail.hud.active_chat.message[player_ref:get_player_name()][state]) .."]"
minetest.show_formspec(
player_ref:get_player_name(),
solarsail.hud.active_chat.formname[player_ref:get_player_name()][state],
formspec .. "container_end[]"
)
end

63
mods/solarsail/init.lua Normal file
View File

@ -0,0 +1,63 @@
-- SolarSail Engine
-- Author: Jordach
-- License: Reserved
-- Primary Namespaces:
solarsail = {}
solarsail.skybox = {}
solarsail.camera = {}
solarsail.controls = {}
solarsail.player = {}
solarsail.npc = {}
solarsail.battle = {}
solarsail.hud = {}
solarsail.save_data = minetest.get_mod_storage()
solarsail.util = {}
solarsail.util.functions = {}
-- 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")
-- 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")
-- NPC functionality, chat systems;
--dofile(minetest.get_modpath("solarsail").."/npc.lua")
-- Player menus:
--dofile(minetest.get_modpath("solarsail").."/menu.lua")

Binary file not shown.

134
mods/solarsail/player.lua Normal file
View File

@ -0,0 +1,134 @@
-- 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()
local entity = minetest.add_entity(pos, model_name)
solarsail.player.model.entity_ref[player_ref:get_player_name()] = entity
-- 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
function solarsail.player.set_properties(player_ref, entity_properties)
solarsail.player.model.entity_ref[player_ref:get_player_name()]:set_properties()
end
-- 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 * -1, z * -1
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 + math.pi/2
if left then
nrads = rads - math.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)
local nx = x - 0
local nz = z - 0
return math.atan2(nz, nx)
end
-- Quickly convert degrees to radians:
function solarsail.util.functions.deg_to_rad(deg)
return deg * (3.142/180)
end

262
mods/solarsail/skybox.lua Normal file
View File

@ -0,0 +1,262 @@
-- 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_region(skybox_name, position_1, position_2)
API spec for changing the skybox based on position:
skybox_name = "name_of_skybox"
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_region(skybox_name, position_1, position_2)
solarsail.skybox.regions.pos_1[skybox_name] = position_1
solarsail.skybox.regions.pos_2[skybox_name] = position_2
solarsail.skybox.regions.skybox[skybox_name] = skybox_name
end
--[[ solarsail.skybox.register_skybox(skybox_name, skybox_defs, cloud_defs)
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
Note: Preferrably as game_skyboxname or mod_skyboxname
]]--
function solarsail.skybox.register_skybox(skybox_name, skybox_defs, cloud_defs)
solarsail.skybox.skybox_defs[skybox_name] = skybox_defs
solarsail.skybox.cloud_defs[skybox_name] = cloud_defs
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("paramat_theory",
{
bgcolor = {r = 0, g = 0, b = 0, a = 0},
type = "plain",
textures = {},
clouds = false
},
{}
)
solarsail.skybox.register_region("paramat_theory",
{
x = -31000,
y = -31000,
z = -31000
},
{
x = 31000,
y = 31000,
z = 31000
}
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B