Last active
July 23, 2023 08:22
-
-
Save Bastlifa/5a8eaa6f7259c2e9ed4f43180c55d984 to your computer and use it in GitHub Desktop.
Rooftops plus dynamic lighting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// a script to remove rooftops if a player enters a building | |
// move the player flag to the page you want to use this on | |
// draw your dynamic lighting lines on your building | |
// use a roof token, best if it's rotation is an integer multiple of 90 degrees (0, 90, 180, 270) | |
// name the roof token "roof", without the quotes. Preferable put it on map layer | |
// drag in player tokens. That is, tokens either assigned to players, or representing characters assigned to player | |
// type !RoofReady into chat, or better yet, use it from a macro. Alternatively, dragging the player flag to the page does this. | |
// should be good to go. Let me know if there are errors please :) | |
// other feature: !RoofDLOff and !RoofDLOn will now turn off or on the dynamic lighting interaction of the script. Default is 'on'. | |
// if you want default to be off, change the declaration on line 21 to read: var dlInteraction = false; | |
// finally, the default is to turn off the roof when characters are under it. You can change this by editing the | |
// interactionRange variable on line 22. 0 Is when they're under the roof, 1 is within 5 feet, 2 10 ft, etc. | |
// Alternatively, you can type !RooftopRange x, where x is the number of 5 foot squares away from which it will interact. | |
on("ready", function() { | |
"use strict"; | |
var allPlayerTokens = []; | |
var allRoofTokens = []; | |
var allPaths = []; | |
var dlInteraction = true; | |
var interactionRange = 0; | |
function getPlayerTokens() | |
{ | |
var campaign = findObjs({type: "campaign"})[0]; | |
var allTokens = findObjs({type: 'graphic', pageid: campaign.get("playerpageid"), layer: "objects"}); | |
allPlayerTokens = []; | |
for (var i = 0; i<allTokens.length; i++) | |
{ | |
if (allTokens[i].get("controlledby") != "" || allTokens[i].get("represents")) | |
{ | |
if (allTokens[i].get("represents")) | |
{ | |
if (getObj('character', allTokens[i].get("represents")).get("controlledby")) | |
{ | |
allPlayerTokens.push(allTokens[i]); | |
} | |
} | |
else | |
{ | |
allPlayerTokens.push(allTokens[i]); | |
} | |
} | |
} | |
} | |
function getRoofTokens() | |
{ | |
var campaign = findObjs({type: "campaign"})[0]; | |
var allMapTokens = findObjs({type: 'graphic', pageid: campaign.get("playerpageid")}); | |
allRoofTokens = []; | |
for (var i = 0; i<allMapTokens.length; i++) | |
{ | |
if (allMapTokens[i].get("name") == "roof") | |
{ | |
allRoofTokens.push(allMapTokens[i]); | |
} | |
} | |
} | |
function getPaths() | |
{ | |
var campaign = findObjs({type: "campaign"})[0]; | |
allPaths = []; | |
allPaths = findObjs({type: 'path', pageid: campaign.get("playerpageid")}); | |
} | |
function roofInsideCheck(roofToken) | |
{ | |
var anyoneInside = false; | |
for (var i = 0; i < allPlayerTokens.length; i++) | |
{ | |
if (roofToken.get("rotation") == 0 || roofToken.get("rotation") == 180) | |
{ | |
if (roofToken.get("left") - (roofToken.get("width")/2 + 70*interactionRange) < allPlayerTokens[i].get("left") && | |
roofToken.get("left") + (roofToken.get("width")/2 + 70*interactionRange) > allPlayerTokens[i].get("left") && | |
roofToken.get("top") - (roofToken.get("height")/2 + 70*interactionRange) < allPlayerTokens[i].get("top") && | |
roofToken.get("top") + (roofToken.get("height")/2 + 70*interactionRange) > allPlayerTokens[i].get("top")) | |
{ | |
anyoneInside = true; | |
} | |
} | |
else if (roofToken.get("rotation") == 90 || roofToken.get("rotation") == 270) | |
{ | |
if (roofToken.get("left") - (roofToken.get("height")/2 + 70*interactionRange) < allPlayerTokens[i].get("left") && | |
roofToken.get("left") + (roofToken.get("height")/2 + 70*interactionRange) > allPlayerTokens[i].get("left") && | |
roofToken.get("top") - (roofToken.get("width")/2 + 70*interactionRange) < allPlayerTokens[i].get("top") && | |
roofToken.get("top") + (roofToken.get("width")/2 + 70*interactionRange) > allPlayerTokens[i].get("top")) | |
{ | |
anyoneInside = true; | |
} | |
} | |
else | |
{ | |
//default for odd rotation, won't be perfect. | |
if (roofToken.get("left") - (roofToken.get("width")/2 + 70*interactionRange) < allPlayerTokens[i].get("left") && | |
roofToken.get("left") + (roofToken.get("width")/2 + 70*interactionRange) > allPlayerTokens[i].get("left") && | |
roofToken.get("top") - (roofToken.get("height")/2 + 70*interactionRange) < allPlayerTokens[i].get("top") && | |
roofToken.get("top") + (roofToken.get("height")/2 + 70*interactionRange) > allPlayerTokens[i].get("top")) | |
{ | |
anyoneInside = true; | |
} | |
} | |
} | |
return anyoneInside; | |
} | |
function removeRoof(roofID) | |
{ | |
getObj('graphic', roofID).set("layer", "walls"); | |
if(dlInteraction) { restorePath(roofID); } | |
} | |
function restoreRoof(roofID) | |
{ | |
getObj('graphic', roofID).set("layer", "map"); | |
if(dlInteraction) { removePath(roofID); } | |
} | |
function removePath(roofID) | |
{ | |
var roofToken = getObj('graphic', roofID); | |
if (!roofToken) {return;} | |
for (var i = 0; i < allPaths.length; i++) | |
{ | |
if (roofToken.get("rotation") == 0 || roofToken.get("rotation") == 180) | |
{ | |
if (roofToken.get("left") - (roofToken.get("width")/2 + 70*interactionRange) < allPaths[i].get("left") && | |
roofToken.get("left") + (roofToken.get("width")/2 + 70*interactionRange) > allPaths[i].get("left") && | |
roofToken.get("top") - (roofToken.get("height")/2 + 70*interactionRange) < allPaths[i].get("top") && | |
roofToken.get("top") + (roofToken.get("height")/2 + 70*interactionRange) > allPaths[i].get("top")) | |
{ | |
allPaths[i].set("layer", "gmlayer"); | |
} | |
} | |
else if (roofToken.get("rotation") == 90 || roofToken.get("rotation") == 270) | |
{ | |
if (roofToken.get("left") - (roofToken.get("height")/2 + 70*interactionRange) < allPaths[i].get("left") && | |
roofToken.get("left") + (roofToken.get("height")/2 + 70*interactionRange) > allPaths[i].get("left") && | |
roofToken.get("top") - (roofToken.get("width")/2 + 70*interactionRange) < allPaths[i].get("top") && | |
roofToken.get("top") + (roofToken.get("width")/2 + 70*interactionRange) > allPaths[i].get("top")) | |
{ | |
allPaths[i].set("layer", "gmlayer"); | |
} | |
} | |
else | |
{ | |
if (roofToken.get("left") - (roofToken.get("width")/2 + 70*interactionRange) < allPaths[i].get("left") && | |
roofToken.get("left") + (roofToken.get("width")/2 + 70*interactionRange) > allPaths[i].get("left") && | |
roofToken.get("top") - (roofToken.get("height")/2 + 70*interactionRange) < allPaths[i].get("top") && | |
roofToken.get("top") + (roofToken.get("height")/2 + 70*interactionRange) > allPaths[i].get("top")) | |
{ | |
allPaths[i].set("layer", "gmlayer"); | |
} | |
} | |
} | |
} | |
function restorePath (roofID) | |
{ | |
var roofToken = getObj('graphic', roofID); | |
if (!roofToken) {return;} | |
for (var i = 0; i < allPaths.length; i++) | |
{ | |
if (roofToken.get("rotation") == 0 || roofToken.get("rotation") == 180) | |
{ | |
if (roofToken.get("left") - (roofToken.get("width")/2 + 70*interactionRange) < allPaths[i].get("left") && | |
roofToken.get("left") + (roofToken.get("width")/2 + 70*interactionRange) > allPaths[i].get("left") && | |
roofToken.get("top") - (roofToken.get("height")/2 + 70*interactionRange) < allPaths[i].get("top") && | |
roofToken.get("top") + (roofToken.get("height")/2 + 70*interactionRange) > allPaths[i].get("top")) | |
{ | |
allPaths[i].set("layer", "walls"); | |
} | |
} | |
else if (roofToken.get("rotation") == 90 || roofToken.get("rotation") == 270) | |
{ | |
if (roofToken.get("left") - (roofToken.get("height")/2 + 70*interactionRange) < allPaths[i].get("left") && | |
roofToken.get("left") + (roofToken.get("height")/2 + 70*interactionRange) > allPaths[i].get("left") && | |
roofToken.get("top") - (roofToken.get("width")/2 + 70*interactionRange) < allPaths[i].get("top") && | |
roofToken.get("top") + (roofToken.get("width")/2 + 70*interactionRange) > allPaths[i].get("top")) | |
{ | |
allPaths[i].set("layer", "walls"); | |
} | |
} | |
else | |
{ | |
if (roofToken.get("left") - (roofToken.get("width")/2 + 70*interactionRange) < allPaths[i].get("left") && | |
roofToken.get("left") + (roofToken.get("width")/2 + 70*interactionRange) > allPaths[i].get("left") && | |
roofToken.get("top") - (roofToken.get("height")/2 + 70*interactionRange) < allPaths[i].get("top") && | |
roofToken.get("top") + (roofToken.get("height")/2 + 70*interactionRange) > allPaths[i].get("top")) | |
{ | |
allPaths[i].set("layer", "walls"); | |
} | |
} | |
} | |
} | |
on("change:campaign:playerpageid", function() { | |
getPlayerTokens(); | |
getRoofTokens(); | |
getPaths(); | |
sendChat("", "/w gm &{template:default} {{name=Rooftops Ready}} {{Player Tokens=" + allPlayerTokens.length + | |
"}} {{Roof Tokens=" + allRoofTokens.length + "}}") | |
}); | |
on("chat:message", function (msg) { | |
if (msg.type === 'api' && msg.content === "!RoofReady"){ | |
getPlayerTokens(); | |
getRoofTokens(); | |
getPaths(); | |
sendChat("", "/w gm &{template:default} {{name=Rooftops Ready}} {{Player Tokens=" + allPlayerTokens.length + | |
"}} {{Roof Tokens=" + allRoofTokens.length + "}}") | |
} | |
}); | |
on("chat:message", function (msg) { | |
if (msg.type === 'api' && msg.content === "!RoofDLOn"){ | |
dlInteraction = true; | |
sendChat("", "/w gm &{template:default} {{name=Rooftops DL Interaction}} {{Now set to On}}"); | |
} | |
}); | |
on("chat:message", function (msg) { | |
if (msg.type === 'api' && msg.content === "!RoofDLOff"){ | |
dlInteraction = false; | |
sendChat("", "/w gm &{template:default} {{name=Rooftops DL Interaction}} {{Now set to Off}}"); | |
} | |
}); | |
on("change:graphic", function(obj){ | |
if (allPlayerTokens.includes(obj)) | |
{ | |
for (var i = 0; i < allRoofTokens.length; i++) | |
{ | |
if (roofInsideCheck(allRoofTokens[i])) { removeRoof(allRoofTokens[i].id); } | |
else { restoreRoof(allRoofTokens[i].id); } | |
} | |
} | |
}); | |
on("chat:message", function (msg) { | |
var args = msg.content.split(" "); | |
if (msg.type === 'api' && args[0] === "!RooftopRange"){ | |
if (args[1]) { interactionRange = parseInt(args[1]); } | |
else { interactionRange = 0; } | |
sendChat("", "/w gm &{template:default} {{name=Rooftops Range}} {{Now set to " + interactionRange*5 + "}}"); | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment