![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,169
|
Every pick in Hero Lab must be within a container (this isn't a container like a backpack - this "container" is purely a programming term) (the mechanism Hero Lab uses to track what items are within what packpack or pouch is referred to within the code as "gear holding").
In the vast majority of cases, that container is called "hero". That's one of the two types of container in Hero Lab - the other type is called a gizmo. Unlike the hero container, where there's exactly one of them in each character, there can be as many or as few gizmos as you need to build your game system. All gizmos are attached to picks, and their purpose is to allow complex customizations of that pick. For example, in Pathfinder, they're what allow you to customize weapons and armor with materials and item powers. They're also used to build metamagic-modified spells - adding the various metamagics to a base spell. In Shadowrun, where nearly every piece of gear is customizable, with a variety of options available, nearly every piece of gear has a gizmo, so that Hero Lab can support that customization. The same sort of manipulations you're used to using on the hero container are also available within a gizmo. Just remember that you have to go to the pick that the gizmo is attached to first (most often, when dealing with gizmos, you'll be starting on that pick, or on one of the picks inside the gizmo, so that's normally not a problem). The code used when dealing with a gizmo is slighly different if you're coming from the pick that contains the gizmo, or if you're coming from a pick within the gizmo. From the overall pick, to get to the gizmo: gizmo.child[XXXXX] foreach pick in gizmo From a pick within the gizmo - this would be used if you wanted to manipulate something else in the gizmo - a prereq, for example, where you have to add one item to the gizmo before you can add another: container.child[XXXXX] foreach pick in container You can also go from a pick within the gizmo to the pick containing the gizmo: parent Even within a gizmo, the "hero" transition still works, and will take you to the hero context. So does herofield[XXXXX]. |
![]() |
![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,169
|
The first step in setting up a gizmo is to write the <entity>. Here's an example from Shadowrun:
Code:
<!-- An entity for the Possession adjustment --> <entity id="adjPossess" form="poCustPoss"> <bootstrap thing="PossHelper"/> </entity> http://hlkitwiki.wolflair.com/index....Element_(Data) Entities are placed in .str or .core files (wherever you're placing the component that will use them). They go after all the <component> and <compset> elements in that file, so they're usually going to be the very last thing in that file. The next step is to add that entity you've just defined to a thing: Code:
<child entity="adjPossess"> <bootstrap thing="attrFor"> <autotag group="Helper" tag="UserSpec"/> <autotag group="AttrSpec" tag="FreeFloat"/> </bootstrap> <bootstrap thing="resSpirPow"/> <bootstrap thing="cpImmNWeap"/> </child> Here's the wiki page for the <thing> element, in case you want to look up the exact details of adding a <child> element to a <thing> element: http://hlkitwiki.wolflair.com/index.php5/Thing_Element_(Data) Since it's normal for everything in a compset to use the same entity, here's an example of an editor entry that offers a checkbox - if the user checks that box in the editor, that <child> will be added: Code:
<inputthing name="Allows Modifications" helptext="Check this if this gear can be modified (unchecking this is rare)"> <it_entitycheck entity="grCustom" default="yes" /> </inputthing> If you don't even want to offer the editor user a choice of whether they're going to add a particular child, set that at the top: Code:
<editthing compset="Melee" name="Weapon: Melee" prefix="wp" defchild="grCustWeap" description="Armor, vehicles, and simple equipment all have their own tabs for creating objects of those types." summary="Defines a melee weapon that can be selected on the Armory tab."> If you have set a defchild="", you can use the target="child" option on tag and bootstrap options to set up bootstraps that will be within the gizmo, as opposed to normal bootstraps that will go inside the same container as the pick itself, or tags that are assigned to the gizmo (the container)(setting up tags in the gizmo is useful for prereqs, the same way setting up hero tags is useful for prereqs for things in the hero container): Code:
<inputthing name="Armor Specials" helptext="Specify any special notes about this armor."> <it_taglist group="ArmorNote" tag="?" target="child"/> </inputthing> <inputthing name="Integral Mods" helptext="Choose any integral mods this armor always comes with."> <it_bootcustom compset="Mods" target="child"> <match><![CDATA[ ModCat.Armor & !thing.showonly ]]></match> <inputthing name="Fixed Rating?" helptext="If this gear uses ratings, specify the minimum rating it can be set to."> <it_tagcheck group="Equipment" tag="FixRating"/> </inputthing> <inputthing name="Rating" helptext="If this gear is only available at a single rating, specify that here."> <it_field field="grUser"/> </inputthing> </it_bootcustom> </inputthing> |
![]() |
![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,169
|
Now, the visual elements - showing that gizmo to the end user.
Here's an example from the gear tab in Shadowrun - this is within a <template>, and that template is the picktemplate="" of a table_dynamic portal: Code:
<portal id="edit" style="actEdit" tiptext="Edit this Gear"> <action action="edit" buttontext=""> </action> </portal> Now, scroll back a little ways in this thread - find where the <entity> was defined. See how it has a form="" option? That's where you set which form gets opened when the user clicks that button. Here's how to define a form: Code:
<form id="poCustPoss" name="Possession Details" marginhorz="10" marginvert="5"> <layoutref layout="poPossess"/> <position><![CDATA[ layout[poPossess].width = 480 perform layout[poPossess].render width = layout[poPossess].width height = layout[poPossess].height ]]></position> </form> 700 (or smaller, if you don't need it very wide) is the widest I'd recommend making a form. There are some netbooks and old computers out there whose screens are only 800 pixels wide, and we want Hero Lab to be able to support those. Too much wider than 700, and some of your form can end up off-screen. If you need lots of space for your form, think downwards - make it taller, and use a scrollbar to let the user see everything. Normally, forms go in files named form_XXXXX.dat |
![]() |
![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,169
|
Using gizmos along with the purchasing mechanisms (if the gizmo represents a piece of gear that you can purchase modifications for, using cash).
If you want the things you add to your gizmo to cost money, you'll need to add the thingbuytemplate="" option to your entity: Code:
<!-- The Customizable gear entity --> <entity id="grCustom" form="gcCustom" thingbuytemplate="BuyCustom"> <bootstrap thing="GearCustom"/> <bootstrap thing="mdRFID"/> <bootstrap thing="mdWireless"/> <bootstrap thing="mdGearSize"/> <bootstrap thing="mdCybGrade"/> <bootstrap thing="mdBioGrade"/> <bootstrap thing="mdAdapsin"/> <movetest><![CDATA[ call MoveTest ]]></movetest> </entity> Then, in visual.dat, add a new template - this will automatically be placed along the bottom of your form, so that users can say OK when they're done purchasing all the stuff, and they won't actually be charged cash until they're done: Code:
<template id="BuyCustom" name="Buy - Customize Form" compset="Transact" istransaction="yes" marginvert="3"> <portal id="lblpaid" style="lblNormal"> <label text="Amount to Pay: ¥"> </label> </portal> <portal id="edtpaid" style="editCenter"> <edit field="xactCash" maxlength="6" format="integer"> </edit> </portal> <portal id="zero" style="lblNormal"> <label> <labeltext><![CDATA[ ~get the cost of the items - if we're in the middle of a buy ~transaction, the total value is held in the 'accumulated cost' field ~instead. var moneyvalue as number moneyvalue = gearpick.field[grCost].value * field[xactQty].value if (state.iscreate = 0) then if (gearpick.isbuying + gearpick.isbuychild <> 0) then moneyvalue = gearpick.field[grPaidTran].value endif endif ~now get the total cost string var money as string call Money @text = "(" & money & " if zero)" ]]></labeltext> </label> </portal> <portal id="free" style="chkFree" tiptext="Check this box to obtain the item for free (e.g. looted, stolen, found, etc.)"> <checkbox field="xactIsFree" message="Obtain for Free"> </checkbox> </portal> <portal id="funds" style="lblDisable"> <label> <labeltext><![CDATA[ var moneyvalue as number var money as string ~during creation, we're using the starting resources if (state.iscreate <> 0) then moneyvalue = #resleft[resResourc] ~during advancement, we'll show the character's current cash else moneyvalue = herofield[acCashNet].value endif call Money @text = "{text clrgrey}(Funds: " & money & ")" ]]></labeltext> </label> </portal> <position><![CDATA[ ~setup appropriate widths for our edit portals portal[edtpaid].width = 40 ~our width is the rightmost extent of the portals width = portal[lblpaid].width + 3 + portal[edtpaid].width + 10 + portal[zero].width var nexttop as number ~position the amount paid portals at the top portal[edtpaid].top = 0 perform portal[lblpaid].centeron[vert,edtpaid] perform portal[zero].centeron[vert,edtpaid] ~position the free checkbox and funds portal beneath the payment portals perform portal[free].alignrel[ttob,edtpaid,10] perform portal[funds].centeron[vert,free] ~position the paid portals horizontally, centered within the span portal[lblpaid].left = 0 perform portal[edtpaid].alignrel[ltor,lblpaid,3] perform portal[zero].alignrel[ltor,edtpaid,10] ~left- and right-align the free and funds portals within the span portal[free].left = 0 perform portal[funds].alignedge[right,0] ~if we're in creation mode, we don't need to show the amount to pay and free checkboxes if (state.iscreate <> 0) then portal[lblpaid].visible = 0 portal[edtpaid].visible = 0 portal[zero].visible = 0 portal[free].visible = 0 ~move the fund left up a line portal[funds].top = 0 perform portal[funds].centerhorz endif ~if we don't purchase gear, we only find or are given it, our free checkox ~if locked ON if (hero.tagis[Hero.Transitory] <> 0) then portal[free].enable = 0 endif ~our height is the bottommost extent of the portals height = portal[funds].bottom ]]></position> </template> Last edited by Mathias; April 1st, 2013 at 12:37 PM. |
![]() |
![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,169
|
By default, when the user adds a thing that has an entity added to it, the form will automatically pop up.
You can change this behavior by setting a flag on the main component you are using for the picks that contain these gizmos. Note that the component you add it to must be the same component listed as component="" In the table where you're adding the items that have the gizmos. The options are: addbehavior="default" addbehavior="customize" addbehavior="never" Not setting this flag is the same as addbehavior="default". Under this setting, the customization form always opens when you add this type of item. customize means that when users are adding or purchasing these customizable items, they'll see an extra button at the bottom, instead of just "Add", "Add and Close", and "Close" - they'll also see "Customize". If they choose customize, the form will show, but "Add" and "Add and Close" will not show the customize form. never means that the user won't have the option to customize it immediately after purchasing it. They'll have to edit the item later. Last edited by Mathias; April 10th, 2013 at 02:10 PM. |
![]() |
![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,169
|
(#3 Reserved in case I think of anything more I want to add)
|
![]() |
![]() |
Senior Member
Lone Wolf Staff
Join Date: May 2005
Posts: 13,169
|
A detail I forgot to note:
Note how all my gizmo examples had a helper pick? That's because of a change that needs to be made to tables within a gizmo. Normally, you can leave the addpick="" part of a table_dynamic blank, because it defaults to addpick="actor". But in a gizmo, there is no default available, so you must have an addpick="". So, I always add a helper pick, and set the addpick="" to that helper pick. Without an addpick, the additem text will always be ?????? The helper pick doesn't need to be complex - you can use the Simple compset that's defined in miscellaneous.str for that pick, because it doesn't need to have any behaviors of its own - it just needs to be present. |
![]() |
![]() |
![]() |
Thread Tools | |
Display Modes | |
|
|