Wierd invalid pointer.

Posted By: draculaFactory

Wierd invalid pointer. - 09/01/10 22:41

The code below causes a crash when I click on my inventory panel and move it, the crash occurs during the "sort_panels" function, the panel pointer that is passed into the function becomes invalid somehow... Oddly enough, to test this, I put "reset(panel,SHOW);" just before "if(temp_panel.layer > panel.layer && temp_panel != panel)" to test and the function did hide the correct panel, meaning that the pointer is not actually invalid.

Code:
// inventory art
BMAP* backpack_bmp = "backpack_panel.tga";
BMAP* items_bmp = "item_icons.tga";
BMAP* item_x48_bmp = "item_button_x48.tga";


// container variable arrays
var slot_owner[500];
var slot_number[500];
var item_slot_id[500];
var icon_bmp_x[500];
var icon_bmp_y[500];
var item_mdl_id[500];
var item_stack[500];
var drop_sound[500];


// pointers used for the 6 inventory pack slots
PANEL* pack_slot1;
PANEL* pack_slot2;
PANEL* pack_slot3;
PANEL* pack_slot4;
PANEL* pack_slot5;
PANEL* pack_slot6;


// helps determine the clicked slot number
var panel_slot_start = 0;

STRING* welcome_str = "Welcome";

TEXT* welcome_text =
{
  layer = 1;
  pos_x = 10;
  pos_y = 10;
  string (welcome_str,"this is","a","TEXT");
  flags = CENTER_X | TRANSLUCENT | SHOW;

}


function sort_panels(PANEL* panel)
{
	var list_no = 0;
	var sss = 0;
	
	PANEL* temp_panel;
	
	while(list_no < total_panels)
	{
		temp_panel = ptr_for_handle(panel_list[list_no]);
		if(temp_panel.layer > panel.layer && temp_panel != panel)
		{
			layer_sort(temp_panel,temp_panel.layer - 1);
		}
		list_no += 1;
	}
	
	layer_sort(panel,total_panels);
}


//moves a panel with mouse
function move_panel(PANEL* panel)
{
	
	//local variables
	VECTOR panel_vec;
	VECTOR pointer_vec;
	VECTOR panel_offset;
	
	vec_set(panel_vec.x,vector(panel.pos_x,panel.pos_y,0));
	
	//get initial mouse position
	pointer_vec.x = mouse_pos.x;
	pointer_vec.y = mouse_pos.y;
	
	sort_panels(panel);
	
	// while mouse held, loop
	while(mouse_left == 1)
	{
		panel_offset.x = mouse_pos.x - pointer_vec.x;
		panel_offset.y = mouse_pos.y - pointer_vec.y;
		
		panel.pos_x = panel_vec.x + panel_offset.x;
		panel.pos_y = panel_vec.y + panel_offset.y;
		
		// restrict panel positions to on-screen
		panel.pos_x = clamp(panel.pos_x,0,screen_size.x - panel.size_x);
		panel.pos_y = clamp(panel.pos_y,0,screen_size.y - panel.size_y);
		
		wait(1);
	}
}


// creates an icon bmp cutout from the slot number
function get_icon_cutout(var slot_no)
{
	
	BMAP* icon_bmp;
	STRING* icon_str = "item_icons.tga";
	
	str_cat(icon_str,"#");
	str_cat(icon_str,str_for_num(NULL,icon_bmp_x[slot_no]));
	str_cat(icon_str,"#");
	str_cat(icon_str,str_for_num(NULL,icon_bmp_y[slot_no]));
	str_cat(icon_str,"#48#48");
	
	icon_bmp = bmap_create(icon_str);
	return(icon_bmp);
}


// inventory panel click event
function inv_panel_click(PANEL* inv_panel)
{
	
	var format;
	var pixel;
	
	// lock and read panel background to determine if it was actually clicked
	format = bmap_lock(inv_panel.bmap,0);
	pixel = pixel_for_bmap(inv_panel.bmap,mouse_pos.x - inv_panel.pos_x,mouse_pos.y - inv_panel.pos_y);
	bmap_unlock(inv_panel.bmap);
	
	// if panel was clicked
	if(pixel != 0)
	{
		
		// if cursor is empty
		if(item_slot_id[0] == 0)
		{
			move_panel(inv_panel);
		}
		
		// bring this panel to front
		sort_panels(inv_panel);
	}
}


