Gamestudio Links
Zorro Links
Newest Posts
Blobsculptor tools and objects download here
by NeoDumont. 03/28/24 03:01
Issue with Multi-Core WFO Training
by aliswee. 03/24/24 20:20
Why Zorro supports up to 72 cores?
by Edgar_Herrera. 03/23/24 21:41
Zorro Trader GPT
by TipmyPip. 03/06/24 09:27
VSCode instead of SED
by 3run. 03/01/24 19:06
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (AndrewAMD, Imhotep), 567 guests, and 4 spiders.
Key: Admin, Global Mod, Mod
Newest Members
sakolin, rajesh7827, juergen_wue, NITRO_FOREVER, jack0roses
19043 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 8 of 8 1 2 3 4 5 6 7 8
Re: Dropping items from inventory bag [Re: Ruben] #437255
02/13/14 08:56
02/13/14 08:56
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
The first 'snd_play' is before '!mouse_panel' so the problem is earlier. Check where, when and how you call your 'item_was_dropped' function. It needs to be called every frame.

Salud!

Re: Dropping items from inventory bag [Re: txesmi] #439930
04/13/14 04:31
04/13/14 04:31
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
I have still not solved this problem, for the program is still not allowing me to drop items from the inventory bag.

I am trying out a new technique. Instead of checking to see if I clicked outside a mouse_panel , I am checking to see if my mouse cursor is outside a certain range of x/y screen pixels (outside the inventory GUI itself) instead. This is the code that I am trying to use to drop an item from my player's inventory bag by click/floating an item outside the inventory bag, left-clicking, and hoping that the item's floating image will disappear from the inventory bag, and show up on the ground next to the player:

Code:
...

#include "inventory.c"

...

var mouse_x;
var mouse_y;

...

function change_mouse_mode()
{	
   mouse_mode += 1;
   mouse_mode %= 2;
   
   if (mouse_mode == 1)
   {
      mouse_map = cursor_pcx;
   }
   
   mouse_pos.x = mouse_cursor.x;
   mouse_pos.y = mouse_cursor.y;
   
   
   while(1) // DEBUGGER THAT SHOWS CURRENT PIXEL LOCATIONS FOR MOUSE CURSOR IN THE pDisplay PANEL BELOW
   {
      mouse_x = mouse_pos.x;
      mouse_y = mouse_pos.y;

      wait(1);
   }
}

...

// DEBUGGER PANEL USED TO SHOW THE CURRENT POSITION OF THE MOUSE CURSOR AT SCREEN PIXEL X AND SCREEN PIXEL Y.

PANEL* pDisplay =
{
        digits (620, 40, 5, *, 1, mouse_x); // DEBUGGER: MOUSE CURSOR X LOCATION
	digits (620, 70, 5, *, 1, mouse_y); // DEBUGGER: MOUSE CURSOR Y LOCATION

	flags = SHOW;
}

...

function slot_was_clicked ( int occurrence, int bag_id, int slot_id, int placed_item_id, int removed_item_id ) 
{
   	Bag *bagPanel;
	
   	if ( ( occurrence == INV_ITEM_REMOVED ) || ( occurrence == INV_ITEM_SWAPPED ) )
   	{
		if (bag_id == MAIN_BAG_ID)
		{
			if (slot_id == ACTIV_WPN_SLOT_ID)
			{
				ent_remove ( active_weapon );
				
				if(placed_item_id == NULL)
				{
					weapon_code = fist_code;
				}
			}
		}   
   	}
   	if ( ( occurrence == INV_ITEM_PLACED ) || ( occurrence == INV_ITEM_SWAPPED ) )
   	{
   		if (bag_id == MAIN_BAG_ID)
		{
			if (slot_id == ACTIV_WPN_SLOT_ID)
			{
				switch ( placed_item_id )
				{
					case SWORD:   activate_sword();  break;
					case MACE:    activate_mace();  break; 
					default:      weapon_code = fist_code; break;
				}
			}
		}   
   	}
   	if(inv_is_floating)
   	{
      		snd_play ( sndExploDebug, 100, 0 );
		
      		if ((mouse_y <= 73) || (mouse_y >= 313) || (mouse_x >= 263))
      		{
			if ( mouse_left )
			{
				snd_play ( sndDebugger, 100, 0 );
				
				var item_id = inv_get_floating_icon_item_id (); // Get the floating icon item id.
				inv_clear_floating_icon (); // Clear the floating icon.

				switch ( item_id ) // Create the new scenery object.
				{
					case SWORD: 
						ENTITY *entObject = ent_create ( "sword.mdl", player.x, dropObject );
						entObject.skill_id = item_id;
						break;
					case MACE: 
						ENTITY *entObject = ent_create ( "mace.mdl", player.x, dropObject );
						entObject.skill_id = item_id;
						break;
				}
			}
		}
   	}
}

...

function main()
{
	...

	set_on_click_callback("slot_was_clicked");

	while(1)
   	{
   		if ( active_weapon != NULL )
   		active_weapon->pan += 5*time_step;
   		
   		mouse_pos.x = mouse_cursor.x;
      		mouse_pos.y = mouse_cursor.y;
      
      		// if we've enabled the mouse:
      		if(mouse_mode > 0)
      		{
      			// move it's position with a cursor:
      			vec_set(mouse_pos.x, mouse_cursor.x);
      	
      		}
   		
   		wait(1);
	}
	
	sys_exit ( NULL );
}



The pDisplay panel in the above code actually shows the current location of the mouse cursor with the X and Y screen pixels of its location, so it appears that mouse_x and mouse_y are storing the correct location coordinates of the mouse cursor.

In the code above, on this line of code in the slot_was_clicked() function:

if ((mouse_y <= 73) || (mouse_y >= 313) || (mouse_x >= 263))

...the inventory bag GUI starts on Screen Pixel Y = 73, and goes to Screen Pixel Y = 313. The inventory bag GUI also starts from the very left side of the screen, and ends on Screen Pixel = 263. So in other words, if my mouse cursor is floating an inventory item, the mouse cursor is within the above Screen Pixel range, and the left mouse button was clicked simultaneously, I am trying to initiate this code:
Code:
snd_play ( sndExploDebug, 100, 0 ); // DEBUG EXPLOSION SOUND
				
var item_id = inv_get_floating_icon_item_id (); // Get the floating icon item id.
inv_clear_floating_icon (); // Clear the floating icon.

switch ( item_id ) // Create the new scenery object.
{
	case SWORD: 
		ENTITY *entObject = ent_create ( "sword.mdl", player.x, dropObject );
		entObject.skill_id = item_id;
		break;
	case MACE: 
		ENTITY *entObject = ent_create ( "mace.mdl", player.x, dropObject );
		entObject.skill_id = item_id;
		break;
}



I do not hear the debug explosion sound when I click/float an inventory item image, and left-click within the Screen Pixel range given above, which lets me know that this part of the function is not activating.

