Author Topic: Looking for help with this script set  (Read 603 times)

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Looking for help with this script set
« on: August 31, 2010, 10:56:00 pm »


               Hiya sweeties,

Well, I thought I was making a simple script, but naturally it's giving me trouble.

Basically the script is for a player to place a blanket on the ground, and then pick it up again.

The first script works fine. It takes the item from the inventory and a blanket appears on the ground.

The second script starts a convo when the player uses the blanket  that is on the ground, and the convo asks if the player wants to pick it up. I figured it was best to use a convo for that in case the blanket was clicked on accidentally.

The third script is where things go wrong. Instead of picking up the blanket, and replacing the blanket in the player's inventory, it creates another blanket on the ground.

Here's the third script that's giving me trouble. Let me know if you need to see the others. (Sorry, I can't figure out how to put it in bbcode...*sheepish*) Thank you for any help. '<img'>

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.c...=4683&id=625テつ テつ テつ  */

//Put this on action taken in the conversation editor
void main()
{

object oPC = GetPCSpeaker();

AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f));

CreateItemOnObject("blanket", oPC);

object oTarget;
oTarget = OBJECT_SELF;

DestroyObject(oTarget, 0.0);

}
               
               

               
            

Legacy_ffbj

  • Hero Member
  • *****
  • Posts: 1097
  • Karma: +0/-0
Looking for help with this script set
« Reply #1 on: September 01, 2010, 02:05:40 am »


               Yeah you could do it that way.  You may want to try something along these lines instead:



//try puttin this onused of the blanket, it might work. ffbj

void main()

{

object oPC =  GetLastUsedBy();

location lLocation = GetLocation(oPC);

object oBlanket = OBJECT_SELF;

AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f));

//performs the animation anyway for either function dropping or picking up blanket

if (GetLocalInt (oBlanket, "Used") == 0)

//create the blanet on the ground with your creation script which you say works

//so insert those lines here, or just use...

{

CreateObject(OBJECT_TYPE_PLACEABLE, "blanket",lLocation);

//thr string resref of the object.

//and add

SetLocalInt (oBlanket, "Used", 1);

return;

}

//blanket set on the ground with local int now not zero, set to 1.

//if not 0 it must be 1 so blanket is already on the ground so



DestroyObject(oBlanket, 2.0);

CreateItemOnObject("blanket", oPC);

}



               
               

               
            

Legacy_ehye_khandee

  • Hero Member
  • *****
  • Posts: 1415
  • Karma: +0/-0
Looking for help with this script set
« Reply #2 on: September 01, 2010, 03:39:57 am »


               

ffbj wrote...

Yeah you could do it that way.  You may want to try something along these lines instead:

//try puttin this onused of the blanket, it might work. ffbj
void main()
{
object oPC =  GetLastUsedBy();
location lLocation = GetLocation(oPC);
object oBlanket = OBJECT_SELF;
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f));
//performs the animation anyway for either function dropping or picking up blanket
if (GetLocalInt (oBlanket, "Used") == 0)
//create the blanet on the ground with your creation script which you say works
//so insert those lines here, or just use...
{
CreateObject(OBJECT_TYPE_PLACEABLE, "blanket",lLocation);
//thr string resref of the object.
//and add
SetLocalInt (oBlanket, "Used", 1);
return;
}
//blanket set on the ground with local int now not zero, set to 1.
//if not 0 it must be 1 so blanket is already on the ground so

DestroyObject(oBlanket, 2.0);
CreateItemOnObject("blanket", oPC);
}



OK, I'm scratching my head here. The placeable blanket is what is on the ground, an ITEM object is what it should create on the PC when the placeable is used - assuming this is correct, why would we have to check for a var on either object? It can only work one way after all, e.g. placeable gone and item created on pc, no?

If my above premise is true, this script is not the tool for the job.

':bandit:'

Feedback?
               
               

               


                     Modifiテδゥ par ehye_khandee, 01 septembre 2010 - 02:40 .
                     
                  


            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Looking for help with this script set
« Reply #3 on: September 01, 2010, 05:04:57 pm »


               

ffbj wrote...

Yeah you could do it that way.  You may want to try something along these lines instead:

