implement magazine reloading, mag & bullet defs
This commit is contained in:
parent
a71c84a524
commit
21ab76ce95
@ -1,4 +1,4 @@
|
||||
Gun_ammo = Instantiatable_class:inherit({
|
||||
Ammo_handler = Instantiatable_class:inherit({
|
||||
name = "Gun_ammo_handler",
|
||||
construct = function(def)
|
||||
assert(def.gun)
|
@ -298,7 +298,6 @@ function gun_default:update_wag(dt)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function gun_default:update_recoil(dt)
|
||||
for axis, _ in pairs(self.offsets.recoil) do
|
||||
for _, i in pairs({"x","y"}) do
|
||||
|
@ -39,4 +39,5 @@ auxillary (beta+/never)
|
||||
bullet drop (maybe bullet wind?)
|
||||
bullet tracers
|
||||
inverse kinematics
|
||||
stamina
|
||||
stamina
|
||||
a better system for reloading magazine (something like a inventory that fractionally reloads magazines so it takes time.)
|
1
init.lua
1
init.lua
@ -7,6 +7,7 @@ dofile(path.."/misc_helpers.lua")
|
||||
dofile(path.."/visual_effects.lua")
|
||||
dofile(path.."/gun_api.lua")
|
||||
dofile(path.."/block_values.lua")
|
||||
dofile(path.."/register_ammo.lua")
|
||||
path = path .. "/classes"
|
||||
dofile(path.."/Instantiatable_class.lua")
|
||||
dofile(path.."/Bullet_ray.lua")
|
||||
|
@ -5,13 +5,10 @@ Default_bullet = {
|
||||
force_mmRHA = 1,
|
||||
dropoff_mmRHA = 0,
|
||||
damage = 0,
|
||||
itemstring = "",
|
||||
construct = function(def)
|
||||
assert(not def.instance, "attempt to create instance of a template")
|
||||
assert(rawget(def, "itemstring"), "no string provided to new bullet template")
|
||||
assert(minetest.registered_items[def.itemstring], "bullet item is not registered. Check dependencies?")
|
||||
|
||||
end
|
||||
}
|
||||
Default_mag = {
|
||||
capacity = 1,
|
||||
craft_reload = true
|
||||
}
|
||||
Guns4d.ammo = {
|
||||
registered_bullets = {
|
||||
@ -21,26 +18,144 @@ Guns4d.ammo = {
|
||||
|
||||
}
|
||||
}
|
||||
local max_wear = 65535
|
||||
function Guns4d.ammo.register_bullet(def)
|
||||
assert(def.itemstring)
|
||||
assert(minetest.registered_items[def.itemstring], "no item '"..def.itemstring.."' found. Must be a registered item (check dependencies?)")
|
||||
Guns4d.ammo.registered_bullets[def.itemstring] = table.fill(Default_bullet, def)
|
||||
end
|
||||
function Guns4d.ammo.register_magazine(def)
|
||||
assert(def.accepted_bullets, "missing property def.accepted_bullets. Need specified bullets to allow for loading")
|
||||
for i, v in pairs(def.accepted_bullets) do
|
||||
if not Guns4d.ammo.registered_bullets[v] then print("WARNING! bullet "..v.." not registered! is this a mistake?") end
|
||||
function Guns4d.ammo.initialize_mag_data(itemstack, meta)
|
||||
meta = meta or itemstack:get_meta()
|
||||
if meta:get_string("guns4d_loaded_bullets") == "" then
|
||||
meta:set_string("guns4d_loaded_bullets", minetest.serialize({}))
|
||||
itemstack:set_wear(max_wear)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
function Guns4d.ammo.update_mag_wear(def, itemstack, meta)
|
||||
meta = meta or itemstack:get_meta()
|
||||
local bullets = minetest.deserialize(meta:get_string("guns4d_loaded_bullets"))
|
||||
local count = 0
|
||||
for i, v in pairs(bullets) do
|
||||
count = count + v
|
||||
end
|
||||
itemstack:set_wear(max_wear-(max_wear*count/def.capacity))
|
||||
return itemstack
|
||||
end
|
||||
function Guns4d.ammo.register_magazine(def)
|
||||
def = table.fill(Default_mag, def)
|
||||
assert(def.accepted_bullets, "missing property def.accepted_bullets. Need specified bullets to allow for loading")
|
||||
assert(def.itemstring, "missing item name")
|
||||
def.accepted_bullets_set = {} --this table is a "lookup" table, I didn't go to college so I have no idea
|
||||
for i, v in pairs(def.accepted_bullets) do
|
||||
if not Guns4d.ammo.registered_bullets[v] then print("guns4D: WARNING! bullet "..v.." not registered! is this a mistake?") end
|
||||
def.accepted_bullets_set[v] = true
|
||||
end
|
||||
Guns4d.ammo.registered_magazines[def.itemstring] = def
|
||||
--register craft prediction
|
||||
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)
|
||||
if craft_inv:contains_item("craft", def.itemstring) and itemstack:get_name()=="" then
|
||||
--potentially give predicted ammo gauge here
|
||||
return def.itemstring
|
||||
local old_on_use = minetest.registered_items[def.itemstring].on_use
|
||||
minetest.override_item(def.itemstring, {
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if old_on_use then
|
||||
old_on_use(itemstack, user, pointed_thing)
|
||||
end
|
||||
local meta = itemstack:get_meta()
|
||||
local ammo = minetest.deserialize(meta:get_string("guns4d_loaded_bullets"))
|
||||
if ammo then
|
||||
minetest.chat_send_player(user:get_player_name(), "rounds in magazine:")
|
||||
for i, v in pairs(ammo) do
|
||||
minetest.chat_send_player(user:get_player_name(), " "..i.." : "..tostring(v))
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(user:get_player_name(), "magazine is empty")
|
||||
end
|
||||
end
|
||||
end)
|
||||
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
|
||||
if craft_inv:contains_item("craft", def.itemstring) and craft_inv:contains_item("craftpreview", def.itemstring) then
|
||||
end
|
||||
end)
|
||||
})
|
||||
if def.craft_reload then
|
||||
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)
|
||||
--initialize all mags
|
||||
local num_mags = 0
|
||||
for i, v in pairs(craft_inv:get_list("craft")) do
|
||||
if v:get_name() == def.itemstring then
|
||||
num_mags = num_mags + 1
|
||||
Guns4d.ammo.initialize_mag_data(v)
|
||||
end
|
||||
end
|
||||
print(num_mags)
|
||||
if itemstack:get_name()=="" then
|
||||
for i, v in pairs(craft_inv:get_list("craft")) do
|
||||
local name =v:get_name()
|
||||
if name == def.itemstring then
|
||||
craft_inv:set_stack("craft", i, Guns4d.ammo.initialize_mag_data(v))
|
||||
end
|
||||
if (name~=def.itemstring) and Guns4d.ammo.registered_magazines[name] then
|
||||
return
|
||||
end
|
||||
if (name~="") and (not (name == def.itemstring)) and (not def.accepted_bullets_set[name]) then
|
||||
print("name:", dump(def.accepted_bullets_set))
|
||||
return
|
||||
end
|
||||
end
|
||||
return def.itemstring
|
||||
end
|
||||
end)
|
||||
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
|
||||
if craft_inv:contains_item("craft", def.itemstring) and craft_inv:contains_item("craftpreview", def.itemstring) then
|
||||
local mag_stack_index
|
||||
local craft_list = craft_inv:get_list("craft")
|
||||
--there's basically no way to cleanly avoid two iterations, annoyingly.
|
||||
for i, v in pairs(craft_list) do
|
||||
local name = v:get_name()
|
||||
if (name~=def.itemstring) then
|
||||
if Guns4d.ammo.registered_magazines[name] then
|
||||
return
|
||||
end
|
||||
else
|
||||
mag_stack_index = i
|
||||
end
|
||||
if not def.accepted_bullets_set[name] then
|
||||
if (name ~= "") and (name~=def.itemstring) then
|
||||
print("return", "'"..name.."'")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
local bullets_unfilled = def.capacity
|
||||
local mag_stack = craft_inv:get_stack("craft", mag_stack_index)
|
||||
local new_ammo_table = minetest.deserialize(mag_stack:get_meta():get_string("guns4d_loaded_bullets"))
|
||||
for i, v in pairs(new_ammo_table) do
|
||||
bullets_unfilled = bullets_unfilled - v
|
||||
end
|
||||
local new_stack = ItemStack(def.itemstring)
|
||||
for i, v in pairs(craft_list) do
|
||||
local name = v:get_name()
|
||||
if def.accepted_bullets_set[name] then
|
||||
local bullet_stack_count = v:get_count()
|
||||
--check if there's not enough bullets to fill it
|
||||
if bullet_stack_count <= bullets_unfilled then
|
||||
--if not then remove the stack and add it
|
||||
bullets_unfilled = bullets_unfilled - bullet_stack_count
|
||||
new_ammo_table[name] = (new_ammo_table[name] or 0)+bullet_stack_count
|
||||
craft_inv:set_stack("craft", i, "")
|
||||
else
|
||||
--if there is then add the bullets needed to it's index in the table
|
||||
--and subtract.
|
||||
new_ammo_table[name] = (new_ammo_table[name] or 0)+bullets_unfilled
|
||||
v:set_count(bullet_stack_count-bullets_unfilled)
|
||||
craft_inv:set_stack("craft", i, v)
|
||||
bullets_unfilled = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
mag_stack:set_count(mag_stack:get_count()-1)
|
||||
craft_inv:set_stack("craft", mag_stack_index, mag_stack)
|
||||
new_stack:get_meta():set_string("guns4d_loaded_bullets", minetest.serialize(new_ammo_table))
|
||||
new_stack = Guns4d.ammo.update_mag_wear(def, new_stack)
|
||||
--print(new_stack:get_string())
|
||||
return new_stack
|
||||
end
|
||||
end)
|
||||
end
|
||||
--register the actual recipe to add ammo to a mag
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user