Author Topic: Checking for the number of items  (Read 389 times)

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Checking for the number of items
« on: October 29, 2010, 02:19:31 am »


               Hi all,

I'd like to set up some fetch quests and I need a script that will check to make sure the player has the right number of items in their inventory.

For example: Npc tells player to go find 10 apples. The player goes out and finds 10 apples and returns to the npc. The script would check to make sure there are 10 apples, then take the apples and give the reward. I know how to script for single items using Lilac Soul's generator, but not a clue on how to check for multiple items.

Can anyone point me to such a script?

Thank you much. '<img'>
               
               

               
            

Legacy_Dagesh

  • Jr. Member
  • **
  • Posts: 55
  • Karma: +0/-0
Checking for the number of items
« Reply #1 on: October 29, 2010, 03:28:21 am »


               

void main()
{
    // our PC speaker
    object oPC = GetPCSpeaker();
    // Set the tag needed on the NPC
    string sTag = GetLocalString( OBJECT_SELF, "RETURN_TAG_OF_ITEM" );
    // Set how much we need on the NPC in the convo
    int nRequiredAmount = GetLocalInt( OBJECT_SELF, "RETURN_NUMBER_OF_ITEMS" );
    // Get the XP reward stored on the NPC
    int nXP = GetLocalInt( OBJECT_SELF, "RETURN_XP_REWARD" );
    // Get the gold reward stored on the NPC
    int nGold = GetLocalInt( OBJECT_SELF, "RETURN_GOLD_REWARD" );

    // This while loop will loop around and around until either
    // we have checked every single item in the PC's inventory
    // or until we have found that the amount of items needed
    // is found.  I added a check for stack size.  This lets you
    // use items that stack
    int nCheck = 0, nStack;
    object oItem = GetFirstItemInInventory( oPC );
    while( GetIsObjectValid( oItem ) )
    {
        if( GetTag( oItem ) == sTag )
        {// if current item has the tag we're looking for
            nStack = GetItemStackSize( oItem );
            nCheck += nStack;// same as: nCheck = nCheck + 1;
            if( nCheck >= nRequiredAmount )
            {// we have found the number we need
                // this will break us out of the loop
                break;
            }
        }
        oItem = GetNextItemInInventory( oPC );
    }

    if( nCheck >= nRequiredAmount )
    {// PC has the required number of items

        // Here we will loop around to remove the items with sTag.
        // we simply loop through the PC's inventory until
        // we have destroyed the amount to take
        // Once we've done that we leave (break) the loop
        // this also checks for stacked items
        // and removes them as needed
        oItem = GetFirstItemInInventory( oPC );
        while( GetIsObjectValid( oItem ) )
        {
            if( GetTag( oItem ) == sTag )
            {// if current item has the tag we're looking for
                nStack = GetItemStackSize( oItem );
                if( nStack > nRequiredAmount )
                {// stack has more than we need
                    // lower stack size minus what NPC takes
                    SetItemStackSize( oItem, nStack - nRequiredAmount );
                    // requirement is fulfilled
                    nRequiredAmount = 0;
                }
                else
                {// stack is not high enough
                    // destroy entire stack
                    DestroyObject (oItem);
                    // remove the stack amount from required amount
                    // so we know how much we still need
                   nRequiredAmount = nRequiredAmount - nStack;
                }
                if( nRequiredAmount <= 0 )
                {// we have found the total number we need
                    // this will break us out of the loop
                    GiveGoldToCreature( oPC, nGold );
                    GiveXPToCreature( oPC, nXP );                    break;
                }
            }
            oItem = GetNextItemInInventory( oPC );
        }
    }
    else
    {// PC does not have enough of the required items
        // You could add a line for the NPC to respond here if you wanted
    }
}


