diff --git a/.vscode/settings.json b/.vscode/settings.json
index 5c370d6..e64f4c1 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -6,5 +6,8 @@
"player_api",
"ItemStack",
"leef"
+ ],
+ "Lua.diagnostics.disable": [
+ "undefined-field"
]
}
\ No newline at end of file
diff --git a/classes/Gun-construct.lua b/classes/Gun-construct.lua
index 28fbc8b..b6855de 100644
--- a/classes/Gun-construct.lua
+++ b/classes/Gun-construct.lua
@@ -186,7 +186,7 @@ local function initialize_b3d_animation_data(self, props)
--we compose it by the inverse because we need to get the global offset in rotation for the animation rotation offset. I really need to comment more often
--print(leef.b3d_nodes.get_node_rotation(nil, main, nil, -1))
- local newvec = leef.b3d_nodes.get_node_rotation(nil, main, nil, target_frame)*leef.b3d_nodes.get_node_rotation(nil, main, nil, -1):inverse()
+ local newvec = leef.b3d_nodes.get_node_rotation(nil, main, nil, target_frame)*leef.b3d_nodes.get_node_rotation(nil, main, nil, props.visuals.animations.loaded.x):inverse()
--used to use euler
table.insert(self.b3d_model.global_frames.rotation, newvec)
end
diff --git a/classes/Gun-methods.lua b/classes/Gun-methods.lua
index c5bc67a..0f9ea08 100644
--- a/classes/Gun-methods.lua
+++ b/classes/Gun-methods.lua
@@ -1,21 +1,9 @@
local gun_default = Guns4d.gun
+local mat4 = leef.math.mat4
--I dont remember why I made this, used it though lmao
function gun_default.multiplier_coefficient(multiplier, ratio)
return 1+((multiplier*ratio)-ratio)
end
-function gun_default:draw()
- assert(self.instance, "attempt to call object method on a class")
- local props = self.properties
- if props.visuals.animations[props.charging.draw_animation] then
- self:set_animation(props.visuals.animations[props.charging.draw_animation], props.charging.draw_time)
- end
- if props.sounds[props.charging.draw_sound] then
- local sounds = Guns4d.table.deep_copy(props.sounds[props.charging.draw_sound])
- self:play_sounds(sounds)
- end
- self.ammo_handler:chamber_round()
- self.rechamber_time = props.charging.draw_time
-end
--update gun, the main function.
function gun_default:update(dt)
assert(self.instance, "attempt to call object method on a class")
@@ -42,18 +30,21 @@ function gun_default:update(dt)
self:update_animation(dt)
self.dir = self:get_dir()
- self.local_dir = self:get_dir(true)
- self.paxial_dir = self:get_player_axial_dir()
- self.local_paxial_dir = self:get_player_axial_dir(true)
self.pos = self:get_pos()+self.handler:get_pos()
- self:update_entity()
+ --update subclasses
+ self:update_entity()
if self.properties.sprite_scope then
self.sprite_scope:update()
end
if self.properties.crosshair then
self.crosshair:update()
end
+ --finalize transforms
+ self:update_rotations()
+end
+
+function gun_default:update_rotations()
local total_offset = self.total_offsets
--axis rotations
total_offset.player_axial.x = 0; total_offset.player_axial.y = 0
@@ -70,8 +61,8 @@ function gun_default:update(dt)
end
end
end
+ --total_offset.gun_axial.x = 0; total_offset.gun_axial.y = 0
end
---update modifiers
--manage burstfire
function gun_default:update_burstfire()
@@ -138,6 +129,21 @@ function gun_default:update_image_and_text_meta(meta)
end
meta:set_string("inventory_image", image)
end
+--draw the gun from holster
+function gun_default:draw()
+ assert(self.instance, "attempt to call object method on a class")
+ local props = self.properties
+ if props.visuals.animations[props.charging.draw_animation] then
+ self:set_animation(props.visuals.animations[props.charging.draw_animation], props.charging.draw_time)
+ end
+ if props.sounds[props.charging.draw_sound] then
+ local sounds = Guns4d.table.deep_copy(props.sounds[props.charging.draw_sound])
+ self:play_sounds(sounds)
+ end
+ self.ammo_handler:chamber_round()
+ self.rechamber_time = props.charging.draw_time
+end
+--attempt to fire the weapon
function gun_default:attempt_fire()
assert(self.instance, "attempt to call object method on a class")
local props = self.properties
@@ -167,15 +173,12 @@ function gun_default:attempt_fire()
end
self:recoil()
self:muzzle_flash()
- --[[if props.durability.shot_per_wear then
- self:damage()
- end]]
- --print(dump(self.properties.sounds.fire))
+
+ --this is gonna have to be optimized eventually because this system is complete ass.
local fire_sound = Guns4d.table.deep_copy(props.sounds.fire) --important that we copy because play_sounds modifies it.
fire_sound.pos = self.pos
self:play_sounds(fire_sound)
- --this should handle the firerate being faster than dt
self.rechamber_time = self.rechamber_time + (60/props.firerateRPM)
return true
end
@@ -278,8 +281,8 @@ function gun_default:get_player_axial_dir(rltv)
end
return dir
end
---this needs to be optimized because it may be called frequently...
-function gun_default:get_dir(rltv, offset_x, offset_y)
+--This should be replaced with
+--[[function gun_default:get_dir(rltv, offset_x, offset_y)
assert(self.instance, "attempt to call object method on a class")
local rotation = self.total_offsets
local handler = self.handler
@@ -312,52 +315,104 @@ function gun_default:get_dir(rltv, offset_x, offset_y)
dir = vector.new(dir)
end
return dir
-end
---Should probably optimize this at some point.
-local zero = vector.zero()
-function gun_default:get_pos(offset_pos, relative, ads, ignore_translations)
+end]]
+--probably doesnt get much more optimized then this.
+local bone_location = vector.new()
+local tmv3_rot = vector.new()
+local tmv4_in = {0,0,0,1}
+local tmv4_pivot_inv = {0,0,0,0}
+local tmv4_offset = {0,0,0,1}
+local tmv4_gun = {0,0,0,1}
+local empty_vec = {x=0,y=0,z=0}
+local ttransform = mat4.identity()
+local out = vector.new() --reserve the memory, we still want to create new vectors each time though.
+--gets the gun's position relative to the player. Relative indicates wether it's relative to the player's horizontal look
+--offset is relative to the's rotation
+function gun_default:get_pos(offset, relative_y, relative_x, with_animation)
assert(self.instance, "attempt to call object method on a class")
- local player = self.player
+ --local player = self.player
local handler = self.handler
- local bone_location = handler.player_model_handler.gun_bone_location
- local gun_translation = self.gun_translation
- if offset_pos then
- gun_translation = gun_translation+offset_pos
- end
- if gun_translation==self.gun_translation then gun_translation = vector.new(gun_translation) end
+ local raw_bone_location = handler.player_model_handler.gun_bone_location
+ local vs = handler:get_properties().visual_size
+ bone_location.x, bone_location.y, bone_location.z = raw_bone_location.x, raw_bone_location.y, raw_bone_location.z
+ local gun_translation = self.gun_translation --needs a refactor
+ local root_transform = self.b3d_model.root_orientation_rest
+ offset = offset or empty_vec
--dir needs to be rotated twice seperately to avoid weirdness
- local pos
- if not relative then
- pos = vector.rotate(bone_location, {x=0, y=-handler.look_rotation.y*math.pi/180, z=0})
- pos = pos+vector.rotate(gun_translation, vector.dir_to_rotation(self.paxial_dir))
- else
- pos = vector.rotate(gun_translation, vector.dir_to_rotation(self.local_paxial_dir)+{x=self.player_rotation.x*math.pi/180,y=0,z=0})+bone_location
- end
- --[[local hud_pos
- if relative then
- hud_pos = vector.rotate(pos, {x=0,y=player:get_look_horizontal(),z=0})+handler:get_pos()
- else
- hud_pos = pos+handler:get_pos()
- end]]
- --if minetest.get_player_by_name("fatal2") then
- --[[local hud = minetest.get_player_by_name("fatal2"):hud_add({
- hud_elem_type = "image_waypoint",
- text = "muzzle_flash2.png",
- world_pos = hud_pos,
- scale = {x=10, y=10},
- alignment = {x=0,y=0},
- offset = {x=0,y=0},
- })
- minetest.after(0, function(hud)
- minetest.get_player_by_name("fatal2"):hud_remove(hud)
- end, hud)]]
- --end
+ local gun_scale = self.properties.visuals.scale
+ --player look. If its relative on a given axis we eliminate it by setting it to 0.
+ local px = (relative_x and 0) or nil
+ local py = (relative_y and 0) or nil
+ local ax = ((not with_animation) and 0) or nil
+ local ay = ((not with_animation) and 0) or nil
+ local az = ((not with_animation) and 0) or nil
+ --offset is relative to the gun, which is rotated about the origin of the root bone, so we need to make the vector relative to the root's vector, rotate, and then bring it back to global space.
+ ttransform=self:get_rotation_transform(ttransform,nil,nil,nil,nil,nil,px,py,ax,ay,az)
+ tmv4_in[1], tmv4_in[2], tmv4_in[3] = offset.x-root_transform[13]*gun_scale, offset.y-root_transform[14]*gun_scale, offset.z-root_transform[15]*gun_scale
+ tmv4_offset = ttransform.mul_vec4(tmv4_offset, ttransform, tmv4_in)
+ tmv4_in[1], tmv4_in[2], tmv4_in[3] = root_transform[13]*gun_scale, root_transform[14]*gun_scale, root_transform[15]*gun_scale
+ tmv4_pivot_inv = ttransform.mul_vec4(tmv4_pivot_inv, ttransform, tmv4_in) --bring it back to global space by adding what we subtracted earlier (which has now been transformed.)
+ tmv4_offset[1],tmv4_offset[2],tmv4_offset[3] = tmv4_offset[1]+tmv4_pivot_inv[1], tmv4_offset[2]+tmv4_pivot_inv[2], tmv4_offset[3]+tmv4_pivot_inv[3]
+
+ --the translation of the gun is translation of the root bone's coordinate system, so the gun_axial rotation would not affect it, therefore we set local rotations to 0.
+ ttransform=self:get_rotation_transform(ttransform, 0,0,0,nil,nil,px,py,ax,ay,az)
+ tmv4_in[1], tmv4_in[2], tmv4_in[3] = gun_translation.x, gun_translation.y, gun_translation.z
+ tmv4_gun = ttransform.mul_vec4(tmv4_gun, ttransform, tmv4_in)
+
+ --the bone location is determined by the rotation of the player alone. This currently only supports player look but will probably support the actual rotation in the future
+ if relative_y then
+ out = vector.new(bone_location)
+ else
+ tmv3_rot.y = -handler.look_rotation.y*math.pi/180
+ out = vector.rotate(bone_location, tmv3_rot)
+ end
+ out.x, out.y, out.z = out.x+tmv4_gun[1]+tmv4_offset[1], out.y+tmv4_gun[2]+tmv4_offset[2], out.z+tmv4_gun[3]+tmv4_offset[3]
+ return out
+end
+
+local roll = mat4.identity() --roll offset (future implementation )
+local lrot = mat4.identity() --local rotation offset
+local grot = mat4.identity() --global rotation offset
+local prot = mat4.identity() --global player rotation
+local trad = math.pi/180
+function gun_default:get_rotation_transform(out, lx,ly,lz,gx,gy,px,py,ax,ay,az)
+ --local pitch, global pitch etc.
+ local rotations = self.total_offsets
+ local arotation = self.animation_rotation
+ local protation = self.player_rotation
+ --eventually we want to INTERNALLY use radians, for now we have to do this though.
+ lz = lz or 0 --roll is currently unused.
+ ax, ay, az = ax or -arotation.x*trad, ay or -arotation.y*trad, az or -arotation.z*trad
+ lx, ly = lx or -rotations.gun_axial.x*trad, ly or -rotations.gun_axial.y*trad
+ gx, gy = gx or -rotations.player_axial.x*trad, gy or -rotations.player_axial.y*trad
+ px, py = px or -protation.x*trad, py or -protation.y*trad
+
+ --this doesnt account for the actual rotation of the player
+ --reset roll matrix
+ roll[1] = 1
+ roll[2] = 0
+ roll[5] = 0
+ roll[6] = 1
+ roll = mat4.rotate_Z(roll, lz+az)
+ --we use bone rotation because it uses the XYZ order. Overall order is "PGLA", player (ZXY)<-global_offset (XYZ)<-local_offset (XYZ)<-roll (Z)\
+ out = mat4.multiply(out, {prot:set_rot_luanti_entity(px, py, 0), grot:set_rot_irrlicht_bone(gx, gy, 0), lrot:set_rot_irrlicht_bone(lx+ax, ly+ay, 0), roll})
+ return out
+end
+local forward = {0,0,1,0}
+local tmv4_out = {0,0,0,0}
+function gun_default:get_dir(rltv, offx, offy)
+ local rotations = self.total_offsets
+ if rltv then
+ ttransform = self:get_rotation_transform(ttransform, (-rotations.gun_axial.x-(offx or 0) )*trad, (-rotations.gun_axial.y-(offy or 0))*trad, nil, nil, nil, 0, 0, nil,nil,nil)
+ else
+ ttransform = self:get_rotation_transform(ttransform, (-rotations.gun_axial.x-(offx or 0))*trad, (-rotations.gun_axial.y-(offy or 0))*trad, nil, nil, nil, nil, nil, nil,nil,nil)
+ end
+ local tmv4 = ttransform.mul_vec4(tmv4_out, ttransform, forward)
+ local pos = vector.new(tmv4[1], tmv4[2], tmv4[3])
- --world pos, position of bone, offset of gun from bone (with added_pos)
return pos
end
-
--=============================================== ENTITY ======================================================
@@ -375,7 +430,6 @@ function gun_default:add_entity()
--obj:on_step()
--self:update_entity()
end
-local mat4 = leef.math.mat4
local tmp_mat4_rot = mat4.identity()
local ip_time = Guns4d.config.gun_axial_interpolation_time
local ip_time2 = Guns4d.config.translation_interpolation_time
@@ -405,7 +459,7 @@ function gun_default:update_entity()
--some complicated math to get client interpolation to work. It doesn't really account for the root bone having an (oriented) parent bone currently... hopefully that's not an issue.
local b3d = self.b3d_model
- local rot = tmp_mat4_rot:set_rot_luanti_entity(axial_rot.x*math.pi/180,axial_rot.y*math.pi/180, 0)
+ local rot = self:get_rotation_transform(tmp_mat4_rot, nil,nil,nil, 0,0, 0,0, 0,0,0)
tmp_mat4_rot = mat4.mul(tmp_mat4_rot, {b3d.root_orientation_rest_inverse, rot, b3d.root_orientation_rest})
local xr,yr,zr = tmp_mat4_rot:get_rot_irrlicht_bone()
@@ -416,7 +470,7 @@ function gun_default:update_entity()
interpolation = ip_time2,
},
rotation = {
- vec = {x=-xr,y=-yr,z=-zr},
+ vec = {x=xr,y=yr,z=zr},
interpolation = ip_time,
}
})
@@ -424,7 +478,7 @@ end
function gun_default:has_entity()
assert(self.instance, "attempt to call object method on a class")
if not self.entity then return false end
- if not self.entity:get_pos() then return false end
+ if not self.entity:is_valid() then return false end
return true
end
@@ -633,20 +687,21 @@ function gun_default:update_animation_rotation()
local frame1 = math.floor(current_frame/self.consts.KEYFRAME_SAMPLE_PRECISION)
local frame2 = math.floor(current_frame/self.consts.KEYFRAME_SAMPLE_PRECISION)+1
current_frame = current_frame/self.consts.KEYFRAME_SAMPLE_PRECISION
+ local rotations = self.b3d_model.global_frames.rotation
local out
- if self.b3d_model.global_frames.rotation then
- if self.b3d_model.global_frames.rotation[frame1] then
- if (not self.b3d_model.global_frames.rotation[frame2]) or (current_frame==frame1) then
- out = vector.new(self.b3d_model.global_frames.rotation[frame1]:get_euler_irrlicht_bone())*180/math.pi
+ if rotations then
+ if rotations[frame1] then
+ if (not rotations[frame2]) or (current_frame==frame1) then
+ out = vector.new(rotations[frame1]:get_euler_irrlicht_bone())*180/math.pi
--print("rawsent")
else --to stop nan
local ip_ratio = (current_frame-frame1)/(frame2-frame1)
- local vec1 = self.b3d_model.global_frames.rotation[frame1]
- local vec2 = self.b3d_model.global_frames.rotation[frame2]
+ local vec1 = rotations[frame1]
+ local vec2 = rotations[frame2]
out = vector.new(vec1:slerp(vec2, ip_ratio):get_euler_irrlicht_bone())*180/math.pi
end
else
- out = vector.copy(self.b3d_model.global_frames.rotation[1])
+ out = vector.copy(rotations[1])
end
--print(frame1, frame2, current_frame, dump(out))
else
@@ -659,7 +714,8 @@ end
--relative to the gun's entity. Returns left, right vectors.
local out = {arm_left=vector.new(), arm_right=vector.new()}
function gun_default:get_arm_aim_pos()
- local current_frame = self.animation_data.current_frame+1
+ local current_frame = self.animation_data.current_frame
+ print(current_frame)
local frame1 = math.floor(current_frame/self.consts.KEYFRAME_SAMPLE_PRECISION)
local frame2 = math.floor(current_frame/self.consts.KEYFRAME_SAMPLE_PRECISION)+1
current_frame = current_frame/self.consts.KEYFRAME_SAMPLE_PRECISION
diff --git a/classes/Gun.lua b/classes/Gun.lua
index bc9db3e..7080d84 100644
--- a/classes/Gun.lua
+++ b/classes/Gun.lua
@@ -1,32 +1,33 @@
--- Gun class
+
+local Vec = vector
+
+--- Gun class fields
--
-- ## Defining a gun:
--
-- **method documentation coming soon** (or never...)
--
--- guns are defined by two table fields: their @{lvl1_fields.consts|consts} and their @{lvl1_fields.properties|properties}.
+-- The appearance and handling of guns by default are defined by two table fields: their @{lvl1_fields.consts|consts} and their @{lvl1_fields.properties|properties}.
-- @{lvl1_fields.properties|properties} define nearly everything, from how a gun handles to how it looks, what model it uses,
-- while @{lvl1_fields.consts|consts} define attributes that should never change, like bones within the gun, framerates,
--- wether the gun is allowed to have certain attributes at all. The rest is mainly for internal workings of the mod.
+-- hwether the gun is allowed to have certain attributes at all. The other fields of the class define tracking variables or other important things for the internal workings.
+--
+-- There are essentially only 2 fields you must define to register a gun: @{gun.itemstring|itemstring}, @{gun.name|name}, and @{lvl1_fields.properties|properties}
+-- To hold the gun, the item defined in itemstring must exist. To have a functional gun however, more will need to be changed in terms of properties.
--
-- Guns4d uses a class system for most moving parts- including the gun. New guns therefore are created with the :inherit(def) method,
-- where def is the definition of your new gun- or rather the changed parts of it. So to make a new gun you can run Guns4d.gun:inherit()
-- or you can do the same thing with a seperate class of weapons. Set name to "__template" for template classes of guns.
--
--- @class Gun
--- @compact
-
-local Vec = vector
-
---- gun fields
--
--- @table gun
+-- @class gun
-- @field properties @{lvl1_fields.properties|properties} which define the vast majority of gun attributes and may change accross instances
-- @field consts @{lvl1_fields.consts|constants} which define gun attributes and should not be changed in an instance of the gun
-- @field offsets runtime storage of @{lvl1_fields.offsets|offsets} generated by recoil sway wag or any other element.
-- @compact
local gun_default = {
- --- `string` the name of the gun. Set to __template for guns which have no instances.
+ --- `string` the name of the gun. Set to __template for guns which have no instances and serve as a template. It is safe to set name to the same as @{gun.itemstring}
name = "__guns4d:default__",
--- `ItemStack` the gun itemstack. Remember to player:set_wielded_item(self.itemstack) when making meta or itemstack changes.
itemstack = nil,
@@ -40,7 +41,7 @@ local gun_default = {
inventory_image_magless = nil,
--- `string` inventory image for when the gun is loaded. This is added automatically during construction.
inventory_image = nil,
- --- `string` the itemstring of the gun- i.e. "guns4d_pack_1:m4". Set to "" for __template guns.
+ --- `string` the itemstring of the gun- i.e. `"guns4d_pack_1:m4"`. Set to `""` for `__template` guns.
itemstring = "",
--- list of registered guns, **DO NOT MODIFY** I really need a metatable for this class...
_registered = {},
@@ -48,7 +49,7 @@ local gun_default = {
bolt_charged = false,
--- `table` list of particle spawner handles (generated by firing)
particle_spawners = {},
- --- `int` the active index of the firemode from @{lvl1_fields.properties.firemodes}
+ --- `int` the active index of the firemode from @{lvl1_fields.properties.firemodes|firemodes}
current_firemode = 1,
--- `float` walking time used to generate the figure 8 for wag
walking_tick = 0,
@@ -90,11 +91,6 @@ local gun_default = {
flash_offset = Vec.new(),
--- `int`=600 The number of rounds (cartidges) this gun can throw per minute. Used by update(), fire() and default controls
firerateRPM = 600,
- --- the item entity's attributes. [DOCUMENTATION NEEDED]
- --[[item = {
- collisionbox = ((not Guns4d.config.realistic_items) and {-.1,-.1,-.1, .1,.1,.1}) or {-.1,-.05,-.1, .1,.15,.1},
- selectionbox = {-.1,-.1,-.1, .1,.1,.1}
- },]]
--- properties.hip
-- @table gun.properties.hip
-- @compact
@@ -251,7 +247,8 @@ local gun_default = {
auto = Guns4d.default_controls.auto,
reload = Guns4d.default_controls.reload,
on_use = Guns4d.default_controls.on_use,
- firemode = Guns4d.default_controls.firemode
+ firemode = Guns4d.default_controls.firemode,
+ jump_cancel_ads = Guns4d.default_controls.jump_cancel_ads
},
--- `table` containing a list of actions for touch screen users passed to @{Control_handler}
touch_control_actions = {
@@ -260,7 +257,8 @@ local gun_default = {
auto = Guns4d.default_touch_controls.auto,
reload = Guns4d.default_touch_controls.reload,
on_secondary_use = Guns4d.default_touch_controls.on_secondary_use,
- firemode = Guns4d.default_touch_controls.firemode
+ firemode = Guns4d.default_touch_controls.firemode,
+ jump_cancel_ads = Guns4d.default_touch_controls.jump_cancel_ads
},
--[[ parts framework coming soon. example for m4
parts = {
@@ -313,14 +311,13 @@ local gun_default = {
-- {action="store", time=.5, anim="store", sounds = {sound="ar_mag_store"}},
-- {action="load", time=.5, anim="load", sounds = {sound="ar_mag_load", delay = .25}},
-- {action="charge", time=.5, anim="charge", sounds={sound="ar_charge", delay = .2}}
- reload = {
- __overfill=true,
- },
+ reload = {},
--- properties.ammo
--
-- @table gun.properties.ammo
-- @compact
ammo = { --#8
+ --- `bool` wether the gun only uses a magazine or accepts raw ammunition too.
magazine_only = false,
--capacity = 0, --this is only needed if magazine_only = false
--- `table` a list of accepted bullet itemstrings
@@ -335,7 +332,7 @@ local gun_default = {
-- @table gun.properties.visuals
-- @compact
visuals = {
- --- name of mesh to display
+ --- name of mesh to display. Currently only supports b3d
mesh = nil,
--- list of textures to use
textures = {},
diff --git a/classes/Player_handler.lua b/classes/Player_handler.lua
index ad889aa..2644c46 100644
--- a/classes/Player_handler.lua
+++ b/classes/Player_handler.lua
@@ -54,8 +54,8 @@ function player_handler:update(dt)
self.gun:update(dt) --gun should be updated first so self.dir is available.
self.control_handler:update(dt)
self.player_model_handler:update(dt)
- player:set_eye_offset(self.gun.total_offsets.look_trans*10)
- self.last_eye_offset = self.gun.total_offsets.look_trans
+ --player:set_eye_offset(self.gun.total_offsets.look_trans*10)
+ --self.last_eye_offset = self.gun.total_offsets.look_trans
--this has to be checked after control handler
if TICK % 4 == 0 then
diff --git a/classes/Player_model_handler.lua b/classes/Player_model_handler.lua
index e7af669..e9c0ce4 100644
--- a/classes/Player_model_handler.lua
+++ b/classes/Player_model_handler.lua
@@ -156,10 +156,12 @@ function player_model:update(dt)
self:update_aiming(dt)
self:update_head(dt)
self:update_arm_bones(dt)
+ self:update_look_offset(dt)
end
local ip_time = Guns4d.config.player_axial_interpolation_time
local ip_time2 = Guns4d.config.translation_interpolation_time
+local ttransform = leef.math.mat4.identity()
function player_model:update_aiming(dt)
--gun bones:
local player = self.player
@@ -168,19 +170,18 @@ function player_model:update_aiming(dt)
local pprops = handler:get_properties()
local vs = pprops.visual_size
- local player_trans = gun.total_offsets.player_trans --player translation.
+ local player_trans = gun.total_offsets.player_trans
local hip_pos = self.offsets.global.arm_right
local ip = Guns4d.math.smooth_ratio(handler.control_handler.ads_location or 0)
local ip_inv = 1-ip
local pos = self.gun_bone_location --reuse allocated table
- --interpolate between the eye and arm pos
- pos.x = ((hip_pos.x*10*ip_inv) + (player_trans.x*10/vs.y)) + ((gun and gun.properties.ads.horizontal_offset*10*ip/vs.y) or 0 )
- pos.y = ((hip_pos.y*10*ip_inv) + (player_trans.y*10/vs.y)) + (pprops.eye_height*10*ip/vs.y)
- pos.z = ((hip_pos.z*10*ip_inv) + (player_trans.z*10/vs.y))
+ --hip pos is already relative to local scale
+ pos.x = (hip_pos.x*10*ip_inv)+( (player_trans.x*10) + ((gun and gun.properties.ads.horizontal_offset*10*ip) or 0 ))/vs.x
+ pos.y = (hip_pos.y*10*ip_inv)+( (player_trans.y*10) + (pprops.eye_height*10*ip) )/vs.y
+ pos.z = (hip_pos.z*10*ip_inv)+( (player_trans.z*10) )/vs.z
- local dir = vector.rotate(gun.local_paxial_dir, {x=gun.player_rotation.x*math.pi/180,y=0,z=0})
- local rot = vector.dir_to_rotation(dir)
+ local xr,yr,zr = gun:get_rotation_transform(ttransform, 0,0,0, nil,nil, nil,0, 0,0,0):get_rot_irrlicht_bone()
player:set_bone_override(self.bone_aliases.gun,
{
position = {
@@ -189,7 +190,7 @@ function player_model:update_aiming(dt)
absolute = true
},
rotation = {
- vec={x=-rot.x,y=-rot.y,z=0},
+ vec={x=xr,y=yr,z=zr},
interpolation=ip_time,
absolute = true
}
@@ -200,9 +201,12 @@ function player_model:update_aiming(dt)
-- minetest.chat_send_all(dump(pos))
end
-function player_model:update_look_offsets()
- player:set_eye_offset(self.gun.total_offsets.look_trans*10)
- self.last_eye_offset = self.gun.total_offsets.look_trans
+function player_model:update_look_offset(dt)
+ local gun = self.handler.gun
+ self.player:set_eye_offset(gun.total_offsets.look_trans*10)
+end
+function player_model:unset_look_offset()
+ self.player:set_eye_offset()
end
--default arm code, compatible with MTG model.
function player_model:update_arm_bones(dt)
@@ -257,6 +261,7 @@ function player_model:prepare_deletion()
--[[if minetest.get_modpath("player_api") then
player_api.set_model(self.player, self.old)
end]]
+ self:unset_look_offset()
local player = self.player
player:set_bone_override(self.bone_aliases.arm_left, {})
player:set_bone_override(self.bone_aliases.arm_right, {})
diff --git a/classes/Sprite_scope.lua b/classes/Sprite_scope.lua
index 0f2541f..4da4697 100644
--- a/classes/Sprite_scope.lua
+++ b/classes/Sprite_scope.lua
@@ -1,18 +1,16 @@
local Sprite_scope = leef.class.new_class:inherit({
images = {
- fore = {
+ --[[fore = {
texture = "scope_fore.png",
scale = {x=13,y=13},
- movement_multiplier = 1,
paxial = false,
},
back = {
texture = "scope_back.png",
scale = {x=10,y=10},
- movement_multiplier = -1,
opacity_delay = 2,
paxial = true,
- },
+ },]]
--[[reticle = {
texture = "gun_mrkr.png",
scale = {x=.5,y=.5},
@@ -49,6 +47,11 @@ local Sprite_scope = leef.class.new_class:inherit({
Guns4d.sprite_scope = Sprite_scope
--rename to draw?
+local vec3_in = vector.new()
+local mat4 = leef.math.mat4
+local vec4_forward = {0,0,1,0}
+local vec4_dir = {0,0,0,0}
+local transform = mat4.new()
function Sprite_scope:update()
local handler = self.handler
local gun = self.gun
@@ -58,28 +61,38 @@ function Sprite_scope:update()
self.fov_set = true
handler:set_fov(80/self.magnification)
end
- local dir = gun.local_dir
local ratio = handler.wininfo.size.x/handler.wininfo.size.y
-
- if control_handler.ads_location ~= 1 then
- dir = dir + (self.gun.properties.ads.offset+vector.new(gun.properties.ads.horizontal_offset,0,0))*0
- end
- local fov = self.player:get_fov()
- local real_aim = Guns4d.math.rltv_point_to_hud(dir, fov, ratio)
- local anim_aim = Guns4d.math.rltv_point_to_hud(vector.rotate({x=0,y=0,z=1}, gun.animation_rotation*math.pi/180), fov, ratio)
- real_aim.x = real_aim.x+anim_aim.x; real_aim.y = real_aim.y+anim_aim.y
-
- --print(dump(self.gun.animation_rotation))
- local paxial_aim = Guns4d.math.rltv_point_to_hud(gun.local_paxial_dir, fov, ratio)
- --so custom scopes can do their thing without doing more calcs
- self.hud_projection_real = real_aim
- self.hud_projection_paxial = paxial_aim
+ local pprops = handler:get_properties()
+ local hip_trans = gun.properties.ads.offset
+ local player_trans = gun.total_offsets.player_trans
for i, v in pairs(self.elements) do
- if self.images[i].paxial then
- self.player:hud_change(v, "position", {x=(paxial_aim.x*self.images[i].movement_multiplier)+.5, y=(paxial_aim.y*self.images[i].movement_multiplier)+.5})
+ local image = self.images[i]
+ local projection_pos=image.projection_pos
+ local relative_pos
+ if projection_pos then
+ vec3_in.x = projection_pos.x/10
+ vec3_in.y = projection_pos.y/10
+ vec3_in.z = projection_pos.z/10
+ relative_pos = gun:get_pos(vec3_in, true, true, true)
+
+ relative_pos.x = relative_pos.x - (player_trans.x + (gun and gun.properties.ads.horizontal_offset or 0))
+ relative_pos.y = relative_pos.y - hip_trans.y - (player_trans.y + pprops.eye_height)
+ relative_pos.z = relative_pos.z - (player_trans.z)
else
- self.player:hud_change(v, "position", {x=(real_aim.x*self.images[i].movement_multiplier)+.5, y=(real_aim.y*self.images[i].movement_multiplier)+.5})
+ local r = gun.total_offsets.gun_axial
+ local a = gun.animation_rotation
+ vec4_dir = mat4.mul_vec4(vec4_dir, gun:get_rotation_transform(transform,nil,nil,nil, nil,nil, 0,0), vec4_forward)
+ relative_pos = vec3_in
+ relative_pos.x = vec4_dir[1]
+ relative_pos.y = vec4_dir[2]
+ relative_pos.z = vec4_dir[3]
+
+ --relative_pos = gun:get_dir(true)
end
+
+ local hud_pos = Guns4d.math.rltv_point_to_hud(relative_pos, 80/self.magnification, ratio)
+ --print(i, hud_pos.x, hud_pos.y)
+ self.player:hud_change(v, "position", {x=hud_pos.x+.5, y=hud_pos.y+.5})
end
elseif self.fov_set then
self.fov_set = false
diff --git a/default_controls.lua b/default_controls.lua
index 8be3b1f..83663e9 100644
--- a/default_controls.lua
+++ b/default_controls.lua
@@ -28,6 +28,16 @@ Guns4d.default_controls.auto = {
end
end
}
+Guns4d.default_controls.jump_cancel_ads = {
+ conditions = {"jump"},
+ loop = false,
+ timer = 0,
+ func = function(self, active, interrupted, data, busy_list, gun, handler)
+ if active then
+ handler.control_handler.ads = false
+ end
+ end
+}
Guns4d.default_controls.firemode = {
conditions = {"sneak", "zoom"},
loop = false,
diff --git a/docs/class/Gun.html b/docs/class/Gun.html
index 764850e..99dd4b7 100644
--- a/docs/class/Gun.html
+++ b/docs/class/Gun.html
@@ -3,7 +3,7 @@
guns are defined by two table fields: their consts and their properties.
-properties define nearly everything, from how a gun handles to how it looks, what model it uses,
-while consts define attributes that should never change, like bones within the gun, framerates,
-wether the gun is allowed to have certain attributes at all. The rest is mainly for internal workings of the mod.
+
The appearance and handling of guns by default are defined by two table fields: their consts and their properties.
+properties define nearly everything, from how a gun handles to how it looks, what model it uses,
+while consts define attributes that should never change, like bones within the gun, framerates,
+hwether the gun is allowed to have certain attributes at all. The other fields of the class define tracking variables or other important things for the internal workings.
+
There are essentially only 2 fields you must define to register a gun: itemstring, name, and properties
+To have a functional gun however, more will need to be changed in terms of properties.
Guns4d uses a class system for most moving parts- including the gun. New guns therefore are created with the :inherit(def) method,
where def is the definition of your new gun- or rather the changed parts of it. So to make a new gun you can run Guns4d.gun:inherit()
or you can do the same thing with a seperate class of weapons. Set name to "__template" for template classes of guns.
string the name of the gun. Set to __template for guns which have no instances.
+
string the name of the gun. Set to __template for guns which have no instances and serve as a template. It is safe to set name to the same as gun.itemstring
table indexed list of modifiers not set by the gun but to be applied to the gun. After changing, gun:update_modifiers() must be called to update it. Also may contain lists of modifiers.
the class from which this class was inherited from
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/class/player_model_handler.html b/docs/class/player_model_handler.html
index 2476c42..608ea6d 100644
--- a/docs/class/player_model_handler.html
+++ b/docs/class/player_model_handler.html
@@ -16,7 +16,7 @@
diff --git a/docs/index.js b/docs/index.js
index 0ba995b..75c0c31 100644
--- a/docs/index.js
+++ b/docs/index.js
@@ -1,10 +1,11 @@
var docs = [
-{path:"class/Gun.html", type:"class", title:"Gun.Gun", text:"Gun class Defining a gun: *method documentation coming soon* (or never...) guns are defined by two table fields: their consts and their properties. properties define nearly everything, from how a gun handles to how it looks, what model it uses, while consts define attributes that should never change, like bones within the gun, framerates, wether the gun is allowed to have certain attributes at all. The rest is mainly for internal workings of the mod. Guns4d uses a class system for most moving parts- including the gun. New guns therefore are created with the :inherit(def) method, where def is the definition of your new gun- or rather the changed parts of it. So to make a new gun you can run Guns4d.gun:inherit() or you can do the same thing with a seperate class of weapons. Set name to \"__template\" for template classes of guns."},
+{path:"class/gun.html", type:"class", title:"Gun.gun", text:"Gun class fields Defining a gun: *method documentation coming soon* (or never...) The appearance and handling of guns by default are defined by two table fields: their consts and their properties. properties define nearly everything, from how a gun handles to how it looks, what model it uses, while consts define attributes that should never change, like bones within the gun, framerates, hwether the gun is allowed to have certain attributes at all. The other fields of the class define tracking variables or other important things for the internal workings. There are essentially only 2 fields you must define to register a gun: itemstring, name, and properties To have a functional gun however, more will need to be changed in terms of properties. Guns4d uses a class system for most moving parts- including the gun. New guns therefore are created with the :inherit(def) method, where def is the definition of your new gun- or rather the changed parts of it. So to make a new gun you can run Guns4d.gun:inherit() or you can do the same thing with a seperate class of weapons. Set name to \"__template\" for template classes of guns."},
{path:"class/player_model_handler.html", type:"class", title:"Player_model_handler.player_model_handler", text:"player_model_handler defining the player model when holding a gun each player model should have a \"gun holding equivelant\". There are numerous reasons for this first and foremost is that because Minetest is a [redacted mindless insults]. because of this you cannot unset bone offsets and return to normal animations. Bone offsets are needed for the arms to aim at the gun there's no simple way around this fact. Since every model is different custom behavior has to be defined for most."},
{path:"module/misc_helpers.html", type:"module", title:"misc_helpers", text:""},
{path:"module/play_sound.html", type:"module", title:"play_sound", text:"implements tools for quickly playing audio."},
{path:"module/Bullet_hole.html", type:"module", title:"Bullet_hole", text:""},
{path:"module/Control_handler.html", type:"module", title:"Control_handler", text:""},
+{path:"module/Gun.html", type:"module", title:"Gun", text:""},
{path:"module/play_sound.html#guns4d_soundspec.min_hear_distance", type:"field", title:"guns4d_soundspec.min_hear_distance", text:"float this is useful if you wish to play a sound which has a \"far\" sound, such as distant gunshots. incompatible with to_player"},
{path:"module/play_sound.html#guns4d_soundspec.sounds", type:"field", title:"guns4d_soundspec.sounds", text:"table a weighted_randoms table for randomly selecting sounds. The output will overwrite the sound field."},
{path:"module/play_sound.html#guns4d_soundspec.to_player", type:"field", title:"guns4d_soundspec.to_player", text:"objRef 4dguns changes to_player so it only plays positionless audio (as it is only intended for first person audio). If set to string \"from_player\" and player present"},
@@ -13,105 +14,113 @@ var docs = [
{path:"module/play_sound.html#guns4d_soundspec.attenuation_rate", type:"field", title:"guns4d_soundspec.attenuation_rate", text:"float the rate of dropoff for a sound. I figure this is a bit more intuitive then jacking the gain up super high for every sound... Set the default in config."},
{path:"module/play_sound.html#guns4d_soundspec.split_audio_by_perspective", type:"field", title:"guns4d_soundspec.split_audio_by_perspective", text:"bool [GUN CLASS SPECIFIC] tells the gun wether to split into third and first person (positionless) audio and adjust gain."},
{path:"module/play_sound.html#guns4d_soundspec.third_person_gain_multiplier", type:"field", title:"guns4d_soundspec.third_person_gain_multiplier", text:"float [GUN CLASS SPECIFIC] replaces the constant/config value \"third_person_gain_multiplier/THIRD_PERSON_GAIN_MULTIPLIER\"."},
-{path:"class/Gun.html#gun.properties", type:"field", title:"gun.properties", text:"properties which define the vast majority of gun attributes and may change accross instances"},
-{path:"class/Gun.html#gun.consts", type:"field", title:"gun.consts", text:"constants which define gun attributes and should not be changed in an instance of the gun"},
-{path:"class/Gun.html#gun.offsets", type:"field", title:"gun.offsets", text:"runtime storage of offsets generated by recoil sway wag or any other element."},
-{path:"class/Gun.html#gun.name", type:"field", title:"gun.name", text:"string the name of the gun. Set to __template for guns which have no instances."},
-{path:"class/Gun.html#gun.itemstack", type:"field", title:"gun.itemstack", text:"ItemStack itemstack held by the player"},
-{path:"class/Gun.html#gun.gun_entity", type:"field", title:"gun.gun_entity", text:"ObjRef the gun entity"},
-{path:"class/Gun.html#gun.itemstring", type:"field", title:"gun.itemstring", text:"string the itemstring of the gun- i.e. \"guns4d_pack_1:m4\". Set to \"\" for __template guns."},
-{path:"class/Gun.html#gun._registered", type:"field", title:"gun._registered", text:"list of registered guns, *DO NOT MODIFY* I really need a metatable for this class..."},
-{path:"class/Gun.html#gun.bolt_charged", type:"field", title:"gun.bolt_charged", text:"bool is the bolt charged"},
-{path:"class/Gun.html#gun.particle_spawners", type:"field", title:"gun.particle_spawners", text:"table list of particle spawner handles (generated by firing)"},
-{path:"class/Gun.html#gun.current_firemode", type:"field", title:"gun.current_firemode", text:"int the active index of the firemode from lvl1_fields.properties.firemodes"},
-{path:"class/Gun.html#gun.walking_tick", type:"field", title:"gun.walking_tick", text:"float walking time used to generate the figure 8 for wag"},
-{path:"class/Gun.html#gun.time_since_last_fire", type:"field", title:"gun.time_since_last_fire", text:"float"},
-{path:"class/Gun.html#gun.time_since_creation", type:"field", title:"gun.time_since_creation", text:"float"},
-{path:"class/Gun.html#gun.rechamber_time", type:"field", title:"gun.rechamber_time", text:"float time left for the chamber to cycle (for firerates)"},
-{path:"class/Gun.html#gun.burst_queue", type:"field", title:"gun.burst_queue", text:"int number of rounds left that need to be fired after a burst fire"},
-{path:"class/Gun.html#gun.muzzle_flash", type:"field", title:"gun.muzzle_flash", text:"function"},
-{path:"class/Gun.html#gun.gun_translation", type:"field", title:"gun.gun_translation", text:"vec3 translation of the gun relative to the \"gun\" bone or the player axial rotation."},
-{path:"class/Gun.html#lvl1_fields.properties.hip", type:"field", title:"lvl1_fields.properties.hip", text:"table hipfire properties"},
-{path:"class/Gun.html#lvl1_fields.properties.ads", type:"field", title:"lvl1_fields.properties.ads", text:"table aiming (\"aiming down sights\") properties"},
-{path:"class/Gun.html#lvl1_fields.properties.firemodes", type:"field", title:"lvl1_fields.properties.firemodes", text:"table list of firemodes"},
-{path:"class/Gun.html#lvl1_fields.properties.firemode_inventory_overlays", type:"field", title:"lvl1_fields.properties.firemode_inventory_overlays", text:"table list of corresponding images for firemodes"},
-{path:"class/Gun.html#lvl1_fields.properties.recoil", type:"field", title:"lvl1_fields.properties.recoil", text:"table defines the guns recoil"},
-{path:"class/Gun.html#lvl1_fields.properties.sway", type:"field", title:"lvl1_fields.properties.sway", text:"table defines the guns idle sway"},
-{path:"class/Gun.html#lvl1_fields.properties.wag", type:"field", title:"lvl1_fields.properties.wag", text:"table defines the movement of the gun while walking"},
-{path:"class/Gun.html#lvl1_fields.properties.charging", type:"field", title:"lvl1_fields.properties.charging", text:"table defines how rounds are chambered into the gun"},
-{path:"class/Gun.html#lvl1_fields.properties.ammo", type:"field", title:"lvl1_fields.properties.ammo", text:"defines what ammo the gun uses"},
-{path:"class/Gun.html#lvl1_fields.properties.visuals", type:"field", title:"lvl1_fields.properties.visuals", text:"defines visual attributes of the gun"},
-{path:"class/Gun.html#lvl1_fields.properties.breathing_scale", type:"field", title:"lvl1_fields.properties.breathing_scale", text:"float=.5 max angular deviation (vertical) from breathing"},
-{path:"class/Gun.html#lvl1_fields.properties.flash_offset", type:"field", title:"lvl1_fields.properties.flash_offset", text:"vector the offset from the center of the muzzle flash. Used by fire()"},
-{path:"class/Gun.html#lvl1_fields.properties.firerateRPM", type:"field", title:"lvl1_fields.properties.firerateRPM", text:"int=600 The number of rounds (cartidges) this gun can throw per minute. Used by update(), fire() and default controls"},
-{path:"class/Gun.html#lvl1_fields.properties.item", type:"field", title:"lvl1_fields.properties.item", text:"the item entity's attributes. This will later include held item definition..."},
-{path:"class/Gun.html#gun.properties.hip.offset", type:"field", title:"gun.properties.hip.offset", text:"vector the offset of the gun (relative to the right arm's default position) at hip."},
-{path:"class/Gun.html#gun.properties.hip.axis_rotation_ratio", type:"field", title:"gun.properties.hip.axis_rotation_ratio", text:"the ratio that the look rotation is expressed through player_axial (rotated around the viewport) rotation as opposed to gun_axial (rotating the entity)."},
-{path:"class/Gun.html#gun.properties.hip.sway_vel_mul", type:"field", title:"gun.properties.hip.sway_vel_mul", text:"sway speed multiplier while at hip"},
-{path:"class/Gun.html#gun.properties.hip.sway_angle_mul", type:"field", title:"gun.properties.hip.sway_angle_mul", text:"sway angle multiplier while at hip+"},
-{path:"class/Gun.html#gun.properties.ads.offset", type:"field", title:"gun.properties.ads.offset", text:"vector the offset of the gun relative to the eye's position at hip."},
-{path:"class/Gun.html#gun.properties.ads.horizontal_offset", type:"field", title:"gun.properties.ads.horizontal_offset", text:"float the horizontal offset of the eye when aiming"},
-{path:"class/Gun.html#gun.properties.ads.aim_time", type:"field", title:"gun.properties.ads.aim_time", text:"the time it takes to go into full aim"},
-{path:"class/Gun.html#lvl1_fields.properties.burst", type:"field", title:"lvl1_fields.properties.burst", text:"int=3 how many rounds in burst using when firemode is at \"burst\""},
-{path:"class/Gun.html#gun.properties.firemodes."single"", type:"field", title:"gun.properties.firemodes.\"single\"", text:""},
-{path:"class/Gun.html#gun.properties.firemodes."burst"", type:"field", title:"gun.properties.firemodes.\"burst\"", text:""},
-{path:"class/Gun.html#gun.properties.firemodes."auto"", type:"field", title:"gun.properties.firemodes.\"auto\"", text:""},
-{path:"class/Gun.html#lvl1_fields.properties.infinite_inventory_overlay", type:"field", title:"lvl1_fields.properties.infinite_inventory_overlay", text:"string overlay on the item to use when infinite ammo is on"},
-{path:"class/Gun.html#gun.properties.firemode_inventory_overlays.single", type:"field", title:"gun.properties.firemode_inventory_overlays.single", text:"\"inventory_overlay_single.png\""},
-{path:"class/Gun.html#gun.properties.firemode_inventory_overlays.auto", type:"field", title:"gun.properties.firemode_inventory_overlays.auto", text:"\"inventory_overlay_auto.png\""},
-{path:"class/Gun.html#gun.properties.firemode_inventory_overlays.burst", type:"field", title:"gun.properties.firemode_inventory_overlays.burst", text:"\"inventory_overlay_burst.png\""},
-{path:"class/Gun.html#gun.properties.firemode_inventory_overlays.safe", type:"field", title:"gun.properties.firemode_inventory_overlays.safe", text:"\"inventory_overlay_safe.png\" (unimplemented firemode)"},
-{path:"class/Gun.html#gun.properties.recoil.velocity_correction_factor", type:"field", title:"gun.properties.recoil.velocity_correction_factor", text:"float TL:DR higher decreases recoil at expense of smoothness. 1/value is the deviation of a normalized bell curve, where x is the time since firing. this means that increasing it decreases the time it takes for the angular velocity to fully \"decay\"."},
-{path:"class/Gun.html#gun.properties.recoil.target_correction_factor", type:"field", title:"gun.properties.recoil.target_correction_factor", text:"float Correction of recoil offset per second is calculated as such: target_correction_factor[axis]time_since_firerecoil[axis]"},
-{path:"class/Gun.html#gun.properties.recoil.target_correction_max_rate", type:"field", title:"gun.properties.recoil.target_correction_max_rate", text:"float The maximum rate per second of recoil offset as determined with target_correction_factor"},
-{path:"class/Gun.html#gun.properties.recoil.angular_velocity_max", type:"field", title:"gun.properties.recoil.angular_velocity_max", text:"float caps the recoil velocity that can stack up from shots."},
-{path:"class/Gun.html#gun.properties.recoil.angular_velocity", type:"field", title:"gun.properties.recoil.angular_velocity", text:"vector {x=float, y=float}, defines the initial angular velocity produced by firing the gun"},
-{path:"class/Gun.html#gun.properties.recoil.bias", type:"field", title:"gun.properties.recoil.bias", text:"vector {x=float, y=float}, ranges -1 to 1. Defines the probability of the recoil being positive or negative for any given axis."},
-{path:"class/Gun.html#gun.properties.recoil.hipfire_multiplier", type:"field", title:"gun.properties.recoil.hipfire_multiplier", text:"float angular velocity multiplier when firing from the hip"},
-{path:"class/Gun.html#gun.properties.sway.max_angle", type:"field", title:"gun.properties.sway.max_angle", text:"float maximum angle of the sway"},
-{path:"class/Gun.html#gun.properties.sway.angular_velocity", type:"field", title:"gun.properties.sway.angular_velocity", text:"float angular velocity the sway"},
-{path:"class/Gun.html#gun.properties.sway.hipfire_angle_multiplier", type:"field", title:"gun.properties.sway.hipfire_angle_multiplier", text:"float maximum angle multiplier while the gun is at the hip"},
-{path:"class/Gun.html#gun.properties.sway.hipfire_velocity_multiplier", type:"field", title:"gun.properties.sway.hipfire_velocity_multiplier", text:"float velocity multiplier while the gun is at the hip"},
-{path:"class/Gun.html#gun.properties.wag.cycle_speed", type:"field", title:"gun.properties.wag.cycle_speed", text:"float=1.6 the cycle speed multiplier"},
-{path:"class/Gun.html#gun.properties.wag.decay_speed", type:"field", title:"gun.properties.wag.decay_speed", text:"float=1 decay factor when walking has stopped and offset remains."},
-{path:"class/Gun.html#gun.properties.wag.offset", type:"field", title:"gun.properties.wag.offset", text:"table containing angular deviation while walking in the same format as an offset vector. Acts as a multiplier on the figure-8 generated while walking."},
-{path:"class/Gun.html#lvl1_fields.properties.pc_control_actions", type:"field", title:"lvl1_fields.properties.pc_control_actions", text:"table containing a list of actions for PC users passed to Control_handler"},
-{path:"class/Gun.html#lvl1_fields.properties.touch_control_actions", type:"field", title:"lvl1_fields.properties.touch_control_actions", text:"table containing a list of actions for touch screen users passed to Control_handler"},
-{path:"class/Gun.html#gun.properties.charging.require_draw_on_swap", type:"field", title:"gun.properties.charging.require_draw_on_swap", text:"bool defines wether the draw animation is played on swap (when loaded). Used in the instance construction method"},
-{path:"class/Gun.html#gun.properties.charging.bolt_charge_mode", type:"field", title:"gun.properties.charging.bolt_charge_mode", text:"string \"none\" bolt will never need to be charged after reload, \"catch\" when fired to empty bolt will not need to be charged after reload, \"no_catch\" bolt will always need to be charged after reload."},
-{path:"class/Gun.html#gun.properties.charging.draw_time", type:"field", title:"gun.properties.charging.draw_time", text:"float the time it takes to swap to the gun"},
-{path:"class/Gun.html#gun.properties.charging.draw_animation", type:"field", title:"gun.properties.charging.draw_animation", text:"string name of the animation to play from visuals.animations"},
-{path:"class/Gun.html#gun.properties.charging.draw_sound", type:"field", title:"gun.properties.charging.draw_sound", text:"string name of the sound to play from sounds"},
-{path:"class/Gun.html#lvl1_fields.properties.reload", type:"field", title:"lvl1_fields.properties.reload", text:"and ordered list of reloading states used by default_controls. the default reload states for a magazine operated weapon, copied from the m4. Example"},
-{path:"class/Gun.html#gun.properties.ammo.accepted_bullets", type:"field", title:"gun.properties.ammo.accepted_bullets", text:"table a list of accepted bullet itemstrings"},
-{path:"class/Gun.html#gun.properties.ammo.accepted_magazines", type:"field", title:"gun.properties.ammo.accepted_magazines", text:"table a list of accepted magazine itemstrings"},
-{path:"class/Gun.html#gun.properties.ammo.initial_mag", type:"field", title:"gun.properties.ammo.initial_mag", text:"string the mag the gun starts with. Set to \"empty\" for no mag, otherwise it defaults to accepted_magazines[1] (if present)"},
-{path:"class/Gun.html#gun.properties.visuals.backface_culling", type:"field", title:"gun.properties.visuals.backface_culling", text:"toggles backface culling"},
-{path:"class/Gun.html#gun.properties.visuals.animations", type:"field", title:"gun.properties.visuals.animations", text:"a table of animations in the format {x=int, y=float}. Indexes define the name of the animation to be refrenced by other functions of the gun."},
-{path:"class/Gun.html#lvl1_fields.properties.sounds", type:"field", title:"lvl1_fields.properties.sounds", text:"a table of soundspecs to be referenced by other functions"},
-{path:"class/Gun.html#lvl1_fields.offsets.recoil", type:"field", title:"lvl1_fields.offsets.recoil", text:""},
-{path:"class/Gun.html#lvl1_fields.offsets.sway", type:"field", title:"lvl1_fields.offsets.sway", text:""},
-{path:"class/Gun.html#lvl1_fields.offsets.walking", type:"field", title:"lvl1_fields.offsets.walking", text:""},
-{path:"class/Gun.html#lvl1_fields.offsets.breathing", type:"field", title:"lvl1_fields.offsets.breathing", text:""},
-{path:"class/Gun.html#lvl1_fields.offsets.look", type:"field", title:"lvl1_fields.offsets.look", text:""},
-{path:"class/Gun.html#gun.animation_rotation", type:"field", title:"gun.animation_rotation", text:"vector containing the offset from animations, this will be generated if {@consts.ANIMATIONS_OFFSET_AIM}=true"},
-{path:"class/Gun.html#gun.gun_axial", type:"field", title:"gun.gun_axial", text:"total offsets of the gun in the same format as a an offset [[total_offsets = {"},
-{path:"class/Gun.html#lvl1_fields.consts.AIM_OUT_AIM_IN_SPEED_RATIO", type:"field", title:"lvl1_fields.consts.AIM_OUT_AIM_IN_SPEED_RATIO", text:""},
-{path:"class/Gun.html#lvl1_fields.consts.KEYFRAME_SAMPLE_PRECISION", type:"field", title:"lvl1_fields.consts.KEYFRAME_SAMPLE_PRECISION", text:"frequency of keyframe samples for animation offsets and"},
-{path:"class/Gun.html#lvl1_fields.consts.DEFAULT_MAX_HEAR_DISTANCE", type:"field", title:"lvl1_fields.consts.DEFAULT_MAX_HEAR_DISTANCE", text:"default max hear distance when not specified"},
-{path:"class/Gun.html#lvl1_fields.consts.DEFAULT_FPS", type:"field", title:"lvl1_fields.consts.DEFAULT_FPS", text:"fps=60 animation fps i.e. during firing when no length is specified"},
-{path:"class/Gun.html#lvl1_fields.consts.HAS_RECOIL", type:"field", title:"lvl1_fields.consts.HAS_RECOIL", text:"bool"},
-{path:"class/Gun.html#lvl1_fields.consts.HAS_BREATHING", type:"field", title:"lvl1_fields.consts.HAS_BREATHING", text:"bool"},
-{path:"class/Gun.html#lvl1_fields.consts.HAS_SWAY", type:"field", title:"lvl1_fields.consts.HAS_SWAY", text:"bool"},
-{path:"class/Gun.html#lvl1_fields.consts.HAS_WAG", type:"field", title:"lvl1_fields.consts.HAS_WAG", text:"bool"},
-{path:"class/Gun.html#lvl1_fields.consts.HAS_GUN_AXIAL_OFFSETS", type:"field", title:"lvl1_fields.consts.HAS_GUN_AXIAL_OFFSETS", text:"bool wether the gun rotates on it's own axis instead of the player's view (i.e. ironsight misalignments)"},
-{path:"class/Gun.html#lvl1_fields.consts.ANIMATIONS_OFFSET_AIM", type:"field", title:"lvl1_fields.consts.ANIMATIONS_OFFSET_AIM", text:"wether animations create an offset"},
-{path:"class/Gun.html#lvl1_fields.consts.LOOP_IDLE_ANIM", type:"field", title:"lvl1_fields.consts.LOOP_IDLE_ANIM", text:"whether the idle animation changes or not"},
-{path:"class/Gun.html#lvl1_fields.consts.THIRD_PERSON_GAIN_MULTIPLIER", type:"field", title:"lvl1_fields.consts.THIRD_PERSON_GAIN_MULTIPLIER", text:"general gain multiplier for third persons when hearing sounds"},
-{path:"class/Gun.html#lvl1_fields.consts.ROOT_BONE", type:"field", title:"lvl1_fields.consts.ROOT_BONE", text:"the root bone of the gun (for animation offsets)"},
-{path:"class/Gun.html#lvl1_fields.consts.MAG_BONE", type:"field", title:"lvl1_fields.consts.MAG_BONE", text:"string=\"magazine\",the bone of the magazine in the gun (for dropping mags)"},
-{path:"class/Gun.html#lvl1_fields.consts.ARM_RIGHT_BONE", type:"field", title:"lvl1_fields.consts.ARM_RIGHT_BONE", text:"string=\"right_aimpoint\", the bone which the right arm aims at to"},
-{path:"class/Gun.html#lvl1_fields.consts.ARM_LEFT_BONE", type:"field", title:"lvl1_fields.consts.ARM_LEFT_BONE", text:"string=\"left_aimpoint\", the bone which the left arm aims at to"},
+{path:"class/gun.html#gun.properties", type:"field", title:"gun.properties", text:"properties which define the vast majority of gun attributes and may change accross instances"},
+{path:"class/gun.html#gun.consts", type:"field", title:"gun.consts", text:"constants which define gun attributes and should not be changed in an instance of the gun"},
+{path:"class/gun.html#gun.offsets", type:"field", title:"gun.offsets", text:"runtime storage of offsets generated by recoil sway wag or any other element."},
+{path:"class/gun.html#gun.name", type:"field", title:"gun.name", text:"string the name of the gun. Set to __template for guns which have no instances and serve as a template. It is safe to set name to the same as gun.itemstring"},
+{path:"class/gun.html#gun.itemstack", type:"field", title:"gun.itemstack", text:"ItemStack the gun itemstack. Remember to player:set_wielded_item(self.itemstack) when making meta or itemstack changes."},
+{path:"class/gun.html#gun.meta", type:"field", title:"gun.meta", text:"MetaDataRef itemstack meta"},
+{path:"class/gun.html#gun.id", type:"field", title:"gun.id", text:"string the ID of the gun used for tracking of it's inventory"},
+{path:"class/gun.html#gun.gun_entity", type:"field", title:"gun.gun_entity", text:"ObjRef the gun entity"},
+{path:"class/gun.html#gun.inventory_image_magless", type:"field", title:"gun.inventory_image_magless", text:"string inventory image for when the gun has no magazine"},
+{path:"class/gun.html#gun.inventory_image", type:"field", title:"gun.inventory_image", text:"string inventory image for when the gun is loaded. This is added automatically during construction."},
+{path:"class/gun.html#gun.itemstring", type:"field", title:"gun.itemstring", text:"string the itemstring of the gun- i.e. \"guns4d_pack_1:m4\". Set to \"\" for __template guns."},
+{path:"class/gun.html#gun._registered", type:"field", title:"gun._registered", text:"list of registered guns, *DO NOT MODIFY* I really need a metatable for this class..."},
+{path:"class/gun.html#gun.bolt_charged", type:"field", title:"gun.bolt_charged", text:"bool is the bolt charged"},
+{path:"class/gun.html#gun.particle_spawners", type:"field", title:"gun.particle_spawners", text:"table list of particle spawner handles (generated by firing)"},
+{path:"class/gun.html#gun.current_firemode", type:"field", title:"gun.current_firemode", text:"int the active index of the firemode from firemodes"},
+{path:"class/gun.html#gun.walking_tick", type:"field", title:"gun.walking_tick", text:"float walking time used to generate the figure 8 for wag"},
+{path:"class/gun.html#gun.time_since_last_fire", type:"field", title:"gun.time_since_last_fire", text:"float"},
+{path:"class/gun.html#gun.time_since_creation", type:"field", title:"gun.time_since_creation", text:"float"},
+{path:"class/gun.html#gun.rechamber_time", type:"field", title:"gun.rechamber_time", text:"float time left for the chamber to cycle (for firerates)"},
+{path:"class/gun.html#gun.burst_queue", type:"field", title:"gun.burst_queue", text:"int number of rounds left that need to be fired after a burst fire"},
+{path:"class/gun.html#gun.muzzle_flash", type:"field", title:"gun.muzzle_flash", text:"function"},
+{path:"class/gun.html#gun.gun_translation", type:"field", title:"gun.gun_translation", text:"vec3 translation of the gun relative to the \"gun\" bone or the player axial rotation."},
+{path:"class/gun.html#gun.property_modifiers", type:"field", title:"gun.property_modifiers", text:"table indexed list of modifiers not set by the gun but to be applied to the gun. After changing, gun:update_modifiers() must be called to update it. Also may contain lists of modifiers."},
+{path:"class/gun.html#lvl1_fields.properties.hip", type:"field", title:"lvl1_fields.properties.hip", text:"table hipfire properties"},
+{path:"class/gun.html#lvl1_fields.properties.ads", type:"field", title:"lvl1_fields.properties.ads", text:"table aiming (\"aiming down sights\") properties"},
+{path:"class/gun.html#lvl1_fields.properties.firemodes", type:"field", title:"lvl1_fields.properties.firemodes", text:"table list of firemodes"},
+{path:"class/gun.html#lvl1_fields.properties.firemode_inventory_overlays", type:"field", title:"lvl1_fields.properties.firemode_inventory_overlays", text:"table list of corresponding images for firemodes"},
+{path:"class/gun.html#lvl1_fields.properties.recoil", type:"field", title:"lvl1_fields.properties.recoil", text:"table defines the guns recoil"},
+{path:"class/gun.html#lvl1_fields.properties.sway", type:"field", title:"lvl1_fields.properties.sway", text:"table defines the guns idle sway"},
+{path:"class/gun.html#lvl1_fields.properties.wag", type:"field", title:"lvl1_fields.properties.wag", text:"table defines the movement of the gun while walking"},
+{path:"class/gun.html#lvl1_fields.properties.charging", type:"field", title:"lvl1_fields.properties.charging", text:"table defines how rounds are chambered into the gun"},
+{path:"class/gun.html#lvl1_fields.properties.ammo", type:"field", title:"lvl1_fields.properties.ammo", text:"defines what ammo the gun uses"},
+{path:"class/gun.html#lvl1_fields.properties.visuals", type:"field", title:"lvl1_fields.properties.visuals", text:"defines visual attributes of the gun"},
+{path:"class/gun.html#lvl1_fields.properties.breathing_scale", type:"field", title:"lvl1_fields.properties.breathing_scale", text:"float=.5 max angular deviation (vertical) from breathing"},
+{path:"class/gun.html#lvl1_fields.properties.flash_offset", type:"field", title:"lvl1_fields.properties.flash_offset", text:"vector the offset from the center of the muzzle flash. Used by fire()"},
+{path:"class/gun.html#lvl1_fields.properties.firerateRPM", type:"field", title:"lvl1_fields.properties.firerateRPM", text:"int=600 The number of rounds (cartidges) this gun can throw per minute. Used by update(), fire() and default controls"},
+{path:"class/gun.html#gun.properties.hip.offset", type:"field", title:"gun.properties.hip.offset", text:"vector the offset of the gun (relative to the right arm's default position) at hip."},
+{path:"class/gun.html#gun.properties.hip.axis_rotation_ratio", type:"field", title:"gun.properties.hip.axis_rotation_ratio", text:"the ratio that the look rotation is expressed through player_axial (rotated around the viewport) rotation as opposed to gun_axial (rotating the entity)."},
+{path:"class/gun.html#gun.properties.hip.sway_vel_mul", type:"field", title:"gun.properties.hip.sway_vel_mul", text:"sway speed multiplier while at hip"},
+{path:"class/gun.html#gun.properties.hip.sway_angle_mul", type:"field", title:"gun.properties.hip.sway_angle_mul", text:"sway angle multiplier while at hip+"},
+{path:"class/gun.html#gun.properties.ads.offset", type:"field", title:"gun.properties.ads.offset", text:"vector the offset of the gun relative to the eye's position at hip."},
+{path:"class/gun.html#gun.properties.ads.horizontal_offset", type:"field", title:"gun.properties.ads.horizontal_offset", text:"float the horizontal offset of the eye when aiming"},
+{path:"class/gun.html#gun.properties.ads.aim_time", type:"field", title:"gun.properties.ads.aim_time", text:"the time it takes to go into full aim"},
+{path:"class/gun.html#lvl1_fields.properties.burst", type:"field", title:"lvl1_fields.properties.burst", text:"int=3 how many rounds in burst using when firemode is at \"burst\""},
+{path:"class/gun.html#gun.properties.firemodes."single"", type:"field", title:"gun.properties.firemodes.\"single\"", text:""},
+{path:"class/gun.html#gun.properties.firemodes."burst"", type:"field", title:"gun.properties.firemodes.\"burst\"", text:""},
+{path:"class/gun.html#gun.properties.firemodes."auto"", type:"field", title:"gun.properties.firemodes.\"auto\"", text:""},
+{path:"class/gun.html#lvl1_fields.properties.infinite_inventory_overlay", type:"field", title:"lvl1_fields.properties.infinite_inventory_overlay", text:"string overlay on the item to use when infinite ammo is on"},
+{path:"class/gun.html#gun.properties.firemode_inventory_overlays.single", type:"field", title:"gun.properties.firemode_inventory_overlays.single", text:"\"inventory_overlay_single.png\""},
+{path:"class/gun.html#gun.properties.firemode_inventory_overlays.auto", type:"field", title:"gun.properties.firemode_inventory_overlays.auto", text:"\"inventory_overlay_auto.png\""},
+{path:"class/gun.html#gun.properties.firemode_inventory_overlays.burst", type:"field", title:"gun.properties.firemode_inventory_overlays.burst", text:"\"inventory_overlay_burst.png\""},
+{path:"class/gun.html#gun.properties.firemode_inventory_overlays.safe", type:"field", title:"gun.properties.firemode_inventory_overlays.safe", text:"\"inventory_overlay_safe.png\" (unimplemented firemode)"},
+{path:"class/gun.html#gun.properties.recoil.velocity_correction_factor", type:"field", title:"gun.properties.recoil.velocity_correction_factor", text:"float TL:DR higher decreases recoil at expense of smoothness. 1/value is the deviation of a normalized bell curve, where x is the time since firing. this means that increasing it decreases the time it takes for the angular velocity to fully \"decay\"."},
+{path:"class/gun.html#gun.properties.recoil.target_correction_factor", type:"field", title:"gun.properties.recoil.target_correction_factor", text:"float Correction of recoil offset per second is calculated as such: target_correction_factor[axis]time_since_firerecoil[axis]"},
+{path:"class/gun.html#gun.properties.recoil.target_correction_max_rate", type:"field", title:"gun.properties.recoil.target_correction_max_rate", text:"float The maximum rate per second of recoil offset as determined with target_correction_factor"},
+{path:"class/gun.html#gun.properties.recoil.angular_velocity_max", type:"field", title:"gun.properties.recoil.angular_velocity_max", text:"float caps the recoil velocity that can stack up from shots."},
+{path:"class/gun.html#gun.properties.recoil.angular_velocity", type:"field", title:"gun.properties.recoil.angular_velocity", text:"vector {x=float, y=float}, defines the initial angular velocity produced by firing the gun"},
+{path:"class/gun.html#gun.properties.recoil.bias", type:"field", title:"gun.properties.recoil.bias", text:"vector {x=float, y=float}, ranges -1 to 1. Defines the probability of the recoil being positive or negative for any given axis."},
+{path:"class/gun.html#gun.properties.recoil.hipfire_multiplier", type:"field", title:"gun.properties.recoil.hipfire_multiplier", text:"float angular velocity multiplier when firing from the hip"},
+{path:"class/gun.html#gun.properties.sway.max_angle", type:"field", title:"gun.properties.sway.max_angle", text:"float maximum angle of the sway"},
+{path:"class/gun.html#gun.properties.sway.angular_velocity", type:"field", title:"gun.properties.sway.angular_velocity", text:"float angular velocity the sway"},
+{path:"class/gun.html#gun.properties.sway.hipfire_angle_multiplier", type:"field", title:"gun.properties.sway.hipfire_angle_multiplier", text:"float maximum angle multiplier while the gun is at the hip"},
+{path:"class/gun.html#gun.properties.sway.hipfire_velocity_multiplier", type:"field", title:"gun.properties.sway.hipfire_velocity_multiplier", text:"float velocity multiplier while the gun is at the hip"},
+{path:"class/gun.html#gun.properties.wag.cycle_speed", type:"field", title:"gun.properties.wag.cycle_speed", text:"float=1.6 the cycle speed multiplier"},
+{path:"class/gun.html#gun.properties.wag.decay_speed", type:"field", title:"gun.properties.wag.decay_speed", text:"float=1 decay factor when walking has stopped and offset remains."},
+{path:"class/gun.html#gun.properties.wag.offset", type:"field", title:"gun.properties.wag.offset", text:"table containing angular deviation while walking in the same format as an offset vector. Acts as a multiplier on the figure-8 generated while walking."},
+{path:"class/gun.html#lvl1_fields.properties.pc_control_actions", type:"field", title:"lvl1_fields.properties.pc_control_actions", text:"table containing a list of actions for PC users passed to Control_handler"},
+{path:"class/gun.html#lvl1_fields.properties.touch_control_actions", type:"field", title:"lvl1_fields.properties.touch_control_actions", text:"table containing a list of actions for touch screen users passed to Control_handler"},
+{path:"class/gun.html#gun.properties.charging.require_draw_on_swap", type:"field", title:"gun.properties.charging.require_draw_on_swap", text:"bool defines wether the draw animation is played on swap (when loaded). Used in the instance construction method"},
+{path:"class/gun.html#gun.properties.charging.bolt_charge_mode", type:"field", title:"gun.properties.charging.bolt_charge_mode", text:"string \"none\" bolt will never need to be charged after reload, \"catch\" when fired to empty bolt will not need to be charged after reload, \"no_catch\" bolt will always need to be charged after reload."},
+{path:"class/gun.html#gun.properties.charging.draw_time", type:"field", title:"gun.properties.charging.draw_time", text:"float the time it takes to swap to the gun"},
+{path:"class/gun.html#gun.properties.charging.draw_animation", type:"field", title:"gun.properties.charging.draw_animation", text:"string name of the animation to play from visuals.animations"},
+{path:"class/gun.html#gun.properties.charging.draw_sound", type:"field", title:"gun.properties.charging.draw_sound", text:"string name of the sound to play from sounds"},
+{path:"class/gun.html#gun.reload", type:"field", title:"gun.reload", text:"and ordered list of reloading states used by default_controls. the default reload states for a magazine operated weapon, copied from the m4. Example"},
+{path:"class/gun.html#gun.properties.ammo.magazine_only", type:"field", title:"gun.properties.ammo.magazine_only", text:"bool wether the gun only uses a magazine or accepts raw ammunition too."},
+{path:"class/gun.html#gun.properties.ammo.accepted_bullets", type:"field", title:"gun.properties.ammo.accepted_bullets", text:"table a list of accepted bullet itemstrings"},
+{path:"class/gun.html#gun.properties.ammo.accepted_magazines", type:"field", title:"gun.properties.ammo.accepted_magazines", text:"table a list of accepted magazine itemstrings"},
+{path:"class/gun.html#gun.properties.ammo.initial_mag", type:"field", title:"gun.properties.ammo.initial_mag", text:"string the mag the gun starts with. Set to \"empty\" for no mag, otherwise it defaults to accepted_magazines[1] (if present)"},
+{path:"class/gun.html#gun.properties.visuals.mesh", type:"field", title:"gun.properties.visuals.mesh", text:"name of mesh to display"},
+{path:"class/gun.html#gun.properties.visuals.textures", type:"field", title:"gun.properties.visuals.textures", text:"list of textures to use"},
+{path:"class/gun.html#gun.properties.visuals.scale", type:"field", title:"gun.properties.visuals.scale", text:"scale multiplier"},
+{path:"class/gun.html#gun.properties.visuals.backface_culling", type:"field", title:"gun.properties.visuals.backface_culling", text:"toggles backface culling"},
+{path:"class/gun.html#gun.properties.visuals.animations", type:"field", title:"gun.properties.visuals.animations", text:"a table of animations in the format {x=int, y=float}. Indexes define the name of the animation to be refrenced by other functions of the gun."},
+{path:"class/gun.html#gun.model_bounding_box", type:"field", title:"gun.model_bounding_box", text:"a table {x1,y1,z1,x2,y2,z2} specifying the bounding box of the model. The first 3 (x1,y1,z1) are the lower of their counterparts"},
+{path:"class/gun.html#gun.sounds", type:"field", title:"gun.sounds", text:"a table of soundspecs to be referenced by other functions"},
+{path:"class/gun.html#lvl1_fields.offsets.recoil", type:"field", title:"lvl1_fields.offsets.recoil", text:""},
+{path:"class/gun.html#lvl1_fields.offsets.sway", type:"field", title:"lvl1_fields.offsets.sway", text:""},
+{path:"class/gun.html#lvl1_fields.offsets.walking", type:"field", title:"lvl1_fields.offsets.walking", text:""},
+{path:"class/gun.html#lvl1_fields.offsets.breathing", type:"field", title:"lvl1_fields.offsets.breathing", text:""},
+{path:"class/gun.html#lvl1_fields.offsets.look", type:"field", title:"lvl1_fields.offsets.look", text:""},
+{path:"class/gun.html#gun.animation_rotation", type:"field", title:"gun.animation_rotation", text:"vector containing the offset from animations, this will be generated if {@consts.ANIMATIONS_OFFSET_AIM}=true"},
+{path:"class/gun.html#gun.gun_axial", type:"field", title:"gun.gun_axial", text:"total offsets of the gun in the same format as a an offset [[total_offsets = {"},
+{path:"class/gun.html#lvl1_fields.consts.KEYFRAME_SAMPLE_PRECISION", type:"field", title:"lvl1_fields.consts.KEYFRAME_SAMPLE_PRECISION", text:"frequency of keyframe samples for animation offsets and"},
+{path:"class/gun.html#lvl1_fields.consts.DEFAULT_MAX_HEAR_DISTANCE", type:"field", title:"lvl1_fields.consts.DEFAULT_MAX_HEAR_DISTANCE", text:"default max hear distance when not specified"},
+{path:"class/gun.html#lvl1_fields.consts.DEFAULT_FPS", type:"field", title:"lvl1_fields.consts.DEFAULT_FPS", text:"fps=60 animation fps i.e. during firing when no length is specified"},
+{path:"class/gun.html#lvl1_fields.consts.HAS_RECOIL", type:"field", title:"lvl1_fields.consts.HAS_RECOIL", text:"bool"},
+{path:"class/gun.html#lvl1_fields.consts.HAS_BREATHING", type:"field", title:"lvl1_fields.consts.HAS_BREATHING", text:"bool"},
+{path:"class/gun.html#lvl1_fields.consts.HAS_SWAY", type:"field", title:"lvl1_fields.consts.HAS_SWAY", text:"bool"},
+{path:"class/gun.html#lvl1_fields.consts.HAS_WAG", type:"field", title:"lvl1_fields.consts.HAS_WAG", text:"bool"},
+{path:"class/gun.html#lvl1_fields.consts.HAS_GUN_AXIAL_OFFSETS", type:"field", title:"lvl1_fields.consts.HAS_GUN_AXIAL_OFFSETS", text:"bool wether the gun rotates on it's own axis instead of the player's view (i.e. ironsight misalignments)"},
+{path:"class/gun.html#lvl1_fields.consts.ANIMATIONS_OFFSET_AIM", type:"field", title:"lvl1_fields.consts.ANIMATIONS_OFFSET_AIM", text:"wether animations create an offset"},
+{path:"class/gun.html#lvl1_fields.consts.LOOP_IDLE_ANIM", type:"field", title:"lvl1_fields.consts.LOOP_IDLE_ANIM", text:"whether the idle animation changes or not"},
+{path:"class/gun.html#lvl1_fields.consts.THIRD_PERSON_GAIN_MULTIPLIER", type:"field", title:"lvl1_fields.consts.THIRD_PERSON_GAIN_MULTIPLIER", text:"general gain multiplier for third persons when hearing sounds"},
+{path:"class/gun.html#lvl1_fields.consts.ROOT_BONE", type:"field", title:"lvl1_fields.consts.ROOT_BONE", text:"the root bone of the gun (for animation offsets)"},
+{path:"class/gun.html#lvl1_fields.consts.MAG_BONE", type:"field", title:"lvl1_fields.consts.MAG_BONE", text:"string=\"magazine\",the bone of the magazine in the gun (for dropping mags)"},
+{path:"class/gun.html#lvl1_fields.consts.ARM_RIGHT_BONE", type:"field", title:"lvl1_fields.consts.ARM_RIGHT_BONE", text:"string=\"right_aimpoint\", the bone which the right arm aims at to"},
+{path:"class/gun.html#lvl1_fields.consts.ARM_LEFT_BONE", type:"field", title:"lvl1_fields.consts.ARM_LEFT_BONE", text:"string=\"left_aimpoint\", the bone which the left arm aims at to"},
{path:"class/player_model_handler.html#fields.offsets", type:"field", title:"fields.offsets", text:"fields.offsets"},
{path:"module/misc_helpers.html#Guns4d.math.weighted_randoms", type:"function", title:"Guns4d.math.weighted_randoms", text:"picks a random index, with odds based on it's value. Returns the index of the selected."},
{path:"module/play_sound.html#Guns4d.play_sounds", type:"function", title:"Guns4d.play_sounds", text:"allows you to play one or more sounds with more complex features, so sounds can be easily coded for guns without the need for functions. WARNING: this function modifies the tables passed to it, use Guns4d.table.shallow_copy() or table.copy for inputted soundspecs Example"},
diff --git a/docs/module/Bullet_hole.html b/docs/module/Bullet_hole.html
index fee3484..e0c2578 100644
--- a/docs/module/Bullet_hole.html
+++ b/docs/module/Bullet_hole.html
@@ -33,7 +33,7 @@
-
-
-
\ No newline at end of file
diff --git a/docs/module/misc_helpers.html b/docs/module/misc_helpers.html
index 95d6b40..e5ba31a 100644
--- a/docs/module/misc_helpers.html
+++ b/docs/module/misc_helpers.html
@@ -39,7 +39,7 @@
diff --git a/init.lua b/init.lua
index 6aca802..f78fee9 100644
--- a/init.lua
+++ b/init.lua
@@ -200,18 +200,17 @@ minetest.register_on_joinplayer(function(player)
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 >:(
+ --[[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
+ frame_range.x = frame_range.x
--minetest.chat_send_all("+1")
- end
+ end]]
--frame_blend = 25
--minetest.chat_send_all(dump(frame_range))
data.frames = frame_range
diff --git a/misc_helpers.lua b/misc_helpers.lua
index 773e1a0..32bf46b 100644
--- a/misc_helpers.lua
+++ b/misc_helpers.lua
@@ -82,7 +82,7 @@ function Guns4d.apply_field_modifiers(props, mods)
end
return out_props
end
-print(dump(Guns4d.apply_field_modifiers({
+--[[print(dump(Guns4d.apply_field_modifiers({
a=0,
y=1,
z=10,
@@ -100,7 +100,7 @@ print(dump(Guns4d.apply_field_modifiers({
override=10
}
}
-)))
+)))]]
function Guns4d.unique_id.generate()
local genned_ids = Guns4d.unique_id.generated
diff --git a/textures/awm_scope_border.png b/textures/awm_scope_border.png
deleted file mode 100644
index fba17df..0000000
Binary files a/textures/awm_scope_border.png and /dev/null differ
diff --git a/touch_support.lua b/touch_support.lua
index cab6dc3..783f648 100644
--- a/touch_support.lua
+++ b/touch_support.lua
@@ -39,7 +39,7 @@ touch.on_secondary_use = function(itemstack, handler, pointed_thing)
pc.on_use(itemstack, handler, pointed_thing)
end
end
-
+Guns4d.default_controls.jump_cancel_ads = table.copy(pc.jump_cancel_ads)
--full auto
touch.auto = table.copy(pc.auto)
touch.auto.conditions = {"LMB"}