Jump to content


Custom AI Script Question


  • Please log in to reply
5 replies to this topic

#1 -DSlaytern-

-DSlaytern-
  • Guest

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.

// Call Shot
IF
	See(NearestEnemyOf(Myself))
	HaveSpell(3121)
	Delay(10)
THEN
	RESPONSE #100
  Spell(Myself,3121)
END


#2 cirerrek

cirerrek
  • Member
  • 193 posts

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

#3 weimer

weimer
  • Member
  • 1569 posts

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().

#4 cirerrek

cirerrek
  • Member
  • 193 posts

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.

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.

#5 weimer

weimer
  • Member
  • 1569 posts

Posted 16 November 2002 - 07:31 PM

Another possibility is that you want:

4121 ARCHER_CALL_SHOT


4121 instead.

#6 -DSlaytern-

-DSlaytern-
  • Guest

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.