// fills the inv panel with an amount of inventory slots
function create_slots(PANEL* inv_panel, var rows, var cols, var start_x, var start_y, var start_slot)
{
	
	var rows_created = 0;
	var cols_created = 0;

	var x_pos;
	var y_pos;
	var slot_step;

	x_pos = start_x;
	y_pos = start_y;
	slot_step = start_slot;

	while(rows_created < rows)
	{
		
		while(cols_created < cols)
		{
			pan_setwindow(inv_panel,0,x_pos,y_pos,48,48,items_bmp,icon_bmp_x[slot_step],icon_bmp_y[slot_step]);
			pan_setbutton(inv_panel,0,0,x_pos,y_pos,item_x48_bmp,item_x48_bmp,item_x48_bmp,item_x48_bmp,NULL,NULL,NULL);
			
			x_pos += 48;
			slot_step ++;
			
			cols_created ++;
			
			wait(1);
		}
		
		y_pos += 48;
		x_pos = start_x;
		
		cols_created = 0;
		rows_created ++;
		
		
		wait(1);
	}
}


// creates the pack panel
function create_inv_panel(var start_slot, var x_pos, var y_pos)
{

	PANEL* inv_panel = pan_create("bmap = backpack_bmp; event = inv_panel_click;",1);
	
	inv_panel.pos_x = x_pos;
	inv_panel.pos_y = y_pos;
	
	create_slots(inv_panel,4,8,64,168,start_slot);
	
	register_panel(inv_panel);
	
	layer_sort(inv_panel,2);
	
	return(inv_panel);
}


// starts the inventory system
function inv_startup()
{
	
	BMAP* drag_icon;
	
	pack_slot1 = create_inv_panel(16,0,32);
	set(pack_slot1,SHOW);
	
	pack_slot2 = create_inv_panel(49,128,48);
	set(pack_slot2,SHOW);
	
	while(1)
	{
		
		if(key_1 == 1)
		{
			snd_play(select_snd,vol_effects,0);
			toggle(pack_slot1,SHOW);
			while(key_1 == 1){wait(1);}
		}
		
		// determine starting slot number for inventory mouse functions
		if(mouse_panel == pack_slot1){panel_slot_start = 16;}
		if(mouse_panel == pack_slot2){panel_slot_start = 49;}
		if(mouse_panel == pack_slot3){panel_slot_start = 81;}
		if(mouse_panel == pack_slot4){panel_slot_start = 113;}
		if(mouse_panel == pack_slot5){panel_slot_start = 145;}
		if(mouse_panel == pack_slot6){panel_slot_start = 177;}
		
		// mouse icon
		if(slot_number[0] != 0)
		{
			
			// create the icon cutout referencing the cursor slot
			drag_icon = get_icon_cutout(0);
			
			// draw the icon under the mouse cursor
			draw_quad(drag_icon,vector(mouse_pos.x - 24,mouse_pos.y - 24,0),NULL,vector(48,48,0),NULL,NULL,100,0);
		}
		
		wait(1);
	}
}




Here's the clencher: I went through the entire code line by line and discovered that the crash was actually being caused by the "welcome_text" element at the top of the script; this text is not the original text that I was using, I pasted this text from the manual for testing to see if a text element was causing the problem. Sure enough, when I comment out "welcome_text", there is no crash when I click on a panel, and everything moves and sorts just fine. The text element is not being referenced by any code in this script.

What gives?
Posted By: Lukas

Re: Wierd invalid pointer. - 09/02/10 14:23

Maybe, in some other part of your code, welcome_str is set to NULL or an invalid pointer?
Posted By: Damocles_

Re: Wierd invalid pointer. - 09/02/10 14:28

strange.
The text could interact with its "layer" position
with the panels internally in the engine.
(beeing a part of a sorted list of layer elements)

Try fuzzing around with the layer parameter.
Posted By: Saturnus

Re: Wierd invalid pointer. - 09/02/10 14:33

Might be related:
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=338912#Post338912
Posted By: EvilSOB

Re: Wierd invalid pointer. - 09/02/10 15:09

Ive looked at SOME of your code but not all, theres just so much.

But one thing that strikes comes to mind....

If your mouse pointer "crosses" the welcome text during the drag process,
then the 'mouse_panel' pointer will become null, because the welcome text
is in the way.
Could this be the cause?
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/02/10 21:53

Alright, I know that I should explain this part further. The system works fine when there is no text defined; if a text is defined, any text at all, anywhere in my code, the crash occurs. The welcome text is only there for the purpose of demonstrating the error. Even if I define a completely empty text, the crash still occurs.

There is a lot of code, I did narrow it down to a single line:
Code:
if(temp_panel.layer > panel.layer && temp_panel != panel)


