Skip to content

General mod Questions thread

1616264666770

Comments

  • kjeronkjeron Member Posts: 2,367
    ACTION_PHP_EACH	identifier AS name => ind	BEGIN
    	ACTION_IF	(ind == 1)	BEGIN
    		LAF	RES_NUM_OF_SPELL_NAME
    		STR_VAR
    			spell_name = EVAL ~%name%~
    		RET
    			spell_res
    		END
    		ACTION_TO_LOWER	name	// if you need the variable name to be the lowercase "cleric_bless" instead of "CLERIC_BLESS"
    		OUTER_SPRINT EVAL ~%name%~ ~%spell_res%~
    	END
    END
    
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2019
    Which is the STAT corresponding to opcode #120 (Immunity to weapons) if any?
  • BubbBubb Member Posts: 1,001
    @Luke93: Opcode #120 does not use a stat.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2019
    Bubb wrote: »
    @Luke93: Opcode #120 does not use a stat.

    As I suspected.

    I mean, I know there are 'WeaponCanDamage()' and WeaponEffectiveVS()', but those triggers are not very reliable since they always refer to the currently equipped weapon(s)......
  • switswit Member, Translator (NDA) Posts: 495
    edited September 2019
    I'm wondering if there is a way to affect Mage and Sorcerer level up progression like it's possible with all the other classes via CLAB files. From what I see CLABSO01 is occupied by Dragon Disciple and CLABMA01 by Wild Mage. Any ideas? If some other CLAB file is associated with these 2 classes (or even all of them), I could filter wizards with spell opcodes. Or maybe constantly running BALDUR.BCS code is the only solution?

    edit: problem solved with EEex (custom function called during level up)
    Post edited by swit on
  • [Deleted User][Deleted User] Posts: 0
    edited September 2019
    The user and all related content has been deleted.
    Post edited by [Deleted User] on
  • switswit Member, Translator (NDA) Posts: 495
    Just apply spells with 177/326 effects filtering for kit = trueclass.

    EDIT - actually, IIRC the unkitted sorcerer actually uses clabma01.2da, so you need to filter by class (mage vs. sorcerer) and by lack of kit.

    thanks, tested and can confirm that Generalist Mage and Sorcerer (also Wildmage) use clabma01.2da.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2019
    Bubb wrote: »
    @Luke93: I can't reproduce - the Kobold always catches on after the current one-round attack period is up.

    May I ask you to provide an animated GIF (as you usually do when demoing things) about this? Feel free to use KOBOLDSU.cre (along with BDSUM00.bcs). In particular, I'd like to see how the kobold react to the switch melee<->ranged weapon.

    As I told you, it sometimes keeps attacking with its ranged weapon even if I'm within 4'.... And when it correctly switches to its melee weapon, it follows me with its melee weapon if I run away from it (instead of re-equipping its ranged weapon....)
  • BubbBubb Member Posts: 1,001
    edited September 2019
    @Luke93: Sure.
    pr5q7hngykiv.gif

    It switches to melee just before I start teleporting around, (which was after its 6-second AttackOneRound ended).

    It has quite a bit of trouble going back to ranged after switching to melee. This is because AttackOneRound's movement portion doesn't check if the reevaluation period is up, so the script can't regain control. Basically you have to catch the Kobold while it is still + when it is on the cusp of a script reevaluation + when you are more than 4 feet away. A hard thing to do...

    AttackReevaluate() also doesn't work, as it never passes control back to the script. If it has been chasing a character for the reevaluation time period, and there is another enemy closer than the target, then it switches to the closer target - it doesn't actually go back and run another script pass.

    So, you can't trust the actions themselves to give script control back. You have to seize it from a higher script slot. Move the following from bdsum00.BCS into a script that's assigned a higher slot:
    IF
        Global("BD_RangedA","LOCALS",0)
        IsWeaponRanged(Myself)
    THEN
        RESPONSE #100
            SetGlobal("BD_RangedA","LOCALS",1)
            Continue()
    END
    
    IF
        Global("BD_RangedA","LOCALS",0)
        !IsWeaponRanged(Myself)
    THEN
        RESPONSE #100
            SetGlobal("BD_RangedA","LOCALS",2)
            Continue()
    END
    
    IF
        Global("BD_RangedA","LOCALS",1)
        Range(NearestEnemyOf(Myself),4)
        IsWeaponRanged(Myself)
    THEN
        RESPONSE #100
            EquipMostDamagingMelee()
            Continue()
    END
    
    IF
        Global("BD_RangedA","LOCALS",1)
        !Range(NearestEnemyOf(Myself),4)
        !IsWeaponRanged(Myself)
        CanEquipRanged()
    THEN
        RESPONSE #100
            EquipRanged()
            Continue()
    END
    

    Now, with that change made:
    r99byl98wz6h.gif

    Edit: Put GIFs into spoilers.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2019
    Bubb wrote: »
    It has quite a bit of trouble going back to ranged after switching to melee. This is because AttackOneRound's movement portion doesn't check if the reevaluation period is up, so the script can't regain control. Basically you have to catch the Kobold while it is still + when it is on the cusp of a script reevaluation + when you are more than 4 feet away. A hard thing to do...

    AttackReevaluate() also doesn't work, as it never passes control back to the script. If it has been chasing a character for the reevaluation time period, and there is another enemy closer than the target, then it switches to the closer target - it doesn't actually go back and run another script pass.

    So, you can't trust the actions themselves to give script control back. You have to seize it from a higher script slot. Move the following from bdsum00.BCS into a script that's assigned a higher slot:

    Thanks for clarifying the mechanics of 'AttackOneRound()' and 'AttackReevaluate()' :)

    Well, I don't like the idea of using a whole script slot just for that...... To tell the truth, if you write something like this, then you don't need to use those instructions – and the CRE reacts as intended
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	WeaponCanDamage(NearestEnemyOf(Myself),MAINHAND)
    	WeaponEffectiveVs(NearestEnemyOf(Myself),MAINHAND)
    	!StateCheck(NearestEnemyOf(Myself),STATE_REALLY_DEAD)
    	Allegiance(NearestEnemyOf(Myself),GOODCUTOFF)
    	Range(NearestEnemyOf(Myself),4)
    	See(NearestEnemyOf(Myself))
    THEN
    	RESPONSE #100
    		EquipMostDamagingMelee()
    		AttackOneRound(NearestEnemyOf(Myself))
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	WeaponCanDamage(NearestEnemyOf(Myself),MAINHAND)
    	WeaponEffectiveVs(NearestEnemyOf(Myself),MAINHAND)
    	!StateCheck(NearestEnemyOf(Myself),STATE_REALLY_DEAD)
    	Allegiance(NearestEnemyOf(Myself),GOODCUTOFF)
    	See(NearestEnemyOf(Myself))
    THEN
    	RESPONSE #100
    		EquipRanged()
    		AttackOneRound(NearestEnemyOf(Myself))
    END
    

    But as I've already told you, in so doing I cannot make use of 'WeaponCanDamage()' and 'WeaponEffectiveVs()' :(
    When switching from melee to ranged, those two triggers refer to the melee weapon – this doesn't make any sense because I'm gonna pick another weapon.... The same holds when switching from ranged to melee (it's basically the dual problem.....) Any idea about a possible workaround ?
  • switswit Member, Translator (NDA) Posts: 495
    Does anyone know which 2da file is used by the engine to assign amount of known spells during character generation for Mages and Bards? For Sorceres it's SPLSRCKN.2DA and for Shamans SPLSHMKN.2DA (they use it on each level up, not only during chargen), but Mages and Bards don't seem to have a file like this. Amount of known spells assigned at the start of SoA doesn't seem to relate to anything:

    mage level 7
    1: known - 5, memorization slots- 4
    2: known - 4, memorization slots- 3
    3: known - 3, memorization slots- 2
    4: known - 2, memorization slots- 1

    bard level 8
    1: known - 6, memorization slots- 3
    2: known - 5, memorization slots- 3
    3: known - 4, memorization slots- 1
  • BubbBubb Member Posts: 1,001
    edited September 2019
    @swit:
    Mage: MXSPLWIZ.2DA entry + 1
    Bard: Hardcoded in exe, (at least in BG2:EE), to:
    Level 1 => 6
    Level 2 => 5
    Level 3 => 4
    Level 4 => 4
    Level 5 => 3
    Level 6 => 3
    Level 7 => 2
    Level 8 => 1
    Level 9 => 1
  • switswit Member, Translator (NDA) Posts: 495
    thanks!
  • I am looking and looking into everything related to Agannazar's Scorcher and can't find anything that tells it to last two rounds. Is it hardcoded?
  • kjeronkjeron Member Posts: 2,367
    edited September 2019
    @polymorphedsquirrel It's part of the projectile, the "Lined-up AoE" flag does that by default, you can limit it to a single hit with the "Limited Path Count" flag.
  • Thanks @kjeron. No chance of limiting duration to one round, though?
  • kjeronkjeron Member Posts: 2,367
    Thanks @kjeron. No chance of limiting duration to one round, though?
    Without that flag, the animation lasts one round, while the effects hit twice, once instantly, and again half a round later.
    With that flag, the effects hit only once, instantly, while the animation is reduced to about 1 second.

    No way to have the animation last one round while hitting only once within the same spell/projectile. You would have to split them into two, one for effects (with the flag set), and one for the animation (without the flag set).
  • kjeron wrote: »
    Thanks @kjeron. No chance of limiting duration to one round, though?
    Without that flag, the animation lasts one round, while the effects hit twice, once instantly, and again half a round later.
    With that flag, the effects hit only once, instantly, while the animation is reduced to about 1 second.
    Surely you mean lasts two rounds, hitting at start of each round? Sorry for nitpicking, I am just trying to understand. But if setting 'that flag'/ meaning LImited Path Count will work essentially like other projectiles, than I could work with that.

  • kjeronkjeron Member Posts: 2,367
    edited September 2019
    Surely you mean lasts two rounds, hitting at start of each round? Sorry for nitpicking, I am just trying to understand. But if setting 'that flag'/ meaning LImited Path Count will work essentially like other projectiles, than I could work with that.
    Nope, Agannazar's hits instantly and 3 seconds later, while the animation plays for one round.

    Even with that flag, it will still hit all creatures between you and the target, that behavior can be changed in the SavingThrow field of each effect.
    BIT10 causes it to ignore the targeted creature.
    BIT11 causes it to ignore the creatures in-between.
  • RaduzielRaduziel Member Posts: 4,714
    Why not add a delayed effect in Agannazar's giving a 1-second immunity to Agannazar's?
  • kjeronkjeron Member Posts: 2,367
    Raduziel wrote: »
    Why not add a delayed effect in Agannazar's giving a 1-second immunity to Agannazar's?
    That would interfere with multiple castings of the spell, and isn't necessary in the EE's.
  • Wow, great thanks for such an elaborate response. Ideas start to take shape. I guess I took the description 2 rounds for granted without measuring it - 12 sec would be indeed very long.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2019
    Bubb wrote: »
    AttackReevaluate()... If it has been chasing a character for the reevaluation time period, and there is another enemy closer than the target, then it switches to the closer target.

    I'd like to have a clarification about this part. Do you know why it doesn't hold if the CRE in question is attacking with a ranged weapon (i.e., it doesn't switch to the closer target)?

    For instance, consider this very simple script and KOBOLDSU.cre
    IF
    	See(NearestEnemyOf(Myself))
    THEN
    	RESPONSE #100
    		EquipRanged()
    		AttackReevaluate(NearestEnemyOf(Myself),30)
    END
    

    The kobold keeps attacking always the same target, even if someone else is closer than the current 'NearestEnemyOf(Myself)'. Why?!
  • BubbBubb Member Posts: 1,001
    @Luke93: Because that target switching case only occurs if the creature is in "chase mode". The kobold won't be moving if it is using a ranged weapon + can still see its target, and thus it won't be "chasing" the target like it would be if it was using melee.

    The behavior can be summed up like this: If the creature has been moving in an attempt to attack its target + it's been moving for the reevaluation time period + it can see a nearer enemy, it will switch targets to attack that nearer enemy.

    You can indeed get a ranged creature to switch targets if you make it run around:
    drnnpy63q5wx.gif
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2019
    @Bubb
    Thanks, I missed the part about "chase mode", that explains it then....

    Anyway, there's a way to make a ranged creature switch target without forcing it to run around: you need to execute 'ClearActions(Myself)' after every attack.....
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2019
    @Bubb

    I'm sorry, but it does seem more complicated than what I originally thought (probably because of some hidden mechanics behind 'AttackReevaluate()'...)

    To sum up: my goal is to make a ranged creature constantly switch targets without forcing it to run around. Do you have any suggestions? The following script isn't working (I'm not sure wether that 'ActionListEmpty()' is needed or not....)
    IF
    	See(NearestEnemyOf(Myself))
    	!Range(NearestEnemyOf(Myself),5)
    	Global("myvar","LOCALS",1)
    THEN
    	RESPONSE #100
    		SetGlobal("myvar","LOCALS",0)
    		ClearActions(Myself)
    END
    
    IF
    	ActionListEmpty()
    	CanEquipRanged()
    	See(SixthNearestEnemyOf(Myself))
    	False()
    THEN
    	RESPONSE #100
    		Continue()
    END
    
    IF
    	ActionListEmpty()
    	CanEquipRanged()
    	See(FifthNearestEnemyOf(Myself))
    	False()
    THEN
    	RESPONSE #100
    		Continue()
    END
    
    IF
    	ActionListEmpty()
    	CanEquipRanged()
    	See(FourthNearestEnemyOf(Myself))
    	False()
    THEN
    	RESPONSE #100
    		Continue()
    END
    
    IF
    	ActionListEmpty()
    	CanEquipRanged()
    	See(ThirdNearestEnemyOf(Myself))
    	False()
    THEN
    	RESPONSE #100
    		Continue()
    END
    
    IF
    	ActionListEmpty()
    	CanEquipRanged()
    	See(SecondNearestEnemyOf(Myself))
    	False()
    THEN
    	RESPONSE #100
    		Continue()
    END
    
    IF
    	ActionListEmpty()
    	CanEquipRanged()
    	See(NearestEnemyOf(Myself))
    	False()
    THEN
    	RESPONSE #100
    		Continue()
    END
    
    IF
    	ActionListEmpty()
    	CanEquipRanged()
    	See(LastSeenBy(Myself))
    THEN
    	RESPONSE #100
    		SetGlobal("myvar","LOCALS",1)
    		EquipRanged()
    		AttackReevaluate(LastSeenBy(Myself),30)
    END
    
    Post edited by _Luke_ on
  • RaduzielRaduziel Member Posts: 4,714
    Question:

    I want to make a spell that, when cast, makes everyone affected attack specifically the caster (ignoring all other enemies) for one round - after that, they may reevaluate to attack whoever they want.

    How can I do it (assuming it can be done at all)?
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    Raduziel wrote: »
    Question:

    I want to make a spell that, when cast, makes everyone affected attack specifically the caster (ignoring all other enemies)....

    So, something similar to Litany of Curses? I'm pretty sure there's a specific opcode for that, but of course it's not available in the bg/iwd engine....
  • RaduzielRaduziel Member Posts: 4,714
    Luke93 wrote: »
    Raduziel wrote: »
    Question:

    I want to make a spell that, when cast, makes everyone affected attack specifically the caster (ignoring all other enemies)....

    So, something similar to Litany of Curses? I'm pretty sure there's a specific opcode for that, but of course it's not available in the bg/iwd engine....

    IDK if it is similar to Litany of Curses.

    Kjeron told me inbox that this can't be done. That's rough but that's life.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited October 2019
    kjeron wrote: »
    Cryosaur wrote: »
    op#179:
    • will affect all attacks, not just the weapon it's on, which would be incorrect when dual-wielding.
    • for two-handed/ranged weapons, it can be ideal if a base weapon damage bonus is desired
    • damage is multiplied by critical hits (and maybe backstabs)
    • multiple op179 effects only allow additional targeting, they do not stack their damage bonus

    I guess (1) and (4) hold for op#178 too, right?
    Moreover, is the IESDP correct about the fact that dice values are ignored?
Sign In or Register to comment.