Legacy GM deck editor scrolling issues

Making a card game for a client of my mine and I've run into a couple issues. Both issues are related to the scrolling. I want to implement a scrollbar on both sides of the editor (the deck side and the trunk side), but I'm sure my current code for the scrollbar won't work properly.

Then, there is an issue with the scrolling of the card selection and the card info that is displayed on the screen. I'm using variables deck_scroll_pos and trunk_scroll_pos to allow the next row of cards to be displayed (currently only four rows are displayed at a time). My current method causes an issue where the selector disappears after scrolling down (it is likely at the wrong position) due to the fact that the scroll position variables are added on to the variables that track the respective sides selector location ( deck_pos, trunk_pos). Removing the scroll position variables would prevent the player from scrolling down to the next row, so I'm not sure what to do. Additionally, the card info on the deck side, inaccurate card info and undefined value is returned due to the fact that the respective side selector position and scroll position are added together.

I hope I'm explaining this well enough. In any case here is my code as well as a short video so that you can see the problem for yourselves:

Code:
Create Event:
execute code:



// x and y Coordinate-Related
x = 0; // x coordinate will be changed when the player decides to change the editor side from "Trunk" to "Deck".
y = 0; // y coordinate will not be changed
move_obj = false; // Will cause this object's coordinates to change so that only the side the player is switching to will be shown.

//
editor_side = EDITOR_SIDE.ES_TRUNK; // Which "side" the player is currently on
cards_per_row = 8; // Amount of cards in each row for both deck and trunk sides
max_rows_visible = 4; // Amount of rows shown on the screen at one time for both deck and trunk sides.
editor_card_scaling = .75; // All trunk and deck cards shown for selection will use this scaling value to make the cards smaller.
card_width = sprite_get_width( card_img_spr );
card_height = sprite_get_height( card_img_spr );
trunk_pos = 0;
deck_pos = 0;
trunk_scroll_pos = 0;
deck_scroll_pos = 0;

// Scrollbar + Slider variables
bar_spr = scrollbar_spr;
bar_width = sprite_get_width( bar_spr );
bar_height = sprite_get_height( bar_spr );
bar_xx[ 0 ] = ( ( room_width / 2 ) ) - 25;
bar_xx[ 1 ] =  room_width  - 25;
bar_yy = 40;
slider_spr = bar_slider_spr;
slider_width = sprite_get_width( slider_spr );
slider_height = sprite_get_height( slider_spr );
slider_start_yy = bar_yy + ( slider_height / 2 );
slider_xx[ 0 ] = bar_xx[ 0 ];
slider_xx[ 1 ] = bar_xx[ 1 ];
slider_yy[ 0 ] = slider_start_yy;
slider_yy[ 1 ] = slider_start_yy;
slider_spd = 10;
slider_limit = bar_height + 5;
scroll_per[ 0 ] = 0;
scroll_per[ 1 ] = 0;


// Trunk, Deck, and [Card] Info rectangle coordinates
trunk_info_rec_x1 = 10;
trunk_info_rec_y1 = 40;
trunk_info_rec_x2 = ( room_width / 2 ) / 4; // Remember that the room is twice the view width (960)
trunk_info_rec_y2 = trunk_info_rec_y1 + bar_height;

trunk_rec_x1 = trunk_info_rec_x2 + 10;
trunk_rec_y1 = trunk_info_rec_y1;
trunk_rec_x2 = ( room_width / 2 ) - 10; // 960 - x
trunk_rec_y2 = trunk_info_rec_y2;

deck_info_rec_x1 = ( room_width / 2 ) + 10; // 960 + x
deck_info_rec_y1 =  trunk_info_rec_y1;
deck_info_rec_x2 = deck_info_rec_x1 + 220; // 220 = ( 1920/2 )/ 4 ) - 20
deck_info_rec_y2 = trunk_rec_y2;

deck_rec_x1 = deck_info_rec_x2 + 10;
deck_rec_y1 = deck_info_rec_y1;
deck_rec_x2 = room_width  - 10; // 1920 - x
deck_rec_y2 = deck_info_rec_y2;




// Trunk Card List + Coordinates + Rows
trunk_card_list = ds_list_create();

trunk_row_cards[ 0 ] = 0; // Amount of cards currently in each row. Each position in the array is relative to another row.
trunk_rows = 1; // Set to one by default, but will be increased by the quotient of the list size and the value set for cards_per_row.

var rr = 0; // Will be used to initialize the value at a new position to 0.
if ds_exists( global.trunk_quantity, ds_type_map ) && ds_exists( trunk_card_list, ds_type_list )
{
   for ( var ii = 0; ii < global.total_cards; ii++; )
   {
     if ds_map_find_value( global.trunk_quantity, + string( global.card_info[ CARD_PROP.CP_NAME, ii ] )) > 0
     {
       ds_list_add( trunk_card_list, global.card_info[ CARD_PROP.CP_NAME, ii ] );
      
       trunk_row_cards[ rr ]++;
       if trunk_row_cards[ rr ] == cards_per_row
       {  
           rr++; // Must increment this variable first!
           trunk_row_cards[ rr ] = 0; // Initialize value at new position to 0.          
       }
     }    
   }
  
// Increase rows by the quotient of the list size by the value of cards_per_row rounded down to the nearest interger.
   trunk_rows += floor( ds_list_size( trunk_card_list ) / cards_per_row );
}



for ( var zz = 0; zz < cards_per_row; zz++; )
{
   trunk_card_xx[ zz ] = trunk_rec_x1 + 40 + ( card_width * zz );
}

for ( var bb = 0; bb < trunk_rows; bb++; )
{
   trunk_card_yy[ bb ] = trunk_rec_y1 + 60 + ( card_height * bb );
}


// Deck Coordinates + Rows
selected_deck = 0; // Will likely change this variable later. Just using it for now.
deck_row_cards[ 0 ] = 0; // Amount of cards currently in each row. Each position in the array is relative to another row.
deck_rows = 1; // Set to one by default, but will be increased by the quotient of the list size and the value set for cards_per_row.
rr = 0; // Must reset this local variable to 0!
if ds_exists( global.deck_list[ selected_deck ], ds_type_list )
{
   for ( var ii = 0; ii < ds_list_size( global.deck_list[ selected_deck ] ); ii++; )
   {
       deck_row_cards[ rr ]++;
       if deck_row_cards[ rr ] == cards_per_row
       {  
           rr++; // Must increment this variable first!
           deck_row_cards[ rr ] = 0; // Initialize value at new position to 0.          
       }          
   }
  
// Increase rows by the quotient of the list size by the value of cards_per_row rounded down to the nearest interger.
   deck_rows += floor( ds_list_size( global.deck_list[ selected_deck ] ) / cards_per_row );
}


