You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-13 13:31:48 +00:00
Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
event.is_action("my_action", true)
```
This commit is contained in:
@@ -50,7 +50,7 @@ void InputMap::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("action_erase_event", "action", "event"), &InputMap::action_erase_event);
|
||||
ClassDB::bind_method(D_METHOD("action_erase_events", "action"), &InputMap::action_erase_events);
|
||||
ClassDB::bind_method(D_METHOD("action_get_events", "action"), &InputMap::_action_get_events);
|
||||
ClassDB::bind_method(D_METHOD("event_is_action", "event", "action"), &InputMap::event_is_action);
|
||||
ClassDB::bind_method(D_METHOD("event_is_action", "event", "action", "exact_match"), &InputMap::event_is_action, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("load_from_project_settings"), &InputMap::load_from_project_settings);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ List<StringName> InputMap::get_actions() const {
|
||||
return actions;
|
||||
}
|
||||
|
||||
List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
|
||||
List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
|
||||
ERR_FAIL_COND_V(!p_event.is_valid(), nullptr);
|
||||
|
||||
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
|
||||
@@ -106,7 +106,9 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re
|
||||
|
||||
int device = e->get_device();
|
||||
if (device == ALL_DEVICES || device == p_event->get_device()) {
|
||||
if (e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) {
|
||||
if (p_exact_match && e->shortcut_match(p_event)) {
|
||||
return E;
|
||||
} else if (!p_exact_match && e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) {
|
||||
return E;
|
||||
}
|
||||
}
|
||||
@@ -134,7 +136,7 @@ void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone)
|
||||
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
|
||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
if (_find_event(input_map[p_action], p_event)) {
|
||||
if (_find_event(input_map[p_action], p_event, true)) {
|
||||
return; // Already addded.
|
||||
}
|
||||
|
||||
@@ -143,13 +145,13 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent
|
||||
|
||||
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||
ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
return (_find_event(input_map[p_action], p_event) != nullptr);
|
||||
return (_find_event(input_map[p_action], p_event, true) != nullptr);
|
||||
}
|
||||
|
||||
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
|
||||
List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event);
|
||||
List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event, true);
|
||||
if (E) {
|
||||
input_map[p_action].inputs.erase(E);
|
||||
if (Input::get_singleton()->is_action_pressed(p_action)) {
|
||||
@@ -185,11 +187,11 @@ const List<Ref<InputEvent>> *InputMap::action_get_events(const StringName &p_act
|
||||
return &E->get().inputs;
|
||||
}
|
||||
|
||||
bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const {
|
||||
return event_get_action_status(p_event, p_action);
|
||||
bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match) const {
|
||||
return event_get_action_status(p_event, p_action, p_exact_match);
|
||||
}
|
||||
|
||||
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
|
||||
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
|
||||
Map<StringName, Action>::Element *E = input_map.find(p_action);
|
||||
ERR_FAIL_COND_V_MSG(!E, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
|
||||
@@ -207,7 +209,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
|
||||
bool pressed;
|
||||
float strength;
|
||||
float raw_strength;
|
||||
List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength, &raw_strength);
|
||||
List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, p_exact_match, &pressed, &strength, &raw_strength);
|
||||
if (event != nullptr) {
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = pressed;
|
||||
|
||||
Reference in New Issue
Block a user