![]() |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,311
|
Howdy!
Can anyone fill me in on how quickadd works? Is its function/key just the thingid of a pick? I am trying to do something with SW and Savage Rifts to implement the First Cooy process so that if an intelligent construct has multiple of the same pick, then it is only displayed once on the summary tab (but with an addition of xCount to the displayed name). The example I have is a +1 Attribute feature. The component has the UserSelect component as well, so i have usrChosen1 to work with. I can tag each one as a MultiCopy, and have them list separately. That has this as the summary: Code:
+1 Attribute (Strength) +1 Attribute (Strength) +1 Attribute (Agility) If a pick needs to have a selection, then I add a Helper.DomainCopy tag to it. Once usrChosen1.ischosen <> 0, the pick gets tagged with a User.HasChosen tag. If a pick doesn't have the User.HasChosen tag, then it gets the Helper.MultiCopy tag added otherwise it gets the Helper.ChosenCopy tag. With this, the selections display as: Code:
+1 Attribute (- Choose -) +1 Attribute (Strength) (x2) [field[xCount].value is 2] Code:
+1 Attribute (Strength) (x3) [field[xCount].value is 3] Code:
+1 Attribute (Agility) [expecting field[xCount].value is 1 and FirstCopy / OnlyCopy tags] +1 Attribute (Strength) (x2) [field[xCount].value is 2] Working on - |
![]() |
![]() |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,311
|
These are my Components and scripts at the moment:
Code:
Eval Script from the Mechanic applied to the actor: <eval phase="Traits" priority="149" index="5" name="Prepare First Copy"><![CDATA[var myString as string myString = "!Helper.SpcDisable & !Helper.SpcReplace" foreach pick in hero from xCopyTracker where myString sortas CopyTrack ~ if we are a pick with the DomainCopy tag, then we have a selection ~ possible, but if no selection is made, then we are an independant copy if (eachpick.tagis[Helper.DomainCopy] <> 0) then ~ if we have chosen a selection, the component is no longer a MultiCopy if (eachpick.tagis[User.HasChosen] <> 0) then perform eachpick.assign[Helper.ChosenCopy] else perform eachpick.assign[Helper.MultiCopy] endif endif ~For things which are multiple copies, each independant, ~all of them are "first" copies. if (eachpick.tagis[Helper.MultiCopy] <> 0) then perform eachpick.assign[Helper.FirstCopy] else ~add the first active thing we found to our quick list - if quickadd ~returns nonzero, we were the first version, so add the "first copy" tag ~to ourselves. ~NOTE: at this point, we'll assume that the first copy is the only copy - ~the OnlyCopy tag is deleted in the "Determine First Copy" script if ~there's more than one. if (eachpick.quickadd <> 0) then perform eachpick.assign[Helper.FirstCopy] perform eachpick.assign[Helper.OnlyCopy] perform eachpick.quickadd endif endif nexteach ]]></eval> Component with the xCount and xIndex fields <component id="xCopyTracker" name="Multiple COpy Helper"> <!-- Selection Tag Expressions --> <field id="xIndex" name="Index of Copy" type="derived" defvalue="0"> </field> <field id="xCount" name="Number of Copies" type="derived" defvalue="0"> </field> <!-- Track whether the first copy --> <eval index="1" phase="Traits" priority="155" name="Determine First Copy"><![CDATA[ doneif (tagis[Helper.FirstCopy] <> 0) ~if we're not the first copy of a special ability, we need to set up a ~redirection to the actual first copy. That means whenever another pick ~does a "hero.child[x]" to find pick x, they always arrive at the first ~copy. This allows the first copy to be determined at every evaluation, ~and the first copy is then the one used to display the totals for the ~ability, even if it's added in multiple places (e.g. sneak attack, which ~can be added by multiple classes). The first copy is the one in the ~quickfind list, so retrieve it. perform quickfind.setfocus ~if we found a copy to set our focus to, we're a secondary copy of this ~ability, delete the Helper.OnlyCopy tag from the first (primary) copy. ~That means the Helper.OnlyCopy tag will only be left on those picks that ~are the only copy of their things. if (state.isfocus <> 0) then perform focus.redirect perform assign[Helper.SpecUp] perform focus.delete[Helper.OnlyCopy] endif ]]></eval> <eval index="2" phase="Traits" priority="200" name="Calc xIndex, xCount"><![CDATA[ ~we only need to run this if we're not the only copy ~if we aren't the only copy, we need to search the rest of our copies and get information if (tagis[Helper.OnlyCopy] = 0) then ~only run these for the first copy if (tagis[Helper.FirstCopy] <> 0) then var searchexpr as string searchexpr = "thingid." & this.idstring var index as number index = 1 foreach pick in hero from xCopyTracker where searchexpr sortas CopyTrack ~assign this thing the current index value, then increment the index for the next thing eachpick.field[xIndex].value = index index += 1 field[xCount].value += 1 nexteach else field[xCount].value += 1 endif else ~xIndex and xCount = 1 field[xIndex].value = 1 field[xCount].value = 1 endif ]]></eval> </component> <!-- Define a sortset that lists abilities in index order. --> <sortset id="CopyTrack" name="Framework abilities in order"> <sortkey isfield="yes" id="domDomain" isascend="yes"/> <sortkey isfield="yes" id="xIndex" isascend="yes"/> </sortset> Working on - |
![]() |
![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,137
|
In retrospect, I really wish we had never used "x" as the prefix for "this can be in many compsets". It just ends up looking really bad in the code. Pick a prefix based on the Id of the component these fields are really in, and use that.
From the description of what you need to solve, you don't need the full complexity of a level-based count and index (which looks to be copied from PF1). All you need is single-ability handling. Here's an example script that only needs a single script on this ability, and just needs a generic "value" field to store the number of copies beyond the first on the main copy of the ability - not a special script on a mechanic that has to run even if nothing it applies to is present on the character. Code:
~see if a quickfind has been created by another copy of this ability perform quickfind.setfocus ~if we didn't find a redirection, we're the first copy of this ability to run this script, so we'll make ourselves the FirstCopy. if (state.isfocus = 0) then perform quickadd perform assign[Helper.FirstCopy] ~add +1 to our value field[abValue].value += 1 ~otherwise, redirect hero.child[] to the FirstCopy, and make us an upgrade else perform focus.redirect ~add +1 to the focus's value focus.field[abValue].value += 1 endif |
![]() |
![]() |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,311
|
Thank Mathias!
That worked well, and I’m moving it and several other fields of two components into a common one so not doing the same thing twice. Only difficulty I’m seeing is that all versions of the same pick, no matter the Domain/Choice get grouped together with a single FirstCopy. Is there a way with quickadd to take that Domain/Choice into account, or would figuring a workaround with tags and +/- counts be best choice? Working on - |
![]() |
![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,137
|
How many choices are there? If the answer is something small, like 6 attributes, I'd build individual picks for each choice, rather than making the user fill in their names in text or select from a drop-down. This system isn't designed around that sort of test, and I'd need to spend a while figuring out how to adapt it to make the check of whether the quickfind was a matching copy before setting a quickadd, and then making sure that worked with all the combinations, because I think it'll work with one pair, but I think if there's a second set of the same pick you wanted to count, it may not work. For example, if agility is the first one that tries to set a quickfind, and it finds the proper firstcopy and then tests and verifies that that's also agility, so that 2x count will work, but then what about the strength copies - the quickfind will find the first agility copy, and you can verify that you're not a match, but then there's no way to try to quickfind again to tr to find another strength copy.
|
![]() |
![]() |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,311
|
For one item, there's 5 attributes (this is for Savage Worlds) so doing the individual picks works for that.
![]() A second item references skills, so that makes anywhere from 12-20 possible picks depending... It would be possible, but would really make for a huge list of selections. What about if I wasn't using quickadd for the whole FirstCopy thing and wanted to create my own procedure for that? In my mind, I'd have to create a sortset to sort by thingid.??? (is that possible?) and use a foreach to tag with Helper.FirstCopy whenever the id+domain changes (and set focus to this pick) and if the next eachpick is the same id+domain then would make it a SpecUp and increase the count on the focus pick... That wouldn't work with findchild[] though would it? because findchild[] uses the quickadd list? Working on - |
![]() |
![]() |
![]() |
Thread Tools | |
Display Modes | |
|
|