added support for touchscreen

This commit is contained in:
FatalErr42O 2024-03-29 22:39:20 -07:00
parent 9922a37206
commit 30bd8d9528
8 changed files with 114 additions and 50 deletions

View File

@ -1,15 +0,0 @@
Bullet = Instantiatable_class:inherit({
registered = {},
range = 100,
force_mmRHA = 1,
dropoff_mmRHA = 0,
damage = 0,
itemstring = "",
construct = function(def)
assert(not def.instance, "attempt to create instance of a template")
assert(rawget(def, "itemstring"), "no string provided to new bullet template")
assert(minetest.registered_items[def.itemstring], "bullet item is not registered. Check dependencies?")
end
})

View File

@ -1,6 +1,6 @@
Guns4d.control_handler = {
--[[example:
controls = {
actions_pc = {
reload = {
conditions = { --the list of controls (see lua_api.txt) to call
"shift",
@ -15,6 +15,7 @@ Guns4d.control_handler = {
}
]]
ads = false,
touchscreen = false
}
--data table:
--[[
@ -32,6 +33,10 @@ end]]
--this function always ends up a mess. I rewrote it here 2 times,
--and in 3dguns I rewrote it at least 3 times. It's always just...
--impossible to understand. So if you see ALOT of comments, that's why.
function controls:get_actions()
assert(self.instance, "attempt to call object method on a class")
return (self.touchscreen and self.actions_touch) or self.actions_pc
end
function controls:update(dt)
assert(self.instance, "attempt to call object method on a class")
self.player_pressed = self.player:get_player_control()
@ -39,7 +44,7 @@ function controls:update(dt)
local call_queue = {} --so I need to have a "call" queue so I can tell the functions the names of other active controls (busy_list)
local busy_list = self.busy_list or {} --list of controls that have their conditions met. Has to be reset at END of update, so on_use and on_secondary_use can be marked
if not (self.gun.rechamber_time > 0 and self.gun.ammo_handler.ammo.next_bullet == "empty") then --check if the gun is being charged.
for i, control in pairs(self.actions) do
for i, control in pairs(self:get_actions()) do
if not (i=="on_use") and not (i=="on_secondary_use") then
local def = control
local data = control.data
@ -104,37 +109,53 @@ function controls:update(dt)
end
function controls:on_use(itemstack, pointed_thing)
assert(self.instance, "attempt to call object method on a class")
if self.actions.on_use then
self.actions.on_use(itemstack, self.handler, pointed_thing)
local actions = self:get_actions()
if actions.on_use then
actions.on_use(itemstack, self.handler, pointed_thing)
end
end
function controls:on_secondary_use(itemstack, pointed_thing)
assert(self.instance, "attempt to call object method on a class")
if self.actions.on_secondary_use then
self.actions.on_secondary_use(itemstack, self.handler, pointed_thing)
local actions = self:get_actions()
if actions.on_secondary_use then
actions.on_secondary_use(itemstack, self.handler, pointed_thing)
end
end
---@diagnostic disable-next-line: duplicate-set-field
function controls:toggle_touchscreen_mode(active)
if active~=nil then self.touchscreen=active else self.touchscreen = not self.touchscreen end
self.handler.touchscreen = self.touchscreen
for i, action in pairs((self.touchscreen and self.actions_pc) or self.actions_touch) do
if not (i=="on_use") and not (i=="on_secondary_use") then
action.timer = action.timer or 0
action.data = nil --no need to store excess data
end
end
for i, action in pairs((self.touchscreen and self.actions_touch) or self.actions_pc) do
if not (i=="on_use") and not (i=="on_secondary_use") then
action.timer = action.timer or 0
action.data = {
timer = action.timer,
continue = false,
time_held = 0,
current_mode = (action.mode=="hybrid" and "toggle") or action.mode or "hold"
}
end
end
end
function controls.construct(def)
if def.instance then
assert(def.actions, "no actions provided")
assert(def.gun.properties.pc_control_actions, "no actions for pc controls provided")
assert(def.gun.properties.touch_control_actions, "no actions for touchscreen controls provided")
assert(def.player, "no player provided")
def.actions = Guns4d.table.deep_copy(def.actions)
--instantiate controls (as we will be adding to the table)
def.actions_pc = Guns4d.table.deep_copy(def.gun.properties.pc_control_actions)
def.actions_touch = Guns4d.table.deep_copy(def.gun.properties.touch_control_actions)
def.busy_list = {}
def.handler = Guns4d.players[def.player:get_player_name()]
def.mode = def.mode or "hold"
for i, action in pairs(def.actions) do
if not (i=="on_use") and not (i=="on_secondary_use") then
action.timer = action.timer or 0
action.data = {
timer = action.timer,
continue = false,
time_held = 0,
current_mode = (def.mode=="hybrid" and "toggle") or def.mode
}
end
end
table.sort(def.actions, function(a,b)
def:toggle_touchscreen_mode(def.touchscreen)
table.sort(def.actions_pc, function(a,b)
return #a.conditions > #b.conditions
end)
end

View File

@ -106,7 +106,7 @@ local gun_default = {
gun_axial = {x=1, y=-1},
player_axial = {x=1,y=1},
},
control_actions = { --used by control_handler
pc_control_actions = { --used by control_handler
__overfill=true, --this table will not be filled in.
aim = Guns4d.default_controls.aim,
auto = Guns4d.default_controls.auto,
@ -114,8 +114,13 @@ local gun_default = {
on_use = Guns4d.default_controls.on_use,
firemode = Guns4d.default_controls.firemode
},
mobile_control_actions = {
touch_control_actions = {
__overfill=true,
aim = Guns4d.default_touch_controls.aim,
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
},
charging = { --how the gun "cocks"
require_draw_on_swap = true,
@ -223,10 +228,10 @@ local gun_default = {
player_axial = Vec.new(),
},
},
spread = {
--[[spread = {
recoil = vector.new(),
walking = vector.new()
},
},]]
animation_rotation = vector.new(),
--[[total_offset_rotation = { --can't be in offsets, as they're added automatically.
gun_axial = Vec.new(),
@ -263,7 +268,7 @@ local gun_default = {
ANIMATIONS_OFFSET_AIM = false,
LOOP_IDLE_ANIM = false
},
animation_data = { --where animations data is stored.
--[[animation_data = { --where animations data is stored.
anim_runtime = 0,
length = 0,
fps = 0,
@ -272,8 +277,7 @@ local gun_default = {
--[[animations = {
}
]]
},
},]]
bolt_charged = false,
particle_spawners = {},
current_firemode = 1,

View File

@ -40,7 +40,7 @@ function player_handler:update(dt)
self.player_model_handler = nil
end
self.player_model_handler = Guns4d.player_model_handler.get_handler(self:get_properties().mesh):new({player=self.player})
self.control_handler = Guns4d.control_handler:new({player=player, actions=self.gun.properties.control_actions, gun=self.gun})
self.control_handler = Guns4d.control_handler:new({player=player, gun=self.gun, touchscreen=self.touchscreen})
--this needs to be stored for when the gun is unset!
self.horizontal_offset = self.gun.properties.ads.horizontal_offset

View File

@ -35,7 +35,7 @@ Guns4d.default_controls.firemode = {
end
end
}
Guns4d.default_controls.toggle_safety = {
--[[Guns4d.default_controls.toggle_safety = {
conditions = {"sneak", "zoom"},
loop = false,
timer = 2,
@ -48,8 +48,8 @@ Guns4d.default_controls.toggle_safety = {
end
end
}
Guns4d.default_controls.on_use = function(itemstack, handler, pointed_thing)
}]]
Guns4d.default_controls.on_use = function(itemstack, handler, pointed_thing, busy_list)
local gun = handler.gun
local fmode = gun.properties.firemodes[gun.current_firemode]
if fmode ~= "safe" and not (gun.burst_queue > 0) then

View File

@ -20,7 +20,8 @@ Guns4d.config = {
simple_headshot = true, --holdover feature before a more complex system is implemented
simple_headshot_body_ratio = .75, --percentage of hitbox height that is body.
default_fov = 80,
headshot_damage_factor = 1.75
headshot_damage_factor = 1.75,
enable_touchscreen_command_name = "guns4d_enable_touchmode",
--`["official_content.replace_ads_with_bloom"] = false,
--`["official_content.uses_magazines"] = true
}
@ -45,6 +46,7 @@ dofile(path.."/item_entities.lua")
dofile(path.."/play_sound.lua")
dofile(path.."/visual_effects.lua")
dofile(path.."/default_controls.lua")
dofile(path.."/touch_support.lua")
dofile(path.."/block_values.lua")
dofile(path.."/ammo_api.lua")
path = path .. "/classes"
@ -54,7 +56,7 @@ dofile(path.."/Control_handler.lua")
dofile(path.."/Ammo_handler.lua")
dofile(path.."/Sprite_scope.lua")
dofile(path.."/Dynamic_crosshair.lua")
dofile(path.."/Gun.lua")
dofile(path.."/Gun.lua") --> loads /classes/gun_construct.lua
dofile(path.."/Player_model_handler.lua")
dofile(path.."/Player_handler.lua")
dofile(path.."/Proxy_table.lua")

52
touch_support.lua Normal file
View File

@ -0,0 +1,52 @@
minetest.register_chatcommand(Guns4d.config.enable_touchscreen_command_name, {
parameters = "player",
description = "toggle wether the user is using a mobile device so controls can be adjusted for an optimal mobile experience",
privs = {privs=true},
func = function(caller, arg)
local handler = Guns4d.players[caller]
if handler and handler.control_handler then
handler.control_handler:toggle_touchscreen_mode()
minetest.chat_send_player(caller, "mobile mode "..((handler.control_handler.touchscreen and "enabled") or "disabled"))
if handler.control_handler.touchscreen then
minetest.chat_send_player(caller, "shift+tap to aim, shift+hold to switch fire modes, tap to fire, hold to fire full auto (when wielding a full auto weapon)")
end
end
end
})
Guns4d.default_touch_controls = {}
local touch = Guns4d.default_touch_controls
local pc = Guns4d.default_controls
--aiming
touch.aim = table.copy(pc.aim)
touch.aim.conditions = {"RMB", "sneak"}
--switching firemode
touch.firemode = table.copy(pc.firemode)
touch.firemode.conditions = {"LMB", "sneak"}
touch.firemode.func = function(active, interrupted, data, busy_list, gun, handler)
if active then
gun:cycle_firemodes()
end
end
--reloading
touch.reload = table.copy(pc.reload)
touch.reload.mode = "toggle"
--firing semi
touch.on_secondary_use = function(itemstack, handler, pointed_thing)
if not handler.control_handler.player_pressed.sneak then
pc.on_use(itemstack, handler, pointed_thing)
end
end
--full auto
touch.auto = table.copy(pc.auto)
touch.auto.conditions = {"LMB"}
touch.auto.func = function(active, interrupted, data, busy_list, gun, handler)
if (not handler.control_handler.player_pressed.sneak) and gun.properties.firemodes[gun.current_firemode] == "auto" then
gun:attempt_fire()
end
end