//try puttin this onused of the blanket, it might work. ffbj
void main()
{
object oPC =  GetLastUsedBy();
location lLocation = GetLocation(oPC);
object oBlanket = OBJECT_SELF;
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f));
//performs the animation anyway for either function dropping or picking up blanket
if (GetLocalInt (oBlanket, "Used") == 0)
//create the blanet on the ground with your creation script which you say works
//so insert those lines here, or just use...
{
CreateObject(OBJECT_TYPE_PLACEABLE, "blanket",lLocation);
//thr string resref of the object.
//and add
SetLocalInt (oBlanket, "Used", 1);
return;
}
//blanket set on the ground with local int now not zero, set to 1.
//if not 0 it must be 1 so blanket is already on the ground so

DestroyObject(oBlanket, 2.0);
CreateItemOnObject("blanket", oPC);
}


Hiya sweetie,

Thanks for replying.
I tried the script and it's still doing the same thing. Creating a second blanket on the ground, and I get the message 'acquired blanket' and immediately after 'lost blanket'. I think what's happening is as soon as the blanket appears in the inventory, it gets used again, thus creating another blanket on top of the first, though it doesnt explain why the first stays there, unless it's not really the first blanket?':blink:'

I noticed the same thing sort of happens with a camp cook script I have where you put raw meat into the placeable camp, and you get cooked meat back. When you click on it to take it out, it gets consumed right away, however if you drag it out to your inventory, it doesn't. What would cause it to do that and is there a way to fix it?
               
               

               
            

Legacy_Xovian

  • Full Member
  • ***
  • Posts: 158
  • Karma: +0/-0
Looking for help with this script set
« Reply #4 on: September 01, 2010, 06:17:27 pm »


               Might try something like this:

Quote


void main()
{
object oPC = GetLastUsedBy();
object oBlanket = GetObjectByTag("blanket");
location lLocation = GetLocation(oPC);
if(GetLocalInt(oBlanket, "Used") == 0)
  {
   AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f));
   CreateItemOnObject("blanket", oPC);
   SetLocalInt(oBlanket, "Used", 1);
  }
else if(GetLocalInt(oBlanket, "Used") == 1)
{
 //Detroy object is set to the same time frame as the completed looping animation.
 DestroyObject(oBlanket, 1.1);
}
else return;
}


As noted in the script, your destory time proably needs to match the time frame the item is supposed to be on the ground and only gets destroyed when "picked up".
You may require a while loop to acomplish this if the problem persists.

The other way of doing it is to make your own void commands, and then use the delay command to have them work in the order you want.
Something like this...probably be the easiest way.
Quote

void PlaceBlanket(object oBlanket)
{
  //add the script that places the blanket down
}

void PickUpBlanket(object oBlanket)
{
  //add the script that picks it up
}
Void Main()
{
object oPC = GetLastUsedBy();
PlaceBlanket(oPC);
DelayCommand(1.1, PickUpBlanket(oPC));
}
               
               

               


                     Modifiテδゥ par Xovian, 01 septembre 2010 - 05:41 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Looking for help with this script set
« Reply #5 on: September 01, 2010, 07:38:20 pm »


               Are these tag based scripts? If so do they have checks at the top to make sure which event is firing them? Just an idea.
               
               

               
            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Looking for help with this script set
« Reply #6 on: September 01, 2010, 10:51:48 pm »


               This is so frustrating for something that should be so simple..hehe.

Ok. The Item the player has in their inventory is named and tagged Blanket and it's property is Cast Spell: Unique Power Self Only (Single Use). This is the script that places it on the ground. It works fine.

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.c...=4683&id=625テつ テつ テつ  */

void main()
{
object oPC;

oPC = GetItemActivatedTarget();
ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 2.5);

object oItem;
oItem = GetItemPossessedBy(oPC, "Blanket");

if (GetIsObjectValid(oItem))
   DestroyObject(oItem);

object oTarget;
object oSpawn;
location lTarget;
oPC = GetItemActivator();

oTarget = oPC;

lTarget = GetLocation(oTarget);

oSpawn = CreateObject(OBJECT_TYPE_PLACEABLE, "blanket2", lTarget);

}

The placeable that gets put on the ground is tagged Blanket2, resref is blanket2. It has a script in the onused slot that opens a conversation asking if the player wants to pick up the blanket. If they choose yes, then this is the script that is supposed to destroy the placeable on the ground, and put the item in their inventory.

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.c...=4683&id=625テつ テつ テつ  */

//Put this on action taken in the conversation editor
void main()
{

object oPC = GetPCSpeaker();

AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f));

