Author Topic: Scripting for Dummies  (Read 507 times)

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Scripting for Dummies
« on: November 19, 2011, 10:20:59 am »


               Well... usually I am trying to do stuff that is pretty off the charts, but I have a rather mundane one for you all. I have a non hostile npc, and at the end of the conversation I would like it to a) remove an item from the PC's inventory, and 'B)' turn into an alternate (hostile) version of itself.

I tried using a modified version script in the mod that does 'B)' in another area for another npc, but it's not working due to my lack of knowledge of how it actually functions.

Any help would be appreciated.

Cheers, Laz
               
               

               


                     Modifié par Lazarus Magni, 19 novembre 2011 - 10:47 .
                     
                  


            

Legacy_Xardex

  • Sr. Member
  • ****
  • Posts: 414
  • Karma: +0/-0
Scripting for Dummies
« Reply #1 on: November 19, 2011, 12:27:00 pm »


               a:

    object oPC = GetPCSpeaker();
    object oItem = GetItemPossessedBy(oPC, "tag_of_the_item");
    if (oItem != OBJECT_INVALID)
    {
        // Do stuff to the item
    } else {
        // The player didn't have the item
    }


b:
ChangeFaction(oNPC, oEnemy);
oNPC = NPC you want to make hostile.
oEnemy = Any NPC from the faction 'hostile'

Make sure oEnemy exists.
               
               

               


                     Modifié par Xardex, 19 novembre 2011 - 12:34 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Scripting for Dummies
« Reply #2 on: November 19, 2011, 12:46:57 pm »


               Hey Xardex,
Thanks for the response. So for the object search/destroy aspect of the script I assume you mean:
object oPC = GetPCSpeaker();
   object oItem = GetFirstItemInInventory(oPC);
   while (GetIsObjectValid(oItem))
   {
       if (GetTag(oItem) == "tag_of_the_item")
       {
       DestroyObject == ("tag of the item")
       }

       oItem = GetNextItemInInventory(oPC);
   }
Or something?

And, it's not that I want the existing NPC to turn hostile, but rather spawn an alternate version of it's self. Something along the lines of:
void main()
{
 DestroyObject(OBJECT_SELF);
 object oSpawnPoint = GetNearestObjectByTag("laz_headmaster", OBJECT_SELF);
 location lSpawnPoint = GetLocation(oSpawnPoint);
 object oHeadGuard = CreateObject(OBJECT_TYPE_CREATURE, "loc_headguard", lSpawnPoint, FALSE);

 oSpawnPoint = GetNearestObjectByTag("laz_headmaster", OBJECT_SELF);
 lSpawnPoint = GetLocation(oSpawnPoint);
 object oHeadMaster = CreateObject(OBJECT_TYPE_CREATURE, "laz_headmaster", lSpawnPoint, FALSE);
}
However I would like to get it to spawn to a waypoint, as the spawn point line doesn't seem to work for the existing set up (or I just don't know how to set it up correctly.)
               
               

               
            

Legacy__Knightmare_

  • Full Member
  • ***
  • Posts: 191
  • Karma: +0/-0
Scripting for Dummies
« Reply #3 on: November 19, 2011, 12:56:24 pm »


               The basic problem with your second script there is that you are trying to find the nearest object by tag to OBJECT_SELF, however, you have previously destroyed OBJECT_SELF, so there is no point of reference any more.

Try things in a different order:

void main()
{
object oSpawnPoint1  = GetNearestObjectByTag("laz_headmaster", OBJECT_SELF);
location lSpawnPoint1 = GetLocation(oSpawnPoint1);

object oSpawnPoint2 = GetNearestObjectByTag("laz_headmaster", OBJECT_SELF);
location lSpawnPoint2 = GetLocation(oSpawnPoint2);

DestroyObject(OBJECT_SELF);

object oHeadGuard = CreateObject(OBJECT_TYPE_CREATURE, "loc_headguard", lSpawnPoint1, FALSE);

object oHeadMaster = CreateObject(OBJECT_TYPE_CREATURE, "laz_headmaster", lSpawnPoint2, FALSE);
}

Since this is run from a conversation, OBJECT_SELF is the NPC who "owns" the conversation.
               
               

               
            