The panel pointer is invalid ONLY in this line, it is not invalid before this line, and it is not invalid after this line. I am not referring to temp_panel, I am referring to the panel pointer that is passed into the function; ptr_for_handle works fine in this case.

Lukas, no welcome_str is not referenced at all by any code elsewhere.

Damocles, that occurred to me, but the text is not even in the same ball park, it is not registered or altered by anything.

EvilSOB, does mouse_panel work for text objects? The position of the text is in the upper left, the panel art is quite large and have dragged it around from multiple areas to make sure that I was actually hitting a panel. I have also tried to call the sort_panels function from the creation of the panel to ensure that no dragging has occured; again, with the text object defined I get a crash and without it, it works great.
Posted By: EvilSOB

Re: Wierd invalid pointer. - 09/02/10 22:07

mouse_panel doesnt 'work' for texts, BUT if there is a text with a higher layer
than an underlying panel, then the text will 'cover' the panel, and
mouse_panel will become NULL.

I hate 'dirty' if's, so thy this if instead...
if((temp_panel.layer > panel.layer) && (temp_panel != panel))
just on a chance the two parts of the if are getting tangled...

Or try this one, in case its temp_panel going wrong...
Code:
function sort_panels(PANEL* panel)
{
	var list_no = 0;
	var sss = 0;
	
	PANEL* temp_panel;
	
	while(list_no < total_panels)
	{
		temp_panel = ptr_for_handle(panel_list[list_no]);
		if((temp_panel!=NULL) && (panel!=NULL))
		{	if((temp_panel.layer > panel.layer) && (temp_panel != panel))
			{
				layer_sort(temp_panel,temp_panel.layer - 1);
			}
		}
		list_no += 1;
	}
	
	layer_sort(panel,total_panels);
}

But beware, this may just "hide" your real problem...
But if it does, that should help you FIND the real problem...
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/02/10 22:54

Well there is no invalid pointer crash with the code that you posted, but it caused a new problem: the panels are sorted in reverse order. Clicking on a panel now sorts it to the bottom layer lol.
Posted By: EvilSOB

Re: Wierd invalid pointer. - 09/03/10 02:58

Do you have, or can you make, a stand-alone mini-project we can test this with?
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/03/10 11:57

Yea sure: http://rapidshare.com/files/416818983/inventory.zip
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/04/10 09:19

any luck so far?
Posted By: EvilSOB

Re: Wierd invalid pointer. - 09/04/10 23:53

Not so far... I havent had that much time, but something "odd" is happening...

Im still looking...
Posted By: EvilSOB

Re: Wierd invalid pointer. - 09/05/10 00:29

It appears to be due to a known, POSSIBLE engine bug with handles...

See THIS thread thats still waiting on JCL to return.

In the meantime I'll modify your script to NOT use handles if I can.
I think I see a way...
Posted By: EvilSOB

Re: Wierd invalid pointer. - 09/05/10 00:49

Went easier than expected... And only minimal changes required...
Click to reveal..
Code:
// data structure
#include <acknex.h>
#include <default.c>

STRING* test = "test.wmb";

BMAP* arrow_cursor_bmp = "arrow.tga";


var total_panels = 0;			// total number of registered panels
PANEL* panel_list[64];			// panel list array



// sets resolution, depth, and window mode and alters aspect
function set_resolution(_x,_y,_depth,_window)
{
	var new_ratio;
	var view_aspect;
	
	video_set(_x,_y,_depth,_window);
	wait(1);
	
	//if fullscreen, alter aspect
	if(video_screen == 1)
	{
		new_ratio = _x / _y;
		view_aspect = new_ratio / 1.6;
		camera.aspect = view_aspect;
	}
	
	// frame rate
	fps_max = 60;
	fps_lock = 1;
	time_factor = 1;
	
}


// main mouse function
function init_mouse()
{
	
	// local vectors
	VECTOR temp_vec;
	
	// mouse properties
	mouse_mode = 1;
	mouse_pointer = 0;
	
	// mouse start position
	wait(1);
	mouse_pos.x = (screen_size.x / 2);
	mouse_pos.y = (screen_size.y / 2);
	
	// change to default cursor
	mouse_map = arrow_cursor_bmp;
	
	// loop forever
	while(1)
	{
		
		// if mouse valid
		if(mouse_valid == 1)
		{
			
			// update mouse position
			vec_set(mouse_pos.x,mouse_cursor.x);
			
		}
		
		wait(1);
	}
}