I set the variable item_id equal to the file title of the floating icon image by using the inv_get_floating_icon_item_id() function from inventory.c , and try to recreate the same item on the ground next to the player, like the player dropped the item on the ground. The inv_clear_floating_icon() function from inventory.c is supposed to delete the current floating icon. However, none of these actions are happening.

Here is the inventory.c code that I am using to create an inventory for the player in my game:

Code:
// 
// Inventory.c - programmed by Bret Truchan.  You are welcome to use this inventory
// system in the creation of commercial or free games.  You may not use it for any
// other purpose.
// 

/*


DOCUMENTATION

Table of Contents

   I. Introduction
  II. Essentials: inv_init() and inv_cleanup()
 III. Creating items for your inventory
  IV. Making your first bag
   V. Opening and Closing bags
  VI. Setting bag close and drag regions
 VII. Adding items to bags

VIII. Item Groups
  IX. Callbacks
  X. Other helpful functions


I. Introduction
---------------

Hello fellow programmer!  I hope that you can find the following inventory
system useful.  My main goal when making this inventory system was to decouple
the inventory system from the rest of the game code.  I also wanted to make it
as easy as possible to create and manage your inventory system.

This inventory has the following features:

1. Easy to use
2. Supports multiple bags
3. Handles the layering of bags for you
4. Supports callbacks for inventory events
5. Supports item "groups". (For example, gerbils can only be put in gerbil
slots.)

I modeled the inventory system after World of Warcraft.  One limitation to this
system is that slots in bags really need to be the same size.  I know how to 
fix this so, for example, your sword would show up huge in the sword slot but
small in a backpack slot, but I'll have to save that for a later release.



II. Essentials: inv_init() and inv_cleanup()
--------------------------------------------

Let's dive right in.  Creating your inventory is done in your lite-c code. 
You should not need to modify inventory.c.  Before anything else, include
inventory.c in your code, like so:

 #include <acknex.h>
 #include <default.c>
 #include "inventory.c" // <---- ADDED THIS

 void main()
 {
   inv_init(); // <---- ADDED THIS
   wait(1); // <---- ADDED THIS

   // etc..

Add the inv_init(); function call to your main loop as shown above.  Because
inventory.c uses some low level C structures, you need to call inv_cleanup()
just before your game closes.


III. Creating items for your inventory
--------------------------------------

Let's skip ahead and create some images that will be needed for your
inventory.  If you have the demo for this inventory code, you can use my demo
images.

  pack.pcx - The is the background image of your inventory pack.
  slot_bg.pcx - The background image of an empty slot.
  item1.pcx - An icon of an item, such as a sword.  This should be the same
size as slot_bg.pcx.

Ok, back to items....

Items are strange.  You might think of an item like a "sword" or "gun". 
However, this inventory system is NOT trying to control how you manage items
for your game.  Although you might have a "sword" item in your inventory, the
structure that's passed around in the inventory code should NOT have
attributes such as "damage" or "weight".

Let's move ahead with an example of adding your first item - A pile of sand.
Maybe this pile of sand will go into your nephew's Christmas Stocking
because he ate all your friggin' cookies?!

 #include <acknex.h>
 #include <default.c>
 #include "inventory.c"

 Item* item_sand;

 void main()
 {
   inv_init();
   wait(1);

   item_sand = inv_create_item(1,0,"item1.pcx","item1.pcx");


See that inv_create_item(...) statement?  inv_create_item() creates an abstract
item in your inventory system. Let's break it down:

 item_pointer = inv_create_item(item_id,group_id,floating_icon,inventory_icon);

Arguments:

 item_id - You make this up.  It can be anything that you want.  It doesn't affect the inventory engine.
 
 group_id - Later on, slots will also have a group id.  Items can only be put into slots with the right group id.

 floating_icon - The image used for the item while it's being dragged around the inventory system.

 inventory_icon - The image for displaying the item when the item is in a slot.

To reiterate, we introduced a new item into our inventory system.  We gave it an item id of 1, which really doesn't mean anything.  We gave it a group_id = 0, which means that the item can be placed into any slot having group_id=0.  We choose the same image "item1.pcx" for the icon used to "float" the item around in the inventory as well as the icon that represents the item in a slot.  That's good enough for now.  We'll keep moving forward..


IV. Making your first bag
-------------------------

There are a few terms that I loosly introduced above.  Your inventory may have multiple "bags".  Bags have multiple "slots", and slots may contain items.  Let's make our first bag.  Luckily, it's pretty easy:

 #include <acknex.h>
 #include <default.c>
 #include "inventory.c"

 Item* item_sand;
 Bag* bag; // <---- added this line

 void main()
 {
   inv_init();
   wait(1);

   item_sand = inv_create_item(1,0,"item1.pcx","item1.pcx");
   bag = inv_create_bag(1,"pack.pcx");  // <---- added this line


Easy!  When you do this, the bag does not appear on the screen.  We'll handle that later.  For now, let's look closely at the
inv_create_bag() function:

   bag = inv_create_bag(bag_id,bag_image);

Arguments

 bag_id - You make this up.  It's not used within the inventory system, but it can be useful when handling callbacks.  We'll  
 discuss callbacks later on.

 bag_image - This should be an image of your open inventory bag.


Creating a bag is only half the battle.  Generally, you use the inv_add_slot_to_bag() function to add
a slot to your bag.  Here's the generic version:

  function inv_add_slot_to_bag(Bag* bag, int slot_id, int group_id, STRING* default_image, int rel_x_pos, int rel_y_pos)

Arguments:

  bag - The bag that you created above.
  slot_id - Any value that you like.  It's only used for callbacks, which I'll cover later.
  group_id - Only items having this value may be added to the slot.
  default_image - An image showing an empty slot.
  rel_x_pos - x position relative to the top left of the bag's image
  rel_y_pos - y position relative to the top left of the bag's image

Here's a real world example of creating 4 slots to your bag:

  inv_add_slot_to_bag(bag,1,0,"slot_bg.pcx",9,38);
  inv_add_slot_to_bag(bag,2,0,"slot_bg.pcx",44,38);
  inv_add_slot_to_bag(bag,3,0,"slot_bg.pcx",78,38);
  inv_add_slot_to_bag(bag,4,0,"slot_bg.pcx",112,38);


V. Opening and Closing bags
---------------------------

Opening bags is easy:

  inv_open_bag(Bag* bag, int panel_x_position, int panel_y_position);

That's it!  Here's use a real world example:

  inv_open_bag(bag, 100,100);

Closing your bag is even easier:

  inv_close_bag(bag);

We haven't added items to bags yet, but you'll see that it's very easy. When you open and close bags, the bags remember what items they contained.  You don't need to re-add the items.


VI. Setting bag close and drag regions
--------------------------------------

This inventory system allows you to drag bags around the screen and close them.  It's optional.  All you need to do is tell the inventory system where the drag region and close region are on the bag image.  Here's an example:

  inv_set_bag_drag_region(bag,5,3,128,18);
  inv_set_bag_close_region(bag,129,0,148,19);

The arguments are:

 function inv_set_bag_drag_region(Bag* bag, int top_left_x, int top_left_y, int bottom_right_x, int bottom_right_y)
 function inv_set_bag_close_region(Bag* bag, int top_left_x, int top_left_y, int bottom_right_x, int bottom_right_y)

Quick note:  For multiple bags, the inventory code automatically handles which bag should be "on top" if they overlap.


VII. Adding items to bags
-------------------------

Believe it or not, you're almost done.  Adding items to the inventory system can be done in two ways.  First, you can add an item directly to a bag.  Alternatively, you can create an item and immediately have it "float" (which means that the icon is visible and is being dragged by the mouse).

Adding an item directly to a bag:

  function inv_insert_item_into_bag(Bag* bag, Item* item)

For example:

  inv_insert_item_into_bag(bag,item_sand);

  (This function will return 1 if there was room in the bag for the item, otherwise 0.)

... OR "Floating" a new item:

  function inv_float_item(Item* item)

For example:

  function inv_float_item(item_sand);

That's it!


VIII. Item Groups
-----------------

Item groups are super easy.  Group_id 0 is special.  If you assign group_id = 0 to a slot, that slot can hold ANY
item.  Let's pretend that you want to make a weapon slot that can ONLY hold weapons.  When you create the sword item,
use the group_id = 4;  Then, when you create the sword slot, set its group_id = 4 too.  Done!


IX. Callbacks
-------------

If you need to know when certain events happen in the inventory system, you'll want to use the callbacks.  I'll explain with an example.  Let's say that you want to know whenever a bag is opened.  First, you need to define a function in your lite-c that will be called when a bag is open.  An open-bag callback function looks like:

a) open_bag_callback

  // put something like this in your lite-c

  function bag_was_opened(int bag_id)
  {
    // do something
  }

Then, register this function with the inventory system by calling set_on_open_bag_callback() like so:

  set_on_open_bag_callback("bag_was_opened");

Whenever a bag is opened, your function bag_was_opened() will be called.  The bag_id of the opened bag will be passed into your function automatically.  Remember when we first created a bag and I said that the bag_id was useless?  I lied.  Here's where it comes into play.  You can tell which bag was opened by looking at the bag_id that's passed in to your callback function.

b) on_click_callback

This is most complicated callback.  It's triggered whenever someone clicks on a slot.  To use it, add something like this to your lite-c:

  function slot_was_clicked(int action, int bag_id, int slot_id, int placed_item_id, int removed_item_id)
  {
    if (action == INV_ITEM_PLACED)
    {
       // item was placed in bag
       // bag_id is the id of the bag where the item was placed
       // slot_id is the id of the slot where the item was placed  
       // placed_item_id is the item id that was placed into the slot  
       // removed_item_id is 0 and should be ignored
    }
    if (action == INV_ITEM_REMOVED)
    {
       // item was removed from bag  
       // bag_id is the id of the bag where the item was placed
       // slot_id is the id of the slot where the item was placed  
       // placed_item_id is 0 and should be ignored 
       // removed_item_id is the item id that was removed from the slot
    }
    if (action == INV_ITEM_SWAPED)
    {
       // item was put in to a slot that already contained an item, so they were swapped  
       // bag_id is the id of the bag where the item was placed
       // slot_id is the id of the slot where the item was placed  
       // placed_item_id is the item id that was placed into the slot 
       // removed_item_id is the item id that was removed from the slot
    }
  }

And register your callback like:

  set_on_click_callback("slot_was_clicked");


c) on_bag_close_callback

This is just like on_bag_open_callback.  Here's an example:

  function bag_was_closed(int bag_id)
  {
    // do something
  }

Then, register this function with the inventory system by calling set_on_close_bag_callback() like so:

  set_on_close_bag_callback("bag_was_closed");



X. Other helpful functions
--------------------------

 PANEL* inv_get_bag_panel_ptr(Bag* bag); // given a bag, return its panel pointer
 inv_is_bag_open(Bag* bag); // returns 1 if the bag is open, otherwise 0
 inv_get_open_bag_count(); // returns the number of open bags
 inv_is_floating(); // returns 1 if the player is floating an inventory item
 inv_is_item_in_bag(Bag* bag, Item* item); // returns 1 if the item is in the bag


*/