Legacy_Xardex

  • Sr. Member
  • ****
  • Posts: 414
  • Karma: +0/-0
Scripting for Dummies
« Reply #4 on: November 19, 2011, 12:58:49 pm »


               Since you know the item you can just use
GetItemPossessedBy
to check if the player has the item. (Instead of looping through them all)

If the player does not have the item it returns OBJECT_INVALID, if he does have it, it returns the item.
               
               

               


                     Modifié par Xardex, 19 novembre 2011 - 12:59 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Scripting for Dummies
« Reply #5 on: November 19, 2011, 01:59:57 pm »


               Thanks Knightmare and Xardex, I did however find another script in the mod, so I will try this first:
void main()
{

object oPC = GetPCSpeaker();

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

ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_UNSUMMON), GetLocation(oTarget));

oTarget = GetObjectByTag("loc_headmaster");

DestroyObject(oTarget, 3.0);

object oSpawn;
oTarget = oPC;

oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "laz_headmaster", GetLocation(oTarget));

oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "loc_headguard", GetLocation(oTarget));

oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "loc_headguard", GetLocation(oTarget));

oTarget = oSpawn;

SetIsTemporaryEnemy(oPC, oTarget);

AssignCommand(oTarget, ActionAttack(oPC));

oTarget = oSpawn;

ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_UNSUMMON), GetLocation(oTarget));

}
Although I don't believe the original non-hostile npc actually gets destroyed on this one. If this doesnt work however I will try your approach.

There is still the issue of destroying the object however.
               
               

               


                     Modifié par Lazarus Magni, 19 novembre 2011 - 02:01 .
                     
                  


            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Scripting for Dummies
« Reply #6 on: November 19, 2011, 07:22:38 pm »


               This might do the trick, assuming that you want to remove a given item + destroy current NPC and replace with an instance of the resref specified in the CreateObject function. It's the same code 'skeleton' as the one correctly suggested by Xardex.

#include "nw_i0_plot"
void main()
{
   object oPC = GetPCSpeaker();
   object oItem = GetItemPossessedBy(oPC, "tag_of_the_item");
   if(oItem != OBJECT_INVALID)
   {
      int nStack = GetItemStackSize(oItem);
      if(nStack > 1) SetItemStackSize(oItem, nStack -1);
      else DestroyObject(oItem);
   }
   object oSpawnPoint = GetNearestObjectByTag("laz_headmaster", OBJECT_SELF);
   object oNewNPC = CreateObject(OBJECT_TYPE_CREATURE, "the_npc_ref",   GetLocation(oSpawnPoint));
   if(!GetIsEnemy(oNewNPC, oPC)) AssignCommand(oNewNPC, SetIsEnemy(oPC));
   DestroyObject(OBJECT_SELF);
}

P.S.: Greetings to you all on Av3!


Kato
               
               

               


                     Modifié par Kato_Yang, 19 novembre 2011 - 08:04 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Scripting for Dummies
« Reply #7 on: November 19, 2011, 08:12:52 pm »


               Thanks Kato, I will give these a try. In your example if I wanted it to spawn with a couple of it's body guards, could I just include a couple extra lines like:
#include "nw_i0_plot"
void main()
{
  object oPC = GetPCSpeaker();
  object oItem = GetItemPossessedBy(oPC, "tag_of_the_item");
  if(oItem != OBJECT_INVALID)
  {
     int nStack = GetItemStackSize(oItem);
     if(nStack > 1) SetItemStackSize(oItem, nStack -1);
     else DestroyObject(oItem);
  }
  object oSpawnPoint = GetNearestObjectByTag("laz_headmaster", OBJECT_SELF);
  object oNewNPC = CreateObject(OBJECT_TYPE_CREATURE, "the_npc_ref",   GetLocation(oSpawnPoint));
  object oNewNPC = CreateObject(OBJECT_TYPE_CREATURE, "bodyguard_resref",   GetLocation(oSpawnPoint));
  if(!GetIsEnemy(oNewNPC, oPC)) AssignCommand(oNewNPC, SetIsEnemy(oPC));
  DestroyObject(OBJECT_SELF);
}

