added burstfire, inventory stat indicator, fixed some firemode defaults

This commit is contained in:
FatalErr42O 2023-12-19 13:15:34 -08:00
parent 8c9afdd44b
commit 74f92aa77f
9 changed files with 111 additions and 36 deletions

View File

@ -34,6 +34,9 @@ function Ammo_handler:update_meta(bullets)
meta:set_string("guns4d_loaded_bullets", bullets or minetest.serialize(self.ammo.loaded_bullets))
meta:set_int("guns4d_total_bullets", self.ammo.total_bullets)
meta:set_string("guns4d_next_bullet", self.ammo.next_bullet)
if self.gun.ammo_handler then --if it's a first occourance it cannot work.
self.gun:update_image_and_text_meta(meta)
end
self.handler.player:set_wielded_item(self.gun.itemstack)
end
--use a round, called when the gun is shot. Returns a bool indicating success.

View File

@ -20,8 +20,14 @@ local gun_default = {
},
firemodes = {
"single", --not limited to semi-automatic.
"auto",
"burst"
"burst",
"auto"
},
firemode_inventory_overlays = {
single = "inventory_overlay_single.png",
auto = "inventory_overlay_auto.png",
burst = "inventory_overlay_burst.png",
safe = "inventory_overlay_safe.png"
},
recoil = { --used by update_recoil()
velocity_correction_factor = { --velocity correction factor is currently very broken.
@ -105,9 +111,12 @@ local gun_default = {
loaded = {x=1,y=1},
},
},
--inventory_image
--inventory_image_empty
--used by ammo_handler
flash_offset = Vec.new(), --used by fire() (for fsx and ray start pos) [RENAME NEEDED]
firerateRPM = 600, --used by update() and by extent fire() + default controls
burst = 3, --default burst length
ammo_handler = Ammo_handler
},
offsets = {
@ -186,6 +195,7 @@ local gun_default = {
time_since_last_fire = 0,
time_since_creation = 0,
rechamber_time = 0,
burst_queue = 0,
muzzle_flash = Guns4d.effects.muzzle_flash
}
--I dont remember why I made this, used it though lmao
@ -219,6 +229,7 @@ function gun_default:update(dt)
self.time_since_creation = self.time_since_creation + dt
self.time_since_last_fire = self.time_since_last_fire + dt
if self.burst_queue > 0 then self:update_burstfire() end
--update some vectors
if self.consts.HAS_SWAY then self:update_sway(dt) end
if self.consts.HAS_RECOIL then self:update_recoil(dt) end
@ -255,9 +266,51 @@ function gun_default:update(dt)
end
end
function gun_default:update_burstfire()
if self.rechamber_time <= 0 then
local success = self:attempt_fire()
if not success then
self.burst_queue = 0
else
self.burst_queue = self.burst_queue - 1
end
end
end
function gun_default:cycle_firemodes()
self.current_firemode = (self.current_firemode+1)%(#self.properties.firemodes)
minetest.chat_send_all(self.properties.firemodes[self.current_firemode+1])
self.current_firemode = ((self.current_firemode)%(#self.properties.firemodes))+1
self.meta:set_int("guns4d_firemode", self.current_firemode)
self:update_image_and_text_meta()
self.player:set_wielded_item(self.itemstack)
end
function gun_default:update_image_and_text_meta(meta)
meta = meta or self.meta
local ammo = self.ammo_handler.ammo
--set the counter
if ammo.total_bullets == 0 then
meta:set_string("count_meta", Guns4d.config.empty_symbol)
else
if Guns4d.config.show_gun_inv_ammo_count then
meta:set_string("count_meta", tostring(ammo.total_bullets))
else
meta:set_string("count_meta", "F")
end
end
--pick the image
local image = self.properties.inventory_image
if ammo.total_bullets > 0 then
image = self.properties.inventory_image
elseif self.properties.inventory_image_magless and (ammo.loaded_mag == "empty" or ammo.loaded_mag == "") then
image = self.properties.inventory_image_magless
elseif self.properties.inventory_image_empty then
image = self.properties.inventory_image_empty
end
--add the firemode overlay to the image
if self.properties.firemode_inventory_overlays[self.properties.firemodes[self.current_firemode]] then
minetest.chat_send_all(self.current_firemode)
image = image.."^"..self.properties.firemode_inventory_overlays[self.properties.firemodes[self.current_firemode]]
else
end
meta:set_string("inventory_image", image)
end
function gun_default:attempt_fire()
assert(self.instance, "attempt to call object method on a class")
@ -279,6 +332,7 @@ function gun_default:attempt_fire()
self:recoil()
self:muzzle_flash()
self.rechamber_time = 60/self.properties.firerateRPM
return true
end
end
end
@ -680,20 +734,23 @@ gun_default.construct = function(def)
def.player = def.handler.player
local meta = def.itemstack:get_meta()
def.meta = meta
local out = {}
--create ID so we can track switches between weapons
--create ID so we can track switches between weapons, also get some other data.
if meta:get_string("guns4d_id") == "" then
local id = tostring(Unique_id.generate())
meta:set_string("guns4d_id", id)
def.player:set_wielded_item(def.itemstack)
def.id = id
def.current_firemode = 1
meta:set_int("guns4d_firemode", 1)
else
def.id = meta:get_string("guns4d_id")
def.current_firemode = meta:get_int("guns4d_firemode")
end
def.ammo_handler = def.properties.ammo_handler:new({ --initialize ammo handler from gun and gun metadata.
gun = def
})
def:update_image_and_text_meta() --has to be called manually in post as ammo_handler would not exist yet.
def.player:set_wielded_item(def.itemstack)
--unavoidable table instancing
def.properties = table.fill(def.base_class.properties, def.properties)
def.particle_spawners = {} --Instantiatable_class only shallow copies. So tables will not change, and thus some need to be initialized.
@ -735,14 +792,6 @@ gun_default.construct = function(def)
gun = def
})
end
if def.properties.entity_scope then
if not def.entity_scope then
end
end
def.ammo_handler = def.properties.ammo_handler:new({
gun = def
})
elseif def.name ~= "__guns4d:default__" then
local props = def.properties
@ -804,14 +853,17 @@ gun_default.construct = function(def)
end
-- if it's not a template, then create an item, override some props
if def.name ~= "__template" then
assert(def.itemstring, "no itemstring provided. Cannot create a gun without an associated itemstring.")
local item_def = minetest.registered_items[def.itemstring]
assert(rawget(def, "name"), "no name provided in new class")
assert(rawget(def, "itemstring"), "no itemstring provided in new class")
assert(not((props.ammo.capacity) and (not props.ammo.magazine_only)), "gun does not accept magazines, but has no set capcity! Please define ammo.capacity")
assert(minetest.registered_items[def.itemstring], def.itemstring.." : item is not registered, check dependencies.")
assert(item_def, def.itemstring.." : item is not registered.")
--override methods so control handler can do it's job
local old_on_use = minetest.registered_items[def.itemstring].on_use
local old_on_s_use = minetest.registered_items[def.itemstring].on_secondary_use
local old_on_use = item_def.on_use
local old_on_s_use = item_def.on_secondary_use
def.properties.inventory_image = item_def.inventory_image
--override the item to hook in controls. (on_drop needed)
minetest.override_item(def.itemstring, {
on_use = function(itemstack, user, pointed_thing)

View File

@ -16,7 +16,7 @@ Guns4d.default_controls.auto = {
loop = true,
timer = 0,
func = function(active, interrupted, data, busy_list, gun, handler)
if gun.properties.firemodes[gun.current_firemode+1] == "auto" then
if gun.properties.firemodes[gun.current_firemode] == "auto" then
gun:attempt_fire()
end
end
@ -31,6 +31,17 @@ Guns4d.default_controls.firemode = {
end
end
}
Guns4d.default_controls.on_use = function(itemstack, handler, pointed_thing)
local gun = handler.gun
local fmode = gun.properties.firemodes[gun.current_firemode]
if fmode ~= "safe" and not (gun.burst_queue > 0) then
local fired = gun:attempt_fire()
if (fmode == "burst") then
gun.burst_queue = gun.properties.burst-((fired and 1) or 0)
end
end
--handler.control_handler.busy_list.on_use = true
end
Guns4d.default_controls.reload = {
conditions = {"zoom"},
loop = false,
@ -180,8 +191,4 @@ Guns4d.default_controls.reload = {
data.state = 0
end
end
}
Guns4d.default_controls.on_use = function(itemstack, handler, pointed_thing)
handler.gun:attempt_fire()
--handler.control_handler.busy_list.on_use = true
end
}

View File

@ -22,6 +22,15 @@ dofile(path.."/Player_model_handler.lua")
dofile(path.."/Player_handler.lua")
dofile(path.."/Proxy_table.lua")
--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,
empty_symbol = "0e"
}
--load after
path = minetest.get_modpath("guns4d")
@ -72,18 +81,19 @@ minetest.register_on_joinplayer(function(player)
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 = 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))
--minetest.chat_send_all(dump(frame_range))
if data.frames.x == frame_range.x and data.frames.y == 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")
--minetest.chat_send_all("+1")
end
minetest.chat_send_all(dump(frame_range))
--frame_blend = 25
--minetest.chat_send_all(dump(frame_range))
data.frames = frame_range
data.current_frame = data.frames.x
end

View File

@ -30,10 +30,8 @@ function Guns4d.ammo.register_bullet(def)
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
meta:set_string("guns4d_loaded_bullets", minetest.serialize({}))
Guns4d.ammo.update_mag(nil, itemstack, meta)
return itemstack
end
function Guns4d.ammo.update_mag(def, itemstack, meta)
@ -47,9 +45,14 @@ function Guns4d.ammo.update_mag(def, itemstack, meta)
count = count + v
end
local new_wear = max_wear-(max_wear*count/def.capacity)
itemstack:set_wear(math.clamp(new_wear, 1, max_wear-1))
--itemstack:set_wear(math.clamp(new_wear, 1, max_wear-1))
meta:set_int("guns4d_total_bullets", count)
meta:set_string("guns4d_next_bullet", current_bullet)
if count > 0 then
meta:set_string("count_meta", tostring(count).."/"..def.capacity)
else
meta:set_string("count_meta", Guns4d.config.empty_symbol.."/"..tostring(def.capacity))
end
return itemstack
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B