Aller au contenu

Photo

Limited Inventory / Bags


  • Veuillez vous connecter pour répondre
9 réponses à ce sujet

#1
Deus of the Apocalypse

Deus of the Apocalypse
  • Members
  • 12 messages
Ok, so I've posted something like this before... but this time I've tried my d*amned'ist to come up with a script myself before resorting to the forums.

After spending all night, (literally), trying to get all of the aspects of what I'm trying to do into one script, something still seems off. I've been working on learning C++ script more & more, & have the gist of reading it fairly well, (i.e. I can understand how scripts function by looking at other ppl's work), but cannot, for the life of me, remember what some of the functions or "symbols" (i.e. &&, etc.) do.

With that being said, here's what I've got so far......
// ****************************************************************************
// ** CONFIGURATION
// ****************************************************************************

// Prevent a PC from storing too many items, etc.
int MBS_Inv_Limit(object oPC, int iCount, object oItem)
{
{
		// Limit this bag to 8 Inventory Slots.
		if(iCount > 8)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
{
		// Limit this bag to 12 Inventory Slots.
		if(iCount > 12)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 16 Inventory Slots.
		// This bag type is used as a small Profession bag:
		// Use "Force Into Preferred Container" for item type.
		if(iCount > 16)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 20 Inventory Slots.
		if(iCount > 20)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 24 Inventory Slots.
		if(iCount > 24)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 32 Inventory Slots.
		// This bag type is also used as a large Profession bag:
		// Use "Force Into Preferred Container" for item type.
		if(iCount > 32)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 36 Inventory Slots.
		if(iCount > 36)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 40 Inventory Slots.
		if(iCount > 40)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 48 Inventory Slots.
		if(iCount > 48)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 56 Inventory Slots.
		if(iCount > 56)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
		{
  
		// Limit this bag to 64 Inventory Slots.
		if(iCount > 64)
			{
			SendMessageToPC(oPC, "You have reached your storage limit.");
			return FALSE;
			}
		}
		
    return TRUE;
}

// ****************************************************************************
// ** CONSTANTS (do not modify)
// ****************************************************************************

// Track of the number of items stored.
const string MBS_COUNT = "MBSCount";

// ****************************************************************************
// ** MAIN (do not modify)
// ****************************************************************************

void main()
{
	// Declare Variables
	string sBag;
	object oPC = GetLastUsedBy();
	string sPC = GetName(oPC);
	object oBag = GetObjectByTag("mbs_bag");
	object oItem = GetInventoryDisturbItem();
	int iType = GetInventoryDisturbType();
    int iCount = GetLocalInt(oBag, MBS_COUNT);
	
	sBag = GetLocalString(oBag,"mbs_slot");
    if (iType == INVENTORY_DISTURB_TYPE_ADDED)
    {
		// We don't care if the stack size isn't at 50,000 (or the default gold
		// stack size), because a custom coin system is being used.
		// Instead, the max. item stack in our world is used.
		// This may be changed to suit one's own needs.
        if (GetItemStackSize(oItem) > 250)
        {
            DelayCommand(0.3, AssignCommand(OBJECT_SELF, ActionGiveItem(oItem, oPC)));
            SendMessageToPC(oPC, "Items must be broken into separate, 250 count stacks.");
        }
        // We will NOT accept ANY item with an inventory, to prevent exploits.
        if (GetHasInventory(oItem))
        {
            DelayCommand(0.3, AssignCommand(OBJECT_SELF, ActionGiveItem(oItem, oPC)));
            // Warn the player that containers cannot be stored in these bags.
			SendMessageToPC(oPC, "You cannot store containers within bags.");
			// Warn all DMs that a player has tried to exploit the bag system.
			SendMessageToAllDMs("Warning:" +sPC+ "tried to put a container into a bag.");
            return;
        }
        if(!MBS_Inv_Limit(oPC, iCount, oItem))
        {
            // Delay to check for a valid item before transferring to the PC.
            DelayCommand(0.3, AssignCommand(OBJECT_SELF, ActionGiveItem(oItem, oPC)));
            return;
        }
        // The inventory items are added to:
        iCount++;
        SetLocalInt(OBJECT_SELF, MBS_COUNT, iCount);
    }
    else if (iType == INVENTORY_DISTURB_TYPE_REMOVED)
    {
        // The inventory items are removed from:
        iCount--;
        SetLocalInt(OBJECT_SELF, MBS_COUNT, iCount);
    }
    
}

If you haven't guessed from my sh!tty-ass work, I'm trying to associate a with an specific item's "property variable".
i.e. (in the variable properties of an item)
StrName = mbs_bag
int = 8 // or whatever limit I want to put on that bag's inventory space / slots

It compiles just fine, but (of-course) doesn't work like I thought it would.

Any suggestions would be great, but I'd REALLY appreciate a rewrite with comments beside each line / function, explaining how / why it works the way it does, (if someone is willing to go that far).

MUCH Appreciated,
-DotA

P.S. Sorry this post is so long, but the BBCodes (for posting script) I knew in the previous forum don't seem to work here, & I can't seem to find any information as to what codes DO work.

Modifié par Deus of the Apocalypse, 30 août 2010 - 01:00 .


#2
diophant

diophant
  • Members
  • 116 messages
The problem is that the engine cannot decide which of the inner blocks in MBS_Inv_Limit should be used. So it starts with the first. If there are more than 8 objects, FALSE will be returned. Otherwise, all other checks will be performed, and of course none of them fails -> I guess all your bags were reduced to a capacity of 8.

I think it is better to set the capacity as a local integer on the bag. Your check now simply becomes

[nwscript]

// Prevent a PC from storing too many items, etc.

int MBS_Inv_Limit(object oPC, int iCount, object oItem)

{

// compare the actual item count with the maximal allowed item count

// (stored in the local int iMaxCount)

if(iCount > GetLocalInt(OBJECT_SELF, "iMaxCount")

{

SendMessageToPC(oPC, "You have reached your storage limit.");

return FALSE;

}

return TRUE;

}

[/nwscript]

The second problem is that giving back the item will also fire the inventory disturbed item, which decreases iCount. I.e., if there are already 8 items in the bag (which is the limit), and you add another one, your script fires, MBS_Inv_Limit returns FALSE, and iCount remains unchanged. Then, the bag returns the item to the player, and iCount is reduced to 7. Thus, you have to move the iCount++ statement directly at the beginning of the "if (iType == INVENTORY_DISTURB_TYPE_ADDED)" block.






#3
Deus of the Apocalypse

Deus of the Apocalypse
  • Members
  • 12 messages
I changed it around, it compiles, but I'm still having the same problem, (or maybe I'm just not writing the script the way I expect it to work in the game).

Currently, I have 2 bags in my test module, & I have everything configured as such:
Display Name = 8 Slot Bag
Tag = mbs_bag
Blueprint = mbs_bag8
Variable = mbs_slot // Int // Value = 8

Display Name = 12 Slot Bag
Tag = mbs_bag
Blueprint = mbs_bag12
Variable = mbs_slot // Int // Value = 12

The script is not loaded into OnAcquire, or any other module script, but is an "idle" script, (as I am assuming that the way I have it written will automatically look for an item with the tag of "mbs_bag", & a string of "mbs_slot" attached to it... followed by the int, which represents it's capacity).

Am I missing anything here?

-DotA

Modifié par Deus of the Apocalypse, 30 août 2010 - 11:42 .


#4
diophant

diophant
  • Members
  • 116 messages
I'm not sure if I understand correctly, but it seems to me as if your script doesn't fire at all. To check this, you can send a debug message to the PC at the beginning of the script, which should be visible on the console:

SendMessageToPC(GetFirstPC(), "script started");



Put the script in the onInventoryDisturbed slot of the bag, then it should fire.

#5
Deus of the Apocalypse

Deus of the Apocalypse
  • Members
  • 12 messages
Ok... so it's not working at all (still)... not firing. I've tried every possible script combination & have placed it in every module property "script slot / drop-down menu" (that made sense, i.e. OnAcquire vs. OnChat).

And btw Diophant, this script can't be placed in an OnDisturbed slot, because it's a bag ITEM type (that PC's can pick up), not a placeable. That's why I have got to come up with a way to get this script (or a similar one) look for a INT (representing the max capacity), on a STR that's attached to the variables of the bag ITEM. Variables are the only modifications you're allowed to change on an item, (unlike ALL the scripts you can attach to other things), unfortunately.

Here's the modified script I tried to write :

[nwscript]

// ****************************************************************************
// ** CONFIGURATION
// ****************************************************************************

// Prevent a PC from storing too many items, etc.

int MBS_Inv_Limit(object oPC, int iCount, object oItem)

{
    {
    // Compare the actual item count with the maximal allowed item count
    // (stored in the local int iMaxCount)
    if(iCount > GetLocalInt(OBJECT_SELF, "iMaxCount"))
        {
        SendMessageToPC(oPC, "You have reached your storage limit.");
        return FALSE;
        }
    }

return TRUE;

}

// ****************************************************************************
// ** CONSTANTS (do not modify)
// ****************************************************************************

// Track of the number of items stored.
const string MBS_COUNT = "MBSCount";

// ****************************************************************************
// ** MAIN (do not modify)
// ****************************************************************************

void main()
{
    // Declare Variables
    object oPC = GetLastDisturbed();
    string sPC = GetName(oPC);
    object oBag = GetObjectByTag("mbs_bag");
    object oItem = GetInventoryDisturbItem();
    int iType = GetInventoryDisturbType();
    int iCount = GetLocalInt(oBag, MBS_COUNT);
   
   
    if (iType == INVENTORY_DISTURB_TYPE_ADDED)
    {
        // The inventory items are added to:
        iCount++;
        SetLocalInt(oBag, MBS_COUNT, iCount);
       
        // We don't care if the stack size isn't at 50,000 (or the default gold
        // stack size), because a custom coin system is being used.
        // Instead, the max. item stack in our world is used.
        // This may be changed to suit one's own needs.
        if (GetItemStackSize(oItem) > 250)
        {
            DelayCommand(0.3, AssignCommand(oBag, ActionGiveItem(oItem, oPC)));
            SendMessageToPC(oPC, "Items must be broken into separate, 250 count stacks.");
        }
        // We will NOT accept ANY item with an inventory, to prevent exploits.
        if (GetHasInventory(oItem))
        {
            DelayCommand(0.3, AssignCommand(oBag, ActionGiveItem(oItem, oPC)));
            // Warn the player that containers cannot be stored in these bags.
            SendMessageToPC(oPC, "You cannot store containers within bags.");
            // Warn all DMs that a player has tried to exploit the bag system.
            SendMessageToAllDMs("Warning:" +sPC+ "tried to put a container into a bag.");
            return;
        }
        if(!MBS_Inv_Limit(oPC, iCount, oItem))
        {
            // Delay to check for a valid item before transferring to the PC.
            DelayCommand(0.3, AssignCommand(oBag, ActionGiveItem(oItem, oPC)));
            return;
        }
       
    }
    else if (iType == INVENTORY_DISTURB_TYPE_REMOVED)
    {
        // The inventory items are removed from:
        iCount--;
        SetLocalInt(oBag, MBS_COUNT, iCount);
    }
   
}
[/nwscript]

Modifié par Deus of the Apocalypse, 01 septembre 2010 - 07:54 .


#6
Deus of the Apocalypse

Deus of the Apocalypse
  • Members
  • 12 messages
As you can see from the above, I tried to get the script to focus directly on the item & item tag (to find the STR & INT), but it still won't work right.

Again, I am still trying to learn C++ script, & tho I can read / understand what someone else writes, I just don't have enough knowledge / understanding of ALL the functions to know rather what I have written will work the way I want it to. I know what I'm trying to accomplish is possible, (I've seen others do similar things, as far as making scripts count items, etc.). I just can't figure out why / what this script isn't firing / working.

Instruct me in the ways of my errors, PLEASE :-P, (I REALLY am trying to learn),

-DotA

#7
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
(According to Script Assist) GetInventoryDisturbType() function "will only work for creatures and placeables" (so not items). That's probably where the trouble is here.

Don't have anything to offer beyond that right now, I'll see if I can come up with something if I find the time, but no promises.

I suggest you make a very simple script that only returns a Float/SpeakString on the PC and figure out which script event you need to use.

Modifié par _Knightmare_, 01 septembre 2010 - 10:16 .


#8
Deus of the Apocalypse

Deus of the Apocalypse
  • Members
  • 12 messages
Hold da phone...... I think I just figured something out about this problem......

I've been doing a LOT of research on the matter & may have figured out how to do this. Let me do a little more research & experimenting, then I'll get back to you guys if it works out like I hope (think) it will.

I'll post my results in a new topic, (as this one may expire by the time I get it worked out, lol).

-DotA

#9
rjshae

rjshae
  • Members
  • 4 485 messages
Kind of a weird idea, but you could have a null item that has no weight or value, an inverted blank appearance (like a raised button) and can't be removed, then fill up the container with as many of those as you need to limit the capacity.

Modifié par rjshae, 02 septembre 2010 - 09:20 .


#10
Deus of the Apocalypse

Deus of the Apocalypse
  • Members
  • 12 messages
Not a bad idea, except I'm trying to keep the resources "used" to a minimum. I would think if you had (say) 139 "null items" filling a "bag" (that would normally have a limit of 147 slots), making it an 8-slot bag, it would cause the resources & DB R/W to go through the roof, (especially, with multiple bags being used by multiple players).

At the moment, I'm trying to write a script that will work with the "natural UI" of inventories, so that minimal resources have to be used, to accomplish the same thing, (i.e., only 1 script w/ different UI's for each bag-type).

-DotA

Modifié par Deus of the Apocalypse, 03 septembre 2010 - 03:44 .