• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Hot bar Spell cooldowns

C

cheque

Guest
I'm currently working on a hot bar for spells in my game, and I got something working but I think its just way to much unnecessary code. I was hopefully one of you Game maker wizards could help me. anyways code:


wep_select = 0;
Spell_slot1 =0;
Spell_slot2 =0;
Spell_slot3 =0;
Spell_slot4 =0;
Spell_slot5 =0;
Spell_slot1_cooldown = 0;
Spell_slot2_cooldown = 0;
Spell_slot3_cooldown = 0;
Spell_slot4_cooldown = 0;
Spell_slot5_cooldown = 0;
Ss1c = Spell_slot1_cooldown;
Ss2c = Spell_slot2_cooldown;
Ss3c = Spell_slot3_cooldown;
Ss4c = Spell_slot4_cooldown;
Ss5c = Spell_slot5_cooldown;
CoolDalpha = 0;
CoolDalpha2 = 0;
CoolDalpha3 = 0;
CoolDalpha4 = 0;
CoolDalpha5 = 0;
OutlineColor = 0;
OutlineColor2 = 0;
OutlineColor3 = 0;
OutlineColor4 = 0;
OutlineColor5 = 0;

var spell_cd = obj_magicTree_GUI.ds_spell_info; //contaning all the cooldowns in a ds list

