Jump to content

Scripts... Again


Aliya

Recommended Posts

Okay, I may be new to modding for IE, but I lurked more than a little here and here, to understand the general meaning of scripts for BG2. I'm making a new mini-mod for it and ran into a small problem. One of my active .Cre's ApplySpells properly making her (she's an evil deva) quite tough. But when I come to the mage .Cre who's first block of the scripts considered of ApplySpells, and they don't work. Simply don't. No animation or sound play and even nothing changes on General text window. I tried to swap them to ReallyForceSpell but with same result. Eben though he DOES become red circled. :beer:

 

IF
Allegiance(Myself,NEUTRAL)
Global("Begin","GLOBAL",0)
THEN
RESPONSE #100
	Enemy()
	SetGlobal("Begin","GLOBAL",1)
END

IF
Global("Begin","GLOBAL",1)
THEN
RESPONSE #100
	ReallyForceSpell(Myself,WIZARD_STONE_SKIN)
	ReallyForceSpell(Myself,WIZARD_GLOBE_OF_INVULNERABILITY)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_NORMAL_MISSILES)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_MAGIC_WEAPONS)
	ReallyForceSpell(Myself,WIZARD_SPELL_TURNING)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_ENERGY)
	SetGlobalTimer("ProtDown","LOCALS",FOUR_ROUNDS) // Timer to cast another PFMW. 
END

Link to comment

Hm, no idea why this wouldn't work. Are you using some special animation for the cre? A sitting cre cannot die, for example. No idea, why.

 

Other than that, I know it's stupid questions but sometimes it's better to double-check:

 

1. Is your computer really plugged in No, seriously: Are you sure it is this script that turns im hostile? Are any other scripts assigned to the cre that could do that?

 

2. Did you check Global("Begin","GLOBAL",1), is it really at 1 when he turned hostile?

 

3. Don't forget to re-check the script is correctly assigned, spelled right, and actually got decompiled. (I have my own experiences with this one..)

 

EDIT: Oh, and the usual: Please get a custom prefix here , for compatibility reasons, if you haven't already. It's a pain if you have to introduce it afterwards.

Link to comment

You should keep conditions that make something go hostile separate from a script that is for attacks or spells.

 

Like example hostile.bcs is for the conditions that make a neutral creature turn hostile when attacked or provoked.

 

CastSpells.bcs is your script for casting spells. Here's an example of a script block from one of my mods.

 

IF
Global("CmMadeline","GLOBAL",0)
See(NearestEnemyOf(Myself(Myself)))
THEN
RESPONSE #100
	ForceSpell(NearestEnemyOf(Myself(Myself)),WIZARD_MAGIC_MISSILE)
	Wait(1)
	ForceSpell(Myself,WIZARD_MINOR_GLOBE_OF_INVULNERABILITY)
	Wait(1)
	ForceSpell(Myself,WIZARD_GHOST_ARMOR)
	SetGlobal("CmMadeline","GLOBAL",1)
END

IF
Global("CmMadeline","GLOBAL",1)
See(NearestEnemyOf(Myself))
THEN
RESPONSE #100
	ForceSpell(NearestEnemyOf(Myself(Myself)),WIZARD_MAGIC_MISSILE)
	SetGlobal("CmMadeline","GLOBAL",2)
END

 

and so on.

 

ApplySpell I believe the mage needs to have that spelled assigned to them. ForceSpell and ReallyForceSpell they don't. ReallyForceSpell skips the spell casting animation and it can not be interrupted.

Link to comment

As the IESDP describes them, there are slight differences amongst the Spell actions.

160 ApplySpell(O:Target,I:Spell*Spell)

This action causes the active creature to cast the specified spell at the target object. The spell is applied instantly; no casting animation is played. The spell cannot be interrupted.

113 ForceSpell(O:Target,I:Spell*Spell)

This action causes the active creature to cast the specified spell at the target object. The spell need not currently be memorised by the caster, and will not be interrupted while being cast. The caster must meet the level requirements of the spell... This action may not be reliable.

181 ReallyForceSpell(O:Target,I:Spell*Spell)

This action causes the active creature to cast the specified spell at the target object. The spell need not currently be memorised by the caster, and will not be interrupted while being cast. The spell is cast instantly (i.e. with a casting time of 0). The caster must meet the level requirements of the spell... This action may not be reliable.

ApplySpell seems to be the most reliable in my experience for contingencies. For normal casting, Spell should suffice (assuming the creature has it memorised).

 

In your first block, you want to check the creature can See() the party or at least Detect() it. Otherwise it may as well start out as enemy. By that same token, the second block will not run until that point, and therefore the spells shouldn't expire before the party gets to the creature (as could happen currently). Furthermore, you want to make sure that second block doesn't loop indefinitely by checking a variable or something.

IF
Allegiance(Myself,NEUTRAL)
See([PC])
THEN
RESPONSE #100
	Enemy()
END

IF
Global("Begin","GLOBAL",0)
Allegiance(Myself,ENEMY)
THEN
RESPONSE #100
	ApplySpell(Myself,WIZARD_STONE_SKIN)
	ApplySpell(Myself,WIZARD_GLOBE_OF_INVULNERABILITY)
	ApplySpell(Myself,WIZARD_PROTECTION_FROM_NORMAL_MISSILES)
	ApplySpell(Myself,WIZARD_PROTECTION_FROM_MAGIC_WEAPONS)
	ApplySpell(Myself,WIZARD_SPELL_TURNING)
	ApplySpell(Myself,WIZARD_PROTECTION_FROM_ENERGY)
	SetGlobalTimer("ProtDown","LOCALS",FOUR_ROUNDS) // Timer to cast another PFMW.
	SetGlobal("Begin","GLOBAL",1)
END

Link to comment

@Jastey - The 'GLOBAL' thing was 'LOCALS' some time, ago and I think I should change it to locals. Yep, I'm sure that decompiled 'em, overwise NI wouldn't save them. I got the prefix for the mod.

 

@CoM_Solaufein - Well, yeah, it's strange that celestial Apply(es) instantly and mage doesn't.

 

@Miloch - Hehe, it's 27th level spellcaster, I'm sure he fit the requirements to cast Dragon's Breath. Actually, thought that for buffing spells you don't need 'See(NearestEnemyOf(Myself))' trigger, lemme check.

 

EDIT: Okay, I've re-written the first script.

 

IF
Allegiance(Myself,NEUTRAL)
Global("Begin","LOCALS",0)
See([PC])
THEN
RESPONSE #100
	Enemy()
	SetGlobal("Begin","LOCALS",1)
END

IF
Global("Begin","LOCALS",1)
See(NearestEnemyOf(Myself))
Allegiance(Myself,ENEMY)
THEN
RESPONSE #100
	ReallyForceSpell(Myself,WIZARD_STONE_SKIN)
	ReallyForceSpell(Myself,WIZARD_GLOBE_OF_INVULNERABILITY)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_NORMAL_MISSILES)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_MAGIC_WEAPONS)
	ReallyForceSpell(Myself,WIZARD_SPELL_TURNING)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_ENERGY)
	SetGlobalTimer("ProtDown","LOCALS",FOUR_ROUNDS)
	SetGlobalTimer("Trigger","LOCALS",SIX_ROUNDS)
	SetGlobalTimer("Buff","LOCALS",TWO_TURNS)
END

IF
Global("Chain","LOCALS",0)
See(NearestEnemyOf(Myself))
Allegiance(Myself,ENEMY)
THEN
RESPONSE #100
	SetGlobal("Chain","LOCALS",1)
	DisplayStringHead(Myself,26328) // Chain Contingency
	ReallyForceSpell(NearestEnemyOf(Myself),WIZARD_POWER_WORD_BLIND)
	ReallyForceSpell(Myself,WIZARD_MORDENKAINENS_SWORD)
	ReallyForceSpell(Myself,WIZARD_MORDENKAINENS_SWORD)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_EVIL)
	SpellNoDec(Myself,WIZARD_TIME_STOP)
END

 

But... still... no buffs. :beer:

Link to comment
No animation or sound play and even nothing changes on General text window.
You won't see any of that for Apply actions, and I'm not sure you always will for Force actions either - is that what you're expecting? Put a DisplayString or something in the 2nd block and see if it's occurring that way. If it happens when the creature cannot see the party, then you wouldn't see it in any case.

 

Also, that 3rd block will never trigger, because the conditions for it will never be true (will never be enemy and the "chain" variable will not = 0). I would suggest checking for an expired timer of at least one round rather than reusing that variable.

 

If all else fails, you can put those effects on an item (or embedded EFFs) and then on the creature. If there supposed to be natural immunities, that's preferable anyway.

Link to comment
Why that? I don't see the chain variable to be set anywhere else?
Oh, I didn't look at it too closely - thought it was the same variable as in the first 2 blocks. But that 2nd block is going to loop unless I'm still not reading it closely enough. So that alone would mean it'd never get to the 3rd block. (It needs to set "Begin" to 2 or something.)
Link to comment

Miloch, yep, I could always do and edit some items, so they would carry the said effects. But, if I 'll do it the mage will be impossible to defeat, only SCSII's component does the 'remove the buff applied by items' and not every one will have that mod installed. I wanted spells, because they CAN be dispelled leaving mages relatively killable. I want this battle to be hard (because it gonna be solo - believe it or not.), not impossible. :beer:

 