// main startup function
function main()
{
	
	// set the resolution
	set_resolution(1440,900,32,1);
	
	// buffer before level load
	wait(3);
	
	// load level
	level_load(test);
	
	init_mouse();
}


// displays on screen text at a position for a limited time
function display_text(var x_pos, var y_pos, STRING* text_str, var seconds)
{
	
	proc_mode = PROC_LATE;
	
	var panel_size_x = 0;
	var font_height = 15;
	var display_count = 0;
	
	// set seconds to ticks
	seconds *= 16;
	
	// set draw text mode
	draw_textmode("Arial",0,font_height,100);
	
	// loop while mouse is over this entity
	while(display_count < seconds)
	{
		
		// position and show description
		panel_size_x = str_width(text_str,NULL);
		font_height = 15;
		
		draw_quad(NULL,vector(x_pos + 2,y_pos,0),NULL,vector(panel_size_x + 4,font_height,0),NULL,vector(1,1,1),100,0);
		draw_text(text_str,x_pos + 2,y_pos,vector(255,255,255));
		
		display_count = minv(display_count + (1 * time_step),seconds);
		
		wait(1);
	}
}


function sort_panels(PANEL* panel)
{
	if(panel==NULL)		return;		//invalid panel parameter
	//
	var list_no;	for(list_no=0;	list_no<total_panels;	list_no++)
	{	if(panel_list[list_no]!=NULL) 
			if(panel_list[list_no].layer > panel.layer)
				layer_sort(panel_list[list_no], panel_list[list_no].layer-1);
	}
	layer_sort(panel,total_panels);
}



//moves a panel with mouse
function move_panel(PANEL* panel)
{
	
	//local variables
	VECTOR panel_vec;
	VECTOR pointer_vec;
	VECTOR panel_offset;
	
	vec_set(panel_vec.x,vector(panel.pos_x,panel.pos_y,0));
	
	//get initial mouse position
	pointer_vec.x = mouse_pos.x;
	pointer_vec.y = mouse_pos.y;
	
	sort_panels(panel);
	
	// while mouse held, loop
	while(mouse_left == 1)
	{
		panel_offset.x = mouse_pos.x - pointer_vec.x;
		panel_offset.y = mouse_pos.y - pointer_vec.y;
		
		panel.pos_x = panel_vec.x + panel_offset.x;
		panel.pos_y = panel_vec.y + panel_offset.y;
		
		// restrict panel positions to on-screen
		panel.pos_x = clamp(panel.pos_x,0,screen_size.x - panel.size_x);
		panel.pos_y = clamp(panel.pos_y,0,screen_size.y - panel.size_y);
		
		wait(1);
	}
}


// register the panel
function register_panel(PANEL* panel)
{
	panel_list[total_panels] = panel;
	total_panels ++;
}


// inventory art
BMAP* backpack_bmp = "backpack_panel.tga";
BMAP* items_bmp = "item_icons.tga";
BMAP* item_x48_bmp = "item_button_x48.tga";

SOUND* select_snd = "select.wav";
var vol_effects = 30;						// misc. sound effect volume

// container variable arrays
var slot_owner[500];									// if > 0, the slot is being used by something
var slot_origin[500];								// original slot number
var item_id[500];										// id number of the slot item; if 0, no item in slot
var bmp_icon_x[500];									// x location of the upper left pixel of the bmap icon
var bmp_icon_y[500];									// y location of the upper left pixel of the bmap icon
var name_index[500];									// name lookup index
var file_index[500];									// mdl file lookup index
var synergy_id[500];									// item has synergy with item number (item_id)
var synergy_usecode[500];							// item synergy use code, looks up the action to be taken


// pointers used for the 6 inventory pack slots
PANEL* pack_slot1;
PANEL* pack_slot2;
PANEL* pack_slot3;
PANEL* pack_slot4;
PANEL* pack_slot5;
PANEL* pack_slot6;


// helps determine the clicked slot number
var panel_slot_start = 0;

var item_hover_time;


// test item data
var ITM_TOME[9] = 				{-99,		-99,		1,		48,	0,		1,		1,		0,		0};
var ITM_MILLBOWL[9] = 			{-99,		-99,		40,	96,	0,		40,	40,	0,		0};


STRING* welcome_str = "Welcome";

TEXT* welcome_txt =	
{
	layer = -10;
	pos_x = 10;
	pos_y = 10;
	string (welcome_str,"this is","a","TEXT");
	flags = CENTER_X | TRANSLUCENT | SHOW;
} 