for ( var qq = 0; qq < cards_per_row; qq++; )
{
   deck_card_xx[ qq ] = deck_rec_x1 + 40 + ( card_width * qq );
}

for ( var jj = 0; jj < deck_rows; jj++; )
{
   deck_card_yy[ jj ] = deck_rec_y1 + 60 + ( card_height * jj );
}

Step Event:
execute code:

/// Selection + Scrolling Input

// Set the scroll percentage based on quotient between the slider's y coordinate and the scrollbar's height.
for ( var bb = 0; bb < 2; bb++; ) { scroll_per[ bb ] = ( slider_yy[ bb ] - slider_start_yy ) / slider_limit; }

// Move selector depending upon the key pressed
if move_obj == false // Make sure this object is no longer moving
{
   switch( editor_side )
   {
       case EDITOR_SIDE.ES_TRUNK:
           if ds_exists( trunk_card_list, ds_type_list )
           {
               if (!ds_list_empty( trunk_card_list ))
               {
                   if ( keyboard_check_pressed( global.up_key ) || global.up_held == true  ) && trunk_pos >= cards_per_row
                   {
                   // Move trunk selector up by decreasing the trunk_pos relative to the amount of cards shown per row.
                       trunk_pos -= cards_per_row;
                   // TRUNK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE TOP OF THE VISIBLE SET OF CARDS
                       if trunk_scroll_pos > 0 && ( trunk_pos < trunk_scroll_pos )
                       {
                       //
                           trunk_scroll_pos--;
                       //
                           if slider_yy[ 0 ] > slider_start_yy { slider_yy[ 0 ] -= slider_spd; }
                       // Prevent the slider from moving above the scrollbar  
                           if slider_yy[ 0 ] < slider_start_yy { slider_yy[ 0 ] = slider_start_yy; }
                       }
                      
                   // Prevent trunk_scroll_pos from becoming negative
                      if trunk_scroll_pos < 0 { trunk_scroll_pos = 0; }                    
                   }            
                  
                  
                   if ( keyboard_check_pressed( global.down_key ) || global.down_held == true ) && ( trunk_pos < ds_list_size( trunk_card_list ) - cards_per_row )
                   {
                   // Move trunk selector down by decreasing the trunk_pos relative to the amount of cards shown per row.
                       trunk_pos += cards_per_row;
                   // TRUNK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE BOTTOM OF THE VISIBLE SET OF CARDS
                       if trunk_pos >= ( cards_per_row * max_rows_visible ) + trunk_scroll_pos
                       {
                       //
                           trunk_scroll_pos++;
                       //
                          if slider_yy[ 0 ] < slider_limit { slider_yy[ 0 ] += slider_spd; }
                        
                       // Prevent the slider from moving past the scrollbar
                          if slider_yy[ 0 ] > slider_limit { slider_yy[ 0 ] = slider_limit; }
                      }
                    
                   // Prevent trunk_scroll_pos from exceeding its maximum value (list size - 1)
                        if trunk_scroll_pos >= ds_list_size( trunk_card_list ) { trunk_scroll_pos = ds_list_size( trunk_card_list ) - 1; }    
                   }
                  
                  
                   if ( keyboard_check_pressed( global.left_key ) || global.left_held == true ) && trunk_pos > 0
                   {
                   // Move the trunk selector to the previous card
                       trunk_pos--;
                   // TRUNK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE TOP OF THE VISIBLE SET OF CARDS
                       if trunk_scroll_pos > 0 && ( trunk_pos < trunk_scroll_pos )
                       {
                       //
                           trunk_scroll_pos--;
                       //
                           if slider_yy[ 0 ] > slider_start_yy { slider_yy[ 0 ] -= slider_spd; }
                       // Prevent the slider from moving above the scrollbar  
                           if slider_yy[ 0 ] < slider_start_yy { slider_yy[ 0 ] = slider_start_yy; }
                       }
                      
                   // Prevent trunk_scroll_pos from becoming negative
                      if trunk_scroll_pos < 0 { trunk_scroll_pos = 0; }                                          
                   }            
                  
                  
                   if ( keyboard_check_pressed( global.right_key ) || global.right_held == true ) && trunk_pos < ds_list_size( trunk_card_list ) - 1
                   {
                   // Move the trunk selector to the next card
                      trunk_pos++;
                   // TRUNK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE BOTTOM OF THE VISIBLE SET OF CARDS    
                      if trunk_pos >= ( cards_per_row * max_rows_visible ) + trunk_scroll_pos
                       {
                       //
                           trunk_scroll_pos++;
                       //
                          if slider_yy[ 0 ] < slider_limit{ slider_yy[ 0 ] += slider_spd; }
                        
                       // Prevent the slider from moving past the scrollbar
                          if slider_yy[ 0 ] > slider_limit { slider_yy[ 0 ] = slider_limit; }
                      }
                    
                   // Prevent trunk_scroll_pos from exceeding its maximum value (list size - 1)
                        if trunk_scroll_pos >= ds_list_size( trunk_card_list ) { trunk_scroll_pos = ds_list_size( trunk_card_list ) - 1; }                                      
                   }                                                        
               }
           }
       break;
      
      
       case EDITOR_SIDE.ES_DECK:
           if ds_exists( global.deck_list[ selected_deck ], ds_type_list )
           {
               if (!ds_list_empty( global.deck_list[ selected_deck ] ))
               {
                   if ( keyboard_check_pressed( global.up_key ) || global.up_held == true ) && deck_pos >= cards_per_row
                   {
                   // Move deck selector up by decreasing the deck_pos relative to the amount of cards shown per row.
                       deck_pos -= cards_per_row;
                   // DECK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE TOP OF THE VISIBLE SET OF CARDS
                       if deck_scroll_pos > 0 && ( deck_pos < deck_scroll_pos )
                       {
                       //
                           deck_scroll_pos--;
                       //
                           if slider_yy[ 1 ] > slider_start_yy { slider_yy[ 1 ] -= slider_spd; }
                       // Prevent the slider from moving above the scrollbar  
                          if slider_yy[ 1 ] < slider_start_yy { slider_yy[ 1 ] = slider_start_yy; }
                       }
                      
                   // Prevent deck_scroll_pos from becoming negative
                      if deck_scroll_pos < 0 { deck_scroll_pos = 0; }
                   }            
                  
                  
                   if ( keyboard_check_pressed( global.down_key ) || global.down_held == true ) && ( deck_pos < ds_list_size( global.deck_list[ selected_deck ] ) - cards_per_row )
                   {
                   // Move deck selector down by decreasing the deck_pos relative to the amount of cards shown per row.
                       deck_pos += cards_per_row;
                   // DECK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE BOTTOM OF THE VISIBLE SET OF CARDS
                       if deck_pos >= ( cards_per_row * max_rows_visible ) + deck_scroll_pos
                       {
                       //
                           deck_scroll_pos++;
                       //
                          if slider_yy[ 1 ] < slider_limit { slider_yy[ 1 ] += slider_spd; }
                        
                       // Prevent the slider from moving past the scrollbar
                          if slider_yy[ 1 ] > slider_limit { slider_yy[ 1 ] = slider_limit; }
                      }
                    
                   // Prevent deck_scroll_pos from exceeding its maximum value (list size - 1)
                        if deck_scroll_pos >= ds_list_size( global.deck_list[ selected_deck ] ) { deck_scroll_pos = ds_list_size( global.deck_list[ selected_deck ] ) - 1; }                    
                   }
                  
                  
                   if ( keyboard_check_pressed( global.left_key ) || global.left_held == true ) && deck_pos > 0
                   {
                   // Move the deck selector to the previous card
                       deck_pos--;
                   // DECK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE TOP OF THE VISIBLE SET OF CARDS
                       if deck_scroll_pos > 0 && ( deck_pos < deck_scroll_pos )
                       {
                       //
                           deck_scroll_pos--;
                       //
                           if slider_yy[ 1 ] > slider_start_yy { slider_yy[ 1 ] -= slider_spd; }
                       // Prevent the slider from moving above the scrollbar  
                           if slider_yy[ 1 ] < slider_start_yy { slider_yy[ 1 ] = slider_start_yy; }
                       }
                      
                   // Prevent deck_scroll_pos from becoming negative
                      if deck_scroll_pos < 0 { deck_scroll_pos = 0; }                    
                   }            
                  
                  
                   if ( keyboard_check_pressed( global.right_key ) || global.right_held == true ) && deck_pos < ds_list_size( global.deck_list[ selected_deck ] ) - 1
                   {

                   // Move the deck selector to the next card
                      deck_pos++;
                   // DECK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE BOTTOM OF THE VISIBLE SET OF CARDS    
                      if deck_pos >= ( cards_per_row * max_rows_visible ) + deck_scroll_pos
                       {
                       //
                           deck_scroll_pos++;
                       //
                          if slider_yy[ 1 ] < slider_limit{ slider_yy[ 1 ] += slider_spd; }
                        
                       // Prevent the slider from moving past the scrollbar
                          if slider_yy[ 1 ] > slider_limit { slider_yy[ 1 ] = slider_limit; }
                      }
                    
                   // Prevent deck_scroll_pos from exceeding its maximum value (list size - 1)
                        if deck_scroll_pos >= ds_list_size( global.deck_list[ selected_deck ] ) { deck_scroll_pos = ds_list_size( global.deck_list[ selected_deck ] ) - 1; }                    
                   }                
               }
           }      
       break;
   }  
}

