ga_take_item takes too many items when it's a stack
#1
Posté 03 décembre 2013 - 12:17
Does anyone know why this happens or how to fix it?
#2
Posté 03 décembre 2013 - 12:29
#3
Posté 03 décembre 2013 - 12:54
#4
Posté 03 décembre 2013 - 01:04
I'll see if I can dig it up somewhere. I'm at work at the moment, but I've always got a USB stick on me with my in-progress modules backed up. Often I can copy a script straight from the MOD file using UltraEdit (which quite helpfully converts the binary info into plain text).
#5
Posté 03 décembre 2013 - 01:08
// ga_destroy_item2
/*
This takes an item from a player
sItemTag = This is the string name of the item's tag
nQuantity = The number of items to destroy. -1 is all of the Player's items of that tag.
*/
#include "nw_i0_plot"
void DestroyItems(object oTarget,string sItem,int nNumItems)
{
int nCount = 0;
object oItem = GetFirstItemInInventory(oTarget);
while (GetIsObjectValid(oItem) == TRUE && nCount < nNumItems)
{
if (GetTag(oItem) == sItem)
{
int nRemainingToDestroy = nNumItems - nCount;
int nStackSize = GetItemStackSize(oItem);
if(nStackSize <= nRemainingToDestroy)
{
DestroyObject(oItem,0.1f);
nCount += nStackSize;
}
else
{
int nNewStackSize = nStackSize - nRemainingToDestroy;
SetItemStackSize(oItem, nNewStackSize);
break;
}
}
oItem = GetNextItemInInventory(oTarget);
}
return;
}
void main(string sItemTag,int nQuantity)
{
int nTotalItem;
object oPC = GetPCSpeaker();
object oItem; // Items in inventory
if ( nQuantity < 0 ) // Destroy all instances of the item
{
nTotalItem = GetNumItems( oPC,sItemTag );
DestroyItems( oPC,sItemTag,nTotalItem );
}
else
{
DestroyItems( oPC,sItemTag,nQuantity );
}
}
#6
Posté 03 décembre 2013 - 01:46
If you take an item and reward the player during the take action (give them gold, xp or whatever), then the player can loop the reward via pickpocketing the item and turning it in repeatedly. This was a bug source in Path of Evil that I hadn't considered until people reported doing it.ColorsFade wrote...
Well, either would work. Destroying might be better. I take it that it matters?
Alternately, the Uber Sword of Ultra Doom +5 that you gave the player temporarily for a specific quest, and then take the sword from them when they turn in the quest for reward, is still pickpocketable for the player to get the item again for general use outside the specific quest. While it's possibly realistic they could steal the sword back, you probably don't want that to be a possibility.
So now I destroy items I intend the player to no longer be able to get.
#7
Posté 03 décembre 2013 - 02:13
kamal_ wrote...
This was a bug source in Path of Evil that I hadn't considered until people reported doing it.
Even in elder scrolls these bugs exist. I remember in oblivion I could turn the quest for the vampirism treatment over and over agian to get the gold.
I guess none can ever predict all these.
But it's good to know that it happens with the ga_take_item. Does it happen if the item is even non pickpocketable?
#8
Posté 03 décembre 2013 - 03:33
I have plans to use the global unacquire event to decrement the journal stage if the player drops or sells the item, to avoid the incongruity of the questgiver happily giving the reward to a player that dropped the item. But even without doing that, it avoids the infinite turn-in problem.
#9
Posté 03 décembre 2013 - 03:45
Even if the speaker who initates the conversation actually has the item, in a 'party chat' conversation there's no guarantee they'll still be the speaker for the node it gets taken from.
I created my own GA_ script that removes a specified number of items from the party, regardless of how many each party member has. It loops through each inventory, removing as many of the items as it finds if the number is less than the specified number to take, then searches the next party member's inventory for the remainder until the right number of items has been taken. So if you want to take 10 items from the party, and they're split across several party members (one has 3, another has 2, another has 12, etc), the script takes three from the first inventory, 2 from the next, and only five from the next.
You can see the script in all its elegant beauty here.
Modifié par DannJ, 03 décembre 2013 - 04:17 .
#10
Posté 03 décembre 2013 - 04:31
Also, have you ever found any trouble caused by a PC having the quest items in an inventory slot with several empty slots in front of it? It seems like some methods stop when they reach a gap like that.
#11
Posté 03 décembre 2013 - 07:37
Tchos wrote...
That script sounds ideal. Does it also work if one of the PCs has more than one stack, both of which are fewer than the required number, and the rest are on other PCs? Say, the quest requires 10 items, and PC 1 had 6, but split into 2 stacks of 3, and PC 2 had 4 more.
Also, have you ever found any trouble caused by a PC having the quest items in an inventory slot with several empty slots in front of it? It seems like some methods stop when they reach a gap like that.
without reading the script - i would have to say yes since the script loops through the entire inventory - such loops do not stop at the mentioned item until the entire inventory has been looped through. loopy huh
#12
Posté 03 décembre 2013 - 10:37
Tchos wrote...
That script sounds ideal. Does it also work if one of the PCs has more than one stack, both of which are fewer than the required number, and the rest are on other PCs? Say, the quest requires 10 items, and PC 1 had 6, but split into 2 stacks of 3, and PC 2 had 4 more.
Also, have you ever found any trouble caused by a PC having the quest items in an inventory slot with several empty slots in front of it? It seems like some methods stop when they reach a gap like that.
I've tested it under all sorts of conditions, including multiple stacks in one inventory, multiple stacks across multiple inventories, etc. It keeps going until it's found and destroyed the correct amount.
What you see in in the inventory interface isn't how the script sees things. The first/next loop isn't checking inventory slots, but rather inventory items. Whether the first item it encounters is in the 1st or 128th inventory slot doesn't matter - it's still the 'first' inventory item (or second, third, etc).
You need to make sure the conversation node checks you've got at least the minimum amount before making that node available. The script doesn't care if you've got less than the required amount - it just takes everything you've got.
There's no check for equipped slots either. If the items you're returning are equippable, then you'd have to have another function that loops through each party member's equipment slots and unequips the items if they match your specified tags. Loopier and loopier (to misquote Alice).
#13
Posté 04 décembre 2013 - 01:35
So, for the check, have you found the default gc_ scripts to be good enough in determining that the party has enough of the item?
#14
Posté 04 décembre 2013 - 03:50
#15
Posté 05 décembre 2013 - 03:59





Retour en haut






