Author Topic: Create Stack of Darts, Bolts, or Arrows ** ok **  (Read 482 times)

Legacy_Supreme_Pizza

  • Jr. Member
  • **
  • Posts: 90
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« on: January 29, 2013, 12:27:22 am »


               I know for a fact that I am not the first person to have issues with stacked items.

I've tried this script and it didn't work. So I installed NWNX_Fixes and still no luck.

FYI the script works for non stackable items.

I will post the relevant functions in the following posts.
               
               

               


                     Modifié par Supreme_Pizza, 03 février 2013 - 08:53 .
                     
                  


            

Legacy_Supreme_Pizza

  • Jr. Member
  • **
  • Posts: 90
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #1 on: January 29, 2013, 12:28:12 am »


               /////////////////////////////////////////////////////
// ATS_GetResRefFromTag                            //
//      Converts a tag into a resref assuming tag  //
//      has the same name as resref.               //
// Returns: string - ResRef                        //
/////////////////////////////////////////////////////
string ATS_GetResRefFromTag(string sTag)
{
   return GetStringLowerCase(GetStringLeft(sTag, 16));
}

/////////////////////////////////////////////////////
// ATS_CreateItemOnPlayer                          //
//      Wrapper for CreateItemOnObject() so it can //
//      be used with DelayCommand()                //
// Returns: None                                   //
//          Check local object variable:           //
//          "ats_returnvalue_created_item" for the //
//          created object                         //
// Fix courtesy of Helimar on the ATS Forums       //
/////////////////////////////////////////////////////
void ATS_CreateItemOnPlayer
(
string sItemTag,           // Tag of the item
object oPlayer,            // Player to create item on
int iStackSize = 1,        // Size of the item stack
int iDropToFloor = FALSE,   // Creates the item on the floor if inventory is full
)
{
   string sItemResRef = ATS_GetResRefFromTag(sItemTag);
   if ((GetStringRight(sItemTag,3)== "DAR") || (GetStringRight(sItemTag,3)== "dar"))
       {iStackSize = 20;}
   else if ((GetStringRight(sItemTag,3)== "BOL") || (GetStringRight(sItemTag,3)== "bol"))
       {iStackSize = 10;}
   else if ((GetStringRight(sItemTag,3)== "ARR") || (GetStringRight(sItemTag,3)== "arr"))
       {iStackSize = 10;}
   else
   {
       object oCreatedItem = CreateItemOnObject(sItemResRef, oPlayer, iStackSize);
       if(GetItemPossessor(oCreatedItem) == OBJECT_INVALID && iDropToFloor == TRUE)
       {   // stacked items do not have the possessor set correctly even if they were
           // created correctly if the new items were added to an existing partial stack
           object chk = GetObjectByTag(GetStringUpperCase(sItemTag));
           if(iStackSize==1) // if it's not we assume it's a stackable
           {
               if(GetNumStackedItems(chk)<=1)
           // check the size of the first object found by GetObjectByTag,
           // which should have more than 1 if stackable, especially since
           // 1 was just added to a partial stack in the previous create.
           // If not, assume it's a non-stackable and create it on the ground
                   oCreatedItem = CreateObject(OBJECT_TYPE_ITEM, sItemResRef, GetLocation(oPlayer));
           }
       }
       SetLocalObject(oPlayer, "ats_returnvalue_created_item", oCreatedItem);
       SetLocalObject(oCreatedItem, "ats_obj_possessor", GetItemPossessor(oCreatedItem));
       if(GetItemHasItemProperty(oCreatedItem, ITEM_PROPERTY_CAST_SPELL) == TRUE)
           SetLocalInt(oCreatedItem, "ats_charges_fix", TRUE);
   }
}
               
               

               
            

Legacy_Supreme_Pizza

  • Jr. Member
  • **
  • Posts: 90
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #2 on: January 29, 2013, 12:29:07 am »


               /////////////////////////////////////////////////////
// ATS_CreateObject                                //
//      Wrapper for CreateObject() so it can       //
//      be used with DelayCommand()                //
// Returns: None                                   //
/////////////////////////////////////////////////////
void ATS_CreateObject
(
int iObjectType,                // object type constant
string sTemplate,               // object resref
location lLocation,             // location of new object
int bUseAppearAnimation = FALSE // use animation
)
{
   object oObjectCreated = CreateObject(iObjectType, sTemplate, lLocation, bUseAppearAnimation);
   if(GetItemHasItemProperty(oObjectCreated, ITEM_PROPERTY_CAST_SPELL) == TRUE)
       SetLocalInt(oObjectCreated, "ats_charges_fix", TRUE);
   SetLocalObject(oObjectCreated, "ats_obj_possessor", GetItemPossessor(oObjectCreated));

}