execute code:

/// Editor Side View Control

if move_obj == true
{
   switch ( editor_side )
   {
       case EDITOR_SIDE.ES_TRUNK:
           if x > 0
           {
              x = lerp( x, 0, 0.8 );
           }
           else
           {
               x = 0;
               move_obj = false;
           }
       break;
      
      
       case EDITOR_SIDE.ES_DECK:
           if x < room_width
           {
              x = lerp( x, room_width, 0.8 );
              
           }
           else
           {
               x = room_width;
               move_obj = false;
           }      
       break;
   }
}
else
{

   if keyboard_check_pressed( global.ES_left_key ) && editor_side == EDITOR_SIDE.ES_DECK { editor_side = EDITOR_SIDE.ES_TRUNK; move_obj = true; }
  
   if keyboard_check_pressed( global.ES_right_key ) && editor_side == EDITOR_SIDE.ES_TRUNK  { editor_side = EDITOR_SIDE.ES_DECK; move_obj = true; }  
}

Other Event: Game End:
execute code:

/// Destroy trunk card list
if ds_exists( trunk_card_list, ds_type_list )
{
   ds_list_destroy( trunk_card_list );
}

Draw Event:
execute code:

/// Draw Editor WIP

// -- Draw Rectangles --
draw_roundrect_colour( trunk_info_rec_x1, trunk_info_rec_y1, trunk_info_rec_x2, trunk_info_rec_y2, c_white, c_white, true  );
draw_roundrect_colour( trunk_info_rec_x1, trunk_info_rec_y1, trunk_info_rec_x2, trunk_info_rec_y2, c_blue, c_blue, false  );

draw_roundrect_colour( trunk_rec_x1, trunk_rec_y1, trunk_rec_x2, trunk_rec_y2, c_white, c_white, true  );
draw_roundrect_colour( trunk_rec_x1, trunk_rec_y1, trunk_rec_x2, trunk_rec_y2, c_blue, c_blue, false  );

draw_roundrect_colour( deck_rec_x1, deck_rec_y1, deck_rec_x2, deck_rec_y2, c_white, c_white, true );
draw_roundrect_colour( deck_rec_x1, deck_rec_y1, deck_rec_x2, deck_rec_y2, c_blue, c_blue, false  );

draw_roundrect_colour( deck_info_rec_x1, deck_info_rec_y1, deck_info_rec_x2, deck_info_rec_y2, c_white, c_white, true  );
draw_roundrect_colour( deck_info_rec_x1, deck_info_rec_y1, deck_info_rec_x2, deck_info_rec_y2, c_blue, c_blue, false  );



// -- Draw the Scrollbars and sliders --
for ( var tt = 0; tt < 2; tt++; )
{
   // Draw the Scrollbar
   draw_sprite_ext( bar_spr, 0, bar_xx[ tt ], bar_yy, 1, 1, 0, c_white, 1 );
  
   // Draw the Scrollbar Slider
   draw_sprite_ext( slider_spr, 0, slider_xx[ tt ], slider_yy[ tt ], 1, 1, 0, c_white, 1 );
}


// -- Set Info color for text drawing --
var card_name_color = c_yellow;
var card_type_color = c_green;
var card_cost_color = c_white;
var card_atk_color = c_white;
var card_arm_color = c_white;
var card_hp_color = c_white;
var card_desc_color = c_white;