// looks up and returns the icon of the indicated slot
function lookup_icon(var slot_no)
{
	
	BMAP* icon_bmp;
	STRING* icon_str = "item_icons.tga";
	
	str_cat(icon_str,"#");
	str_cat(icon_str,str_for_num(NULL,bmp_icon_x[slot_no]));
	str_cat(icon_str,"#");
	str_cat(icon_str,str_for_num(NULL,bmp_icon_y[slot_no]));
	str_cat(icon_str,"#48#48");
	
	icon_bmp = bmap_create(icon_str);
	return(icon_bmp);
}


// looks up and returns the name string of the indicated slot
function lookup_name_str(var slot_no)
{
	
	STRING* name_str = "Unknown";
	
	if(name_index[slot_no] == 1){str_cpy(name_str,"Tome");}
	
	if(name_index[slot_no] == 40){str_cpy(name_str,"Milling Bowl");}
	
	return(name_str);
}


// looks up and returns the mdl file string of the indicated slot
function lookup_file_str(var slot_no)
{
	
	STRING* file_str = "Unknown";
	
	if(file_index[slot_no] == 1){str_cpy(file_str,"tome1.mdl");}
	
	if(file_index[slot_no] == 40){str_cpy(file_str,"bowl1.mdl");}
	
	return(file_str);
}


// adds an item to the specified slot
function slot_add_item(var* item_array, var slot_no)
{
	// slot_owner is not modified, it is a property of the slot itself
	slot_origin[slot_no] = slot_no;
	item_id[slot_no] = item_array[2];
	bmp_icon_x[slot_no] = item_array[3];
	bmp_icon_y[slot_no] = item_array[4];
	name_index[slot_no] = item_array[5];
	file_index[slot_no] = item_array[6];
	synergy_id[slot_no] = item_array[7];
	synergy_usecode[slot_no] = item_array[8];
}


// clears the indicated slot
function slot_clear(var slot_no)
{
	
	// slot_owner is not modified, it is a property of the slot itself
	slot_origin[slot_no] = 0;
	item_id[slot_no] = 0;
	bmp_icon_x[slot_no] = 0;
	bmp_icon_y[slot_no] = 0;
	name_index[slot_no] = 0;
	file_index[slot_no] = 0;
	synergy_id[slot_no] = 0;
	synergy_usecode[slot_no] = 0;
}


// copies item data from the source slot to the target slot
function slot_copy(var source_slot, var target_slot)
{
	
	// slot_owner is not modified, it is a property of the slot itself
	slot_origin[target_slot] = slot_origin[source_slot];
	item_id[target_slot] = item_id[source_slot];
	bmp_icon_x[target_slot] = bmp_icon_x[source_slot];
	bmp_icon_y[target_slot] = bmp_icon_y[source_slot];
	name_index[target_slot] = name_index[source_slot];
	file_index[target_slot] = file_index[source_slot];
	synergy_id[target_slot] = synergy_id[source_slot];
	synergy_usecode[target_slot] = synergy_usecode[source_slot];
}


// inventory panel click event
function click_inv_panel(PANEL* inv_panel)
{
	
//	var format;
//	var pixel;
//	
//	// lock and read panel background to determine if it was actually clicked
//	format = bmap_lock(inv_panel.bmap,0);
//	pixel = pixel_for_bmap(inv_panel.bmap,mouse_pos.x - inv_panel.pos_x,mouse_pos.y - inv_panel.pos_y);
//	bmap_unlock(inv_panel.bmap);
//	
//	// if panel was clicked
//	if(pixel != 0)
//	{
		
		
		move_panel(inv_panel);
//	}
}


// inventory panel slot click event
function click_inv_slot(var button_number, PANEL* inv_panel)
{
	
	// determine which slot was clicked
	var slot = panel_slot_start + (button_number - 1);
	
	// cursor icon pointer
	BMAP* mouse_item_bmp;
	
	// end info display loop from the last slot
	item_hover_time = -99;
	
	// if clicked slot has item data
	if(item_id[slot] > 0)
	{
		
		// move item data from the slot to the cursor
		slot_copy(slot,0);
		slot_clear(slot);
		
		// play select sound
		snd_play(select_snd,vol_effects,0);
		
		// while mouse is held
		while(mouse_left == 1)
		{
			
			// draw the icon under the cursor
			mouse_item_bmp = lookup_icon(0);
			draw_quad(mouse_item_bmp,vector(mouse_pos.x - 24,mouse_pos.y - 24,0),NULL,vector(48,48,0),NULL,NULL,100,0);
			
			wait(1);
		}
		
		wait(2);
		
		// if cursor still has data (item released over game view)
		if(item_id[0] > 0)
		{
			
			// move item data from the cursor back to the original slot
			slot_copy(0,slot_origin[0]);
			slot_clear(0);
			
			// play select sound
			snd_play(select_snd,vol_effects,0);
		}
	}
}


