Gamestudio Links
Zorro Links
Newest Posts
AlpacaZorroPlugin v1.3.0 Released
by kzhao. 05/20/24 01:28
Free Live Data for Zorro with Paper Trading?
by AbrahamR. 05/18/24 13:28
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
3 registered members (kzhao, AndrewAMD, bigsmack), 824 guests, and 5 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Hanky27, firatv, wandaluciaia, Mega_Rod, EternallyCurious
19051 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 3 of 8 1 2 3 4 5 6 7 8
Re: Access variable from other program? [Re: WretchedSid] #434871
12/28/13 20:25
12/28/13 20:25
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
Originally Posted By: JustSid
As far as the current translation unit is concerned: Yes. The include is replaced with the contents of the other script by the pre-processor.

By the way at whoever suggested global variables: Shame on you! Polluting the global namespace with variables is evil!

Okay. Let say I create a function named active_weapon_slot() in OrcStronghold.c , as shown below:

Code:
function active_weapon_slot()
{
	if(str_cmp(active_weapon_slot.floating_icon, "steel_sword.pcx")) 
     {
          active_sword = ent_create ("sword.mdl", my.x, attach_weapon);
     }
     else
     {
          ent_remove(active_sword);
     }
}



Now lets say I use the inv_create_item() function (taken from inventory.c) in the main function of OrcStronghold.c , as shown below:

Code:
// Inside OrcStronghold.c

function main()
{
   ...

item_shield = inv_create_item(1,0,"shield.pcx","shield.pcx");
   item_apple = inv_create_item(1,0,"apple.pcx","apple.pcx");
   item_sword = inv_create_item(0,1,"steel_sword.pcx","steel_sword.pcx");
   item_mace = inv_create_item(0,1,"mace.pcx","mace.pcx");
   item_gold = inv_create_item(1,0,"gold_coins.pcx","gold_coins.pcx");



In this last piece of code, I just created five items (.pcx images of equipment items) to be used to populate the slots of the inventory bag. I can drag these images among the different slots of the inventory bag, if I chose to.

However, I still have not created the slots themselves for the inventory bag, in order to put items into. I now perform that action here within the same OrcStrongholdMain.c main function:

Code:
...

   // ACTIVE ITEM SLOT
   
   active_weapon_slot = inv_add_slot_to_bag(bag, 0, 1, 
      "leather_texture.pcx", 9, 60); // 3RD VALUE "1" (which
      //    belongs to group_id variable), ONLY EQUIPMENT 
      //    ITEMS WITH group_id value = 1 CAN BE INSERTED 
      //    INTO THIS SLOT.  ONLY WEAPON ITEMS ARE ASSIGNED
      //    group_id = 1 .  ALL NON-WEAPON ITEMS ARE ASSIGNED 
      //    group_id = 0 , SO ONLY WEAPON ITEMS CAN BE 
      //    INSERTED INTO THIS SLOT.  I SET 
      //    active_weapon_slot EQUAL TO THIS SLOT.  
      //    "active_weapon_slot()" is a function in 
      //    OrcStronghold.c , outside the main function.

   // EACH ROW OF INVENTORY BAG IS SPACED OUT BY 64 HEIGHT
   // FIRST ROW OF INVENTORY BAG

   inv_add_slot_to_bag(bag,1,0,"leather_texture.pcx",9,150);
   inv_add_slot_to_bag(bag,2,0,"leather_texture.pcx",70,150);
   inv_add_slot_to_bag(bag,3,0,"leather_texture.pcx",130,150);
   inv_add_slot_to_bag(bag,4,0,"leather_texture.pcx",190,150);
      // NOTICE THAT THE THIRD VALUE OF THESE SLOTS 
      //    ARE ASSIGNED THE VALUE 0 (zero).  THE REASON FOR 
      //    THIS IS BECAUSE THESE ITEMS ARE NOT WEAPONS, 
      //    THEREFORE, I ASSIGN THEIR group_id VARIABLE TO 0.

   ...



So in the last code above, I created an inventory bag with five slots. The top slot is reserved as the "active weapon" slot. This slot checks to see what the group_id is of an equipment item (.pcx image). If the group_id of the image is 1, that image can be placed in that slot. If the group_id of the equipment item is not 1 (like zero), then the equipment item cannot be placed in this slot.

I also created four other slots underneath the "active weapon" slot. These four slots can accept any items, weapon or non-weapon. That is because their group_id value (3rd value) is equal to 0.

Now, I also created the function active_weapon_slot() in OrcStronghold.c , before the main function. This function is supposed to represent the "active weapon" slot in the inventory bag. Whatever .pcx image of a weapon is placed in this "active weapon" slot inside the inventory bag, that is the weapon that the player should be armed with, in the player's hand, ready to use.

This is the code of function active_weapon_slot() that is trying to accomplish this:

Code:
// Inside OrcStronghold.c

function active_weapon_slot()
{
	if(str_cmp(active_weapon_slot.floating_icon, "steel_sword.pcx")) 
     {
          active_sword = ent_create ("sword.mdl", my.x, attach_weapon);
     }
     else
     {
          ent_remove(active_sword);
     }
}



The function above is comparing the floating_icon variable's string, to the string "steel_sword.pcx". The variable floating_icon comes from inventory.c , and is used in the function inv_create_item , that we used earlier to create equipment item .pcx images, to be used to populate slots in the inventory bag. The function inv_create_item() is shown here:

Code:
// Inside inventory.c

...

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;
}