// ============================ BEGIN CODE =================================


#define new(type) malloc(sizeof(type##))
#define delete(object) free(object)

#define bag_layer 1
#define slot_layer 2
#define floating_item_layer 94

#define INV_ITEM_PLACED 1
#define INV_ITEM_SWAPPED 2
#define INV_ITEM_REMOVED 3

/* 
	struct Item

	The item structure holds a single item's information.  Items are intended to 
	track inventory icons only.  They're not really meant to manage an entire
	game's items.  For example, you would NOT use the item struct to hold values
	such as damage or defense rating for a sword.  The id in the item struct is
	intended to help associate these inventory based items with whatever item
	management is used in the game.  The id is set by the game developer to
	any arbitrary value.  The id is used in callback functions.
	
*/

typedef struct
{
   int id;
   int group_id;
   STRING* floating_icon;
   STRING* inventory_icon;
} Item;


// === Slot ===

typedef struct
{
	PANEL* slot_panel;
	
	int id;
	int group_id;
	int rel_x_pos;
	int rel_y_pos;
	int width;
	int height;
	
	STRING* background_image;
	
   Item *item;
   
   int bag_id;
   
} Slot;

// === Bag ===

typedef struct
{
	int id;
	int is_open;
	
	int drag_region_top_left_x;
	int drag_region_top_left_y;
	int drag_region_bottom_right_x;
	int drag_region_bottom_right_y;

	int close_region_top_left_x;
	int close_region_top_left_y;
	int close_region_bottom_right_x;
	int close_region_bottom_right_y;
	
	PANEL* bag_panel;
   Slot* slots[16];
   int _slot_count;
   STRING* image_name;
     
} Bag;


// === Floating Item ===

typedef struct
{
	Item* item;
	PANEL* floating_item_panel;
	
} FloatingItem;


// Ugly linked list for keeping track of panels and associated slots

typedef struct SlotPanelAssoc
{
	PANEL* slot_panel;
	Slot* slot;
	struct SlotPanelAssoc* next;
	struct SlotPanelAssoc* prev;
	
} SlotPanelAssoc;


// Another ugly linked list for keeping track of z-order of open bags

typedef struct BagLayer
{
	Bag* bag;
	struct BagLayer* next;
	struct BagLayer* prev;
	
} BagLayer;


// Global variables

SlotPanelAssoc* slot_panel_assoc;
BagLayer* bag_layer_node;
 
FloatingItem* global_floating_item_ptr;

int inv_floating_flag;
int inv_open_bag_count; // The number of open bags
int inv_item_count; // index used for the inv_items_array
int inv_bag_count;  // index used for the inv_bags_array

Item* inv_items_array[5000];  // Global array to hold item pointers.  Used by cleanup script only.
Bag* inv_bags_array[100]; // Again, store all created bags in this array so we can properly deallocate them later.


// =============== FUNCTIONS =============================================================


// function prototypes

