|
import {registerSettings} from "./settings.js"
|
|
import {movementTracking, actionCount} from "./movementFunctions.js"
|
|
|
|
Hooks.once("init", () => {
|
|
//Wait until the game is initialized, then register the settings created previously.
|
|
registerSettings();
|
|
});
|
|
Hooks.once("canvasInit", () => {
|
|
//When the canvas intializes the first time after a reload, if enhanced terrain layer is active, overwrite the original environment/obstacle lists with a PF2e specific list.
|
|
if (game.modules.get("enhanced-terrain-layer")?.active){
|
|
canvas.terrain.getEnvironments = function(){return [
|
|
{ id: 'aquatic', text: 'Aquatic', icon:'systems/pf2e/icons/spells/crashing-wave.webp'},
|
|
{ id: 'arctic', text: 'Arctic', icon:'systems/pf2e/icons/spells/warped-terrain.webp' },
|
|
{ id: 'coast', text: 'Coast', icon:'systems/pf2e/icons/features/ancestry/skilled-heritage.webp' },
|
|
{ id: 'desert', text: 'Desert', icon:'systems/pf2e/icons/spells/dust-storm.webp' },
|
|
{ id: 'forest', text: 'Forest', icon:'systems/pf2e/icons/spells/plant-growth.webp' },
|
|
{ id: 'hills', text: 'Hills', icon:'systems/pf2e/icons/spells/passwall.webp' },
|
|
{ id: 'mountain', text: 'Mountain', icon:'systems/pf2e/icons/spells/stone-tell.webp' },
|
|
{ id: 'plains', text: 'Plains', icon:'systems/pf2e/icons/spells/commune-with-nature.webp' },
|
|
{ id: 'sky', text: 'Sky', icon:'systems/pf2e/icons/spells/darkness.webp' },
|
|
{ id: 'swamp', text: 'Swamp', icon:'systems/pf2e/icons/spells/blight.webp' },
|
|
{ id: 'underground', text: 'Underground', icon:'systems/pf2e/icons/spells/dance-of-darkness.webp' },
|
|
{ id: 'urban', text: 'Urban', icon:'systems/pf2e/icons/spells/pulse-of-the-city.webp' },
|
|
{ id: 'current', text: 'Current', icon:'systems/pf2e/icons/spells/air-walk.webp', obstacle:true },
|
|
{ id: 'crowd', text: 'Crowd', icon:'systems/pf2e/icons/spells/tireless-worker.webp' , obstacle:true},
|
|
{ id: 'furniture', text: 'Furniture', icon:'systems/pf2e/icons/spells/secret-chest.webp', obstacle:true},
|
|
{ id: 'ice', text: 'Ice', icon:'systems/pf2e/icons/spells/clinging-ice.webp', obstacle:true},
|
|
{ id: 'incline', text: 'Incline', icon:'systems/pf2e/icons/spells/unimpeded-stride.webp', obstacle:true },
|
|
{ id: 'magical', text: 'Magical', icon:'systems/pf2e/icons/default-icons/spell.webp', obstacle:true},
|
|
{ id: 'plants', text: 'Plants', icon:'systems/pf2e/icons/spells/natures-enmity.webp', obstacle:true },
|
|
{ id: 'rubble', text: 'Rubble', icon:'systems/pf2e/icons/spells/wall-of-stone.webp', obstacle:true },
|
|
{ id: 'water', text: 'Water', icon:'systems/pf2e/icons/spells/mariners-curse.webp', obstacle:true },
|
|
{ id: 'wind', text: 'Wind', icon:'systems/pf2e/icons/spells/punishing-winds.webp', obstacle:true }
|
|
];
|
|
}
|
|
}
|
|
});
|
|
|
|
Hooks.once("dragRuler.ready", (SpeedProvider) => {
|
|
class PF2eSpeedProvider extends SpeedProvider {
|
|
//Registers colours for up to four movement actions so colours can be customized for them, and sets defaults
|
|
get colors(){
|
|
return [
|
|
{id: "FirstAction", default: 0x3222C7},
|
|
{id: "SecondAction", default: 0xFFEC07},
|
|
{id: "ThirdAction", default: 0xC033E0},
|
|
{id: "FourthAction", default: 0x1BCAD8}
|
|
]
|
|
};
|
|
// Get the distance for each movement interval to give to drag ruler
|
|
getRanges(token){
|
|
var numactions = actionCount(token); //Use the actionCount function to determine how many actions that token gets each round.
|
|
var movement = movementTracking(token); //Use the movementTracking function to get how far each movement range should be.
|
|
const ranges = []; //create blank array to store the ranges in.
|
|
|
|
if (numactions > 0 && movement.A1 > 0){
|
|
//Set the ranges for each of our four actions to be given to the drag ruler.
|
|
ranges.push({range: movement.A1, color: "FirstAction"},{range: movement.A2, color: "SecondAction"}, { range: movement.A3, color: "ThirdAction"},{range: movement.A4, color: "FourthAction"});
|
|
//Remove ranges from the function until only the ranges equal to the number of legal actions remain.
|
|
for (var i = numactions, len=ranges.length; i<len; i++){
|
|
ranges.pop();
|
|
};
|
|
} else {ranges.push({range: 0, color: "FirstAction"})}; //Since ranges is empty if you've got no actions add a range for the first action of 0.
|
|
return ranges;
|
|
};
|
|
};
|
|
// When dragruler is ready to go give it all the PF2 specific stuff
|
|
dragRuler.registerModule("pf2e-dragruler", PF2eSpeedProvider) //register the speed provider so its selectable from the drag ruler configuration.
|
|
});
|
|
|
|
Hooks.on('updateCombat', () => {
|
|
if(game.user.isGM && game.settings.get("drag-ruler", "enableMovementHistory") && game.settings.get("pf2e-dragruler", "offTurnMovement")){
|
|
const combat = game.combats.active; //set the current combat
|
|
if(combat?.turns.length > 0){
|
|
const previousCombatant = combat.turns[(combat.turn - 1) < 0 ? (combat.turns.length - 1) : (combat.turn - 1)];
|
|
const nextCombatant = combat.turns[combat.turn]; //find the next combatant
|
|
if(nextCombatant?.flags?.dragRuler){
|
|
dragRuler.resetMovementHistory(combat, nextCombatant._id); //if movement history exists, clears it for the next combatant prior to acting. Gives a clean slate for the new turn, important for clearing out off turn movement.
|
|
};
|
|
if(previousCombatant?.flags?.dragRuler){
|
|
dragRuler.resetMovementHistory(combat, previousCombatant._id); //if movement history exists, clears it for the next combatant prior to acting. Gives a clean slate for the new turn, important for clearing out off turn movement.
|
|
};
|
|
};
|
|
};
|
|
});
|
|
|
|
Hooks.once("enhancedTerrainLayer.ready", (RuleProvider) => {
|
|
class PF2eRuleProvider extends RuleProvider {
|
|
calculateCombinedCost(terrain, options) {
|
|
const token = options?.token;
|
|
const tokenElevation = token?.document?.elevation || 0
|
|
let cost;
|
|
if(token){
|
|
var movementType = movementTracking(token).type; //gets type of movement.
|
|
//gets token elevation.
|
|
var ignoredEnv= Object.keys(token.actor.flags.pf2e?.movement?.env?.ignore || {any: false} ).filter(a => token.actor.flags.pf2e?.movement?.env?.ignore?.[a]); //finds all the flags set by effects asking the actor to ignore a type of terrain.
|
|
var reducedEnv= Object.keys(token.actor.flags.pf2e?.movement?.env?.reduce || {any: false} ).filter(a => token.actor.flags.pf2e?.movement?.env?.reduce?.[a]); //finds all the flags set by effects asking the actor to reduce the cost of a type of terrain.
|
|
if(token.actor.flags.pf2e?.movement?.ignoreTerrain|| token.actor.flags.pf2e?.movement?.climbing){
|
|
cost = 1
|
|
return cost
|
|
};
|
|
}
|
|
//Function for Minus Equal, minimum 1.
|
|
function mem1(a, value){
|
|
if(a <= value){return 1}
|
|
else{return (a - value)}
|
|
}
|
|
let environments = [];
|
|
let obstacles = [];
|
|
let costs = [];
|
|
for(var ii = 0; ii<terrain.length; ii++) {
|
|
if(terrain[ii].object.document.elevation >= tokenElevation && (terrain[ii].object.document.elevation-(terrain[ii].object.document.depth ?? 0)) <= tokenElevation && (token?.actor?.alliance ?? "none" !== (terrain[ii].object?.actor?.alliance ?? 0))){
|
|
environments.push(terrain[ii].environment)
|
|
obstacles.push(terrain[ii].obstacle)
|
|
costs.push(terrain[ii].cost)
|
|
if(token && !token.actor.flags.pf2e?.movement?.respectTerrain){
|
|
if(reducedEnv?.find(e => e == 'non-magical') && (environments[ii] !== 'magical' || obstacles[ii] !== 'magical')){
|
|
costs[ii] = mem1(costs[ii],1)
|
|
}
|
|
if(ignoredEnv?.find(e => e == 'non-magical') && (environments[ii] !== 'magical' || obstacles[ii] !== 'magical')){
|
|
costs[ii] = 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Calculate the cost for this terrain
|
|
if(token && !token.actor.flags.pf2e?.movement?.respectTerrain){
|
|
for(var i = 0; i < environments.length; i++){
|
|
if(reducedEnv?.find(e => e == environments[i])||reducedEnv?.find(e => e == obstacles[i])||token.actor.flags.pf2e?.movement?.reduceTerrain){costs[i] = mem1(costs[i],1)}
|
|
if(ignoredEnv?.find(e => e == environments[i])||ignoredEnv?.find(e => e == obstacles[i])){costs[i]=1}
|
|
if (movementType == 'swim' && obstacles[i] == "water" || movementType == 'swim' && environments[i] == "water" ){costs[i]=1}
|
|
if (movementType == 'burrow' && obstacles[i] == "underground" || movementType == 'burrow' && environments[i] == "underground" ){costs[i]=1}
|
|
}
|
|
}
|
|
costs.push(1);
|
|
cost = Math.max(...costs)
|
|
if(token && token.actor.flags.pf2e?.movement?.increaseTerrain){cost += 1}
|
|
return cost;
|
|
}
|
|
}
|
|
enhancedTerrainLayer.registerModule("pf2e-dragruler", PF2eRuleProvider);
|
|
});
|