Author Topic: AttackReevaluate()  (Read 3299 times)

Offline Galactygon

  • Modding since 2002
  • Planewalker
  • *****
  • Posts: 378
  • Gender: Male
  • Creator of spells
AttackReevaluate()
« on: April 03, 2005, 08:48:49 PM »
For some reason, when I try using AttackReevaluate() as a scripting command, the creature gets stuck in that mode and keeps on attacking the target until the target dies or turns invisible. However, if I use AttackOneRound(), I don't encounter this problem. The trouble with AttackOneRound() is that I cannot use it in a cast and attack situation, nor does it check how the creature is doing until 6 seconds (or one round) passes.

By the way, my script is about 1500 lines long, and I have full of IF blocks starting with an "ActionListEmpty()".

-Galactygon

Offline Vlasák

  • Planewalker
  • *****
  • Posts: 11
  • Gender: Male
Re: AttackReevaluate()
« Reply #1 on: April 04, 2005, 01:33:52 AM »
My idea is probably wrong because as you've said AttackOneRound didn't led to the combat lasts to the death/invisibility of the opponent... but... are there really any trigger that could be valid after the reevalute period above your AttackReevaluate block? - maybe the trigger of this attack block is the only valid after reevaluate.
Baldur's Gate II add-on CZ - TC from Dalelands
http://addoncz.gamestar.cz

English forums are opened!

Offline devSin

  • Planewalker
  • *****
  • Posts: 1632
  • Gender: Male
Re: AttackReevaluate()
« Reply #2 on: April 04, 2005, 03:35:43 PM »
There are several actions that are persistent and don't really get cleared from the queue, and ActionListEmpty() will be false from that point on. It can also lead to cases where the engine will skip blocks if it evaluates them before the last executed actions are completed. Try removing most of the ActionListEmpty() triggers and see if that helps.

Offline Galactygon

  • Modding since 2002
  • Planewalker
  • *****
  • Posts: 378
  • Gender: Male
  • Creator of spells
Re: AttackReevaluate()
« Reply #3 on: April 04, 2005, 05:19:37 PM »
Removing ActionListEmpty() will cause some problems, and using SetInterrupt() will cause the creature to get stuck sometimes (ie if a creature has to walk towads a target and cast a spell, he will continue doing that even if he gets wounded, etc).

-Galactygon

Offline Galactygon

  • Modding since 2002
  • Planewalker
  • *****
  • Posts: 378
  • Gender: Male
  • Creator of spells
Re: AttackReevaluate()
« Reply #4 on: April 04, 2005, 05:21:24 PM »
The only solution that I can think of at the moment is setting a global local when the creature starts attacking, and have a ClearAction somewhere else (if the global local is one).

-Galactygon

Offline SimDing0™

  • Back In Black
  • Global Moderator
  • Planewalker
  • *****
  • Posts: 3496
  • Gender: Male
  • Word Enhancer
Re: AttackReevaluate()
« Reply #5 on: April 04, 2005, 05:21:46 PM »
You might try setting a timer when the attack action starts, and checking either for the timer expiring or ActionListEmpty in an OR block.

Offline Galactygon

  • Modding since 2002
  • Planewalker
  • *****
  • Posts: 378
  • Gender: Male
  • Creator of spells
Re: AttackReevaluate()
« Reply #6 on: April 04, 2005, 05:57:31 PM »
You cannot set timers under 1 round (or at least, I haven't been able to), which makes it work like AttackOneRound().

-Galactygon

Offline SimDing0™

  • Back In Black
  • Global Moderator
  • Planewalker
  • *****
  • Posts: 3496
  • Gender: Male
  • Word Enhancer
Re: AttackReevaluate()
« Reply #7 on: April 04, 2005, 06:06:01 PM »
I'm fairly certain timers under one round do work. It's possible that there's some odd behaviour I've missed, though.

Offline Galactygon

  • Modding since 2002
  • Planewalker
  • *****
  • Posts: 378
  • Gender: Male
  • Creator of spells
Re: AttackReevaluate()
« Reply #8 on: April 18, 2005, 01:44:55 PM »
I managed to solve the problem myself (although, you all did help me, afterall) without eliminating the ActionListEmpty() or using any dirty methods (like summoning a creature and making the summoned creature clear the actions of the summoner). I put to use Sim's idea into action, but I used LOCAL variables rather than LOCAL timers.

I added this to my code:
Code: [Select]
IF
  ActionListEmpty()
  See(NearestEnemyOf(Myself))
THEN
  RESPONSE #100
    SetGlobal("AttackedSomeone","LOCALS",1)
    AttackReevaluate(LastSeenBy(Myself),15)
END

Note that it is mandatory to place the SetGlobal() action before the AttackReevaluation period.

I then placed this at the first line of my script:

Code: [Select]
IF
  Global("AttackedSomeone","LOCALS",1)
THEN
  RESPONSE #100
    SetGlobal("AttackedSomeone","LOCALS",0)
    ClearActions(Myself)
END

-Galactygon

Offline devSin

  • Planewalker
  • *****
  • Posts: 1632
  • Gender: Male
Re: AttackReevaluate()
« Reply #9 on: April 18, 2005, 02:04:36 PM »
Quote
Note that it is mandatory to place the SetGlobal() action before the AttackReevaluation period.
This makes me wonder how, exactly, AttackReevaluate() works. Does it immediately kill the action queue and re-parse the script, or does it fall through to the following actions in the block (or does that only happen if it hits the same block again)?

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1944
  • Gender: Male
    • The Fields of the Dead
Re: AttackReevaluate()
« Reply #10 on: April 18, 2005, 02:40:55 PM »
Maybe it is possible that AttackReevaluate() works differently between the IE games. The AI I have written makes heavy use of AttackReevaluate(), ActionListEmpty() and a CastAndAttack timer to seperate actions.

-Echon

Offline Galactygon

  • Modding since 2002
  • Planewalker
  • *****
  • Posts: 378
  • Gender: Male
  • Creator of spells
Re: AttackReevaluate()
« Reply #11 on: August 12, 2005, 04:20:28 PM »
I have recently found an even better way of coding it than I did back in April, but I thought I might share it in case someone might find it interesting. Here are the steps:

1.) I decided to create a new global local (sounds funny :) ) called "ActionList" that is set to one right before the creature attacks:

Code: [Select]
IF
  ...
THEN
  RESPONSE #100
    SetGlobal("ActionList","LOCALS",1)
    AttackReevaluate(LastSeenBy(Myself),15)
END

I then accompanied every single scripting block that had on ActionListEmpty() with an "OR".

Code: [Select]
IF
  OR(2)
    ActionListEmpty()
    Global("ActionList","LOCALS",1)
  ...
THEN
  ...
END
So every scripting block will either be executed when I am free of all actions OR if I have "ActionList" set to one (meaning the creature is in the middle of an action that doesn't trigger ActionListEmpty() such as RandomWalkContinuous() or AttackReevaluate() )

And lastly, don't forget to reset the variable to zero before the creature starts executing an action that can be interrupted with an ActionListEmpty().

Code: [Select]
IF
  ...
THEN
  RESPONSE #100
    SetGlobal("ActionList","LOCALS",0)
    ...
END

I think it would be a good idea to place this in the scripting guide Sim has assembled for us.

-Galactygon

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
What color is grass?:
What is the seventh word in this sentence?:
What is five minus two (use the full word)?: