Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,213
|
No, tables on the hero, just on a normal tab, where the user adds each career choice pick. All of those are set up with gizmos, so the user then clicks the button to open the customization form, and within that form, they choose their two skills, choose a specialty, and fill in a box for how many years they spent on that one.
|
#11 |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321
|
Thanks Mathias!
That pointed me in the right direction. I have a Lifepath component with a child entity, lpCustom using the LifepathHelper (a thing based on the LifepathHelper component). Code:
<!-- Lifepath Module --> <!-- form="lifepathgiz"> --> <entity id="lpCustom" form="lifepathgiz"> <bootstrap thing="LifepathHelper"/> </entity> <component id="LifepathHelper" name="Lifepath Helper"> <field id="lpSpecExpr" name="Specialty Expression" type="derived" maxlength="500" defvalue="TRUE"> </field> <!-- build the expression strings based on tags --> <eval index="1" phase="Render" priority="5000"><![CDATA[ var expr as string ~ get the tags from the container for what Specialties are available expr = container.tagids[Specialty.?,"|"] expr = replace(expr, "Specialty", "thingid", 0) field[lpSpecExpr].text = expr ]]></eval> </component> When a Specialty is selected (doing an autotag with Helper.Shadow) this error pops up: Quote:
Is there something I'm missing or how is this handled for SR5 and the Life Modules? Working on - |
|
#12 |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,213
|
To see that, use the "debug selection tasks" to examine when the very first task is on the lpT2KStreetKid pick is - it'll be after Initialization/10000, and it needs to be at or before that time. A blank script works to solve this:
Code:
<eval index="1" phase="Initialization" priority="9500"> <before name="the script on lpCustom that's at 10000"/><![CDATA[ ~empty script, but earlier than scripts on the picks in this gizmo ]]></eval> |
#13 |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321
|
Worked perfectly.
I can add the specialty to the gizmo with no issue. However, even though the Specialty pick is on the gizmo with the Helper.Shadow tag, it's not reflecting on the hero. Is there something I need to implement to have that reflect on the actor itself? or would that need to be a Displace? EDIT: I found it. needed to add this to the Specialty component definition. Code:
<shadow target="hero">Helper.Shadow</shadow> Working on -
Last edited by TCArknight; December 7th, 2020 at 03:42 PM. |
#14 |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321
|
Second part of the Lifepath gizmo question -
For example, there are a small number of skills (and they are defined as unique) in the system so they are all bootstrapped to the hero from the beginning. If I want to make a selection of a skill in the lifepath module and the table has an autotag entry so that the selected skill gets a particular tag (SkillRankIncrease), it appears that the skill is copied to the gizmo and that copy is tagged instead of the skill already existing on the hero. Making the skill Shadow to the hero results in a new copy of the Skill, one with the SkillRankIncrease tag, and one without. Is this what you were referring to about having to pick a Master and hide any other copies? Working on - |
#15 |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,213
|
Yep - even if they're unique, you'll need to use useronce uniqueness to make this work - then, yeah, shadow them to the hero, and then you need to set up scripts that can make one copy the main copy, and add together each one's bonuses to get a final value that's from all your lifepaths.
Here are the relevant scripts in SR5, although you'll have to wade through a lot of code relating to skill groups and skillsofts that are shadowrun-specific, and probably not something you have to worry about. So you'll want to pull all that out. I'm afraid I don't remember right now what caused us to have to split "Shadowed skills find their normal versions" into two scripts, and whether you'll need to retain that. Code:
<eval index="3" phase="Initialize" priority="29999" name="Determine FirstCopy"><![CDATA[ ~if we're not user once unique, then every copy is the FirstCopy if (tagis[User.Unique] = 0) then perform assign[Helper.FirstCopy] done endif if (quickadd <> 0) then perform assign[Helper.FirstCopy] endif ]]></eval> <eval index="4" phase="Initialize" priority="30000" name="Not FirstCopy"><![CDATA[ if (tagis[Helper.FirstCopy] = 0) then perform quickfind.redirect perform assign[Hide.Skill] endif ]]></eval> Code:
<eval index="8" phase="Traits" priority="8500" name="Shadowed skills find their normal versions"> <before name="Calc trtFinal Final"/> <after name="Calc grRating #3"/><![CDATA[ ~this only applies to shadowed skills ~those will be the ones added as skillsofts doneif (shadowed + tagexpr[SkillHelp.Autosoft | SkillHelp.Personafix] = 0) ~exclude new skill advancements doneif (tagis[Advance.Gizmo] <> 0) ~if we have a root pick, and our root pick is an advancement, stop now if (isroot <> 0) then doneif (root.tagis[Advance.Gizmo] <> 0) ~if that root pick has a root, and that's an advancement, stop now ~(this happens when Drake is added as an advancement - the Elemental ~Attack skill is two bootstraps down from the actual pick) if (root.isroot <> 0) then doneif (root.root.tagis[Advance.Gizmo] <> 0) endif endif ~handling for if we're added by a life module if (parent.tagis[component.LifeModule] <> 0) then ~no special handling needed in this case ~if we weren't added by a life module, and we're a skill group, stop now elseif (tagis[component.SkillGroup] <> 0) then done ~if we're a skillsoft/autosoft, our rating is our parent's rating elseif (parent.tagis[component.Gear] <> 0) then ~our replacement value is the rating of the program that added us field[trtReplace].value = parent.field[grRating].value ~if we're attached to the targeting autosoft, we'll need to grab some ~tags in order for the weapons to find us perform parent.pulltags[AutosoType.Targeting] perform parent.pulltags[ExoticProf.?] ~if we're not in a device, or not running, hide ourselves and don't ~proceed to looking for existing copies of the skill to replace if (hero.tagexpr[Hero.MatrixOnly | Hero.Vehicle] <> 0) then if (parent.field[grIsEquip].value = 0) then perform assign[Hide.Skill] perform assign[Helper.Disable] done endif elseif (tagis[SkillHelp.Personafix] <> 0) then ~nothing we need to do in this case elseif (tagis[SkillHelp.Autosoft] <> 0) then if (hero.tagis[Hero.Vehicle] = 0) then perform assign[Hide.Skill] perform assign[Helper.Disable] done endif elseif (parent.tagis[Equipment.KnowInfus] <> 0) then perform field[trtBase].modify[+,1,"Knowledge Infusion"] perform assign[SkillHelp.KnowInfus] elseif (parent.tagis[Equipment.GearSkill] <> 0) then if (parent.field[grIsEquip].value = 0) then perform assign[Hide.Skill] perform assign[Helper.Disable] done endif elseif (parent.container.ishero = 0) then if (container.parent.field[grIsEquip].value = 0) then perform assign[Hide.Skill] perform assign[Helper.Disable] done endif else perform assign[Hide.Skill] perform assign[Helper.Disable] done endif ~if the thing we're bootstrapped by requires activation, but it's not ~active, then we're hidden if (parent.tagis[User.Activation] <> 0) then if (parent.field[abilActive].value = 0) then perform assign[Hide.Skill] perform assign[Helper.Disable] done endif endif ~if we're a skill that came from a possessing spirit, there are some ~changes that need to be applied elseif (parent.tagis[component.Adjustment] <> 0) then if (hero.tagis[Hero.Channeling] <> 0) then perform assign[Hide.Skill] done endif perform assign[SkillHelp.FixSkill] perform assign[SkillHelp.NoSpecial] perform assign[SkillHelp.SpiritSkl] ~if our parent isn't activated, we're hidden. We also don't want to run ~the rest of this script, since that's when our value is added to the ~regular version of our skill if (parent.activated = 0) then perform assign[Hide.Skill] done endif ~normally, this is an overriding value perform field[trtOver].modify[=,container.child[attrFor].field[trtFinal].value,"Possessing Spirit's Force"] endif var ismatch as number var cantest as number ~now, check to see if a non-skillsoft copy of this skill is present on the hero foreach pick in hero from Skill where "!Hide.Skill & " & tagids[thingid.?] ismatch = 0 cantest = 0 ~if the skill we found is shadowed, then we can only make use of it if ~we're a skill from a life module, and it's also from a life module if (eachpick.shadowed <> 0) then ~if it's shadowed because it was originally added as an advancement, ~then that's OK - we can use that copy if (eachpick.tagis[Advance.Gizmo] <> 0) then cantest = 1 elseif (tagis[SkillHelp.LifeSkill] <> 0) then if (eachpick.tagexpr[SkillHelp.LifeSkill & !SkillHelp.LaterLMSkl] <> 0) then cantest = 1 endif endif else cantest = 1 endif ~if the skill we found is ourself, discard it as an option if (eachpick.uniqindex = uniqindex) then cantest = 0 endif if (cantest <> 0) then ~if we need a menu selection, make sure that the target's menu ~menu selection is the same as ours if (field[usrCandid1].isempty = 0) then if (field[usrChosen1].ischosen <> 0) then if (eachpick.field[usrChosen1].ischosen <> 0) then if (compare(eachpick.field[usrChosen1].chosen.idstring, field[usrChosen1].chosen.idstring) = 0) then ismatch = 1 endif endif endif elseif (tagis[User.NeedDomain] <> 0) then if (eachpick.field[domDomain].isempty = 0) then if (field[domDomain].isempty = 0) then if (compare(eachpick.field[domDomain].text,field[domDomain].text) = 0) then ismatch = 1 endif endif endif else ismatch = 1 endif ~for a knowledge skill, make sure that the knowledge skill categories ~are the same. For example, the Academic Knowledge: Buildings skill ~from a university architecture module would not stack with the ~Professional Knowledge: Buildings from a Trade school architecture ~life module if (tagis[component.SkillKnow] <> 0) then if (eachpick.field[sklKnowCat].value <> field[sklKnowCat].value) then ismatch = 0 endif endif endif if (ismatch <> 0) then if (field[trtOver].value >= 0) then eachpick.field[trtOver].value = maximum(eachpick.field[trtOver].value,field[trtOver].value) perform eachpick.assign[SkillHelp.DisableSpc] endif eachpick.field[trtReplace].value = maximum(eachpick.field[trtReplace].value,field[trtReplace].value) perform assign[Hide.Skill] perform assign[SkillHelp.LaterLMSkl] endif nexteach ]]></eval> <eval index="9" phase="Traits" priority="950" name="Shadowed skills find their normal versions - early changes"> <before name="Bound trtUser"/><![CDATA[ ~this only applies to shadowed skills ~those will be the ones added as skillsofts doneif (shadowed + tagexpr[SkillHelp.Autosoft | SkillHelp.Personafix] = 0) ~exclude new skill advancements doneif (tagis[Advance.Gizmo] <> 0) ~if we have a root pick, and our root pick is an advancement, stop now if (isroot <> 0) then doneif (root.tagis[Advance.Gizmo] <> 0) ~if that root pick has a root, and that's an advancement, stop now ~(this happens when Drake is added as an advancement - the Elemental ~Attack skill is two bootstraps down from the actual pick) if (root.isroot <> 0) then doneif (root.root.tagis[Advance.Gizmo] <> 0) endif endif ~this script is specific to those added as life modules doneif (parent.tagis[component.LifeModule] = 0) perform assign[SkillHelp.LifeSkill] var ismatch as number var cantest as number ~now, check to see if a non-skillsoft copy of this skill is present on the hero foreach pick in hero from Skill where tagids[thingid.?] ismatch = 0 cantest = 0 ~if the skill we found is shadowed, then we can only make use of it if ~we're a skill from a life module, and it's if (eachpick.shadowed <> 0) then if (tagis[SkillHelp.LifeSkill] <> 0) then if (eachpick.tagis[SkillHelp.LifeSkill] <> 0) then cantest = 1 endif endif else cantest = 1 endif ~if the skill we found is ourself, discard it as an option if (eachpick.uniqindex = uniqindex) then cantest = 0 endif if (cantest <> 0) then ~if we need a menu selection, make sure that the target's menu ~menu selection is the same as ours if (field[usrCandid1].isempty = 0) then if (field[usrChosen1].ischosen <> 0) then if (eachpick.field[usrChosen1].ischosen <> 0) then if (compare(eachpick.field[usrChosen1].chosen.idstring, field[usrChosen1].chosen.idstring) = 0) then ismatch = 1 endif endif endif elseif (tagis[User.NeedDomain] <> 0) then if (eachpick.field[domDomain].isempty = 0) then if (field[domDomain].isempty = 0) then if (compare(eachpick.field[domDomain].text,field[domDomain].text) = 0) then ismatch = 1 endif endif endif else ismatch = 1 endif ~for a knowledge skill, make sure that the knowledge skill categories ~are the same. For example, the Academic Knowledge: Buildings skill ~from a university architecture module would not stack with the ~Professional Knowledge: Buildings from a Trade school architecture ~life module if (tagis[component.SkillKnow] <> 0) then if (eachpick.field[sklKnowCat].value <> field[sklKnowCat].value) then ismatch = 0 endif endif endif if (ismatch <> 0) then ~what we're going to do here is make sure that both copies - ourselves ~and the copy we found - have identical trtInitial fields - both the ~value and the history should be the same. So, we start by recording ~the history that's currently in eachpick's field, then add our value ~to the copy we found, and then set our own value = to the new total, ~but we only add the history we recorded to our own history, meaning ~that at the end, from either copy, you'll see each thing that ~contributed to the history recorded here. if (field[trtLifMod].value <> 0) then perform eachpick.field[trtInitial].modify[+,field[trtLifMod].value,"Life Module: " & parent.field[name].text] endif if (eachpick.field[trtLifMod].value <> 0) then perform field[trtInitial].modify[+,eachpick.field[trtLifMod].value,"Life Module: " & eachpick.parent.field[name].text] endif endif nexteach ]]></eval> |
#16 |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321
|
Thanks Mathias, I'll dive into this to see what works best and simplest.
Working on -
Last edited by TCArknight; December 8th, 2020 at 02:21 PM. |
#17 |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321
|
New question.
I've gotten the Skill selection/improvement process working where if the skill is selected for a module, it improves the version of itself on the hero which has the Helper.MasterSkill tag I've added. I'm using a table_dynamic for the selections of the skill. However, I've found that (when I have multiple selections available) if I add a skill to the list the first time, that is isn't available to select a second time (or more). In order to have the skill available for multiple selections, would I need to have the skills set as not unique? What impact would that have on the quickadd process? Working on - |
#18 |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,213
|
This is for something along the lines of knowledge skills in PF, where you need to fill in some text or make a choice in a menu? If so, then check out all of the rows dealing with the ismatch variable in the SR5 examples - that's where it's looking to make sure the same text is filled in, both on the copy on the master, and on the copy in the module, or if it's a drop-down, that the same choice was made on both. But yeah, those skills would not be unique.
|
#19 |
Senior Member
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321
|
Mathias,
I appreciate all the help on this. Is it possible to bootstrap a Resource on the gizmo child that can be used to keep track of the number of selections of that type that are available? I have the Lifepath module with this as the child: Code:
<!-- Lifepath Module --> <!-- form="lifepathgiz"> --> <entity id="lpCustom" form="lifepathgiz"> <bootstrap thing="LifepathHelper"/> </entity> Code:
foreach bootstrap in this where "thingid.resLPSpecialty" eachthing.field[resMax].value += parent.field[lpNumSpec].value nexteach Code:
<portal id="lpSpecialty" style="tblNormal"> <table_dynamic component="Specialty" showtemplate="SimpleItem" choosetemplate="SimpleItem" alwaysupdate="yes" scrollable="yes" addpick="LifepathHelper" headerpick="LifepathHelper" candidatepick="LifepathHelper" candidatefield="lpSpecExpr"> <autotag group="Helper" tag="Shadow"/> <headertitle><![CDATA[ @text = parent.tagnames[LifepathCat.?,","] &" (" & parent.field[name].text & ") Specialty - " & container.childfound[resLPSpecialty].field[resShort].text ]]></headertitle> <additem><![CDATA[ @text = "Select Specialty" ]]></additem> </table_dynamic> </portal> Working on - |
#20 |
|
|