Down at the Foundry

So I figured I would show off my little journey on how I am setting up the new Foundry version of the game and an example of setting up something so that it won’t be a pain to maintain.

So the Trimaldi’s Magitech Cannon is an example of something that should in theory be easy, but because we’re working with data objects, requires a bit of noodling to figure out the best way to do it. The folks at ProjectFU just made an item entry with links to a bunch of prefabbed Magicannon items of each damage type and expecting you to drag them over and delete an existing one when you use the feature to make a new one.

This is functional, except Dave now is using the Variant Magitech Armament skill, which means the Trimaldis can Sublimate other Rare Weapons into the Magitech Cannon to use their qualities. How best do we tackle this? Well a single item that we can modify is probably the best answer, but how about the damage types?

Well, we solved that with macros in Roll20, I’m sure we can do that in Foundry too, right? Yes, and it’s Javascript based which means we can directly alter the underlying data object. This opens possibilities for automating Sublimating new items in the future, but for now we’re just going to worry about changing the damage type.

After a bit of banging around in the data model and figuring out what Foundy will and won’t let you play with, I came up with this script. It’s locked to the Trimaldis, but I don’t expect this to change anytime soon.

function makeUpdate (dmgType) {
    let newObject = {"img":"systems/projectfu/styles/static/compendium/classes/tinkerer/gadget/magicannon/magicannon-" + dmgType + ".png",
        "system.summary.value":"A magitech firearm that deals "+ dmgType+" damage.",
        "system.damageType.value":dmgType,
        "description": "<p>A magitech firearm that deals <strong>"+ dmgType+"</strong> @ICON["+ dmgType+"] damage.</p>"
    }
    return newObject;
}

// Find the Trimaldis and their cannon
let trimaldis=game.actors.getName("Trimaldis");
let cannon=trimaldis.items.getName("Magitech Cannon");

//Make list of cannon types.
const dmg = ["physical", "air", "bolt", "earth", "fire", "ice"]

// Make dialog prompt
let myContent = `
  <div class="form-group">
          <label for="dmgSelect">Select damage type</label>
          <select name="dmgSelect">`

for (i = 0; i < dmg.length; i++){
  let capDMG = dmg[i].capitalize()
  myContent += `
  <option value="${dmg[i]}">${capDMG}</option>`
}

myContent += `</select>
        </div>`


await Dialog.prompt({
    title: 'Select Magitech Cannon Damage type',
    content: myContent,
        callback: async(html) => {
          let selection = html.find('[name="dmgSelect"]').val();
          let change = makeUpdate(selection)
          await cannon.update(change) // Call the update and wait for it to finish
    }
 })

It could probably be improved upon, but it works and that’s all that matters to me.

Now when the Trimaldis click on the Magitech Cannon Inventory action in their action bar, they’ll see something a bit different from what the default option is:



So what happens if we click on the “Alter Magitech Cannon” button? We get this popup. (You’ll also likely be hitting the Spend 2 IP button which, unlike my Roll20 version, actually works here. :laughing:)

Selecting an option will not only change the damage type, but also updates all the text on the item description.

Not bad for an evening’s work.

So how do we expand upon this? Well, just like the description, damageType, and other things we’re modifying here, all of the other bits of automation are just parts of the data object, so if we know which ones we’d modify for a given weapon, we can just make a version of this script that clears out any modifications from the base version of the Magitech Cannon, then pulls all the information that may exist on whatever weapon the Trimaldis are canabilizing for their gun. That one is probably going to take a bit more time to automate… but completely doable.

Excited to try out more bits of automation like this. :slight_smile:

1 Like

So this looks great. And so of course I’m going to trample on that by asking questions & making suggestions.

Hard-coded constants

Right now, you’ve hard-coded the actor and item names into this script. Is it possible to pass those into the script, like as attributes or parameters or something from when the user clicks the button?

Sublimating qualities

If the item quality is stored in a separate attribute, rather than embedded in the item description, you can do the same sort of thing there that you did with elements:

  • Find the actor you want e.g. “trimaldis”
  • Loop through carried items, filtering by items of type weapon
  • Collect the qualities from those items and present them in a dropdown
  • Once the user makes a selection, modify the Magicannon item

Function names

Very generic function names like “makeUpdate” might be better off as something specific and descriptive, e.g. “objectUpdateByDamageType”. I don’t know if your code runs in its own scope or whether it’s run in some larger namespace. If it’s tightly scoped, you don’t care about this suggestion.

Trample away. :laughing: I always feel like I learn something or gain a little extra understanding when we go through these. :slight_smile:

You can pass in parameters, but given that this is strictly intended for the Trimaldis and will only appear for Dave, I didn’t want to add in too much extra complexity. That said, it will be useful for future macros and scripts.

This was almost exactly what I had in mind. Good to see my logic was sound. :slight_smile:

Macros run in their own scope, so I didn’t worry about it being too specific. That said, I would in a larger script and/or if I start making World Scripts (things that effect the whole game).

1 Like

All very cool, thanks, Mike!

And … I guess, after all that hardcoding, this is the wrong time to bring up that I was thinking of changing the family name (ducks) … :zany_face:

2 Likes

Dave, that is about the easiest thing to change in this entire setup. :laughing:

1 Like

The argument for getting into the habit of it is that you’ll inevitably copy-paste stuff like this when it comes time to make another button, and when you copy-paste it’s inevitable that you’ll forget to fix something like this sooner or later

1 Like