function inv_close_bag(Bag*);
function _inv_do_float(FloatingItem*);
function _inv_drag_bag(Bag*, int drag_offset_x, int drag_offset_y);

function addBagLayer(Bag*);
function removeBagLayer(Bag*);
function reorderBagLayers();
function addSlotPanelAssoc(Slot* slot, PANEL* slot_panel);
function removeSlotPanelAssoc(Slot* slot);

function getSlotPtrForPanelPtr(PANEL* panel_ptr);
function getBagPtrForPanelPtr(PANEL* panel_ptr);


// Callback function prototypes

void on_click_callback_function_ptr(int inv_action, int bag_id, int slot_id, int placed_item_id, int removed_item_id);
void on_float_end_callback_function_ptr();
void on_close_bag_callback_function_ptr(int bag_id);
void on_open_bag_callback_function_ptr(int bag_id);




// --------------- Inventory Function -----------------------------------
 
/* // ORIGINAL FUNCTION 
function inv_init()
{
	// Create a instance of the floating item struct and set the global_floating_item_ptr to it
	
	FloatingItem* floating_item = new(FloatingItem);
	floating_item->item = NULL;	
	inv_floating_flag = 0; // set global floating flag
	global_floating_item_ptr = floating_item;  

}
*/

// NEW FUNCTION

function inv_init() 
{
	// Create a instance of the floating item struct and set the global_floating_item_ptr to it
	
	FloatingItem* floating_item = new(FloatingItem);
	floating_item->item = NULL;	
	inv_floating_flag = 0; // set global floating flag
	global_floating_item_ptr = floating_item;  
	
	on_click_callback_function_ptr = NULL;
	on_float_end_callback_function_ptr = NULL;
	on_close_bag_callback_function_ptr = NULL;
	on_open_bag_callback_function_ptr = NULL;
}
 
function bagOnClick(PANEL* panel_ptr)
{
	Bag* bag;
	
	bag = getBagPtrForPanelPtr(panel_ptr);
	
	// Check to see if the player is dragging the panel
	
	if (bag->drag_region_top_left_x != bag->drag_region_bottom_right_x)
	{
		if ((mouse_pos.x > (bag->bag_panel->pos_x + bag->drag_region_top_left_x))
		&& (mouse_pos.x < (bag->bag_panel->pos_x + bag->drag_region_top_left_x + (bag->drag_region_bottom_right_x - bag->drag_region_top_left_x)))
		&& (mouse_pos.y > (bag->bag_panel->pos_y + bag->drag_region_top_left_y))
		&& (mouse_pos.y < (bag->bag_panel->pos_y + bag->drag_region_top_left_y + (bag->drag_region_bottom_right_y - bag->drag_region_top_left_y))))
		{
			_inv_drag_bag(bag,mouse_pos.x - bag->bag_panel->pos_x, mouse_pos.y - bag->bag_panel->pos_y);
		}
	}
	
	if (bag->close_region_top_left_x != bag->close_region_bottom_right_x)
	{
		if ((mouse_pos.x > (bag->bag_panel->pos_x + bag->close_region_top_left_x))
		&& (mouse_pos.x < (bag->bag_panel->pos_x + bag->close_region_top_left_x + (bag->close_region_bottom_right_x - bag->close_region_top_left_x)))
		&& (mouse_pos.y > (bag->bag_panel->pos_y + bag->close_region_top_left_y))
		&& (mouse_pos.y < (bag->bag_panel->pos_y + bag->close_region_top_left_y + (bag->close_region_bottom_right_y - bag->close_region_top_left_y))))
		{
			inv_close_bag(bag);
			return(0);
		}
	}

	// Bring bag to the front

	removeBagLayer(bag);		
	addBagLayer(bag);		

	reorderBagLayers();

}

function _inv_drag_bag(Bag* bag, int drag_offset_x, int drag_offset_y)
{
	int i;
		
	while(mouse_left)
	{
		
		vec_set(mouse_pos,mouse_cursor);
					
		// Move bag
		bag->bag_panel->pos_x = mouse_pos.x - drag_offset_x;
		bag->bag_panel->pos_y = mouse_pos.y - drag_offset_y;
		
		// Move all slots
		for (i=0; i < bag->_slot_count; i++)
		{
			bag->slots[i]->slot_panel->pos_x = bag->slots[i]->rel_x_pos + bag->bag_panel->pos_x;
			bag->slots[i]->slot_panel->pos_y = bag->slots[i]->rel_y_pos + bag->bag_panel->pos_y;
		}		
		
		wait(1);
	}
}

function slotOnClick(PANEL* clicked_panel) // KEY TO SOLVING PROBLEM?????????????????????????????????????????????????????????????????????????????????
{

	Slot* clicked_slot = getSlotPtrForPanelPtr(clicked_panel);

	if (clicked_slot == NULL) { diag("\n*** Error: panel not found\n"); }
	
	// player clicked on item in inventory while not floating an item
	
	diag("test1");
	
	if (global_floating_item_ptr->item == NULL)
	{
		diag("test2");

		if (clicked_slot->item != NULL) // Player is grabbing an item out of the inventory
		{
			
			diag("\ngrab started\n");
			
			// optionally callback with action, bag_id, slot_id, item_id
			if (on_click_callback_function_ptr) on_click_callback_function_ptr(INV_ITEM_REMOVED,clicked_slot->bag_id,clicked_slot->id,0,clicked_slot->item->id);


			// Create the floating panel
			
			global_floating_item_ptr->floating_item_panel = pan_create("",floating_item_layer);
			
			// Set the item and panel image of the floating item structure.  This effectively "floats"
			// the item that was stored in the inventory slot.
			
			global_floating_item_ptr->item = clicked_slot->item;
			global_floating_item_ptr->floating_item_panel->bmap = bmap_create(clicked_slot->item->floating_icon);
			global_floating_item_ptr->floating_item_panel->flags |= VISIBLE;
			
			// Set the item pointer of the clicked on slot to NULL
			
			clicked_slot->item = NULL;
			
			// Restore inventory slot image to be the default background image
			
			clicked_slot->slot_panel->bmap = bmap_create(clicked_slot->background_image);			

			inv_floating_flag = 1;
			_inv_do_float(global_floating_item_ptr);
			

		}
	}
	else
	{
		diag("test3");

		if ((clicked_slot->group_id == 0) || (clicked_slot->group_id == global_floating_item_ptr->item->group_id)) // Test to make sure that item can be placed in the slot
		{		
			if (clicked_slot->item == NULL) // player is putting an item into an empty inventory slot
			{
				// optionally callback with action, bag_id, slot_id, item_id
				if (on_click_callback_function_ptr) on_click_callback_function_ptr(INV_ITEM_PLACED,clicked_slot->bag_id,clicked_slot->id,global_floating_item_ptr->item->id,0);
				
				// Place item in slot
				clicked_slot->item = global_floating_item_ptr->item;	
				clicked_panel->bmap = bmap_create(global_floating_item_ptr->item->inventory_icon);
				global_floating_item_ptr->item = NULL;		
	
				// End float
				pan_remove(global_floating_item_ptr->floating_item_panel);
				inv_floating_flag = 0;	
			}		
				
			else // player is swapping the floating item for the one in the inventory
			{
	
				// optionally callback with action, bag_id, slot_id, item_id
				if (on_click_callback_function_ptr) on_click_callback_function_ptr(INV_ITEM_SWAPPED,clicked_slot->bag_id,clicked_slot->id,global_floating_item_ptr->item->id,clicked_slot->item->id);
				
				
				// Backup the information of the clicked on slot
				Item* clicked_slot_item_pointer = clicked_slot->item;
				STRING* clicked_slot_inventory_icon = str_create(clicked_slot->item->inventory_icon);
				
				// Set the slot to the floating item
				clicked_slot->item = global_floating_item_ptr->item;
				clicked_panel->bmap = bmap_create(global_floating_item_ptr->item->inventory_icon);
				
				// Set the floating item to the slot
				global_floating_item_ptr->item = clicked_slot_item_pointer;
				global_floating_item_ptr->floating_item_panel->bmap = bmap_create(clicked_slot_inventory_icon);
				
			}
		}
	}
	
}

