// Call Shot IF See(NearestEnemyOf(Myself)) HaveSpell(3121) Delay(10) THEN RESPONSE #100 Spell(Myself,3121) END
Custom AI Script Question
Started by
-DSlaytern-
, Nov 15 2002 04:53 AM
5 replies to this topic
#1 -DSlaytern-
Posted 15 November 2002 - 04:53 AM
I am trying to make my Archer use Call Shot, but for some reason, I am having difficulty doing so.
#2
Posted 15 November 2002 - 08:40 AM
I am pretty sure that Delay() is an Action, not a Trigger, so you would want to remove it from the Triggers section of your script.
IF
See() Is a trigger // if See() returns true
HaveSpell() Is a trigger // and if HaveSpell() returns true
THEN
RESPONSE #100
Spell() Is an Action // Cast this spell on the appropriate target
END
_______________
IF
See(NearestEnemyOf(Myself))
HaveSpell(3121)
!GlobalTimerNotExpired("DS_ARCHER_CALL_SHOT","LOCALS")
THEN
RESPONSE #100
SetGlobalTimer("DS_ARCHER_CALL_SHOT","LOCALS",60)
Spell(Myself,3121)
END
Setting the Global Timer will help prevent a re-cast of the spell, while you are still under the affects of the first spell, because it says, Archer Call Shot lasts for 60 seconcd or 10 rounds or 1 turn. So if I have cast it in the past turn, then I don't want both of my triggers coming true, which will prevent the re-cast of the spell.
Cirerrek
IF
See() Is a trigger // if See() returns true
HaveSpell() Is a trigger // and if HaveSpell() returns true
THEN
RESPONSE #100
Spell() Is an Action // Cast this spell on the appropriate target
END
_______________
IF
See(NearestEnemyOf(Myself))
HaveSpell(3121)
!GlobalTimerNotExpired("DS_ARCHER_CALL_SHOT","LOCALS")
THEN
RESPONSE #100
SetGlobalTimer("DS_ARCHER_CALL_SHOT","LOCALS",60)
Spell(Myself,3121)
END
Setting the Global Timer will help prevent a re-cast of the spell, while you are still under the affects of the first spell, because it says, Archer Call Shot lasts for 60 seconcd or 10 rounds or 1 turn. So if I have cast it in the past turn, then I don't want both of my triggers coming true, which will prevent the re-cast of the spell.
Cirerrek
-cirerrek Cirerrek's IE Miscellania
#3
Posted 15 November 2002 - 08:52 AM
Delay is also a trigger. Loosely, Delay(N) is true if the internal game time (in seconds) modulo N is 0.
The problem you are running into is well-established: HaveSpell() doesn't work very well for innate abilities. In fact, in earlier versions of SoA calling HaveSpell on some obscure ones (Mazzy's courage things spring to mind) would crash the game.
I suggest that you either use something else to keep track of what is going on, or just always assume that you have the spell. Spell() won't cast it if you don't. Don't ask why they didn't use that logic for computing HaveSpell().
The problem you are running into is well-established: HaveSpell() doesn't work very well for innate abilities. In fact, in earlier versions of SoA calling HaveSpell on some obscure ones (Mazzy's courage things spring to mind) would crash the game.
I suggest that you either use something else to keep track of what is going on, or just always assume that you have the spell. Spell() won't cast it if you don't. Don't ask why they didn't use that logic for computing HaveSpell().
#4
Posted 15 November 2002 - 03:23 PM
Ah, I was not aware that Delay() was also a trigger. Wesley, could you draw up heavily commented snippet on how you would use Delay() as a trigger, please? For some reason, I a not quite grasping what you have said here.
Wesley is correct in that some of the innate abilties did not work with HaveSpell() checks and some would actually crash your game. The reason they didn't work is that these abilities should have had their Spell Level set to 1, but they did not, as shipped with the game. I don't remember ARCHER_CALL_SHOT as being one that was a problem, but I could be wrong about that.
A workaround for the HaveSpell() crash problem is to do something like this.
// * This workaround requires the corrected version of Kit.IDS file
// * Top of the script somewhere
// * Variable Reset
IF
PartyRested()
THEN
RESPONSE #100
SetGlobal("DS_USED_ARCHER_CALL_SHOT","LOCALS",0)
END
// * Get 1 at level 1, 2 at level 5, 3 at level 9, 4 at level 13 etc.,.
// * 9th-12th level
IF
See(NearestEnemyOf(Myself))
KIT(Myself,ARCHER)
CheckStatGT(Myself,8,LEVEL)
CheckStatLT(Myself,13,LEVEL)
!GlobalTimerNotExpired("DS_ARCHER_CALL_SHOT","LOCALS")
GlobalLT("DS_USED_ARCHER_CALL_SHOT","LOCALS", 3)
THEN
RESPONSE #100
IncrementGlobal("DS_USED_ARCHER_CALL_SHOT","LOCALS", 1)
SetGlobalTimer("DS_ARCHER_CALL_SHOT","LOCALS",60)
Spell(Myself,3121)
END
// * 5th-8th level
IF
See(NearestEnemyOf(Myself))
KIT(Myself,ARCHER)
CheckStatGT(Myself,4,LEVEL)
CheckStatLT(Myself,9,LEVEL)
!GlobalTimerNotExpired("DS_ARCHER_CALL_SHOT","LOCALS")
GlobalLT("DS_USED_ARCHER_CALL_SHOT","LOCALS", 2)
THEN
RESPONSE #100
IncrementGlobal("DS_USED_ARCHER_CALL_SHOT","LOCALS", 1)
SetGlobalTimer("DS_ARCHER_CALL_SHOT","LOCALS",60)
Spell(Myself,3121)
END
// * 1st-4th level
IF
See(NearestEnemyOf(Myself))
KIT(Myself,ARCHER)
CheckStatLT(Myself,5,LEVEL)
!GlobalTimerNotExpired("DS_ARCHER_CALL_SHOT","LOCALS")
Global("DS_USED_ARCHER_CALL_SHOT","LOCALS", 0)
THEN
RESPONSE #100
SetGlobal("DS_USED_ARCHER_CALL_SHOT","LOCALS", 1)
SetGlobalTimer("DS_ARCHER_CALL_SHOT","LOCALS",60)
Spell(Myself,3121)
END
There is probably a way to do it without the corrected Kit.IDS file, but I can't think of it off the top of my head.
Loosely, Delay(N) is true if the internal game time (in seconds) modulo N is 0.
Wesley is correct in that some of the innate abilties did not work with HaveSpell() checks and some would actually crash your game. The reason they didn't work is that these abilities should have had their Spell Level set to 1, but they did not, as shipped with the game. I don't remember ARCHER_CALL_SHOT as being one that was a problem, but I could be wrong about that.
A workaround for the HaveSpell() crash problem is to do something like this.
// * This workaround requires the corrected version of Kit.IDS file
// * Top of the script somewhere
// * Variable Reset
IF
PartyRested()
THEN
RESPONSE #100
SetGlobal("DS_USED_ARCHER_CALL_SHOT","LOCALS",0)
END
// * Get 1 at level 1, 2 at level 5, 3 at level 9, 4 at level 13 etc.,.
// * 9th-12th level
IF
See(NearestEnemyOf(Myself))
KIT(Myself,ARCHER)
CheckStatGT(Myself,8,LEVEL)
CheckStatLT(Myself,13,LEVEL)
!GlobalTimerNotExpired("DS_ARCHER_CALL_SHOT","LOCALS")
GlobalLT("DS_USED_ARCHER_CALL_SHOT","LOCALS", 3)
THEN
RESPONSE #100
IncrementGlobal("DS_USED_ARCHER_CALL_SHOT","LOCALS", 1)
SetGlobalTimer("DS_ARCHER_CALL_SHOT","LOCALS",60)
Spell(Myself,3121)
END
// * 5th-8th level
IF
See(NearestEnemyOf(Myself))
KIT(Myself,ARCHER)
CheckStatGT(Myself,4,LEVEL)
CheckStatLT(Myself,9,LEVEL)
!GlobalTimerNotExpired("DS_ARCHER_CALL_SHOT","LOCALS")
GlobalLT("DS_USED_ARCHER_CALL_SHOT","LOCALS", 2)
THEN
RESPONSE #100
IncrementGlobal("DS_USED_ARCHER_CALL_SHOT","LOCALS", 1)
SetGlobalTimer("DS_ARCHER_CALL_SHOT","LOCALS",60)
Spell(Myself,3121)
END
// * 1st-4th level
IF
See(NearestEnemyOf(Myself))
KIT(Myself,ARCHER)
CheckStatLT(Myself,5,LEVEL)
!GlobalTimerNotExpired("DS_ARCHER_CALL_SHOT","LOCALS")
Global("DS_USED_ARCHER_CALL_SHOT","LOCALS", 0)
THEN
RESPONSE #100
SetGlobal("DS_USED_ARCHER_CALL_SHOT","LOCALS", 1)
SetGlobalTimer("DS_ARCHER_CALL_SHOT","LOCALS",60)
Spell(Myself,3121)
END
There is probably a way to do it without the corrected Kit.IDS file, but I can't think of it off the top of my head.
-cirerrek Cirerrek's IE Miscellania
#5
Posted 16 November 2002 - 07:31 PM
Another possibility is that you want:
4121 instead.
4121 ARCHER_CALL_SHOT
4121 instead.
#6 -DSlaytern-
Posted 18 November 2002 - 02:34 AM
Thanks, I got the Called Shot ability to work. Replaced Delay in favour of GlobalTimer and corrected the typo of 3121 to 4121.