Includes Changes such as:
First Exotic Class weapon: Minigun Changes to Energy/Magless weapon cooling. Brand new server introduction. Major HUD rework. Brand new auth handler. Modified default player physics. Clean up of code from init.lua to relevant files.fps_game
parent
8046c385fa
commit
795a0d6f6b
|
@ -1,10 +1,14 @@
|
|||
## Specially ignored directories:
|
||||
mods/test
|
||||
mods/weapons/sounds
|
||||
mods/persistence/db/weapons_player_auth.prs
|
||||
mods/persistence/db/weapons_player_data.prs
|
||||
|
||||
### macOS ###
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
mods/test
|
||||
mods/weapons/sounds
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
@ -28,4 +32,4 @@ Network Trash Folder
|
|||
Temporary Items
|
||||
.apdisk
|
||||
.vs/slnx.sqlite
|
||||
.vs
|
||||
.vs
|
||||
|
|
|
@ -6,4 +6,14 @@ active_object_send_range_blocks = 5
|
|||
active_block_range = 5
|
||||
ask_reconnect_on_crash = true
|
||||
player_transfer_distance = 128
|
||||
max_objects_per_block = 512
|
||||
max_objects_per_block = 512
|
||||
|
||||
movement_acceleration_default = 4.45
|
||||
movement_acceleration_air = 1.55
|
||||
movement_speed_walk = 5.25
|
||||
movement_speed_crouch = 0.95
|
||||
movement_speed_climb = 1.25
|
||||
movement_speed_jump = 7
|
||||
movement_liquid_fluidity = 0.65
|
||||
movement_liquid_fluidity_smooth = 0.75
|
||||
movement_liquid_sink = 0
|
|
@ -0,0 +1 @@
|
|||
This file is just to ensure Git properly includes this directory as Minetest will crash on attempting to access a non-existent folder.
|
|
@ -1 +0,0 @@
|
|||
return {["archfan"] = {["ammo_scale"] = 1, ["offsets"] = {["killfeed"] = {["y"] = 0, ["x"] = 0}, ["hp"] = {["y"] = 0, ["x"] = 0}, ["ammo"] = {["y"] = 0, ["x"] = 0}, ["score"] = {["y"] = 0, ["x"] = 0}}, ["hp_scale"] = 1, ["nick"] = "Gandalf"}, ["Emerald"] = {["ammo_scale"] = 1, ["offsets"] = {["killfeed"] = {["y"] = 0, ["x"] = 0}, ["hp"] = {["y"] = 0, ["x"] = 0}, ["ammo"] = {["y"] = 0, ["x"] = 0}, ["score"] = {["y"] = 0, ["x"] = 0}}, ["hp_scale"] = 1, ["nick"] = "Emerald"}, ["Jordach"] = {["ammo_scale"] = 1, ["offsets"] = {["killfeed"] = {["y"] = 0, ["x"] = 0}, ["hp"] = {["y"] = 0, ["x"] = 0}, ["ammo"] = {["y"] = 0, ["x"] = 0}, ["score"] = {["y"] = 0, ["x"] = 0}}, ["hp_scale"] = 1, ["nick"] = "NotJordach"}}
|
|
@ -18,52 +18,75 @@ solarsail.color = {}
|
|||
solarsail.util = {}
|
||||
solarsail.util.clipboard = {}
|
||||
solarsail.util.functions = {}
|
||||
solarsail.avg_dtime = 0
|
||||
solarsail.last_dtime = {}
|
||||
|
||||
-- Handle flat mapgen, for building a world
|
||||
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)))
|
||||
else
|
||||
dtime_steps = dtime_steps + 1
|
||||
solarsail.last_dtime[dtime_steps] = dtime
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_node("solarsail:wireframe", {
|
||||
description = "Wireframe, prototyping node",
|
||||
tiles = {"solarsail_wireframe.png"},
|
||||
groups = {debug=1}
|
||||
})
|
||||
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
|
||||
|
||||
--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")
|
|
@ -0,0 +1,106 @@
|
|||
-- Authentication module for Battle for Arkhos
|
||||
-- License RESERVED
|
||||
-- Author Jordach
|
||||
|
||||
weapons.auth = nil
|
||||
local sudo_invoked = false
|
||||
|
||||
local function rst_sudo()
|
||||
sudo_invoked = false
|
||||
end
|
||||
|
||||
local function grant_sudo_privs(name)
|
||||
-- Grants admins all privs for temporary reasons; these are not permanent.
|
||||
if name == minetest.settings:get("name") then
|
||||
local privs = {}
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
privs[priv] = true
|
||||
end
|
||||
sudo_invoked = true
|
||||
minetest.set_player_privs(name, privs)
|
||||
minetest.after(0.2, rst_sudo)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
if true then
|
||||
local loaded, wad, file_created = persistence.load_data("weapons_player_auth", true)
|
||||
weapons.auth = table.copy(wad)
|
||||
wad = nil
|
||||
end
|
||||
|
||||
weapons.auth_handler = {
|
||||
get_auth = function(name)
|
||||
-- I really doubt this as it's loaded from a persistence db; as it creates an empty table.
|
||||
if weapons.auth == nil then
|
||||
return nil
|
||||
elseif weapons.auth[name] == nil then
|
||||
return nil
|
||||
else
|
||||
return weapons.auth[name]
|
||||
end
|
||||
end,
|
||||
|
||||
create_auth = function(name, password)
|
||||
weapons.auth[name] = {}
|
||||
weapons.auth[name].password = password
|
||||
weapons.auth[name].privileges = {}
|
||||
weapons.auth[name].privileges.shout = true
|
||||
weapons.auth[name].privileges.interact = true
|
||||
weapons.auth[name].last_login = tonumber(os.time())
|
||||
persistence.save_data("weapons_player_auth", weapons.auth)
|
||||
end,
|
||||
|
||||
delete_auth = function(name)
|
||||
weapons.auth[name] = {}
|
||||
persistence.save_data("weapons_player_auth", weapons.auth)
|
||||
return true
|
||||
end,
|
||||
|
||||
set_password = function(name, password)
|
||||
weapons.auth[name].password = password
|
||||
persistence.save_data("weapons_player_auth", weapons.auth)
|
||||
return true
|
||||
end,
|
||||
|
||||
set_privileges = function(name, privileges)
|
||||
weapons.auth[name].privileges = privileges
|
||||
|
||||
if not sudo_invoked then
|
||||
persistence.save_data("weapons_player_auth", weapons.auth)
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
reload = function()
|
||||
return true
|
||||
end,
|
||||
|
||||
record_login = function(name)
|
||||
weapons.auth[name].last_login = tonumber(os.time())
|
||||
persistence.save_data("weapons_player_auth", weapons.auth)
|
||||
return true
|
||||
end,
|
||||
|
||||
iterate = function()
|
||||
return pairs(weapons.auth)
|
||||
end
|
||||
}
|
||||
|
||||
minetest.register_authentication_handler(weapons.auth_handler)
|
||||
minetest.log("action", "[Weapons] weapons/auth.lua registered and loaded authentication for world-persistent logins.")
|
||||
|
||||
minetest.register_chatcommand("sudo", {
|
||||
--params = "N/A",
|
||||
description = "Grants the username as defined in minetest.conf temporary admin privs.",
|
||||
func = function(name)
|
||||
if grant_sudo_privs(name) then
|
||||
minetest.log("warning", name .. " has been granted temporary privs.")
|
||||
return true, "Temporary admin and server privs granted. With great power, comes great responsibility."
|
||||
else
|
||||
minetest.log("warning", name .. " is not in the minetest.conf. This incident will be reported.")
|
||||
return false, weapons.get_nick(minetest.get_player_by_name(name)) .. " is not in the minetest.conf. This incident will be reported."
|
||||
end
|
||||
end,
|
||||
})
|
|
@ -81,8 +81,10 @@ local function conv_heat_to_rpm(weapon, player)
|
|||
local mult = weapon._accel_mult or 1
|
||||
if current_heat == nil then
|
||||
return 1
|
||||
elseif current_heat > 0 then
|
||||
return (current_heat/100) + mult
|
||||
elseif current_heat > 99 then
|
||||
return 1
|
||||
elseif current_heat < 100 then
|
||||
return solarsail.util.functions.remap(current_heat, 0, 100, 1, weapon._accel_mult)
|
||||
else
|
||||
return 1
|
||||
end
|
||||
|
|
|
@ -13,6 +13,72 @@ function weapons.get_nick(player)
|
|||
end
|
||||
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
|
||||
|
||||
--[[
|
||||
solarsail.util.functions.blend_colours()
|
||||
|
||||
val = Input Value
|
||||
min_val = Minimum value (values less than this are capped)
|
||||
max_val = Maximum value (values more than this are capped)
|
||||
min_col = ColorSpec defining the colour of the minimum value.
|
||||
returns a ColorSpec blended or capped as one of the two input colours.
|
||||
]]--
|
||||
|
||||
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
|
||||
|
|
|
@ -112,7 +112,8 @@ local function get_ammo_appearances(player, weapon)
|
|||
local over_string = "hud_bar_overlay.png^[opacity:127"
|
||||
local weapon = minetest.registered_nodes[player:get_wielded_item():get_name()]
|
||||
local is_thermal = false
|
||||
if weapon._is_energy == nil then
|
||||
if weapon == nil then
|
||||
elseif weapon._is_energy == nil then
|
||||
elseif weapon._is_energy then
|
||||
is_thermal = true
|
||||
end
|
||||
|
|
|
@ -19,7 +19,10 @@ if true then
|
|||
wpd = nil
|
||||
end
|
||||
|
||||
-- Special, load the additions to the solarsail global before anything else.
|
||||
-- Handle world persistent login as we delete worlds between games.
|
||||
dofile(minetest.get_modpath("weapons").."/auth.lua")
|
||||
|
||||
-- Special usecase, load the additions to the solarsail global before anything else.
|
||||
-- Ideally, this should be at the bottom with the others, but we make do.
|
||||
dofile(minetest.get_modpath("weapons").."/functions.lua")
|
||||
|
||||
|
@ -71,7 +74,7 @@ end
|
|||
function core.send_leave_message(player_name, timed_out)
|
||||
local msg = weapons.team_colourize(minetest.get_player_by_name(player_name), weapons.player_data[player_name].nick) .. " left the game"
|
||||
if timed_out then
|
||||
msg = msg .. ", due to network error."
|
||||
msg = msg .. ", due to network interruption or error."
|
||||
else
|
||||
msg = msg .. "."
|
||||
end
|
||||
|
@ -102,9 +105,41 @@ function core.get_server_status(player_name, joined)
|
|||
if num < #nplayers then
|
||||
status = status .. weapons.team_colourize(nplayers[num].user, nplayers[num].nick) .. ", "
|
||||
else
|
||||
status = status .. weapons.team_colourize(nplayers[num].user, nplayers[num].nick) .. "."
|
||||
status = status .. weapons.team_colourize(nplayers[num].user, nplayers[num].nick) .. ".\n"
|
||||
end
|
||||
end
|
||||
|
||||
if solarsail.avg_dtime == nil or solarsail.avg_dtime == 0 then
|
||||
local _chance = math.random(1, 100)
|
||||
local _msg = "Excuse me, but why are you launching the server as a client?"
|
||||
print(_chance)
|
||||
if _chance < 11 then
|
||||
-- https://discord.com/channels/369122544273588224/369122544273588226/807084993854701608
|
||||
-- From @ElCeejus
|
||||
_msg = "Excuse me bruv? Why are yeh laoonching Minetaest hes a client yeh? Kinda schtewpid innit?"
|
||||
end
|
||||
status = status .. minetest.colorize("#ff0000", _msg)
|
||||
else
|
||||
status = status .. "Average Server Lag: " ..
|
||||
minetest.colorize(
|
||||
solarsail.util.functions.blend_colours(
|
||||
solarsail.avg_dtime,
|
||||
0.03,
|
||||
0.12,
|
||||
"#00ff00",
|
||||
"#ff0000"
|
||||
),
|
||||
string.format("%.2f", tostring(solarsail.avg_dtime)) .. "s"
|
||||
)
|
||||
end
|
||||
|
||||
if weapons.auth[player_name] == nil then
|
||||
elseif weapons.auth[player_name].last_login == nil then
|
||||
else
|
||||
local date = os.date("%Y/%m/%d %H:%M:%S", weapons.auth[player_name].last_login)
|
||||
status = status .. "\nLast Join: " ..
|
||||
minetest.colorize(weapons.teams.no_team, date)
|
||||
end
|
||||
return status
|
||||
end
|
||||
|
||||
|
@ -297,9 +332,11 @@ dofile(minetest.get_modpath("weapons").."/weapons/blocks.lua")
|
|||
dofile(minetest.get_modpath("weapons").."/weapons/assault_rifle.lua")
|
||||
dofile(minetest.get_modpath("weapons").."/weapons/burst_rifle.lua")
|
||||
dofile(minetest.get_modpath("weapons").."/weapons/sniper_rifle.lua")
|
||||
dofile(minetest.get_modpath("weapons").."/weapons/scout_rifle.lua")
|
||||
dofile(minetest.get_modpath("weapons").."/weapons/veteran_rifle.lua")
|
||||
dofile(minetest.get_modpath("weapons").."/weapons/auto_shotgun.lua")
|
||||
dofile(minetest.get_modpath("weapons").."/weapons/plasma_autorifle.lua")
|
||||
dofile(minetest.get_modpath("weapons").."/weapons/light_machine_gun.lua")
|
||||
dofile(minetest.get_modpath("weapons").."/weapons/minigun.lua")
|
||||
|
||||
--dofile(minetest.get_modpath("weapons").."/weapons/railgun.lua")
|
||||
--dofile(minetest.get_modpath("weapons").."/weapons/smg.lua")
|
||||
|
|
|
@ -48,7 +48,9 @@ base_class.items = {
|
|||
"weapons:sniper_rifle",
|
||||
"weapons:veteran_rifle",
|
||||
"weapons:pump_shotgun",
|
||||
"weapons:light_machine_gun",
|
||||
"weapons:plasma_autorifle",
|
||||
"weapons:minigun",
|
||||
"weapons:pickaxe",
|
||||
"core:team_neutral"
|
||||
}
|
||||
|
|
|
@ -509,7 +509,7 @@ minetest.register_globalstep(function(dtime)
|
|||
elseif weapon._is_energy then
|
||||
local ammo = weapon._ammo_type
|
||||
if not solarsail.controls.player[pname].LMB then
|
||||
if player_cooldown_timer[pname] > 0.06 then
|
||||
if player_cooldown_timer[pname] > weapon._cool_timer then
|
||||
local cng = math.floor(weapons.player_list[pname][ammo] * weapon._cool_rate) - 1
|
||||
if cng < 0 then cng = 0 end
|
||||
weapons.player_list[pname][ammo] = cng
|
||||
|
@ -518,7 +518,7 @@ minetest.register_globalstep(function(dtime)
|
|||
player_cooldown_timer[pname] = player_cooldown_timer[pname] + dtime
|
||||
end
|
||||
elseif weapons.is_reloading[pname][player:get_wielded_item():get_name()] then
|
||||
if player_cooldown_timer[pname] > 0.06 then
|
||||
if player_cooldown_timer[pname] > weapon._cool_timer then
|
||||
local cng = math.floor(weapons.player_list[pname][ammo] * weapon._cool_rate) - 1
|
||||
if cng < 0 then cng = 0 end
|
||||
weapons.player_list[pname][ammo] = cng
|
||||
|
|
|
@ -164,7 +164,7 @@ Range 150 nodes.]],
|
|||
_spread_aim = 0.5,
|
||||
|
||||
_break_hits = 2,
|
||||
_block_chance = 50,
|
||||
_block_chance = 85,
|
||||
|
||||
-- Arm Animations + Arm visual settings;
|
||||
_anim = {
|
||||
|
|
|
@ -81,7 +81,7 @@ Range 150 nodes.]],
|
|||
_spread_aim = 0.5,
|
||||
|
||||
_break_hits = 2,
|
||||
_block_chance = 50,
|
||||
_block_chance = 75,
|
||||
|
||||
-- Arm Animations + Arm visual settings;
|
||||
_anim = {
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
local function add_extras(player)
|
||||
local ldir = player:get_look_dir()
|
||||
local ppos = vector.add(player:get_pos(), vector.new(0, 1.2+ldir.y/3.5, 0))
|
||||
|
||||
local px, pz = solarsail.util.functions.yaw_to_vec(player:get_look_horizontal(), 1, false)
|
||||
ppos = vector.add(ppos, vector.multiply(vector.new(px, 0, pz), 0.225))
|
||||
local dir = vector.new(pz, 0, -px)
|
||||
local res = vector.add(ppos, vector.multiply(dir, 0.25))
|
||||
|
||||
local ent = minetest.add_entity(res, "weapons:ar_casing")
|
||||
local pvel = player:get_velocity()
|
||||
pvel.x = pvel.x/2
|
||||
pvel.y = pvel.y/2
|
||||
pvel.z = pvel.z/2
|
||||
local vel = vector.multiply(vector.new(pz/1.5, ldir.y+1, -px/1.5), 3)
|
||||
vel = vector.add(vel, vector.new(math.random(-25, 25)/100, 0, math.random(-25, 25)/100))
|
||||
ent:set_acceleration({x=0, y=-9.80, z=0})
|
||||
ent:set_velocity(vector.add(pvel, vel))
|
||||
end
|
||||
|
||||
local wep_rpm = 420
|
||||
local shots_used = 1
|
||||
|
||||
weapons.register_weapon("weapons:light_machine_gun", true,
|
||||
{
|
||||
-- Config
|
||||
_type = "gun",
|
||||
_ammo_type = "lmg",
|
||||
_slot = "primary",
|
||||
_localisation = {
|
||||
itemstring = "weapons:light_machine_gun",
|
||||
name = "Light Machine Gun",
|
||||
tooltip =
|
||||
[[A light machine gun. Good at suppressive fire.
|
||||
|
||||
Stats:
|
||||
|
||||
20 Damage.
|
||||
6.65 second reload.
|
||||
Unaimed spread +- 15 nodes at maximum range.
|
||||
Aimed spread +- 2 nodes at maximum range.
|
||||
Range 125 nodes.]],
|
||||
},
|
||||
|
||||
-- HUD / Visual
|
||||
_tracer = "ar",
|
||||
_name = "light_machine_gun",
|
||||
_crosshair = "assault_crosshair.png",
|
||||
_crosshair_aim = "assault_crosshair.png",
|
||||
_fov_mult = 0,
|
||||
_fov_mult_aim = 0.6,
|
||||
_min_arm_angle = -45,
|
||||
_max_arm_angle = 75,
|
||||
_arm_angle_offset = 0,
|
||||
-- Sounds
|
||||
_firing_sound = "ass_rifle_fire",
|
||||
_reload_sound = "ass_rifle_reload",
|
||||
_casing = "Armature_Casing",
|
||||
|
||||
-- Base Stats:
|
||||
_pellets = 1,
|
||||
_mag = 100,
|
||||
_rpm = wep_rpm,
|
||||
_reload = 6.65,
|
||||
_speed = 1200,
|
||||
_range = 125,
|
||||
_damage = 10,
|
||||
_movespeed = 0.95,
|
||||
_movespeed_aim = 0.45,
|
||||
_shots_used = shots_used,
|
||||
|
||||
_recoil = 1.5,
|
||||
_recoil_vert_min = 2,
|
||||
_recoil_vert_max = 4.25,
|
||||
_recoil_hori = 6,
|
||||
_recoil_factor = 0.8,
|
||||
_recoil_aim_factor = 0.5,
|
||||
|
||||
_spread = 15,
|
||||
_spread_aim = 2,
|
||||
|
||||
_break_hits = 1,
|
||||
_block_chance = 90,
|
||||
|
||||
-- Arm Animations + Arm visual settings;
|
||||
_anim = {
|
||||
idle = {x=0, y=0},
|
||||
idle_fire = {x=0, y=8},
|
||||
aim = {x=10, y=10},
|
||||
aim_fire = {x=10, y=18},
|
||||
reload = {x=60, y=219}
|
||||
},
|
||||
_arms = {
|
||||
mesh = "assault_arms.x",
|
||||
texture = "assault_rifle.png",
|
||||
},
|
||||
on_fire = weapons.raycast_bullet,
|
||||
on_fire_visual = add_extras,
|
||||
on_reload = weapons.magazine_reload,
|
||||
bullet_on_hit = weapons.bullet_on_hit,
|
||||
})
|
|
@ -0,0 +1,254 @@
|
|||
function apply_recoil(player, weapon, ammo)
|
||||
local pname = player:get_player_name()
|
||||
local yaw_rad = player:get_look_horizontal()
|
||||
local pitch_rad = player:get_look_vertical()
|
||||
-- Physical knockback; can be canceled out
|
||||
local result_x, result_z =
|
||||
solarsail.util.functions.yaw_to_vec(yaw_rad, weapon._recoil, true)
|
||||
local result_y =
|
||||
solarsail.util.functions.y_direction(pitch_rad, weapon._recoil)
|
||||
local pitch_mult = solarsail.util.functions.xz_amount(pitch_rad)
|
||||
player:add_velocity({
|
||||
x=result_x * pitch_mult,
|
||||
y=result_y,
|
||||
z=result_z * pitch_mult
|
||||
})
|
||||
|
||||
-- Camera recoil; cannot be canceled out
|
||||
local vert_deg, hori_deg, look_pitch, look_hori = 0
|
||||
local pammo = weapons.player_list[pname][ammo]
|
||||
local vert_curve =
|
||||
solarsail.util.functions.remap(pammo, 0, 100, weapon._recoil_vert_min, weapon._recoil_vert_max)
|
||||
local hori_curve =
|
||||
solarsail.util.functions.remap(pammo, 0, 100, weapon._recoil_hori, weapon._recoil_hori_max)
|
||||
|
||||
if math.random(0, 1) == 1 then
|
||||
hori_curve = -hori_curve
|
||||
end
|
||||
|
||||
-- Handle aiming
|
||||
local pname = player:get_player_name()
|
||||
if weapons.player_list[pname].aim_mode then
|
||||
look_pitch = player:get_look_vertical() + (math.rad(-vert_curve) * weapon._recoil_aim_factor)
|
||||
look_hori = player:get_look_horizontal() + (math.rad(hori_curve) * weapon._recoil_aim_factor)
|
||||
else
|
||||
look_pitch = player:get_look_vertical() + (math.rad(-vert_curve) * weapon._recoil_factor)
|
||||
look_hori = player:get_look_horizontal() + (math.rad(hori_curve) * weapon._recoil_factor)
|
||||
end
|
||||
player:set_look_vertical(look_pitch)
|
||||
player:set_look_horizontal(look_hori)
|
||||
end
|
||||
|
||||
|
||||
function raycast_minigun(player, weapon)
|
||||
local wield = player:get_wielded_item():get_name()
|
||||
local pname = player:get_player_name()
|
||||
local ammo = weapon._ammo_type
|
||||
|
||||
if weapons.player_list[pname][ammo] < 101 then -- Ensure there's actually bullets in the mag/chamber
|
||||
minetest.sound_play({name=weapon._firing_sound},
|
||||
{pos=player:get_pos(), max_hear_distance=128, gain=1.75, pitch=math.random(95, 105)/100})
|
||||
|
||||
if weapon.on_fire_visual == nil then
|
||||
else
|
||||
weapon.on_fire_visual(player)
|
||||
end
|
||||
|
||||
for i=1, weapon._pellets do
|
||||
-- Ray calculations.
|
||||
local raybegin = vector.add(player:get_pos(), {x=0, y=weapons.default_eye_height, z=0})
|
||||
local raygunbegin = vector.add(player:get_pos(), {x=0, y=1.2, z=0})
|
||||
local vec_x, vec_y, vec_z = 0
|
||||
|
||||
local _spread = solarsail.util.functions.remap(weapons.player_list[pname][ammo], 0, 100, weapon._spread, weapon._spread_max)
|
||||
local _spread_aim = solarsail.util.functions.remap(weapons.player_list[pname][ammo], 0, 100, weapon._spread_aim, weapon._spread_aim_max)
|
||||
|
||||
-- Handle aiming
|
||||
if weapons.player_list[pname].aim_mode then
|
||||
vec_x = math.random(-_spread_aim * 100, _spread_aim * 100) / 100
|
||||
vec_y = math.random(-_spread_aim * 100, _spread_aim * 100) / 100
|
||||
vec_z = math.random(-_spread_aim * 100, _spread_aim * 100) / 100
|
||||
else
|
||||
vec_x = math.random(-_spread * 100, _spread * 100) / 100
|
||||
vec_y = math.random(-_spread * 100, _spread * 100) / 100
|
||||
vec_z = math.random(-_spread * 100, _spread * 100) / 100
|
||||
end
|
||||
local aim_mod = {x=vec_x, y=vec_y, z=vec_z}
|
||||
local raymod = vector.add(
|
||||
vector.multiply(player:get_look_dir(), weapon._range), aim_mod
|
||||
)
|
||||
local rayend = vector.add(raybegin, raymod)
|
||||
local ray = minetest.raycast(raybegin, rayend, true, false)
|
||||
local pointed = ray:next()
|
||||
pointed = ray:next()
|
||||
local target_pos
|
||||
|
||||
if weapon._tracer == nil then
|
||||
else
|
||||
local tracer_pos = vector.add(
|
||||
vector.add(player:get_pos(), vector.new(0, 1.2, 0)),
|
||||
vector.multiply(player:get_look_dir(), 1)
|
||||
)
|
||||
local yp = solarsail.util.functions.y_direction(player:get_look_vertical(), 20)
|
||||
local px, pz = solarsail.util.functions.yaw_to_vec(player:get_look_horizontal(), 20, false)
|
||||
local pv = vector.add(raybegin, {x=px, y=yp, z=pz})
|
||||
local pr = vector.add(pv, raymod)
|
||||
|
||||
local tracer_vel = vector.add(
|
||||
vector.multiply(vector.direction(pv, pr), 120),
|
||||
vector.new(0, 0.44, 0)
|
||||
)
|
||||
|
||||
local xz, y = solarsail.util.functions.get_3d_angles(
|
||||
vector.add(player:get_pos(), vector.new(0, weapons.default_eye_height, 0)),
|
||||
vector.add(tracer_pos, tracer_vel)
|
||||
)
|
||||
|
||||
local ent = minetest.add_entity(tracer_pos,
|
||||
"weapons:tracer_" .. weapon._tracer)
|
||||
|
||||
ent:set_velocity(tracer_vel)
|
||||
ent:set_rotation(vector.new(y, xz, 0))
|
||||
end
|
||||
|
||||
if pointed == nil then
|
||||
else
|
||||
-- Handle target;
|
||||
if pointed.type == "object" then
|
||||
target_pos = pointed.ref:get_pos()
|
||||
else
|
||||
target_pos = pointed.under
|
||||
end
|
||||
end
|
||||
|
||||
-- Calculate time to target and distance to target;
|
||||
if target_pos == nil then
|
||||
else
|
||||
local dist = solarsail.util.functions.pos_to_dist(raybegin, target_pos)
|
||||
|
||||
minetest.after(dist/weapon._speed, weapon.bullet_on_hit, pointed, player,
|
||||
weapon, target_pos, dist)
|
||||
end
|
||||
end
|
||||
-- Handle recoil of the equipped weapon
|
||||
apply_recoil(player, weapon, ammo)
|
||||
|
||||
local res = 1
|
||||
weapons.player_list[pname][ammo] = weapons.player_list[pname][ammo] + res
|
||||
if weapons.player_list[pname][ammo] > 100 then
|
||||
weapons.player_list[pname][ammo] = 100
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
local function add_extras(player)
|
||||
local ldir = player:get_look_dir()
|
||||
local ppos = vector.add(player:get_pos(), vector.new(0, 1.2+ldir.y/3.5, 0))
|
||||
|
||||
local px, pz = solarsail.util.functions.yaw_to_vec(player:get_look_horizontal(), 1, false)
|
||||
ppos = vector.add(ppos, vector.multiply(vector.new(px, 0, pz), 0.225))
|
||||
local dir = vector.new(pz, 0, -px)
|
||||
local res = vector.add(ppos, vector.multiply(dir, 0.25))
|
||||
|
||||
local ent = minetest.add_entity(res, "weapons:ar_casing")
|
||||
local pvel = player:get_velocity()
|
||||
pvel.x = pvel.x/2
|
||||
pvel.y = pvel.y/2
|
||||
pvel.z = pvel.z/2
|
||||
local vel = vector.multiply(vector.new(pz/1.5, ldir.y+1, -px/1.5), 3)
|
||||
vel = vector.add(vel, vector.new(math.random(-25, 25)/100, 0, math.random(-25, 25)/100))
|
||||
ent:set_acceleration({x=0, y=-9.80, z=0})
|
||||
ent:set_velocity(vector.add(pvel, vel))
|
||||
end
|
||||
|
||||
local wep_rpm = 125
|
||||
local shots_used = 1
|
||||
|
||||
weapons.register_weapon("weapons:minigun", true,
|
||||
{
|
||||
-- Config
|
||||
_type = "gun",
|
||||
_ammo_type = "minigun",
|
||||
_is_energy = true,
|
||||
_heat_accelerated = true,
|
||||
_accel_mult = 16,
|
||||
_cool_rate = 1,
|
||||
_cool_timer = 0.325,
|
||||
_slot = "primary",
|
||||
_localisation = {
|
||||
itemstring = "weapons:minigun",
|
||||
name = "Minigun",
|
||||
tooltip =
|
||||
[[A Minigun.
|
||||
Nothing saturates a target better.
|
||||
Stats:
|
||||
|
||||
10 Damage.
|
||||
Infinite Ammo!.
|
||||
Unaimed spread +- 8 nodes at maximum range.
|
||||
Aimed spread +- 1 nodes at maximum range.
|
||||
Range 125 nodes.]],
|
||||
},
|
||||
|
||||
-- HUD / Visual
|
||||
_tracer = "ar",
|
||||
_name = "minigun",
|
||||
_crosshair = "shotgun_crosshair.png",
|
||||
_crosshair_aim = "assault_crosshair.png",
|
||||
_fov_mult = 0,
|
||||
_fov_mult_aim = 0.9,
|
||||
_min_arm_angle = -45,
|
||||
_max_arm_angle = 75,
|
||||
_arm_angle_offset = 0,
|
||||
-- Sounds
|
||||
_firing_sound = "ass_rifle_fire",
|
||||
_reload_sound = "ass_rifle_reload",
|
||||
_casing = "Armature_Casing",
|
||||
|
||||
-- Base Stats:
|
||||
_pellets = 1,
|
||||
_mag = 0,
|
||||
_rpm = wep_rpm,
|
||||
_reload = 6.65,
|
||||
_speed = 1200,
|
||||
_range = 125,
|
||||
_damage = 10,
|
||||
_movespeed = 0.95,
|
||||
_movespeed_aim = 0.45,
|
||||
_shots_used = shots_used,
|
||||
|
||||
_recoil = 1.5,
|
||||
_recoil_vert_min = 0.2,
|
||||
_recoil_vert_max = 3.5,
|
||||
_recoil_hori = 0.2,
|
||||
_recoil_hori_max = 5.5,
|
||||
_recoil_factor = 0.8,
|
||||
_recoil_aim_factor = 0.5,
|
||||
|
||||
_spread = 4.5,
|
||||
_spread_max = 14,
|
||||
_spread_aim = 0.25,
|
||||
_spread_aim_max = 4.5,
|
||||
|
||||
_break_hits = 1,
|
||||
_block_chance = 55,
|
||||
|
||||
-- Arm Animations + Arm visual settings;
|
||||
_anim = {
|
||||
idle = {x=0, y=0},
|
||||
idle_fire = {x=0, y=8},
|
||||
aim = {x=10, y=10},
|
||||
aim_fire = {x=10, y=18},
|
||||
reload = {x=60, y=219}
|
||||
},
|
||||
_arms = {
|
||||
mesh = "assault_arms.x",
|
||||
texture = "assault_rifle.png",
|
||||
},
|
||||
on_fire = raycast_minigun,
|
||||
on_fire_visual = add_extras,
|
||||
on_reload = weapons.energy_overheat,
|
||||
bullet_on_hit = weapons.bullet_on_hit,
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
local wep_rpm = 400
|
||||
local wep_rpm = 325
|
||||
local shots_used = 1
|
||||
|
||||
local plas_ent = {
|
||||
|
@ -19,40 +19,19 @@ local plas_ent = {
|
|||
local function dmg_block(pos, weapon)
|
||||
local damage, node, result =
|
||||
weapons.calc_block_damage(minetest.registered_nodes[minetest.get_node(pos).name], weapon, pos)
|
||||
minetest.set_node(pos, {name=node})
|
||||
local p2 = minetest.get_node(pos).param2
|
||||
minetest.set_node(pos, {name=node, param2=p2})
|
||||
end
|
||||
|
||||
function plas_ent:collide(self, moveresult)
|
||||
local pos = self.object:get_pos()
|
||||
--[[
|
||||
|
||||
local pos_block
|
||||
if moveresult.collisions[1] == nil then
|
||||
pos_block = table.copy(self.object:get_pos())
|
||||
pos_block.x = math.floor(pos_block.x)
|
||||
pos_block.y = math.floor(pos_block.y)
|
||||
pos_block.z = math.floor(pos_block.z)
|
||||
elseif moveresult.collisions[1].type == "object" then
|
||||
if moveresult.collisions[1].object:get_pos() ~= nil then
|
||||
pos_block = table.copy(moveresult.collisions[1].object:get_pos())
|
||||
pos_block.x = math.floor(pos_block.x)
|
||||
pos_block.y = math.floor(pos_block.y)
|
||||
pos_block.z = math.floor(pos_block.z)
|
||||
else
|
||||
pos_block = table.copy(pos)
|
||||
pos_block.x = math.floor(pos_block.x)
|
||||
pos_block.y = math.floor(pos_block.y)
|
||||
pos_block.z = math.floor(pos_block.z)
|
||||
end
|
||||
elseif moveresult.collisions[1].type == "node" then
|
||||
pos_block = table.copy(moveresult.collisions[1].node_pos)
|
||||
else
|
||||
pos_block = table.copy(pos)
|
||||
pos_block.x = math.floor(pos_block.x)
|
||||
pos_block.y = math.floor(pos_block.y)
|
||||
pos_block.z = math.floor(pos_block.z)
|
||||
dmg_block(pos_block, minetest.registered_nodes["weapons:plasma_autorifle"])
|
||||
end
|
||||
|
||||
]]
|
||||
|
||||
if self._player_ref == nil then
|
||||
self.object:remove()
|
||||
|
@ -60,7 +39,6 @@ function plas_ent:collide(self, moveresult)
|
|||
end
|
||||
|
||||
local weapon = minetest.registered_nodes["weapons:plasma_autorifle"]
|
||||
--dmg_block(pos_block, weapon)
|
||||
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
local ppos = player:get_pos()
|
||||
|
@ -152,8 +130,9 @@ weapons.register_weapon("weapons:plasma_autorifle", true,
|
|||
_ammo_type = "plasma_autorifle",
|
||||
_is_energy = true,
|
||||
_heat_accelerated = true,
|
||||
_accel_mult = 1.75,
|
||||
_accel_mult = 3.5,
|
||||
_cool_rate = 0.95,
|
||||
_cool_timer = 0.075,
|
||||
_slot = "primary",
|
||||
_localisation = {
|
||||
itemstring = "weapons:plasma_autorifle",
|
||||
|
@ -202,6 +181,8 @@ Range 150 nodes.]],
|
|||
_recoil_factor = 0.8/1.5,
|
||||
_recoil_aim_factor = 0.5/1.5,
|
||||
|
||||
_break_hits = 1,
|
||||
_block_chance = 75,
|
||||
_spread = 6.5,
|
||||
_spread_aim = 0.5,
|
||||
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
weapons.register_weapon("weapons:shotgun",
|
||||
{
|
||||
drawtype = "mesh",
|
||||
mesh = "shotgun_fp.b3d",
|
||||
range = 1,
|
||||
|
||||
_ammo_bg = "shotgun_bg",
|
||||
_ammo_type = "primary",
|
||||
_kf_name = "Shotgun",
|
||||
_alt_mode = "weapons:shotgun_alt",
|
||||
_fov_mult = 0,
|
||||
_crosshair = "shotgun_crosshair.png",
|
||||
_type = "gun",
|
||||
_firing_sound = "shotgun_fire",
|
||||
_casing_sound = "shotgun_casing",
|
||||
_reload_sound = "shotgun_reload",
|
||||
_tp_model = "shotgun_tp.x",
|
||||
_name = "shotgun",
|
||||
_pellets = 16,
|
||||
_mag = 2,
|
||||
_rpm = 225,
|
||||
_reload = 3.75,
|
||||
_reload_node = "weapons:shotgun_reload",
|
||||
_speed = 750,
|
||||
_range = 150,
|
||||
_damage = 7,
|
||||
_break_hits = 1,
|
||||
_recoil = 14,
|
||||
_spread_min = -14,
|
||||
_spread_max = 14,
|
||||
_tracer = "shotgun",
|
||||
_phys_alt = 1,
|
||||
on_fire = weapons.raycast_bullet,
|
||||
bullet_on_hit = weapons.bullet_on_hit,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
return itemstack
|
||||
end,
|
||||
on_drop = function(itemstack, dropper, pointed_thing)
|
||||
return itemstack
|
||||
end
|
||||
},
|
||||
{
|
||||
drawtype = "mesh",
|
||||
mesh = "shotgun_alt_fp.b3d",
|
||||
range = 1,
|
||||
|
||||
_ammo_bg = "shotgun_bg",
|
||||
_ammo_type = "primary",
|
||||
_kf_name = "Shotgun",
|
||||
_alt_mode = "weapons:shotgun",
|
||||
_fov_mult = 0.925,
|
||||
_crosshair = "shotgun_crosshair.png",
|
||||
_type = "gun",
|
||||
_firing_sound = "shotgun_fire",
|
||||
_casing_sound = "shotgun_casing",
|
||||
_reload_sound = "shotgun_reload",
|
||||
_tp_model = "shotgun_tp.x",
|
||||
_name = "shotgun",
|
||||
_pellets = 16,
|
||||
_mag = 2,
|
||||
_rpm = 225,
|
||||
_reload = 3.75,
|
||||
_reload_node = "weapons:shotgun_reload",
|
||||
_speed = 750,
|
||||
_range = 150,
|
||||
_damage = 7,
|
||||
_break_hits = 1,
|
||||
_recoil = 10,
|
||||
_spread_min = -11,
|
||||
_spread_max = 11,
|
||||
_tracer = "shotgun",
|
||||
_phys_alt = 0.45,
|
||||
_is_alt = true,
|
||||
|
||||
on_fire = weapons.raycast_bullet,
|
||||
bullet_on_hit = weapons.bullet_on_hit,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
return itemstack
|
||||
end,
|
||||
on_drop = function(itemstack, dropper, pointed_thing)
|
||||
return itemstack
|
||||
end
|
||||
},
|
||||
{
|
||||
drawtype = "mesh",
|
||||
mesh = "shotgun_reload_fp.b3d",
|
||||
use_texture_alpha = true,
|
||||
range = 1,
|
||||
|
||||
_ammo_bg = "shotgun_bg",
|
||||
_ammo_type = "primary",
|
||||
_kf_name = "Shotgun",
|
||||
_damage = 6,
|
||||
_tp_model = "shotgun_tp.x",
|
||||
_reset_node = "weapons:shotgun",
|
||||
_mag = 2,
|
||||
_fov_mult = 0,
|
||||
_type = "gun",
|
||||
_phys_alt = 0.7,
|
||||
|
||||
on_fire = weapons.raycast_bullet,
|
||||
bullet_on_hit = weapons.bullet_on_hit,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
return itemstack
|
||||
end,
|
||||
on_drop = function(itemstack, dropper, pointed_thing)
|
||||
return itemstack
|
||||
end
|
||||
},
|
||||
"shotgun.png", "scout_class")
|
|
@ -60,8 +60,8 @@ Range 200 nodes.]],
|
|||
_spread = 25,
|
||||
_spread_aim = 0,
|
||||
|
||||
_break_hits = 2,
|
||||
_block_chance = 85,
|
||||
_break_hits = 4,
|
||||
_block_chance = 100,
|
||||
|
||||
-- Arm Animations + Arm visual settings;
|
||||
_anim = {
|
||||
|
|
Loading…
Reference in New Issue