// -- Draw Trunk Contents --
var ii = 0; // Variable used as the list position argument to retrieve the card name value using ds_list_find_value()
if ds_exists( trunk_card_list, ds_type_list )
{
   if (!ds_list_empty( trunk_card_list ))
   {
       for ( var nn = 0; nn < min( trunk_rows, max_rows_visible ); nn++; )
       {
           for ( var zz = 0; zz < trunk_row_cards[ nn ]; zz++; )
           {
           // Draw "Glow" Selector Sprite (Will likely change later)
               if trunk_pos == ii + trunk_scroll_pos
               {                
                   draw_set_blend_mode( bm_add );
                   draw_sprite_ext( glow_selector_spr, 0, trunk_card_xx[ zz  ], trunk_card_yy[ nn ], editor_card_scaling + 0.05, editor_card_scaling + 0.05, 0, c_yellow, 1 );
                   draw_set_blend_mode( bm_normal );
               }
                        
           // Draw the subimage of the card in the player's trunk
               draw_sprite_ext( card_img_spr, find_card_info( ds_list_find_value( trunk_card_list, ii + trunk_scroll_pos ), CARD_PROP.CP_SUBIMG ), trunk_card_xx[ zz  ],
                               trunk_card_yy[ nn ], editor_card_scaling, editor_card_scaling, 0, c_white, 1 );
                              
          // Increment ii after sprite subimage is drawn, so that the next card's image is drawn during the next iteration                    
               ii++;
           }                            
       }
   // Draw Trunk Card info
       var trunk_info_card_xx = ( trunk_info_rec_x1 + trunk_info_rec_x2 ) / 2
       var trunk_info_card_yy = trunk_info_rec_y1 + ( card_height / 2 ) + 15;
       var trunk_info_name_xx = trunk_info_card_xx;
       var trunk_info_name_yy = trunk_info_rec_y1 + card_height + 30;  
       var trunk_card_type = find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_TYPE );
       var trunk_CT_str = get_card_type_str( trunk_card_type );
       var trunk_CT_xx =  trunk_info_rec_x1 + 10;
       var trunk_CT_yy = trunk_info_name_yy + 20;
       var trunk_card_cost = find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_COST );
       var trunk_CC_label_xx = trunk_CT_xx; // x coordinate of the text "Cost:" on the trunk side
       var trunk_CC_label_yy = trunk_CT_yy + 20; // y coordinate of the text "Cost:" on the trunk side
       var trunk_CC_xx = trunk_info_rec_x2 - 20; // Card Cost x coordinate
       var trunk_CC_yy = trunk_CT_yy + 20; // Card Cost y coordinate
        
       draw_sprite_ext( card_img_spr, find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_SUBIMG ), trunk_info_card_xx,
                        trunk_info_card_yy, 1, 1, 0, c_white, 1 );
       draw_set_halign( fa_center );              
       draw_text_colour( trunk_info_name_xx, trunk_info_name_yy, ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), card_name_color, card_name_color,
                         card_name_color, card_name_color, 1 );  
       draw_set_halign( fa_left ); // Reset horizontal alignment
       draw_text_colour( trunk_CT_xx, trunk_CT_yy, "[ " + string( trunk_CT_str ) + " Card ]", card_type_color, card_type_color, card_type_color, card_type_color, 1  );
      
       draw_text_colour( trunk_CC_label_xx, trunk_CC_label_yy, "Cost:", card_cost_color, card_cost_color, card_cost_color, card_cost_color, 1  );        
       draw_set_halign( fa_right );
       draw_text_colour( trunk_CC_xx, trunk_CC_yy,  + string( trunk_card_cost ), card_cost_color, card_cost_color, card_cost_color, card_cost_color, 1  );      
       draw_set_halign( fa_left ); // Reset horizontal alignment  
      
       switch( trunk_card_type )
       {
           case CARD_TYPE.CT_SUMMON:
               // Draw Attack, Armor, HP, Description/Effect
               var trunk_CATK_xx = trunk_CC_xx;
               var trunk_CATK_yy = trunk_CC_yy + 20;
               var trunk_CATK_label_xx = trunk_CC_label_xx;
               var trunk_CATK_label_yy = trunk_CATK_yy;
               var trunk_card_atk = find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_ATK );
              
               var trunk_CARM_xx = trunk_CATK_xx;
               var trunk_CARM_yy = trunk_CATK_yy + 20;
               var trunk_CARM_label_xx = trunk_CATK_label_xx;
               var trunk_CARM_label_yy = trunk_CARM_yy;
               var trunk_card_arm = find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_ARMOR );  
              
               var trunk_CHP_xx = trunk_CARM_xx;
               var trunk_CHP_yy = trunk_CARM_yy + 20;
               var trunk_CHP_label_xx = trunk_CARM_label_xx;
               var trunk_CHP_label_yy = trunk_CHP_yy;
               var trunk_card_hp = find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_HP );
              
               var trunk_CD_xx = trunk_info_rec_x1 + 10;
               var trunk_CD_yy = trunk_CHP_yy + 40;
               var trunk_card_desc = find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_DESC );                          
              
               draw_text_colour( trunk_CATK_label_xx, trunk_CATK_label_yy, "Attack:", card_atk_color, card_atk_color, card_atk_color, card_atk_color, 1  );
               draw_text_colour( trunk_CARM_label_xx, trunk_CARM_label_yy, "Armor:", card_arm_color, card_arm_color, card_arm_color, card_arm_color, 1  );
               draw_text_colour( trunk_CHP_label_xx, trunk_CHP_label_yy, "HP:", card_hp_color, card_hp_color, card_hp_color, card_hp_color, 1  );                                                      
               draw_set_halign( fa_right );
               draw_text_colour( trunk_CATK_xx, trunk_CATK_yy,  + string( trunk_card_atk ), card_atk_color, card_atk_color, card_atk_color, card_atk_color, 1  );
               draw_text_colour( trunk_CARM_xx, trunk_CARM_yy,  + string( trunk_card_arm ), card_arm_color, card_arm_color, card_arm_color, card_arm_color, 1  );
               draw_text_colour( trunk_CHP_xx, trunk_CHP_yy,  + string( trunk_card_hp ), card_hp_color, card_hp_color, card_hp_color, card_hp_color, 1  );                                      
               draw_set_halign( fa_left ); // Reset horizontal alignment
               var w = trunk_info_rec_x2 -  ( trunk_info_rec_x1 + 10 );
               var sep = 20;
               draw_text_ext_colour( trunk_CD_xx, trunk_CD_yy,  + string( trunk_card_desc ), sep, w, card_desc_color, card_desc_color, card_desc_color, card_desc_color, 1  );            
            break;
          
          
           case CARD_TYPE.CT_TOOL:
           // Draw Description/Effect
               var trunk_CD_xx = trunk_info_rec_x1 + 10;
               var trunk_CD_yy = trunk_CC_yy + 40;
               var trunk_card_desc = find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_DESC );
               var w = trunk_info_rec_x2 -  ( trunk_info_rec_x1 + 10 );
               var sep = 20;
               draw_text_ext_colour( trunk_CD_xx, trunk_CD_yy, + string( trunk_card_desc ), sep, w, card_desc_color, card_desc_color, card_desc_color, card_desc_color, 1  );                            
           break;
          
          
          case CARD_TYPE.CT_EVENT:
           // Draw Description/Effect
               var trunk_CD_xx = trunk_info_rec_x1 + 10;
               var trunk_CD_yy = trunk_CC_yy + 40;
               var trunk_card_desc = find_card_info( ds_list_find_value( trunk_card_list, trunk_pos + trunk_scroll_pos ), CARD_PROP.CP_DESC );
               var w = trunk_info_rec_x2 - ( trunk_info_rec_x1 + 10 );
               var sep = 20;
               draw_text_ext_colour( trunk_CD_xx, trunk_CD_yy, + string( trunk_card_desc ), sep, w, card_desc_color, card_desc_color, card_desc_color, card_desc_color, 1  );              
          break;
       }      
                          
   }
}




