Aller au contenu

Photo

GetFirstObject/GetNextObject + CreateObject


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

#1
Rubies

Rubies
  • Members
  • 292 messages
Hi there,

Having a bit of trouble with a script, but I'm assuming the issue is more related to the CreateObject function rather than the loop (or both).

The issue is that there multiple creatures spawned at each waypoint - in my actual module, it spawns four creatures, but trying with chickens spawned about 9, arranged in a neat "]" shape.

I wrote up a quick shortened copy of the script that demonstrates the issue.


void main()
{
object oObject;

    oObject = GetFirstObjectInArea(OBJECT_SELF);

    while(GetIsObjectValid(oObject))
    {

        if(GetObjectType(oObject) == OBJECT_TYPE_WAYPOINT
        && GetTag(oObject) == "spawn")
        {
        CreateObject(OBJECT_TYPE_CREATURE, "nw_chicken", GetLocation(oObject), FALSE);
        }

    oObject = GetNextObjectInArea(OBJECT_SELF);
    }
}



Would it be more appropriate to use something similar to this?


void main()
{
int nNth = 1;

object oObj;

    oObject = GetObjectByTag("spawn", nNth);

    while (GetIsObjectValid(oObject))
    {

        if(GetObjectType(oObject) == OBJECT_TYPE_WAYPOINT)
        {
        CreateObject(OBJECT_TYPE_CREATURE, "nw_chicken", GetLocation(oObject), FALSE);
        }

    ++nNth;
    oObject = GetObjectByTag("spawn", nNth);
    }
}


Modifié par Rubies, 03 septembre 2010 - 09:19 .


#2
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
My guess is that your problem lies in something you did not state. Are you running this script from the OnEnter Event for an area. If you are every time a chicken enters the area he is causing the script to fire again. You will need to place a control to make sure that it only fires for PC's



object oPC = GetEnteringObject();

If (!GetIsPC(oPC)) return;

#3
Rubies

Rubies
  • Members
  • 292 messages
It's not running from an OnEnter, no. There are no attached scripts to creatures nor areas except for this single script which is on a placeable activation (for testing).

I haven't tried the second script, yet, because I didn't want to rewrite nearly 1500 lines of code with the altered spawning, if there was a way to fix the first script. :P

Modifié par Rubies, 03 septembre 2010 - 08:58 .


#4
GhostOfGod

GhostOfGod
  • Members
  • 863 messages
In the first script you have this line:

if(GetObjectType(oWP) == OBJECT_TYPE_WAYPOINT.....

You are using object oWP but you did not declare/define any object oWP. Is that supposed to be oObject?
Or is this just a typo in your shortened version?

Just a thought.

Modifié par GhostOfGod, 03 septembre 2010 - 09:14 .


#5
Shadooow

Shadooow
  • Members
  • 4 470 messages
[quote]void main()

{

object oObject;



    oObject = GetFirstObjectInArea(OBJECT_SELF);



    while(GetIsObjectValid(oObject))

    {



        if(GetObjectType([b]oWP[/b]) == OBJECT_TYPE_WAYPOINT

        && GetTag(oObject) == "spawn")

        {

        CreateObject(OBJECT_TYPE_CREATURE, "nw_chicken", GetLocation(oObject), FALSE);

        }



    oObject = GetNextObjectInArea(OBJECT_SELF);

    }

}[/quote]where does oWP came from? I think it should be oObject



however I don't really understand from your description whats the issue, too much chicken or less?



#6
Rubies

Rubies
  • Members
  • 292 messages
Whoops. It should be oObject, yeah. My mistake. That's a mistake in this script and not the actual one, I'm just bad like that. :P

The issue is that it should only spawn 1 creature per waypoint, where it's spawning multiple. Can't quite understand why, at this point, and after a few hours of fiddling I resorted to asking for a bit of help. :)

Modifié par Rubies, 03 septembre 2010 - 09:20 .


#7
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
The explanation can be found in the link to the thread on the old forms.  This script will work. 
http://nwn.bioware.c...604307&forum=47

  void CreatVoid (object oObject) { }

void main()
{

    object oWP =  GetFirstObjectInArea();

    while(GetIsObjectValid(oWP))
    {
        if(GetObjectType(oWP) == OBJECT_TYPE_WAYPOINT
        && GetTag(oWP) == "spawn")
        {
         DelayCommand(0.1,  CreatVoid(  CreateObject(OBJECT_TYPE_CREATURE, "nw_chicken", GetLocation(oWP), FALSE)));
        }
    oWP = GetNextObjectInArea();
    }
}


Modifié par Lightfoot8, 03 septembre 2010 - 09:27 .


#8
Rubies

Rubies
  • Members
  • 292 messages
