Aller au contenu

Photo

Objects and while looping, bug?


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

#1
kamal_

kamal_
  • Members
  • 5 240 messages
I'm not sure if this is something I'm missing, or a bug in NWN2's handling of this, so I wanted to put it out there. I was getting some unexpected behavior with my npc's not going to waypoints they should be. I started adding some error checking debug messages, and things got weird.

The following will sometimes return a blank tag in the debug message. (A waypoint with this tag is always present.)
object oWp1 = GetRandomObjectByTag ("wp_com_npcguitar",fMaxDistance);
SendMessageToPC(oPC, "Debug: DoActivity, switch case guitar while loop " + GetTag(oWp1));


This while loop does not break out when the object is tagged "wp_com_npcguitar", it loops forever (until the game engine ends it). Additionally, the debug message printed sometimes returns a blank tag.

while (GetTag(oWp1)!="wp_com_npcguitar")
{
object oWp1 = GetRandomObjectByTag ("wp_com_npcguitar",fMaxDistance);
SendMessageToPC(oPC, "Debug: DoActivity, switch case guitar while loop " + GetTag(oWp1));
}



This while loop properly breaks out. However, the if statement in it just enforces what it should already be doing as a while loop.

int nCheck =0;
while ((GetTag(oWp1)!="wp_com_npcguitar") && (nCheck == 0))
{
object oWp1 = GetRandomObjectByTag ("wp_com_npcguitar",fMaxDistance);
if (GetTag(oWp1) =="wp_com_npcguitar")
{
nCheck =1;
}
SendMessageToPC(oPC, "Debug: DoActivity, switch case guitar while loop " + GetTag(oWp1));
}

#2
kevL

kevL
  • Members
  • 4 056 messages
kam_

i recall, when looking at the #include a week or so ago, that 'object oWp1' was defined twice in the same scope - Sky's ASC immediately pointed it out and refused to compile. This repeated in many if not all functions,

just looking at the line

object oWp1 = GetRandomObjectByTag ("wp_com_npcguitar",fMaxDistance);

after

while (GetTag(oWp1)!="wp_com_npcguitar")

tells me that 'oWp1' is *still* getting defined multiple times ... ie, "object oWp1 = " repeats when it should be simply "oWp1 = " the second or more times.


Strongly suggest making the jump to the ASC if you haven't, it points to issues and potential issues before they become problems ( gives excellent error messages )

in fact Everyone should be using the ASC - it's a simple drag&drop to install the plug-in,

#3
kamal_

kamal_
  • Members
  • 5 240 messages
Then I'm doing something wrong with the ASC, I have it installed (and have for some time). I'm not getting any error messages.

Modifié par kamal_, 31 mars 2012 - 10:54 .


#4
MasterChanger

MasterChanger
  • Members
  • 686 messages
I believe that kevL is on to something. The term should be "declared" rather than "defined" though: you can use "
oWp1 = ....
" any number of times, but "
object oWp1...
" should only appear once. I believe that the compiler (without the Advanced Script Compiler plugin) will actually throw an error if you declare an object within a loop for this reason.

Modifié par MasterChanger, 31 mars 2012 - 11:21 .


#5
kamal_

kamal_
  • Members
  • 5 240 messages
removing the "object' and the nCheck stuff, the error comes back. As you can see in the picture, the first debug DoActivity statement says the tag is blank even though it was assigned immediately prior.

http://dl.dropbox.co...3112_193733.jpg

//Standard guitar/lute behavior for NPC
void NpcGuitar (object oNpc, object oWp1, int nSpeak)
{
//inject randomizing code. Kamal
oWp1 = GetRandomObjectByTag ("wp_com_npcguitar",fMaxDistance);
object oPC =GetFirstPC(); //for debug, kamal
SendMessageToPC(oPC, "Debug: DoActivity, switch case guitar tag " + GetTag(oWp1));
int nCheck =0;
while (GetTag(oWp1)!="wp_com_npcguitar")
{
oWp1 = GetRandomObjectByTag ("wp_com_npcguitar",fMaxDistance);
SendMessageToPC(oPC, "Debug: DoActivity, switch case guitar while loop " + GetTag(oWp1));
}
ClearFlags (oNpc);
NpcEquipItemRight(oNpc);
float fNpc = GetFacing (oNpc);
float fDwp2 = GetFacing (oWp1);
if (fNpc != fDwp2){SetFacing(fDwp2);}

etc..

Modifié par kamal_, 31 mars 2012 - 11:42 .


#6
MasterChanger

MasterChanger
  • Members
  • 686 messages

kamal_ wrote...
oWp1 = GetRandomObjectByTag ("wp_com_npcguitar",fMaxDistance);
SendMessageToPC(oPC, "Debug: DoActivity, switch case guitar while loop " + GetTag(oWp1));


I would try sticking a check in between these two lines to make sure that oWp1 is a valid object. You don't really know if the problem is with the tag or finding the object is my suspicion.

#7
kevL

kevL
  • Members
  • 4 056 messages
I think it's (not) finding the object; take a look at :

// Get a random nearby object within the specified distance with
// the specified tag.
object GetRandomObjectByTag(string sTag, float fMaxDistance)
{
  int nNth;
  if (fMaxDistance == DISTANCE_SHORT) {
    nNth = d2();
  } else if (fMaxDistance == DISTANCE_MEDIUM) {
    nNth = d4();
  } else {
    nNth = d6();
  }
  object oObj = GetNearestObjectByTag(sTag, OBJECT_SELF, nNth);
  if (GetIsObjectValid(oObj) && GetDistanceToObject(oObj) <= fMaxDistance)
    return oObj;
  return OBJECT_INVALID;
}

above, says it's possible the function is 'finding' an object w/ tag("wp_com_npcguitar") *that does not exist*, when nNth is greater than the number of objects w/ tag("wp_com_npcguitar") in the area. Personally i'd rewrite the function, to count the number of said objects first, then choose randomly among them,


ps. tks MC, my bad

Edit, Or if a custom float is being used for fMaxDistance, the function would always 'find' the 0th object - is that even valid?

Modifié par kevL, 01 avril 2012 - 12:03 .


#8
kevL

kevL
  • Members
  • 4 056 messages
kam_
there's got to be something uhm quirky about your methodology then, 'cause MC is prob. very right that the standard compiler would throw an error, and I'm certain the ASC does

#9
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
@kamal: just remove the second 'object', the first one (outside the while loop) is necessary. The second one (inside the while loop) creates a new variable each time the loop goes round, when then gets dumped at the end of the loop. That's why the check at the beginning of the loop is coming up empty, the variable it's looking at has already been dumped.

It should look like:

object oWP = blah blah;
while (oWP != WP I'm looking for) {
oWP = get another WP;
}

I would use GetNearestObject though, with an int that increments each time round, getting the nth furthest WP. That way, the NPCs stay fairly local, instead of roaming the whole area. Also, you never try to move to a WP in another area, nor do you run the risk of an infinite loop if the script never manages to randomly find the right WP.

int iTer = 1;
object oWP = GetNearestObject(...iTer);
while (GetIsObjectValid(oWP) && (GetTag(oWP) != blahblah)) {
iTer++;
oWP = GetNearestObject(....iTer);
}
if (GetIsObjectValid(oWP)) {
Yea! I found the right WP!;
}
else {
Oh noes! the WP don't exist in this area!;
}

#10
kamal_

kamal_
  • Members
  • 5 240 messages
KevL_ since you know the ASC works for you, try compiling all in
http://dl.dropbox.co...9894/ai_test.7z
the relevant scripts are the
sh_npc_leg_oh
sh_npc_activeinc
sh_npc_include

Lugaid:
fMaxDistance is a float defined at the beginning of the script (it happens to be 5000.00 while I'm testing). So when I have
oWp1 = GetRandomObjectByTag ("wp_com_npctrainingone", fMaxDistance);
that should ensure the npc stays within a local area. You do have a point for a sanity check to make sure the wp exists.

Modifié par kamal_, 01 avril 2012 - 12:38 .


#11
kevL

kevL
  • Members
  • 4 056 messages
okay, it looks much cleaner than before; just getting a warning :

> Compiling: sh_npc_activinc.NSS

> Warning: NSC6023: Function "NpcFollowPC" argument "iHurry" default value does not match the initializer value for a previous declaration. The first declaration value will be used.

It means the prototype at the top of the script has a different argument for iHurry than the declaration/definition found down in the body, note this didn't show up fer me in the toolset, only with the standalone ASC.

sh_npc_leg_oh compiles fine,



--------
C:\\Documents and Settings\\kL\\My Documents\\Neverwinter Nights 2\\override\\kamal_aiTest>f:\\asc -glo -v1.69 -y *.nss
NWNScriptCompiler - built Jan 21 2012 15:45:53
Copyright © 2008-2011 Skywing.
Portions copyright © 2003-2003, Edward T. Smith.
Portions copyright © 2003, The Open Knights Consortium.
Loading base game resources...
Compiling: b_sls2_npc_ud.NSS
Compiling: ga_sls2_changeblueprints.NSS
ga_sls2_changeblueprints.nss(14): Warning: NSC6010: Entry point function "main" has a default value for argument "sTag", but the runtime will select default argument values from a hardcoded list of defaults for script entry point symbols. Consider removing explicit default arguments from the function and handling the actual runtime default values (which are zero, OBJECT_INVALID, and an empty string, as appropriate).

ga_sls2_changeblueprints.nss(14): Warning: NSC6010: Entry point function "main" has a default value for argument "sNewLightBP", but the runtime will select default argument values from a hardcoded list of defaults for script entry point symbols. Consider removing explicit default arguments from the function and handling the actual runtime default values (which are zero, OBJECT_INVALID, and an empty string, as appropriate).
ga_sls2_changeblueprints.nss(14): Warning: NSC6010: Entry point function "main" has a default value for argument "sNewVfxBP", but the runtime will select default argument values from a hardcoded list of defaults for script entry point symbols. Consider removing explicit defaultarguments from the function and handling the actual runtime default values (which are zero, OBJECT_INVALID, and an empty string, as appropriate).
ga_sls2_changeblueprints.nss(14): Warning: NSC6010: Entry point function "main" has a default value for argument "bDelay", but the runtime will select default argument values from a hardcoded list of defaults for script entry point symbols. Consider removing explicit default arguments from the function and handling the actual runtime default values (which are zero, OBJECT_INVALID, and an empty string, as appropriate).
Compiling: ga_sls2_lightevent_area.NSS
Compiling: ga_sls2_lightevent_object.NSS
Compiling: ga_sls2_lightevent_shape.NSS
Compiling: gc_sls2_checkstate.NSS
gc_sls2_checkstate.nss(15): Warning: NSC6010: Entry point function "StartingConditional" has a default value for argument "sFitting", but the runtime will select default argument values from a hardcoded list of defaults for script entry point symbols. Consider removing explicitdefault arguments from the function and handling the actual runtime default values (which are zero, OBJECT_INVALID, and an empty string, asappropriate).
Compiling: ginc_sls2.NSS
ginc_sls2.nss is an include file, ignored.
Compiling: i_sls2_lightrod_ac.NSS
Compiling: npc_activinc.NSS
npc_activinc.nss is an include file, ignored.
Compiling: npc_default1.NSS
Compiling: npc_display_time.NSS
Compiling: npc_include.NSS
npc_include.nss is an include file, ignored.
Compiling: npc_leg_oh.NSS
Compiling: npc_oc_enter.NSS
Compiling: npc_open_ob.NSS
Compiling: npc_speak.NSS
npc_speak.nss is an include file, ignored.
Compiling: p_sls2_fitting_ud.NSS
Compiling: p_sls2_fitting_us.NSS
Compiling: p_sls2_sundial_us.NSS
Compiling: script1.NSS
script1.nss is an include file, ignored.
Compiling: script2.NSS
script2.nss(1): Error: NSC1040: Syntax error at "if"
Compilation aborted with errors.
Error: Failed to process file "Script2.nss".
Compiling: script3.NSS
script3.nss(2): Error: NSC1040: Syntax error at "if"
Compilation aborted with errors.
Error: Failed to process file "Script3.nss".
Compiling: script4.NSS
script4.nss(2): Error: NSC1040: Syntax error at "if"
Compilation aborted with errors.
Error: Failed to process file "Script4.nss".
Compiling: script5.NSS
script5.nss(1): Error: NSC1040: Syntax error at "if"
Compilation aborted with errors.
Error: Failed to process file "Script5.nss".
Compiling: script6.NSS
script6.nss(2): Error: NSC1040: Syntax error at "if"
Compilation aborted with errors.
Error: Failed to process file "Script6.nss".
Compiling: script7.NSS
script7.nss(2): Error: NSC1040: Syntax error at "while"
script7.nss(5): Error: NSC1040: Syntax error at "if"
Compilation aborted with errors.
Error: Failed to process file "Script7.nss".
Compiling: sh_npc_actions.NSS
sh_npc_actions.nss is an include file, ignored.
Compiling: sh_npc_activinc.NSS
sh_npc_activinc.nss is an include file, ignored.
Compiling: sh_npc_activinc1.NSS
sh_npc_activinc1.nss is an include file, ignored.
Compiling: sh_npc_activinc_backup.NSS
sh_npc_activinc_backup.nss is an include file, ignored.
Compiling: sh_npc_activinc_old.NSS
sh_npc_activinc_old.nss is an include file, ignored.
Compiling: sh_npc_alternate_base.NSS
Compiling: sh_npc_barmaid.NSS
Compiling: sh_npc_bartender.NSS
Compiling: sh_npc_bminc.NSS
sh_npc_bminc.nss is an include file, ignored.
Compiling: sh_npc_default1.NSS
Compiling: sh_npc_default_original.NSS
Compiling: sh_npc_display_time.NSS
Compiling: sh_npc_include.NSS
sh_npc_include.nss is an include file, ignored.
Compiling: sh_npc_include1.NSS
sh_npc_include1.nss is an include file, ignored.
Compiling: sh_npc_include2.NSS
sh_npc_include2.nss is an include file, ignored.
Compiling: sh_npc_include3.NSS
sh_npc_include3.nss is an include file, ignored.
Compiling: sh_npc_include4.NSS
sh_npc_include4.nss is an include file, ignored.
Compiling: sh_npc_include5.NSS
sh_npc_include5.nss is an include file, ignored.
Compiling: sh_npc_include6.NSS
sh_npc_include6.nss is an include file, ignored.
Compiling: sh_npc_include7.NSS
sh_npc_include7.nss is an include file, ignored.
Compiling: sh_npc_leg_oh.NSS
sh_npc_activinc.nss(3060): Warning: NSC6023: Function "NpcFollowPC" argument "iHurry" default value does not match the initializer value for a previous declaration. The first declaration value will be used.
Compiling: sh_npc_leg_oh1.NSS
sh_npc_activinc.nss(3060): Warning: NSC6023: Function "NpcFollowPC" argument "iHurry" default value does not match the initializer value for a previous declaration. The first declaration value will be used.
Compiling: sh_npc_leg_oh_backup.NSS
sh_npc_activinc.nss(3060): Warning: NSC6023: Function "NpcFollowPC" argument "iHurry" default value does not match the initializer value for a previous declaration. The first declaration value will be used.
Compiling: sh_npc_leg_oh_backup2.NSS
sh_npc_activinc.nss(3060): Warning: NSC6023: Function "NpcFollowPC" argument "iHurry" default value does not match the initializer value for a previous declaration. The first declaration value will be used.
Compiling: sh_npc_leg_oh_backup3.NSS
sh_npc_activinc.nss(3060): Warning: NSC6023: Function "NpcFollowPC" argument "iHurry" default value does not match the initializer value for a previous declaration. The first declaration value will be used.
Compiling: sh_npc_oc_enter.NSS
Compiling: sh_npc_open_ob.NSS
Compiling: sh_npc_randomizer.NSS
sh_npc_randomizer.nss is an include file, ignored.
Compiling: sh_npc_speak.NSS
sh_npc_speak.nss is an include file, ignored.
Compiling: sh_npc_speak_backup.NSS
sh_npc_speak_backup.nss is an include file, ignored.
Compiling: sls2_heartbeat.NSS
Compiling: sls2_onenter.NSS
Compiling: tr_sls2_chainoff_en.NSS
Compiling: tr_sls2_chainon_en.NSS
Compiling: tr_sls2_off_en.NSS
Compiling: tr_sls2_oneshot_en.NSS
Compiling: tr_sls2_on_en.NSS
Compiling: tr_sls2_pressure_en.NSS
Compiling: tr_sls2_pressure_ex.NSS
6 error(s); see above for context.
Total Execution time = 6796ms


not bad :)

Modifié par kevL, 01 avril 2012 - 02:14 .


#12
kevL

kevL
  • Members
  • 4 056 messages
you're right, so much for certainty.

re-declaring oWp1 didn't throw an error, (when it is in a subscope)

#13
kamal_

kamal_
  • Members
  • 5 240 messages

kevL wrote...

okay, it looks much cleaner than before; just getting a warning :

> Compiling: sh_npc_activinc.NSS

> Warning: NSC6023: Function "NpcFollowPC" argument "iHurry" default value does not match the initializer value for a previous declaration. The first declaration value will be used.

It means the declaration at the top of the script has a different argument for iHurry than the definition found down in the body, note this didn't show up fer me in the toolset, only with the standalone ASC.

sh_npc_leg_oh compiles fine,

Good. I've been trying to clean things up to clarify the sources of any logic problems.

I must have messed NpcFollowPC up in my attempts to combine UncleFB and Lugaid's scripts into a unified set of code. There's been a lot of use of find and replace. It's not being used in the test area yet, so it shouldn't affect anything.

Those other errors are from scripts included for testing purposes, like the sls code that makes changing time easy, backup copies of scripts, and "scripts" that are just text for copy/paste (the script1 ->script7).

Even cleaned up, I'm still seeing invalid tagmessages. The while loop catches them and fixes them, and my npcs seem to be better about moving to their waypoints. I still see the debug invalid tag messages with regularity, that means that if it was released in this state, the invalid tag debug to catch when a builder left out the necessary waypoints would have to be removed, since it's generating the message when the required waypoints are present. Still, much improved from when I posted this thread.

#14
kevL

kevL
  • Members
  • 4 056 messages
i honestly think the problem, now is in GetRandomObjectByTag( )

let me take a shot at rewriting that ...


// Get a random nearby object within the specified distance with
// the specified tag.
// 2012 march 31, kevL's
//    - modified to count number of objects and
//    not return an object_count greater than that

// Distances used for determining positions
//  const float DISTANCE_TINY = 1.0;
//  const float DISTANCE_SHORT = 3.0;
//  const float DISTANCE_MEDIUM = 5.0;
//  const float DISTANCE_LARGE = 10.0;
//  const float DISTANCE_HUGE = 20.0;

// kL, those are declared (grrr) in 'x0_i0_position'
// but they seem a bit too small ...


#include "x0_i0_position"

object kL_GetRandomObjectByTag(string sTag, float fMaxDistance)
{
  int iObject; object oObject;
  int i = 1;

  object oNear = GetNearestObjectByTag(sTag, OBJECT_SELF, i);
  // GetNearest seems to work only in the area of OBJECT_SELF, good.
  while (GetIsObjectValid(oNear))
  {
    i ++;
    oNear = GetNearestObjectByTag(sTag, OBJECT_SELF, i);
  }
  // count is one too many ..
  i -= 1;


  if (fMaxDistance <= DISTANCE_SHORT)
  {
    iObject = d2();
  }
  else if (fMaxDistance <= DISTANCE_MEDIUM)
  {
    iObject = d4();
  }
  else if (fMaxDistance <= DISTANCE_LARGE)
  {
    iObject = d6();
  }
  else
  {
    // Random starts w/ 0 (subtract 1), so add 1
    iObject = Random(i) + 1;

    // iObject -> that's a pun, haha :|
  }

  // max the count at the number of objects, i
  if (iObject > i) iObject = i;

  oObject = GetNearestObjectByTag(sTag, OBJECT_SELF, iObject);
  if (GetIsObjectValid(oObject) && GetDistanceToObject(oObject) <= fMaxDistance)
  {
    return oObject;
  }

  return OBJECT_INVALID;
}


//void main(){}


edit, oops ... ok, hold on a minute ... Done

Modifié par kevL, 01 avril 2012 - 04:57 .


#15
kamal_

kamal_
  • Members
  • 5 240 messages
I subbed in your script (thank goodness for find-> replace), and did some testing. I am no longer getting the debug invalid tag messages.

I've included that code and credited you with a link to your post and use of your function name (and credit on release of course).

#16
kevL

kevL
  • Members
  • 4 056 messages
k, Tks
( I just don't want it bugged when i Play it :)

btw, found a slight hole: it is *possible* an object outside fMaxDistance will return invalid. but only when the number of objects is greater than fMaxDistance if that makes any sense ;p

#17
kamal_

kamal_
  • Members
  • 5 240 messages
What is the reasoning for the
iObject = dx();
lines in the different ranges? The else case seems to cover all distances and any number of objects.

I changed it a bit, putting a GetDistance check in the while loop, that should remove the hole you found, objects out of range are never counted. I also removed the if distance, dx() checks.

object kL_GetRandomObjectByTag(string sTag, float fMaxDistance)
{
    int iObject; object oObject;
    int i = 1;   
    object oNear = GetNearestObjectByTag(sTag, OBJECT_SELF, i);
      // GetNearest seems to work only in the area of OBJECT_SELF, good.
      while ((GetIsObjectValid(oNear)) && (GetDistanceToObject(oObject) <= fMaxDistance))
          {
        i ++;
        oNear = GetNearestObjectByTag(sTag, OBJECT_SELF, i);
          }
      // count is one too many ..
      i -= 1;
       // Random starts w/ 0 (subtract 1), so add 1
       iObject = Random(i) + 1;         // iObject -> that's a pun, haha :|
      // max the count at the number of objects, i
      if (iObject > i) iObject = i;
    oObject = GetNearestObjectByTag(sTag, OBJECT_SELF, iObject);
      if (GetIsObjectValid(oObject) && GetDistanceToObject(oObject) <= fMaxDistance)
          {
        return oObject;
          }
    return OBJECT_INVALID;
}

edit: corrected the bracketing of (GetDistanceToObject(oObject) <= fMaxDistance))

Modifié par kamal_, 01 avril 2012 - 11:03 .


#18
kevL

kevL
  • Members
  • 4 056 messages
heya, yeah

the function may originally have been designed for something very specific, where the number of objects were standardized, hence the close relation between distance and # of objects. I'm glad to see it take on a more general form and had left those checks in there, mainly for 'backward compatibility'. Ie, in case you yerself had used float consts, or had arranged the objects such that dx( ) made practical sense.

I'd be a little leary of the additional while( ) check, tho. Eg, what if the engine-search for objects finds an object outside the radius before finding all those inside the radius? i doubt it ever happens that way, but if it did the loop would end prematurely. I suggest using it like you have it, and if empty tags pop up again an object never gets found, that becomes a suspect. ( A more proper way to do the same thing would be defining the circle via GetFirst/NextObjectInShape, which I think would be a good idea if/when the function gets rewritten again )

Otherwise, i like the changes ....

Modifié par kevL, 01 avril 2012 - 11:28 .


#19
kamal_

kamal_
  • Members
  • 5 240 messages
Clarified a bit with an extra parenthesis.

I emailed Uncle FB, since I'm having an issue with a couple of other things.

An npc that is walking to their next destination maintains the "arm pose" of a previous activity until they reach their destination? eg: holding an invisible lute for instance.

Once they reach their destination, they do not start playing the animation. They were previously doing so at least some of the time.

PJ156 says he hasn't seen that behavior, and he's the biggest user of Uncle FB. Actually he said he did see "invisible lute", but Uncle FB had fixed it (in the version I based off of). I didn't think I broke anything in my adaptation of the original code, but apparently have done so.

edit: clarified that it's the arms that remain in position, the npc's legs walk correctly, no "skating".

Modifié par kamal_, 01 avril 2012 - 11:43 .


#20
kevL

kevL
  • Members
  • 4 056 messages
i'm not much w/ animations,
but skaters and dead-standers etc. seem more related to the whims of personal computers than scripts - you could try what Lugaid's been trying by using ClearAllActions( ) or even adding a line that plays the IdleAnimation (?) right before the NPC is given the command to walk to next WP,

then something similar when they reach their destination and need to play/chop/etc. Basically i'm wondering if forcing PlayCustomAnimation line at each NPC interval helps

#21
kamal_

kamal_
  • Members
  • 5 240 messages
They're not skating, they walk but their arms remain in the "holding lute" position. When the reach position they correctly turn to the right facing and equip their item, but the animation for the new action doesn't begin. They do stop the "invisible lute" arm position for the "arms at side" position when they reach the target waypoint and equip their item.

I suspect that the animation's not playing because it's stuck in the position of the previous animation. I did try a ClearAllActions as the first part of the two actions I'm currently testing, guitar and woodsman. Didn't seem to do anything. Will have to do further testing when I get a chance this week.

#22
kevL

kevL
  • Members
  • 4 056 messages
ko, luxorz!

#23
Shallina

Shallina
  • Members
  • 1 011 messages
your loop check for an abject with a tag. As long of one of those exist it will run.

You need to change the tag of the object you checked so it won't be selected again.

#24
kamal_

kamal_
  • Members
  • 5 240 messages

Shallina wrote...

your loop check for an abject with a tag. As long of one of those exist it will run.

You need to change the tag of the object you checked so it won't be selected again.

The problems, now solved, were that the while was not exiting when it found an object with the tag. The second problem was that it would not detect that an object had the tag even though there was one and the tag was set immediately prior to the loop.

I'm not sure if you're aware what I am doing with the code, changing the tag, and later resting the tag, would prevent multiple selections of the same waypoint, but likely cause worse problems.

#25
kamal_

kamal_
  • Members
  • 5 240 messages
Stupid mobile won't let me clarify. I am aware duplicate choice of a waypoint will cause some bugs. For many actions it won't particularly matter if it happens, a generic commoner not standing right on a waypoint for cheering because they got bumped by another generic commoner isn't really a big deal. In fact that already happens in my test area since I have 5 test npcs and the test area only has 4 waypoints for the actions I'm testing.

It would be a problem for some actions where you do really want to make sure the commoners are at a waypoint, sitting for instance. So yes ultimately it will be something to be worked out. I need to get things working in general first though. I don't want to put in code for multiple issues at the same time only to find trying to do that confuses what's going on further.

There's a couple possible approaches, and one is indeed to rename a waypoint that is currently "in use". I believe that approach may generate issues with timing, but who knows at this point. There are a couple other approaches I can think of, but I don't plan to address the issue until I am confident I have other issues successfully resolved so I can minimize variables in what I am testing.