function inv_clear_floating_icon ()
{
	if ( inv_floating_flag )
	{
		inv_floating_flag = 0;
		global_floating_item_ptr->item = NULL;		
		bmap_remove(global_floating_item_ptr->floating_item_panel->bmap);
		pan_remove(global_floating_item_ptr->floating_item_panel);
	}
}

var inv_get_floating_icon_item_id ()
{
	if ( inv_floating_flag )
	{
		return global_floating_item_ptr->item->id; 
	}
	else
	{
		error ( "Not existent floating icon on 'inv_get_floating_icon_item_id'.\nValidate the existence of a floating icon before calling 'inv_get_floating_icon_item_id'." );
		return -1;
	}
}

// END OF NEW CODE

function inv_create_item(item_id, group_id, STRING* floating_icon, STRING* inventory_icon)
{
	// Create item and assign images
	
	Item* item = new(Item);
	item->floating_icon = floating_icon;		
	item->inventory_icon = inventory_icon;
	item->id = item_id;
	item->group_id = group_id;
	
	// Add item to global array for cleanup purposes

	inv_items_array[inv_item_count] = item;
	inv_item_count++;
	
	return item;
		
}



function _inv_do_float(FloatingItem* floating_item)
{
	proc_mode = PROC_LATE;
		
	mouse_mode = 4;
	mouse_pointer = 1;
	 
	while(inv_floating_flag == 1)
	{
		floating_item->floating_item_panel.pos_x = mouse_pos.x + 10;
		floating_item->floating_item_panel.pos_y = mouse_pos.y + 10;
		wait(1);		
	}

	// optionally do a callback when floating ends
		
	if (on_float_end_callback_function_ptr) on_float_end_callback_function_ptr();

}

function inv_float_item(Item* item)
{
	
	global_floating_item_ptr->item = item;
	global_floating_item_ptr->floating_item_panel = pan_create("",floating_item_layer);
	global_floating_item_ptr->floating_item_panel->bmap = bmap_create(item->floating_icon);
	
	global_floating_item_ptr->floating_item_panel->flags |= VISIBLE;
	
	inv_floating_flag = 1; // set global floating flag
	
	_inv_do_float(global_floating_item_ptr);
	
	return global_floating_item_ptr;
}


function inv_create_bag(int bag_id, STRING* image_name)
{
	Bag* bag;
	bag = new(Bag);
	
	bag->image_name = image_name;
	bag->id = bag_id;
	
	// Initialize slot_count to 0
	bag->_slot_count = 0;
	bag->is_open = 0;
	
	// Add bag to global array for cleanup purposes

	inv_bags_array[inv_bag_count] = bag;
	inv_bag_count++;
	
	return bag;
}

function inv_set_bag_drag_region(Bag* bag, int top_left_x, int top_left_y, int bottom_right_x, int bottom_right_y)
{
	bag->drag_region_top_left_x = top_left_x;	
	bag->drag_region_top_left_y = top_left_y;	
	bag->drag_region_bottom_right_x = bottom_right_x;	
	bag->drag_region_bottom_right_y = bottom_right_y;
}

function inv_set_bag_close_region(Bag* bag, int top_left_x, int top_left_y, int bottom_right_x, int bottom_right_y)
{
	bag->close_region_top_left_x = top_left_x;	
	bag->close_region_top_left_y = top_left_y;	
	bag->close_region_bottom_right_x = bottom_right_x;	
	bag->close_region_bottom_right_y = bottom_right_y;
}

function inv_open_bag(Bag* bag, int panel_x_position, int panel_y_position)
{
	bag->bag_panel = pan_create("",bag_layer_node);
	bag->bag_panel->bmap = bmap_create(bag->image_name);
	bag->bag_panel->event = bagOnClick;

	bag->is_open = 1;
	
	int i;
	
	// Add slots
	
	for (i=0; i < bag->_slot_count; i++)
	{
		
		bag->slots[i]->slot_panel = pan_create("",slot_layer);
		
		if (bag->slots[i]->item == NULL)
		{
			bag->slots[i]->slot_panel->bmap = bmap_create(bag->slots[i]->background_image);
		}
		else
		{
			bag->slots[i]->slot_panel->bmap = bmap_create(bag->slots[i]->item->inventory_icon);
		}
		
		bag->slots[i]->slot_panel->event = slotOnClick;
		bag->slots[i]->slot_panel->pos_x = bag->slots[i]->rel_x_pos + panel_x_position;
		bag->slots[i]->slot_panel->pos_y = bag->slots[i]->rel_y_pos + panel_y_position;
		
		// Make the new slot panel visible
		bag->slots[i]->slot_panel->flags |= VISIBLE;
		
		// Add this panel and slot to the linked list
		addSlotPanelAssoc(bag->slots[i],bag->slots[i]->slot_panel);
	}
	
	bag->bag_panel->pos_x = panel_x_position;
	bag->bag_panel->pos_y = panel_y_position;
		
	bag->bag_panel->flags |= VISIBLE;
	
	if (on_open_bag_callback_function_ptr) on_open_bag_callback_function_ptr(bag->id);
	
	inv_open_bag_count++;
	
	// Add the pointer to this bag to the front of a linked list of bag pointers.  This
	// linked list is maintained to allow reordering of bags based on layer.
	addBagLayer(bag);
	reorderBagLayers();
	
}

function inv_close_bag(Bag* bag)
{
	if (bag == NULL) 
	{
		diag("\nWARNING: inv_close_bag called with argument NULL\n");
		return 0;
	}

	bag->is_open = 0;
	
	int i;
	
	for (i=0; i < bag->_slot_count; i++)
	{
		// Remove each slot panel
		pan_remove(bag->slots[i]->slot_panel);
		
		// Remove the slot from the associative array
		removeSlotPanelAssoc(bag->slots[i]);
	}

	// remove bag panel
	
	pan_remove(bag->bag_panel);
	
	if (on_close_bag_callback_function_ptr) on_close_bag_callback_function_ptr(bag->id);
		
	inv_open_bag_count--;
	
	// Remove the pointer to this bag from a linked list of bag pointers.  This
	// linked list is maintained to allow reordering of bags based on layer.
	
	removeBagLayer(bag);		
}

