• Please note: In an effort to ensure that all of our users feel welcome on our forums, we’ve updated our forum rules. You can review the updated rules here: http://forums.wolflair.com/showthread.php?t=5528.

    If a fellow Community member is not following the forum rules, please report the post by clicking the Report button (the red yield sign on the left) located on every post. This will notify the moderators directly. If you have any questions about these new rules, please contact support@wolflair.com.

    - The Lone Wolf Development Team

Transition trouble

Lord Magus

Well-known member
I am running into trouble with a particular item I am coding

It is a special armor that is easily enchanted with specific armor item powers, reducing the cost of such powers by half.

I have tried the following 2 scripts at First - 2550, but I get the error message:
Syntax error in 'eval' script for Thing 'mAMSAWvScl' (Eval Script '#1') on line 1
-> Script reference is invalid under the circumstances

Code:
  perform findchild[BaseItemPw,thingid.ipAMSAArFo?].setfocus
  focus.field[iPriceCash].value *= 0.5

Code:
  perform container.gizmo.setfocus
  if (focus.tagis[thingid.ipAMSAArFo?] <> 0) then
    focus.field[iPriceCash].value *= 0.5
  endif

I then tried this
Code:
  foreach pick in gizmo from BaseItemPw where "thingid.ipAMSAArFo?"
    eachpick.field[iPriceCash].value *= 0.5
  nexteach
which at least compiled but did not reduce the price and gave me this message
Attempt to access non-existent containing entity from script
- - -
Can't foreach over invalid container (this is probably related to a previous error)
- - -
Can't foreach over invalid container (this is probably related to a previous error)

Finally, it dawned on me that the armor type and the item powers are both gizmos on a magic armor pick, so I tried
Code:
  perform container.parent.setfocus
  perform focus.findchild[BaseItemPw,thingid.ipAMSAArFo?].setfocus
  focus.field[iPriceCash].value *= 0.5
and got the same error as the first 2 tries.

Is it possible to steer me in the right direction or at least to point me to an item that does a similar thing? I feel like I'm getting lost in transitions here. Thanks!
 
Am I to understand you want a set of armor to reduce the cost of things you add to it? In general, scripts can only affect things that are on the character already, so until you purchase the thing, you can't reduce the cost (AFAIK). That said, the error on your first script is likely due to missing quotes:

Code:
perform findchild[BaseItemPw,"thingid.ipAMSAArFo?"].setfocus

Although, come to think of it, it might also be the ? at the end. I think I've seen this before where you can use the ? alone, but not with something else, such as:

[thingid.?] = OK
[thingis.ipAM?] != OK

Also, when using setfocus, it's good practice to include the following line after:

Code:
doneif (state.isfocus = 0)
 
Last edited:
Am I to understand you want a set of armor to reduce the cost of things you add to it? In general, scripts can only affect things that are on the character already, so until you purchase the thing, you can't reduce the cost (AFAIK).

Indeed, the set of armor is supposed to reduce the cost of armor powers such as air focus (a power in my campaign), so this is a gizmo affecting another gizmo by modifying its cost (iPriceCash) after it has been added, but before the item total cost is calculated and charged.

I have been able to manipulate the cost of an added weapon power in another instance; the script was on the power itself and referred to the weapon type. I may have to re-visit that again; I just had to establish focus on the parent container for that one (iMagWeapon or something like that), strangely enough, and not on the weapon gizmo itself.

That said, the error on your first script is likely due to missing quotes

My bad. Will correct this when I get home today.

Although, come to think of it, it might also be the ? at the end. I think I've seen this before where you can use the ? alone, but not with something else

I've read in the Wiki that you can use wild cards in this situation as it's a tag expression. But then, I forgot the quotes, so I may be a little over my head here!

Also, when using setfocus, it's good practice to include the following line

Indeed. I have not been used to this, it's the first time I delve into parent and gizmo stuff. Will do! Thanks!
 
That said, the error on your first script is likely due to missing quotes

Unfortunately, adding the quotes did not change the outcome.

Am I to understand you want a set of armor to reduce the cost of things you add to it? In general, scripts can only affect things that are on the character already, so until you purchase the thing, you can't reduce the cost (AFAIK).

