changes to how vertical rotation matches with the look rotation in hipfire
This commit is contained in:
parent
01ee029c73
commit
af970be519
@ -43,7 +43,7 @@ function Dynamic_crosshair:update(dt)
|
||||
local temp_vector = vector.new()
|
||||
|
||||
for offset, v in pairs(gun.offsets) do
|
||||
if (offset ~= "walking" or not self.normalize_walking) and (offset ~= "breathing" or not self.normalize_breathing) and (offset ~= "sway" or not self.normalize_sway) then
|
||||
if (offset ~= "walking" or not self.normalize_walking) and (offset ~= "breathing" or not self.normalize_breathing) and (offset ~= "sway" or not self.normalize_sway) and (offset ~= "look_snap" or not self.normalize_sway) then
|
||||
temp_vector = temp_vector + absolute_vector(v.player_axial) + absolute_vector(v.gun_axial)
|
||||
end
|
||||
end
|
||||
|
143
classes/Gun.lua
143
classes/Gun.lua
@ -235,6 +235,10 @@ local gun_default = {
|
||||
gun_axial = Vec.new(), --gun axial unimplemented...
|
||||
player_axial = Vec.new(),
|
||||
},
|
||||
look_snap = {
|
||||
gun_axial = Vec.new(),
|
||||
player_axial = Vec.new() --unimplemented
|
||||
},
|
||||
},
|
||||
--[[spread = {
|
||||
recoil = vector.new(),
|
||||
@ -256,9 +260,9 @@ local gun_default = {
|
||||
player_axial = Vec.new(),
|
||||
},
|
||||
},
|
||||
--magic number BEGONE
|
||||
--magic number BEGONE. these are variables that are constant across the class, but are at times too specific to be config settings (generally), or otherwise must be overriden.
|
||||
consts = {
|
||||
HIP_PLAYER_GUN_ROT_RATIO = .75,
|
||||
HIP_ROTATION_RATIO = .75,
|
||||
AIM_OUT_AIM_IN_SPEED_RATIO = 2.5,
|
||||
KEYFRAME_SAMPLE_PRECISION = .1, --[[what frequency to take precalcualted keyframe samples. The lower this is the higher the memory allocation it will need- though minimal.
|
||||
This will fuck shit up if you change it after gun construction/inheritence (interpolation between precalculated vectors will not work right)]]
|
||||
@ -319,19 +323,10 @@ function gun_default:update(dt)
|
||||
assert(self.instance, "attempt to call object method on a class")
|
||||
if not self:has_entity() then self:add_entity(); self:clear_animation() end
|
||||
local handler = self.handler
|
||||
local look_rotation = handler.look_rotation --remember that this is in counterclock-wise rotation. For 4dguns we use clockwise so it makes a bit more sense for recoil. So it needs to be inverted.
|
||||
local total_rot = self.total_offset_rotation
|
||||
local player_rot = self.player_rotation
|
||||
local constant = Guns4d.config.vertical_rotation_factor
|
||||
|
||||
--player look rotation. I'm going to keep it real, I don't remember what this math does. Player handler just stores the player's rotation from MT in degrees, which is for some reason inverted
|
||||
player_rot.y = -handler.look_rotation.y
|
||||
local next_vert_aim = ((player_rot.x+look_rotation.x)/(1+constant*dt))-look_rotation.x
|
||||
if math.abs(look_rotation.x-next_vert_aim) > .005 then
|
||||
player_rot.x = next_vert_aim
|
||||
else
|
||||
player_rot.x = -look_rotation.x
|
||||
end
|
||||
|
||||
--timers
|
||||
if self.rechamber_time > 0 then
|
||||
self.rechamber_time = self.rechamber_time - dt
|
||||
@ -343,6 +338,7 @@ function gun_default:update(dt)
|
||||
|
||||
if self.burst_queue > 0 then self:update_burstfire() end
|
||||
--update some vectors
|
||||
self:update_look_rotation(dt)
|
||||
if self.consts.HAS_SWAY then self:update_sway(dt) end
|
||||
if self.consts.HAS_RECOIL then self:update_recoil(dt) end
|
||||
if self.consts.HAS_BREATHING then self:update_breathing(dt) end
|
||||
@ -354,6 +350,7 @@ function gun_default:update(dt)
|
||||
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()
|
||||
|
||||
if self.properties.sprite_scope then
|
||||
self.sprite_scope:update()
|
||||
@ -361,18 +358,7 @@ function gun_default:update(dt)
|
||||
if self.properties.crosshair then
|
||||
self.crosshair:update()
|
||||
end
|
||||
|
||||
--automatically cock if uncocked.
|
||||
local ammo = self.ammo_handler.ammo
|
||||
--[[if ammo.total_bullets and (ammo.total_bullets > 0 and ammo.next_bullet == "empty") then
|
||||
self:charge()
|
||||
end]]
|
||||
--print(dump(self.ammo_handler.ammo.next_bullet))
|
||||
|
||||
local offsets = self.offsets
|
||||
--local player_axial = offsets.recoil.player_axial + offsets.walking.player_axial + offsets.sway.player_axial + offsets.breathing.player_axial
|
||||
--local gun_axial = offsets.recoil.gun_axial + offsets.walking.gun_axial + offsets.sway.gun_axial
|
||||
--apply the offsets.
|
||||
total_rot.player_axial.x = 0; total_rot.player_axial.y = 0
|
||||
total_rot.gun_axial.x = 0; total_rot.gun_axial.y = 0
|
||||
for type, _ in pairs(total_rot) do
|
||||
@ -487,6 +473,31 @@ function gun_default:recoil()
|
||||
end
|
||||
self.time_since_last_fire = 0
|
||||
end
|
||||
function gun_default:update_look_rotation(dt)
|
||||
assert(self.instance, "attempt to call object method on a class")
|
||||
local handler = self.handler
|
||||
local look_rotation = handler.look_rotation --remember that this is in counterclock-wise rotation. For 4dguns we use clockwise so it makes a bit more sense for recoil. So it needs to be inverted.
|
||||
local player_rot = self.player_rotation
|
||||
player_rot.y = -handler.look_rotation.y
|
||||
local rot_factor = Guns4d.config.vertical_rotation_factor*dt
|
||||
rot_factor = rot_factor*(.5*(1+handler.ads_location))
|
||||
local next_vert_aim = ((player_rot.x-look_rotation.x)/(1+rot_factor))+look_rotation.x --difference divided by a value and then added back to the original
|
||||
if math.abs(look_rotation.x-next_vert_aim) > .005 then
|
||||
player_rot.x = next_vert_aim
|
||||
else
|
||||
player_rot.x = look_rotation.x
|
||||
end
|
||||
|
||||
if not handler.control_handler.ads then
|
||||
local pitch = self.total_offset_rotation.player_axial.x+player_rot.x
|
||||
self.offsets.look_snap.gun_axial.x = (pitch*(1-self.consts.HIP_ROTATION_RATIO))+(handler.look_rotation.x-player_rot.x)
|
||||
self.offsets.look_snap.player_axial.x = -pitch*(1-self.consts.HIP_ROTATION_RATIO)
|
||||
else
|
||||
self.offsets.look_snap.gun_axial.x = 0
|
||||
self.offsets.look_snap.player_axial.x = 0
|
||||
end
|
||||
end
|
||||
--============================================== positional info =====================================
|
||||
--all of this dir shit needs to be optimized HARD
|
||||
function gun_default:get_gun_axial_dir()
|
||||
assert(self.instance, "attempt to call object method on a class")
|
||||
@ -504,23 +515,11 @@ function gun_default:get_player_axial_dir(rltv)
|
||||
if not rltv then
|
||||
if (self.properties.sprite_scope and handler.control_handler.ads) or (self.properties.crosshair and not handler.control_handler.ads) then
|
||||
--we need the head rotation in either of these cases, as that's what they're showing.
|
||||
dir = Vec.rotate(dir, {x=-handler.look_rotation.x*math.pi/180,y=-handler.look_rotation.y*math.pi/180,z=0})
|
||||
dir = Vec.rotate(dir, {x=handler.look_rotation.x*math.pi/180,y=-handler.look_rotation.y*math.pi/180,z=0})
|
||||
else
|
||||
dir = Vec.rotate(dir, {x=self.player_rotation.x*math.pi/180,y=self.player_rotation.y*math.pi/180,z=0})
|
||||
end
|
||||
end
|
||||
--[[local hud_pos = Vec.rotate(dir, {x=0,y=self.player_rotation.y*math.pi/180,z=0})+player:get_pos()+{x=0,y=player:get_properties().eye_height,z=0}+vector.rotate(player:get_eye_offset()/10, {x=0,y=self.player_rotation.y*math.pi/180,z=0})
|
||||
local hud = player: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)
|
||||
player:hud_remove(hud)
|
||||
end, hud)]]
|
||||
return dir
|
||||
end
|
||||
--this needs to be optimized because it may be called frequently...
|
||||
@ -529,9 +528,7 @@ function gun_default:get_dir(rltv, offset_x, offset_y)
|
||||
local rotation = self.total_offset_rotation
|
||||
local handler = self.handler
|
||||
--rotate x and then y.
|
||||
--old code. I used a site (symbolab.com) to precalculate the rotation matrices to save on performance since spread has to run this.
|
||||
--local dir = Vec.rotate({x=0, y=0, z=1}, {y=0, x=((rotation.gun_axial.x+rotation.player_axial.x)*math.pi/180), z=0})
|
||||
--dir = Vec.rotate(dir, {y=((rotation.gun_axial.y+rotation.player_axial.y)*math.pi/180), x=0, z=0})
|
||||
--old code. I used a site (symbolab.com) to precalculate the rotation matrices to save on performance since spread for pellets has to run this.
|
||||
local p = -(rotation.gun_axial.x+rotation.player_axial.x+(offset_x or 0))*math.pi/180
|
||||
local y = -(rotation.gun_axial.y+rotation.player_axial.y+(offset_y or 0))*math.pi/180
|
||||
local Cy = math.cos(y)
|
||||
@ -543,25 +540,9 @@ function gun_default:get_dir(rltv, offset_x, offset_y)
|
||||
y=-Sp,
|
||||
z=Cy*Cp
|
||||
}
|
||||
if not rltv then --look rotation is that actual rotation of the player's camera, player_rotation is the gun's current rotation (because vertical rotation will differ for smoothness.)
|
||||
if (self.properties.sprite_scope and handler.control_handler.ads) or (self.properties.crosshair and not handler.control_handler.ads) then
|
||||
--we need the head rotation in either of these cases, as that's what they're showing.
|
||||
--dir = Vec.rotate(dir, {x=-handler.look_rotation.x*math.pi/180,y=-handler.look_rotation.y*math.pi/180,z=0})
|
||||
--[[
|
||||
Cy = math.cos(y)
|
||||
Sy = math.sin(y)
|
||||
Cp = math.cos(p)
|
||||
Sp = math.sin(p)
|
||||
dir.x = (Cy*dir.x)+(Sy*Sp*dir.y)+(Sy*Cp*dir.z)
|
||||
dir.y = (dir.y*Cp)-(dir.z*Sp)
|
||||
dir.z = -(dir.x*Sy)+(dir.y*Sp*Cy)+(dir.z*Cy*Cp)]]
|
||||
p = handler.look_rotation.x*math.pi/180
|
||||
y = handler.look_rotation.y*math.pi/180
|
||||
else
|
||||
p = -self.player_rotation.x*math.pi/180
|
||||
y = -self.player_rotation.y*math.pi/180
|
||||
--dir = Vec.rotate(dir, {x=self.player_rotation.x*math.pi/180,y=self.player_rotation.y*math.pi/180,z=0})
|
||||
end
|
||||
if not rltv then
|
||||
p = -self.player_rotation.x*math.pi/180
|
||||
y = -self.player_rotation.y*math.pi/180
|
||||
Cy = math.cos(y)
|
||||
Sy = math.sin(y)
|
||||
Cp = math.cos(p)
|
||||
@ -576,20 +557,7 @@ function gun_default:get_dir(rltv, offset_x, offset_y)
|
||||
end
|
||||
return dir
|
||||
end
|
||||
--some old debug code for get_dir
|
||||
--local hud_pos = dir+player:get_pos()+{x=0,y=player:get_properties().eye_height,z=0}+vector.rotate(player:get_eye_offset()/10, {x=0,y=player_rotation.y*math.pi/180,z=0})
|
||||
--[[local hud = player: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)
|
||||
player:hud_remove(hud)
|
||||
end, hud)]]
|
||||
--broken! doesn't properly reflect values.
|
||||
--Should probably optimize this at some point.
|
||||
function gun_default:get_pos(added_pos, relative, debug)
|
||||
assert(self.instance, "attempt to call object method on a class")
|
||||
local player = self.player
|
||||
@ -644,21 +612,46 @@ function gun_default:get_pos(added_pos, relative, debug)
|
||||
return pos
|
||||
end
|
||||
|
||||
|
||||
--=============================================== ENTITY ======================================================
|
||||
|
||||
|
||||
function gun_default:add_entity()
|
||||
assert(self.instance, "attempt to call object method on a class")
|
||||
self.entity = minetest.add_entity(self.player:get_pos(), self.name.."_visual")
|
||||
local obj = self.entity:get_luaentity()
|
||||
obj.parent_player = self.player
|
||||
--obj.parent_player = self.player
|
||||
Guns4d.gun_by_ObjRef[self.entity] = self
|
||||
obj:on_step()
|
||||
--obj:on_step()
|
||||
--self:update_entity()
|
||||
end
|
||||
function gun_default:update_entity()
|
||||
local obj = self.entity
|
||||
local player = self.player
|
||||
local axial_rot = self.total_offset_rotation.gun_axial
|
||||
local handler = self.handler
|
||||
local props = self.properties
|
||||
--attach to the correct bone, and rotate
|
||||
local visibility = true
|
||||
if self.sprite_scope and self.sprite_scope.hide_gun and (not (handler.ads_location == 0)) then
|
||||
visibility = false
|
||||
end
|
||||
if handler.control_handler.ads then
|
||||
local normal_pos = (props.ads.offset)*10
|
||||
obj:set_attach(player, handler.player_model_handler.bone_names.aim, normal_pos, -axial_rot, visibility)
|
||||
else
|
||||
local normal_pos = vector.new(props.hip.offset)*10
|
||||
obj:set_attach(player, handler.player_model_handler.bone_names.hipfire, normal_pos, -axial_rot, visibility)
|
||||
end
|
||||
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
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function gun_default:update_wag(dt)
|
||||
local handler = self.handler
|
||||
local wag = self.offsets.walking
|
||||
|
@ -51,7 +51,7 @@ function player_handler:update(dt)
|
||||
--for the gun's scopes to work properly we need predictable offsets.
|
||||
end
|
||||
--update some properties.
|
||||
self.look_rotation.x, self.look_rotation.y = Guns4d.math.clamp((player:get_look_vertical() or 0)*180/math.pi, -80, 80), 360-player:get_look_horizontal()*180/math.pi
|
||||
self.look_rotation.x, self.look_rotation.y = Guns4d.math.clamp((-player:get_look_vertical() or 0)*180/math.pi, -80, 80), 360-player:get_look_horizontal()*180/math.pi
|
||||
if TICK % 10 == 0 then
|
||||
self.wininfo = minetest.get_player_window_information(self.player:get_player_name())
|
||||
end
|
||||
|
@ -64,7 +64,7 @@ function player_model:update(dt)
|
||||
if handler.control_handler.ads then
|
||||
eye_pos.x = ((handler.horizontal_offset*10)/pprops.visual_size.x) --horizontal_offset already is eye_offset on x
|
||||
end
|
||||
player:set_bone_position(self.bone_names.hipfire, self.offsets.relative.arm_right, {x=-(pitch*gun.consts.HIP_PLAYER_GUN_ROT_RATIO), y=180-player_axial_offset.y, z=0})
|
||||
player:set_bone_position(self.bone_names.hipfire, self.offsets.relative.arm_right, {x=-pitch, y=180-player_axial_offset.y, z=0})
|
||||
--player:set_bone_position(self.bone_names.reticle, eye_pos, vector.new(combined.x, 180-combined.y, 0))
|
||||
--can't use paxial dir as it needs to be relative on Y still.
|
||||
local dir = vector.rotate(gun.local_paxial_dir, {x=gun.player_rotation.x*math.pi/180,y=0,z=0})
|
||||
@ -101,7 +101,7 @@ function player_model:update_head(dt)
|
||||
local player = self.player
|
||||
local handler = self.handler
|
||||
local gun = handler.gun
|
||||
player:set_bone_position(self.bone_names.head, self.offsets.relative.head, {x=-handler.look_rotation.x,z=0,y=0})
|
||||
player:set_bone_position(self.bone_names.head, self.offsets.relative.head, {x=handler.look_rotation.x,z=0,y=0})
|
||||
end
|
||||
--should be renamed to "release" but, whatever.
|
||||
function player_model:prepare_deletion()
|
||||
|
@ -235,7 +235,7 @@ local function reregister_item(self, props)
|
||||
animation = self.properties.visuals.animations.loaded
|
||||
})
|
||||
end
|
||||
local function create_visual_entity(def, props)
|
||||
local function register_visual_entity(def, props)
|
||||
minetest.register_entity(def.name.."_visual", {
|
||||
initial_properties = {
|
||||
visual = "mesh",
|
||||
@ -246,34 +246,9 @@ local function create_visual_entity(def, props)
|
||||
static_save = false,
|
||||
backface_culling = props.visuals.backface_culling
|
||||
},
|
||||
on_step = --[[def.entity_function or]] function(self)
|
||||
local obj = self.object
|
||||
if not self.parent_player then obj:remove() return end
|
||||
local player = self.parent_player
|
||||
local handler = Guns4d.players[player:get_player_name()]
|
||||
local lua_object = handler.gun
|
||||
if not lua_object then obj:remove() return end
|
||||
--this is changing the point of rotation if not aiming, this is to make it look less shit.
|
||||
local axial_modifier = vector.new()
|
||||
if not handler.control_handler.ads then
|
||||
local pitch = lua_object.total_offset_rotation.player_axial.x+lua_object.player_rotation.x
|
||||
axial_modifier = vector.new(pitch*(1-lua_object.consts.HIP_PLAYER_GUN_ROT_RATIO),0,0)
|
||||
end
|
||||
local axial_rot = lua_object.total_offset_rotation.gun_axial+axial_modifier
|
||||
--attach to the correct bone, and rotate
|
||||
local visibility = true
|
||||
if lua_object.sprite_scope and lua_object.sprite_scope.hide_gun and (not (handler.ads_location == 0)) then
|
||||
visibility = false
|
||||
end
|
||||
if handler.control_handler.ads then
|
||||
local normal_pos = (props.ads.offset)*10
|
||||
obj:set_attach(player, handler.player_model_handler.bone_names.aim, normal_pos, -axial_rot, visibility)
|
||||
else
|
||||
local normal_pos = vector.new(props.hip.offset)*10
|
||||
-- vector.multiply({x=normal_pos.x, y=normal_pos.z, z=-normal_pos.y}, 10)
|
||||
obj:set_attach(player, handler.player_model_handler.bone_names.hipfire, normal_pos, -axial_rot, visibility)
|
||||
end
|
||||
end,
|
||||
on_step = function(self)
|
||||
if not self.object:get_attach() then self.object:remove() end
|
||||
end
|
||||
})
|
||||
end
|
||||
--========================== MAIN CLASS CONSTRUCTOR ===============================
|
||||
@ -304,5 +279,5 @@ function gun_default:construct_base_class()
|
||||
end
|
||||
|
||||
Guns4d.gun.registered[self.name] = self --add gun self to the registered table
|
||||
create_visual_entity(self, props) --register the visual entity
|
||||
register_visual_entity(self, props) --register the visual entity
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user