//***********************************************************************************************************************************************************************

/*

// ORIGINAL FUNCTION

function inv_add_slot_to_bag(Bag* bag, int slot_id, int group_id, STRING* default_image, int rel_x_pos, int rel_y_pos)
{
	Slot* new_slot;
	new_slot = new(Slot);

	// Set the position for the new slot
	
	new_slot->rel_x_pos = rel_x_pos;
	new_slot->rel_y_pos = rel_y_pos;	
	new_slot->background_image = default_image;
	new_slot->item = NULL;
	new_slot->id = slot_id;
	new_slot->group_id = group_id;
	new_slot->bag_id = bag->id;	
		
	bag->slots[bag->_slot_count] = new_slot;
	
	bag->_slot_count += 1;
	
}
*/

// NEW FUNCTION

function inv_add_slot_to_bag(Bag* bag, int slot_id, int group_id, STRING* default_image, int rel_x_pos, int rel_y_pos)
{
	Slot* new_slot;
	new_slot = new(Slot);

	// Set the position for the new slot
	
	new_slot->rel_x_pos = rel_x_pos;
	new_slot->rel_y_pos = rel_y_pos;	
	new_slot->background_image = default_image;
	new_slot->item = NULL;
	new_slot->id = slot_id;
	new_slot->group_id = group_id;
	new_slot->bag_id = bag->id;	
	new_slot->slot_panel = NULL;	// <---- NEW LINE
	
	bag->slots[bag->_slot_count] = new_slot;
	
	bag->_slot_count += 1;
	
}

/*

// ORIGINAL FUNCTION

function inv_insert_item_into_bag(Bag* bag, Item* item)  // COULD THIS SOLVE THE PROBLEM?????????????????????????????????????????????????????????????????????
{
	int i;
	
	for(i=0;i < bag->_slot_count; i++)
	{
		if (bag->slots[i] != NULL)
		{
			if (bag->slots[i]->item == NULL)
			{
				if ((bag->slots[i]->group_id == item->group_id) || (bag->slots[i]->group_id == 0))
				{
					bag->slots[i]->item = item;				
					bag->slots[i]->slot_panel->bmap = bmap_create(item->inventory_icon);
					return 1;
				}
			}
		}
	}
	
	return 0;
}

*/

// NEW FUNCTION

function inv_insert_item_into_bag ( Bag* bag, Item* item )
{
	int i;
	for(i=0;i < bag->_slot_count; i++)
	{
		if (bag->slots[i] != NULL)
		{
			if (bag->slots[i]->item == NULL)
			{
				if ((bag->slots[i]->group_id == item->group_id) || (bag->slots[i]->group_id == 0))
				{
					bag->slots[i]->item = item;
					if ( bag->slots[i]->slot_panel )				
						bag->slots[i]->slot_panel->bmap = bmap_create(item->inventory_icon					);
					if (on_click_callback_function_ptr) on_click_callback_function_ptr(INV_ITEM_PLACED,bag->id,bag->slots[i]->id,item->id,NULL);
					return 1;
				}
			}
		}
	}
	
	return 0;
}

function inv_cleanup()
{
	diag("\nStarting inventory cleanup\n");
	
	int i;
	int j;
	
	// Clean up items
	
	Item* item;
	
	for(i=0;i<inv_item_count;i++)
	{
		diag("\n   * cleaning up inventory item");
		item = inv_items_array[i];
		
		if (item != NULL)
		{
			free(item->floating_icon);
			free(item->inventory_icon);
			free(item);
			diag(" - success");
		}
	}
	
	// Clean up bags
	
	Bag* bag;
	
	for (i=0; i<inv_bag_count; i++)
	{
		diag("\n   * cleaning up bag");		
		bag = inv_bags_array[i];
		
		if (bag != NULL)
		{
			// Clean up slots in bag

			for (j=0; j < bag->_slot_count; j++)
			{
				diag("\n     - cleaning up slot");
				free(bag->slots[j]->background_image);
				free(bag->slots[j]);
			}			
			
			free(bag->image_name);
			free(bag);
		}		
	}
	
	free(global_floating_item_ptr);
	
	diag("\nCompleted inventory cleanup\n");
	
}

// NEW FUNCTION*********************************************************************************************************************

var inv_get_floating_icon_item_id ()
{
	if ( !inv_floating_flag  )
		return -1;
	inv_floating_flag = 0;
	Item *item = global_floating_item_ptr->item;
	//item = global_floating_item_ptr->item;
	global_floating_item_ptr->item = NULL;		
   bmap_remove(global_floating_item_ptr->floating_item_panel->bmap);
   pan_remove(global_floating_item_ptr->floating_item_panel);
   //);
	return item->id;
}

// ------------- Helpful functions --------------

function inv_get_bag_panel_ptr(Bag* bag)
{
	return bag->bag_panel;	
}

function inv_is_bag_open(Bag* bag)
{
	if (bag == NULL) return 0;
	return bag->is_open;
}

function inv_get_open_bag_count()
{
	return inv_open_bag_count;
}

function inv_is_floating()
{
	return inv_floating_flag;
}

function inv_is_item_in_bag(Bag* bag, Item* item)
{
	int i;
	
	for(i=0;i < bag->_slot_count; i++)
	{
		if (bag->slots[i]->item == item)
		{
			return 1;
		}
	}
	
	return 0;
}


// ------------- Create Callback Functions ---------

function set_on_click_callback(STRING* function_name) { on_click_callback_function_ptr = engine_getscript(function_name); } //******************************************************
function set_on_float_end_callback(STRING* function_name) { on_float_end_callback_function_ptr = engine_getscript(function_name); }
function set_on_close_bag_callback(STRING* function_name) { on_close_bag_callback_function_ptr = engine_getscript(function_name); }
function set_on_open_bag_callback(STRING* function_name) { on_open_bag_callback_function_ptr = engine_getscript(function_name); }



// --------------- linked-list functions --------------------------------

// ** list functions for managing bag z order

function addBagLayer(Bag* bag)
{
	if(bag_layer_node == NULL)
	{
		bag_layer_node = new(BagLayer);
		bag_layer_node->bag = bag;

		bag_layer_node->next = NULL;
		bag_layer_node->prev = NULL;
	}
	else
	{
		// Create a new BagLayer struct and put it at the beginning of the list
		BagLayer* new_bag_layer_node = new(BagLayer);
		new_bag_layer_node->bag = bag;
				
		bag_layer_node->prev = new_bag_layer_node;
		new_bag_layer_node->next = bag_layer_node;
		new_bag_layer_node->prev = NULL;
		
		bag_layer_node = new_bag_layer_node;
	}
	
}