As you see in the code above, floating_icon is the third variable taken as an argument in the inv_create_item function. However, if you notice in the code before last, I am trying to access the string value of that floating_icon variable (that is used as an argument in inv_create_item() inside inventory.c script) from the OrcStronghold.c script , in order to compare it with the string value "steel_sword.pcx". "steel_sword.pcx" is the file name of the sword image that is used to populate the inventory bag slots. If floating_icon string value of the active weapon slot equals "steel_sword.pcx", I want to attach a .mdl sword model to the player's hand, which is shown in the code above last.

When I compile this, this is my error:

Compiling ORCSTRONGHOLD.C - [Esc] to abort......
Error in 'line 180:
'floating_icon' : is not a member of 'BOOL'
< if(str_cmp(active_weapon_slot.floating_icon, "steel_sword.pcx"))
.. 0.108 sec
Error compiling ORCSTRONGHOLD.C
Error E355: Startup failure - any key to abort

Even though I #include inventory.c at the beginning of OrcStronghold.c , either I am using the function active_weapon_slot incorrectly, or I am not able to access the floating_icon value in the active weapon slot for some reason.

Do you know what I am doing wrong?

Last edited by Ruben; 12/28/13 20:34.
Re: Access variable from other program? [Re: Ruben] #434872
12/28/13 20:36
12/28/13 20:36
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
Speaking in layman's terms, when a picture of a sword is inside the "active weapon" slot of the inventory bag, I want my player to be armed with a sword. If a picture of a mace is inside the "active weapon slot" of the inventory bag, I want my player to be armed with a mace; etc.

That is what this code is trying to accomplish.

Should I post this in a different thread that is beyond the "Starting with Gamestudio" thread?

Last edited by Ruben; 12/28/13 20:37.
Re: Access variable from other program? [Re: Ruben] #434877
12/29/13 01:27
12/29/13 01:27
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
I will attempt to explain this in simpler terms again. It seems very hard for me to communicate this problem to people. If people on this thread cannot understand my problem after trying to explain it here, I will have no choice but to take this to a different thread beyond "Starting with Gamestudio". So here it goes:
Code:
Script:     OrcStronghold.c
Functions:  main()
            active_weapon_slot()
Actions:    #include "inventory.c" in beginning of script.
            In Main():  Uses inv_create_item() function 
               (stored in inventory.c) to process .pcx images 
               of equipment items, like sword, mace, gold, 
               apple, etc., so that their .pcx images can be 
               used in the inventory bag GUI as equipment 
               item images that can be placed in slots, 
               representing equipment items in the player's 
               inventory.
            In Main():  Uses inv_add_slot_to_bag() function 
               (stored in inventory.c) to add slots in the 
               inventory bag.  The programmer can create as 
               many slots as she/he wants for the inventory 
               bag.  The function name "active_weapon_slot" 
               is set equal to the inv_add_slot_to_bag 
               instance that is supposed to represent the 
               slot used for arming the player with a weapon.
            In active_weapon_slot():  Tries to compare the 
               variable string stored in floating_icon 
               variable (which is an argument in 
               inv_create_item() function, stored in 
               inventory.c) against the string 
               "steel_sword.pcx".  The file name 
               "steel_sword.pcx" is an argument passed to the 
               inv_create_item() function from 
               OrcStronghold.c main() function, to allow an 
               image of a sword representing a sword in 
               inventory, that can be used among the slots in 
               the inventory bag.

