mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 11:41:08 +01:00
Added the clown car
This commit is contained in:
parent
8ce7dc16db
commit
e8961afc5e
6 changed files with 135 additions and 2 deletions
BIN
assets/icons/arrow-dunk.png
Normal file
BIN
assets/icons/arrow-dunk.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
|
|
@ -439,7 +439,9 @@
|
|||
},
|
||||
"HUD": {
|
||||
"tokenHUD": {
|
||||
"genericEffects": "Foundry Effects"
|
||||
"genericEffects": "Foundry Effects",
|
||||
"depositPartyTokens": "Deposit Party Tokens",
|
||||
"retrievePartyTokens": "Retrieve Party Tokens"
|
||||
}
|
||||
},
|
||||
"Levelup": {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import { shuffleArray } from '../../helpers/utils.mjs';
|
||||
|
||||
export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['daggerheart'],
|
||||
actions: {
|
||||
combat: DHTokenHUD.#onToggleCombat
|
||||
combat: DHTokenHUD.#onToggleCombat,
|
||||
togglePartyTokens: DHTokenHUD.#togglePartyTokens
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -19,6 +22,10 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
|||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
|
||||
context.partyOnCanvas = this.actor.system.partyMembers.some(member => member.getActiveTokens().length > 0);
|
||||
context.icons.toggleParty = 'systems/daggerheart/assets/icons/arrow-dunk.png';
|
||||
context.actorType = this.actor.type;
|
||||
context.usesEffects = this.actor.type !== 'party';
|
||||
context.canToggleCombat = DHTokenHUD.#nonCombatTypes.includes(this.actor.type)
|
||||
? false
|
||||
: context.canToggleCombat;
|
||||
|
|
@ -59,6 +66,102 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
|||
}
|
||||
}
|
||||
|
||||
static async #togglePartyTokens(_, button) {
|
||||
const icon = button.querySelector('img');
|
||||
icon.classList.toggle('flipped');
|
||||
button.dataset.tooltip = game.i18n.localize(
|
||||
icon.classList.contains('flipped')
|
||||
? 'DAGGERHEART.APPLICATIONS.HUD.tokenHUD.retrievePartyTokens'
|
||||
: 'DAGGERHEART.APPLICATIONS.HUD.tokenHUD.depositPartyTokens'
|
||||
);
|
||||
|
||||
const animationDuration = 500;
|
||||
const activeTokens = this.actor.system.partyMembers.flatMap(member => member.getActiveTokens());
|
||||
const { x: actorX, y: actorY } = this.actor.token;
|
||||
if (activeTokens.length > 0) {
|
||||
for (let token of activeTokens) {
|
||||
await token.document.update(
|
||||
{ x: actorX, y: actorY, alpha: 0 },
|
||||
{ animation: { duration: animationDuration } }
|
||||
);
|
||||
setTimeout(() => token.document.delete(), animationDuration);
|
||||
}
|
||||
} else {
|
||||
const activeScene = game.scenes.find(x => x.active);
|
||||
const newTokens = await activeScene.createEmbeddedDocuments(
|
||||
'Token',
|
||||
this.actor.system.partyMembers.map(member => ({
|
||||
...member.getTokenDocument(),
|
||||
actorId: member.id,
|
||||
actorLink: true,
|
||||
alpha: 0,
|
||||
x: actorX,
|
||||
y: actorY
|
||||
}))
|
||||
);
|
||||
|
||||
const { sizeX, sizeY } = activeScene.grid;
|
||||
const nrRandomPositions = Math.ceil(newTokens.length / 8) * 8;
|
||||
/* This is an overcomplicated mess, but I'm stupid */
|
||||
const positions = shuffleArray(
|
||||
[...Array(nrRandomPositions).keys()].map((_, index) => {
|
||||
const nonZeroIndex = index + 1;
|
||||
const indexFloor = Math.floor(index / 8);
|
||||
const distanceCoefficient = indexFloor + 1;
|
||||
const side = 3 + indexFloor * 2;
|
||||
const sideMiddle = Math.ceil(side / 2);
|
||||
const inbetween = 1 + indexFloor * 2;
|
||||
const inbetweenMiddle = Math.ceil(inbetween / 2);
|
||||
|
||||
if (index < side) {
|
||||
const distance =
|
||||
nonZeroIndex === sideMiddle
|
||||
? 0
|
||||
: nonZeroIndex < sideMiddle
|
||||
? -nonZeroIndex
|
||||
: nonZeroIndex - sideMiddle;
|
||||
return { x: actorX - sizeX * distance, y: actorY - sizeY * distanceCoefficient };
|
||||
} else if (index < side + inbetween) {
|
||||
const inbetweenIndex = nonZeroIndex - side;
|
||||
const distance =
|
||||
inbetweenIndex === inbetweenMiddle
|
||||
? 0
|
||||
: inbetweenIndex < inbetweenMiddle
|
||||
? -inbetweenIndex
|
||||
: inbetweenIndex - inbetweenMiddle;
|
||||
return { x: actorX + sizeX * distanceCoefficient, y: actorY + sizeY * distance };
|
||||
} else if (index < 2 * side + inbetween) {
|
||||
const sideIndex = nonZeroIndex - side - inbetween;
|
||||
const distance =
|
||||
sideIndex === sideMiddle
|
||||
? 0
|
||||
: sideIndex < sideMiddle
|
||||
? sideIndex
|
||||
: -(sideIndex - sideMiddle);
|
||||
return { x: actorX + sizeX * distance, y: actorY + sizeY * distanceCoefficient };
|
||||
} else {
|
||||
const inbetweenIndex = nonZeroIndex - 2 * side - inbetween;
|
||||
const distance =
|
||||
inbetweenIndex === inbetweenMiddle
|
||||
? 0
|
||||
: inbetweenIndex < inbetweenMiddle
|
||||
? inbetweenIndex
|
||||
: -(inbetweenIndex - inbetweenMiddle);
|
||||
return { x: actorX - sizeX * distanceCoefficient, y: actorY + sizeY * distance };
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
for (let token of newTokens) {
|
||||
const position = positions.pop();
|
||||
token.update(
|
||||
{ x: position.x, y: position.y, alpha: 1 },
|
||||
{ animation: { duration: animationDuration } }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_getStatusEffectChoices() {
|
||||
// Include all HUD-enabled status effects
|
||||
const choices = {};
|
||||
|
|
|
|||
|
|
@ -418,3 +418,15 @@ export async function createEmbeddedItemsWithEffects(actor, baseData) {
|
|||
export const slugify = name => {
|
||||
return name.toLowerCase().replaceAll(' ', '-').replaceAll('.', '');
|
||||
};
|
||||
|
||||
export function shuffleArray(array) {
|
||||
let currentIndex = array.length;
|
||||
while (currentIndex != 0) {
|
||||
let randomIndex = Math.floor(Math.random() * currentIndex);
|
||||
currentIndex--;
|
||||
|
||||
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,13 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.clown-car img {
|
||||
transition: 0.5s;
|
||||
|
||||
&.flipped {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if usesEffects}}
|
||||
<button type="button" class="control-icon" data-action="togglePalette" data-palette="effects" data-tooltip="HUD.AssignStatusEffects">
|
||||
<img src="{{icons.effects}}">
|
||||
</button>
|
||||
|
|
@ -54,6 +55,13 @@
|
|||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq actorType 'party')}}
|
||||
<button type="button" class="control-icon clown-car" data-action="togglePartyTokens" data-tooltip="{{#if partyOnCanvas}}{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.retrievePartyTokens"}}{{else}}{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.depositPartyTokens"}}{{/if}}">
|
||||
<img {{#if partyOnCanvas}}class="flipped"{{/if}} src="{{icons.toggleParty}}">
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
<button type="button" class="control-icon" data-action="togglePalette" data-palette="movementActions"
|
||||
aria-label="{{ localize "HUD.SelectMovementAction" }}" data-tooltip>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue