0% found this document useful (0 votes)
178 views6 pages

Token Lighting and Vision Control

Uploaded by

Gabriel Borda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
178 views6 pages

Token Lighting and Vision Control

Uploaded by

Gabriel Borda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

Acender e Apagar Tocha

for ( const token of [Link] ) {


if ( [Link] ) {
await [Link]({
"light": {
"dim": 0.1,
"bright": 0.1
}
});
} else {
await [Link]({
"light": {
"dim": 6,
"bright": 6,
"alpha" : 0.2,
"color": "#ffa200",
"animation": {"speed": 1, "intensity": 4, "type": "torch"}
}
});
}
}

Remover Efeitos Ativos

const removeList = _token.[Link](e => [Link]);


_token.[Link]("ActiveEffect", removeList);

Desafios Complexos

[Link](9, 3)

PV/PM

// Update all tokens on the map so that the name shows on hover and the bars always
show.
// Display Modes: ALWAYS, CONTROL, HOVER, NONE, OWNER, OWNER_HOVER

const tokens = [Link](token => {


return {
_id: [Link],
"[Link]": "[Link]",
"[Link]": "[Link]",
"displayName": CONST.TOKEN_DISPLAY_MODES.ALWAYS,
"displayBars": CONST.TOKEN_DISPLAY_MODES.ALWAYS
};
});

[Link]('Token', tokens)

Sem vida e nome

// Update all controlled tokens on the map so that the names and bars only shows on
hover.
// Display Modes: ALWAYS, CONTROL, HOVER, NONE, OWNER, OWNER_HOVER
const tokens = [Link](token => {
return {
_id: [Link],
"[Link]": "[Link]",
"[Link]": "[Link]",
"displayName": CONST.TOKEN_DISPLAY_MODES.HOVER,
"displayBars": CONST.TOKEN_DISPLAY_MODES.HOVER
};
});

[Link]('Token', tokens)

Change Token Vision

// Open a dialog for quickly changing token vision parameters of the controlled
tokens.
// This macro was written by @Sky#9453
// [Link]

if ([Link] === 0)
return [Link]("Please select a token first");

let applyChanges = false;