This should work for you.  It's compiled and tested just in case.  Make sure to not add it to the last node of the conversation or things won't work (GetPCSpeaker will be an invalid object because the convo is over so the script won't know who to take the items from).

edit: Tried to make the code look decent instead of the stupid mishmash this forum style gives it.  Bah.
edit again: added XP and gold reward
               
               

               


                     Modifié par Dagesh, 29 octobre 2010 - 02:45 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Checking for the number of items
« Reply #2 on: October 29, 2010, 04:27:36 am »


               Uf you include nw_io_plot  you can use. GetNumItems
also in nw_io_plot is TakeNumItems for when you want to remove the items from the PC.
               
               

               
            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Checking for the number of items
« Reply #3 on: October 29, 2010, 06:18:07 pm »


               Wow, Dagesh, that's great! Thank you so much. '<img'>

Thank you too, Lightfoot.



*hugs to all*
               
               

               
            

Legacy_Dagesh

  • Jr. Member
  • **
  • Posts: 55
  • Karma: +0/-0
Checking for the number of items
« Reply #4 on: October 29, 2010, 10:09:59 pm »


               Lightfoot, I was trying to recall those functions but for the life of me I couldn't.  Oh well, punching scripts out is always good practice.
               
               

               
            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Checking for the number of items
« Reply #5 on: October 30, 2010, 12:27:42 pm »


               Hey there, sweetie,
I seem to be doing something wrong. Maybe you can help? Here's what I did.
I made stackable apples and set it at 1.
Then in the script, where it says return tag of item, I put in "Apple"
Where it says return number of items, I put "10" because I want the player to collect 10 apples.
Where it says return xp reward, I put "50".
And where it says return gold reward, I put "20"
Just so you know, I replaced the entire return statement with the word apple or the numbers mentioned, with quotations of around it of course.
Then down where it says  int nCheck = 0, nStack; I changed the 0 to 1, since we only need one stack of 10 apples.
Then down where it says // requirement is fulfilled
                    nRequiredAmount = 0; I changed the 0 to 10 since I just want 10 apples.
Naturally the npc isnt responding like I want.
Please help...hehe. I'm hopeless. ':unsure:'


Dagesh wrote...


void main()
{
    // our PC speaker
    object oPC = GetPCSpeaker();
    // Set the tag needed on the NPC
    string sTag = GetLocalString( OBJECT_SELF, "RETURN_TAG_OF_ITEM" );
    // Set how much we need on the NPC in the convo
    int nRequiredAmount = GetLocalInt( OBJECT_SELF, "RETURN_NUMBER_OF_ITEMS" );
    // Get the XP reward stored on the NPC
    int nXP = GetLocalInt( OBJECT_SELF, "RETURN_XP_REWARD" );
    // Get the gold reward stored on the NPC
    int nGold = GetLocalInt( OBJECT_SELF, "RETURN_GOLD_REWARD" );

    // This while loop will loop around and around until either
    // we have checked every single item in the PC's inventory
    // or until we have found that the amount of items needed
    // is found.  I added a check for stack size.  This lets you
    // use items that stack
    int nCheck = 0, nStack;
    object oItem = GetFirstItemInInventory( oPC );
    while( GetIsObjectValid( oItem ) )
    {
        if( GetTag( oItem ) == sTag )
        {// if current item has the tag we're looking for
            nStack = GetItemStackSize( oItem );
            nCheck += nStack;// same as: nCheck = nCheck + 1;
            if( nCheck >= nRequiredAmount )
            {// we have found the number we need
                // this will break us out of the loop
                break;
            }
        }
        oItem = GetNextItemInInventory( oPC );
    }

    if( nCheck >= nRequiredAmount )
    {// PC has the required number of items

        // Here we will loop around to remove the items with sTag.
        // we simply loop through the PC's inventory until
        // we have destroyed the amount to take
        // Once we've done that we leave (break) the loop
        // this also checks for stacked items
        // and removes them as needed
        oItem = GetFirstItemInInventory( oPC );
        while( GetIsObjectValid( oItem ) )
        {
            if( GetTag( oItem ) == sTag )
            {// if current item has the tag we're looking for
                nStack = GetItemStackSize( oItem );
                if( nStack > nRequiredAmount )
                {// stack has more than we need
                    // lower stack size minus what NPC takes
                    SetItemStackSize( oItem, nStack - nRequiredAmount );
                    // requirement is fulfilled
                    nRequiredAmount = 0;
                }
                else
                {// stack is not high enough
                    // destroy entire stack
                    DestroyObject (oItem);
                    // remove the stack amount from required amount
                    // so we know how much we still need
                   nRequiredAmount = nRequiredAmount - nStack;
                }
                if( nRequiredAmount <= 0 )
                {// we have found the total number we need
                    // this will break us out of the loop
                    GiveGoldToCreature( oPC, nGold );
                    GiveXPToCreature( oPC, nXP );                    break;
                }
            }
            oItem = GetNextItemInInventory( oPC );
        }
    }
    else
    {// PC does not have enough of the required items
        // You could add a line for the NPC to respond here if you wanted
    }
}


This should work for you.  It's compiled and tested just in case.  Make sure to not add it to the last node of the conversation or things won't work (GetPCSpeaker will be an invalid object because the convo is over so the script won't know who to take the items from).

edit: Tried to make the code look decent instead of the stupid mishmash this forum style gives it.  Bah.
edit again: added XP and gold reward


               
               

               
            

Legacy_Dagesh

  • Jr. Member
  • **
  • Posts: 55
  • Karma: +0/-0
Checking for the number of items
« Reply #6 on: October 30, 2010, 02:29:30 pm »


               It will be easier for me to help if your code is posted but I will try to help with what I understand you are meaning.

archer4217 wrote...

Hey there, sweetie,
I seem to be doing something wrong. Maybe you can help? Here's what I did.
I made stackable apples and set it at 1.
Then in the script, where it says return tag of item, I put in "Apple"

That is fine and should not harm anything.  The reason I used those 'GetLocalInt' variables is so that you could use the same script on multiple NPCs and all you have to do is 'store' those numbers and that item tag on the NPC.  If you need help doing that I am happy to help there.

Where it says return number of items, I put "10" because I want the player to collect 10 apples.
Where it says return xp reward, I put "50".
And where it says return gold reward, I put "20"
Just so you know, I replaced the entire return statement with the word apple or the numbers mentioned, with quotations of around it of course.

All this is very good work on your part.  So far so good.

Then down where it says  int nCheck = 0, nStack; I changed the 0 to 1, since we only need one stack of 10 apples.
Then down where it says // requirement is fulfilled
                    nRequiredAmount = 0; I changed the 0 to 10 since I just want 10 apples.
Naturally the npc isnt responding like I want.

This is where you are probably having the problem.  Those variables don't need to be changed.  Think of them as internal gears that will squeeze and punch the variables you entered above.  If we change them, even a little, the whole machine will junk up.  Try changing this part back to the original numbers and retry it.

Please help...hehe. I'm hopeless. ':unsure:'

As we all are
               
               

               


                     Modifié par Dagesh, 30 octobre 2010 - 01:31 .
                     
                  


            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Checking for the number of items
« Reply #7 on: October 30, 2010, 10:17:41 pm »


               Yes, Please. I definately need help with this. '<img'>


That is fine and should not harm anything.  The reason I used those 'GetLocalInt' variables is so that you could use the same script on multiple NPCs and all you have to do is 'store' those numbers and that item tag on the NPC.  If you need help doing that I am happy to help there.



Thank you so much for your help and patience, sweetie. *hugs*
               
               

               


                     Modifié par archer4217, 30 octobre 2010 - 09:25 .
                     
                  


            

Legacy_Dagesh

  • Jr. Member
  • **
  • Posts: 55
  • Karma: +0/-0
Checking for the number of items
« Reply #8 on: October 31, 2010, 08:34:35 pm »


               There are a couple of ways to set variables on NPCs.  Think of variables like pockets you put information into.  You have to tell the system if it is an 'integer' pocket or a 'string' pocket (a string is simply a list of words that a PC sees in game like a conversation or sending messages to PCs), or a 'float' pocket (a float is a number that uses decimal points).  Not only do these "pockets" hold different types of information, they also have names.  We use these names so that the game can tell between one 'string' pocket from another one.  From here on let's call "pockets" variables.



That being said, we can place variables on NPCs a number of ways.

1) If you right click the NPC and go to properties, then under the advanced tab down at the bottom you will find a button named "variables".  Click on that and you will see a window pop up.  You  will see a field for "Name", "Type", and "Value".  Using the variables in our script we could plug one in.  Under name: "RETURN_TAG_OF_ITEM" (w/o quotes), type: "string", value: put the tag of the item (ex. apple).  Make sure to click on "Add" before clicking on "OK" or the variable will not be set.



2) In the area viewer window, where you can see the NPCs, right click on the one you want to add variables too and instead of clicking on 'Properties' click on 'Variables'.  You will see a window just like option 1).  The directions are the same.