So I added SetGlobal and the dependence from the second block. Oh, I have a distinct feeling they aren't working on my machine. Maybe supporting every script with "begin" local should cure the problem.

 

IF
Global("Begin","LOCALS",1)
Global("Chain","LOCALS",0)
See(NearestEnemyOf(Myself))
THEN
RESPONSE #100
	ReallyForceSpell(Myself,WIZARD_STONE_SKIN)
	ReallyForceSpell(Myself,WIZARD_GLOBE_OF_INVULNERABILITY)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_NORMAL_MISSILES)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_MAGIC_WEAPONS)
	ReallyForceSpell(Myself,WIZARD_SPELL_TURNING)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_ENERGY)
	SetGlobalTimer("ProtDown","LOCALS",FOUR_ROUNDS)
	SetGlobalTimer("Trigger","LOCALS",SIX_ROUNDS)
	SetGlobalTimer("Buff","LOCALS",TWO_TURNS)
		SetGlobal("Begin","LOCALS",2)
	SetGlobal("Chain","LOCALS",1)
END

IF
Global("Chain","LOCALS",1)
See(NearestEnemyOf(Myself))
THEN
RESPONSE #100
	SetGlobal("Chain","LOCALS",2)
	DisplayStringHead(Myself,26328) // Chain Contingency
	ReallyForceSpell(NearestEnemyOf(Myself),WIZARD_POWER_WORD_BLIND)
	ReallyForceSpell(Myself,WIZARD_MORDENKAINENS_SWORD)
	ReallyForceSpell(Myself,WIZARD_MORDENKAINENS_SWORD)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_EVIL)
	SpellNoDec(Myself,WIZARD_TIME_STOP)
END

 

The most simple mage's script consists of only See and HaveSpell triggers, example.

 

IF
See(NearestEnemyOf(Myself))
HaveSpell(WIZARD_TIME_STOP)
THEN
RESPONSE #100
	Spell(Myself,WIZARD_TIME_STOP)
END

 

And their buffing script, which WORKS.

 

IF
See(NearestEnemyOf(Myself))
Global("Prep","LOCALS",0)
!Dead("Myself")
THEN
RESPONSE #100
	DisplayString(Myself,39969) // Spell Sequencer - Fired
	ApplySpell(Myself,WIZARD_STONE_SKIN)
	ApplySpell(Myself,WIZARD_SPIRIT_ARMOR)
	ApplySpell(Myself,WIZARD_GLOBE_OF_INVULNERABILITY)
	ApplySpell(Myself,WIZARD_PROTECTION_FROM_NORMAL_MISSILES)
	DisplayString(Myself,39968) // Spell Trigger - Fired
	ApplySpell(Myself,WIZARD_PROTECTION_FROM_MAGIC_WEAPONS)
	ApplySpell(Myself,WIZARD_SPELL_TURNING)
	ApplySpell(Myself,WIZARD_PROTECTION_FROM_ENERGY)
	DisplayString(Myself,26328) // Chain Contingency
	ApplySpell(Myself,WIZARD_SPELL_IMMUNITY_ABJURATION)
	ApplySpell(Myself,WIZARD_SPELL_IMMUNITY_DIVINATION)
	ApplySpell(Myself,WIZARD_IMPROVED_INVISIBILITY)
	DisplayString(Myself,25942) // Contingency
	ApplySpell(Myself,WIZARD_FIRE_SHIELD_RED)
	SetGlobal("Prep","LOCALS",1)
END

Link to comment

IF

Global("Chain","LOCALS",1)

See(NearestEnemyOf(Myself))

THEN

RESPONSE #100

SetGlobal("Chain","LOCALS",2)

DisplayStringHead(Myself,26328) // Chain Contingency

ReallyForceSpell(NearestEnemyOf(Myself),WIZARD_POWER_WORD_BLIND)

ReallyForceSpell(Myself,WIZARD_MORDENKAINENS_SWORD)

ReallyForceSpell(Myself,WIZARD_MORDENKAINENS_SWORD)

ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_EVIL)

SpellNoDec(Myself,WIZARD_TIME_STOP)

END

 

 

You need to close the variable.

Link to comment

D'oh. Anyway from afore mentioned script he does Power Word: Blind me and that's it. : :beer: I don't really get it: why he skips the first script and goes for the second?

 

What do I need to add for these scripts to make true?

 

IF
Allegiance(Myself,NEUTRAL)
Global("Begin","LOCALS",0)
See([PC])
THEN
RESPONSE #100
	Enemy()
	SetGlobal("Begin","LOCALS",1)
END