object oTarget;
oTarget = GetObjectByTag("Blanket2");

DestroyObject(oTarget, 0.0);

AssignCommand(oPC, ActionWait(1.0f));

CreateItemOnObject("blanket", oPC);

}

I think what's happening is it 'is' picking up the blanket but then it's immediately placing another one on the ground again. I tried the other script suggestions but they aren't helping. Why would it immediately place another blanket on the ground without the player opting to use the item?

I know it's a silly little insignificant script, but it's gnawing at me now. ':blink:'
               
               

               
            

Legacy_Xovian

  • Full Member
  • ***
  • Posts: 158
  • Karma: +0/-0
Looking for help with this script set
« Reply #7 on: September 01, 2010, 11:13:56 pm »


               You seem to be using 2 tags for the same object.

oTarget = GetObjectByTag("Blanket2");
and
CreateItemOnObject("blanket", oPC);

If tag based scripts are enabled as they seem to be, you should only have one tag, that of "Blanket2" or Blanket, but not both. The latter might be using ResRef (not at home to verify what createitem uses), but my point is, you should probably call either the tag, or the resref, but not both in the same script...keeps things cleaner and easier to find where any errors might be.

Also your timing by delayed commands and the object being destroyed are not happening sequentially.
It's being destroyed before the animation finishes.

This might help as well:

CreateItemOnObject("blanket", oPC);


object oBlanket = GetObjectByTag("Blanket2");
CreateItemOnObject(oBlanket, oPC);
               
               

               


                     Modifiテδゥ par Xovian, 01 septembre 2010 - 10:21 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Looking for help with this script set
« Reply #8 on: September 01, 2010, 11:53:28 pm »


               

Ok. The Item the player has in their inventory is named and tagged Blanket and it's property is Cast Spell: Unique Power Self Only (Single Use). This is the script that places it on the ground. It works fine.

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.c...=4683&id=625テつ テつ テつ  */

void main()
{
  object oPC;

  oPC = GetItemActivatedTarget();
  ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 2.5);

  object oItem;
  oItem = GetItemPossessedBy(oPC, "Blanket");

  if (GetIsObjectValid(oItem))
     DestroyObject(oItem);

   object oTarget;
  object oSpawn;
  location lTarget;
  oPC = GetItemActivator();

  oTarget = oPC;

  lTarget = GetLocation(oTarget);

  oSpawn = CreateObject(OBJECT_TYPE_PLACEABLE, "blanket2", lTarget);
}


Umm,  Guess what.  This script does not work that well.  

Since your PC is bending over to place the blanket down,  (a guess since you say the the script is working right) I am assumeing that you are not useing tag based scripting. but are instead running the script on the target.   

...
object oItem;
  oItem = GetItemPossessedBy(oPC, "Blanket");
...

This is going to make oItem equal to the first Blanket that it finds in the PC's inventory.  This may or may not be the blanket that was used.  If the PC has two blankets your destroy command my get rid of the wrong one.  The blanket that wasy used with the single use should get auto destroyed.  So the PC could lose them both.
 
Edited script with comments.

void main()
{
  object oPC;
  oPC = GetItemActivator(); //The PC who used the Item.

  // I am guessing that oPC is also Object Self If the animation is being played.
  ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 2.5);

     // No reason for any of this, the blanket will destroy itself.
     //object oItem;
     //oItem = GetItemPossessedBy(oPC, "Blanket");
     //
     // if (GetIsObjectValid(oItem))
     // DestroyObject(oItem);
   //object oTarget; //Not needed
  //object oSpawn; // Not Needed

  location lTarget;

  // oPC = GetItemActivator(); // Already changed it to this above.
  //oTarget = oPC;// not needed

  lTarget = GetLocation(oPC);// Changed to oPC
   CreateObject(OBJECT_TYPE_PLACEABLE, "blanket2", lTarget); // Got Ride of the assignment not needed.
}


The Trimmed script without comments.

void main()
{
  object oPC;
  oPC = GetItemActivator(); //The PC who used the Item.
  ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 2.5);
  location lTarget;
  lTarget = GetLocation(oPC);
  CreateObject(OBJECT_TYPE_PLACEABLE, "blanket2", lTarget);
}


