Skip to content

Commit

Permalink
Merge pull request #18 from Saibot393/DEVELOPMENT-v2.3.0
Browse files Browse the repository at this point in the history
Development v2.3.0
  • Loading branch information
Saibot393 authored Jul 17, 2023
2 parents 0420180 + c6e609b commit 2853957
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 36 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## v2.3.0
- Added compendium token support for "Spawn riders"
- Added "cluster" placement pattern
- Added "Adjust rider size" setting

## v2.2.1
- Bug fix for free riding tokens and stairways compatibility

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Since v2.2.0 the module also has basic support for tokens to grapple one another
- Familiar riding: to allow familiars to ride their master (familiars will be placed on their masters corners)
- Grappling: to allow tokens to grapple one another
- Prevent enemy riding: to stop tokens from riding enemy tokens (GMs ignore this setting)
- Adjust rider size: to reduce the size of riders should their size be greater or equal to the size of the ridden token
#### Client:
- Rider movement: to decide what shall happen if a rider tries to move while still being mounted, either dismount the rider, stop the movement or move the ridden token
- Message popups: to activate some popups on certain actions
Expand Down
8 changes: 7 additions & 1 deletion lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
"name" : "Gegner reiten verhindern",
"descrp" : "Hält Marken davon ab Gegner zu reiten (SL Befehle ignorieren diese Einstellung)"
},

"FitRidersize" : {
"name" : "Passe Reitergröße an",
"descrp" : "Passt die Größe der reitenden Marke an, sollte sie größer oder gleich der gerittenen Marke sein"
},

"MessagePopUps" : {
"name" : "Pop-up Meldungen",
Expand Down Expand Up @@ -143,7 +148,8 @@
"descrp" : "Das Muster in welchem die Reitermarken platziert werden",
"options" : {
"CirclePlacement" : "Kreis",
"RowPlacement" : "Reihe"
"RowPlacement" : "Reihe",
"ClusterPlacement" : "Bündel"
}
},

Expand Down
8 changes: 7 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
"name" : "Prevent enemy riding",
"descrp" : "Stops tokens from riding enemy tokens (GMs can still override this)"
},

"FitRidersize" : {
"name" : "Adjust rider size",
"descrp" : "Adjusts the size of the rider in the case that it is greater or equal to the size of the ridden token"
},

"MessagePopUps" : {
"name" : "Message popups",
Expand Down Expand Up @@ -143,7 +148,8 @@
"descrp" : "The pattern in which the rider tokens will be placed",
"options" : {
"CirclePlacement" : "Circle",
"RowPlacement" : "Row"
"RowPlacement" : "Row",
"ClusterPlacement" : "Cluster"
}
},

Expand Down
5 changes: 3 additions & 2 deletions module.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"name": "saibot"
}
],
"version": "2.2.1",
"version": "2.3.0",
"compatibility": {
"minimum": "10",
"verified": "11"
Expand All @@ -33,6 +33,7 @@
"scripts/utils/GeometricUtils.js",
"scripts/utils/RideableUtils.js",
"scripts/helpers/RideablePopups.js",
"scripts/helpers/EffectManager.js",
"scripts/helpers/RideableFlags.js",
"scripts/RidingScript.js",
"scripts/MountingScript.js",
Expand All @@ -51,7 +52,7 @@
}
],
"url": "https://github.com/Saibot393/Rideable",
"download": "https://github.com/Saibot393/Rideable/archive/refs/tags/v2.2.1.zip",
"download": "https://github.com/Saibot393/Rideable/archive/refs/tags/v2.3.0.zip",
"manifest": "https://github.com/Saibot393/Rideable/releases/latest/download/module.json",
"readme": "https://github.com/Saibot393/Rideable/blob/main/README.md",
"changelog": "https://github.com/Saibot393/Rideable/blob/main/CHANGELOG.md",
Expand Down
29 changes: 10 additions & 19 deletions scripts/MountingScript.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as FCore from "./CoreVersionComp.js";

