first script.
Looks good. but you can safly remove the include for nw_io_plot it is just not used or needed.
second script.
Line: #include nw_I0_plot.
this is only used for a wrapper around a standerd function. I would just get ride of the include and use the standard function. The function being TakeGold. Not an error just a prefferance.
Line: object oItem = GetItemPossessedBy(oPC, sItemTagName);
oItem is not used anywhere in the script just get ride of this line.
Line: object oTarget = oPC;
oTarget is only used in one place in the script. It would be better to just use oPC the creating a whole new var for oTarget. however since the only place it is used is in an assigncommand, for a function that does not need to be assigned, just get rid of the line and the assignedcammand lower down in the script..
Line; DestroyNumItems(oPC, sItemTagName, nRequired);
This function is flawed. leave it as is. the function will need to be fixed in the include however.(script3)
Line: AssignCommand(oTarget, TakeGold(nGoldRequired, oPC, TRUE));
This is where the unneeded assignedcommand and wrapper function are, changing the line to :
TakeGoldFromCreature(nGoldRequired, oPC, TRUE);
allows us to get rid of the two lines mentioned above.
Line: DelayCommand(0.5,ExportSingleCharacter(oPC));
Now this is an interresting one. First I do not see anyreason to export the character without also updating the DB if you are also storing shard information in the DB. Doing so just risks getting the DB and character out os sink in the event of a server crash. but that is not the real problem here. This export of the PC at a 0.5 delay risks saving the character in a state out of sink with itsself. The DestroyNumItems function above destroys stacks of items at an incremental delay of 0.3 seconds. So if it ever destroys more then one stack on the PC, they will be saved at a time when there inventory is out of sink. I would suggest just removing the line.
Line: CreateItemOnObject(sItemResRef, oPC, nGivenTotal);
Here the problem is that CreateItemOnObject can only create one stack. If nGivenTotal is ever greater then the Max Stack Size for the item, It will simply not give the PC the number of item requested. To fix this you need to check if the Max stack size is greater then the number of items you where trying to create. If it was not create some more.
Here is the second script with the fixes in it.
//-----------------------------------------------
// Script Name = ??
//Required Includes DONT TOUCH
#include "item_conv_inc"
void main()
{
// ***SETTINGS***
//Set this to the # of the Item they must have
int nRequired = 2;
//Set this to 0 if they DO NOT require gold
int nGoldRequired = 100000; //Amount of gold they need
//Set the tagname of the item they must have to get the item given
string sItemTagName = "tagname";
string sName = "Name of Item Goes Here";
//Set this to the resref of the item they will recieve (if qualified)
//this is NOT the tagname!
string sItemResRef = "resref";
//Set this to the # of the item you wish to give
//(If the item given is stackable it will be stacked!)
int nGivenTotal = 1; //Default = 1; (Give only one by default)
/////////////////////////////////////////////////////////////////
//WARNING: Don't Alter Anything below!!!
/////////////////////////////////////////////////////////////////
object oPC = GetPCSpeaker();
int nStackSize;
int nCount = GetIemCount(oPC, sItemTagName);
//This part will prevent exploits (like dropping gold to prevent losing it etc)
if(nCount < nRequired)
{
FloatingTextStringOnCreature("You must have " +
IntToString(nRequired) + sName +"!", oPC, FALSE);
return;
}
if(GetGold(oPC) < nGoldRequired)
{
FloatingTextStringOnCreature("You don't have " +
IntToString(nGoldRequired) + " gold on you!", oPC, FALSE);
return;
}
//Obviously we are continuing if they have enough shards..
//Take 2 of them from the PC
DestroyNumItems(oPC, sItemTagName, nRequired);
//take gold
TakeGoldFromCreature(nGoldRequired, oPC, TRUE);
//Give the PC X of the item to be given
object oItem;
int nMaxStack;
do
{
oItem = CreateItemOnObject(sItemResRef, oPC,nGivenTotal);
// if nMaxStack is 0 we need to get is value.
if(!nMaxStack) nMaxStack = StringToInt(Get2DAString("baseitems","Stacking",GetBaseItemType(oItem))); nGivenTotal-= nMaxStack;
// if nGiveTotal is postive we still need to give some items.
}while (nGivenTotal>0);
//End main script
}
This just leaves the include file to fix. ( and no Guile your fix did not take care of the problem.
Ok the DestroyNumItems as it is currently written with the fix. is finding the item with the correct tag and checking to see if the stack size is equal to or greater then then number to destroy if it is it decreasses the stack size by the number to destroy and breaking the loop. First problem with this Idea is that you can not set a stack size to 0 or below. if you try to it just defaults to 1. So if the PC only had a stack of two on him and you are trying to destroy two items. It would try to set the stack size to 0 and only succeed in setting it to 1, Declair that both items where destroyed and break the loop. Now lets assume that you are trying to destroy 3 items and the PC has split the stack of the 4 shards he has into two stacks of two. when the inventory search comes to the first stack of two and compairs the stack size it is not greater or equal to the number to destroy so it will skip right past that section. the stack size is also not equal to one, so it will skip right past that section also and continue on searching for the next item doing nothing to this stack. When it finds the secong stack It will do the same nothing. So no Items will be destroyed.
Here is the fix for your include script.
//-------------------------------------------------------------------------------------------------
// Include Script Name = item_conv_inc (Save it Under THIS Name!)
// This is an include script, it's saved under the name (item_conv_inc)
// This script has 2 Custom Fucntions which...
// a) Return How many of a particular item the PC Has (GetItemCount)
// Destroys X of a given item by tagname, (can reduce Item StackSize)
//////////////////////////////////////////////////////////////////////////////
//Declare All Prototypes
int GetIemCount(object oPC, string sTag);
void DestroyNumItems(object oTarget, string sTag, int nToDestroy = 2);
////////////////////////////////////////////////////////////////////////////
//Prototypes Defined
//Define Prototype
int GetIemCount(object oPC, string sTag)
{
int i = 0;
string sIT;
int nStackSize;
object oItem = GetFirstItemInInventory(oPC);
//Continue till there are 0 left to destroy...
while (GetIsObjectValid(oItem))
{
sIT = GetTag(oItem);
if (sIT == sTag)
{
nStackSize = GetItemStackSize(oItem);
i += nStackSize;
}
oItem = GetNextItemInInventory(oPC);
}
//Tell the script how many "shards" they have (included all stacked count)
return i;
}
//Define Prototype
void DestroyNumItems(object oTarget, string sTag, int nToDestroy = 2)
{
float fDelay;
int nStackSize;
int nAdj;
string sIT; // Item Tagname
object oItem = GetFirstItemInInventory(oTarget);
//Continue till there are 0 left to destroy...
while (GetIsObjectValid(oItem) && nToDestroy >= 1)
{
sIT = GetTag(oItem);
nStackSize = GetItemStackSize(oItem);
//If they have 2 Shards & This is indeed a Shard (item)
if (sIT == sTag) //Obviously they have at least 1 stack size
{
fDelay += 0.03;
if(nStackSize <= nToDestroy)
{
DestroyObject(oItem, fDelay);
nToDestroy -= nStackSize;
if(!nToDestroy) break;
}
else
{
SetItemStackSize(oItem,nStackSize - nToDestroy);
break;
}
}
oItem = GetNextItemInInventory(oTarget);
}
}
Modifié par Lightfoot8, 03 septembre 2011 - 11:24 .