In fact, the armor pick is is in a gizmo on the (hero) pick iMagArmor. The armor powers are in the same gizmo on iMagArmor. So what I am shooting for is to have a pick in the gizmo alter a field on another pick in the same gizmo (if it's there), before the final price for the item is calculated... or at least that's how I understand it.

Among my script attempts, the only two that compile without spitting out a syntax error are:
Code:
~ First - 2550 (altering iPriceCash must be done early)
foreach pick in gizmo from BaseItemPw where "thingid.ipAMSAArFo?"
  eachpick.field[iPriceCash].value *= 0.5
nexteach
but then, immediately, this message appears:
Attempt to access non-existent containing entity from script
- - -
Can't foreach over invalid container (this is probably related to a previous error)
- - -
Can't foreach over invalid container (this is probably related to a previous error)

Code:
~ First - 2550
perform gizmo.findchild[BaseItemPw,"thingid.ipAMSAArFo?"].setfocus
focus.field[iPriceCash].value *= 0.5
but then, immediately, this message appears:
Attempt to access non-existent containing entity from script
- - -
Attempt to access 'focus' pick or thing from script when no focus exists
- - -
Attempt to access 'focus' pick or thing from script when no focus exists

At least in the second case, I get that it does not "find" a suitable target pick.

And that is where I am stuck at the moment. I have read that you can only foreach on hero and gizmo, not parent or other containers, and attempts at these indeed ended up in errors. If anybody has other pointers (or can just confirm that what I am aiming for in fact cannot be done), I'll gladly take them. Thanks again!
 
Last edited:
I just want to check a basic setting - you're sure you set up this new magic armor to have a gizmo?

At the bottom of the thing definition of the armor itself should be a child entry, like this:

<child entity="mSpecMagic">
<bootstrap thing="arBanded"/>
</child>
</thing>

Or if you're viewing this in the editor, the Gizmo button is among the grid of blue buttons on the right-hand side.


If you created the item on the Armor, Magic tab, it'll default to having a gizmo, but the error messages you're receiving suggest it doesn't have one.
 
I just want to check a basic setting - you're sure you set up this new magic armor to have a gizmo?

In fact not... the thing I am working on is a "regular" non-magical scale mail variant, made of wyvern scales.

When this non-magical armor is used to create a custom magic armor (on the Armor tab of a character) (i.e. when it is added as a gizmo to the iMagArmor pick), it reduces the cost of certain armor item powers that can be added along to it to iMagArmor. So it's the non-magical armor I'm creating, not a specific magic armor on the Magic armor tab of the editor.

When the base version of the armor is used, it's just a fine masterwork set of scale mail.
 
At this point, I recommend posting the entire thing element for this armor, copied from the .user file you've created - open that file in a text editor, and find the definition of this armor, and copy it and paste it here. As an example of what you're looking for, this is plain old studded leather:

Code:
<thing id="arStudded" name="Studded leather"description="An improved form of leather armor, studded leather armor is covered with dozens of metal protuberances. While these rounded studs offer little defense individually, in the numbers they are arrayed in upon such armor, they help catch lethal edges and channel them away from vital spots. The rigidity caused by the additional metal does, however, result in less mobility than is afforded by a suit of normal leather armor." compset="Armor">
<fieldval field="gWeight" value="20"/>
<fieldval field="gSizeCost" value="25"/>
<tag group="ArmorAC" tag="3"/>
<tag group="ArmorMaxDx" tag="5"/>
<tag group="ArmorCheck" tag="1"/>
<tag group="ArmorArcFl" tag="15"/>
<tag group="ArmorClass" tag="Light"/>
<tag group="EquipType" tag="MetalSome"/>
<tag group="EquipType" Leather"/>
</thing>
 
Here goes...
(ipAMSAArFoc and ipAMSAArFo2 are Air Focus 1 and Air Focus 2, which are magic armor powers)

Code:
  <thing id="mAMSAWvSc" name="Air wyvern scale armor" description="This grey scale armor is made from an air wyvern scales sewn over high quality light leather. It is light and comfortable.\n\nThe cost of adding Electricity Resistance or an*Air Focus to this armor is reduced by 50%.\n\nCost to make: 500 £ of scales, 50 £ other materials; Leather working*DC 24, 5 days, 50 £ retry." compset="Armor" summary="Made from an air wyvern scales sewn over high quality light leather.">
    <comment>Cost reduction for Elec Resistance not coded yet</comment>
    <fieldval field="gWeight" value="15"/>
    <fieldval field="gSizeCost" value="1100"/>
    <usesource source="SOUL"/>
    <usesource source="sSOULAMS"/>
    <tag group="ArmorMaxDx" tag="3"/>
    <tag group="EquipType" tag="Leather"/>
    <tag group="ArmorCheck" tag="3"/>
    <tag group="ArmorArcFl" tag="20"/>
    <tag group="ArmorClass" tag="Medium"/>
    <tag group="Ability" tag="eSOULMat"/>
    <tag group="HasAbility" tag="eSOULMat"/>
    <tag group="ArmorAC" tag="6"/>
    <tag group="Helper" tag="AlwaysMast"/>
    <eval phase="First" priority="2550"><![CDATA[~ Script try no.1: This script compiles
perform gizmo.findchild[BaseItemPw,"thingid.ipAMSAArFo?"].setfocus
doneif (state.isfocus = 0)
focus.field[iPriceCash].value *= 0.5

~ Script try no.2: This script compiles
foreach pick in gizmo from BaseItemPw where "thingid.ipAMSAArFo?"
  eachpick.field[iPriceCash].value *= 0.5
nexteach

~ Script try no.3: This script does not compile
~ perform container.parent.setfocus
~ doneif (state.isfocus = 0)
~ perform focus.findchild[BaseItemPw,"thingid.ipAMSAArFo?"].setfocus
~ focus.field[iPriceCash].value *= 0.5

~ Script try no.4: This script does not compile
~ perform container.parent.setfocus
~ doneif (state.isfocus = 0)
~ focus.findchild[BaseItemPw,"thingid.ipAMSAArFo?"].field[iPriceCash].value *= 0.5]]></eval>
    <prereq message="This armor is already made out of a special material and a second type can not be added.">
      <validate>var X2HaveMate as number
        Call X2HaveMate
        @valid = X2HaveMate</validate>
      </prereq>
    </thing>
 
Oh, right - I've been mixing up PF2 and PF1, since we got to re-do the dumb way we set up custom magic items for PF2.

Ok, so when constructing a custom armor, the armor is inside the gizmo of the "custom/magic armor" gizmo. The armor itself does not have a gizmo.

(the exception to that is if you construct your item as a special/magic armor to begin with - Elven chain is an example of a non-magical armor, created on the special/magic armor tab, that can then be customized with item powers and a bonus once the user buys it).

So, you either need to move the item from one tab to another, if it's an item similar to elven chain, or if it is a standard type of armor, that's normally bought as a mundane item but could be enchanted, then your scripts need to change their context - the armor is inside the gizmo of the custom/magic item, so "container" is the transition to that gizmo from inside the container. But make sure to add doneif (container.ishero <> 0) for every script that's going to be manipulating the other picks inside this container, because that's how you prevent them from operating if the user is building a mundane version of this armor.
 
And I wanted to re-iterate something Sendric pointed out early on - changing the iPriceCash field can only happen once the item power is a pick - that's after the user has paid for it. So changing iPriceCash using an eval script will make the total value of the armor come out correctly, but users will need to make sure to pay the correct amount when making the initial purchase.

Off the top of my head, I don't remember a way to apply that sort of discount to purchases within a specific context.
 
...Changing the iPriceCash field can only happen once the item power is a pick...

So wouldn't that be the case on a custom magic armor or weapon, where you pick the type of armor or weapon, pick item powers, and then purchase the item after it has been defined?

The following item (weapon) power has a variable iPriceCash field value, that is set according to which type of weapon the power is added to. Granted, the script is on the power itself, not on another thing, but it is working. (EDIT: I set the price adjustment script to run at First-2550, but it seems to work if set up to First-10000)

Code:
    </thing>
  <thing id="ipAMSCstImp" name="Casting" description="A {i}casting{/i} weapon is a casting implement and can thus be used as a conduit to cast spells, much like a wand or staff.\n\nIf the weapon is dedicated to one or more spells, only those spells can be cast through it; otherwise, only spells of the affinity(ies) the weapon has a focus for can be cast through it. A wielder with the spellstrike ability ignores these requirements and can in fact use any weapon as a casting implement. Ranged weapons can be casting implements, for the same cost.\n\nBy their nature, wands, as well as masterwork rods and staves, are automatically {i}casting{/i} implements at no extra cost. The limitations above still apply to them, particularly to dedicated wands.\n\nOnly masterwork weapons can be made into {i}casting implements{/i}.\n\n{b}Construction{/b}\n{b}Requirements{/b} Craft Magic Arms and Armor; {b}Cost{/b} 250 gp for light weapons, 1*000 gp for one-handed weapons, 2*250 gp for two-handed weapons, 4*000 gp for firearms, 6*250 gp for siege weapons." compset="ItemPower" summary="Weapon usable as a conduit for spells" uniqueness="useronce">
    <fieldval field="iCL" value="3"/>
    <usesource source="sSOULAMS"/>
    <usesource source="sSOULCamp"/>
    <tag group="iSchool" tag="Universal"/>
    <tag group="iSchool" tag="Transmutat"/>
    <tag group="PowerType" tag="Weapon"/>
    <eval phase="PreLevel" priority="5150"><![CDATA[   perform container.parent.setfocus

   doneif (state.isfocus = 0)

   if (focus.tagis[component.BaseWep] <> 0) then
      perform focus.assign[AMSItem.CastImp]
   endif]]></eval>
    <eval phase="First" priority="2550" index="2"><![CDATA[   perform container.parent.setfocus

   doneif (state.isfocus = 0)

   if (focus.tagis[wCategory.Firearm] <> 0) then
      field[iPriceCash].value = 4000
   elseif (focus.tagis[wClass.OneHanded] <> 0) then
      field[iPriceCash].value = 1000
   elseif (focus.tagis[wClass.TwoHanded] <> 0) then
      field[iPriceCash].value = 2250
   elseif (focus.tagis[wClass.Siege] <> 0) then
      field[iPriceCash].value = 6250
   else
      field[iPriceCash].value = 250
   endif]]></eval>
    <evalrule phase="Validation" priority="5000" message="A casting implement must be a masterwork item."><![CDATA[   perform container.parent.setfocus

   validif (focus.tagis[EquipType.Masterwork] <> 0)]]></evalrule>
    <evalrule phase="PreLevel" priority="5125" index="2" message="Item is already a casting implement.">perform container.parent.setfocus

   validif (focus.tagis[AMSItem.CastImp] = 0)</evalrule>
    </thing>
 
Last edited:
Did that with the "doneif" you recommended!

Fair, but not quite what I meant. I was thinking of something even before you do a foreach loop (which the doneif I showed you wouldn't help with) or before the setfocus. Something like:

Code:
doneif (tagis[IsArmor.iMagArmor] = 0)

This would be done at the top of the script and would prevent anything from happening if this armor is being selected in the custom armor tab. Note: Not sure at what timing this would need to run, so probably something to worry about later.

So wouldn't that be the case on a custom magic armor or weapon, where you pick the type of armor or weapon, pick item powers, and then purchase the item after it has been defined?

The following item (weapon) power has a variable iPriceCash field value, that is set according to which type of weapon the power is added to. Granted, the script is on the power itself, not on another thing, but it is working. (EDIT: I set the price adjustment script to run at First-2550, but it seems to work if set up to First-10000)

If I understand correctly, you're adding this item power to the armor during the purchase process, and it correctly changes the armor's price? I think that makes sense. However, it's not the same thing as what you're trying to do with this armor. The process would look something like this:

Example 1 (Item Power)
1) Select Armor
2) Purchase Item Power
3) Armor Price Adjusted
4) Purchase Armor