?
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Scripting for Dummies
« Reply #8 on: November 19, 2011, 08:24:12 pm »


               Then it would look like this, yet if the NPCs you're spawning are already hostile the code can be simplified further.

#include "nw_i0_plot"
void main()
{
   object oPC = GetPCSpeaker();
   object oItem = GetItemPossessedBy(oPC, "tag_of_the_item");
   if(oItem != OBJECT_INVALID)
   {
      int nStack = GetItemStackSize(oItem);
      if(nStack > 1) SetItemStackSize(oItem, nStack -1);
      else DestroyObject(oItem);
   }
   object oSpawnPoint = GetNearestObjectByTag("laz_headmaster", OBJECT_SELF);
   location loc = GetLocation(oSpawnPoint);
   object oNewNPC = CreateObject(OBJECT_TYPE_CREATURE, "the_npc_ref", loc);
   object oBody =  CreateObject(OBJECT_TYPE_CREATURE, "the_body_ref",   loc);
   if(!GetIsEnemy(oNewNPC, oPC)) AssignCommand(oNewNPC, SetIsEnemy(oPC));
   if(!GetIsEnemy(oBody, oPC)) AssignCommand(oBody, SetIsEnemy(oPC));
   DestroyObject(OBJECT_SELF);
}


Kato 
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Scripting for Dummies
« Reply #9 on: November 19, 2011, 08:27:45 pm »


               The alternate versions of the NPCs are indeed hostile (and beefed up), where as the original are defender (or commoner) faction, and marked as plot. This is why I was wanting to spawn the alternate versions at the end of completing the quest.
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Scripting for Dummies
« Reply #10 on: November 19, 2011, 08:35:37 pm »


               Okay, so this should be sufficient and faster then:

void main()
{   
   object oItem = GetItemPossessedBy(GetPCSpeaker(), "tag_of_the_item");
   if(oItem != OBJECT_INVALID)
   {
      int nStack = GetItemStackSize(oItem);
      if(nStack > 1) SetItemStackSize(oItem, nStack -1);
      else DestroyObject(oItem);
   }
   object oSpawnPoint = GetNearestObjectByTag("laz_headmaster", OBJECT_SELF);
   location loc = GetLocation(oSpawnPoint);
   CreateObject(OBJECT_TYPE_CREATURE, "the_npc_ref", loc);
   CreateObject(OBJECT_TYPE_CREATURE, "the_body_ref", loc);
   // Add any other NPC(s) here
   DestroyObject(OBJECT_SELF);
}

Yet if the spawn point's location is the same as the NPC to destroy, the code would be even shorter of operations.


Kato
               
               

               


                     Modifié par Kato_Yang, 19 novembre 2011 - 09:22 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Scripting for Dummies
« Reply #11 on: November 19, 2011, 09:09:55 pm »


               I am a little hung up on the spawn point. Is it refering to the spawn point of the original NPC?

Alternatively there is a way point in the room that could possibly be used.
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Scripting for Dummies
« Reply #12 on: November 19, 2011, 09:13:39 pm »


               Sorry, I should have said spawn location, comparing it to the NPC to destroy location.
               
               

               


                     Modifié par Kato_Yang, 19 novembre 2011 - 09:15 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Scripting for Dummies
« Reply #13 on: November 19, 2011, 09:16:47 pm »


               So I take it the alternate (hostile) version of the NPC will spawn in place of the original NPC?
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Scripting for Dummies
« Reply #14 on: November 19, 2011, 09:21:45 pm »


               Okay, this is answering my last question, so here's what it looks like:

void main()
{   
   object oItem = GetItemPossessedBy(GetPCSpeaker(), "tag_of_the_item");
   if(oItem != OBJECT_INVALID)
   {
      int nStack = GetItemStackSize(oItem);
      if(nStack > 1) SetItemStackSize(oItem, nStack -1);
      else DestroyObject(oItem);
   }   
   location loc = GetLocation(OBJECT_SELF);
   CreateObject(OBJECT_TYPE_CREATURE, "the_npc_ref", loc);
   CreateObject(OBJECT_TYPE_CREATURE, "the_body_ref", loc);
   // Add any other NPC(s) here
   DestroyObject(OBJECT_SELF);



Kato