Skip to content

Huge problems with "While" scripts

I'm having huge problems getting while scripts to work. Here is an example of the type of script I'm talking about, the sort you might have say, if you have a party enter a really cold room and want to do cold damage to them, as an example

void main()
{

//DEFINE STUFF
//
  object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, ///);
  while(GetIsObjectValid(///))
  {
      
      if (//	WHATEVER CHECKS))
      {
            //DO WHATEVER
           
      }
}
      oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, ///);
   }
}

I'm putting this script on AreaHeartbeat, because I want the script to fire every round.

The trouble I'm having is that I get the too many operands error in game, other time the game will crash and sometimes the script file will even corrupt, requiring a brand new script file to be made.

I would prefer using this sort of script if possible otherwise I would need to create a script many times longer script to define every object that could possibly enter a radius

Any scripting Wizards have advice?

Comments

  • TarotRedhandTarotRedhand Member Posts: 1,481
    Very quick guesses. First I think you mean a TMI instruction. Too Many Instructions. This is most likely because you are using an actual (6 second) heartbeat and it's firing before your function has finished meaning that another instance of your function is running at the same time ad infinitum until it runs out of script memory. Consider trying a pseudo heartbeat instead.

    TR
  • nwfan87nwfan87 Member Posts: 99
    @TarotRedhand That's correct, it is the TMI error. I'm using the while script on a "onheartbeat" event. If using a Pseudo heartbeat is a better alternative, are there online resources on how to do that (something on lexicon maybe)? Would save a lot of resources If those scripts could replace some of the onheartbeat scripts, where it wouldn't be such a strain on the system.
  • meaglynmeaglyn Member Posts: 149
    TMI is caused by a single script running usually in an infinite loop. it has nothing to do with 6 second HB and running another version of the script. The engine is pretty much single threaded and will only run one script at a time.

    The code you show is not all that helpful due to all the stuff you cut out but... you have the loop closing } before you change your loop condition variable, so that, as shown (aside from it not compiling), will be an infinite loop. You have to update oTarget in the loop. If you post the actual script without cutting out bits we can help more.

    That said if you have a large number of objects you could hit TMI just in the loop but that is very unlikely. It used to happen some in the various AI routines but usually in modified versions and with loops in loops etc. Also if you create an object in the shape in your loop that could be a problem too... but again, not enough info in that script snippet.
  • ProlericProleric Member Posts: 1,286
    while(GetIsObjectValid(oTarget))
    
    would fix the TMI.
  • nwfan87nwfan87 Member Posts: 99
    @Proleric That would help, missed in this (as described by @meaglyn) bad example.

    @meaglyn, here is a better and compiled example of the sort of thing I meant.

    
    //AN EXAMPLE SCRIPT. THE PILLAR FIRES AN ICE DAGGER WHEN THERE IS AN UNFRIENDLY TARGET WITHIN THE GIVEN RADIUS
    void main()
    {
    
    object oPillar = OBJECT_SELF;
    location lLocation = GetLocation(oPillar);
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLocation);
    while(GetIsObjectValid(oTarget))
      {
        if (!GetIsReactionTypeFriendly(oTarget))
          {
            SignalEvent(oPillar, EventSpellCastAt(oTarget, SPELL_ICE_DAGGER));
          }
       }
          oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLocation);
       }
    

    I know certain objects for various reasons do not cast certain spells very well, but really, just asking about the logic of the script.
  • TarotRedhandTarotRedhand Member Posts: 1,481
    The line -
    oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLocation);
    
    is in the wrong place. Where you have it will effectively do nothing because it is outside the while loop. Your code should look like -
    //AN EXAMPLE SCRIPT. THE PILLAR FIRES AN ICE DAGGER WHEN THERE IS AN UNFRIENDLY TARGET WITHIN THE GIVEN RADIUS
    
    void main()
    {
        object oPillar = OBJECT_SELF;
        location lLocation = GetLocation(oPillar);
        object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLocation);
        while(GetIsObjectValid(oTarget))
        {
            if (!GetIsReactionTypeFriendly(oTarget))
                SignalEvent(oPillar, EventSpellCastAt(oTarget, SPELL_ICE_DAGGER));
    
            oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLocation);
        }
    }
    
    TR
  • nwfan87nwfan87 Member Posts: 99
    @TarotRedhand I'll have to try that and see what the results are. :)
  • meaglynmeaglyn Member Posts: 149
    What TR said... is what I said earlier :) What you have there is an infinite loop -- or rather a TMI loop since it will stop when it reaches the instruction count limit ...
  • nwfan87nwfan87 Member Posts: 99
    @TarotRedhand @meaglyn Thank you for this. Was able to test it out on the intended script. That seems to have done the trick, thank you very much for your help! :)
Sign In or Register to comment.