// -- Draw Deck Contents --
var qq = 0; // Variable used as the list position argument to retrieve the card name value using ds_list_find_value()
if ds_exists( global.deck_list[ selected_deck ], ds_type_list )
{
   if (!ds_list_empty( global.deck_list[ selected_deck ] ))
   {
       for ( var bb = 0; bb < min( deck_rows, max_rows_visible ); bb++; )
       {
           for ( var uu = 0; uu < deck_row_cards[ bb ]; uu++; )
           {
           // Draw "Glow" Selector Sprite (Will likely change later)
               if deck_pos == qq + deck_scroll_pos
               {                
                   draw_set_blend_mode( bm_add );
                   draw_sprite_ext( glow_selector_spr, 0, deck_card_xx[ uu  ], deck_card_yy[ bb ], editor_card_scaling + 0.05, editor_card_scaling + 0.05, 0, c_yellow, 1 );
                   draw_set_blend_mode( bm_normal );
               }
                          
           // Draw the subimage of the card in the player's deck
               draw_sprite_ext( card_img_spr, find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], qq + deck_scroll_pos ), CARD_PROP.CP_SUBIMG ), deck_card_xx[ uu  ],
                               deck_card_yy[ bb ], editor_card_scaling, editor_card_scaling, 0, c_white, 1 );
          // Increment qq after sprite subimage is drawn, so that the next card's image is drawn during the next iteration                    
               qq++;
           }                            
       }
   // Draw Deck Card info
       var deck_info_card_xx = ( deck_info_rec_x1 + deck_info_rec_x2 ) / 2
       var deck_info_card_yy = deck_info_rec_y1 + ( card_height / 2 ) + 15;
       var deck_info_name_xx = deck_info_card_xx;
       var deck_info_name_yy = deck_info_rec_y1 + card_height + 30;  
       var deck_card_type = find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_TYPE );
       var deck_CT_str = get_card_type_str( deck_card_type );
       var deck_CT_xx =  deck_info_rec_x1 + 10;
       var deck_CT_yy = deck_info_name_yy + 20;
       var deck_card_cost = find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_COST );
       var deck_CC_label_xx = deck_CT_xx; // x coordinate of the text "Cost:" on the deck side
       var deck_CC_label_yy = deck_CT_yy + 20; // y coordinate of the text "Cost:" on the deck side
       var deck_CC_xx = deck_info_rec_x2 - 20; // Card Cost x coordinate
       var deck_CC_yy = deck_CT_yy + 20; // Card Cost y coordinate

              
       draw_sprite_ext( card_img_spr, find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_SUBIMG ), deck_info_card_xx,
                       deck_info_card_yy, 1, 1, 0, c_white, 1 );
       draw_set_halign( fa_center );              
       draw_text_colour( deck_info_name_xx, deck_info_name_yy, ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), card_name_color, card_name_color,
                         card_name_color, card_name_color, 1 );  
       draw_set_halign( fa_left ); // Reset horizontal alignment
       draw_text_colour( deck_CT_xx, deck_CT_yy, "[ " + string( deck_CT_str ) + " Card ]", card_type_color, card_type_color, card_type_color, card_type_color, 1  );
      
       draw_text_colour( deck_CC_label_xx, deck_CC_label_yy, "Cost:", card_cost_color, card_cost_color, card_cost_color, card_cost_color, 1  );        
       draw_set_halign( fa_right );
       draw_text_colour( deck_CC_xx, deck_CC_yy,  + string( deck_card_cost ), card_cost_color, card_cost_color, card_cost_color, card_cost_color, 1  );      
       draw_set_halign( fa_left ); // Reset horizontal alignment
              
       switch( deck_card_type )
       {
           case CARD_TYPE.CT_SUMMON:
               // Draw Attack, Armor, HP, Description/Effect
               var deck_CATK_xx = deck_CC_xx;
               var deck_CATK_yy = deck_CC_yy + 20;
               var deck_CATK_label_xx = deck_CC_label_xx;
               var deck_CATK_label_yy = deck_CATK_yy;
               var deck_card_atk = find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_ATK );
              
               var deck_CARM_xx = deck_CATK_xx;
               var deck_CARM_yy = deck_CATK_yy + 20;
               var deck_CARM_label_xx = deck_CATK_label_xx;
               var deck_CARM_label_yy = deck_CARM_yy;
               var deck_card_arm = find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_ARMOR );  
              
               var deck_CHP_xx = deck_CARM_xx;
               var deck_CHP_yy = deck_CARM_yy + 20;
               var deck_CHP_label_xx = deck_CARM_label_xx;
               var deck_CHP_label_yy = deck_CHP_yy;
               var deck_card_hp = find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_HP );
              
               var deck_CD_xx = deck_info_rec_x1 + 10;
               var deck_CD_yy = deck_CHP_yy + 40;
               var deck_card_desc = find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_DESC );                          
              
               draw_text_colour( deck_CATK_label_xx, deck_CATK_label_yy, "Attack:", card_atk_color, card_atk_color, card_atk_color, card_atk_color, 1  );
               draw_text_colour( deck_CARM_label_xx, deck_CARM_label_yy, "Armor:", card_arm_color, card_arm_color, card_arm_color, card_arm_color, 1  );
               draw_text_colour( deck_CHP_label_xx, deck_CHP_label_yy, "HP:", card_hp_color, card_hp_color, card_hp_color, card_hp_color, 1  );                                                      
               draw_set_halign( fa_right );
               draw_text_colour( deck_CATK_xx, deck_CATK_yy,  + string( deck_card_atk ), card_atk_color, card_atk_color, card_atk_color, card_atk_color, 1  );
               draw_text_colour( deck_CARM_xx, deck_CARM_yy,  + string( deck_card_arm ), card_arm_color, card_arm_color, card_arm_color, card_arm_color, 1  );
               draw_text_colour( deck_CHP_xx, deck_CHP_yy,  + string( deck_card_hp ), card_hp_color, card_hp_color, card_hp_color, card_hp_color, 1  );                                      
               draw_set_halign( fa_left ); // Reset horizontal alignment
               var w = deck_info_rec_x2 -  ( deck_info_rec_x1 + 10 );
               var sep = 20;
               draw_text_ext_colour( deck_CD_xx, deck_CD_yy,  + string( deck_card_desc ), sep, w, card_desc_color, card_desc_color, card_desc_color, card_desc_color, 1  );            
            break;
          
          
           case CARD_TYPE.CT_TOOL:
           // Draw Description/Effect
               var deck_CD_xx = deck_info_rec_x1 + 10;
               var deck_CD_yy = deck_CC_yy + 40;
               var deck_card_desc = find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_DESC );
               var w = deck_info_rec_x2 -  ( deck_info_rec_x1 + 10 );
               var sep = 20;
               draw_text_ext_colour( deck_CD_xx, deck_CD_yy, + string( deck_card_desc ), sep, w, card_desc_color, card_desc_color, card_desc_color, card_desc_color, 1  );                            
           break;
          
          
          case CARD_TYPE.CT_EVENT:
           // Draw Description/Effect
               var deck_CD_xx = deck_info_rec_x1 + 10;
               var deck_CD_yy = deck_CC_yy + 40;
               var deck_card_desc = find_card_info( ds_list_find_value( global.deck_list[ selected_deck ], deck_pos + deck_scroll_pos ), CARD_PROP.CP_DESC );
               var w = deck_info_rec_x2 - ( deck_info_rec_x1 + 10 );
               var sep = 20;
               draw_text_ext_colour( deck_CD_xx, deck_CD_yy, + string( deck_card_desc ), sep, w, card_desc_color, card_desc_color, card_desc_color, card_desc_color, 1  );              
          break;
       }
   }
}