string ATS_GetUniquePlayerID(object oPlayer)
{
   return ("ATS_PID_" + GetPCPlayerName(oPlayer) + GetName(oPlayer));

}
               
               

               
            

Legacy_Supreme_Pizza

  • Jr. Member
  • **
  • Posts: 90
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #3 on: January 29, 2013, 12:30:34 am »


               /////////////////////////////////////////////////////
// ATS_CreateItemInContainer                       //
//      Wrapper for CreateItemOnObject() so it can //
//      be used with DelayCommand()                //
// Returns: None                                   //
//          Check local object variable:           //
//          "ats_returnvalue_created_item" for the //
//          created object                         //
// Fix courtesy of Helimar on the ATS Forums       //
/////////////////////////////////////////////////////
void ATS_CreateItemInContainer
(
string sItemTag,           // Tag of the item
object oContainer,         // Container to create the item in
int iStackSize = 1,        // Size of the item stack
int iForceCreation = TRUE, // If container is full, the object is created on the owner
)
{
   string sItemResRef = ATS_GetResRefFromTag(sItemTag);

   object oCreatedItem = CreateItemOnObject(sItemResRef, oContainer, iStackSize);
   if(GetItemPossessor(oCreatedItem) == OBJECT_INVALID && iForceCreation == TRUE)
   {
       // stacked items do not have the possessor set correctly even if they were
       // created correctly if the new items were added to an existing partial stack
       object chk = GetObjectByTag(GetStringUpperCase(sItemTag));
       if(iStackSize==1) // if it's not we assume it's a stackable
       {
           if(GetNumStackedItems(chk)<=1)
           { // check the size of the first object found by GetObjectByTag,
       // which should have more than 1 if stackable, especially since
       // 1 was just added to a partial stack in the previous create.
       // If not, assume it's a non-stackable and create it on the player
               object oPlayer = GetItemPossessor(oContainer);
               ATS_CreateItemOnPlayer(sItemTag, oPlayer, iStackSize);
               oCreatedItem = GetLocalObject(oPlayer, "ats_returnvalue_created_item");
           }
       }
   }
   SetLocalObject(oContainer, "ats_returnvalue_created_item", oCreatedItem);
   SetLocalObject(oCreatedItem, "ats_obj_possessor", GetItemPossessor(oCreatedItem));
   if(GetItemHasItemProperty(oCreatedItem, ITEM_PROPERTY_CAST_SPELL) == TRUE)
       SetLocalInt(oCreatedItem, "ats_charges_fix", TRUE);
}
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #4 on: January 29, 2013, 04:38:31 pm »


               Why would you use GetObjectByTag at all? Doing that with anything with a nonunique tag is asking for trouble, and you already have an easy way of getting it - Create. I'll post what I think is what you're trying to do with the first function, though it'd be easier if you were a little more specific than 'it doesn't work'.

Funky
               
               

               


                     Modifié par FunkySwerve, 29 janvier 2013 - 04:40 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #5 on: January 29, 2013, 05:15:23 pm »


               Here's a cleaned-up version of the first function, with some comments indicating potential problem spots that might explain dysfunction:


/////////////////////////////////////////////////////
// ATS_CreateItemOnPlayer //
// Wrapper for CreateItemOnObject() so it can //
// be used with DelayCommand() //
// Returns: None //
// Check local object variable: //
// "ats_returnvalue_created_item" for the //
// created object //
// Fix courtesy of Helimar on the ATS Forums //
/////////////////////////////////////////////////////
void ATS_CreateItemOnPlayer(string sItemTag,object oPlayer, int iStackSize = 1, int iDropToFloor = FALSE) {

    string sItemResRef = GetStringLowerCase(GetStringLeft(sTag, 16));
    string sCheck = GetStringLowercase(GetStringRight(sItemTag, 3));
    if (sCheck == "dar")
        iStackSzie = 20;
    else if (sCheck == "bol")
        iStackSize = 10;
    else if (sCheck == "arr")
        iStackSize = 10;
    else {

        object oCreatedItem = CreateItemOnObject(sItemResRef, oPlayer, iStackSize);
        if (iDropToFloor && GetItemPossessor(oCreatedItem) == OBJECT_INVALID) {/* FKY: reordered and cleaned up - put booleans first to cut runtimes*/
            // stacked items do not have the possessor set correctly even if they were
            // created correctly if the new items were added to an existing partial stack

            /*FKY: I assume the above is what you're trying to address? I'm not familiar with ths issue, but...*/
            object chk = GetObjectByTag(GetStringUpperCase(sItemTag)); /*FKY: This is a bad idea, since tags are case-sensitive, and since, if memory serves, GOBT goes by most recently added AREA, not item */
            /*if(iStackSize==1) // if it's not we assume it's a stackable - FKY: removed bc redundant - it must be 1 here as written*/

            if(GetNumStackedItems(chk)<=1)
            /*FKY: What's the purpose of this? Will return 0 for invalid items, so you might as well just check if
            GetIsObjectValid(chk). Dropped items already head to the ground, unless you have other scripts to prevent it*/
            // check the size of the first object found by GetObjectByTag,
            // which should have more than 1 if stackable, especially since
            // 1 was just added to a partial stack in the previous create.
            // If not, assume it's a non-stackable and create it on the ground
                oCreatedItem = CreateObject(OBJECT_TYPE_ITEM, sItemResRef, GetLocation(oPlayer));
        }
        SetLocalObject(oPlayer, "ats_returnvalue_created_item", oCreatedItem);/*FKY: did you intend for the remainder only to fire if stacksize = 1? At present, this is what it does, so if so, move this stuff outside this bracket, down.*/
        SetLocalObject(oCreatedItem, "ats_obj_possessor", GetItemPossessor(oCreatedItem));
        if (GetItemHasItemProperty(oCreatedItem, ITEM_PROPERTY_CAST_SPELL))
            SetLocalInt(oCreatedItem, "ats_charges_fix", TRUE);
    }
}