// inventory panel slot mouse over event
function touch_inv_slot(var button_number, PANEL* inv_panel)
{
	
	// determine which slot was touched
	var slot = panel_slot_start + (button_number - 1);
	
	// name string
	STRING* name_str = "Unknown";
	
	item_hover_time = 0;
	
	// if the slot has item data
	if(item_id[slot] > 0)
	{
		while(item_hover_time < 5 && item_hover_time != -99)
		{
			if(mouse_moving == 0){item_hover_time = minv(item_hover_time + (1 * time_step),5);}
			wait(1);
		}
		
		if(item_hover_time == 5)
		{
			name_str = lookup_name_str(slot);
			while(item_hover_time != -99)
			{
				display_text(mouse_pos.x,mouse_pos.y - 18,name_str,0.001);
				wait(1);
			}
		}
	}
	
	// if slot is empty
	else
	{
		item_hover_time = -99;
	}
}


// inventory panel slot mouse off event
function release_inv_slot(var button_number, PANEL* inv_panel)
{
	
	// determine over which slot the mouse was released
	var slot = panel_slot_start + (button_number - 1);
	
	// if cursor moved away from the slot
	if(event_type == EVENT_RELEASE)
	{
		item_hover_time = -99;
	}
	
	// if mouse was truely released over a slot
	if(event_type == EVENT_BUTTONUP)
	{
		
		// cursor has item data
		if(item_id[0] > 0)
		{
			
			// if drop slot is empty
			if(item_id[slot] == 0)
			{
				
				// move item data from the cursor to the slot
				slot_copy(0,slot);
				slot_clear(0);
				
				// slot_origin must be updated to new slot location
				slot_origin[slot] = slot;
			}
			
			// if drop slot is not empty
			else
			{
				
				// move item data from the cursor back to the original slot
				slot_copy(0,slot_origin[0]);
				slot_clear(0);
			}
			
			// play select sound
			snd_play(select_snd,vol_effects,0);
			
		}
	}
}


// fills the inv panel with an amount of inventory slots
function create_slots(PANEL* inv_panel, var rows, var cols, var start_x, var start_y, var start_slot)
{
	
	var rows_created = 0;
	var cols_created = 0;

	var x_pos;
	var y_pos;
	var slot_step;

	x_pos = start_x;
	y_pos = start_y;
	slot_step = start_slot;

	while(rows_created < rows)
	{
		
		while(cols_created < cols)
		{
			pan_setwindow(inv_panel,0,x_pos,y_pos,48,48,items_bmp,bmp_icon_x[slot_step],bmp_icon_y[slot_step]);
			pan_setbutton(inv_panel,0,0,x_pos,y_pos,item_x48_bmp,item_x48_bmp,item_x48_bmp,item_x48_bmp,click_inv_slot,release_inv_slot,touch_inv_slot);
			
			x_pos += 48;
			slot_step ++;
			
			cols_created ++;
			
			wait(1);
		}
		
		y_pos += 48;
		x_pos = start_x;
		
		cols_created = 0;
		rows_created ++;
		
		
		wait(1);
	}
}


// creates the pack panel
function create_inv_panel(var start_slot, var x_pos, var y_pos)
{

	PANEL* inv_panel = pan_create("bmap = backpack_bmp; event = click_inv_panel;",NULL);
	
	inv_panel.pos_x = x_pos;
	inv_panel.pos_y = y_pos;
	
	create_slots(inv_panel,4,8,64,168,start_slot);
	
	register_panel(inv_panel);
	
	// bring this panel to front
	layer_sort(inv_panel,total_panels);
	
	return(inv_panel);
}