Script:     inventory.c
Functions:  inv_add_slot_to_bag(Bag* bag, int slot_id, int 
               group_id, STRING* default_image, int 
               rel_x_pos, int rel_y_pos)
            inv_create_item(item_id, group_id, STRING* 
               floating_icon, STRING* inventory_icon)
Actions:    inv_add_slot_to_bag() function creates a slot for 
               a custom made inventory bag for the player.
            inv_create_item() function allow a .pcx image to 
               be used in the inventory bag, representing an 
               equipment item.



Code:

Code:
// OrcStronghold.c

#include "inventory.c"

...

function active_weapon_slot()
{
   if(str_cmp(active_weapon_slot.floating_icon, "steel_sword.pcx")) 
   {
      active_sword = ent_create ("sword.mdl", my.x, attach_weapon);
   }
   else
   {
      ent_remove(active_sword);
   }
}

...

function main()
{
   ...

   item_shield = inv_create_item(1,0,"shield.pcx","shield.pcx");
   item_apple = inv_create_item(1,0,"apple.pcx","apple.pcx");
   item_sword = inv_create_item(0,1,"steel_sword.pcx","steel_sword.pcx");
   item_mace = inv_create_item(0,1,"mace.pcx","mace.pcx");
   item_gold = inv_create_item(1,0,"gold_coins.pcx","gold_coins.pcx");
   
   ... 
   
   // START OF INVENTORY BAG
 
   // ACTIVE ITEM SLOT
   
   active_weapon_slot = inv_add_slot_to_bag(bag, 0, 1, "leather_texture.pcx", 
      9, 60); 

   inv_add_slot_to_bag(bag,1,0,"leather_texture.pcx",9,150);
   inv_add_slot_to_bag(bag,2,0,"leather_texture.pcx",70,150);
   inv_add_slot_to_bag(bag,3,0,"leather_texture.pcx",130,150);
   inv_add_slot_to_bag(bag,4,0,"leather_texture.pcx",190,150);
	
   ...
   
}


Code:
// inventory.c

...

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_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;	
}

...



How can I get OrcStronghold.c to access the floating_icon value (stored in inv_create_item() function, which is stored in inventory.c script) for the "active weapon" slot, using the active_weapon_slot() function in OrcStronghold.c ?

I think this is about the simplest way that I can try to explain this.


Last edited by Ruben; 12/29/13 01:39.
Re: Access variable from other program? [Re: Ruben] #434878
12/29/13 02:20
12/29/13 02:20
Joined: Nov 2006
Posts: 497
Ohio
xbox Offline
Senior Member
xbox  Offline
Senior Member

Joined: Nov 2006
Posts: 497
Ohio
From what I am understanding, by the looks of part of your code such as
Code:
Slot* new_slot;
new_slot = new(Slot);


you are trying to use structs. You cannot (as far as I am aware) store variables in functions. Functions are just routines or methods that allow you to modify data, call other routines, etc. You can do as the others were saying and save these variables to global variables so that you can always access them, However the downside to that is if you decide to make more inventory slots, you must go add more global variables to match the new slots.

Back to using stucts. Structs are the best way to go in this situation because for every new "slot" you want to add, create a new "instance" of a slot struct and now you can easily access those variables per instance. example
Code:
typedef struct{
var rel_x_pos, rel_y_pos;
STRING* background_image;
var item;
var id;
var group_id;
var bag_id;
} Slot;

If you have already done that, sorry for typing code.
Once that is done, if you have stored the instances in an array example.
Code:
Slot* inv_slots[100];
inv_slots[0] = new Slot;


you could easily access the variables like this
Code:
inv_slots[21].item = 2; // or what ever you want to do with it.
//or change the background picture like this.
inv_slots[53].background_image = "newBackground.pcx";


I hope this helps. If not I sincerely apologize.
Best wishes!

Re: Access variable from other program? [Re: xbox] #435012
01/01/14 20:18
01/01/14 20:18
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
Thank you xbox. I think you are on the right track.

I am trying to use structs now in my situation. However, for some reason I am still not able to attach a sword to my player's hand when I drag a sword image toward the active weapon slot in the player's inventory bag.

So far, this is what I have done in my code:

OrcStronghold.c
Code:
// OrcStronghold.c

#include "Player.c"

...

Item* inv_slots[13];
inv_slots = new(Item);

