GameMaker Using called info in a 2D Array

I have an array that is almost 100 units in height (and 3 in length). Here is just a sampling:

TextBox [0,0] = Wrench_obj //The object that is hovered over.
TextBox [0,1] = "Wrench: " //Name of item
TextBox [0,2] = "A heavy tool used to work pipes." //Description of item.

TextBox [1,0] = Pliers_obj
TextBox [1,1] = "Pliers: "
TextBox [1,2] = "These are needle-nosed."

TextBox [2,0] = Saw_obj
TextBox [2,1] = "Handsaw: "
TextBox [2,2] = "The old way to CTRL+X."

TextBox [3,0] = Bucket_Empty_obj
TextBox [3,1] = "Empty Bucket: "
TextBox [3,2] = "An empty bucket; there's nothing in it."

TextBox [4,0] = Bucket_Water_obj
TextBox [4,1] = "Bucket of Water: "
TextBox [4,2] = "This bucket is full of high quality H2O."

What I am trying to achieve is when the cursor mouses-over an object, it will display text in the bottom left-hand side of the screen. Ideally, the code would be something like: if the hovered-over object is [x,0] then draw the string [x,1] and string [x,2] at (600, 50). So if it is the Wrench_obj that is hovered over, it displays "Wrench: A heavy tool used to work pipes." But if it is the Bucket_Empty_obj that is hovered over, it displays: "Empty Bucket: An empty bucket; there's nothing in it." And so on.

My thinking is that by having all of these item names and descriptions in one place, I won't have to code all the separate messages for all 100 items. I've been struggling to figure this out, and after hours of no success, I turn to you, oh community, for help. Much appreciated.
 

Nidoking

Member
You have a parent object for them all, right? Just have that search through the array for its own object_index to get the message to display. I assume you've already got the mechanics of handling the actual hover text.

You could also map the object indices to the array indices, potentially even just having whatever object creates the array loop through it and build the map as it goes. Then you can use the map instead of searching every time.
 
Well, I would not use objects. What you're using is simply data. Just store it as data, with whatever you need to access held within that data. I would use a ds_list combined with ds_maps personally, but you could also use a ds_grid, or an array as you are (though arrays are going to be a little harder to mange if you want to delete or sort items). If you need to draw a sprite for it, store the sprite you need to draw in the data structure as well, if you need something to happen when clicked, store a script name in it. Then you can simply draw the inventory with a for loop:
Code:
var inv_start_x = 100;
var inv_start_y = 100; // The position where you want the inventory drawing to start
var inv_cell_size = 64; // This is the size of the "area" that a single inventory item should occupy on the screen
var inv_width = 10; // How many items you want before the inventory drawing loops to the next line
draw_set_halign(fa_center);
draw_set_valign(fa_top);
for (var i=0;i<array_height_2d(TextBox);i++) {
   var _sprite = TextBox[i,0]; // I've replaced object with sprite here, as objects are unnecessary
   var _name = TextBox[i,1]; 
   var _desc = TextBox[i,2];
   var _script = TextBox[i,3];
   var xx = inv_start_x+(i mod inv_width)*inv_cell_size; // This starts at inv_start_x, then it mods i by inv_width, which will equal 0, then 1, then 2, up to 10, before looping back to 0, then it multiplies i by inv_cell_size
   var yy = inv_start_y+(i div inv_width)*inv_cell_size; // Same as above, except that i div inv_width means that it will stay at 0 until 10 has been reached, then it will go to 1 until another 10 have been reached and then it will go to 2, etc
   draw_sprite(_sprite,0,xx,yy); // Draw your inv sprite
   draw_text(xx+inv_cell_size/2,yy,_name); // Draw your inv name
   if (point_in_rectangle(mouse_x,mouse_y,xx,yy,xx+inv_cell_size,yy+inv_cell_size)) { // If the mouse is within the "area" for the item that is currently being looped through
      draw_text(xx+inv_cell_size/2,yy+inv_cell_size/2,_desc); // Draw it's description
      if (mouse_check_button_released(mb_left)) { // If the user clicks while hovering
         script_execute(_script); // Execute the associated script
      }
   }
}
 