if keyboard_check_pressed(ord("1"))
{
wep_select = 1;
if Ss1c = Spell_slot1_cooldown{
Spell_slot1 = ds_MagicTree[# 0,0]; //ds_MagicTree is the actual ds_list for the hotbar ranging from 0-4
if Spell_slot1 > 0{
Spell_slot1_cooldown = spell_cd[# 2,Spell_slot1];
Ss1c = Spell_slot1_cooldown;
Ss1c -= .05;}
}}

if keyboard_check_pressed(ord("2"))
{
wep_select = 2;
if Ss2c = Spell_slot2_cooldown{
Spell_slot2 = ds_MagicTree[# 0,1];
if Spell_slot2 > 0{
Spell_slot2_cooldown = spell_cd[# 2,Spell_slot2];
Ss2c = Spell_slot2_cooldown;
Ss2c -= .05;}
}}

if keyboard_check_pressed(ord("3"))
{
wep_select = 3;
if Ss3c = Spell_slot3_cooldown{
Spell_slot3 = ds_MagicTree[# 0,2];
if Spell_slot3 > 0{
Spell_slot3_cooldown = spell_cd[# 2,Spell_slot3];
Ss3c = Spell_slot3_cooldown;
Ss3c -= .05;}
}}

if keyboard_check_pressed(ord("4"))
{
wep_select = 4;
if Ss4c = Spell_slot4_cooldown{
Spell_slot4 = ds_MagicTree[# 0,3];
if Spell_slot4 > 0{
Spell_slot4_cooldown = spell_cd[# 2,Spell_slot4];
Ss4c = Spell_slot4_cooldown;
Ss4c -= .05;}
}}


if keyboard_check_pressed(ord("5"))
{
wep_select = 5;
if Ss5c = Spell_slot5_cooldown{
Spell_slot5 = ds_MagicTree[# 0,4];
if Spell_slot5 > 0{
Spell_slot5_cooldown = spell_cd[# 2,Spell_slot5];
Ss5c = Spell_slot5_cooldown;
Ss5c -= .05;}
}}


var Sps1_c = ds_MagicTree[# 0,0];
var Sps2_c = ds_MagicTree[# 0,1];
var Sps3_c = ds_MagicTree[# 0,2];
var Sps4_c = ds_MagicTree[# 0,3];
var Sps5_c = ds_MagicTree[# 0,4];

if Sps1_c != Spell_slot1 {OutlineColor = make_color_rgb(255,0,0); Ss1c =Spell_slot1_cooldown;}
if Sps2_c != Spell_slot2 {OutlineColor2 = make_color_rgb(255,0,0); Ss2c =Spell_slot2_cooldown;}
if Sps3_c != Spell_slot3 {OutlineColor3 = make_color_rgb(255,0,0); Ss3c =Spell_slot3_cooldown;}
if Sps4_c != Spell_slot4 {OutlineColor4 = make_color_rgb(255,0,0); Ss4c =Spell_slot4_cooldown;}
if Sps5_c != Spell_slot5 {OutlineColor5 = make_color_rgb(255,0,0); Ss5c =Spell_slot5_cooldown;}

#region cooldown Ss1c/Spell_slot1_cooldown
if (Ss1c <= 0){Ss1c = Spell_slot1_cooldown;}
if (Ss1c < Spell_slot1_cooldown){Ss1c -= .05;}
if (Ss1c = Spell_slot1_cooldown){CoolDalpha = 0;} else {CoolDalpha = 1;}

if Ss1c = Spell_slot1_cooldown{OutlineColor = make_color_rgb(0,255,255);} // blue
if Ss1c < Spell_slot1_cooldown and Ss1c > Spell_slot1_cooldown-(Spell_slot1_cooldown*.4){OutlineColor = make_color_rgb(255,0,0);}// red
if Ss1c = Spell_slot1_cooldown-(Spell_slot1_cooldown*.4){OutlineColor = make_color_rgb(255,100,0);}// orange
if Ss1c = Spell_slot1_cooldown-(Spell_slot1_cooldown*.6){OutlineColor = make_color_rgb(255,200,0);} // yellow
if Ss1c = Spell_slot1_cooldown-(Spell_slot1_cooldown*.8){OutlineColor = make_color_rgb(8,255,0);}// green


if (Ss2c <= 0){Ss2c = Spell_slot2_cooldown;}
if (Ss2c < Spell_slot2_cooldown){Ss2c -= .05;}
if (Ss2c = Spell_slot2_cooldown){CoolDalpha2 = 0;} else {CoolDalpha2 = 1;}

if Ss2c = Spell_slot2_cooldown{OutlineColor2 = make_color_rgb(0,255,255);} // blue
if Ss2c < Spell_slot2_cooldown and Ss2c > Spell_slot2_cooldown-(Spell_slot2_cooldown*.4){OutlineColor2 = make_color_rgb(255,0,0);}// red
if Ss2c = Spell_slot2_cooldown-(Spell_slot2_cooldown*.4){OutlineColor2 = make_color_rgb(255,100,0);}// orange
if Ss2c = Spell_slot2_cooldown-(Spell_slot2_cooldown*.6){OutlineColor2 = make_color_rgb(255,200,0);} // yellow
if Ss2c = Spell_slot2_cooldown-(Spell_slot2_cooldown*.8){OutlineColor2 = make_color_rgb(8,255,0);}// green


if (Ss3c <= 0){Ss3c = Spell_slot3_cooldown;}
if (Ss3c < Spell_slot3_cooldown){Ss3c -= .05;}
if (Ss3c = Spell_slot3_cooldown){CoolDalpha3 = 0;} else {CoolDalpha3 = 1;}

if Ss3c = Spell_slot3_cooldown{OutlineColor3 = make_color_rgb(0,255,255);} // blue
if Ss3c < Spell_slot3_cooldown and Ss3c > Spell_slot3_cooldown-(Spell_slot3_cooldown*.4){OutlineColor3 = make_color_rgb(255,0,0);}// red
if Ss3c = Spell_slot3_cooldown-(Spell_slot3_cooldown*.4){OutlineColor3 = make_color_rgb(255,100,0);}// orange
if Ss3c = Spell_slot3_cooldown-(Spell_slot3_cooldown*.6){OutlineColor3 = make_color_rgb(255,200,0);} // yellow
if Ss3c = Spell_slot3_cooldown-(Spell_slot3_cooldown*.8){OutlineColor3 = make_color_rgb(8,255,0);}// green


if (Ss4c <= 0){Ss4c = Spell_slot4_cooldown;}
if (Ss4c < Spell_slot4_cooldown){Ss4c -= .05;}
if (Ss4c = Spell_slot4_cooldown){CoolDalpha4 = 0;} else {CoolDalpha4 = 1;}

if Ss4c = Spell_slot4_cooldown{OutlineColor4 = make_color_rgb(0,255,255);} // blue
if Ss4c < Spell_slot4_cooldown and Ss4c > Spell_slot4_cooldown-(Spell_slot4_cooldown*.4){OutlineColor4 = make_color_rgb(255,0,0);}// red
if Ss4c = Spell_slot4_cooldown-(Spell_slot4_cooldown*.4){OutlineColor4 = make_color_rgb(255,100,0);}// orange
if Ss4c = Spell_slot4_cooldown-(Spell_slot4_cooldown*.6){OutlineColor4 = make_color_rgb(255,200,0);} // yellow
if Ss4c = Spell_slot4_cooldown-(Spell_slot4_cooldown*.8){OutlineColor4 = make_color_rgb(8,255,0);}// green


if (Ss5c <= 0){Ss5c = Spell_slot5_cooldown;}
if (Ss5c < Spell_slot5_cooldown){Ss5c -= .05;}
if (Ss5c = Spell_slot5_cooldown){CoolDalpha5 = 0;} else {CoolDalpha5 = 1;}

if Ss5c = Spell_slot5_cooldown{OutlineColor5 = make_color_rgb(0,255,255);} // blue
if Ss5c < Spell_slot5_cooldown and Ss5c > Spell_slot5_cooldown-(Spell_slot5_cooldown*.4){OutlineColor5 = make_color_rgb(255,0,0);}// red
if Ss5c = Spell_slot5_cooldown-(Spell_slot5_cooldown*.4){OutlineColor5 = make_color_rgb(255,100,0);}// orange
if Ss5c = Spell_slot5_cooldown-(Spell_slot5_cooldown*.6){OutlineColor5 = make_color_rgb(255,200,0);} // yellow
if Ss5c = Spell_slot5_cooldown-(Spell_slot5_cooldown*.8){OutlineColor5 = make_color_rgb(8,255,0);}// green

#region //background color

if Ss5c != Spell_slot5_cooldown
{
d3d_set_fog(true, OutlineColor5, 0, 0);
draw_sprite_ext(select_h,0,x+802-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,.3);
d3d_set_fog(false, c_white, 0, 0);
draw_sprite_ext(select_h,0,x+802-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

if Ss4c != Spell_slot4_cooldown
{
d3d_set_fog(true, OutlineColor4, 0, 0);
draw_sprite_ext(select_h,0,x+770-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,.3);
d3d_set_fog(false, OutlineColor4, 0, 0);
draw_sprite_ext(select_h,0,x+770-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

if Ss3c != Spell_slot3_cooldown
{
d3d_set_fog(true, OutlineColor3, 0, 0);
draw_sprite_ext(select_h,0,x+738-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,.3);
d3d_set_fog(false, OutlineColor3, 0, 0);
draw_sprite_ext(select_h,0,x+738-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

if Ss2c != Spell_slot2_cooldown
{
d3d_set_fog(true, OutlineColor2, 0, 0);
draw_sprite_ext(select_h,0,x+706-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,.3);
d3d_set_fog(false, OutlineColor2, 0, 0);
draw_sprite_ext(select_h,0,x+706-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

if Ss1c != Spell_slot1_cooldown
{
d3d_set_fog(true, OutlineColor, 0, 0);
draw_sprite_ext(select_h,0,x+674-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,.3);
d3d_set_fog(false, OutlineColor, 0, 0);
draw_sprite_ext(select_h,0,x+674-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

#endregion

#region //outline color
if _select = 5
{
d3d_set_fog(true, OutlineColor5, 0, 0);
draw_sprite_ext(select_h2,0,x+802-800,y+78+432,image_xscale+.1,image_yscale+.1,image_angle,image_blend,.5);
d3d_set_fog(false, OutlineColor5, 0, 0);
draw_sprite_ext(select_h2,0,x+802-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

if _select = 4
{
d3d_set_fog(true, OutlineColor4, 0, 0);
draw_sprite_ext(select_h2,0,x+770-800,y+78+432,image_xscale+.1,image_yscale+.1,image_angle,image_blend,.5);
d3d_set_fog(false, OutlineColor4, 0, 0);
draw_sprite_ext(select_h2,0,x+770-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

if _select = 3
{
d3d_set_fog(true, OutlineColor3, 0, 0);
draw_sprite_ext(select_h2,0,x+738-800,y+78+432,image_xscale+.1,image_yscale+.1,image_angle,image_blend,.5);
d3d_set_fog(false, OutlineColor3, 0, 0);
draw_sprite_ext(select_h2,0,x+738-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

if _select = 2
{
d3d_set_fog(true, OutlineColor2, 0, 0);
draw_sprite_ext(select_h2,0,x+706-800,y+78+432,image_xscale+.1,image_yscale+.1,image_angle,image_blend,.5);
d3d_set_fog(false, OutlineColor2, 0, 0);
draw_sprite_ext(select_h2,0,x+706-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}

if _select = 1
{
d3d_set_fog(true, OutlineColor, 0, 0);
draw_sprite_ext(select_h2,0,x+674-800,y+78+432,image_xscale+.1,image_yscale+.1,image_angle,image_blend,.5);
d3d_set_fog(false, OutlineColor, 0, 0);
draw_sprite_ext(select_h2,0,x+674-800,y+78+432,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}
#endregion

var x1x = -130
var y1y = 502

draw_text_color(x+x1x,y+y1y,(round(Ss1c)),c_white,c_aqua,OutlineColor,OutlineColor,CoolDalpha);
draw_text_color(x+x1x+32,y+y1y,(round(Ss2c)),c_white,c_aqua,OutlineColor2,OutlineColor2,CoolDalpha2);
draw_text_color(x+x1x+64,y+y1y,(round(Ss3c)),c_white,c_aqua,OutlineColor3,OutlineColor3,CoolDalpha3);
draw_text_color(x+x1x+96,y+y1y,(round(Ss4c)),c_white,c_aqua,OutlineColor4,OutlineColor4,CoolDalpha4);
draw_text_color(x+x1x+128,y+y1y,(round(Ss5c)),c_white,c_aqua,OutlineColor5,OutlineColor5,CoolDalpha5);

I only provided the code I'm using for the spell cooldown. here are 4 examples of what it looks like

HOTBAR_EXMP.png

if this is not enough information I will gladly provide more. again sorry for my horrible programming skills lol, thank you for any help
 

kburkhart84

Firehammer Games
It seems that you do need some organization. If its me, I have some object that is tracking the spells and their cooldowns. This is independent from the cooldowns you are showing in the bar. This object would store the spells' cooldowns both in seconds, and as a percentage. Then, each box in the hotbar would know what spell it is currently referring to, and store some reference to it in a variable(this reference would lead back to the other object's list of spells). You want the spells to manage themselves, and the hotbar to ONLY worry about drawing whatever cooldown of whatever spell it is looking at(I assume you might have different spells in the boxes at any given time based on player preference).

Basically, each object should only be responsible for one basic thing. The object with the spells tracks its cooldown, and the GUI things only gets a reference to that and draws itself.

Another thought, I would try to reduce any code duplication where I can. Instead of having all those variables, either have multiple objects(one for each section of a bar), or have an array. This would let you set a variable for looping through the array if that's how you did it. Or if you have separate objects/instances, then each one would have an instance variable that tells it what keyboard key to check(and what spell it is referring to for the cooldown, and the rest of the code would be the same for all of them.

A simple example of this is with simple GUI buttons. All the buttons can use the same parent object. That parent object handles drawing text from a variable, and executing some function(also in a variable), and handles the animation/sound of hovering the cursor over the button. Then, you can put multiple of those in the room, and just override that variable either in the instance_create event or using the dialogs for editing instances in the room editor. Since the code that is drawing the text uses a variable, it never changes because you just change the variable. The same is said for the function to execute when the button is clicked.

If you think in the same fashion for all these hotbar buttons, you will see how you can get rid of all that duplicate code and just use variables to tell them what spells to refer to and what keys to check. If your spells can be executed from multiple places(either multiple buttons on a customizeable hotbar, or maybe a direct keyboard shortcut, or in a dialog showing skills like in some MMOs), then you want only one object that is actually handling the spell execution, and anything else that could make the spell execute would just tell that object to do it.
 
C

cheque

Guest
so I was able to simplify some code but still I cant get it to work as the original, any tips?
code:

create event:
GML:
spell_cell_size32x32 = 32;
spell_slot_width = 5;
slots_x = 4;
slots_y =22;
spell_sacle =1;
Spell_List32x32 = spr_test_magic_spellList;
spell_spr_items_colums =sprite_get_width(Spell_List32x32)/spell_cell_size32x32;

spell_slot_cooldown = 0;
spell_slots = 0;
ssc = 0;
HotBar_slots = 5;

ds_HotBar = ds_grid_create(2,HotBar_slots);

ds_HotBar[# 0,0] = Spell.W_strike;
ds_HotBar[# 1,0] = 1;

ds_HotBar[# 0,1] = Spell.A_strike;
ds_HotBar[# 1,1] = 1;

ds_HotBar[# 0,3] = Spell.F_strike;
ds_HotBar[# 1,3] = 1;


step event:
GML:
if spell_slots > 0{
if (ssc <= 0){ssc = spell_slot_cooldown;}
if (ssc < spell_slot_cooldown){ssc -= .05;}}


Draw GUI event:
GML:
var ii, ix, iy, xx, yy, sx, sy, iitem, spell_grid;
ii = 0; ix = 0; iy = 0;
spell_grid = ds_HotBar;

repeat(HotBar_slots){
xx = (slots_x + ((spell_cell_size32x32)*ix*spell_sacle))+430;
yy = (slots_y + ((spell_cell_size32x32)*iy*spell_sacle))+615;

iitem = spell_grid[# 0,ii];

sx = (iitem mod spell_spr_items_colums)*spell_cell_size32x32;
sy = (iitem div spell_spr_items_colums)*spell_cell_size32x32;

draw_sprite_part_ext(Spell_List32x32, 1, sx,sy,spell_cell_size32x32,spell_cell_size32x32,xx,yy,spell_sacle,spell_sacle,c_white,1); //draws the spell

/////////////////////cooldown code:
var spell_cd = obj_magicTree_GUI.ds_spell_info; //a ds_list containing the info of the spells, like name, and cooldown time.

spell_slots = ds_HotBar[# 0,ii]; // a ds_list of the hotbar containing the info of which spell is in which hotbar slot.
spell_slot_cooldown = spell_cd[# 2,spell_slots];
if spell_slots > 0{ssc = spell_slot_cooldown;} ///////when removing this code<<<<<<<<<<

if keyboard_check_pressed(ord(ii+1))
{
    if spell_slots > 0{ssc = spell_slot_cooldown;}

if spell_slots > 0{
spell_slot_cooldown = spell_cd[# 2,spell_slots];
ssc -= .05;}}

if spell_slots > 0{ //if slot is empty
draw_text_color(xx,yy,round(ssc),c_white,c_aqua,OutlineColor,OutlineColor,1); //Draws the cooldown
}
/////////////////////
ii +=1;
ix = ii mod spell_slot_width;
iy = ii div spell_slot_width;
}
when removing the code: if spell_slots > 0{ssc = spell_slot_cooldown;} from the draw GUI event, the cooldown start to count down but it counts down on all the slots.
Examples:
HOTBAR_EXMP_repated numbers.png

when I don't remove the code above, it shows the cooldown number but doesn't count down. because of that code.
HOTBAR_EXMP_nums.png

any ideas would be apricated, thank you.
 

TailBit

Member
The reason it counts down all of them is because the only place you change ssc is when you press a number button
GML:
if keyboard_check_pressed(ord(ii+1))
{
    if spell_slots > 0{ssc = spell_slot_cooldown;}
so it will start to count down that skill
GML:
draw_text_color(xx,yy,round(ssc),c_white,c_aqua,OutlineColor,OutlineColor,1); //Draws the cooldown
and draw that variable for all the skills

But .. you are never really counting down the value in the obj_magicTree_GUI.ds_spell_info list, only reading it once .. your step event never changes it either, or does it just hold the value what to set the cooldown to?

So here, I edited the code between the ///'s .. you can remove your step event .. or actually do a cooldown loop there instead of the step event
GML:
/////////////////////cooldown code:
var spell_cd = obj_magicTree_GUI.ds_spell_info; //a ds_list containing the info of the spells, like name, and cooldown time.

spell_slots = ds_HotBar[# 0,ii]; // a ds_list of the hotbar containing the info of which spell is in which hotbar slot.
ssc = spell_cd[# 2,spell_slots];

if spell_slots > 0{ //if slot isn't empty

    // do some cooldown
    ssc -= 0.5;
       
    // this is where you are supposed to select/use the skill, right?
    if keyboard_check_pressed(ord(ii+1))
    && ssc <=  0{
        // use skill
        ssc = spell_cd[# ???,spell_slots]; // 2 is cooldown progress, which one tells what to set it to on use?
       
    }
   
    // the above code does change ssc .. but that won't affect your grid at all .. so we have to update it
    spell_cd[# 2,spell_slots] = ssc;
   
    draw_text_color(xx,yy,round(ssc),c_white,c_aqua,OutlineColor,OutlineColor,1); //Draws the cooldown
}
/////////////////////
I usually put the current cooldown in my hotbar grid, as only the equipped ones would need cooldown .. what is the 1 position for here: ds_HotBar[# 1, ?

now, if you put your cooldown in the hotbar, then you could use the ds_grid function to lower the value of the whole row/column at once .. and just make sure that when you draw it then you draw max(0,round(ssc))
 
Last edited:
C

cheque

Guest
so I took your code and tweaked it a bit, but ended up working. thank you for your help
Code:

Draw GUI event:
GML:
spell_slots = ds_HotBar[# 0,ii]; // a ds_list  containing the info of which spell is in which hotbar slot.
ssc = spell_cd[# 2,spell_slots];
spell_slot_cooldown = spell_cd[# 3,spell_slots]; //added  spell_cd[# 3 same as spell_cd[# 2 but wont change when cooldown.

if spell_slots > 0{ //if slot isn't empty

    // do some cooldown, stop it at 0
if (ssc <= 0){ssc = spell_slot_cooldown;} //if cooldown is at 0, rest to spell_slot_cooldown
if (ssc < spell_slot_cooldown){ssc -= .05;} //cooldown


    if keyboard_check_pressed(ord(ii+1))
        {
         ssc -= 0.5;   
        }
    
    // the above code does change ssc .. but that won't affect your grid at all .. so we have to update it
    spell_cd[# 2,spell_slots] = ssc;
  
    if (ssc < spell_slot_cooldown){ //only show when its on cooldown
    draw_text_color(xx,yy,round(ssc),c_white,c_aqua,OutlineColor,OutlineColor,1); //Draws the cooldown
    }

}
example:
HOTBAR_EXMP_working.png
 
C

cheque

Guest
once I get the hotbar looking exactly like the first one I had. ill post the full code of the object.
 
C

cheque

Guest
looks like its working as before here is the full code of the object:

Create Event:
GML:
wep_select = 0;
spell_slot_cooldown = 0;
spell_slots = 0;
ssc = 0;
CoolDalpha  = 0;
OutlineColor = 0;

mouse_in_HUB = false;

Spell_List32x32 = spr_test_magic_spellList;
spell_spr_UI = spr_select_hub;
select_h = spr_select_hub;
select_h2 = spr_select_hub2;

spell_cell_size32x32 = 32;
spell_sacle =1;
HotBar_slots = 5;

spell_slot_width = 5;
spell_slot_height = 1;
spell_selected_slot = 0;
pickup_slot = -1;

m_slotx = 0;
m_sloty = 0;

spell_spr_items_colums =sprite_get_width(Spell_List32x32)/spell_cell_size32x32;
spell_spr_items_row =sprite_get_height(Spell_List32x32)/spell_cell_size32x32;

slots_x = 4;
slots_y =22;

ds_HotBar = ds_grid_create(2,HotBar_slots);


ds_HotBar[# 0,0] = Spell.W_strike;
ds_HotBar[# 1,0] = 1;


ds_HotBar[# 0,1] = Spell.A_strike;
ds_HotBar[# 1,1] = 1;

ds_HotBar[# 0,3] = Spell.F_strike;
ds_HotBar[# 1,3] = 1;

ds_HotBar[# 0,4] = 6; //same as Spell.HE_strike
ds_HotBar[# 1,4] = 1;
Step Event:
GML:
mousex = device_mouse_x_to_gui(0);
mousey = device_mouse_y_to_gui(0);

var cell_xbuff = (spell_cell_size32x32)*spell_sacle;
var cell_ybuff = (spell_cell_size32x32)*spell_sacle;

var i_mousex = mousex - (slots_x+14);
var i_mousey = mousey - (slots_y);

var nx = i_mousex div cell_xbuff;
var ny = i_mousey div cell_ybuff;



m_slotx = nx-13;
m_sloty = ny-19;  

var msx = m_slotx;
var msy = m_sloty;



if msx <= -1 or msx >= 5 or msy <= -1 or msy >= 1 // my solution to keeping selected squares only to be in the hotbar
{
m_slotx = -1;
m_sloty = -1;
mouse_in_HUB = false;
}else{mouse_in_HUB = true;}

spell_selected_slot = m_slotx + (m_sloty*spell_slot_width);

var MCBP_mb_L = mouse_check_button_pressed(mb_left);
var MCBP_mb_R = mouse_check_button_pressed(mb_right);

var magTree_grid = ds_HotBar;
var ss_spell = magTree_grid[# 0, spell_selected_slot];



   

if (pickup_slot != -1){
    if (MCBP_mb_L){
    if spell_selected_slot >= 0 or spell_selected_slot = -6{
    if (HotBar_slots >= spell_selected_slot+1){
     
       
        if (!mouse_in_HUB){
           
        #region    drop spell
   
                magTree_grid[# 1,pickup_slot] -=1;
                // if last one destoy item fron HUB bar
                if(magTree_grid[# 1, pickup_slot] == 0){
                 magTree_grid[# 0,pickup_slot] = Spell.none;
                 pickup_slot = -1;
                }}
        #endregion

       
        if (ss_spell == Spell.none){ //add picked up spell to an empty slot
            //selected slot = picked up slot
            magTree_grid[# 0, spell_selected_slot] = magTree_grid [# 0, pickup_slot];
            magTree_grid[# 1, spell_selected_slot] = magTree_grid [# 1, pickup_slot];
            //picked up slot = empty
                magTree_grid[# 0, pickup_slot] = Spell.none;
                magTree_grid[# 1, pickup_slot] = 0;
               
                pickup_slot =-1;
           
        } else {
            var ss_spell_num = magTree_grid[# 1,spell_selected_slot];
            magTree_grid[# 0, spell_selected_slot] = magTree_grid [# 0, pickup_slot];
            magTree_grid[# 1, spell_selected_slot] = magTree_grid [# 1, pickup_slot];
           
                magTree_grid[# 0, pickup_slot] = ss_spell;
                magTree_grid[# 1, pickup_slot] = ss_spell_num;
               
                 pickup_slot =-1;
           
        }
   
}
    }
}
}



else if (ss_spell != Spell.none){
    if (MCBP_mb_R) and spell_selected_slot >= 0{ //mouse_check_button_pressed(mb_right)
        if (HotBar_slots >= spell_selected_slot+1){
    pickup_slot = spell_selected_slot;
    }
        }}
Draw GUI Event:
GML:
var spell_cd = obj_magicTree_GUI.ds_spell_info;

var ii, ix, iy, xx, yy, sx, sy, iitem, spell_grid, numHB;
ii = 0; ix = 0; iy = 0; numHB = 1;
spell_grid = ds_HotBar;

repeat(HotBar_slots){


xx = (slots_x + ((spell_cell_size32x32+2)*ix*spell_sacle))+430;
yy = (slots_y + ((spell_cell_size32x32)*iy*spell_sacle))+615;

iitem = spell_grid[# 0,ii];


sx = (iitem mod spell_spr_items_colums)*spell_cell_size32x32;
sy = (iitem div spell_spr_items_colums)*spell_cell_size32x32;

draw_sprite_part_ext(select_h,0,0,0,spell_cell_size32x32,spell_cell_size32x32,xx,yy,spell_sacle,spell_sacle,c_white,1);

if (iitem <= 0){
draw_text_transformed(xx+10,yy+5,(numHB),scale,scale,image_angle);
}

switch(ii){
    case spell_selected_slot:
        if (iitem > 0) draw_sprite_part_ext(Spell_List32x32, 1, sx,sy,spell_cell_size32x32,spell_cell_size32x32,xx,yy,spell_sacle,spell_sacle,c_white,1);
   
    gpu_set_blendmode(bm_add);
    draw_sprite_part_ext(spell_spr_UI,0,0,0,spell_cell_size32x32,spell_cell_size32x32,xx,yy,spell_sacle,spell_sacle,c_red,.8);
    gpu_set_blendmode(bm_normal);
   
    break;
   
    case pickup_slot:
    if (iitem > 0) draw_sprite_part_ext(Spell_List32x32, 0, sx,sy,spell_cell_size32x32,spell_cell_size32x32,xx,yy,spell_sacle,spell_sacle,c_white,.6); //testing it out
   

    break;
   
    default:
   
        if (iitem > 0) draw_sprite_part_ext(Spell_List32x32, 1, sx,sy,spell_cell_size32x32,spell_cell_size32x32,xx,yy,spell_sacle,spell_sacle,c_white,1);

break;
        }

#region yoyogame forum
spell_slots = ds_HotBar[# 0,ii]; // a ds_list of the hotbar containing the info of which spell is in which hotbar slot.
ssc = spell_cd[# 2,spell_slots];
spell_slot_cooldown = spell_cd[# 3,spell_slots];


if spell_slots > 0{ //if slot isn't empty


        if (ssc <= 1){ssc = spell_slot_cooldown;}
if (ssc < spell_slot_cooldown){ssc -= .05;}


   if keyboard_check_pressed(ord(ii+1))
   
        {
             if ssc = spell_slot_cooldown{ssc -= 0.5;} //start cooldown
         wep_select = ii;
       
    }
   
    spell_cd[# 2,spell_slots] = ssc;
 

if spell_slots > 0{
if ssc != spell_slot_cooldown{
if ssc <= spell_slot_cooldown and ssc >= spell_slot_cooldown-(spell_slot_cooldown*.4){OutlineColor = make_color_rgb(255,0,0);}// red
if ssc <= spell_slot_cooldown-(spell_slot_cooldown*.4) and ssc >= spell_slot_cooldown-(spell_slot_cooldown*.6) {OutlineColor = make_color_rgb(255,100,0);}// orange
if ssc <= spell_slot_cooldown-(spell_slot_cooldown*.6) and ssc >= spell_slot_cooldown-(spell_slot_cooldown*.8) {OutlineColor = make_color_rgb(255,200,0);} // yellow
if ssc <= spell_slot_cooldown-(spell_slot_cooldown*.8) and ssc >= spell_slot_cooldown {OutlineColor = make_color_rgb(8,255,0);}// green
}else{OutlineColor = make_color_rgb(0,255,255);} // blue}
}

 
 
   if ssc != spell_slot_cooldown
{
d3d_set_fog(true, OutlineColor, 0, 0);
draw_sprite_ext(select_h,0,xx+16,yy+16,image_xscale,image_yscale,image_angle,image_blend,.5);
d3d_set_fog(false, OutlineColor, 0, 0);
draw_sprite_ext(select_h,0,xx+16,yy+16,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}
 
    if (ssc < spell_slot_cooldown){
    draw_text_color(xx+11,yy+9,round(ssc),c_white,c_aqua,OutlineColor,OutlineColor,1); //Draws the cooldown
    }

}


#endregion



if wep_select = ii
{
   
d3d_set_fog(true, OutlineColor, 0, 0);
draw_sprite_ext(select_h2,0,xx+16,yy+16,image_xscale+.1,image_yscale+.1,image_angle,image_blend,.5);
d3d_set_fog(false, OutlineColor, 0, 0);
draw_sprite_ext(select_h2,0,xx+16,yy+16,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
}


numHB +=1;
ii +=1;
ix = ii mod spell_slot_width;
iy = ii div spell_slot_width;
}


if (pickup_slot != -1){ // the spell when picked up
iitem = spell_grid[# 0,pickup_slot];
sx = (iitem mod spell_spr_items_colums)*spell_cell_size32x32;
sy = (iitem div spell_spr_items_colums)*spell_cell_size32x32;
if (iitem > 0) draw_sprite_part_ext(Spell_List32x32, 1, sx,sy,spell_cell_size32x32,spell_cell_size32x32,mousex-16,mousey-16,spell_sacle+.1,spell_sacle+.1,c_white,1);
}
Clean up event:
GML:
ds_grid_destroy(ds_HotBar);

example:
HOTBAR_EXMP_final.png
 
Top