new Dialog({
title: `Token Vision Configuration`,
content: `
<form>
<div class="form-group">
<label>Vision Type:</label>
<select id="vision-type" name="vision-type">
<option value="nochange">No Change</option>
<option value="dim0">Self</option>
<option value="dim30">Darkvision (30 ft)</option>
<option value="dim60">Darkvision (60 ft)</option>
<option value="dim90">Darkvision (90 ft)</option>
<option value="dim120">Darkvision (120 ft)</option>
<option value="dim150">Darkvision (150 ft)</option>
<option value="dim180">Darkvision (180 ft)</option>
<option value="bright120">Devil's Sight (Warlock)</option>
</select>
</div>
<div class="form-group">
<label>Light Source:</label>
<select id="light-source" name="light-source">
<option value="nochange">No Change</option>
<option value="none">None</option>
<option value="candle">Candle</option>
<option value="lamp">Lamp</option>
<option value="bullseye">Lantern (Bullseye)</option>
<option value="hooded-dim">Lantern (Hooded - Dim)</option>
<option value="hooded-bright">Lantern (Hooded - Bright)</option>
<option value="light">Light (Cantrip)</option>
<option value="torch">Torch</option>
</select>
</div>
</form>
`,
buttons: {
yes: {
icon: "<i class='fas fa-check'></i>",
label: `Apply Changes`,
callback: () => applyChanges = true
},
no: {
icon: "<i class='fas fa-times'></i>",
label: `Cancel Changes`
},
},
default: "yes",
close: html => {
if (applyChanges) {
for ( let token of [Link] ) {
let visionType = [Link]('[name="vision-type"]')[0].value || "none";
let lightSource = [Link]('[name="light-source"]')[0].value || "none";
let dimSight = 0;
let brightSight = 0;
let dimLight = 0;
let brightLight = 0;
let lightAngle = 360;
let lockRotation = [Link];
// Get Vision Type Values
switch (visionType) {
case "dim0":
dimSight = 0;
brightSight = 0;
break;
case "dim30":
dimSight = 30;
brightSight = 0;
break;
case "dim60":
dimSight = 60;
brightSight = 0;
break;
case "dim90":
dimSight = 90;
brightSight = 0;
break;
case "dim120":
dimSight = 120;
brightSight = 0;
break;
case "dim150":
dimSight = 150;
brightSight = 0;
break;
case "dim180":
dimSight = 180;
brightSight = 0;
break;
case "bright120":
dimSight = 0;
brightSight= 120;
break;
case "nochange":
default:
dimSight = [Link];
brightSight = [Link];
}
// Get Light Source Values
switch (lightSource) {
case "none":
dimLight = 0;
brightLight = 0;
break;
case "candle":
dimLight = 10;
brightLight = 5;
break;
case "lamp":
dimLight = 45;
brightLight = 15;
break;
case "bullseye":
dimLight = 120;
brightLight = 60;
lockRotation = false;
lightAngle = 52.5;
break;
case "hooded-dim":
dimLight = 5;
brightLight = 0;
break;
case "hooded-bright":
dimLight = 60;
brightLight = 30;
break;
case "light":
dimLight = 40;
brightLight = 20;
break;
case "torch":
dimLight = 40;
brightLight = 20;
break;
case "nochange":
default:
dimLight = [Link];
brightLight = [Link];
lightAngle = [Link];
lockRotation = [Link];
}
// Update Token
[Link](token);
[Link]({
vision: true,
dimSight: dimSight,
brightSight: brightSight,
light:{
dim: dimLight,
bright: brightLight
},
lightAngle: lightAngle,
lockRotation: lockRotation
});
}
}
}
}).render(true);

Close All Doors

/**
* Closes all doors on the canvas
* Author: @Atropos#3814
*/

[Link]("Wall", [Link](w => {


return {_id: [Link], ds: [Link] === 1 ? 0 : [Link]};
}));

Furtividade x Percepção