3) You can add variables via scripting.  Though not necessary in our case, I just want you to know if can be done.  The function is either, "SetLocalInteger", "SetLocalString", or SetLocalFloat" (as well as Location and Object but that's more advanced).



For our case, set these variables on the NPC:

RETURN_TAG_OF_ITEM

-string (value is the tag of the item to return)

RETURN_NUMBER_OF_ITEMS

-integer (or int as short, value is the number you want the PC to return)

RETURN_XP_REWARD

-int (value is XP to give PC when they return the items)

RETURN_GOLD_REWARD

-int (value is gold to give PC when they return the items)
               
               

               
            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Checking for the number of items
« Reply #9 on: November 01, 2010, 04:40:10 am »


               That's great, sweetie. The npc took the 10 single apples and gave the rewards perfectly. She didn't take the stack of 10 apples though, but I won't bother using them. The singles work just fine.

Referring to variables as pockets was brilliant and made it easier to grasp the concept better than any other explanation I've been offered. Thank you so much.

So now I have another question for you. Is it possible to make a conditional script for the conversation that checks to see if the pc has 10 apples before proceeding with the rest of the convo?

I tried to do it with Lilac Soul's generator, but once again it only offers checks for 1 item and not several items.

               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Checking for the number of items
« Reply #10 on: November 01, 2010, 05:08:42 am »


               Something kinda like so archer:

#include "nw_i0_plot"
int StartingConditional()
{
object oPC = GetPCSpeaker();

if (GetNumItems(oPC, "Apples") >= 10) return TRUE;

else return FALSE;
}


Hope that helps.
               
               

               
            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Checking for the number of items
« Reply #11 on: November 01, 2010, 07:14:44 am »


               That was exactly what I needed, Ghost. Thank you so very much! *hugs*