TailBit

Member
I would do a instance_place check where the mouse is, and to avoid looking up the correct index every time, have it store the object it last searched for and the index it found:

GML:
var ins = instance_position(mouse_x,mouse_y, obj_item_parent);

if (ins != noone){
    
    // if this is a new object .. look up the array index
    if(last_object != ins.object_index){
        last_object = ins.object_index;
        last_index  = noone;
        for(var i = 0; i<array_height_2d(TextBox);i++){
            if TextBox[i,0] = last_object {
                last_index = i;
                break;
            }
        }
    }
    
    // if we know the index, draw it
    if last_index != noone{
        draw_text(x,y,TextBox[last_index,1]);
    }

}
maybe found_object/index would be a better name
 
Wow. Thank you all for the replies. I've been away for a few days and am just checking back. I will try out your suggestions and let you know how it went. Thank you very much.
 
Okay, here is the update. In the Text_Parent_Control object I have a:
Create Event with ShowText = false;
Mouse Enter with ShowText = true;
Mouse Leave with ShowText = false;
and DrawGUI with:
GML:
TextBox [0,0] = WrenchObj //The object that is hovered over.
TextBox [0,1] = "Wrench: " //Name of item
TextBox [0,2] = "A heavy tool used to work pipes." //Description of item.

TextBox [1,0] = PliersObj
TextBox [1,1] = "Pliers: "
TextBox [1,2] = "These are needle-nosed."

TextBox [2,0] = saw_obj
TextBox [2,1] = "Handsaw: "
TextBox [2,2] = "The old way to CTRL+X."

TextBox [3,0] = Bucket_Empty_Obj
TextBox [3,1] = "Empty Bucket: "
TextBox [3,2] = "An empty bucket; there's nothing in it."

TextBox [4,0] = Bucket_Water_obj
TextBox [4,1] = "Bucket of Water: "
TextBox [4,2] = "This bucket is full of high quality H2O."

    if (ShowText == true) &&
    object_index == self then
    {
    for (var i=0;i<array_height_2d(TextBox);i++)
        {
        var _name = TextBox[i,1];
        var _desc = TextBox[i,2];
        draw_text(60, 525, string(_name) + string(_desc));
        }
    }
This still isn't working.
I've also tried swapping the Wrench_obj with Wrench_sp (etc), and it still isn't working. I feel like I'm closer, but I'm just not getting it. Any additional help would be appreciated. Thanks.
 
Well, object_index won't ever == self. You'd need to extract the data from the array first, something like this:
Code:
if (ShowText == true) {
    for (var i=0;i<array_height_2d(TextBox);i++) {
        var _obj_id = TextBox[i,0];
        if (object_index == _obj_id) {
            var _name = TextBox[i,1];
            var _desc = TextBox[i,2];
            draw_text(60, 525, string(_name) + string(_desc));
            break;
        }
    }
}
This'll loop through the array, looking at all the object indices stored in it, and if the object currently running the code has an object_index that matches one of them, it draws that text then breaks the the loop.
 
Well, object_index won't ever == self. You'd need to extract the data from the array first, something like this:
Code:
if (ShowText == true) {
    for (var i=0;i<array_height_2d(TextBox);i++) {
        var _obj_id = TextBox[i,0];
        if (object_index == _obj_id) {
            var _name = TextBox[i,1];
            var _desc = TextBox[i,2];
            draw_text(60, 525, string(_name) + string(_desc));
            break;
        }
    }
}
This'll loop through the array, looking at all the object indices stored in it, and if the object currently running the code has an object_index that matches one of them, it draws that text then breaks the the loop.
You. Are. Awesome.
That fixed it.
Thank you very much!
 
Top