// starts the inventory system
function inv_startup()
{
	
	slot_add_item(ITM_TOME,16);
	slot_add_item(ITM_MILLBOWL,17);
	pack_slot1 = create_inv_panel(16,32,32);
	pack_slot2 = create_inv_panel(49,160,48);
	pack_slot3 = create_inv_panel(81,288,64);
	pack_slot4 = create_inv_panel(113,416,80);
	pack_slot5 = create_inv_panel(145,544,96);
	pack_slot6 = create_inv_panel(177,672,112);
	
	set(pack_slot1,SHOW);
	set(pack_slot2,SHOW);
	set(pack_slot3,SHOW);
	set(pack_slot4,SHOW);
	set(pack_slot5,SHOW);
	set(pack_slot6,SHOW);
	
	while(1)
	{
		
		if(key_1 == 1)
		{
			snd_play(select_snd,vol_effects,0);
			toggle(pack_slot1,SHOW);
			sort_panels(pack_slot1);
			while(key_1 == 1){wait(1);}
		}
		
		if(key_2 == 1)
		{
			snd_play(select_snd,vol_effects,0);
			toggle(pack_slot2,SHOW);
			sort_panels(pack_slot2);
			while(key_2 == 1){wait(1);}
		}
		
		if(key_3 == 1)
		{
			snd_play(select_snd,vol_effects,0);
			toggle(pack_slot3,SHOW);
			sort_panels(pack_slot3);
			while(key_3 == 1){wait(1);}
		}
		
		if(key_4 == 1)
		{
			snd_play(select_snd,vol_effects,0);
			toggle(pack_slot4,SHOW);
			sort_panels(pack_slot4);
			while(key_4 == 1){wait(1);}
		}
		
		if(key_5 == 1)
		{
			snd_play(select_snd,vol_effects,0);
			toggle(pack_slot5,SHOW);
			sort_panels(pack_slot5);
			while(key_5 == 1){wait(1);}
		}
		
		if(key_6 == 1)
		{
			snd_play(select_snd,vol_effects,0);
			toggle(pack_slot6,SHOW);
			sort_panels(pack_slot6);
			while(key_6 == 1){wait(1);}
		}
		
		// determine starting slot number for inventory mouse functions
		if(mouse_panel == pack_slot1){panel_slot_start = 16;}
		if(mouse_panel == pack_slot2){panel_slot_start = 49;}
		if(mouse_panel == pack_slot3){panel_slot_start = 81;}
		if(mouse_panel == pack_slot4){panel_slot_start = 113;}
		if(mouse_panel == pack_slot5){panel_slot_start = 145;}
		if(mouse_panel == pack_slot6){panel_slot_start = 177;}
		
		wait(1);
	}
}


Posted By: paracharlie

Re: Wierd invalid pointer. - 09/05/10 19:03

Wow, nice inventory you have. I was trying to create my own inventory for my rpg that is as save friendly as possible. I would desperately like to use your inventory system in my rpg if you dont mind, minus the artwork of course?
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/05/10 20:15

Wow didn't think that I could do an array of panel pointers.... That helps a lot, I'll give it a shot.

Paracharlie: You should see the actual inventory grin that was just a bare bones version. Go for it I guess. BTW you might run into some funkiness with it later, the idea was to make an inventory that allowed you to have completely variable inventory panels on screen; for example, opening a chest would create an inventory screen that only displays the slots that the chest was using, thats what the slot_owner variable is for, the slot is not considered to be "free" unless nothing was using it, otherwise a chest might bleed into another set of slots by just checking to see if the inventory slot is simply occupied.
Posted By: paracharlie

Re: Wierd invalid pointer. - 09/05/10 20:34

Drac I would like the whole system if you dont mind sharing with me. I would love to see the whole thing.
I tried making my own, but I just have not been able to make one myself, I always get lost somewhere in the process and end up with a pile of crap, lol.
For that matter, I'd even give you a small donation for your time for a full working system.
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/06/10 01:02

Eh the thing is that it's still not finished; so anything that I give you would be a pile of crap because you would have to practically re-write it to fit your system. Typically an inventory system has tie-ins to stat systems and quest systems, etc. I can give it to you in a nut shell:

Use a panel for the inventory screen, use windows on the panel to display a section of an image file (all icons placed on a single "sprite sheet"), place a button over each window on the panel with an invisible image the size of the window object, each button controls a specific slot. When clicking on a button, the data from one section of the array is copied to another, I generally use position 0 on the array to indicate the cursor.

I've done lots of inventory systems in the past, I have just never shared them with anyone because I noticed that mine were totally different from the way others were doing it. This one just uses some of the cool new lite-c functions that make stuff neater. Like I used to use a different panel that follows the mouse to display an item "in" the cursor; now I use the bitmap cut out thingie, which just draws an icon under the cursor.

The only way that this inventory system differs is that the panels, buttons, and windows are all created during gameplay, and not pre-defined.
Posted By: paracharlie

Re: Wierd invalid pointer. - 09/06/10 02:09