...

function main()
{
   ...

   // Creating equipment items to be used in inventory bag (.pcx images to click
   //    and drag among slots in inventory bag)

   item_shield = inv_create_item(1,0,"shield.pcx","shield.pcx");
   item_apple = inv_create_item(1,0,"apple.pcx","apple.pcx");
   item_sword = inv_create_item(0,1,"steel_sword.pcx","steel_sword.pcx");
   item_mace = inv_create_item(0,1,"mace.pcx","mace.pcx");
   item_gold = inv_create_item(1,0,"gold_coins.pcx","gold_coins.pcx");

   bag = inv_create_bag(1,"leather_seam.pcx");  // <---- added this line

   // START OF INVENTORY BAG
   
   // ACTIVE ITEM SLOT
   
   inv_slots[0] = inv_add_slot_to_bag(bag,0,1,"leather_texture.pcx",9,60); 
      // Active Weapon slot

   // EACH ROW OF INVENTORY BAG IS SPACED OUT BY 64 HEIGHT
   // FIRST ROW OF INVENTORY BAG

   inv_slots[1] = inv_add_slot_to_bag(bag,1,0,"leather_texture.pcx",9,150);
   inv_slots[2] = inv_add_slot_to_bag(bag,2,0,"leather_texture.pcx",70,150);
   inv_slots[3] = inv_add_slot_to_bag(bag,3,0,"leather_texture.pcx",130,150);
   inv_slots[4] = inv_add_slot_to_bag(bag,4,0,"leather_texture.pcx",190,150);
	
   // SECOND ROW OF INVENTORY BAG
	
   inv_slots[5] = inv_add_slot_to_bag(bag,5,0,"leather_texture.pcx",9,214);
   inv_slots[6] = inv_add_slot_to_bag(bag,6,0,"leather_texture.pcx",70,214);
   inv_slots[7] = inv_add_slot_to_bag(bag,7,0,"leather_texture.pcx",130,214);
   inv_slots[8] = inv_add_slot_to_bag(bag,8,0,"leather_texture.pcx",190,214);
	
   // THIRD ROW OF INVENTORY BAG
	
   inv_slots[9] = inv_add_slot_to_bag(bag,9,0,"leather_texture.pcx",9,278);
   inv_slots[10] = inv_add_slot_to_bag(bag,10,0,"leather_texture.pcx",70,278);
   inv_slots[11] = inv_add_slot_to_bag(bag,11,0,"leather_texture.pcx",130,278);
   inv_slots[12] = inv_add_slot_to_bag(bag,12,0,"leather_texture.pcx",190,278);

   if(str_cmp(inv_slots[0].floating_icon, "steel_sword.pcx")) 
   {
        active_sword = ent_create ("sword.mdl", my.x, attach_weapon);
   }
   else
   {
        ent_remove(active_sword);
   }

   ...
}


Code:
// Player.c

#include "inventory.c"

...

// Attaches a weapon to player's hand

action attach_weapon() 
{
   set(my,PASSABLE);
   proc_mode = PROC_LATE;
	
   while (you != NULL) 
   {
      vec_for_vertex(temp.x,you,997); //hand palm base: Vector # 987
      vec_for_vertex(temp2.x,you,968); //hand palm tip: Vector # 982
      vec_set(my.x,temp.x);
      vec_diff(temp.x,temp2.x,temp.x);
      vec_to_angle(my.pan,temp.x); // ERROR "'pan' is not a member of 'VECTOR'
      vec_set(my.pan,my.pan);
 
      wait(1);
   }
}

...


Code:
// inventory.c

...

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;

...

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_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_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;	
}

...



When I compile OrcStronghold.c , it does not produce any syntax errors, but when I access my inventory bag and drag a sword image ("steel_sword.pcx") over to the active weapon slot, and get out of the inventory bag, my player is not being armed with the sword.

Does anyone know what I may be doing wrong in trying to make this happen?

Last edited by Ruben; 01/01/14 20:34.
Re: Access variable from other program? [Re: Ruben] #435014
01/01/14 21:07
01/01/14 21:07
Joined: Nov 2006
Posts: 497
Ohio
xbox Offline
Senior Member
xbox  Offline
Senior Member

Joined: Nov 2006
Posts: 497
Ohio
where is the code showing what happens when you drag the sword to the active slot?

