You can pass the ship object itself to the widget, like this.
<<shielddamage $milleniumFalcon>>
The widget itself has access to it via its $args argument array and (after a few sanity checks) can modify all the properties of the object. A version with some simple error reporting would look like this.
<<widget "shielddamage">>
<<if $args[0] && Number.isFinite($args[0].shields)>>
<<set $args[0].shields -= random(1, 10)>>
<<else>>
@@.error;invalid arguments <<- $args.raw>>@@
<</if>>
<</widget>>
The advantage here is that you have easy access to other variables of the ship. For example, let's assume you want to expand the widget to do the following in the future:
- When the shields are damaged, trigger all ":shieldsdamaged" event handlers and when they are fully depleted, all ":shieldsgone" event handlers additionally to it, with both getting full access to the damaged ship's JS object.
- If the ship has indestructible shields (they need to be bypassed or shut down from the inside), don't damage them at all.
- Have a 20% chance of overloading the shields if the damage exceeds 33% of their current strength.
You can do all of this without changing how the widget is called, just by changing its code.
<<widget "shielddamage">>
<<if $args[0] && Number.isFinite($args[0].shields)>>
<<if !$args[0].indestructibleShields>>
<<set _damage = random(1, 10)>>
<<if _damage * 3 > $args[0].shields && random(1, 5) === 1>>
<<set _damage = $args[0].shields>>
<</if>>
<<set $args[0].shields -= Math.min($args[0].shields, _damage)>>
<<run jQuery.event.trigger({
type: ":shieldsdamaged",
ship: $args[0],
damage: _damage,
})>>
<<if $args[0].shields <= 0>>
<<run jQuery.event.trigger({
type: ":shieldsgone",
ship: $args[0],
})>>
<</if>>
<</if>>
<<else>>
@@.error;invalid arguments <<- $args.raw>>@@
<</if>>
<</widget>>
(Relatively) easy extensibility, pretty easy usage. Event handlers can be added in your story's JavaScript section, like this.
jQuery(document).on(":shieldsdamaged", function(event) {
/* get your ship from event.ship and the damage from event.damage */
});