Lone Wolf Development Forums

Lone Wolf Development Forums (http://forums.wolflair.com/index.php)
-   HL - Savage Worlds (http://forums.wolflair.com/forumdisplay.php?f=59)
-   -   Common Code Examples (http://forums.wolflair.com/showthread.php?t=33740)

zarlor January 11th, 2013 04:40 AM

Common Code Examples
 
I thought I would consolidate a list of things that get used over and over again in the Editor, or that I have otherwise found to be very useful. Hopefully this will be helpful for those, like me, who work best from having lots and lots of examples.

First I have found it very useful to go through the documentation found in Hero Lab by going to Help -> Savage Worlds Manual and from within that Manual there is a link to "Creating Custom Material" that also has some useful, although maybe a little confusing, stuff in it. But probably the most useful section I found was a little more buried. Go to Help -> Savage Worlds Manual, then click on "Adding Custom Content" then hit the "Click here" part of the sentence that says "Click here for more information on using the Editor with Savage Worlds." That information and the Tutorials section there on creating a Race is something I found to be really helpful. Finally I found the Expressions at http://hlkitwiki.wolflair.com/index....ag_Expressions to be very useful as well. I would also add that Mathias has written some really useful posts on the Pathfinder forum which he links here. Some of his examples may look Pathfinder specific, but they're still very relevant for coding in Savage Worlds files, too.

Now on to the examples. Remember that in most cases we might list Edges or Skills below, but those really could be anything, where appropriate, so Hindrances or Equipment or Racial Abilities, whatever it is you have the UniqueID for. Also remember that for Savage Worlds the die type numbers are half the actual die type for our purposes in the program. So a d4 is 2, a d6 is 3, d8 is 4, a d12 is 6 and then anything higher than 6 turns into d12+(your number-6), so 7 is d12+1, 10 is d12+4 and so on.

So on to some specific code things I've found useful.

-----
To grant a specific skill at d6 (we use Healing in this example):

Bootstrap: skHealing
Eval Script: Pre-Traits/5000

Code:

~This will offset the cost:
perform #resspent[resSkill,-,1,"Chaplain"]

~This will increase the Skill
foreach pick in hero where "thingid.skHealing"
  eachpick.field[trtBonus].value += 1
nexteach

Note here that we had to use a Bootstrap to add the Healing Skill, then we offset the cost of it to make it free to have it, and finally we added "1" to the die type, since the Bootstrap gave us the skill at d4. if we added "2" we could start with a d8 in the skill, and so on.

To do that for a set Knowledge skill, let's use Knowledge (Latin) for this example:

Bootstrap: skKnow Fields...: FieldID: domDomain, Value: Latin


Code:

~This will offset the cost:
perform #resspent[resSkill,-,1,"Latin"]

~This will increase Latin
 foreach pick in hero where "thingid.skKnow"
  if (compare(lowercase(eachpick.field[domDomain].text),"latin") = 0) then
      perform eachpick.field[trtBonus].modify[+,1,"Latin"]
  endif
 nexteach

-----
To modify a skill (or other trait,in this case we'll use Guts) roll, adding a +2 bonus to the roll rather than the die type, use (the thing in quotes is just a way of saying what it was that provided the bonus, in this case we're saying it's something called "Gutsy", maybe that's an Edge or a Racial Ability, what it is doesn't matter much, just make it understandable for why the bonus was given.):

Eval Script: Pre-Traits/5000 Timing: Before: Calc trtFinal

Code:

perform #traitroll[skGuts,+,2,"Gutsy"]
If you want to make sure that bonus doesn't stack with other bonuses, then use #traitprof instead of #traitroll.

-----
To modify a skill (again, we'll use Guts) by adding one die type use:

Eval Script: Pre-Traits/5000 Timing: Before: Calc trtFinal

Code:

perform #traitadjust[skGuts,+,1,"Gusto"]
-----
To search for an appropriate Knowledge skill (in this case Astronomy) of d10 or higher:

Pre-reqs:
Message: Knowledge (Astronomy) d10 required.

Code:

foreach pick in hero where "thingid.skKnow"
  if (compare(lowercase(eachpick.field[domDomain].text),"astronomy") = 0) then
      validif (eachpick.field[trtFinal].value >= 5)
  endif
nexteach

-----
To find a Knowledge field (in this case Arcane) and then add a bonus (+2) to the roll:

Eval Script: Pre-Traits/5000 Timing: Before: Calc trtFinal

Code:

~go through all knowledge skills and find an "Arcane" one
foreach pick in hero where "thingid.skKnow"
  if (compare(lowercase(eachpick.field[domDomain].text),"arcane") = 0) then
      perform #traitroll[skKnow,+,2,"Highest Clearance"]
  endif
nexteach

Don't forget you can replace #traitroll with #traitadjust in the above if you want to add die types instead of roll bonuses.

-----
How about doing the reverse of that by finding a Knowledge field (in this case Arcane) and only adding a +2 bonus to everything that is NOT that version:

Eval Script: Pre-Traits/5000 Timing: Before: Calc trtFinal

Code:

~go through all knowledge skills and find an "Arcane" one
foreach pick in hero where "thingid.skKnow"
  if (compare(lowercase(eachpick.field[domDomain].text),"arcane") <> 0) then
      perform eachpick.field[trtRoll].modify[+,1,"Smarty Pants"]
  endif
nexteach

-----
To check if any one of a particular thing exists, like you would use in a Pick-req, but where we're not just looking for a single Edge to exist but rather if any one of a list of Edges exist. For this example we have Edges for both NCO and Officer and I just want to check that the character has either one of those edges:

Expr-reqs:
Message: Rank (NCO or Officer) Edge required.
Code:

hero.tagis[Edge.edgTDNCO] + hero.tagis[Edge.edgTDOffic] <> 0
-----
To check if any one of different criteria exist. This one is a bit more complicate. Let's say you wanted to check for if a character has either a Spirit of d8 OR a particular Edge (we'll use Nepotism for this, from Necropolis):

Pre-reqs:
Message: Spirit d8 required.

Code:

validif (hero.child[attrSpi].field[trtFinal].value >= 4)
validif (hero.tagis[Edge.edgNCNepot] <> 0)
if (@ispick <> 0) then
  altpick.linkvalid = 0
endif

Now say you needed that to be a Knowledge skill instead, say Artillery d6, in which case we could use:

Code:

foreach pick in hero where "thingid.skKnow"
  if (compare(lowercase(eachpick.field[domDomain].text),"artillery") = 0) then
    validif (eachpick.field[trtFinal].value >= 3)
  endif
nexteach
validif (hero.tagis[Edge.edgNCNepot] <> 0)
if (@ispick <> 0) then
  altpick.linkvalid = 0
endif


The "if (@ispick <> 0) then" part of that code is primarly just an error trap, so it seems it should be good practice to use it in this instance. (See http://forums.wolflair.com/showthread.php?t=33096 for more details.)

-----
To level up a character, like the Veteran of the Wierd West Edge does in Deadlands:

Eval Script: Pre-Traits/5000 Timing: Before: Calc trtFinal

Code:

#resmax[resXP] += 20
#resmax[resAdvance] +=4

It appears that you need to both add the XP AND the number of Advances that XP would give you to get these to work right.

-----
For Expr-reqs it's important to note that if you are looking to check against a Trait that you KNOW every character has, like any of the Attributes (say, Spirit of d6 or higher) you an use something like:

Code:

#trait[attrSpi] >= 3
To check for a Spirit of d6. However, if you are looking for something that any partcular character might NOT have at all, like a skill (say, Boating at d6 or higher) then you need to use the #traitfound expression instead, so:

Code:

#traitfound[skBoating] >= 3
-----
To add an extra wound level:

Eval Scripts: Setup/10000

Code:

herofield[acMaxWound].value += 1
-----
To have the program ignore some amount of wound penalties (like for the Nerves of Steel Edge):

Eval Scripts: Setup/10000

Code:

herofield[acIgnWound].value += 2
-----
To perform different actions based on the existence of a certain Edge. In this example I have a derived trait called Fame (trPMFame) and if this character has the Noble edge (edgPMNoble) I want to add 15 points to the Fame trait, but if they don't have the Edge I want to give them 10 points of fame instead.

Eval Script: Pre-Traits/5000 Timing: Before: Calc trtFinal

Code:

if (hero.tagis[Edge.edgPMNoble] <> 0) then
  perform #traitadjust[trPMFame,+,15,"Admiral"]
 else
  perform #traitadjust[trPMFame,+,10,"Admiral"]
endif

-----
To add extra damage onto a weapon, in this case jbearwillis asked for (and CapedCrusader provided the code) the ability to add an extra 1/2 Agility die modifier to damage for a weapon:

Eval Script: Traits/5000 Timing: Before: Calc trtFinal

Code:

var DamagePlus as number
DamagePlus = hero.childfound[attrAgi].field[trtFinal].value - 1
field[wpDmgBonus].value += DamagePlus

-----
To create a drop-down "pick list", let's say to apply a +1 roll bonus to one of three skills (the Scholar Edge is another example worth looking at):

Menu #1 Source: All Picks on Hero (this will make sure you don't get an error for trying to modify a skill that doesn't exist on the character)
Menu #1 Tag Expression: thingid.skBoating | thingid.skDriving | thingid.skPiloting
Eval Scripts: Pre-Traits/5000 - Before: Calc trtFinal

Code:

~apply the +1 modifier to selected skill
if (field[usrChosen1].ischosen <> 0) then
  perform field[usrChosen1].chosen.field[trtRoll].modify[+,1,"Ordo Novus Templum"]
endif

-----
To create a weapon that doesn't use up your "hand slots", like you might use for a shoulder mounted weapon in power armor, or retractable claws:

Eval Script
Phase: Pre-Traits/5000

Code:

if (field[grIsEquip].value <> 0) then
  herofield[acHands].value += 1
endif

Eval Rule
Phase: Validation/8000

Code:

~if we have no more than three hands of gear equipped, we're good
validif (hero.tagcount[Hero.Hand] <= herofield[acHands].value)

~mark associated tabs as invalid
container.panelvalid[armory] = 0

Timing: Script Name: Check Hands

zarlor January 11th, 2013 04:40 AM

To create separators and sort gear/weapons in some way other than the defaults you have to have some idea of what the defaults are and where they sort. Individual items will sort themselves, but it depends on what "Type" you select as to how they will group up.

By default equipment/gear will sort itself under the following headings in the following order:

Custom
Adventuring Gear
Clothing
Food
Animals & Tack
Communication
Computers
Surveillance
Ammunition
Medical
Services
Weapon Accessories
Travel
Shelter
Miscellaneous


For weapons the headings and order are as follows:

Medieval Blades
Medieval Axes and Mauls
Medieval Pole Arms
Modern Melee
Futuristic Melee
Medieval Ranged
Black Powder
Modern Pistol
Modern Submachine Gun
Modern Shotgun
Modern Rifle
Modern Assault Rifle
Modern Ranged
Modern Machine Gun
Modern Energy
Futuristic Ranged
Special: Cannons
Special: Rocket Launchers
Special: Missiles
Special: Mines
Special: Flamethrowers
Special: Grenades
Special: Explosives
Vehicle Weapons
Improvised Weapons


Most of those categories have a separator that shows up as grey in the program to act like a separator for the groups that only shows up if there is any equipment set to their type in your user file(s). One thing you will often see in settings that might not use the standard Savage Worlds equipment lists is different headers. The way to get that to happen for your gear for a specific setting/source is to modify (or add) an entry on the Setting Adjust tab and check the "No Standard Gear?" box. This will make most all of the other gear and separators dissapear so you can use your own.

I say "most" because a few separators are not set as "standard gear", namely Food and Clothing. Also Ammunition, but it's also a special case in that it is a separate Tab in the Editor. (If you need to use one of those you'll have to add the Unique ID, eqSepFood for Food or eqSepCloth for Clothing, for example, to the "Preclude" list so it won't show up alongside the separator you create to replace it.)

Let's say we had some weapons we wanted to categorize our own way. All we have to do is commandeer those categories above. Just don't think of them as categories at all, but rather markers for the order that things are in. So if we wanted Hoth Pistols and Hoth Rifles to be a couple of categories, and then Tatooine Pistols and Tatooine Rifles to be two more and we want them to show up in that order, we might commandeer Modern Pistol, Modern Submachine Gun, Modern Shotgun and Modern Rifle to be those categories instead, for example.

So make a new weapon and name it "– Hoth Pistols –" and give it a Unique ID that tells you this is a separator (we usually like to use a 2 Character ID for a particular source, so let's call our Source "House Rules" and give it an ID of "HR"), so let's give this a Unique ID of wpHRSepHPi (the only important part of that is the "wp", the rest is a way to make a Unique ID so I added "HR" to be the 2-character ID we're using using for our setting, "Sep" to denote this as a Separator and "HPi" as shorthand for a Hoth Pistol. In truth you could put anything you want in there, as long as no other Thing used the same Unique ID.) For the "Weapon Type" select "Modern Pistol" from the drop-down list and on the right click the "Show Only?" checkbox. That last part will make sure it stays greyed out and isn't something the player will be able to "buy" as a weapon. Now any new weapons you make that you set to have a "Weapon Type" of "Modern Pistol" will show up in the player's Armory Tab in the Character Profile as being under the "– Hoth Pistols –" section. Do the same for the other types with the names you wanted, so set Hoth Rifles to use Modern Submachine Gun, Tatooine Pistols to use the category of Modern Shotgun and Tatooine Rifles to use Modern Rifle and they'll all show up nice and grouped the way you want them when a player goes to the Armory Tab on their character profile and clicks on "Add New Ranged Weapons".

The same can be done for categorizing armor and shields, but with a few little caveats. First the order for them is:

Medieval Armor
Medieval Shields
Modern Armor
Futuristic Armor
Natural Armor


In this case, however, there is no drop-down list for "Armor Type". Instead you have to go to the "Tags" button and from there you would add a tag for the category you want use for one of the above types. You need to set the Group ID: of this tage to be "ArmorType" (no spaces and capitalization is important.) The "Name" and "Abbreviation" fields should use one of the names in the above list that you will be using. For the Tag ID use the name following the colon below, depending on the category you decide to use:

Medieval Armor: MedArmor
Medieval Shields: MedShield
Modern Armor: ModArmor
Futuristic Armor: FutArmor
Natural Armor: Natural

Finally you can do the same with Vehicles, but they break themselves down into two drop-down lists that sort within each other by Vehicle Type and Vehicle Era. They sort as follows:

Civilian: Ground Vehicles
WWII Military: Ground Vehicles
Modern Military: Ground Vehicles
Futuristic Military: Ground Vehicles
Civilian: Aircraft
WWII Military: Aircraft
Modern Military: Aircraft
Futuristic Military: Aircraft
Civilian: Boats & Ships
WWII Military: Boats & Ships
Modern Military: Boats & Ships
Futuristic Military: Boats & Ships

Of note is that, unlike gear, vehicle tags are actually dynamic, so while the base "Type" by default only has Ground Vehicle, Aircraft, and Boats & Ships you should be able to enter new ones in there as you like, such as Spacecraft and such. I'm not positive where they will fit in the sort order, but playing around should help you figure that out.
-----

When adding Vehicles it's important to note that Bootstrapping a weapon will Bootstrap it to the portfolio the Vehicle is added to. Instead weapons need to be put in as a Gizmo instead. However, first we need to set a little something to prevent an error (you can check the Wiki for details of WHY this needs to be done, but for our purposes let's just say that it needs to be done.)

Containerreg: Initialization/2000 set the Tag Expression: TRUE

Gizmo: Set the Entity Unique Id to: "LoadOut" (without the quotes) and then hit Bootstraps:

Here you can add the weapons. There are also some fields you can set to help out with things like ammo and how they should look on the sheet. For each weapon that needs them go to Fields...

Field Id: livename Value: (The text you want to display, I usually put the text from the book, like "10mm laser (x2), turret", for example)

To set this so it has no weight add another field here:

Field Id: gearWeight Value: 0

And finally if you want to list how much Ammo the weapon has add one more field:

Field Id: wpShots Value: 1000 (or however much ammo/shots that weapon has).
-----

Creatures also have some special fields you can use for them when adding their special abilities. For them you would do a Bootstrap but several "Racial Abilities" have some special fields you can use with them. Specifically the following are of note:

abAquatic
abArmor
abBurrow
abFear
abFlyGener
abSize

For any of these you can set a Field with the a Field: abilValue Value: (whatever it should be). So, for example, if you have a creature than can Burrow at a Pace of 8 then you could Bootstrap abBurrow and for the Field: abilValue you would set Value: 8. These can be negative numbers as well, so abFear might have an abilValue of, say, -2 if you needed. The value should be fairly obvious for each of those things, whether it's for a Pace value or Armor or what have you.

One special one that also falls into this category is abWeapon. For this you have a field to set.

Field Id: livename
Value: (Name of the weapon, such as Claw/Bite, for example, or Bite (AP 10) for AP attacks.)

AND you have a Tags... to set:

Group Id: WeaponDie TagId: (Half Weapon Die type.)

abWeapon assumes this is a Str+Die type of weapon, so a Str+d4 claw attack would have a TagId: 2.

For creatures that have actual weapons and other equipment you might bootstrap there is a further Tag you may want to set on any of the the equipment you add to them.

GroupId: Equipment Tag Id: StartEquip

I don't really now WHY to add that, but it looks like that is how it's commonly handled.
---------------------------------

Many settings don't allow any Arcane Backgrounds or Edges that rely on having an AB. For easy reference here is a list all of all AB related items that you might add to your Preclude tab to fit this requirement:

edgAdept
edgArcMag
edgArcMir
edgArcPsi
edgArcSci
edgArcSup
edgChamp
edgGadget
edgHolyWar
edgMental
edgMrFixIt
edgNewPwr
edgPwrPts
edgPwrSurg
edgRapRch
edgRapRch2
edgSoulDrn
edgWizard
skFaith
skPsionics
skSpellcst

zarlor January 11th, 2013 04:41 AM

To add 4 additional Skill Points:

Eval Script: Setup/8000

Code:

#resmax[resSkill] +=4
-----
To set an Edge to only be usable by a Female character:

Expr-Req
Code:

hero.child[mscPerson].field[perGender].value = 1
For Male set that value to 0.

-----

Some settings use a languages rule that says the character should have 1/2 of their Smarts in languages. This one is essentially already set up, so use an Eval Script in a Setting Adjustment as follows:

Eval Script: Initialization/1000

Code:

perform hero.assign[Hero.SmartsLang]
-----
Some settings allow the character to pick certain higher ranked Edges at character creation. The Born A Hero setting works for this, but it allows for all ranks to be ignored. Here's an example that allows for everything but Legendary Edges to show as valid if they were picked at character creation. To select, say, only Seasoned edge just remove all the other MinRank values other than MinRank.1.

Eval Script: Initialization/200

Code:

foreach thing in Edge where "(MinRank.1 | MinRank.2 | MinRank.3)"
  if (hero.tagis[mode.creation] = 1) then
      var ignoretag as string
      ignoretag = "IgnoreRank." & eachthing.idstring
      perform hero.assignstr[ignoretag]
  endif
nexteach

This accesses a new feature that CapedCrusader graciously put into place for us where this "IgnoreRank." mechanic will allow a specific Edge to show as valid even if the character does not otherwise meet the Rank Requirements.

Next we need to make sure the Edge remains valid once we go into Advancement mode.

Eval Script: Validation/100

Code:

foreach pick in hero from Edge where "(MinRank.1 | MinRank.2 | MinRank.3)"
  if (eachpick.creation = 1) then
      perform eachpick.assign[Helper.IgnoreRank]
  endif
nexteach

-----
For adding a bonus to a trait based on Rank.

Eval Script: Pre-Traits/5000

Code:

var bonus as number
bonus = herofield[acRank].value + 1
perform #traitadjust[trCommand,+,bonus,"Valhalla Graduate"]

CapedCrusader has noted of this: "For NPC's though, since we don't know what Rank they are until everything is bought, and it can change every time something on the character changes, it has to be populated much later. So, be aware that using the acRank value can be somewhat unpredictable with NPC's."

-----
A thorny one that Erich brought up dealing with how to use the mechanic used by the Racial Property "Very Costly Atribute", but in this case trying to do it for all Knowledge skills. Knowledge skill are rather special since they are not Unique, you can have multiples of the. CapedCrusaader came through with the following code:

Eval Script: Effects/1000

Code:

foreach pick in hero from Advance where "Skill.skKnow"
  eachpick.field[advCost].value *= 2
nexteach

Eval Script: Traits/5000 Index: 2

Code:

foreach pick in hero where "Skill.skKnow"
  perform #resspent[resSkill,+,eachpick.field[trtUser].value - 1,"Hindrance Name"]
  var modifier as number
  modifier = maximum(eachpick.field[trtUser].value - eachpick.linkage[attribute].field[trtFinal].value,0)
  perform #resspent[resSkill,+,modifier,"Hindrance Name"]
nexteach

-----
To make the effects of an Edge or Hindrance show up as selectable (under the "Activated Abilities" section) on the In-Play tab check the "Activated by User?" cehckbox and enclose your code like the following:

Code:

if (field[abilActive].value <> 0) then
  herofield[acIgnWound].value += 1
endif

In this case we're using "Liquid Courage" as an example so just replace that "herofield[acIgnWound].value += 1" with the code you need for the activated ability.

-----
CapedCrusader worked out the following code for me to apply a +1 bonus to damage for all Melee attacks on a character coming from a specific Edge. This is an example of stepping through just one set of things, in this case Melee Weapons, and applying to something just to those.

Pre-Traits/5000
Code:

foreach pick in hero from WeapMelee
  eachpick.field[wpDmgBonus].value += 1
nexteach
perform hero.child[wpUnarmed].setfocus
  focus.field[wpDmgBonus].value += 1

-----
This one is an example of narrowing down to a specific set of things (like above) but then checking for and changing a further subset of those things, in this case we're going to step through Ranged Weapons, then we'll look for the ones that have the tag for a Thrown weapon and then set what the range value is for those weapons, as taken from the Mighty Throw Edge from Weird Wars: Rome:

At Pre-Traits/5000
Code:

foreach pick in hero from WeapRange
  if (eachpick.tagis[Weapon.Thrown] <> 0) then
      eachpick.field[wpShort].value = 4
      eachpick.field[wpMedium].value = 8
      eachpick.field[wpLong].value = 16
  endif
nexteach

-----
Gumbytie gave us the following for linking an existing skill to a different Attribute. In this example it's changing Fighting to work off of Smarts instead of Agility as the linked stat:

Put this at Setup/1000:
Code:

perform hero.childfound[skFighting].setlinkage[attribute,Attribute,"thingid.attrSma"]
-----
From SeelyOne in response to dartnet's request for a way to give a bonus to all Skills that are Smarts-based

Pre-Traits/5000 before Calc trtFinal

Code:

foreach pick in hero from Skill where "Attribute.attrSma"
  eachpick.field[trtRoll].value += 1
nexteach


zarlor February 4th, 2013 06:02 AM

If anyone has more, anything I missed, or just corrections to the above, please let me know. I would certainly appreciate the feedback.

Erich February 4th, 2013 07:45 AM

Please sticky this.

-Erich

jbearwillis February 4th, 2013 07:42 PM

Hey CapeCrusader is there a way to sticky this Post so people can always find it.

SeeleyOne February 3rd, 2014 05:30 PM

Changing the XP Table
 
There is a way to change the XP table. The example here changes it to 25 XP per Rank.

Make a new Mechanic in the Editor, just add it to your user file. You can also link it to a particular source if you only want to use it in certain campaigns or settings.

Phase: Final
Priority: 5010

Eval Script:
Code:


    var xp as number
    var xpperrank as number
    xpperrank = 25
    xp = hero.child[resXP].field[resMax].value
 
    if (xp < xpperrank * 4) then
      herofield[acRank].value = round(xp / xpperrank,0,-1)
    else
      herofield[acRank].value = 4
      endif

The first part only changes the XP table. It does not change the Advancements after 80 XP (which slows down to one per 10 XP instead of per 5 XP). So just add a second Eval script to the mechanic so that it will be nice and do it for us. This will not calculate when making an NPC and it telling us how much XP it has. Who uses that anyway? :P

Phase: Setup
Priority: 2010
Code:

    var xp as number
    xp = hero.child[resXP].field[resMax].value
    if (xp >= 85) then
      #resmax[resAdvance] +=1
      endif
    if (xp >= 95) then
      #resmax[resAdvance] +=1
    endif

I have found that the above code gets angry when you import a creature or stock character. The reason is that they do not have the resAdvance value. I have changed the code to the following:

Code:

if (herofield[acCharType].value = -1) then
    var xp as number
    xp = hero.child[resXP].field[resMax].value
    if (xp >= 85) then
      #resmax[resAdvance] +=1
      endif

    if (xp >= 95) then
      #resmax[resAdvance] +=1
    endif
endif


SeeleyOne February 15th, 2014 10:34 PM

Sometimes you might want an edge to not appear on the print-out after you obtain a superior version of it. For example, it does not need to say both Attractive and Very Attractive.

While the timing below might not be 100% necessary, I found that after some playing around that it does have an effect on it. When I tried it in other phases it would not work. So you are welcome to figure out its nuances if you want to (and if you do not, just use what I show)

Eval Script
Phase: Pre-Traits
Priority: 5000

Code
Code:

if (hero.tagis[Edge.edgWhatever] = 1) then
      perform this.assign[Print.NoPrint]
endif

I was not able to find examples of how to make an edge refer to itself. Or anything else for that matter (unless you count picks), when looking over the source files. However, I have learned to use the "this" when programming in other programming languages so I decided to give it a try.

SeeleyOne May 28th, 2014 07:20 PM

Some settings or house rules have a Skill Rating maximum that is dependent upon the character's Rank. This can be done by making a mechanic that has a Source that has the given setting/house rule set checked.

The example below makes it so that a Novice can only get d8 in a skill rating. It increases to d10 at Seasoned. It increases to d12 at Veteran.

Pre-Traits 5000
Code:

    var xp as number
    var skillMax as number
    xp = hero.child[resXP].field[resMax].value
    skillMax = 4

~Determine the skillMax bonus by XP value.

    if (xp >= 20) then
      skillMax +=1
    endif

    if (xp >= 40) then
      skillMax +=1
    endif

~Apply the skillMax to each skill.
foreach pick in hero from Skill
    eachpick.field[trtMaximum].value = skillMax
nexteach


Paragon August 15th, 2014 07:50 AM

At the suggestion of the estimable Zarlor, I thought I'd note this one:

Pre-Traits/5000
Code:
Code:

foreach pick in hero from WeapRange
if (eachpick.tagis[WeaponType.ModPistol] <> 0) then
eachpick.field[wpDmgBonus].value += 2
endif
nexteach

This was a bit of code on the Gunslinger Edge for my XCOM SW game, that allowed all modern pistols to do +2 damage in the Sniper's hands. It was put together by kitbashing together a couple of bits of code, one from Caped Crusader and one from (I'm guessing) Zarlor.

A couple of things to be aware of, though:

1. Damage bonuses are listed directly with the damage value, so if you have a pistol with something like, say, 2D6-1, this will produce a result that says 2D6-1+2. That actually gets you the correct result, but its a little--odd. As Zarlor says, if you want to fix that, you could do it by copying the problematic weapons, precluding the old ones, then moving the -1 into the damage bonus field.

2. You need to be aware of what types there are, and potentially do a more complicated code (Zarlor suggested:

Code:

foreach pick in hero from WeapRange
  if (eachpick.tagis[WeaponType.ModPistol] | eachpick.tagis[WeaponType.FutPistol] <> 0) then
      eachpick.field[wpDmgBonus].value += 2
  endif
nexteach

should be structured right) it you have more than one type you're trying to apply the modifier to. In addition, it may be necessary to change types on some things (if I wanted to apply it to the by the book Laser Pistol I'd need to copy-edit-preclude process, as its not actually tagged as a pistol of any sort, just an energy weapon).

SeeleyOne August 16th, 2014 04:18 PM

Sometimes it is desirable to have a value show up with a given Edge or racial ability.

At this time it does not appear that Savage Worlds has access to Pathfinder's abValue field, which is a value that can be added to by other sources (such as other edges). So far I have only tested it with the Traits 5000, in anticipation to potentially linking it to attribute values, and it works.

Here is what I did to a replaced version of the Command edge.
Code:

var CommRad as number
CommRad = 5

if (hero.tagis[Edge.edgComPres] = 1) then
      CommRad += 5
endif

field[livename].text = field[thingname].text & " (Radius: " & CommRad & ")"

As I show above, it can add to the value if specific Edges are present (in this case Command Presence).

SeeleyOne August 18th, 2014 10:03 PM

Some settings and/or house rules might want a more fluid amount of Major and Minor Hindrances. Instead of requiring a set number you can base it on a targeted maximum Reward Point value.

To get this to work I used a replace Thing ID for valHinders, which is a Simple called Hindrances.

In the first Eval Rule script, I changed the equations for the
~RDS SWD Max Major and Max Minor are now dynamic values

In this example I decided on a maximum of 10, which can be 5 Major Hindrances, 10 Minor Hindrances, or any combination that equals 10 Reward Points.

Code:


      var major as number
      var minor as number

      ~iterate through all hindrances and tally up the number of majors and minors
      ~Note: We must only tally hindrances that are user added and not an advance.
      foreach pick in hero from Hindrance
        if (eachpick.isuser + !eachpick.tagis[Advance.?] >= 2) then
          if (eachpick.field[hinMajor].value = 0) then
            minor += 1
          else
            major += 2
            endif
          endif
        nexteach

      ~determine our maximum number of major and minor hindrances
      var max_major as number
      var max_minor as number

      ~RDS SWD Max Major and Max Minor are now dynamic values
      max_major = minimum(major, 10)
      max_minor = minimum(minor, 10 - max_major)

      ~if we have no more than our maximum major and minor hindrances, we're good
      if (major <= max_major) then
        validif (minor <= max_minor)
        endif

      ~synthesize our validation message appropriately
      @message="Maximum of " & max_major & " points worth of major and " & max_minor & " points worth of minor hindrances allowed"

      ~mark associated tabs as invalid
      container.panelvalid[edges] = 0

      ~assign a tag to the hero to indicate the invalid state
      ~Note: This is used to color highlight the title above hindrances on the tab.
      perform hero.assign[Hero.BadHinders]

The effect is that as Major are selected, it will diminish the number of possible Minor Hindrances. For a more by-the-book value you might want to put 4 instead of my 10 above.

Paragon February 19th, 2015 06:51 PM

From Caped Crusader, a note about how to make sure someone can take a normal amount of Hindrances if their racial template already gives them one:

Code:

#resmax[resHinder] += 1 (or 2 if it's Major)

SeeleyOne June 2nd, 2015 07:14 AM

I just came up with an even more efficient code for enforcing Novice and character creation and for enforcing the Rank while choosing Advances.

It can also be used with an alternate XP table. All that you have to do (as far as Rank is concerned) is change the value of xpPerRank in this code and you are done. You would possibly have to alter the number of Advances in a different Eval script.

I spread out the code a bit so that it is easier for us to read.

Phase: Final
Priority: 5010

Code:

    var endRank as number
    var xpPerRank as number
    var advPerRank as number
    var advCount as number
    var xp as number
    var xpRank as number
    var rankCount as number
    var endRank as number

    xpPerRank = 20
    advPerRank = xpPerRank / 5
    advCount = 0
    xp = hero.child[resXP].field[resMax].value
    xpRank = xpPerRank
    rankCount = 0
    endRank = 0

  ~ Check for spent Advances
  foreach pick in hero from Advance sortas _CompSeq_
      advCount += eachpick.field[advCost].value
  nexteach

  ~ Determine Rank based on current Advance
  ~ Seasoned
  rankCount = advPerRank -1
  if (advCount >= rankCount) then
      if (xp >= xpRank) then
          endRank = 1
      endif
  endif

  ~ Veteran
  rankCount = rankCount + advPerRank
  xpRank = xpRank + xpPerRank
  if (advCount >= rankCount) then
      if (xp >= xpRank) then
          endRank = 2
      endif
  endif

  ~ Heroic
  rankCount = rankCount + advPerRank
  xpRank = xpRank + xpPerRank
  if (advCount >= rankCount) then
      if (xp >= xpRank) then
          endRank = 3
      endif
  endif

  ~ Legendary
  rankCount = rankCount + advPerRank
  xpRank = xpRank + xpPerRank
  if (advCount >= rankCount) then
      if (xp >= xpRank) then
          endRank = 4
      endif
  endif

  ~ Apply the Rank
  herofield[acRank].value = endRank


SeeleyOne June 7th, 2015 11:43 AM

There are times that you will want a Racial Ability or an Edge make it so that you can ignore the Rank requirements for certain edge types.

For the first example, I made a Racial Property that ignores the Rank requirement for all Combat edges. I figured that it was a good racial property to give a particularly warlike race/culture. It has two Eval scripts.

Phase: Validation
Priority: 100
Code:

foreach pick in hero from Edge where "EdgeType.Combat"
    perform assign[Helper.IgnoreRank]
nexteach

Phase: Initialization
Priority: 200
Code:

foreach thing in Edge where "EdgeType.Combat"
      var ignoretag as string
      ignoretag = "IgnoreRank." & eachthing.idstring
      perform hero.assignstr[ignoretag]
nexteach

For the second example, I revised the Valhalla Graduate edge. Before I had made the leadership edges be Novice but then used an Exp-Req to get their Rank requirement back if the Valhalla Graduate was not on the character. This revised way is better because I don't have to make copies of any leadership edges to make it work and it is far simpler.

It also requires two eval scripts to work. They are similar to above, but the priority of the Initialization had to change because it is from an edge.

Phase Validation
Priority 100
Code:

foreach pick in hero from Edge where "EdgeType.Leadership"
    perform assign[Helper.IgnoreRank]
nexteach

Phase Initialization
Priority 2101
Code:

foreach thing in Edge where "EdgeType.Leadership"
      var ignoretag as string
      ignoretag = "IgnoreRank." & eachthing.idstring
      perform hero.assignstr[ignoretag]
nexteach


dartnet June 16th, 2015 09:31 PM

Here is the code to raise the max cap on an Attribute.

Pre-Traits/5000
Code:
Code:

#traitbonus[attrStr] += 1
hero.child[attrStr].field[trtMaximum].value += 1

Before:

Calc trtFinal

Endtransmission July 7th, 2015 12:03 AM

Bootstrapping Vs AutoAdd

So we've all seen and played with Bootstrapping one Thing to another, lets call them Thing 1 and Thing 2. This adds Thing 2 to a character as long as Thing 1 is attached and can never be removed. Sometimes useful, mostly... not so much. What happens if we want to automatically some equipment or an injury that should later be removable, or add a skill to someone when they pick up an object, but keep it when they drop the object again?

This is where AutoAdd comes into play

Code:

<autoadd thing="injACSLoss" portal="peInjury"></autoadd>
autoadd thing="xxxxxx" adds the requested Thing to the character, but if you don't add the Portal ID as well, it will either not show up on the character at all, or will be permenantly attached with no way to ever remove it. You can find the Portal IDs by going through the tab_*.dat files in Savage/Source. Each of the tab_ files equates to one of the screens in Hero Lab.

For simplicity sake, here's the list of available portals... assuming you've not created any of your own. You'll notice that the portals are prefixed with the tab abbreviation, e.g. ba for Basic, sk for Skills etc. etc.

Basics tab
- baAttrib - This is the Attributes panel
- baTrait - This is the Derived Traits panel
- baRank - This is the character Rank
- baCreation - Shows character creation details (Advances, edges, hindrance points etc.)
- baStatus - Shows the current status (encumrance/load limit)

Skills tab
- skSkills - shows the list of current skills
- skLangs - Shows the Languages panel

Edges tab
- edEdges - Shows the Edges area
- edHinders - Shows the hindrances area
- edRewards - shows the rewards area

Arcane Tab
- apPowers - Lists all powers


Armoury tab
- arMelee - shows the Melee weapons section
- arRange - shows the Ranged weapons section
- arSpecial - Special weapons
- arDefense - Defensive items

Gear tab
- grGear - Misc gear area
- grGizmos - Weird science gear
- grVehicle - Vehicles

Advances tab
- adAdvances - Selected advances

Personal tab
- peImages - Shows image
- peInjury - Shows the Temporary injuries
- peAdjust - Permanent Adjustments
The other personal information seems to come from elsewhere and is included using the Thing mscPerson

Allies
- alAllies - Shows the list of allies

Journal
- jrTitle - This is just a title according to the code comments
- Journal - This is a table to add new journal entries

In-Play
- ipTracker - This is where you'd add new trackers
- ipActive - This is the list of active abilities
- ipFCActiv - This is a list of the magic item powers for the character
- ipFCActiSh - This is for Fantasy Companion Magic item skill bonuses
- ipFCActivE - Lists active Edges
- ipFCActiPh - Fantasy Companion Magic Item granted powers with a header
- ipSPCActih - Lists the active super powers with a header
- ipAdjust - Shows any adjustments

Special tab
- spSpecial - Lists all special traits

Endtransmission July 7th, 2015 11:23 AM

Something else that came up tonight that I've meant to put in here before.

If you are just writing and testing on a Windows environment, you may not see these problems, but the Mac client (much like the OS) is case sensitive and *demands* perfect match.

This can explain some errors you may encounter with errors that appear to be syntactically correct.

AndrewD2 July 7th, 2015 11:53 AM

Everything in Hero Lab is case sensitive.

Endtransmission July 7th, 2015 12:03 PM

Quote:

Originally Posted by AndrewD2 (Post 212249)
Everything in Hero Lab is case sensitive.

It should be, yes, but I've encountered this problem a few times when developing or testing something on my windows machine works and testing on the mac where it doesn't. In every case it has been case sensitivity.

AndrewD2 July 7th, 2015 12:14 PM

That is ... odd. What is an example? I know UIDs and Tags are all Case Sensetive, although I guess some things like if statements can be If of if (I've seen both used in code).

Endtransmission July 7th, 2015 12:44 PM

The most recent example was

Code:

<before name="calc trtFinal"/>
vs
Code:

<before name="Calc trtFinal"/>
Calc should be upper case to work on a Mac, but seems to work with either in windows

AndrewD2 July 7th, 2015 12:52 PM

that is weird ... it's a string and shouldn't matter either way. If it's causing errors on a mac you should report a bug.

Paragon July 7th, 2015 05:54 PM

Quote:

Originally Posted by Endtransmission (Post 212251)
It should be, yes, but I've encountered this problem a few times when developing or testing something on my windows machine works and testing on the mac where it doesn't. In every case it has been case sensitivity.

Yeah. In specific, your problem with my file wasn't causing a problem when I loaded it myself, so I didn't even realize the case was wrong.

SeeleyOne May 11th, 2016 08:51 PM

I have been fixing up a modded version of the Hellfrost data. It looks like that I got the Disciple of Tiw working, where it allows for the character to treat Combat edges as one rank lower. I figure that there are uses for this in other settings/edges.

The timing is so that it will work for an Edge (as that is what the Disciple of Tiw is).

Initialization/2101
Code:

var rank as number
var target as number
rank = herofield[acRank].value
target = 0

if (rank <= 3) then
  rank += 1
  foreach thing in Edge where "EdgeType.Combat"
      target = eachthing.tagvalue[MinRank.?]
      if (rank = target) then
        var ignoretag as string
        ignoretag = "IgnoreRank." & eachthing.idstring
        perform hero.assignstr[ignoretag]
      endif
  nexteach
endif

Validation/100
Code:

var rank as number
var target as number
rank = herofield[acRank].value
target = 0

if (rank <= 3) then
  rank += 1
  foreach thing in Edge where "EdgeType.Combat"
      target = eachthing.tagvalue[MinRank.?]
      if (rank = target) then
        perform assign[Helper.IgnoreRank]
      endif
  nexteach
endif


CapedCrusader July 24th, 2017 07:38 PM

Changing the Cash Symbol
 
Changing the cash symbol, and moving it to after the number: (PreTraits/5000 seems fine)

Code:

      herofield[acCshSymbl].text = " gp"
      perform hero.assign[Hero.CashBackwd]


salcor December 6th, 2017 04:19 PM

Question,

I am looking for a common code example for raising an attribute by 1 or two levels.

I have looked through the listed examples and it didn't just out at me. Thanks.

Salcor

zarlor December 7th, 2017 05:49 AM

That's because I think we mostly included stuff that wasn't readily available from other examples in the base data files already. Just take a look at the Race Elven (racElven), for example, which you'll find bootstraps the Racial Ability Agile (abAgile). Looking at the Racial Ability we see at Pre-Traits 5000 it does:

Code:

#traitcreation[attrAgi] += 1

salcor December 7th, 2017 05:10 PM

Thanks,

I guess there really isn't anything different between raising the attributes before the player chooses them or after.

Salcor

zarlor December 8th, 2017 05:04 AM

In what context are you trying to do this?

salcor December 11th, 2017 12:49 PM

Zarlor,

Sorry I am working on character attribute adjustments for Savage Rifts Iconic Frameworks. I was wondering, how do you change the assigned skill for a weapon. I made Flame Bolt as a ranged weapon and want to tie it to Psionics.

Salcor

zarlor December 11th, 2017 04:47 PM

AH, I haven't really read through Rifts, but I would think #traitcreation would be fine if I understanding Iconic Frameworks well enough. As for assigned skill... I'm not too sure about that.

GunbunnyFuFu January 12th, 2018 07:24 PM

Adding Power?
 
Greetings,

I'd like to add the Mega Powers from Savage Rifts. I can do this with the editor..how can I add a Mega Power (or a new power, for that matter) outside of the editor?

Thanks,

GB

zarlor January 13th, 2018 05:51 AM

What do you mean by "outside of the editor"? Speaking strictly for a new Power (I'm not familiar with Rifts to know what a Mega Power is compared to a Power) if you were using a text editor you could copy the code for some other power in the .user file and paste that as a new section to modify the xml code from there (I like using Notepad++ for modifying xml files for that). Unless you mean within the main HL program, in which case I think there is a spot under the Powers tab where you might be able to add a custom power there (but that will only get saved in the portfolio you are modifying and noplace else.) Or do you mean something else?

GunbunnyFuFu January 13th, 2018 06:00 AM

A Mega Power is just an enhanced version of a regular power. Thanks for the help...I'll copy the relevant data from the custom .user file. Should this data be appended to one of the .dat files (perhaps the main file..rifts.dat)?

GB

zarlor January 13th, 2018 07:19 PM

That's a question for the Rifts thread. That depends on how they are trying to organize things as to which .dat file it should be in so that's heavily dependent on that specific project.

GunbunnyFuFu January 14th, 2018 02:45 AM

Thanks Zarlor!

Phrll July 21st, 2018 12:46 PM

Zarlor, this is a great thread! Thanks much for starting it!

TCArknight May 17th, 2020 06:29 AM

[SWADE] - How to add a power as an innate ability
  1. Create "Innate Abilities" Arcane Background. Make note of the ID you give it.
  2. Go to the Invalid Powers button and select all of the listed powers. Leave Power Points and number of Powers empty. You can adjust these through scripts.
  3. Create Racial Ability / Property which adds the power you are looking for.
  4. Bootstrap the Arcane Background from (1) and the Innate Power to the Ability / Property created in (3)
  5. Open the Tags section of the bootstrap for your innate power.
  6. Add Arcane as the Group with the ID from (1) as the Tag.
  7. Save and Reload your data, Select the race with the new Ability/Property. See the shiny new "Innate Abilities" tab with the power you've made innate. :)

Of course, you may have to create a new power depending if your power has any innate modifiers like Range (Self) or such.

TCArknight May 17th, 2020 02:13 PM

Something I haven't seen discussed, and it may apply in all game systems, is if you have the need for bootstrapping an edge to an ability but the edge has a chooser on it and you need a specific selection from the chooser as part of the bootstrap.

In the editor:
Field ID: usrChosen1
Value: id of the needed choice
select Pick instead of Assign.

Reload your dataset and you should be good. :)


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

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