Senior Member
Join Date: Dec 2011
Posts: 100
|
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. |
#1 |
Senior Member
Volunteer Data File Contributor
Join Date: Jan 2010
Location: Chicago, IL (USA)
Posts: 10,729
|
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. |
#2 |
Senior Member
Join Date: Dec 2011
Posts: 100
|
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:
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. |
|
#3 |
Senior Member
Join Date: Dec 2011
Posts: 100
|
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 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) |
#4 |
|
|