228 lines
9.3 KiB
Lua
228 lines
9.3 KiB
Lua
local Vec = vector
|
|
Guns4d = {
|
|
players = {},
|
|
handler_by_ObjRef = {},
|
|
gun_by_ObjRef = {} --used for getting the gun object by the ObjRef of the gun
|
|
}
|
|
--default config values, config will be added soon:tm:
|
|
Guns4d.config = {
|
|
show_mag_inv_ammo_bar = true,
|
|
show_mag_inv_ammo_count = true,
|
|
show_gun_inv_ammo_count = true,
|
|
control_hybrid_toggle_threshold = .3,
|
|
control_held_toggle_threshold = 0,
|
|
empty_symbol = "E",
|
|
default_damage_group = "fleshy",
|
|
infinite_ammo_priv = "guns4d_infinite_ammo",
|
|
interpret_initial_wear_as_ammo = false,
|
|
punch_from_player_not_gun = true,
|
|
vertical_rotation_factor = 10,
|
|
simple_headshot = true, --holdover feature before a more complex system is implemented
|
|
simple_headshot_body_ratio = .75, --percentage of hitbox height that is body.
|
|
default_fov = 80,
|
|
headshot_damage_factor = 1.75,
|
|
enable_touchscreen_command_name = "guns4d_enable_touchmode",
|
|
minimum_supersonic_energy_assumption = 900, --used to determine the energy of a "supersonic" bullet for bullet whizzing sound effects
|
|
default_audio_attenuation_rate = .8, --changes the dropoff rate of sound. Acts as a multiplier for the distance used to calculate inverse square law. Most guns (from the gun packs) set their own, so this is mainly for reloads.
|
|
mix_supersonic_and_subsonic_sounds = true,
|
|
default_pass_sound_mixing_factor = 10,
|
|
third_person_gain_multiplier = 1/3,
|
|
default_penetration_iteration_distance = .25,
|
|
maximum_bullet_holes = 20,
|
|
--enable_assert = false,
|
|
realistic_items = false
|
|
--`["official_content.replace_ads_with_bloom"] = false,
|
|
--`["official_content.uses_magazines"] = true
|
|
}
|
|
local modpath = minetest.get_modpath("guns4d")
|
|
|
|
local conf = Settings(modpath.."/guns4d_settings.conf"):to_table() or {}
|
|
local mt_conf = minetest.settings:to_table() --allow use of MT config for servers that regularly update 4dguns through it's development
|
|
for i, v in pairs(Guns4d.config) do
|
|
--Guns4d.config[i] = conf[i] or minetest.settings["guns4d."..i] or Guns4d.config[i]
|
|
--cant use or because it'd evaluate to false if the setting is alse
|
|
if mt_conf["guns4d."..i] ~= nil then
|
|
Guns4d.config[i] = mt_conf["guns4d."..i]
|
|
elseif conf[i] ~= nil then
|
|
Guns4d.config[i] = conf[i]
|
|
end
|
|
end
|
|
|
|
minetest.rmdir(modpath.."/temp", true)
|
|
minetest.mkdir(modpath.."/temp")
|
|
|
|
dofile(modpath.."/infinite_ammo.lua")
|
|
dofile(modpath.."/misc_helpers.lua")
|
|
dofile(modpath.."/item_entities.lua")
|
|
dofile(modpath.."/play_sound.lua")
|
|
dofile(modpath.."/visual_effects.lua")
|
|
dofile(modpath.."/default_controls.lua")
|
|
dofile(modpath.."/touch_support.lua")
|
|
dofile(modpath.."/block_values.lua")
|
|
dofile(modpath.."/ammo_api.lua")
|
|
local path = modpath .. "/classes"
|
|
dofile(path.."/Bullet_hole.lua")
|
|
dofile(path.."/Bullet_ray.lua")
|
|
dofile(path.."/Control_handler.lua")
|
|
dofile(path.."/Ammo_handler.lua")
|
|
dofile(path.."/Sprite_scope.lua")
|
|
dofile(path.."/Dynamic_crosshair.lua")
|
|
dofile(path.."/Gun.lua") --> loads /classes/gun_construct.lua
|
|
dofile(path.."/Player_model_handler.lua")
|
|
dofile(path.."/Player_handler.lua")
|
|
|
|
--model compatibility
|
|
path = modpath .. "/models"
|
|
dofile(path.."/3darmor/init.lua")
|
|
|
|
|
|
--load after
|
|
path = minetest.get_modpath("guns4d")
|
|
|
|
local player_handler = Guns4d.player_handler
|
|
local objref_mtable
|
|
minetest.register_on_joinplayer(function(player)
|
|
local pname = player:get_player_name()
|
|
Guns4d.players[pname] = player_handler:new({player=player}) --player handler does just what it sounds like- see classes/Player_handler
|
|
Guns4d.handler_by_ObjRef[player] = Guns4d.players[pname]
|
|
--set the FOV to a predictable value
|
|
player:set_fov(Guns4d.config.default_fov)
|
|
--ObjRef overrides will be integrated into MTUL (eventually TM)
|
|
if not objref_mtable then
|
|
objref_mtable = getmetatable(player)
|
|
|
|
local old_set_fov = objref_mtable.set_fov
|
|
Guns4d.old_set_fov = old_set_fov
|
|
function objref_mtable.set_fov(self, ...)
|
|
local handler = Guns4d.handler_by_ObjRef[self]
|
|
local fov = select(1, ...)
|
|
if handler then --check, just in case it's not a player (and thus should throw an error)
|
|
if fov == 0 then
|
|
fov = Guns4d.config.default_fov
|
|
elseif select(2, ...) == true then
|
|
fov = Guns4d.config.default_fov*fov
|
|
end
|
|
handler.default_fov = fov
|
|
if handler.fov_lock then return end
|
|
end
|
|
local args = {...}
|
|
args[1] = fov --basically permenantly set the player's fov to 80, making multipliers and resets return there.
|
|
old_set_fov(self, unpack(args))
|
|
end
|
|
|
|
local old_get_pos = objref_mtable.get_pos
|
|
function objref_mtable.get_pos(self, ...)
|
|
local gun = Guns4d.gun_by_ObjRef[self]
|
|
local mt_pos = old_get_pos(self, ...)
|
|
if mt_pos then --mods (including this) will frequently use this as a check if an ent is still around.
|
|
if (not gun) or gun.released then
|
|
return mt_pos
|
|
else
|
|
local v, _, _ = gun:get_pos()
|
|
return v
|
|
end
|
|
end
|
|
end
|
|
function objref_mtable._guns4d_old_get_pos(self, ...)
|
|
return old_get_pos(self, ...)
|
|
end
|
|
|
|
local old_set_animation = objref_mtable.set_animation
|
|
--put vargs there for maintainability.
|
|
function objref_mtable.set_animation(self, frame_range, frame_speed, frame_blend, frame_loop, ...)
|
|
local gun = Guns4d.gun_by_ObjRef[self]
|
|
if gun then
|
|
local data = gun.animation_data
|
|
data.runtime = 0
|
|
data.fps = frame_speed or 15
|
|
data.loop = frame_loop
|
|
if frame_loop == nil then --still have no idea what nutjob made the default true >:(
|
|
frame_loop = false
|
|
end
|
|
--so... minetest is stupid, and so it won't let me set something to the same animation twice (utterly fucking brilliant).
|
|
--This means I literally need to flip flop between +1 frames
|
|
frame_range = table.copy(frame_range)
|
|
--minetest.chat_send_all(dump(frame_range))
|
|
if (data.frames.x == frame_range.x and data.frames.y == frame_range.y) and not (frame_range.x==frame_range.y) then
|
|
--oh yeah, and it only accepts whole frames... because of course.
|
|
frame_range.x = frame_range.x+1
|
|
--minetest.chat_send_all("+1")
|
|
end
|
|
--frame_blend = 25
|
|
--minetest.chat_send_all(dump(frame_range))
|
|
data.frames = frame_range
|
|
data.current_frame = data.frames.x
|
|
end
|
|
return old_set_animation(self, frame_range, frame_speed, frame_blend, frame_loop, ...)
|
|
end
|
|
|
|
local old_set_frame_speed = objref_mtable.set_animation_frame_speed
|
|
function objref_mtable.set_animation_frame_speed(self, frame_speed, ...)
|
|
local gun = Guns4d.gun_by_ObjRef[self]
|
|
if gun then
|
|
gun.animation_data.fps = frame_speed or 15
|
|
end
|
|
old_set_frame_speed(self, frame_speed, ...)
|
|
end
|
|
|
|
local old_remove = objref_mtable.remove
|
|
function objref_mtable.remove(self)
|
|
local gun = Guns4d.gun_by_ObjRef[self]
|
|
if gun then
|
|
Guns4d.gun_by_ObjRef[self] = nil
|
|
end
|
|
return old_remove(self)
|
|
end
|
|
|
|
|
|
|
|
--[[minetest.after(1, function(playername)
|
|
minetest.get_player_by_name(playername):hud_add({
|
|
hud_elem_type = "compass",
|
|
text = "gun_mrkr.png",
|
|
scale = {x=1, y=1},
|
|
alignment = {x=0,y=0},
|
|
position = {x=.5,y=.5},
|
|
size = {x=200, y=200},
|
|
offset = {x=-.5,y=.5},
|
|
direction = 0
|
|
})
|
|
end, player:get_player_name())]]
|
|
end
|
|
end)
|
|
--we grab the ObjRef metatable from the first available source.
|
|
--because we want guns to function as real objects, we have to override the metatable get_pos() for all objects
|
|
--this is made more efficient by using a table lookup for ObjRefs we want to update properly.
|
|
--"uns4d[ObjRef] = gun" is declared on_activate() in the entity.
|
|
--[[minetest.after(0, function()
|
|
|
|
end)]]
|
|
minetest.register_on_leaveplayer(function(player)
|
|
local pname = player:get_player_name()
|
|
Guns4d.players[pname]:prepare_deletion()
|
|
Guns4d.players[pname] = nil
|
|
Guns4d.handler_by_ObjRef[player] = nil
|
|
end)
|
|
|
|
--ticks are rarely used, but still ideal for rare checks with minimal overhead.
|
|
TICK = 0
|
|
minetest.register_globalstep(function(dt)
|
|
TICK = TICK + 1
|
|
if TICK > 100000 then TICK = 0 end
|
|
for player, handler in pairs(Guns4d.players) do
|
|
if not handler then
|
|
--spawn the player handler. The player handler handles the gun(s),
|
|
--the player's model, and controls
|
|
handler = player_handler:new({player=player})
|
|
end
|
|
handler:update(dt)
|
|
--[[minetest.get_player_by_name(player):hud_add({
|
|
hud_elem_type = "compass",
|
|
text = "gay.png",
|
|
scale = {x=10, y=10},
|
|
alignment = {x=0,y=0},
|
|
offset = {x=-.5,y=-.5},
|
|
direction = 0
|
|
})]]
|
|
end
|
|
end) |