Lone Wolf Development Forums  

Go Back   Lone Wolf Development Forums > Hero Lab Forums > HL - d20 System
Register FAQ Community Today's Posts Search

Notices

Reply
 
Thread Tools Display Modes
Nightfox
Senior Member
 
Join Date: Dec 2011
Posts: 100

Old November 29th, 2016, 09:06 AM
So I've got a long bit of code that currently has 7 foreach statements. Each of these foreach statements are looking for picks based on values in an index field. For those much more skilled at this then I, is there a better way of pulling a pick based on an index field, or am I stuck using foreach?

The specific index fields I'm looking at are cIndex and cClsIndex in case that helps.
Nightfox is offline   #1 Reply With Quote
ShadowChemosh
Senior Member
Volunteer Data File Contributor
 
Join Date: Jan 2010
Location: Chicago, IL (USA)
Posts: 10,729

Old November 29th, 2016, 10:20 AM
I honestly don't have a good answer without spending time to research. My question would be "why" you would need to use the Index values? I have never used them in all my scripting of HL or the authoring kit.

What is your "goal" here and what are you trying to accomplish? That would be a more helpful in answering you then this specific index value question.

Also anything running 7 foreach loops is going to SUCK CPU time and should be avoided.

Hero Lab Resources:
Pathfinder - d20pfsrd and Pathfinder Pack Setup
3.5 D&D (d20) - Community Server Setup
5E D&D - Community Server Setup
Hero Lab Help - Hero Lab FAQ, Editor Tutorials and Videos, Editor & Scripting Resources.
Created by the community for the community
- Realm Works kickstarter backer (Alpha Wolf) and Beta tester.
- d20 HL package volunteer editor.
ShadowChemosh is offline   #2 Reply With Quote
Nightfox
Senior Member
 
Join Date: Dec 2011
Posts: 100

Old November 29th, 2016, 01:57 PM
As you saw in the epic progression thread, I am trying to find the values the hero would have at 20th level for BAB and saves. HL only tracks the total, not the sub values at any given level, and i'd like this to be viable for any hero of 21st level or above.

My current approach is to look at the first 20 classes [cIndex] on the hero. If it is a race [component.BaseRace] or a template [component.BaseTemp] we can pull the values from there directly.

However for class levels [component.BaseClass] we need to know how many levels of each class we have and then get the appropriate tags from the associated cHelp. I could remove most of these foreach loops if I could simply access the tags from the pick on the class array but I'm not sure that's possible without knowing what the pick is first.

This feels like a chicken/egg problem.
Quote:
I want the 3rd book from the right on the bottom shelf.
I don't know what the book is called until I pull it.
And I cannot pull it until I know what it is called.
In this case I know the helper file's position on the class array, but I do not know what the class is yet.

The final steps would be doing the calculations for the BAB and saves based on the number of levels of each class (step 1) and the tags (step 2). Add any values from BaseRace and BaseTemp to get our total.
Nightfox is offline   #3 Reply With Quote
Nightfox
Senior Member
 
Join Date: Dec 2011
Posts: 100

Old December 3rd, 2016, 11:27 AM
This is so I can find the solution later.
To answer my own question, yes... sort of.

foreach will search through all picks that meet the criteria. If you know exactly what you are looking for and it has something unique (such as an index or a tag that will only appear once on the hero such as BaseRace) you can use findchild.

The findchild statement will search though the hero, but will stop at the first pick that meets the criteria. This makes it a little less intensive then the foreach, but it is still a non-indexed search so will use more processing power then a simple hero.child or hero.childfound statement. Also note, as a non-indexed search, it will return with the first pick, so if there are multiples, you may not get the same pick every time.

Format:
container.findchild[context, "expression"]
If the context is unique enough, you don't need an expression. NOTE: if you have an expression, the quotes are necessary.

Assuming you want to do more then one thing with the pick, you might want to use setfocus.

Format:
perform container.findchild[context, "expression"].setfocus
you can now access fields from the pick much like you would with foreach, except you use focus instead of eachpick

here are some examples for future me to reference.
Code:
~ find our hero's race and pull the number or racial hit dice
var rHD as number
perform hero.findchild[BaseRace].setfocus
rHD = focus.field[rHitDice].value

~ what class did we have at level 10 and how
~ many levels did we have in that class at that time.
var class as string
var ClsLev as number
perform hero.findchild[ClassList,"fieldval:cIndes=10"].setfocus
ClsLev = focus.field[cThisIndex].value
class = focus.linkage[helper].field[cAbbr].text

~ what was our second class and how many
~ levels does our hero have in that class
var TotClLev as number
perfom hero.findchild[BaseClHelp, "arrayval:1"].setfocus
TotClLev = focus.field[cTotalLev].value
Now for a longer example
Code:
~ if our hero did not increase BAB, or Fort save at our 10 ECL,
~ we are going to give them a +1 Luck bonus to attack
var cLev as number
var cAtk as number
var AtkMod as number
var cFort as number
var FortMod as number
var cSv1 as number
cSv1 = 0

perform hero.findchild[ClassList,"fieldval:cIndexMod = 10"].setfocus
doneif (state.isfocus = 0)
~ first lets get how many levels we have in this class
cLev = focus.field[cThisIndex].value

~now we will start with our attack bonus
if (focus.linkage[helper].tagis[Attack.Good] <> 0) then
  AtkMod = 1
  elseif (focus.linkage[helper].tagis[Attack.Medium] <> 0) then
    AtkMod = 0.75
  elseif (focus.linkage[helper].tagis[Attack.Poor] <> 0) then
    AtkMod = 0.5
  else
    AtkMod = 0
  endif
~ now we can caluculate if we received an attack bonus for this level
~ by calculating the bonus for the total level and subtracting the
~ bonus for one level lower.
cAtk = Round(AtkMod * cLev,0,-1) - Round(AtkMod*(cLev-1),0,-1)

~ now we will check for the fort save
if (focus.linkage[helper].tagis[cFort.Good] <> 0) then
  FortMod = 0.5
  if (cLev = 1) then
    cSv1 = 2
    endif
  elseif (focus.likage[helper].tagis[cFort.Poor] <> 0) then
    FortMod = 0.33334
  else
    Fortmod = 0
  endif
~ and now to repeat what we did above to find the save
cFort = round(FortMod * cLev,0,-1) - round(FortMod*(cLev-1),0.-1) + cSv1 

~ test if we have a bonus in either condition
doneif (cAtk + cFort <> 0)

~ and to add the luck bonus
hero.child[Attack].field[BonLuck].value = maximum(hero.child[Attack].field[BonLuck].value, 1)
Nightfox is offline   #4 Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 03:40 AM.


Powered by vBulletin® - Copyright ©2000 - 2024, vBulletin Solutions, Inc.
wolflair.com copyright ©1998-2016 Lone Wolf Development, Inc. View our Privacy Policy here.