Thanks a ton! I Googled it twice but couldn't really find a suitable link. If I wanted to buff a creature spawned by such a wrapper, I assume the only way of doing it would be to include it as part of that, correct?

As in if I wanted to recreate:

object oSpawn = CreateObject(blahblah);
ApplyEffectToObject(blahblah, oSpawn);

Would I have to write it as:

void CreateScaryMonstah(object oSpawn)
{
ApplyEffectToObject(blahblah, oSpawn);
}

It's a fairly minor point, but when you're spawning a few different types of creatures with varying buff amounts it adds up quick. :P

Modifié par Rubies, 03 septembre 2010 - 10:03 .


#9
ehye_khandee

ehye_khandee
  • Members
  • 855 messages

Rubies wrote...

Hi there,

Having a bit of trouble with a script, but I'm assuming the issue is more related to the CreateObject function rather than the loop (or both).

The issue is that there multiple creatures spawned at each waypoint - in my actual module, it spawns four creatures, but trying with chickens spawned about 9, arranged in a neat "]" shape.

I wrote up a quick shortened copy of the script that demonstrates the issue.


void main()
{
object oObject;

    oObject = GetFirstObjectInArea(OBJECT_SELF);

    while(GetIsObjectValid(oObject))
    {

        if(GetObjectType(oObject) == OBJECT_TYPE_WAYPOINT
        && GetTag(oObject) == "spawn")
        {
        CreateObject(OBJECT_TYPE_CREATURE, "nw_chicken", GetLocation(oObject), FALSE);
        }

    oObject = GetNextObjectInArea(OBJECT_SELF);
    }
}



Would it be more appropriate to use something similar to this?


void main()
{
int nNth = 1;

object oObj;

    oObject = GetObjectByTag("spawn", nNth);

    while (GetIsObjectValid(oObject))
    {

        if(GetObjectType(oObject) == OBJECT_TYPE_WAYPOINT)
        {
        CreateObject(OBJECT_TYPE_CREATURE, "nw_chicken", GetLocation(oObject), FALSE);
        }

    ++nNth;
    oObject = GetObjectByTag("spawn", nNth);
    }
}







In the first case, your error (assuming this is running on the OnUse of an object is in line 5 which reads

oObject = GetFirstObjectInArea(OBJECT_SELF);

and should read 

oObject = GetFirstObjectInArea(GetArea(OBJECT_SELF));

... 

that should do it, so I won't bother with the alternate script.

Best wishes.

#10
Rubies

Rubies
  • Members
  • 292 messages

In the first case, your error (assuming this is running on the OnUse of an object is in line 5 which reads



oObject = GetFirstObjectInArea(OBJECT_SELF);



and should read



oObject = GetFirstObjectInArea(GetArea(OBJECT_SELF));



...



that should do it, so I won't bother with the alternate script.



Best wishes.




Thanks for the suggestion, but the GetFirstObjectInArea function uses the caller's area if no GetArea function is used, so GetFirstObjectInArea(OBJECT_SELF) and GetFirstObjectInArea(GetArea(OBJECT_SELF)) have the same result!

#11
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
Yes, Best bet would be to apply the effect in the wrapper.

#12
Rubies

Rubies
  • Members
  • 292 messages
Great, thanks. :)

#13
ehye_khandee

ehye_khandee
  • Members
  • 855 messages
According to the NWN description



// Get the first object in oArea.

// If no valid area is specified, it will use the caller's area.

// *return value on error: OBJECT_INVALID

object GetFirstObjectInArea(object oArea=OBJECT_INVALID)



end quote from script engine ...



The LAST line would indicate oArea if not specified is OBJECT_INVALID, which seems to conflict with the statement of the line above ... test it if you like, but I'll opt for filling in the requested data and be sure it is pointing at the right object.



Just my 2 cents.




#14
Shadooow

Shadooow
  • Members
  • 4 470 messages

ehye_khandee wrote...

According to the NWN description

// Get the first object in oArea.
// If no valid area is specified, it will use the caller's area.
// *return value on error: OBJECT_INVALID
object GetFirstObjectInArea(object oArea=OBJECT_INVALID)

end quote from script engine ...

The LAST line would indicate oArea if not specified is OBJECT_INVALID, which seems to conflict with the statement of the line above ... test it if you like, but I'll opt for filling in the requested data and be sure it is pointing at the right object.

Just my 2 cents.

but he specified the area ;)
OBJECT_SELF is the valid object and he filled it into the function, making GetArea is not needed and only confusing,

EDIT: LightFoot8 solved it, it was due to getfirst/nextobjectinarea messed with createobject. But the GetObjectByTag approach should not have this issue, so It might be better way since you don't need delay and new function and you could declare the effect outside of the while command only once (a bit more efficient than declaring it in the function VoidCreate)

Modifié par ShaDoOoW, 03 septembre 2010 - 10:44 .