Funky
               
               

               


                     Modifié par FunkySwerve, 29 janvier 2013 - 05:18 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #6 on: January 30, 2013, 02:21:58 am »


               The other big bug in the mix is that you are only creating the item if  it does not have arr, bol or dar in the tag.  If it is one of them you are simply setting the stack size and then skiping the creation.   Simply get rid of the last else in the code.  From funky's corrected post. 

...string sItemResRef = GetStringLowerCase(GetStringLeft(sTag, 16));
    string sCheck = GetStringLowercase(GetStringRight(sItemTag, 3));
    if (sCheck == "dar")
        iStackSzie = 20;
    else if (sCheck == "bol")
        iStackSize = 10;
    else if (sCheck == "arr")
        iStackSize = 10;
    else {...
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #7 on: January 30, 2013, 07:47:25 am »


               Psst. See the comment at the end:
/*FKY: did you intend for the remainder only to fire if stacksize = 1? At present, this is what it does, so if so, move this stuff outside this bracket, down.*/

Though I meant to say 'so if not' '<img'> Moving it down a bracket puts it outside that else, but leaves the rest in, which is I THINK what he intended - though it's a bit hard to be sure.

Funky
               
               

               
            

Legacy_Supreme_Pizza

  • Jr. Member
  • **
  • Posts: 90
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #8 on: February 03, 2013, 01:37:15 am »


               Thanks guys!

This is the reson NWN will never die.

OK...

So this is what I have now thanks to your help.

void ATS_CreateItemOnPlayer(string sItemTag, object oPlayer, int iStackSize = 1)
{
    string sItemResRef = ATS_GetResRefFromTag(sItemTag);
    string sCheck = GetStringLowerCase(GetStringRight(sItemTag, 3));
    if (sCheck == "dar")
        iStackSize = 20;
    else if (sCheck == "bol")
        iStackSize = 10;
    else if (sCheck == "arr")
        iStackSize = 10;
    object oCreatedItem = CreateItemOnObject(sItemResRef, oPlayer, iStackSize);
    SetLocalObject(oPlayer, "ats_returnvalue_created_item", oCreatedItem);
    SetLocalObject(oCreatedItem, "ats_obj_possessor", GetItemPossessor(oCreatedItem));
    if(GetItemHasItemProperty(oCreatedItem, ITEM_PROPERTY_CAST_SPELL) == TRUE)
        SetLocalInt(oCreatedItem, "ats_charges_fix", TRUE);
}


It's clear, concise and makes total sense.

However, darts bolts and arrows still are not created.

I am starting to wonder if it is broken elsewhere.
               
               

               


                     Modifié par Supreme_Pizza, 03 février 2013 - 01:37 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #9 on: February 03, 2013, 01:52:05 am »


               What sItemTag are you feeding into the function?
               
               

               
            

Legacy_Supreme_Pizza

  • Jr. Member
  • **
  • Posts: 90
  • Karma: +0/-0
Create Stack of Darts, Bolts, or Arrows ** ok **
« Reply #10 on: February 03, 2013, 08:56:08 am »


               

Lightfoot8 wrote...

What sItemTag are you feeding into the function?


Thanks!

I thought the script was good but I didn't  trust it.

Your question puhed me to check the constants where I found another error.

Thanks for all the help. ':wizard:'