Skip to content

Commit

Permalink
feat: Add hero point handler randomization settings: no selection, ra…
Browse files Browse the repository at this point in the history
…ndom party member, or party member who hasn't received a point. Defaults to random (i.e. the way it used to work).
  • Loading branch information
xdy committed Jan 7, 2025
1 parent e9658d7 commit 0c7a612
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
52 changes: 49 additions & 3 deletions src/module/feature/heroPointHandler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,22 +144,68 @@ export async function heroPointHandler(state: HPHState) {
handlerDialog.render(true);
}

// Constants
const PARTY_MEMBERS_FLAG_KEY = "partymembersThatHaveGottenHeropoints";

/**
* Selects a random party member index from the provided list of actors,
* ensuring the same actor is not repeatedly selected until all have been selected.
*
* @param {CreaturePF2e[]} actors - The list of party members to select from.
* @return {Promise<number>} The index of the selected actor in the input array, or -1 if the input array is empty.
*/
async function randomPartymemberThatHasNotReceivedAHeropoint(actors): Promise<number> {
if (actors.length === 0) {
await game.actors?.party?.unsetFlag(MODULENAME, PARTY_MEMBERS_FLAG_KEY);
return -1;
}

const existingFlagValue = String(game.actors?.party?.getFlag(MODULENAME, PARTY_MEMBERS_FLAG_KEY));
const hasReceivedHP: Set<string> = existingFlagValue ? new Set(existingFlagValue.split(",")) : new Set();
if (hasReceivedHP.size === actors.length) {
hasReceivedHP.clear();
}

const noHPYet = actors.filter((actor) => !hasReceivedHP.has(actor.id));
if (noHPYet.length === 0) {
hasReceivedHP.clear();
noHPYet.push(...actors);
}
const randomIndex: number = Math.floor(Math.random() * noHPYet.length);
const selectedActorId: string = noHPYet[randomIndex]?.id || actors[Math.floor(Math.random() * actors.length)]?.id;
hasReceivedHP.add(selectedActorId);

await game.actors?.party?.setFlag(MODULENAME, PARTY_MEMBERS_FLAG_KEY, [...hasReceivedHP].join(","));

return actors.findIndex((actor) => actor.id === selectedActorId);
}

async function buildHtml(remainingMinutes: number, state: HPHState) {
// TODO How to start using bootstrap? (I use bootstrap classes in the html).
// TODO Extract to a handlebars template

// TODO Get user name, add within parentheses after actor name
let charactersContent = "";
const actors = heroes();

let checked: number;
switch (state) {
case HPHState.Start:
checked = -1;
break;
case HPHState.Timeout:
checked = actors.length > 0 ? Math.floor(Math.random() * actors.length) : -1;
case HPHState.Timeout: {
let selectedActor = -1;
switch (game.settings.get(MODULENAME, "heropointHandlerRandomization")) {
case "none":
break;
case "random":
selectedActor = Math.floor(Math.random() * actors.length);
break;
case "randomPartymemberThatHasNotReceivedAHeropoint":
selectedActor = await randomPartymemberThatHasNotReceivedAHeropoint(actors);
}
checked = actors.length > 0 ? selectedActor : -1;
break;
}
case HPHState.Check:
checked = -1;
break;
Expand Down
15 changes: 15 additions & 0 deletions src/module/settings/reminders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,21 @@ export class WorkbenchRemindersSettings extends SettingsMenuPF2eWorkbench {
onChange: () => updateHooks(),
requiresReload: true,
},
heropointHandlerRandomization: {
name: `${MODULENAME}.SETTINGS.heropointHandlerRandomization.name`,
hint: `${MODULENAME}.SETTINGS.heropointHandlerRandomization.hint`,
scope: "world",
config: true,
default: "random",
type: String,
choices: {
none: game.i18n.localize(`${MODULENAME}.SETTINGS.heropointHandlerRandomization.none`),
random: game.i18n.localize(`${MODULENAME}.SETTINGS.heropointHandlerRandomization.random`),
randomPartymemberThatHasNotReceivedAHeropoint: game.i18n.localize(`${MODULENAME}.SETTINGS.heropointHandlerRandomization.randomPartymemberThatHasNotReceivedAHeropoint`),
},
onChange: () => updateHooks(),
requiresReload: true,
},
};
}
}
7 changes: 7 additions & 0 deletions static/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,13 @@
"hint": "Check to automatically start the Hero Point handler timer when the game is ready.",
"name": "... and automatically start Hero Point Handler."
},
"heropointHandlerRandomization": {
"hint": "How to select player to get random heropoint",
"name": "... how to select player to get random heropoint.",
"none": "No one",
"random": "A random partymember",
"randomPartymemberThatHasNotReceivedAHeropoint": "A partymember that hasn't gotten one yet."
},
"housepatcher": {
"hint": "(REALLY EXPERIMENTAL) Enter a json array to patch system compendiums. See housepatcher.md on the github for documentation.",
"name": "(REALLY EXPERIMENTAL) Housepatcher (patches in house rules). Requires refresh (f5) after changing.",
Expand Down

0 comments on commit 0c7a612

Please sign in to comment.