EDIT: Also, forgot to ask, I want to add a glowing effect around the cards to indicate which card the selector is on. Right now I'm using a sprite created using GMS glow effect and using draw_set_blend_mode() on the sprite.
 

TailBit

Member
So scrolling with the cards at preset positions, no smooth scrolling.

Usually you would only need to know the selected card index, and just move it .. if it is moved out of view, then adjust it to a valid index and change the row_to_start_drawing_from + move the scrollbar.

I'm still a bit unsure what trunk_scroll_pos is .. I thought it would be what row to start drawing from, but from the code and video, it changes what card to start drawing from? which is a bit confusing.

(It's too late for me atm to make a example)

EDIT: does your global.card_info[ CARD_PROP.CP_NAME, index] contain 3 entries of every card?

I kinda expected it to add cards to the trunk_card_list by repeating it for each quantity in global.trunk_quantity:
Code:
repeat( ds_map_find_value( global.trunk_quantity, + string( global.card_info[ CARD_PROP.CP_NAME, ii ] )) )
      ds_list_add( trunk_card_list, global.card_info[ CARD_PROP.CP_NAME, ii ] );
EDIT2: when moving up or down outside the view, then you might want to move trunk_scroll_pos the same amount..

as you could see that when you moved from 29 to 37 (1:55 in the video), then trunk_scroll_pos increased by 1 (so it was at 4).. (max_rows*max_columns + trunk_scroll_pos =) 8*4+4 = 36 so it was not enough to be displayed.
 
Last edited:
Sorry for the late reply

I'm still a bit unsure what trunk_scroll_pos is .. I thought it would be what row to start drawing from, but from the code and video, it changes what card to start drawing from? which is a bit confusing.
Basically. Usually when I make scrolling menus they're vertical and text based like what I did here (see video, skip to 0:51), so I usually make a scroll position variable that is used to show the next card in the list:
The variables trunk_scroll_pos and deck_scroll_pos work the same way in this project. However, now that I think about it though that probably isn't a good way to do this because I'm dealing with multiple rows and columns.

does your global.card_info[ CARD_PROP.CP_NAME, index] contain 3 entries of every card?

I kinda expected it to add cards to the trunk_card_list by repeating it for each quantity in global.trunk_quantity
I'm simply checking whether the player has at least one copy of a card in their trunk and if so the game will add that card to the trunk_card_list. The global.card_info array contains one entry per card. Here are the scripts for the creation of the array:
Code:
/// init_card_info()
/*

    Card Number |   Subimage Number   |  Card Type    |   Name   |  Cost   |   Health   |   Armor   |   Attack  |   Description |   Effect

*/
var array_width = 9; // Relative to how much info should be in each row
global.total_cards = 15; // Number relative to the amount of cards in the game
var val = 0; // The values to be added to the array

// -- Set default values --
for ( var nn = 0; nn < global.total_cards; nn++; )
{
    for ( var ii = 0; ii < array_width; ii++; )
    {
    // Set the value to be stored in the array to either a card number or the value of noone (-4) to refer to a null or empty value.
        if ii == 0 { val = ii; } else { val = noone; }

    // Store default values in the array 
        global.card_info[ ii, nn ] = val;
    }
}



// -- Add information for every card  --
// Store info about each card within the global.card_info 2D array.
// Summons
add_card_info( ARRAY_COORD.GIANT_TURTLE, 1, 1, CARD_TYPE.CT_SUMMON, "Giant Turtle", 5, 10, 15, 1, "Giant Turtle test description.", noone );

add_card_info( ARRAY_COORD.FRAIL_SWORDSMAN, 2, 2, CARD_TYPE.CT_SUMMON, "Frail Swordsman", 3, 5, 4, 4, "Frail Swordsman test description.", noone );
add_card_info( ARRAY_COORD.BLUE_OGRE, 3, 3, CARD_TYPE.CT_SUMMON, "Blue Ogre", 10, 15, 3, 10, "Blue Ogre test description.", noone );

add_card_info( ARRAY_COORD.FLAME_GOBLIN, 4, 4, CARD_TYPE.CT_SUMMON, "Flame Goblin", 8, 10, 4, 10, "Flame Goblin test description.", noone );

add_card_info( ARRAY_COORD.WILD_DRAGON, 5, 5, CARD_TYPE.CT_SUMMON, "Wild Dragon", 12, 15, 2, 10, "Wild Dragon test description.", noone );
// Tools
add_card_info( ARRAY_COORD.WOODEN_SWORD, 6, 6, CARD_TYPE.CT_TOOL, "Wooden Sword", 2, noone, noone, noone, "Increase one unit's attack by three points.",
             set_card_effect_array( "Wooden Sword" ) );
       
add_card_info( ARRAY_COORD.RUSTED_ARMOR, 7, 7, CARD_TYPE.CT_TOOL, "Rusted Armor", 5, noone, noone, noone, "Increase one unit's armor by seven points.",
             set_card_effect_array( "Rusted Armor" ) );
       
add_card_info( ARRAY_COORD.HOLY_WATER, 8, 8, CARD_TYPE.CT_TOOL, "Holy Water", 10, noone, noone, noone, "Increase one unit's health by five.",
               set_card_effect_array( "Holy Water" ) );
         
add_card_info( ARRAY_COORD.DEGRADATION_CANNON, 9, 9, CARD_TYPE.CT_TOOL, "Degradation Cannon", 8, noone, noone, noone, "Decrease one unit's armor by six.",
               set_card_effect_array( "Degradation Cannon" ) );
         
add_card_info( ARRAY_COORD.GOLDEN_SABER, 10, 10, CARD_TYPE.CT_TOOL, "Golden Saber", 14, noone, noone, noone, "Increase one unit's attack by 20 points.",
               set_card_effect_array( "Golden Saber" ) );

// Events
add_card_info( ARRAY_COORD.SACRIFICIAL_RESTORATION, 11, 11, CARD_TYPE.CT_EVENT, "Sacrificial Restoration", 0, noone, noone, noone,
               "Sacrifice one summoned unit to restore five crystals.", set_card_effect_array( "Sacrificial Restoration" ) );
         
add_card_info( ARRAY_COORD.BARRIER, 12, 12, CARD_TYPE.CT_EVENT, "Barrier", 3, noone, noone, noone, "Negates any damage inflicted to the user for one turn.",
               set_card_effect_array( "Barrier" ) );
         
add_card_info( ARRAY_COORD.QUICK_DRAW, 13, 13, CARD_TYPE.CT_EVENT, "Quick Draw", 1, noone, noone, noone,
               "Draw two cards.", set_card_effect_array( "Quick Draw" ) );

         
add_card_info( ARRAY_COORD.EARTHQUAKE, 14, 14, CARD_TYPE.CT_EVENT, "Earthquake", 10, noone, noone, noone,
               "Destroy all summoned units on the field.", set_card_effect_array( "Earthquake" ) );
         
add_card_info( ARRAY_COORD.SLEEP_SPELL, 15, 15, CARD_TYPE.CT_EVENT, "Sleep Spell",  5, noone, noone, noone,
 "Select one summoned unit on your opponent's side of the field. That unit cannot attack for one turn.", set_card_effect_array( "Sleep Spell" ) );
Code:
/// add_card_info( Array Coordinate, Card Number, Card Subimg, Card Type, Name, Cost, Health, Armor, Attack, Description, Effect )

var array_coord = argument0; // Second coordinate that will make up the position for specific info on each card
var card_num = argument1; // Number associated with the card. This could be used as a unique identifer (id) or for sorting purposes.
var card_subimg = argument2; // The subimage number of the card_img_spr sprite that relates to a specific card. 0 will always be the "backside" image of the card.
var card_type = argument3; // Indicates whether the card is a "Summon", "Tool" or "Event" card.
var name = argument4; // Name of the card
var cost = argument5; // How much it costs to use the card and the penalty for losing a summoned unit.
var hp = argument6; // Amount of health a Summon has. When it reaches 0, the card will be destroyed and the amount of crystals lost depends on the penalty (cost).
var armor = argument7; // Factored into the amount of damage taken from an opponent's attack. Opponent Attack - Armor = Damage
var attack = argument8; // The base damage a monster will deal while attacking
var desc = argument9; // Card description
var card_effect = argument10; // Effect of the card. Value will be noone (-4) if a "Summon" has no effect or be set to an array containing a script and neccessary arguments

global.card_info[ CARD_PROP.CP_NUM, array_coord ] = card_num;
global.card_info[ CARD_PROP.CP_SUBIMG, array_coord ] = card_subimg;
global.card_info[ CARD_PROP.CP_TYPE, array_coord ] = card_type;
global.card_info[ CARD_PROP.CP_NAME, array_coord ] = name;
global.card_info[ CARD_PROP.CP_COST, array_coord ] = cost;
global.card_info[ CARD_PROP.CP_HP, array_coord ] = hp;
global.card_info[ CARD_PROP.CP_ARMOR, array_coord ] = armor;
global.card_info[ CARD_PROP.CP_ATK, array_coord ] = attack;
global.card_info[ CARD_PROP.CP_DESC, array_coord ] = desc;
global.card_info[ CARD_PROP.CP_EFFECT, array_coord ] = card_effect;
when moving up or down outside the view, then you might want to move trunk_scroll_pos the same amount..

as you could see that when you moved from 29 to 37 (1:55 in the video), then trunk_scroll_pos increased by 1 (so it was at 4).. (max_rows*max_columns + trunk_scroll_pos =) 8*4+4 = 36 so it was not enough to be displayed.
Oh, I see. I'll try that.

EDIT: Your suggestion solved the problem of the selector disappearing, but now the sum of the deck_scroll_pos and deck_pos will result in a value that is high (above the max 39), resulting in the card info displayed being inaccurate and an undefined value displayed for the card name.

Scrolling when pressing left and right doesn't function as I attended it to. I noticed that advancing past 31 when pressing the right key "shifts" all cards over to the next card. The same thing happens when moving to the left when deck_pos > 0 (shift to the previous card).

I want the selector to jump to the last card on previous row when scrolling left and the first card on the next row when scrolling right.
 
Last edited:

TailBit

Member
From what I have understood:
- deck_pos is the selected card
- deck_scroll_pos is the card you start drawing from

Combined they shouldn't make any value that you could have much use of, so you should only use "deck_pos" to get the card info, or "deck_scroll_pos + slot number (qq) " when drawing the cards

It do sound to me like you want to move only using rows ..

Now .. to avoid the shifting .. when moving left, check if you were on the first card, if so then move _scroll_pos a whole row up.
Code:
if ( keyboard_check_pressed( global.left_key ) || global.left_held == true ) && deck_pos > 0
{

    // DECK SCROLL CODE - THIS CODE WILL BE CALLED WHEN THE PLAYER MOVES TO THE TOP OF THE VISIBLE SET OF CARDS
    // if selection is on the first column
    if( (deck_pos mod cards_per_row) == 0 && deck_scroll_pos>0){
    {
        deck_scroll_pos = max(0,deck_scroll_pos - cards_per_row);
      
        if slider_yy[ 1 ] > slider_start_yy { slider_yy[ 1 ] -= slider_spd; }
        // Prevent the slider from moving above the scrollbar
        if slider_yy[ 1 ] < slider_start_yy { slider_yy[ 1 ] = slider_start_yy; }
    }

    // Move the deck selector to the previous card
    deck_pos--;
}
same with the other way:
Code:
if( (deck_pos mod cards_per_row) == cards_per_row-1){
    deck_scroll_pos += min(ds_list_size( global.deck_list[ selected_deck ] )-1,deck_scroll_pos+cards_per_row);
}
note that you should change deck_pos after moving the scroll pos .. or you could simply do it the other way around

if you move deck_pos then you can just calculate what row it is on and multiply it with the number of cards each row:
Code:
if ( keyboard_check_pressed( global.left_key ) || global.left_held == true ) && deck_pos > 0
{
    // Move the deck selector to the previous card
    deck_pos--;
  
    deck_scroll_pos = (deck_pos div cards_per_row) * cards_per_row;

    if slider_yy[ 1 ] > slider_start_yy { slider_yy[ 1 ] -= slider_spd; }
    // Prevent the slider from moving above the scrollbar
    if slider_yy[ 1 ] < slider_start_yy { slider_yy[ 1 ] = slider_start_yy; }
}

if ( keyboard_check_pressed( global.right_key ) || global.right_held == true ) && deck_pos < ds_list_size( global.deck_list[ selected_deck ] ) - 1
{
    // Move the deck selector to the next card
    deck_pos++;
    deck_scroll_pos = max(deck_scroll_pos, ((deck_pos div cards_per_row)-(max_rows_visible-1))*cards_per_row);

    if slider_yy[ 1 ] < slider_limit{ slider_yy[ 1 ] += slider_spd; }
    // Prevent the slider from moving past the scrollbar
    if slider_yy[ 1 ] > slider_limit { slider_yy[ 1 ] = slider_limit; }
}
Wait .. you do not move the slider based on percentage, but rather when it is triggered to do so? does it even have some drag n drop function?

Usually my code for re-adjusting the slider would just be about setting the percentage, and the rest of the code would handle the rest:
Code:
slider_pos = deck_scroll_row / max(1,deck_max_rows - max_rows_visible);
Hmmm xD .. anyway .. you got a bit to work with here.

EDIT: realized a oversight and changed -max_rows_visible-1 to -(max_rows_visible-1)
 
Last edited:
Sorry for the late reply. The code you suggested to remove the shifting and fix the inaccurate/undefined value for the card info worked:

I only need to get the scrollbar working properly and I need to know how to add the glow around the card sprites (preferably without the use of shaders).


Wait .. you do not move the slider based on percentage, but rather when it is triggered to do so? does it even have some drag n drop function?

Usually my code for re-adjusting the slider would just be about setting the percentage, and the rest of the code would handle the rest:
I tried the scroll you mentioned, but it didn't work. Guessing I did something wrong.

I'm not using any DnD functions and the way I have it, the slider moves when the y coordinate is changed whenever the player moves back up to the top or continues to move down past the first four rows.


Thanks for your help so far.
 

TailBit

Member
I did notice that you already had a scroll_per array, but you don't really use it for anything

Code:
// Scrollbar + Slider variables
bar_spr = scrollbar_spr;
bar_width = sprite_get_width( bar_spr );
bar_height = sprite_get_height( bar_spr );
bar_xx[ 0 ] = ( ( room_width / 2 ) ) - 25;
bar_xx[ 1 ] =  room_width  - 25;
bar_yy = 40;
slider_spr = bar_slider_spr;
slider_width = sprite_get_width( slider_spr );
slider_height = sprite_get_height( slider_spr );
slider_start_yy = bar_yy + ( slider_height / 2 );
slider_xx[ 0 ] = bar_xx[ 0 ];
slider_xx[ 1 ] = bar_xx[ 1 ];
slider_yy[ 0 ] = slider_start_yy;
slider_yy[ 1 ] = slider_start_yy;
slider_spd = 10;
slider_limit = bar_height + 5;
scroll_per[ 0 ] = 0;
scroll_per[ 1 ] = 0;


// -- Draw the Scrollbars and sliders --
for ( var tt = 0; tt < 2; tt++; )
{
   // Draw the Scrollbar
   draw_sprite_ext( bar_spr, 0, bar_xx[ tt ], bar_yy, 1, 1, 0, c_white, 1 );
 
   // Draw the Scrollbar Slider
   draw_sprite_ext( slider_spr, 0, slider_xx[ tt ], slider_yy[ tt ], 1, 1, 0, c_white, 1 );
}
And no, I was talking if the player should be able to use the mouse to drag n drop the scrollbar

So what I want to do is to make the code for positioning the bar just above the draw code for the bar .. it should only need to know what row it is on

what matters most is that you have the:
Code:
bar_height = sprite_get_height( bar_spr );
slider_height = sprite_get_height( slider_spr );
slider_limit = bar_height - slider_height;
slider_yy[1] = 0;
we will position them relative to how:

Code:
max_cards_rows = ds_list_size(trunk_card_list) div cards_per_row;
max_rows_visible = 4;
card_rows_scroll_limit = max_card_rows - max_rows_visible;
trunk_scroll_row = trunk_scroll_pos div cards_per_row;
..are positioned.

both can set the scroll_per[1]:
Code:
scroll_per[1] = trunk_scroll_row / card_rows_scroll_limit;
// or
scroll_per[1] = slider_yy[1] / slider_limit;
note that I will not mix slider_yy and slider_start_yy here, slider_start_yy will just be the top of the bar, and the slider sprite will have no y offset.. if you need to drag it around with an offset then I recommend making a slider_offset variable for that (see spoiler at bottom):

In this case we want to use:
Code:
scroll_per[1] = trunk_scroll_row / card_rows_scroll_limit;

slider_yy[1] = floor( floor(slider_limit * scroll_per[1]) );
then your draw the slider:
Code:
draw_sprite_ext( slider_spr, 0, slider_xx[ tt ], slider_start_yy + slider_yy[ tt ], 1, 1, 0, c_white, 1 );
you should not need to change the position on the bar in any other code, unless you are pulling it around with the mouse, then it should get the position of where you want to be in the deck.

For drag and drop with the bar, something like this
Code:
if(slider_grab == noone)
if mousepress
for(i=0;i<2;i++)
if position_in_rectangle(...)
{
    slider_offset = mouse_y - slider_start_yy - slider_yy[i];
    slider_grab = i;
}

if(slider_grab != noone)
{
    slider_yy[slider_grab] = mouse_y - slider_start_yy - slider_offset;
    scroll_per[1] = slider_yy[1] / slider_limit;

    trunk_scroll_pos = round(card_rows_scroll_limit * scroll_per[slider_grab]) * cards_per_row;

    if mouserelease slider_grab=noone;
}
if slider_grab isn't noone then the slider shouldn't auto position itself after the card rows .. you could even make it so that it won't auto re-adjust the bar if it is near enough that the value it what it should be at:
Code:
if (trunk_scroll_pos div cards_per_row) == round(card_rows_scroll_limit * scroll_per[i])
But .. I actually think it would be better if you left the trunk/deck out of the slider moving code and instead kept the:
Code:
    trunk_scroll_pos = round(card_rows_scroll_limit * scroll_per[slider_grab]) * cards_per_row;
somewhere in the trunk code, so it updates when slider_grab is the correct value

Anyway, need to wrap it up and go home for the weekend xD
 
Top