From the above code, I see that you have the active weapon slot set with what I assume to be just an empty square to represent an inventory space. I think what you need to do via code is set
Code:
inv_slots[0] = item_sword;


For some reason though, I feel like the visual inventory will get messed up by overwriting the inventory to the sword, although the sword should be created.

Re: Access variable from other program? [Re: xbox] #435018
01/01/14 21:26
01/01/14 21:26
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
There seems to be a lot going on with the code that drags the sword to the active slot, which I don't even fully understand. Here is the entire open source inventory.c script that I am using:

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 -----------------------------------
 
 
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;  

}
 
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)
{

	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_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);		
}

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

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;
	
}

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;
				}
				/*
				else // ADDED BY RUBEN
				if(bag->slots[i]->group_id == 1)
				{
					bag->slots[i]->item = item;				
					bag->slots[i]->slot_panel->bmap = bmap_create(item->inventory_icon);
					return 1;
				}
				// END OF ADDED BY RUBEN
				*/
			}
		}
	}
	
	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");
	
}


// ------------- 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;
	
}



I don't know if you can find it in there. I will look myself and see if I myself can find it.

Last edited by Ruben; 01/01/14 21:28.
Re: Access variable from other program? [Re: Ruben] #435025
01/01/14 21:42
01/01/14 21:42
Joined: Nov 2006
Posts: 497
Ohio
xbox Offline
Senior Member
xbox  Offline
Senior Member

Joined: Nov 2006
Posts: 497
Ohio
I believe the part you're looking for is at the end of the function slotOnClick.

This seems to be were the item being dragged is being set to the slot in the inventory. So you need to check if the sword is placed in a specific slot.

I need to leave for work right now so I'll help more tomorrow.

EDIT: In your if statement where you are doing the strcmp instead of doing inv_slots[0].floating_icon try inv_slots[0]->floating_icon

Last edited by xbox; 01/02/14 05:17.
Re: Access variable from other program? [Re: xbox] #435028
01/02/14 06:28
01/02/14 06:28
Joined: Jun 2010
Posts: 590
California
Ruben Offline OP
User
Ruben  Offline OP
User

Joined: Jun 2010
Posts: 590
California
Well, I put this in the beginning of OrcStronghold.c :

Code:
Item* inv_slots[13];
inv_slots = new(Item);

ENTITY* active_sword;



I also changed the string comparison if statement in my main function (inside OrcStronghold.c) to:

Code:
if(str_cmp(inv_slots[0]->floating_icon, "steel_sword.pcx"))
   {
        active_sword = ent_create ("sword.mdl", my.x, attach_weapon);
   }
   else
   {
        ent_remove(active_sword);
   }



...and I am still getting the same results. I am able to place a .pcx image of a sword in the active weapon slot of my inventory bag, but it is not arming my player with a sword attached to its hand as a result.

Re: Access variable from other program? [Re: Ruben] #435030
01/02/14 07:36
01/02/14 07:36
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,
I guess you have to use the module callbacks that are built for these cases. If you define and register the slot callback function it should be called when you click/drop on a slot.

Code:
// bags
#define MAIN_BAG_ID        1
#define TRADER01_BAG_ID    2
// slots
#define WEAPON_SLOT_ID     1
// groups
#define WEAPON_GROUP       1
// items
#define SWORD01_ID         101
#define SWORD02_ID         102
#define HAMMER01_ID        201
#define HAMMER02_ID        202


function fncMyCallback ( int action, int bag_id, int slot_id, int placed_item_id, int removed_item_id )
{
	if ( bag_id == MAIN_BAG_ID )
	{
		if ( slot_id == WEAPON_SLOT_ID )
		{
			if ( removed_item_id != 0 )
			{
				// Remove the old weapon model
			}
			
			if ( ( placed_item >= SWORD01_ID ) && ( placed_item < HAMMER01_ID ) )
			{
				// Create the new sword model
			}
		}
	}
}

function main ()
{
	Bag *bag = inv_create_bag ( MAIN_BAG_ID, "leather_seam.pcx" );
	Slot *slot = inv_add_slot_to_bag ( bag, WEAPON_SLOT_ID, WEAPON_GROUP, "leather_texture.pcx", 9, 60 ); // Active Weapon slot
	Item *item_sword01 = inv_create_item ( SWORD01_ID, WEAPON_GROUP, "steel_sword.pcx", "steel_sword.pcx" );
	
	set_on_click_callback ( "fncMyCallback" );
}


Page 3 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