Well I've screwed it up enough times to actually understand what your saying. What throws confuses me is copying data from one array to another. Is that where having an item_id would be used? See I still have alot of confusion and inventory's are definately not easy but I'm learning.
No problem though Drac. I'll figure it out eventually, I still have so much other things to do.
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/06/10 03:23

No see like this, just take a look at my script where it uses arrays. The actual item data could look something like this...
Code:
var item_spoon[3] = {1, 48, 96};



Each item, in this example, has 3 properties. The spoon's properties are: item_id (which is 1), bmp_x (which is pixel x location 48 on the icon sprite sheet), and bmp_y (which is pixel y location 96 on the icon sprite sheet).

The arrays that are the inventory slots would look like this:
Code:
var item_id[500];
var bmp_x[500];
var bmp_y[500];



The [500] after each array means that there are 500 inventory slots, you could increase it to 1000, or like 278394 if you wanted to...

The items are moved around by simply altering the [number] of the property arrays, not the item data arrays. This means that if the spoon item was contained in slot 54, then it would look like this in code:
Code:
...
item_id[54] = 1;
bmp_x[54] = 48;
bmp_y[54] = 96;
...


The above is the state of the three defined properties of inventory slot number 54. To delete the item from the slot, just set them all to zero grin

If you want more properties for your items you have to define more arrays:
Code:
var item_id[500];
var bmp_x[500];
var bmp_y[500];
var gold_value[500];
var sound_effect_number[500];
var weight[500];



And since we've added more properties, you must alter the item data array to allow for more properties:
Code:
var item_spoon[3] = {1, 48, 96, 100, 22, 1};



100 being the gold value of the spoon, 22 is the number of the sound effect that it makes, and 1 is the spoon's weight.

Take a look at the function in the script that adds an item, it simply uses a variable pointer to fill the correct array (inventory slot) with the correct numbers grin

So a function that adds your spoon would look like this:
Code:
function add_item(var* item_array, var slot)
{
	item_id[slot] = item_array[0];
	bmp_x[slot] = item_array[1];
	bmp_y[slot] = item_array[2];
	gold_value[slot] = item_array[3];
	sound_effect_number[slot] = item_array[4];
	weight[slot] = item_array[5];
}


You call the function like this: add_item(item_spoon,54);
Posted By: paracharlie

Re: Wierd invalid pointer. - 09/07/10 12:21

Hmm, I totally understand that. I'll mess around with your explanation until I fully understand. I also have alot of properties for items and weapons in my game; with weight always being a factor, so this layout really works out well for my game.
Thank you very much for taking the time to help me understand this.
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/08/10 07:53

Yea, it's not that hard. I can help you with most everything that I have implemented so far. Mine have tons of properties too and I am constantly adding more.
Posted By: paracharlie

Re: Wierd invalid pointer. - 09/08/10 11:57

Ok great. I'll be working on it today, so I'm sure I'll have some questions for you.
Posted By: paracharlie

Re: Wierd invalid pointer. - 09/09/10 12:23

Drac, what do you use synergy_id and synergy_usecode for? What do they do?
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/10/10 03:21

That is only half-implemented in that older script, you can delete references to that. In the script that is used for combining or using items on other items, such as dragging a spell scroll and dropping it on a spellbook to add the spell. The synergy_id is the id of the item type that the cursor item reacts with, synergy_usecode is the value of the action that takes place. For example, the synergy_id of the spell scroll matches the spellbook's id (the spellbook doesn't react when dragged and dropped on the scroll, however, so the spellbook's synergy_id is 0); the synergy_usecode is used in another lookup function, it looks up a block of code that unlocks the spell in the spellbook and then destroys the scroll.
Posted By: paracharlie

Re: Wierd invalid pointer. - 09/10/10 17:13

Ahh very cool.
Kind of like what Everquest did.
Another question Drac.
Why is slot_owner and slot_origin set to -99 for both tome and milling bowl?
Posted By: draculaFactory

Re: Wierd invalid pointer. - 09/14/10 14:43

Sorry that this took so long. -99 means nothing... slot_origin is used to snap the item back to its original slot (that it was dragged from) when you try to drop it somewhere invalid, it is not updated during the dragging process, only when the item is successfully placed somewhere. -99 is just something that I put there to remind myself that its value is updated during game play; there will never be an item with an actual -99 value in it, look at the function that adds an item to the inventory, it updates slot_origin right away.
Posted By: paracharlie

Re: Wierd invalid pointer. - 09/17/10 13:15

Thanks for your help Drac, I'm really having a easy time with this inventory.
© 2024 lite-C Forums