IF
Global("Begin","LOCALS",1)
Global("Chain","LOCALS",0)
See(NearestEnemyOf(Myself))
Allegiance(Myself,ENEMY)
THEN
RESPONSE #100
	ReallyForceSpell(Myself,WIZARD_STONE_SKIN)
	ReallyForceSpell(Myself,WIZARD_GLOBE_OF_INVULNERABILITY)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_NORMAL_MISSILES)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_MAGIC_WEAPONS)
	ReallyForceSpell(Myself,WIZARD_SPELL_TURNING)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_ENERGY)
	SetGlobalTimer("ProtDown","LOCALS",FOUR_ROUNDS)
	SetGlobalTimer("Trigger","LOCALS",SIX_ROUNDS)
	SetGlobalTimer("Buff","LOCALS",TWO_TURNS)
	SetGlobal("Begin","LOCALS",2)
	SetGlobal("Chain","LOCALS",1)
END

IF
Global("Chain","LOCALS",1)
See(NearestEnemyOf(Myself))
THEN
RESPONSE #100
	DisplayStringHead(Myself,26328) // Chain Contingency
	ReallyForceSpell(NearestEnemyOf(Myself),WIZARD_POWER_WORD_BLIND)
	ReallyForceSpell(Myself,WIZARD_MORDENKAINENS_SWORD)
	ReallyForceSpell(Myself,WIZARD_MORDENKAINENS_SWORD)
	ReallyForceSpell(Myself,WIZARD_PROTECTION_FROM_EVIL)
	SpellNoDec(Myself,WIZARD_TIME_STOP)
	SetGlobal("Chain","LOCALS",2)
END

Link to comment
D'oh. Anyway from afore mentioned script he does Power Word: Blind me and that's it. : :beer: I don't really get it: why he skips the first script and goes for the second?
That spell appears to be the only one that has a target other than self. You still seem to be expecting to see the creature cast spells on itself, no? That won't necessarily be the case. One of the only ways to tell for sure is force-join (ctrl+q) it into your party or something.

 

Also there's nothing wrong with following the game's casting script format, especially if you know they work. About the only thing I add is "cast-and-attack" timer between casting, so that the creature can attack while prepping for the next spell. (You can have the creature cheesily force-cast spells one after the other without delay, but that is... um... cheesy :).)

Link to comment

'Cast-and-attack' script is from SCSII, I presume? Nah, this mage has 'increased number of spells per round' effect on him (a.k.a. Alacrity). So no attacking in this battle. I'm using SpellNoDec and Spell mostly, so that they could be interrupted. Somehow. :) Maybe using some long-lasting casting i can do this, wait a minute I'll check, if I can replace ForceSpell with Spell... :beer:

 

EDIT: Well, it seems even editing the whole scripts with Spell action doesn't give anything. And I checked: everything is memorized via Shadowkeeper. Creature is standing in 'bended' position in the game, meaning that *something* is running...

 

IF
Global("Begin","LOCALS",1)
Global("Chain","LOCALS",0)
See(NearestEnemyOf(Myself))
HaveSpell(WIZARD_STONE_SKIN)
HaveSpell(WIZARD_GLOBE_OF_INVULNERABILITY)
HaveSpell(WIZARD_PROTECTION_FROM_MAGIC_WEAPONS)
HaveSpell(WIZARD_SPELL_TURNING)
HaveSpell(WIZARD_PROTECTION_FROM_ENERGY)
THEN
RESPONSE #100
	Spell(Myself,WIZARD_STONE_SKIN)
	Spell(Myself,WIZARD_GLOBE_OF_INVULNERABILITY)
	Spell(Myself,WIZARD_PROTECTION_FROM_MAGIC_WEAPONS)
	Spell(Myself,WIZARD_SPELL_TURNING)
	Spell(Myself,WIZARD_PROTECTION_FROM_ENERGY)
	SetGlobalTimer("ProtDown","LOCALS",FOUR_ROUNDS)
	SetGlobalTimer("Trigger","LOCALS",SIX_ROUNDS)
	SetGlobalTimer("Buff","LOCALS",TWO_TURNS)
	SetGlobal("Begin","LOCALS",2)
	SetGlobal("Chain","LOCALS",1)
END

 

Hmmm... Maybe it's not the scripts fault, I just thought... Miloch, can you check? I gave the creature these effects.

 

1. Movementrate bonus (V: 3)

2. Modify proficiencies (*)

3. Increase casting speed factor (V: 3)

4. Intelligence bonus (V: 3)

5. Protection from spell (Flesh to Stone)

6. Protection from creature type (Demonic)

7. Protection from creature type (Undead)

8. Immunity to spell level (Lvl: 1)

9. Immunity to weapons (non-silver and non-magical)

10. Increase spells cast pr. round (V: 4)

11. THAC0 bonus (V: 5)

12. Protection from spell (Disintegrate)

13. Haste (Permanent)

14. Aid (non-cumulative)

15. Free Action

16. Regeneration

17. Increase critical hits

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...