Aller au contenu

Photo

Scripting for Dummies


  • Veuillez vous connecter pour répondre
15 réponses à ce sujet

#1
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
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 .


#2
Xardex

Xardex
  • Members
  • 217 messages
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 .


#3
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
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.)

#4
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
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.

#5
Xardex

Xardex
  • Members
  • 217 messages
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 .


#6
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
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 .


#7
Kato -

Kato -
  • Members
  • 392 messages
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 .


#8
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
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);
}

?

#9
Kato -

Kato -
  • Members
  • 392 messages
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 

#10
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
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.

#11
Kato -

Kato -
  • Members
  • 392 messages
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 .


#12
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
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.

#13
Kato -

Kato -
  • Members
  • 392 messages
Sorry, I should have said spawn location, comparing it to the NPC to destroy location.

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


#14
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
So I take it the alternate (hostile) version of the NPC will spawn in place of the original NPC?

#15
Kato -

Kato -
  • Members
  • 392 messages
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

#16
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Exellent, thank you very much Kato!