let selectedTokens=[Link]
if ([Link]===0) return [Link]("You need to select
tokens.")
const validTokens=[Link](i=>!![Link])

// Roll for each actor


let stealthCheckPromises=[Link](i=>new Roll(`1d20+$
{[Link]}`).roll())
stealthCheckPromises= await [Link](stealthCheckPromises)
const stealthCheckResults=[Link](i=>[Link])

let i=0;
let bigMessage=""
while (i<[Link]){
let relevantToken=validTokens[i]
let relevantActor=[Link]
let actorsStealthCheck=stealthCheckResults[i]

let foundBy=`${[Link]} rolou ${actorsStealthCheck} de Furtividade e


foi vista por:<br>`

for (let tokenDoc of [Link]){

if ([Link]===[Link]) continue // We aren't searching


ourselves... I hope.

let searchingActor=[Link]
if (!searchingActor) continue // Skip broken tokens

let searchingActorPerception=(await (new Roll(`1d20+$


{[Link]}`).evaluate())).total

let seesMe=(searchingActorPerception>=actorsStealthCheck)
if (seesMe){
foundBy+=`${[Link]} que rolou ${searchingActorPerception}
de percepção. <br>`
}
}
bigMessage+=foundBy+"<br>"
i++
}
const chatData = {
user: [Link],
speaker: [Link],
content: bigMessage,
whisper: [Link]((u) => [Link]).map((u) => [Link]),
};

await [Link](chatData)

Distância de Tokens

let tokenA = [Link][0]


let tokenB = [Link][1]
let px_dist = new Ray([Link], [Link]).distance
let distance = [Link] * px_dist / [Link]
let vert_distance = [Link]([Link] - [Link])
let total_dist = [Link](distance**2 + vert_distance**2)
[Link]({'content': `A distância real é: ${total_dist} $
{[Link]}`})

Tokens Combate

/**
/**
* Joga todos os tokens em combate e roda as iniciativas dos PCs,
*/
async function main() {
await [Link]();
[Link]({ messageOptions: { rollMode:
CONST.DICE_ROLL_MODES.PRIVATE }})
}
main();

Encerrar Combate

[Link]()
[Link](1)

Combatente Atual

(async () => {
await [Link]()
token = [Link]
[Link](token).control()
const position = [Link](token).position
[Link](position)
})();

Common questions

Powered by AI

Token management is expanded to handle initiative and turn sequences by embedding functions to toggle combat status for tokens and automate initiative rolling. The script moves through the combat sequence using 'game.combats.active.previousTurn()' to manage turns, ensuring sequential order and appropriate game flow. This comprehensive management allows seamless transition between combat states and orderly resolution of combat scenarios .

Lighting configuration for controlled tokens can be managed by checking the current state of a token's light setting and updating it accordingly. If a token's bright light setting is already on, the light configuration is set to minimal (dim and bright light set to 0.1). Otherwise, the light is configured with specific dim and bright light radii, as well as other properties like color and animation type. This is done by invoking the 'update' method on the token's document with the appropriate lighting parameters .

All doors on the canvas are closed by updating each wall's 'ds' property, where 'ds' represents the door state. The script iterates over each wall in the scene, checking if the 'ds' property equals 1 (open) and setting it to 0 (closed) accordingly. This change effectively closes all doors via updating the 'updateEmbeddedDocuments' method for walls .

The macro automates combat management by first toggling the combat status for all tokens using 'canvas.tokens.toggleCombat()'. Subsequently, it rolls initiatives for NPCs in a private mode using 'game.combat.rollNPC()', ensuring that only game masters see the results, thus efficiently managing the combat state and sequence of turns in gameplay .

The script calculates the actual distance between two controlled tokens (tokenA and tokenB) using the geometric distance between their center points on the grid. It considers the horizontal pixel distance, applies the scene's grid distance, and adjusts for differences in elevation. The vertical distance is considered as the absolute difference in elevation data, and the total distance is reported using the Pythagorean theorem to consider both horizontal and vertical components, encapsulated in a chat message .

Token vision parameters are adjusted in real-time through a dialog that allows users to select vision types and light sources. The script updates vision parameters such as 'dimSight' and 'brightSight' based on vision type, and light properties like 'dimLight' and 'brightLight' through selected light source. Once confirmed, the script applies changes to each selected token, modifying how tokens interact visually with the environment .

Vision and light sources for tokens are customized through a dialog interface that allows users to select different vision types like 'dim60' for Darkvision (60 ft), and light sources such as 'candle' or 'torch'. These choices affect how much of the map a token can see (dim and bright sight) and the lighting parameters (dim and bright light) applied to the token. Such customization impacts gameplay by influencing visibility, strategic planning in terms of light management, and ambiance through visual representation in the game setting .

Specific in-game events or results are communicated to game masters through private messages using 'whisper' functionality within the chat data object. This includes results from stealth checks or perceptive observations formatted into a message and directed únicamente to GM by filtering and mapping game users who hold GM privileges .

To adjust the visibility settings of tokens, methods are implemented to update each token's display modes. For example, a method updates all controlled tokens so that names and health bars are only visible when hovered over by setting the 'displayName' and 'displayBars' properties to HOVER. Another method sets them to ALWAYS, making the names and bars visible at all times. This is done using 'updateEmbeddedDocuments' on the token's data with the new display modes .

The script determines visibility during stealth versus perception checks by first obtaining stealth rolls for selected tokens. It compares each token's stealth result with perception rolls of other tokens in the scene. If a token's perception roll is equal to or exceeds the active token's stealth roll, the token is considered to have spotted the active token. This process is iterated for each token, and a message is compiled and sent to GM to report outcomes .

You might also like