• Please note: In an effort to ensure that all of our users feel welcome on our forums, we’ve updated our forum rules. You can review the updated rules here: http://forums.wolflair.com/showthread.php?t=5528.

    If a fellow Community member is not following the forum rules, please report the post by clicking the Report button (the red yield sign on the left) located on every post. This will notify the moderators directly. If you have any questions about these new rules, please contact support@wolflair.com.

    - The Lone Wolf Development Team

Community Editor Project - HaveSpell Procedure

Quintain

Well-known member
Currently, the HaveSpell procedure works for "standard" classes who have their own spell list. However, with the introduction of hybrid classes that use other class' spell list, the HaveSpell does not properly validate these classes:

Looking for Community brainstorming on integrating this new validation requirement with the current procedure:

Code:
    ~ This procedure tests if a character has a specific spell and sets the valid field
    ~ ===How to use this Procedure===
    ~ var SpellID as String
    ~ var HaveSpell as number
    ~ SpellID = "spCureLig1"
    ~ Call HaveSpell
    ~ @valid = HaveSpell

    var HaveSpell as number
    var SpellID as string
    var s2search as string
    var s2classes as string
    var X as number
    ~ Init fields here
    X = 0
    HaveSpell = 0

    ~ Add thingid to the spell id passed us
    SpellID = "thingid." & SpellID
    ~ replace the | with |thingid. tag groups
    SpellID  = replace(SpellID,"|","|thingid.",0)

    ~ Get the classes that are valid for the spell ID(s) passed to us
    foreach thing in BaseSpell where SpellID
       ~ only do anything if we a spell with classes
       if (eachthing.tagis[sClass.?] <> 0) then
          ~ if loop counter not zero then add a seperator between strings
          if ( X <> 0) then
             ~ add a seperator between each loop
             s2classes &= "|"
          endif    
          ~ Build a search sting of all class tags
          s2classes = eachthing.tagids[sClass.?,"|"]
          ~ increment loop counter
          X += 1
       endif
    nexteach

    ~ Get the classes that are valid for the spell ID(s) passed to us
    foreach pick in hero where SpellID
       ~ only do anything if we a spell with classes
       if (eachpick.tagis[sClass.?] <> 0) then
          ~ if loop counter not zero then add a seperator between strings
          if ( X <> 0) then
             ~ add a seperator between each loop
             s2classes &= "|"
          endif    
          ~ Build a search sting of all class tags
          s2classes = eachpick.tagids[sClass.?,"|"]
          ~ increment loop counter
          X += 1
       endif
    nexteach

    ~ replace the sClass tags with thingid tag groups
    s2search = replace(s2classes,"sClass","thingid",0)

    ~ Loop through classes and see if we have one of the classes
    ~ valid for casting CLW spells
    foreach pick in hero where s2search
       HaveSpell = 1
    nexteach
 
Well that was actually allot easier than I first thought. I have a new version fixed and uploaded to GitHub.

This new version will take into account classes that use other classes spell list. In testing I used the Cure Light Wounds spell. This will now validate as TRUE for Cleric, Oracle, Warpriest, etc. Where before it only validated for Cleric or Witch.

In addition I was able to remove two of the three foreach loops meaning this will take a WHOLE lot less CPU.
 
Nice!

Hmm.. still not working for Arcanist and the RGG -- Summon Monster feats file, and this is with Summon Monster I memorized (not just in spellbooks).

The string being passed to the procedure is: "spSummMon1|spSummMon2|spSummMon3|spSummMon4|spSummMon5|spSummMon6|spSummMon7|spSummMon8|spSummMon9|spSummNat1|spSummNat2|spSummNat3|spSummNat4|spSummNat5|spSummNat6|spSummNat7|spSummNat8|spSummNat9"

I ran a test. I stripped off all the references to spells I did not have -- and the validation passed. The procedure needs to account for a mix of valid/invalid spell refernences.

I think the solution here is to have an "early exit". Returning to the calling script upon the first successful find of a Spell ID on the hero.
 
