|
|
(11 intermediate revisions by one user not shown) |
Line 1: |
Line 1: |
− | The following script creates the API command <code>!mark</code>
| + | {{revdate}} |
| + | {{main|API:Script Index}} |
| | | |
− | ==== Syntax ====
| |
− | <blockquote style="border:1px #0088ee solid;background:#eee;padding:0.5em">!mark ''tokenset'' [''status'' [''type'']]</blockquote>
| |
| | | |
− | {| class="wikitable" | + | {{script overview |
− | |- | + | |name=Marking Conditions |
− | ! Parameter
| + | |author={{user profile|235259|Brian}} |
− | ! Values
| + | |dependencies={{api repository link|splitArgs}} |
− | |- | + | |version=3.3 |
− | | ''tokenset''
| + | |lastmodified=2015-03-26}} |
− | | Defines the set of tokens on the map to mark. One of:
| + | '''Marking Conditions''' creates the API commands <code>!mark</code>, <code>!unmark</code>, and <code>!clearmark</code> |
− | * The name of a token
| + | <br clear="all"> |
− | * !all
| + | |
− | * !key=value[,key=value[,key=value...etc]]
| + | === Syntax === |
− | |- | + | {{syntaxbox top|formal=true|Marking Conditions}} |
− | | ''status'' | + | {{API command|mark}} {{API parameter|name=tokenid}} {{API parameter|name=status</em> {{API parameter|name=type|optional=true}}<em>|optional=true}}<br> |
− | | (Optional) A D&D 4e status (except for dying, helpless, unconscious, insubstantial, or surprised) or the name of a [[API:Objects#Graphic (Token/Map/Card/Etc.)|statusmarker icon]]. The script has several aliases for the statuses. For example, immobilized, immobile, and immob all correspond to the same marker. | + | {{API command|unmark}} {{API parameter|name=tokenid}} {{API parameter|optional=true|name=status</em> {{API parameter|optional=true|name=type}}<em>}}<br> |
| + | {{API command|clearmark}} {{API parameter|name=tokenid}} |
| + | {{Formal API command| |
| + | {{token|S}} {{rarr}} {{API command|mark}} {{token|tokenid}} {{token|status|-}} |
| + | {{token|S}} {{rarr}} {{API command|unmark}} {{token|tokenid}} {{token|status|-}} |
| + | {{token|S}} {{rarr}} {{API command|clearmark}} {{token|tokenid|-}} |
| + | {{token|tokenid}} {{rarr}} {{string|-}} |
| + | {{token|status}} {{rarr}} {{epsilon}} |
| + | {{token|status}} {{rarr}} {{string}}{{token|damage|-}} |
| + | {{token|damage}} {{rarr}} {{epsilon}} |
| + | {{token|damage}} {{rarr}} acid<br> |
| + | {{token|damage}} {{rarr}} cold<br> |
| + | {{token|damage}} {{rarr}} fire<br> |
| + | {{token|damage}} {{rarr}} force<br> |
| + | {{token|damage}} {{rarr}} lightning<br> |
| + | {{token|damage}} {{rarr}} necrotic<br> |
| + | {{token|damage}} {{rarr}} poison<br> |
| + | {{token|damage}} {{rarr}} psychic<br> |
| + | {{token|damage}} {{rarr}} radiant<br> |
| + | {{token|damage}} {{rarr}} thunder |
| + | }} |
| + | {{syntaxbox end}} |
| + | |
| + | {{param description top}} |
| + | {{param description|name=tokenid|value=ID of a token object. This can be obtained with <code>@{target{{!}}token_id}</code> or <code>@{selected{{!}}token_id}</code>.}} |
| + | {{param description|name=status|value=Optional. Either the name of a [[API:Objects#Graphic (Token/Map/Card/Etc.)|statusmarker icon]], or else one of many aliases to D&D 4e conditions. |
| | | |
− | If ''status'' is not specified, the purple statusmarker will be used (which corresponds to the Marked status). | + | |
− | |- | + | If ''status'' is not specified, the purple statusmarker will be used.}} |
− | | ''type''
| + | {{param description|name=type|value=Optional. A D&D 4e damage type. Only used if ''status'' is "ongoing", "damage", or "dam". If supplied, should be one of: |
− | | (Optional) A D&D 4e damage type. Only used if ''status'' is ''ongoing'', ''damage'', or ''dam''. One of: | + | |
| * acid | | * acid |
| * cold | | * cold |
Line 32: |
Line 55: |
| * radiant | | * radiant |
| * thunder | | * thunder |
− | If ''type'' is not specified, a statusmarker to represent untyped damage will be used. | + | If ''type'' is not specified, a statusmarker to represent untyped damage will be used.}} |
− | |}
| + | {{param description bottom}} |
| | | |
− | ==== The ''tokenset'' Parameter ====
| + | The <code>!mark</code> command will set a marker, while the <code>!unmark</code> command will clear it. <code>!clearmark</code> will clear all markers from the token. |
− | The ''tokenset'' parameter requires some additional notice. If a token's name is used, obviously that token will be the only token in the set. Alternatively, if <code>!all</code> is used, all tokens on the map will be in the set. The value that requires explanation is the <code>!key=value</code> list.
| + | |
| | | |
− | ''key'' may be one of: | + | ==== Conditions and Aliases ==== |
− | * distance
| + | The available ''status'' aliases and the D&D 4e conditions they map to are listed below. |
− | * controlledby
| + | |
− | * bar1
| + | |
− | * bar2
| + | |
− | * bar3
| + | |
| | | |
− | Values for the <code>distance</code> key may be:
| + | {| class="wikitable" |
− | * nearest
| + | |- |
− | * furthest
| + | ! Condition |
− | * ''N''
| + | ! Aliases |
− | * ''>N''
| + | ! Condition |
− | * ''<N''
| + | ! Aliases |
− | | + | |- style="vertical-align:top" |
− | If you use any <code>distance</code> key, you must have a token selected, and that token will not be part of the <code>tokenset</code>. ''N'' looks for tokens '''exactly''' N squares from the selected token. ''>N'' and ''<N'' look for tokens N or more, or else N or less squares away from the selected token, as appropriate. ''nearest'' and ''furthest'' calculate the rest of the <code>tokenset</code>, and then select the nearest or furthest tokens within that set. (There might be multiple results, if there are multiple equidistant tokens.)
| + | | style="width:100px" | '''Blinded''' |
− | | + | | style="width:200px" | blinded<br>blind |
− | Values for the <code>controlledby</code> key may be:
| + | | style="width:100px" | '''Prone''' |
− | * none
| + | | style="width:200px" | prone |
− | * ''name''
| + | |- style="vertical-align:top" |
− | | + | || '''Dazed''' |
− | If you use <code>none</code>, the <code>tokenset</code> will include tokens with no controlling player, or which represent characters with no controlling player (generally, NPC tokens). Otherwise, the mark will look for a token controlled by a player named ''name'', or a token representing a character named ''name''.
| + | || dazed<br>daze |
− | | + | || '''Restrained''' |
− | Values for the <code>barN</code> keys may be:
| + | || restrained |
− | * ''N''
| + | |- style="vertical-align:top" |
− | * ''>N''
| + | || '''Deafened''' |
− | * ''<N''
| + | || deafened<br>deaf |
− | | + | || '''Slowed''' |
− | If ''N'' is used as the value, the <code>tokenset</code> will look for tokens with a current value of exactly N; the token does not need a maximum value set. Otherwise, N should be a value in the [0..1] range, the token needs both current and maximum values, and the <code>tokenset</code> will search for tokens with the relevant bar at or above (or at or below) the given percentage.
| + | || slowed<br>slow |
− | | + | |- style="vertical-align:top" |
− | ==== Code ====
| + | || '''Dominated''' |
− | <pre data-language="javascript">
| + | || dominated<br>dominate |
− | /**
| + | || '''Stunned''' |
− | * Provides commands for marking enemies.
| + | || stunned<br>stun |
− | */
| + | |- style="vertical-align:top" |
− | var conditions = conditions || {};
| + | || '''Immobilized''' |
− | conditions.markingCharacters = [];
| + | || immobilized<br>immobile<br>immob |
− | on("chat:message", function(msg) {
| + | || '''Weakened''' |
− | if(msg.type != 'api' || msg.content.toLowerCase().indexOf('!mark') != 0) return;
| + | || weakened<br>weak |
− |
| + | |- style="vertical-align:top" |
− | var args = msg.content.toLowerCase().split(' ');
| + | || '''Marked''' |
− | args.shift();
| + | || marked<br>mark |
− |
| + | || '''Ongoing Damage''' |
− | var mark = 'purple'; // default to defender's "mark" condition
| + | || ongoing<br>damage<br>dam |
− | if(args[1]) switch(args[1])
| + | |- style="vertical-align:top" |
− | {
| + | || '''Petrified''' |
− | case 'blinded':
| + | || petrified<br>petrify<br>stone |
− | case 'blind':
| + | || '''Dying<br>Helpless<br>Unconscious<br>Insubstantial<br>Surprised''' |
− | mark = 'bleeding-eye';
| + | | style="width:200px" | '''''Marking Conditions''' explicitly does not handle these statuses, and will generate an error message if you try to use one.'' |
− | break;
| + | |} |
− | case 'dazed':
| + | |
− | case 'daze':
| + | |
− | mark = 'pummeled';
| + | |
− | break;
| + | |
− | case 'deafened':
| + | |
− | case 'deaf':
| + | |
− | mark = 'screaming';
| + | |
− | break;
| + | |
− | case 'dominated':
| + | |
− | case 'dominate':
| + | |
− | mark = 'chained-heart';
| + | |
− | break;
| + | |
− | case 'immobilized':
| + | |
− | case 'immobile':
| + | |
− | case 'immob':
| + | |
− | mark = 'fishing-net';
| + | |
− | break;
| + | |
− | case 'marked':
| + | |
− | case 'mark':
| + | |
− | mark = 'purple';
| + | |
− | break;
| + | |
− | case 'petrified':
| + | |
− | case 'petrify':
| + | |
− | case 'stone':
| + | |
− | mark = 'white-tower';
| + | |
− | break;
| + | |
− | case 'prone':
| + | |
− | mark = 'back-pain';
| + | |
− | break;
| + | |
− | case 'restrained':
| + | |
− | mark = 'aura';
| + | |
− | break;
| + | |
− | case 'slowed':
| + | |
− | case 'slow':
| + | |
− | mark = 'snail';
| + | |
− | break;
| + | |
− | case 'stunned':
| + | |
− | case 'stun':
| + | |
− | mark = 'lightning-helix';
| + | |
− | break;
| + | |
− | case 'weakened':
| + | |
− | case 'weak':
| + | |
− | mark = 'broken-heart';
| + | |
− | break;
| + | |
− | case 'ongoing':
| + | |
− | case 'damage':
| + | |
− | case 'dam':
| + | |
− | if(args[2]) switch(args[2])
| + | |
− | {
| + | |
− | case 'acid':
| + | |
− | mark = 'chemical-bolt';
| + | |
− | break;
| + | |
− | case 'cold':
| + | |
− | mark = 'frozen-orb';
| + | |
− | break;
| + | |
− | case 'fire':
| + | |
− | mark = 'half-haze';
| + | |
− | break;
| + | |
− | case 'force':
| + | |
− | mark = 'blue';
| + | |
− | break;
| + | |
− | case 'lightning':
| + | |
− | mark = 'edge-crack';
| + | |
− | break;
| + | |
− | case 'necrotic':
| + | |
− | mark = 'death-zone';
| + | |
− | break;
| + | |
− | case 'poison':
| + | |
− | mark = 'skull';
| + | |
− | break;
| + | |
− | case 'psychic':
| + | |
− | mark = 'pink';
| + | |
− | break;
| + | |
− | case 'radiant':
| + | |
− | mark = 'angel-outfit';
| + | |
− | break;
| + | |
− | case 'thunder':
| + | |
− | mark = 'yellow';
| + | |
− | break;
| + | |
− | default:
| + | |
− | sendChat('ERROR', '/w ' + msg.who + ' No damage type called ' + args[2]
| + | |
− | + '. If the damage has no type, do not include a type!');
| + | |
− | return;
| + | |
− | }
| + | |
− | else mark = 'all-for-one'; // untyped ongoing damage
| + | |
− | break;
| + | |
− | case 'dying':
| + | |
− | case 'helpless':
| + | |
− | case 'unconscious':
| + | |
− | case 'insubstantial':
| + | |
− | case 'surprised':
| + | |
− | sendChat('ERROR', '/w ' + msg.who + ' The ' + args[1]
| + | |
− | + ' status is not implemented for the !mark command.');
| + | |
− | return;
| + | |
− | break;
| + | |
− | default:
| + | |
− | mark = args[1]; // allows for direct status setting
| + | |
− | break;
| + | |
− | }
| + | |
− |
| + | |
− | var so = msg.selected || {};
| + | |
− | var tgtList = conditions.targetList(args[0], so, msg.who);
| + | |
− | if(mark == 'none') conditions.unmarkTokens(tgtList, msg.who);
| + | |
− | else conditions.markTokens(tgtList, msg.who, mark);
| + | |
− | });
| + | |
− | | + | |
− | /**
| + | |
− | * Parses the input to search for tokens which need to be marked (or unmarked).
| + | |
− | * The tokens are returned as an array. The descriptor begins with an
| + | |
− | * exclamation point to differentiate it from polling a single token, and is a
| + | |
− | * comma-separated set of key=value pairs. All pairs will be true for each
| + | |
− | * token selected. For example, !distance=<1,controlledby=none,bar1=<.5 would
| + | |
− | * find only those tokens which are within 1 square of the currently selected
| + | |
− | * token, are controlled by nobody (ie, NPCs), and have 50% or less remaining
| + | |
− | * on bar1.
| + | |
− | *
| + | |
− | * all All tokens on the current page
| + | |
− | * distance=N A token exactly N squares from the currently selected token
| + | |
− | * distance=<N A token N squares or less from the currently selected token
| + | |
− | * distance=>N A token N squares or more from the currently selected token
| + | |
− | * distance=nearest The nearest token to the currently selected token
| + | |
− | * distance=furthest The furthest token from the currently selected token
| + | |
− | * controlledby=none A token not controlled by any player -- generally, the option to use for finding NPCs
| + | |
− | * controlledby=player A token controlled by the player named `player'
| + | |
− | * bar1=N A token whose current bar1 value is N
| + | |
− | * bar1=<N A token whose current bar1 value is N% or less
| + | |
− | * bar1=>N A token whose current bar1 value is N% or more
| + | |
− | * bar2=N A token whose current bar2 value is N
| + | |
− | * bar2=<N A token whose current bar2 value is N% or less
| + | |
− | * bar2=>N A token whose current bar2 value is N% or more
| + | |
− | * bar3=N A token whose current bar3 value is N
| + | |
− | * bar3=<N A token whose current bar3 value is N% or less
| + | |
− | * bar3=>N A token whose current bar3 value is N% or more
| + | |
− | *
| + | |
− | * The `distance' options will never return the currently selected token, only
| + | |
− | * other tokens based on their distance from the currently selected token.
| + | |
− | *
| + | |
− | * The `all' option does not take any value, is ignored if it isn't the first
| + | |
− | * option, and ignores all other options if it's first. It's a loner, used
| + | |
− | * mostly for cleaning things up (eg, !mark !all none to clear all marks on the
| + | |
− | * page).
| + | |
− | *
| + | |
− | * @param descriptor arg0 of the user input. This should be either a
| + | |
− | * formatted search for tokens, or the name of a single
| + | |
− | * token.
| + | |
− | * @param selectedObjs an array of selected objects
| + | |
− | * @param who the player to send whispers about errors
| + | |
− | * @return an array of token objects which will have their statusmarkers modified
| + | |
− | */
| + | |
− | conditions.targetList = function(descriptor, selectedObjs, who)
| + | |
− | {
| + | |
− | var selected;
| + | |
− | var targets = [];
| + | |
− |
| + | |
− | for(var i = 0; i < selectedObjs.length; i++)
| + | |
− | {
| + | |
− | if(selectedObjs[i]._type == 'graphic')
| + | |
− | {
| + | |
− | var tmp = getObj(selectedObjs[i]._type, selectedObjs[i]._id);
| + | |
− | if(tmp && tmp.get('_subtype') == 'token')
| + | |
− | {
| + | |
− | selected = tmp; // use the first token we find as reference for 'nearest'/'furthest'
| + | |
− | break;
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− |
| + | |
− | if(descriptor.indexOf('!') == 0) // descriptor describes a group of tokens
| + | |
− | {
| + | |
− | var parts = descriptor.substring(1).split(',');
| + | |
− | var filters = [];
| + | |
− | var error = false;
| + | |
− |
| + | |
− | if(parts[0] == 'all') filters.push(function(tgt) { return true; });
| + | |
− | else parts.forEach(function(kvp) {
| + | |
− | var key = kvp.substring(0, kvp.indexOf('='));
| + | |
− | var value = kvp.substring(kvp.indexOf('=')+1);
| + | |
− | var func;
| + | |
− |
| + | |
− | switch(key)
| + | |
− | {
| + | |
− | case 'distance':
| + | |
− | if(!selected)
| + | |
− | {
| + | |
− | sendChat('ERROR', '/w ' + who + ' There is no token selected.');
| + | |
− | error = true;
| + | |
− | return;
| + | |
− | }
| + | |
− | var sL = selected.get('left');
| + | |
− | var sT = selected.get('top');
| + | |
− |
| + | |
− | if(value == 'nearest' || value == 'furthest') func = function(tgt) {
| + | |
− | // near/far can't be decided until after all other filters have run;
| + | |
− | // using dumy function until then
| + | |
− | return tgt != selected;
| + | |
− | };
| + | |
− | else if(value.indexOf('<') == 0) func = function(tgt) {
| + | |
− | // find tokens <= value spaces away
| + | |
− | var squares = (+value.substring(1)) * 70;
| + | |
− | var distL = Math.abs(sL - tgt.get('left'));
| + | |
− | var distT = Math.abs(sT - tgt.get('top'));
| + | |
− |
| + | |
− | return tgt != selected && distL <= squares && distT <= squares;
| + | |
− | }
| + | |
− | else if(value.indexOf('>') == 0) func = function(tgt) {
| + | |
− | // find tokens >= value spaces away
| + | |
− | var squares = (+value.substring(1)) * 70;
| + | |
− | var distL = Math.abs(sL - tgt.get('left'));
| + | |
− | var distT = Math.abs(sT - tgt.get('top'));
| + | |
− |
| + | |
− | return tgt != selected && (distL >= squares || distT >= squares);
| + | |
− | }
| + | |
− | else func = function(tgt) {
| + | |
− | // find tokens exactly value spaces away
| + | |
− | var squares = (+value) * 70;
| + | |
− | var distL = Math.abs(sL - tgt.get('left'));
| + | |
− | var distT = Math.abs(sT - tgt.get('top'));
| + | |
− |
| + | |
− | return tgt != selected && ((distL == squares && distT == squares)
| + | |
− | || (distL == squares && distT < squares)
| + | |
− | || (distL < squares && distT == squares));
| + | |
− | }
| + | |
− | break;
| + | |
− | case 'controlledby':
| + | |
− | if(value == 'none') func = function(tgt) {
| + | |
− | // find NPC tokens
| + | |
− | if(tgt.get('_represents') == '')
| + | |
− | return tgt.get('controlledby') == '';
| + | |
− | else
| + | |
− | {
| + | |
− | var character = getObj('character', tgt.get('_represents'));
| + | |
− | return character.get('controlledby') == '';
| + | |
− | }
| + | |
− | }
| + | |
− | else func = function(tgt) {
| + | |
− | // find tokens controlled by value
| + | |
− | var players = findObjs({_type: 'player', _displayname: value},
| + | |
− | {caseInsensitive: true});
| + | |
− | if(players[0]) return tgt.get('controlledby').indexOf(players[0].id) != -1;
| + | |
− | players = findObjs({_type: 'player', _displayname: value.replace('-', ' ')},
| + | |
− | {caseInsensitive: true});
| + | |
− | if(players[0]) return tgt.get('controlledby').indexOf(players[0].id) != -1;
| + | |
− |
| + | |
− | var characters = findObjs({_type: 'character', name: value},
| + | |
− | {caseInsensitive: true});
| + | |
− | if(characters[0]) return tgt.get('_represents') == characters[0].id;
| + | |
− | characters = findObjs({_type: 'character', name: value.replace('-', ' ')},
| + | |
− | {caseInsensitive: true});
| + | |
− | if(characters[0]) return tgt.get('_represents') == characters[0].id;
| + | |
− |
| + | |
− | return false;
| + | |
− | }
| + | |
− | break;
| + | |
− | case 'bar1':
| + | |
− | case 'bar2':
| + | |
− | case 'bar3':
| + | |
− | if(value.indexOf('<') == 0) func = function(tgt) {
| + | |
− | // find tokens with bar# at or below value%
| + | |
− | var barCur = tgt.get(key+'_value');
| + | |
− | var barMax = tgt.get(key+'_max');
| + | |
− | var percent = barCur / barMax;
| + | |
− | if(barMax == NaN || barCur == NaN) return false;
| + | |
− |
| + | |
− | return percent <= (+value.substring(1));
| + | |
− | }
| + | |
− | else if(value.indexOf('>') == 0) func = function(tgt) {
| + | |
− | // find tokens with bar# at or above value%
| + | |
− | var barCur = tgt.get(key+'_value');
| + | |
− | var barMax = tgt.get(key+'_max');
| + | |
− | var percent = barCur / barMax;
| + | |
− | if(barMax == NaN || barCur == NaN) return false;
| + | |
− |
| + | |
− | return percent >= (+value.substring(1));
| + | |
− | }
| + | |
− | else func = function(tgt) {
| + | |
− | // find tokens with bar# at value
| + | |
− | var barCur = tgt.get(key+'_value');
| + | |
− | if(barCur == NaN) return false;
| + | |
− |
| + | |
− | return barCur == (+value);
| + | |
− | }
| + | |
− | break;
| + | |
− | default:
| + | |
− | sendChat('ERROR', '/w ' + who + ' ' + key + ' is not a valid token filter key.');
| + | |
− | return;
| + | |
− | }
| + | |
− |
| + | |
− | filters.push(func);
| + | |
− | });
| + | |
− |
| + | |
− | if(error) return [];
| + | |
− |
| + | |
− | targets = filterObjs(function(obj) {
| + | |
− | if(obj.get('_pageid') != Campaign().get('playerpageid')) return false;
| + | |
− | if(obj.get('_type') != 'graphic') return false;
| + | |
− | if(obj.get('_subtype') != 'token') return false;
| + | |
− |
| + | |
− | var matchAll = filters.length > 0;
| + | |
− | filters.forEach(function(f) {
| + | |
− | if(!matchAll) return;
| + | |
− | if(!f(obj)) matchAll = false;
| + | |
− | });
| + | |
− |
| + | |
− | return matchAll;
| + | |
− | });
| + | |
− |
| + | |
− | // if we have distance=nearest or distance=furthest, trim `targets' as appropriate
| + | |
− | // do nothing if $selected is null
| + | |
− | if(selected)
| + | |
− | parts.forEach(function(kvp) {
| + | |
− | var key = kvp.substring(0, kvp.indexOf('='));
| + | |
− | var value = kvp.substring(kvp.indexOf('=')+1);
| + | |
− |
| + | |
− | if(key == 'distance')
| + | |
− | {
| + | |
− | var sL = selected.get('left');
| + | |
− | var sT = selected.get('top');
| + | |
− |
| + | |
− | if(value == 'nearest')
| + | |
− | {
| + | |
− | var minDist = -1;
| + | |
− | var toKeep = [];
| + | |
− | targets.forEach(function(tgt) {
| + | |
− | var distL = Math.abs(tgt.get('left') - sL);
| + | |
− | var distT = Math.abs(tgt.get('top') - sT);
| + | |
− |
| + | |
− | var distance = Math.max(distL, distT);
| + | |
− | if(minDist == -1 || minDist > distance)
| + | |
− | {
| + | |
− | toKeep = [tgt];
| + | |
− | minDist = distance;
| + | |
− | }
| + | |
− | else if(minDist == distance)
| + | |
− | {
| + | |
− | toKeep.push(tgt);
| + | |
− | }
| + | |
− | });
| + | |
− |
| + | |
− | targets = toKeep;
| + | |
− | }
| + | |
− | else if(value == 'furthest')
| + | |
− | {
| + | |
− | var maxDist = -1;
| + | |
− | var toKeep = [];
| + | |
− | targets.forEach(function(tgt) {
| + | |
− | var distL = Math.abs(sL - tgt.get('left'));
| + | |
− | var distT = Math.abs(sT - tgt.get('top'));
| + | |
− |
| + | |
− | var distance = Math.max(distL, distT);
| + | |
− | if(maxDist == -1 || maxDist < distance)
| + | |
− | {
| + | |
− | toKeep = [tgt];
| + | |
− | maxDist = distance;
| + | |
− | }
| + | |
− | else if(maxDist == distance)
| + | |
− | {
| + | |
− | toKeep.push(tgt);
| + | |
− | }
| + | |
− | });
| + | |
− |
| + | |
− | targets = toKeep;
| + | |
− | }
| + | |
− | }
| + | |
− | });
| + | |
− | }
| + | |
− | else // descriptor is a token name
| + | |
− | {
| + | |
− | var target = findObjs({
| + | |
− | _type: 'graphic',
| + | |
− | name: descriptor,
| + | |
− | _pageid: Campaign().get('playerpageid')
| + | |
− | }, {caseInsensitive: true})[0];
| + | |
− | if(!target)
| + | |
− | {
| + | |
− | sendChat('ERROR', '/w ' + who + ' Cannot find a token named ' + args[0] + '.');
| + | |
− | return;
| + | |
− | }
| + | |
− |
| + | |
− | targets.push(target);
| + | |
− | }
| + | |
− |
| + | |
− | return targets;
| + | |
− | }
| + | |
− | | + | |
− | /**
| + | |
− | * Marks all given targets and keeps track of who marked it.
| + | |
− | *
| + | |
− | * @param targets an array of target token objects to mark
| + | |
− | * @param character the character performing the mark
| + | |
− | * @param mark optional. The type of statusmarker to use for the mark.
| + | |
− | */
| + | |
− | conditions.markTokens = function(targets, character, mark)
| + | |
− | {
| + | |
− | targets.forEach(function(tgt) { // tgt is a token object
| + | |
− | tgt.set('status_'+mark, true);
| + | |
− | });
| + | |
− | }
| + | |
− | | + | |
− | /**
| + | |
− | * Removes all marks on the target tokens that were placed there by the calling
| + | |
− | * player.
| + | |
− | *
| + | |
− | * @param targets an array of target token objects to clean up
| + | |
− | * @param character the player who's removing marks -- only marks placed by the player will be removed
| + | |
− | */
| + | |
− | conditions.unmarkTokens = function(targets, character)
| + | |
− | {
| + | |
− | targets.forEach(function(tgt) {
| + | |
− | tgt.set('statusmarkers', '');
| + | |
− | });
| + | |
− | }
| + | |
− | </pre> | + | |
− | | + | |
− | ==== Examples ====
| + | |
− | '''!mark !distance=nearest,bar1<.5 brown''' | + | |
− | <blockquote>This will set the brown marker on the nearest token with 50% or less of its bar1.</blockquote> | + | |
− | | + | |
− | '''!mark !distance=<1,controlledby=none immob''' | + | |
− | <blockquote>This will set the 'immobilize' icon to all NPC tokens 1 square away (or closer!)</blockquote>
| + | |
− | | + | |
− | '''!mark Wulfgar none''' | + | |
− | <blockquote>This will remove all statusmarkers from the token named Wulfgar</blockquote>
| + | |
| | | |
− | [[Category:User API Scripts|Marking Conditions]]
| + | === Changelog === |
− | [[Category:API Commands|Marking Conditions]]
| + | {{changelog version|3.3|2015-03-26|* [bugfix] fixed bugs reported by {{user profile|376031|Ron}}}} |
| + | {{changelog version|3.2|2015-01-24|* [bugfix] no-arg crash}} |
| + | {{changelog version|3.1|2015-01-22|* Fixed transcription error}} |
| + | {{changelog version|3.0|2015-01-09|* Release}} |