0

I've made a controls room for custom keymapping. I had an idea - if key is assigned to more than 1 control, then it shows up red. But it works only partially.

Spawn code:

with(instance_create(64,64,obj_button_key)) {
    mytext="UP: ";
    myKEY=global.keyUP;
    mytype=1;
}
with(...

scr_keymap_conflict(argument0):

var ii;
ii = 0;

if (argument0 == global.keyUP) ii+=1;
if (argument0 == global.keyDOWN) ii+=1;
if (argument0 == global.keyLEFT) ii+=1;
if (argument0 == global.keyRIGHT) ii+=1;
if (argument0 == global.keySPRINT) ii+=1;
if (argument0 == global.keyCROUCH) ii+=1;
if (argument0 == global.keyGRENADE) ii+=1;
if (argument0 == global.keyACTION) ii+=1;
if (argument0 == global.keyCHAT) ii+=1;
if (argument0 == global.keyMELEE) ii+=1;
if (argument0 == global.keyDROP) ii+=1;

if (ii > 1) {
    return true;
}

Draw:

if (active) {draw_set_color(c_yellow)}
else if (scr_keymap_conflict(myKEY)) {draw_set_color(c_red)}
else draw_set_color(c_gray);
...

It seems like there's a problem with scr_keymap_conflict(argument0) giving invalid info, so some buttons turn red, but some don't, an example, if there are two vk_space controls, then the first one will become red, but the second won't (I have a feeling that draw_set_color is overwriting separate objects at random moments). Anyway, global.key... hold ASCII real values (keyboard shortcuts). active and mytype are not important in this case. Anyone got any idea how to fix this?

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
Martin
  • 15
  • 2
  • 7
  • Code looks correct. https://www.dropbox.com/s/y9a251wf7uf841u/redefine_keys.gmk – Dmi7ry Jan 19 '14 at 12:52
  • at first I tried with `switch(argument0)` and without adding `break` at the end, but there was no difference. Well I'll keep experimenting, maybe I'll come to a conclusion. Btw I have studio, so your file won't probably work and I already have my own key redefination scripts (which took me like 2 days to make) – Martin Jan 19 '14 at 19:00
  • is there a different way to check for objects with same variables? I mean something similar to `instance_number(obj)`, but more like `instance_variable(obj,var)` which returns true if more of these `obj` instances have same value `var` variables – Martin Jan 19 '14 at 19:14
  • you can import project. if you want get all objects which have some variables as `true`, you can make list and add needed objects to it. like this: `global.list = ds_list_create(); with (obj_enemy) { if (aaa=true and bbb=true) { ds_list_add(global.list, id) } }` – Dmi7ry Jan 21 '14 at 10:22

1 Answers1

0

Your script is only returning a value in case of ii being equal or more than 1. When GM ends a script without a return value (or simply calling "return") the value returned is just random, it might be "true" or "false", or "hello world" string.

(typically it is the previous function's result).

This is a first bug, but when you fix it you'll notice keys will never turn red.. This is because semantically you're checking if a key is binded to two "functions". NOT if two "functions" are binded to 2 keys.

You would need a different system for that, easiest thing I can think of is to use a controller (code below isn't tested, just to show the idea):

create event controlling object

keyUP = ds_list_create();
keyDown = ds_list_create();
keyLEFT = ds_list_create();
keyRIGHT = ds_list_create();
keySPRINT = ds_list_create();
keyCROUCH = ds_list_create();
keyGRENADE = ds_list_create();
keyACTION = ds_list_create();
keyCHAT = ds_list_create();
keyMELEE = ds_list_create();
keyDROP = ds_list_create();

step event controlling object

ds_list_clear(keyUP);
ds_list_clear(keyDOWN);
//... etc for all keys

with (objKeys) {
    ds_list_add(myKEY, id);
}

spawn code of objKeys

with(instance_create(64,64,obj_button_key)) {
    mytext="UP: ";
    myKEY=objKeyController.keyUP; 
        //notice that it refers to the controller's list
    mytype=1;
}

draw event

if (active) {draw_set_color(c_yellow)}
else if (ds_list_size(myKEY) > 1) {draw_set_color(c_red)}
else draw_set_color(c_gray);
...

The controller's step event can probably be removed if you add/remove the keys to/from the lists on assignment (user input). That way the lists don't have to rebuild each step. Also an obvious improvement is to stash all those "keys" inside a map instead of simple variables.

This method has O(n) time instead of O(n^2) you would get when using a function instance_variable(obj,var)

paul23
  • 8,799
  • 12
  • 66
  • 149
  • something weird started happening o.O I tried your code, but without success. So I reversed it. Now for completly no reasons whenever I press on "Options" button to go to options menu to reassign keys it just starts lagging, fps drops quickly and control object just skips `if (room == rm_options)` and instead triggers both - `if (room == rm_menu) { scr_menu_init(); } else { scr_othermenu_init(); }` – Martin Jan 21 '14 at 16:52
  • which makes dialog buttons from main menu and options screen in a single room. I can't imagine how could this have happened o.O – Martin Jan 21 '14 at 16:55
  • lol, it got fixed when i reinstalled config (deleted my game's *.ini file) – Martin Jan 21 '14 at 17:00
  • i'll experiment around with instance_number and instance_find using loops :/ – Martin Jan 21 '14 at 17:17