Author Topic: How do you make an NPC take only ONE potion?  (Read 621 times)

Legacy_LostChangeling

  • Newbie
  • *
  • Posts: 49
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« on: March 23, 2015, 07:19:05 pm »


               

Hi, everyone. New here. Been working on a module for Neverwinter Nights (absolutely wonderful game). '<img'> There's just a problem I've run into.


 


I'm trying to make an NPC take a certain potion from my player at a certain point in the game. Now as you know potions are stackable items, meaning you can have a batch of say up to 10 of the same potion grouped together in the same space in your inventory. This seems to lead to an interesting problem: during the game the NPC grabs all of the potions I have in the same batch, as if treating the entire batch as one single thing, rather than just deduct 1 from the batch. So if I have 3 bottles of ale at first -- all grouped together in one batch -- I'm not left with 2 but 0. This sort of thing didn't happen with non-stackable items.


 


Question: how do you script the thing so that the NPC will take only one potion, leaving you with still 2? Tried searching online for some tutorial or hints; no luck. Any help will be greatly appreciated, thanks!



               
               

               
            

Legacy_kalbaern

  • Hero Member
  • *****
  • Posts: 1531
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #1 on: March 24, 2015, 01:59:13 am »


               

Post your current script and one of us can easily modify it for you.



               
               

               
            

Legacy_LostChangeling

  • Newbie
  • *
  • Posts: 49
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #2 on: March 24, 2015, 08:01:28 am »


               

Thanks. Here's the script. Basically I'm just trying to make an NPC take a bottle of ale from the player and give him/her a healing potion in return.


 


I usually watch my spelling very carefully, by the way.  '<img'>


 


void main()

{

    // Give the speaker the items

    CreateItemOnObject("nw_it_mpotion003", GetPCSpeaker(), 1);

 

 

    // Remove items from the player's inventory

    object oItemToTake;

    oItemToTake = GetItemPossessedBy(GetPCSpeaker(), "NW_IT_MPOTION021");

    if(GetIsObjectValid(oItemToTake) != 0)

        DestroyObject(oItemToTake);

}


               
               

               
            

Legacy_MagicalMaster

  • Hero Member
  • *****
  • Posts: 2712
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #3 on: March 24, 2015, 08:58:17 am »


               

You can't destroy the object since that includes every item in the stack.  You'll need to adjust the stack size instead (unless, say, the stack size was 1 to start...).  See if you can figure it out from there -- if not, we can help fix it.



               
               

               
            

Legacy_LostChangeling

  • Newbie
  • *
  • Posts: 49
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #4 on: March 24, 2015, 11:07:01 am »


               

Ah, HA!  '<img'>


 


I believe then that what I need to do is: (1) get the current stack size; (2) subtract 1 from it; and (3) make the result the new stack size. Presumably the code would be something like this:


 


SetItemStackSize(object oItemToTake, ((GetItemStackSize(object oItemToTake)) - 1));


 


Substituted the last line in my script above (the one in blue) with this line (the one in red) and then tried compiling it; the toolset returned 'Error: Unknown state in compiler'. What gives? I've very little grasp of the syntax of the language actually; the script in blue was created with the script wizard. Help, please? Thanks!



               
               

               
            

Legacy_Fester Pot

  • Hero Member
  • *****
  • Posts: 1698
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #5 on: March 24, 2015, 12:01:33 pm »


               

Well, you've already defined oItemToTake as an object, so it's just in name that's required.


 


SetItemStackSize(oItemToTake, (GetItemStackSize(oItemToTake)) - 1);


 


FP!



               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #6 on: March 24, 2015, 01:42:43 pm »


               
void TakeNumItemsFromPC(object oPC, string sRef, int nNmb)

{

   int nDeleted, nItemStack;

   object oItem = GetFirstItemInInventory(oPC);

   while(GetIsObjectValid(oItem) && nDeleted < nNmb)

   {

      if(GetResRef(oItem) == sRef)

      {

         nItemStack = GetItemStackSize(oItem);

         if(nItemStack <= (nNmb-nDeleted))

         {

            nDeleted += nItemStack;

            DestroyObject(oItem);

         }

         else

         {

            SetItemStackSize(oItem, nItemStack-(nNmb-nDeleted));

            nDeleted += (nNmb-nDeleted);

         }

      }

      oItem = GetNextItemInInventory(oPC);

   }

}

 

 

Modify the function accordingly if you prefer using the tag instead of the resref.

 

 

Kato


               
               

               
            

Legacy_LostChangeling

  • Newbie
  • *
  • Posts: 49
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #7 on: March 24, 2015, 05:29:01 pm »


               

Thanks, Kato! This may well prove helpful!


 


I actually tried Fester Pot's correction of my piece of script. This time it compiled properly. And guess what: in the game the stack does get reduced in size as I wanted it to, but if my player has only one bottle of ale, the number stops getting reduced! Apparently any stack must have at least a value of 1, so if you want to simulate the last bottle of ale being taken away you can no longer use SetItemStackSize, but must use DestroyObject. (I initially thought that when the stack size is reduced to 0, then the item is automatically 'destroyed'.) Ah, well, more correction work for me...


 


Well, at least progress is now being made. Thanks so much, you fellas rock!  '<img'>



               
               

               
            

Legacy_MagicalMaster

  • Hero Member
  • *****
  • Posts: 2712
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #8 on: March 24, 2015, 06:48:57 pm »


               


Apparently any stack must have at least a value of 1, so if you want to simulate the last bottle of ale being taken away you can no longer use SetItemStackSize, but must use DestroyObject.




 


Correct, hence my earlier hint of


 




(unless, say, the stack size was 1 to start...)




 


Kato's script is designed to work across multiple stacks of items if needed, hence the loop and some of the other stuff.  I'm assuming it works correctly as it looks about right.



               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
How do you make an NPC take only ONE potion?
« Reply #9 on: March 25, 2015, 05:23:59 am »


               

All true you guys, sorry that I misread the exact concept sought after...