import { RideableFlags } from "./helpers/RideableFlags.js";
import { EffectManager } from "./helpers/EffectManager.js";
import { GeometricUtils } from "./utils/GeometricUtils.js";
import { RideableUtils, cModuleName } from "./utils/RideableUtils.js";
import { RideablePopups } from "./helpers/RideablePopups.js";
Expand Down Expand Up @@ -32,9 +31,9 @@ class MountingManager {
//Additional functions
static onIndependentRiderMovement(pToken) {} //everything that happens upon a rider moving (besides the basics)

static onMount(pRider, pRidden, pRidingOptions) {} //everything that happens upon a token mounting (besides the basics)
static async onMount(pRider, pRidden, pRidingOptions) {} //everything that happens upon a token mounting (besides the basics)

static onUnMount(pRider, pRidden, pRidingOptions) {} //everything that happens upon a token unmounting (besides the basics)
static async onUnMount(pRider, pRidden, pRidingOptions) {} //everything that happens upon a token unmounting (besides the basics)

//Aditional Informations
static TokencanMount (pRider, pRidden, pRidingOptions, pShowPopups = false) {} //returns if pRider can currently mount pRidden (ignores TokenisRideable and TokencanRide) (can also show appropiate popups with reasons why mounting failed)
Expand Down Expand Up @@ -133,11 +132,11 @@ class MountingManager {

await RideableFlags.addRiderTokens(pTarget, vValidTokens, pRidingOptions);

UpdateRidderTokens(pTarget, vValidTokens.concat(vpreviousRiders), pRidingOptions);

for (let i = 0; i < vValidTokens.length; i++) {
MountingManager.onMount(vValidTokens[i], pTarget, pRidingOptions);
await MountingManager.onMount(vValidTokens[i], pTarget, pRidingOptions);
}

UpdateRidderTokens(pTarget, vValidTokens.concat(vpreviousRiders), pRidingOptions);
}
}
}
Expand Down Expand Up @@ -168,7 +167,6 @@ class MountingManager {
vRiddenTokens[i] = RideableFlags.RiddenToken(vRiderTokens[i]);
}

console.log(pRemoveRiddenreference);
RideableFlags.stopRiding(vRiderTokens, pRemoveRiddenreference);

UnsetRidingHeight(vRiderTokens, vRiddenTokens);
Expand Down Expand Up @@ -247,7 +245,7 @@ class MountingManager {
}
}

