• 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

Disabling Spells

Fenris447

Well-known member
How would I go about disabling a spell? The new Order of Scribes has a feature that temporarily removes spells from your spellbook for 1d6 long rests. I have everything figured out for how to do this, except for two problems:


1. I have a foreach loop that should look at each spell in the hero with a particular thingid, but for some reason it's only finding copy of the spell in the spellbook, not the pick in the Wizard's prepared spells.

Code:
foreach pick in hero from BaseSpell where "thingid.(spellID here)"
perform eachpick.assign[Helper.Disable]
nexteach

For whatever reason, this is only finding and assigning the tag to the copy of the spell in the spellbook, and not doing the same to the spell in the Wizard's list of prepared spells. I think "from BaseSpell" is extraneous here, but removing it doesn't help. What am I missing?

2. The Helper.Disable tag does nothing to spells, so it's just a placeholder in the code above. I tried Hide.Spell, but that also didn't do anything. Once I figure out my problem with the foreach, is there any tag I can add/delete or field I can change in the spell to make it clear that the Wizard can't use it until it comes back? Worst case I'll just add sNameMod that says "Forgotten" or whatever, but I'd prefer something to make it go red.
 
I'd try doing it with a focus instead so its doing it on a specific spell chosen from a drop down menu. Also you need to make sure you have the right timing on the scripting. Hide.Spell will not do it. You might have to try deleting the sClass tag for the class to make it not show up in the list of spells you can prepare.
 
I already have a dropdown to actually pull the spell from the spellbook. I can directly add an sNameMod (or do whatever else I need) to the spellbook pick of the spell. The foreach I'm using is actually using a string for the expression, which is the thingid that I've pulled from the chosen (spellbook) spell.

What I need to do is also find and manipulate the copy of that spell that's in the prepared list, which is a separate pick of that spell.
 
The spell in the spellbook will have a tag: Spellbook.cHelpWiz
The prepared spell will have a tag: Helper.Memorized

You might want to find the one with Helper.Memorized and remove the Helper tag. That should remove it from the Prepared list.
 
Here's and example of how I might set up the foreach.

Code:
var searchexpr as string
searchexpr = "thingid.(spellID) & Helper.Memorized"

foreach pick in hero from BaseSpell where searchexpr
eachpick.delete[Helper.Memorized]
nexteach

I use a variable since it's easier for me to parse or manipulate the string later if I need to.

The problem is probably with timing since both copies of the spell are picks that are assigned through different portals that probably run really close together in timing, the trick is to pick the right time. I don't know when they kick off but it might be worth digging into the timing report of a "live" character with a spellbook.

I'm going to suggest another path after thinking about how the rule as written is phrased. How hard would it be to use your spell selection to "disable" to instead throw a validation error - something like: "You must not have the spell (SPELLNAME) memorized if you have it chosen in (ABILITYNAME)."

Kinda like the Acolyte of Nature ability on the Nature Cleric Domain throws an error if you don't have the cantrip you choose memorized.
 
I'd LOVE to have it throw an error. That would be preferable over what I'm trying to do. But I have no idea how to generate validation errors (outside of some light experience with pre-requisites). Any resources you could point me to there? I'll take a look at the Acolyte of Nature, of course.
 
Last edited:
I'd LOVE to have it throw an error. That would be preferable over what I'm trying to do. But I have no idea how to generate validation errors (outside of some light experience with pre-requisites). Any resources you could point me to there? I'll take a look at the Acolyte of Nature, of course.
I would add debug lines to 100% verify that the foreach loop is not working:

Code:
foreach pick in hero from BaseSpell where "thingid.(spellID here)"
debug eachpick.idstring
perform eachpick.assign[Helper.Disable]
nexteach

Then go to "Develop->Floating Info Windows->Show Debug Output". Then you will actually see which Picks its finding.
 
Yeah I know it was at least finding the spellbook version of the spell, as I could see the tags were being pushed to it. The debug will need to check for more than just the id string, since they'd be the same for the same spell. I can also have the debug push me something like the memorized tag, if present, to see if I'm actually getting the memorized version.

