Aller au contenu

Photo

Stumped on this script


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

#1
Darin

Darin
  • Members
  • 282 messages
 Goal: have three dead zombies become three undead zombies when this is called in a single-node conversation
result: works on only 1 zombie
Notes: 3 dead zombies in area, all with tag "ch3_zombie" (from a set new tag from onspawn ran earlier)

the script:

// ga_limbo
/*
Description:
sTag = Tag of creature to send to limbo
nNew = set to 1 to spawn-in a new version of that creature
*/
// Name_Date
void main(string sTag, int nNew, string sNewTag, int nTimes)
{
if(nTimes==0)
            nTimes==1;
int nN = 1;
for(nN;nN<=nTimes;nN++)
{
      object oLimbo = GetObjectByTag(sTag);
      location lLocation = GetLocation(oLimbo);
      SendCreatureToLimbo(oLimbo);
      if(nNew==1)
               CreateObject(OBJECT_TYPE_CREATURE,sTag,lLocation,FALSE,sNewTag);
 }
}

The variables set on the node:
nNew = 1
sNewTag = ch3_zombie_done
nTimes = 3


Why will only 1 of them spawn?

Modifié par EpicFetus, 23 décembre 2012 - 10:05 .


#2
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
if(nTimes==0) nTimes==1;
should be
if(nTimes==0) nTimes=1;
But that shouldn't affect what you're trying to do. What exactly does the SendCreatureToLimbo function do? If it immediately jumps oLimbo to some other place, then on the next iteration, your next zombie will be spawned in that new place. You should assign the spawn location to a variable outside the loop, so that it doesn't have to be derived over and over, especially if the creature with sTag is getting jumped around in the meantime.

#3
Darin

Darin
  • Members
  • 282 messages
reversing order also failed, though thought it was worth a try.

#4
kevL

kevL
  • Members
  • 4 070 messages
- just hacked around with this. Added a resref string. I think it's more complicated than it needs to be ....


// string sCorpse	= tag of object to destroy/send to Limbo. ( "ch3_zombie" )
// int bCreate		= create a living object at location of destroyed object ( TRUE ).
// string sResRef	= resref of creature to spawn at location of corpse. ( ? )
// string sNewTag	= give the created object this tag. ( "ch3_zombie_done" )
// int iTimes		= # of objects w/ sCorpse tag in the current area to create. ( 3 )


void main(string sCorpse, int bCreate, string sResRef, string sNewTag, int iTimes)
{
  // always destroy/create at least one
  if (iTimes < 1) iTimes = 1;

  location lLoc;

  // initialize count
  int i = 1;

  // search only the current area for corpses;
  // search from conversation owner
  object oCorpse = GetNearestObjectByTag(sCorpse, OBJECT_SELF, i);

  // there must be a corpse, & counter must be less than or equal to spec'd # of spawns
  while (i <= iTimes && GetIsObjectValid(oCorpse))
  {
    lLoc = GetLocation(oCorpse);

    // i had some problems putting this here instead of below, in a different script ...
    // it would be better here ( else the spawn may get displaced a meter or so ).
    // (( or something like that, i think objects don't get destroyed/acted on until
    // after the script completes anyway - sometimes they do, sometimes not :\\ ))
//    DestroyObject();

    if (bCreate) CreateObject(OBJECT_TYPE_CREATURE, sResRef, lLoc, FALSE, sNewTag);

    // or SendCreatureToLimbo()
    DestroyObject(oCorpse);

    // find the next corpse in the current area
    i ++;
    oCorpse = GetNearestObjectByTag(sCorpse, OBJECT_SELF, i);
  }
}


#5
Darin

Darin
  • Members
  • 282 messages
It may be an issue with the conversation spawning a hostile creature that is, in turn, cutting off the conversation and therefore the script. Does that make any sense whatsoever?

#6
kevL

kevL
  • Members
  • 4 070 messages
i don't think so ( not to me anyway )

you could try putting a short DelayCommand() around CreateObject(), say 0.1f seconds ...

[edit] prob. have to wrap w/ CreateObjectVoid() [/edit]


something I'm wary of in conversations, that may be problem with one-noders, is running scripts from the last line (in this case only line) of the dialog -- I believe i've had things fail to fire from final nodes for whatever reason, and I've taken to a policy for testing this, of always ending a dialog on say a blue-PC node esp. for running scripts


Is the purpose of this, in basics, to get a few corpses to rise as Zombies ?

Modifié par kevL, 28 décembre 2012 - 08:13 .


#7
diophant

diophant
  • Members
  • 116 messages
