godot-third-person-basic-scene/scenes/controls/controls.gd

273 lines
7.7 KiB
GDScript

extends Control
var control_system_conf = {}
func _init():
load_control_system()
func _ready():
pass
func reload_control_system():
# Adding new Action
for key in control_system_conf:
if not InputMap.has_action(key):
InputMap.add_action(key)
# Adding new event
for newevent in control_system_conf[key]:
var ele = generate_inputevent(newevent)
if not InputMap.action_has_event(key, ele):
InputMap.action_add_event(key, ele)
# Remove action/event not used
for keyInput in InputMap.get_actions():
var foundAction:bool = false
for key in control_system_conf:
if key == keyInput:
foundAction = true
break
if not foundAction:
InputMap.erase_action(keyInput)
continue
var listInput = InputMap.get_action_list(keyInput)
for eventInput in listInput:
var foundEvent:bool = false
var vis = get_dict_inputevent(eventInput)
for v in control_system_conf[keyInput]:
if compare_dict_inputevent(v, vis):
foundEvent = true
break
if not foundEvent:
InputMap.action_erase_event(keyInput, eventInput)
func compare_dict_inputevent(ref, cmp):
if ref.size() != cmp.size():
return false
for key in ref:
if ref[key] != cmp[key]:
return false
return true
func get_dict_inputevent(event):
if event is InputEventKey:
return {
'type' : 'InputEventKey',
'keycode' : event.get_keycode(),
'physical_keycode' : event.get_physical_keycode(),
'unicode' :event.get_unicode(),
'echo' : event.is_echo(),
'alt' : event.is_alt_pressed(),
'command' : event.is_command_pressed(),
'control' : event.is_ctrl_pressed(),
'meta' : event.is_meta_pressed(),
'shift' : event.is_shift_pressed(),
'storing_command': event.is_storing_command()
}
elif event is InputEventMouseButton:
return { 'type' : 'InputEventMouseButton', 'value' : event.get_button_index() }
elif event is InputEventJoypadButton:
return { 'type' : 'InputEventJoypadButton', 'value' : event.get_button_index() }
return { 'type' : 'Unknown'}
func generate_inputevent(param):
if param['type'] == 'InputEventKey':
var ele:InputEventKey = InputEventKey.new()
ele.set_physical_scancode(param['physical_scancode'])
ele.set_scancode(param['scancode'])
ele.set_echo(param['echo'])
if OS.get_ime_selection():
ele.set_unicode(param['unicode'])
ele.set_alt(param['alt'])
ele.set_command(param['command'])
ele.set_control(param['control'])
ele.set_metakey(param['meta'])
ele.set_shift(param['shift'])
return ele
elif param['type'] == 'InputEventMouseButton':
var ele:InputEventMouseButton = InputEventMouseButton.new()
ele.set_button_index(param['value'])
return ele
elif param['type'] == 'InputEventJoypadButton':
var ele:InputEventJoypadButton = InputEventJoypadButton.new()
ele.set_button_index(param['value'])
return ele
return null
func get_hash_inputevent(event):
var head:String
if event is InputEventKey:
head = 'a'
elif event is InputEventMouseButton:
head = 'm'
elif event is InputEventJoypadButton:
head = 'j'
else:
head ='z'
return head + str(get_string_input(event))
func get_string_input_mousse_button(event:InputEventMouseButton):
match event.get_button_index():
1:
return "BUTTON_LEFT"
3:
return "BUTTON_MIDDLE"
2:
return "BUTTON_RIGHT"
4:
return "BUTTON_WHEEL_UP"
5:
return "BUTTON_WHEEL_DOWN"
6:
return "BUTTON_WHEEL_LEFT"
7:
return "BUTTON_WHEEL_RIGHT"
8:
return "BUTTON_XBUTTON1"
9:
return "BUTTON_XBUTTON2"
_:
return "MOUSSE BUTTON: " + str(event.get_button_index())
func get_string_input_joypad_button(event:InputEventJoypadButton):
match event.get_button_index():
0:
return "JOY_BUTTON_A"
1:
return "JOY_BUTTON_B"
2:
return "JOY_BUTTON_X"
3:
return "JOY_BUTTON_Y"
4:
return "JOY_BUTTON_BACK"
5:
return "JOY_BUTTON_GUIDE"
6:
return "JOY_BUTTON_START"
7:
return "JOY_BUTTON_LEFT_STICK"
8:
return "JOY_BUTTON_RIGHT_STICK"
9:
return "JOY_BUTTON_LEFT_SHOULDER"
10:
return "JOY_BUTTON_RIGHT_SHOULDER"
11:
return "JOY_BUTTON_DPAD_UP"
12:
return "JOY_BUTTON_DPAD_DOWN"
13:
return "JOY_BUTTON_DPAD_LEFT"
14:
return "JOY_BUTTON_DPAD_RIGHT"
_:
return "JOYPAD BUTTON: " + str(event.get_button_index())
func get_string_input_keyboard(event:InputEventKey):
return OS.get_keycode_string(event.keycode)
func get_string_input(event):
if event is InputEventKey:
return get_string_input_keyboard(event) # OS.get_scancode_string(event.get_scancode_with_modifiers())
elif event is InputEventMouseButton:
return get_string_input_mousse_button(event)
elif event is InputEventJoypadButton:
return get_string_input_joypad_button(event)
else:
return str(event)
func load_current_control():
var conf = {}
for key in InputMap.get_actions():
var a = InputMap.action_get_events(key)
var beta = []
for z in a:
beta.append( get_dict_inputevent(z) )
conf[key] = beta
return conf
func configure_control():
if $Window/VBox/Menu/SortByInput.is_pressed():
configure_control_sort_by_input()
else:
configure_control_sort_by_categories()
func configure_control_sort_by_input():
#$Window/VBox/Input/Control
var def = {}
for action in InputMap.get_actions():
for z in InputMap.action_get_events(action):
var id = str(get_hash_inputevent(z)) + "_" + str(action)
def[id] = { 'event': z, 'action': action }
var defsorted = def.keys()
defsorted.sort()
var lastevent = null
for id in defsorted:
var z = def[id]['event']
var action = def[id]['action']
var zhash = get_dict_inputevent(z).hash()
if zhash != lastevent:
var separator = HSeparator.new()
$Window/VBox/Input/Control.add_child( separator )
lastevent = zhash
if z is InputEventKey:
var item = preload( "res://scenes/controls/control_input.tscn" ).instantiate(1) #.instance()
item.set_param(action, get_string_input_keyboard(z), action, z)
#item.connect( "del_pressed", self, "_on_input_box_del_pressed" )
#print(action,':', z, z.get_scancode_with_modifiers(),' - ', z.get_scancode(), ' - ', z.unicode , ' - ', OS.get_scancode_string(z.get_scancode_with_modifiers()))
$Window/VBox/Input/Control.add_child( item )
#$Window/VBox/Test.add_child( item )
elif z is InputEventMouseButton:
var item = preload( "res://scenes/controls/control_input.tscn" ).instantiate()
#item.set_label(action, "Mouse Button: " + str(z.get_button_index()))
item.set_param(action, "Mouse Button: " + get_string_input_mousse_button(z), action, z)
#item.connect( "del_pressed", self, "_on_input_box_del_pressed" )
$Window/VBox/Input/Control.add_child( item )
#print(action,':', z, z.get_button_mask(), ' - ', z.get_factor(), ' - ' , z.get_button_index() )
elif z is InputEventJoypadButton:
#print(action,':', z, z.get_button_index() )
var item = preload( "res://scenes/controls/control_input.tscn" ).instantiate()
#item.set_label(action, "Joypad Button: " + str(z.get_button_index()))
item.set_param(action, "Joypad Button: " + get_string_input_joypad_button(z), action, z)
#item.connect( "del_pressed", self, "_on_input_box_del_pressed" )
$Window/VBox/Input/Control.add_child( item )
for action in InputMap.get_actions():
var separator = HSeparator.new()
$Window/VBox/Input/Control.add_child( separator )
var control_box = preload( "res://scenes/controls/control_function.tscn" ).instantiate()
#control_box.set_label(key)
control_box.set_param(action, action, true)
#control_box.connect( "add_pressed", self, "_on_control_box_add_pressed" )
$Window/VBox/Input/Control.add_child( control_box )
func configure_control_sort_by_categories():
print("configure_control_sort_by_categories")
func load_control_system():
control_system_conf = load_current_control()
func _on_quit_pressed():
$Window.visible = false
func _on_sort_by_input_pressed():
configure_control()