Is there any way to determine when in the timing a pick goes live? To see when that memorized spell is actually considered present on the hero? I would have assumed it's live the moment it's picked, before the timings even start. But that must not be the case here. Because the foreach is based on the thingid, it should pull in every version of that spell on there. But it's not.
 
Yeah I know it was at least finding the spellbook version of the spell, as I could see the tags were being pushed to it. The debug will need to check for more than just the id string, since they'd be the same for the same spell. I can also have the debug push me something like the memorized tag, if present, to see if I'm actually getting the memorized version.

Is there any way to determine when in the timing a pick goes live? To see when that memorized spell is actually considered present on the hero? I would have assumed it's live the moment it's picked, before the timings even start. But that must not be the case here. Because the foreach is based on the thingid, it should pull in every version of that spell on there. But it's not.

Trial and Error is one method, the other is to look at the timing report and find when picks go live.
 
Trial and Error is one method, the other is to look at the timing report and find when picks go live.

One thing to try to is to look into the floating info windows and choose Show Selection Tasks and find the copies of your spell.

Those windows show when scripts run against the pick, sometimes you can see a script name that you can do some poking around with in the timing report, plus it just plain gives you target timing slots to see if you can trial and error it.

Unfortunately a lot of the eval scripting behind BaseSpell isn't visible to us.
 
One thing to try to is to look into the floating info windows and choose Show Selection Tasks and find the copies of your spell.

Those windows show when scripts run against the pick, sometimes you can see a script name that you can do some poking around with in the timing report, plus it just plain gives you target timing slots to see if you can trial and error it.

Unfortunately a lot of the eval scripting behind BaseSpell isn't visible to us.

You can't see the stuff that's in the raw source code so a lot of it is trial and error to figure out.
 
For the record, I did get it figured out. I used the spell selector in the configurable thing, which imposes the hasagent tag on new copies of the spells. Then I searched all spells with that tag and built a list. That list was then used to find the spellbook and prepared versions of each of those spells.

All of this ran at Final 50000 and works perfectly.

Code:
  ~set our variables
  var searchexpr as string
  var otherexpr as string
  var blep as number

  ~start off the string for the tag expression with an open parenthesis
  searchexpr = "("

  ~look at all the spells that have been selected by this configurable   
  foreach pick in hero from BaseSpell where "hasagent.cfg5C1WthWrd"

  ~if this isn't the first spell we've found, add an OR (" | ") before it in the string
    if (blep > 0) then
      searchexpr &= " | " 
     endif

  ~add the found spell's thingid to the search expression
    searchexpr &= eachpick.tagids[thingid.?]

  ~blep tracks how many spells have been added to the list we're building
  ~so once we've found one, add to blep so we can add an OR as above
    blep += 1

  ~hide the found spell; this version of the spell is from the configurable
   perform eachpick.assign[Hide.Spell]
   nexteach

  ~close the tag expression string with a parenthesis
  searchexpr &= ")"

  ~make a copy the string with just the spells listed 
  otherexpr = searchexpr

  ~add the tag that shows we're looking for the spellbook version of the spell
  searchexpr &= " & portal.ClsBook"

  ~add the tag that shows we're looking for the prepared version of the spell
  otherexpr &= " & Helper.Memorized"


  ~run through the list of spells, looking for their spellbook versions
  foreach pick in hero from BaseSpell where searchexpr

  ~add "(Lost)" to the end of the spell's name
      eachpick.field[sNameMod].text = "Lost"

  ~hide this spell, as it's in the spellbook and has disappeared
      perform eachpick.assign[Hide.Spell]
  nexteach

  ~run through the list of spells, looking for their prepared versions
  foreach pick in hero from BaseSpell where otherexpr

  ~add "(Lost from spellbook)" to the end of the spell's name
      eachpick.field[sNameMod].text = "Lost from spellbook"
  nexteach
 

Yeah the scripting is not always going to be short one-liners of code... sometimes if you want to something it's going to be a long multiline thing. Just imagine if you had to code a new class and needed to add a spell list like this...
 
Yeah scripts aren't always so clean. I added the note lines just for this post, to help anyone looking to do something similar in the future. But figuring it out was not easy at all.
 
Back
Top