EDIT:
Before I look at the other script It would help if I could confirm that you are not using tag based scripting. For if you are using Tag Based scripting This script will also be firing every time you acquire the item. So when your Conversation fires the PC to get a new blanket. The script fires and creates a new one on the ground. But this is only if you are using TB scripts.
               
               

               


                     Modifiテδゥ par Lightfoot8, 01 septembre 2010 - 11:05 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Looking for help with this script set
« Reply #9 on: September 02, 2010, 12:04:49 am »


               It is because when you acquire the blanket on the second script it is triggering the OnAcquireItem event which then fires the "blanket" script again, which in turn recreates the blanket on the ground. When using tag based scripts you need to put a check at the top of them so it know which module event to fire from.

Try your first script like this and see if it helps out:
(I added three lines. One just above the void main and the 2 just after the void main.)

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.c...=4683&id=625テつ テつ テつ  */
#include "x2_inc_switches"
void main()
{
int nEvent =GetUserDefinedItemEventNumber();
if(nEvent !=  X2_ITEM_EVENT_ACTIVATE)return;

object oPC;

oPC = GetItemActivatedTarget();
ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 2.5);

object oItem;
oItem = GetItemPossessedBy(oPC, "Blanket");

if (GetIsObjectValid(oItem))
   DestroyObject(oItem);

object oTarget;
object oSpawn;
location lTarget;
oPC = GetItemActivator();

oTarget = oPC;

lTarget = GetLocation(oTarget);

oSpawn = CreateObject(OBJECT_TYPE_PLACEABLE, "blanket2", lTarget);

}


Hope that helps.

EDIT: Jinx Lightfoot8 '<img'>
               
               

               


                     Modifiテδゥ par GhostOfGod, 01 septembre 2010 - 11:07 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Looking for help with this script set
« Reply #10 on: September 02, 2010, 12:12:10 am »


               Fixed and rescripted to use of action. What it means? It means that if the player cancel the get low action, the script fails. Also the blanket at groud appear at the right time - when the player finish the get low animation.

void main_continue(object oPC)
{
object oItem = GetItemPossessedBy(oPC, "Blanket");
 if (GetIsObjectValid(oItem))
 {
 DestroyObject(oItem);
 }
CreateObject(OBJECT_TYPE_PLACEABLE, "blanket2",GetLocation(oPC));
}

#include "x2_inc_switches"

void main()
{
 if(GetUserDefinedItemEventNumber() !=  X2_ITEM_EVENT_ACTIVATE)
 {
 return;
 }
object oPC = GetItemActivator();
AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0, 2.5));
AssignCommand(oPC,ActionDoCommand(main_continue(oPC)));
}


EDIT: if you will go with this script the blanket item must be set to plot so it will be not destroyed if the player cancel the action
               
               

               


                     Modifiテδゥ par ShaDoOoW, 01 septembre 2010 - 11:34 .
                     
                  


            

Legacy_ffbj

  • Hero Member
  • *****
  • Posts: 1097
  • Karma: +0/-0
Looking for help with this script set
« Reply #11 on: September 03, 2010, 01:58:35 am »


               

// I just have the item blanket in inventory and it stays there, creating or

// uncreating the blanket on the ground as need.

//so you have the item with the resref blanket, and the placeable resref blanket2

//I forgot about the fact you can't put a placeable in your inventory.

//anyway one approach.

#include "x2_inc_switches"



void main()

{

int nEvent =GetUserDefinedItemEventNumber();

    if (!nEvent == X2_ITEM_EVENT_ACTIVATE)

    return;

// Check if item target is valid.

   object oPC = GetItemActivator();

   object oBlanket = GetItemActivated();

   object oBlanket2 = GetNearestObjectByTag("Blanket2", oPC);

   location lLocation = GetLocation(oPC);



AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f));

//performs the animation anyway for either function dropping or picking up blanket

if (GetLocalInt (oBlanket, "InUse") == 0)

//create the blanet on the ground with your creation script which you say works

//so insert those lines here, or just use...

{

CreateObject(OBJECT_TYPE_PLACEABLE, "blanket2",lLocation);

//the string resref of the object being created on the ground.

SetLocalInt (oBlanket, "InUse", 1);

return;

}

if (GetLocalInt (oBlanket, "InUse") == 1)

SetLocalInt (oBlanket, "InUse", 0);

DestroyObject(oBlanket2, 1.0);



}



               
               

               
            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Looking for help with this script set
« Reply #12 on: September 03, 2010, 05:57:46 pm »


               Thanks sweeties. You're all great for helping me out. *hugs everyone*