Example 2 (Armor)
1) Select Armor
2) Purchase Item Power
3) Item Power Price Adjusted
4) Purchase Armor
 
If I understand correctly, you're adding this item power to the armor during the purchase process, and it correctly changes the armor's price?

For the item example I just gave (the "Casting" item power), there is a script on the power to set its own price (iPriceCash field) depending on which weapon type it is associated with. It can run no later than First 10000, otherwise iPriceCash is modified but not taken into account for the custom weapon's final price. Thus, while the script gathers information on another pick on the gizmo, it only modifies the thing it is on (the "Casting" power).

For the armor, the price-modifying script on the armor aims to affect the prices of the powers, not the armor's. I add the armor, then the script reduces some item power prices, if the relevant powers are added, during the purchase process. So it does not modify the thing it is on (the armor), but the prices of other picks in the gizmo (armor powers).

The process in the case of the armor would look something like this:
1) Select - Custom/Magic Armor - from the "Magic, Custom & Masterwork" section of the Armor tab
2) A window pops up, enabling customization (iMagArmor pick)
3) Pick base Armor
4) Pick armor Powers
5) Armor power prices adjusted by script on previously chosen armor
6) Final price of armor calculated in the pop-up window, according to the picks added, including armor type, masterwork, ac enhancement bonuses and armor powers (including those with modified price)
7) Purchase Armor at final price
 
Last edited:
Well, I finally got somewhere! Here's a brief recap for future reference.

The key seems to be to set up the armor not as a regular mundane armor (on the Armor tab of the editor), but rather as a magic armor (on the Armor, magic tab) even though it is not "magic"; it facilitates the transitions required.

I had to start from a copy of the iElvenChn thing: for some reason, if I started from scratch, even adding exactly the same things (except for the armor type), the price of the base armor would not be counted in the calculations.

The following script runs flawlessly so far, at First - 10000 (if later, iPriceCash is not accounted in final price)
Code:
perform gizmo.findchild[BaseItemPw,"thingid.ipAMSAArFo?"].setfocus
doneif (state.isfocus = 0)
focus.field[iPriceCash].value *= 0.5

For a single power, you can also use
Code:
gizmo.childfound[ipAMSAArFoc].field[iPriceCash].value *= 0.5

Thank you all for your help!
 
Back
Top