static onMount(pRider, pRidden, pRidingOptions) {
static async onMount(pRider, pRidden, pRidingOptions) {
if (pRider) {

if (pRidden) {
Expand All @@ -264,11 +262,8 @@ class MountingManager {
}
}

//Aplly mounted effect if turned on
if (game.settings.get(cModuleName, "RidingSystemEffects") && !(RideableFlags.isFamiliarRider(pRider) || RideableFlags.isGrappled(pRider))) {
if (EffectManager.getSystemMountingEffect()) {
pRider.actor.createEmbeddedDocuments("Item", [EffectManager.getSystemMountingEffect()]);
}
if (game.settings.get(cModuleName, "FitRidersize")) {
RideableFlags.savecurrentSize(pRider);
}
}

Expand All @@ -291,10 +286,8 @@ class MountingManager {
}
}

if (game.settings.get(cModuleName, "RidingSystemEffects")) {
if (EffectManager.getSystemMountingEffect()) {
await pRider.actor.deleteEmbeddedDocuments("Item", pRider.actor.itemTypes.effect.filter(vElement => vElement.sourceId == EffectManager.getSystemMountingEffect().flags.core.sourceId).map(vElement => vElement.id));
}
if (game.settings.get(cModuleName, "FitRidersize")) {
RideableFlags.resetSize(pRider);
}
}

Expand Down Expand Up @@ -406,8 +399,6 @@ Hooks.on("deleteToken", (...args) => MountingManager.onTokenDeletion(...args));

Hooks.on(cModuleName+".IndependentRiderMovement", (...args) => MountingManager.onIndependentRiderMovement(...args));

Hooks.on("ready", function() { EffectManager.preloadEffects(); });

//wrap and export functions

function MountSelected(pTargetHovered = false) { return MountingManager.MountSelected(pTargetHovered); }
Expand Down
82 changes: 78 additions & 4 deletions scripts/RidingScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ import { GeometricUtils, cGradtoRad } from "./utils/GeometricUtils.js";
//positioning options
const cRowplacement = "RowPlacement"; //place all tokens in a RowPlacement
const cCircleplacement = "CirclePlacement"; //place all tokens in a circle
const cBlockplacement = "BlockPlacement"; //place all tokens in a Block
const cClusterplacement = "ClusterPlacement"; //place all tokens in a Cluster

const cPlacementPatterns = [cRowplacement, cCircleplacement];
const cPlacementPatterns = [cRowplacement, cCircleplacement, cClusterplacement];

export { cRowplacement, cPlacementPatterns };

const cSizeFactor = 2/3;

//Ridingmanager will do all the work for placing riders and handling the z-Height
class Ridingmanager {
//DECLARATIONS
Expand All @@ -24,12 +28,14 @@ class Ridingmanager {

static OnIndependentRidermovement(pToken, pchanges, pInfos, pRidden, psendingUser) {} //Handles what should happen if a rider moved independently

static planRiderTokens(pRiddenToken, pRiderTokenList, pAnimations = true) {} //Works out where the Riders of pRiddenToken should move based on the updated pRiddenToken
static async planRiderTokens(pRiddenToken, pRiderTokenList, pAnimations = true) {} //Works out where the Riders of pRiddenToken should move based on the updated pRiddenToken

static planPatternRidersTokens(pRiddenToken, pRiderTokenList, pAnimations = true) {} //works out the position of tokens if they are spread according to a set pattern

static placeRiderHeight(pRiddenToken, pRiderTokenList, pPlaceSameheight = false) {} //sets the appropiate riding height (elevation) of pRiderTokenList based on pRiddenToken

static async fitRiders(pRiddenToken, pRiderTokenList, pSizeFactor = cSizeFactor) {} //reduces the size of all tokens that are equal or greater in size to their ridden token to pSizeFactor of ridden token

static planRelativRiderTokens(pRiddenToken, pRiderTokenList, pAnimations = true) {} //works out the position of tokens if they can move freely on pRiddenToken

//DEPRICATED:
Expand Down Expand Up @@ -177,7 +183,7 @@ class Ridingmanager {
}
}

static planRiderTokens(pRiddenToken, pRiderTokenList, pAnimations = true) {
static async planRiderTokens(pRiddenToken, pRiderTokenList, pAnimations = true) {
let vRiderTokenList = pRiderTokenList;
let vRiderFamiliarList = []; //List of Riders that Ride as familiars
let vGrappledList = [];
Expand All @@ -198,6 +204,11 @@ class Ridingmanager {

vRiderTokenList = vRiderTokenList.filter(vToken => !vRiderFamiliarList.includes(vToken));
}

//reduce size if necessary
if (game.settings.get(cModuleName, "FitRidersize")) {
await Ridingmanager.fitRiders(pRiddenToken, vRiderTokenList);
}

if (RideableFlags.RiderscanMoveWithin(pRiddenToken)) {
Ridingmanager.planRelativRiderTokens(pRiddenToken, vRiderTokenList, pAnimations);
Expand All @@ -215,9 +226,11 @@ class Ridingmanager {

static planPatternRidersTokens(pRiddenToken, pRiderTokenList, pAnimations = true) {
if (pRiderTokenList.length) {
let vAngleSteps; //to fix javascript syntax bug

switch (RideableFlags.RiderPositioning(pRiddenToken)) {
case cCircleplacement:
let vAngleSteps = 360/pRiderTokenList.length;
vAngleSteps = 360/pRiderTokenList.length;

//calculate maximum placement heights and widths
let vMaxHeight = 0;
Expand All @@ -237,6 +250,58 @@ class Ridingmanager {

break;

case cClusterplacement:
let vSizeFactor = GeometricUtils.insceneSize(pRiddenToken);

let vsortedTokens;
let vsortedSizes;
let vPlacementInterval = [0,0];
vAngleSteps = 0;
let vBaseRadius = 0;
let vMaxSize;
let vSizesumm;

//sort tokens
[vsortedTokens, vsortedSizes] = GeometricUtils.sortbymaxdim(pRiderTokenList);

//place largest tokens first
vsortedTokens.reverse();
vsortedSizes.reverse();

//for 0th token
vMaxSize = vsortedSizes[0];

while (vPlacementInterval[1] < vsortedTokens.length) {
//placements
for (let i = vPlacementInterval[0]; i <= vPlacementInterval[1]; i++) {
Ridingmanager.placeTokenrotated(pRiddenToken, pRiderTokenList[i], vBaseRadius * vSizeFactor * Math.sin(vAngleSteps*cGradtoRad*i), -vBaseRadius * vSizeFactor * Math.cos(vAngleSteps*cGradtoRad*i), pAnimations);
}

vBaseRadius = vBaseRadius + vMaxSize/2;

//new calculations
vPlacementInterval[0] = vPlacementInterval[1] + 1;
vPlacementInterval[1] = vPlacementInterval[0];

vMaxSize = vsortedSizes[vPlacementInterval[0]];
vSizesumm = vsortedSizes[vPlacementInterval[0]];

//check if next element exists and fits in new circumference
while (((vPlacementInterval[1]+1) < vsortedTokens.length) && ((2*vBaseRadius + Math.max(vsortedSizes[vPlacementInterval[1]+1], vMaxSize))*Math.PI > (vSizesumm + vsortedSizes[vPlacementInterval[1]+1]))) {

vPlacementInterval[1] = vPlacementInterval[1] + 1;

vMaxSize = Math.max(vMaxSize, vsortedSizes[vPlacementInterval[1]]);
vSizesumm = vSizesumm + vsortedSizes[vPlacementInterval[1]];
}

vAngleSteps = 360/(vPlacementInterval[1] - vPlacementInterval[0] + 1);

vBaseRadius = vBaseRadius + vMaxSize/2;
}

break;

case cRowplacement:
default:
Ridingmanager.placeRidersTokensRow(pRiddenToken, pRiderTokenList, pAnimations);
Expand All @@ -259,6 +324,15 @@ class Ridingmanager {
}
}

static async fitRiders(pRiddenToken, pRiderTokenList, pSizeFactor = cSizeFactor) {
for (let i = 0; i < pRiderTokenList.length; i++) {

if ((pRiderTokenList[i].width >= pRiddenToken.width) && (pRiderTokenList[i].height >= pRiddenToken.height)) {
await pRiderTokenList[i].update({width : pSizeFactor*pRiddenToken.width, height : pSizeFactor*pRiddenToken.height});
}
}
}

static planRelativRiderTokens(pRiddenToken, pRiderTokenList, pAnimations = true) {
let vRiddenForm = RideableFlags.TokenForm(pRiddenToken);

Expand Down
39 changes: 31 additions & 8 deletions scripts/helpers/EffectManager.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,52 @@
import { RideableUtils, cModuleName } from "../utils/RideableUtils.js";
import { RideableFlags } from "./RideableFlags.js";

const cMountedPf2eEffectID = "Compendium.pf2e.other-effects.Item.9c93NfZpENofiGUp"; //Mounted effects of Pf2e system

var vSystemRidingEffect = null; //saves the systems mounting effects (if any)

class EffectManager {

//DECLARATIONS
static async preloadEffects() {} //preloads effects to make things smoother

static getSystemMountingEffect() {} //returns an appropiate Mounting effect if the game system has one
//Hooks
static onRiderMount(pRider, pRidden, pRidingOptions) {} //handle creation of mounting effects

static onRiderUnMount(pRider, pRidden, pRidingOptions) {} //handle deletion of mounting effects

//IMPLEMENTATION
static async preloadEffects() {
if (RideableUtils.isPf2e()) {
vSystemRidingEffect = (await fromUuid(cMountedPf2eEffectID)).toObject();
}
}
static getSystemMountingEffect() {

if (vSystemRidingEffect) {
return vSystemRidingEffect;

//Hooks
static onRiderMount(pRider, pRidden, pRidingOptions) {
console.log("here");
if (game.settings.get(cModuleName, "RidingSystemEffects") && !(RideableFlags.isFamiliarRider(pRider) || RideableFlags.isGrappled(pRider))) {
if (vSystemRidingEffect) {
pRider.actor.createEmbeddedDocuments("Item", [vSystemRidingEffect]);
}
}
}

static onRiderUnMount(pRider, pRidden, pRidingOptions) {
if (game.settings.get(cModuleName, "RidingSystemEffects")) {
if (vSystemRidingEffect) {
pRider.actor.deleteEmbeddedDocuments("Item", pRider.actor.itemTypes.effect.filter(vElement => vElement.sourceId == vSystemRidingEffect.flags.core.sourceId).map(vElement => vElement.id));
}
}

return;
}
}

export { EffectManager }
export { EffectManager }

//Hooks

Hooks.on("ready", function() { EffectManager.preloadEffects(); });

Hooks.on(cModuleName + "." + "Mount", (...args) => EffectManager.onRiderMount(...args));

Hooks.on(cModuleName + "." + "UnMount", (...args) => EffectManager.onRiderUnMount(...args));
Loading

0 comments on commit 2853957

Please sign in to comment.