function removeBagLayer(Bag* bag)
{
	int first_node = 1;
	
	BagLayer* iterator = bag_layer_node;
	
	while(iterator != NULL)
	{
		if (iterator->bag == bag)
		{
			// Tie together next and previous nodes
			if (iterator->prev != NULL) iterator->prev->next = iterator->next;			
			if (iterator->next != NULL) iterator->next->prev = iterator->prev;
			
			if (first_node) bag_layer_node = iterator->next;
			
			// Free up removed slotPanelAssoc struct
			delete(iterator);
			
			
			return 1;
		}
		iterator = iterator->next;
		first_node = 0;
	}
}

function reorderBagLayers()
{
	int new_bag_layer = 90;
	int sanity_check = 0;
	int i;
	
	BagLayer* iterator = bag_layer_node;
	Bag* bag;
		
	while(iterator != NULL)
	{
		// Chage bag layer
		bag = iterator->bag;		
		layer_sort(bag->bag_panel,new_bag_layer);
		
		// Change bag's slot layers
		for (i=0; i < bag->_slot_count; i++)
		{
			layer_sort(bag->slots[i]->slot_panel,new_bag_layer + 1);
		}		
		
		new_bag_layer -= 3;
		iterator = iterator->next;
		
		sanity_check++;
		if (sanity_check > 100) 
		{
			diag("ERROR: reorderBagLayers has run amok!");
			break;
		}
	}
	
}

// ** list functions for storing associations between panels and slots

function addSlotPanelAssoc(Slot* slot, PANEL* slot_panel)
{
	if(slot_panel_assoc == NULL)
	{
		slot_panel_assoc = new(SlotPanelAssoc);
		slot_panel_assoc->slot_panel = slot_panel;
		slot_panel_assoc->slot = slot;

		slot_panel_assoc->next = NULL;
		slot_panel_assoc->prev = NULL;
		
	}
	else
	{
		// Create a new slot_panel_assoc struct and put it at the beginning of the list
		SlotPanelAssoc* new_slot_panel_assoc = new(SlotPanelAssoc);
		new_slot_panel_assoc->slot_panel = slot_panel;
		new_slot_panel_assoc->slot = slot;
				
		slot_panel_assoc->prev = new_slot_panel_assoc;
		new_slot_panel_assoc->next = slot_panel_assoc;
		new_slot_panel_assoc->prev = NULL;
		
		slot_panel_assoc = new_slot_panel_assoc;
	}
}

function removeSlotPanelAssoc(Slot* slot)
{
	int first_node = 1;

	SlotPanelAssoc* iterator = slot_panel_assoc;
	
	while(iterator != NULL)
	{
		if (iterator->slot == slot)
		{
			// Tie together next and previous nodes
			if (iterator->prev != NULL) iterator->prev->next = iterator->next;			
			if (iterator->next != NULL) iterator->next->prev = iterator->prev;

			if (first_node) slot_panel_assoc = iterator->next;
			
			// Free up removed slotPanelAssoc struct
			delete(iterator);
			
			return 1;
		}
		iterator = iterator->next;
		first_node = 0;
	}
}

function getSlotPtrForPanelPtr(PANEL* panel_ptr)
{
	SlotPanelAssoc* iterator = slot_panel_assoc;

	if (iterator == NULL) 
	{
		diag("\nWARNING: getStructForPanelPtr returned NULL.");
	}
	
	while(iterator != NULL)
	{
		if (iterator.slot_panel == panel_ptr)
		{
			return(iterator.slot);
		}
		iterator = iterator->next;
	}
	
	return NULL;
}

/* 

	getBagPtrForPanelPtr(PANEL* panel_ptr)
 
	Given a panel pointer, return a pointer to the bag having that panel.
	In this case, we're lucky because the bags are all stored in the
	global inv_bags_array.  Why not store the slots in a similar array? --
	Because they're constantly created and destroyed.
	
*/

function getBagPtrForPanelPtr(PANEL* panel_ptr)
{
	int i;
	Bag* bag;
	
	for (i=0;i<inv_bag_count;i++)
	{
		bag = inv_bags_array[i];
		
		if (bag->bag_panel == panel_ptr)
		{
			return bag;
		}	
	}
	
	return NULL;
	
}



Does anyone know why the slot_was_clicked() function is not erasing an inventory image icon from the inventory bag and creating that same item on the ground next to the player when I click/float an inventory item at Screen Pixel Y less than or equal to 73 and greater than or equal to 313, and Screen Pixel X greater than 263; and then left click the mouse?

Any help would be appreciated. Thank you.


Last edited by Ruben; 04/13/14 04:33.
Re: Dropping items from inventory bag [Re: Ruben] #439989
04/14/14 18:57
04/14/14 18:57
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
Hi Ruben,
there are several troubles with your code.

inv_is_floating is a function. You must call it this way:
Code:
if ( inv_is_floating() )
{...



Anyway looking into inventory.c I saw that the floating icon is created after the event call so it will never be true.

You set slot_was_clicked as the function called when a slot is clicked so you can be totally sure that the mouse is over the clicked slot when the event is called. It is not possible to find the mouse out of the inventory panel when you click over a slot.

Same happens with the mouse buttons. You can be totally sure that the mouse left button is pressed when the slot click event is called (unless enable_mouse is set to 2).

Hope it helps wink

Re: Dropping items from inventory bag [Re: txesmi] #440029
04/16/14 08:16
04/16/14 08:16
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
Hi Ruben,
I wanted to give you a new possibility with a little change to inventory.c. I added a new occurrence to the slot click event in order to detect the mouse right button.

You need to add a new macro for the new occurrence
Code:
#define INV_ITEM_RIGHT_CLICK 4 // 354th code line



The modified slotOnClick function: the function added as event to every slot.
Code:
function slotOnClick(PANEL* clicked_panel) 
{
	Slot* clicked_slot = getSlotPtrForPanelPtr(clicked_panel);

	if (clicked_slot == NULL) { diag("\n*** Error: panel not found\n"); }
	
	if (global_floating_item_ptr->item == NULL) 	// player clicked on item in inventory while not floating an item
	{
// 16/04/2014 Addition -----------------------------------------------------
		if ( event_type == EVENT_CLICK ) // mouse left button event
		{
// -------------------------------------------------------------------------
			if (clicked_slot->item != NULL) // Player is grabbing an item out of the inventory
			{
				// optionally callback with action, bag_id, slot_id, item_id
				if (on_click_callback_function_ptr) 
					on_click_callback_function_ptr(INV_ITEM_REMOVED,clicked_slot->bag_id,clicked_slot->id,0,clicked_slot->item->id);
	
	
				// Create the floating panel
				
				global_floating_item_ptr->floating_item_panel = pan_create("",floating_item_layer);
				
				// Set the item and panel image of the floating item structure.  This effectively "floats"
				// the item that was stored in the inventory slot.
				
				global_floating_item_ptr->item = clicked_slot->item;
				global_floating_item_ptr->floating_item_panel->bmap = bmap_create(clicked_slot->item->floating_icon);
				global_floating_item_ptr->floating_item_panel->flags |= VISIBLE;
				
				// Set the item pointer of the clicked on slot to NULL
				
				clicked_slot->item = NULL;
				
				// Restore inventory slot image to be the default background image
				
				clicked_slot->slot_panel->bmap = bmap_create(clicked_slot->background_image);			
	
				inv_floating_flag = 1;
				_inv_do_float(global_floating_item_ptr);
				
			}
// 16/04/2014 Addition -----------------------------------------------------
		}
		else if ( event_type == EVENT_RIGHTCLICK ) // mouse right button event
		{
			if (clicked_slot->item != NULL)
			{
				if (on_click_callback_function_ptr) 
					on_click_callback_function_ptr(INV_ITEM_RIGHT_CLICK,clicked_slot->bag_id,clicked_slot->id,clicked_slot->item->id,0);
			}
		}
// -------------------------------------------------------------------------
	}
	else
	{
		if ((clicked_slot->group_id == 0) || (clicked_slot->group_id == global_floating_item_ptr->item->group_id)) // Test to make sure that item can be placed in the slot
		{		
			if (clicked_slot->item == NULL) // player is putting an item into an empty inventory slot
			{
				// optionally callback with action, bag_id, slot_id, item_id
				if (on_click_callback_function_ptr) on_click_callback_function_ptr(INV_ITEM_PLACED,clicked_slot->bag_id,clicked_slot->id,global_floating_item_ptr->item->id,0);
				
				// Place item in slot
				clicked_slot->item = global_floating_item_ptr->item;	
				clicked_panel->bmap = bmap_create(global_floating_item_ptr->item->inventory_icon);
				global_floating_item_ptr->item = NULL;		
	
				// End float
				pan_remove(global_floating_item_ptr->floating_item_panel);
				inv_floating_flag = 0;	
			}		
			else // player is swapping the floating item for the one in the inventory
			{
	
				// optionally callback with action, bag_id, slot_id, item_id
				if (on_click_callback_function_ptr) on_click_callback_function_ptr(INV_ITEM_SWAPPED,clicked_slot->bag_id,clicked_slot->id,global_floating_item_ptr->item->id,clicked_slot->item->id);
				
				
				// Backup the information of the clicked on slot
				Item* clicked_slot_item_pointer = clicked_slot->item;
				STRING* clicked_slot_inventory_icon = str_create(clicked_slot->item->inventory_icon);
				
				// Set the slot to the floating item
				clicked_slot->item = global_floating_item_ptr->item;
				clicked_panel->bmap = bmap_create(global_floating_item_ptr->item->inventory_icon);
				
				// Set the floating item to the slot
				global_floating_item_ptr->item = clicked_slot_item_pointer;
				global_floating_item_ptr->floating_item_panel->bmap = bmap_create(clicked_slot_inventory_icon);
				
			}
		}
	}
}



Since every slot is a panel, they are not buttons, you must set enable_mouse to 2 in order to get the event call when you click with the right mouse button over a slot.

Code:
mouse_mode = 2; // or 4 or whatever you use
enable_mouse = 2;



At this point you should be able to detect the mouse right click over a slot inside your slot_was_clicked function.

Code:
function slot_was_clicked ( int occurrence, int bag_id, int slot_id, int placed_item_id, int removed_item_id ) 
{
	Bag *bagPanel;
	
	if ( ( occurrence == INV_ITEM_REMOVED ) || ( occurrence == INV_ITEM_SWAPPED ) )
	{
		if (bag_id == MAIN_BAG_ID)
		{
			if (slot_id == ACTIV_WPN_SLOT_ID)
			{
				ent_remove ( active_weapon );
				
				if(placed_item_id == NULL)
				{
					weapon_code = fist_code;
				}
			}
		}   
	}
	if ( ( occurrence == INV_ITEM_PLACED ) || ( occurrence == INV_ITEM_SWAPPED ) )
	{
		if (bag_id == MAIN_BAG_ID)
		{
			if (slot_id == ACTIV_WPN_SLOT_ID)
			{
				switch ( placed_item_id )
				{
					case SWORD:   activate_sword();  break;
					case MACE:    activate_mace();  break; 
					default:      weapon_code = fist_code; break;
				}
			}
		}   
	}
	if ( occurrence == INV_ITEM_RIGHT_CLICK )
	{
		snd_play ( sndExploDebug, 100, 0 );
	}
}



This code let you hear the sndExploDebug sound when you click over a filled slot and when you have not an item grabbed.

Imagine you want to drop an item at the player position when you click over a filled slot with the mouse right button. You would need to create a new entity in the scenery and clear the clicked slot. You know how to create a new entity but there is no function to clear a slot. I wrote it for you. Add it to inventory.c and use it into your slot_was_clicked function.

Code:
function inv_clear_slot ( int bag_id, int slot_id )
{
	Bag* bag;
	
	int ii;
	for ( ii=0; ii<inv_bag_count; ii++ )
	{
		bag = inv_bags_array[ii];
		if ( bag->id != bag_id )
			continue;
		
		int i = 0;
		for ( ; i<bag->_slot_count; i++ )
		{
			Slot *slot = bag->slots[i];
			if ( slot->id != slot_id )
				continue;
			
			if ( slot->item == NULL )
				continue;
			
			if (on_click_callback_function_ptr)
				on_click_callback_function_ptr(INV_ITEM_REMOVED,bag_id,slot_id,slot->item->id,slot->item->id);
			
			slot->item = NULL;
			if ( slot->slot_panel != NULL )
				slot->slot_panel->bmap = bmap_create(slot->background_image);
		}
	}
}



This function gets slower the more bags exists but the item index management does not let me build it other way.

Hope it helps
Salud!

Re: Dropping items from inventory bag [Re: txesmi] #440106
04/18/14 00:43
04/18/14 00:43
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
txesmi: It worked!!! You are amazing!! I am now able to drop items from the player's inventory bag.

Now I just need to figure out how to make the same dropped item appear on the ground next to the player.

I am totally willing to include you in the credits for this game when it is finished, if you would like. This is a HUGE completed milestone, friend. I have been working quite a long time on this issue. This really made my day. :-D

Last edited by Ruben; 04/18/14 00:46.
Re: Dropping items from inventory bag [Re: Ruben] #440172
04/19/14 16:04
04/19/14 16:04
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
I'm glad to help grin

Salud!

pd: The clicked slot item id is stored in placed_item_id

Re: Dropping items from inventory bag [Re: txesmi] #440275
04/22/14 09:03
04/22/14 09:03
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
Well, I managed to solve all the other bugs with this thread's issue of dropping an inventory item, so, I consider this thread completed.

Thank you all for your help. I greatly appreciate it. This thread truly helped me accomplish a huge milestone in my game. :-)

Re: Dropping items from inventory bag [Re: Ruben] #440779
05/02/14 00:12
05/02/14 00:12
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
txesmi: By the way, I sent you a private message.

Page 8 of 8 1 2 3 4 5 6 7 8

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1