Last edited:
Code:
spSummMon1|spSummMon2|spSummMon3|spSummMon4|spSummMon5|spSummMon6|spSummMon7|spSummMon8|spSummMon9| spSummNat1|spSummNat2|spSummNat3|spSummNat4|spSummNat5|spSummNat6|spSummNat7|spSummNat8|spSummNat9
If this is "exactly" what you typed in then the issue would be in the "space" between spSummMon9 & spSummNat1. I would expect that to cause the expressions that are generated to be invalid.

Try again making sure NO spaces exist. If it still fails I will try and look at it tonight when I get home.
 
Code:
spSummMon1|spSummMon2|spSummMon3|spSummMon4|spSummMon5|spSummMon6|spSummMon7|spSummMon8|spSummMon9| spSummNat1|spSummNat2|spSummNat3|spSummNat4|spSummNat5|spSummNat6|spSummNat7|spSummNat8|spSummNat9
If this is "exactly" what you typed in then the issue would be in the "space" between spSummMon9 & spSummNat1. I would expect that to cause the expressions that are generated to be invalid.

Try again making sure NO spaces exist. If it still fails I will try and look at it tonight when I get home.

That's a copy paste error into the post, not from the function. I did that after performing my test and it's an empty space as a result of the deleted double quote:

Here's the actual string:

"spSummMon1|spSummMon2|spSummMon3|spSummMon4|spSummMon5|spSummMon6|spSummMon7|spSummMon8|spSummMon9|spSummNat1|spSummNat2|spSummNat3|spSummNat4|spSummNat5|spSummNat6|spSummNat7|spSummNat8|spSummNat9"

Odd. Something on the html is embedding a space in the spSummMon5 -- there are no spaces in the string.

Edit: I just confirmed this. I had a level 10 wizard and level 10 druid, and the validation was passed due to all classes having all spells, but the same doesn't happen with just a wizard. However, when I went with just druid, the validation passed (given the string above). It appears the last validation is the one that the procedure returns to the calling script. So, and early exit would likely fix this.
 
Last edited:
Honestly the logic I have built should work. It should find the first "class" that can cast any of those spells and say valid.

Until I get it into debug mode I won't have a good idea how to fix this and I have not had time yet.

My guess would be HL is having an issue with the same sSpell.? tag showing up multiple times in the expression used by the findchild[].
 
Honestly the logic I have built should work. It should find the first "class" that can cast any of those spells and say valid.

Until I get it into debug mode I won't have a good idea how to fix this and I have not had time yet.

My guess would be HL is having an issue with the same sSpell.? tag showing up multiple times in the expression used by the findchild[].

I did an experiment, for the mix of summon monster and summon nature's ally string I posted before and put summon monster I last. It still validates for a level 10 druid, but does not for a level 10 wizard, nor a level 10 arcanist.
 
Honestly the logic I have built should work. It should find the first "class" that can cast any of those spells and say valid.

Until I get it into debug mode I won't have a good idea how to fix this and I have not had time yet.

My guess would be HL is having an issue with the same sSpell.? tag showing up multiple times in the expression used by the findchild[].

What we need, if your statement is true, is a way to compact a delimited string into unique values. Do we have any sort of procedure or function that does this?
 
So as soon as I use your long string of spells I get a HL script error as soon as I try and select the feat. Is this what you where getting?

Code:
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25
- - -
Invalid tag expression specified for 'foreach' statement
Location: Procedure 'HaveSpell' near line 25

As the expression is correct my guess would be that we just hit a length limitation of a search expression.

@Mathias or Aaron my foreach expression is 358 characters long. What is the maximum length of a expression for a foreach loop?
 
I've asked Colen. In the meantime, can you do a debug, get the actual string, and post it, so that we can make sure it's not just a mis-spelling or missed parentheses within the string?
 
Yeah, 358 should definitely be within the limit. Let us know the exact tag expression string, and our eagle eyes will hopefully spot the issue!
 
Back
Top