AFAIK there is no command that destroys or jumps a creature immediately; DestroyObject or JumpToLocation take effect AFTER the script ends. I think this might be the problem of the script; the Zombie sent to limbo in the first script is the same one in every iteration. Then you spawn 3 new Zombies, all at the same location. This tends to fail for unknown reasons.
What you could try is using this line in the first script:
object oLimbo = GetObjectByTag(sTag, nN);
Check in the toolset whether the default value for the second parameter is 1 or 0 (I haven't it opened at the moment). If it is 1, it should work like I wrote, otherwise use GetObjectByTag(sTag, nN - 1);

#8
Loki_999

Loki_999
  • Members
  • 430 messages

Yeah, original script will keep getting the same one because GetObjectByTag works across the whole module (you could instead try a variant using a loop with GetNearestObjectByTag and iterate around them, although as noted, remember DestroyObject only fires after script ends)

 

Bit of a bad practice, but hey, scripting in NWScript is messy anyway.

 

Just grab all 3 zombie objects first, then perform the actions.

 

ie:

 

object oZombie1 = GetObjectByTag(sTag, 0);

object oZombie2 = GetObjectByTag(sTag, 1);

object oZombie3 = GetObjectByTag(sTag, 2);

 

Yeah, nasty, but it should be fine with that.



#9
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
HI,
 
I'm not entirely sure why you have what you have, as I suspect there is an easier way to do what you are trying to do. However, I have tried to work with what you have given and would try this below ... do not confuse your sTag and sNewTag by the way.

EDIT: Note, I have removed the need for any nNew variable usage, as this (in theory) should be handled via the conversation choices anyway.

EDIT 2: Note also that sTag should be UNIQUE for every call of this function. i.e. If used in more than one place, then sTag has to be different in every case, and you must have the unique tagged objects within the module in question.

EDIT 3: The variable nTimes could also be eliminated, as you could simply search for the UNIQUE tagged objects in every case and change the while command to while(oZombie != OBJECT_INVALID) where oZombie has been defined as in object oZombie = GetObjectByTag("yourtaghere");
 
EDIT 4: Subject to which type of object you are using as the "dead" zombie, then you could potentially just use the "raise dead" type function on a creature object. I say this because the "SendCreatureToLimbo" says that it only works on creatures. Therefore, your script appears to be doing more work than it needs to if you see what I mean? i.e. Why send the dead zombies to limbo and create new ones if you can simply raise the dead ones and set a new tag for them anyway (if you actually need to do that)?

Cheers,
Lance.
 
void main(string sTag, int nNew, string sNewTag, int nTimes)
 {
	int nN = 1;
	
		while(nN <= nTimes)
		{ 
			object oLimbo = GetObjectByTag(sTag); 
			location lLocation = GetLocation(oLimbo); 
			SendCreatureToLimbo(oLimbo); 
			
			object oNEW = CreateObject(OBJECT_TYPE_CREATURE,sTag,lLocation,FALSE,sNewTag);
			
			nN = nN + 1;
		}
 }


#10
Dann-J

Dann-J
  • Members
  • 3 161 messages

This is a slight variation of a script that I use to have 'dead' creatures suddenly rise up. I place the creatures in the area with zero hit points and the same tags, and make sure the corpses are set not to fade and have nothing in their inventories. They initially lay on the ground as unselectable and un-highlightable corpses.

 

I used skeletons, so they looked much like the skeleton placeable models until they resurrected, but it'll work with any creature. I also had the skeletons keep resurrecting whenever you tried to steal from the tomb (disarm or spring trap, unlock sarcophagus, disturb contents of sarcophagus). If you only want it to work once, you can add a line to cause the creatures to fade once you've killed them for good.

// sTag = tag of creature
// iNumber = number of creatures
// sFX = name of SEF to play on creature (optional)

#include "nw_i0_spells"

void main(string sTag, int iNumber, string sFX)
{
object oSelf = GetPCSpeaker();

object oTarget = GetNearestObjectByTag(sTag, oSelf, 1);
effect eResurrect = EffectResurrection();
effect eVis = EffectNWN2SpecialEffectFile( sFX );
int i = 1;
float fDelay;
if (iNumber < 1 ) iNumber = 1;

while (i <= iNumber)
	{
	if (GetIsDead(oTarget))
		{
		fDelay = GetRandomDelay(0.5, 1.0);
		if (sFX != "")
			DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget, 2.0));
		DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eResurrect, oTarget));
		DelayCommand(fDelay+0.05, AssignCommand(oTarget, PlayAnimation(ANIMATION_FIREFORGET_STANDUP)));
		DelayCommand(fDelay+0.1, ForceRest(oTarget));
		SetPlotFlag(oTarget, 0);
		}
	i++;
	oTarget = GetNearestObjectByTag(sTag, oSelf, i);
	}

}