feat: only allow specific selectable values for the cooldown duration of spells

World data (including compendium packs) is migrated automatically. In order to also migrate packs
provided by modules, you can use the following macro:
```js
const pack = game.packs.get("<name-of-the-module>.<name-of-the-pack>");
game.ds4.migration.migrateCompendiumFromTo(pack, 4, 5);
```
This commit is contained in:
Johannes Loher 2022-02-14 00:58:23 +01:00
parent 73e2d44c55
commit da1f6999eb
20 changed files with 558 additions and 876 deletions

View file

@ -10,7 +10,7 @@ import {
migrateScenes,
} from "./migrationHelpers";
export async function migrate(): Promise<void> {
async function migrate(): Promise<void> {
await migrateActors(getActorUpdateData);
await migrateScenes(getSceneUpdateData);
await migrateCompendiums(migrateCompendium);
@ -39,3 +39,8 @@ function getActorUpdateData(): Record<string, unknown> {
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
const migrateCompendium = getCompendiumMigrator({ getActorUpdateData, getSceneUpdateData });
export const migration = {
migrate,
migrateCompendium,
};

View file

@ -12,7 +12,7 @@ import {
migrateScenes,
} from "./migrationHelpers";
export async function migrate(): Promise<void> {
async function migrate(): Promise<void> {
await migrateItems(getItemUpdateData);
await migrateActors(getActorUpdateData);
await migrateScenes(getSceneUpdateData);
@ -32,3 +32,8 @@ const migrateCompendium = getCompendiumMigrator(
{ getItemUpdateData, getActorUpdateData, getSceneUpdateData },
{ migrateToTemplateEarly: false },
);
export const migration = {
migrate,
migrateCompendium,
};

View file

@ -12,7 +12,7 @@ import {
migrateScenes,
} from "./migrationHelpers";
export async function migrate(): Promise<void> {
async function migrate(): Promise<void> {
await migrateItems(getItemUpdateData);
await migrateActors(getActorUpdateData);
await migrateScenes(getSceneUpdateData);
@ -34,3 +34,8 @@ const migrateCompendium = getCompendiumMigrator(
{ getItemUpdateData, getActorUpdateData },
{ migrateToTemplateEarly: false },
);
export const migration = {
migrate,
migrateCompendium,
};

View file

@ -12,7 +12,7 @@ import {
migrateScenes,
} from "./migrationHelpers";
export async function migrate(): Promise<void> {
async function migrate(): Promise<void> {
await migrateItems(getItemUpdateData);
await migrateActors(getActorUpdateData);
await migrateScenes(getSceneUpdateData);
@ -21,6 +21,7 @@ export async function migrate(): Promise<void> {
function getItemUpdateData(itemData: Partial<foundry.data.ItemData["_source"]>) {
if (itemData.type !== "spell") return;
// @ts-expect-error the type of cooldownDuration was UnitData<TemporalUnit> at the point for this migration, but it changed later on
const cooldownDurationUnit: string | undefined = itemData.data?.cooldownDuration.unit;
const updateData: Record<string, unknown> = {
@ -38,3 +39,8 @@ function getItemUpdateData(itemData: Partial<foundry.data.ItemData["_source"]>)
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
export const migration = {
migrate,
migrateCompendium,
};

119
src/migrations/005.ts Normal file
View file

@ -0,0 +1,119 @@
// SPDX-FileCopyrightText: 2021 Johannes Loher
//
// SPDX-License-Identifier: MIT
import { CooldownDuration } from "../item/item-data-source";
import {
getActorUpdateDataGetter,
getCompendiumMigrator,
getSceneUpdateDataGetter,
migrateActors,
migrateCompendiums,
migrateItems,
migrateScenes,
} from "./migrationHelpers";
const secondsPerRound = 5;
const secondsPerMinute = 60;
const roundsPerMinute = secondsPerMinute / secondsPerRound;
const minutesPerHour = 60;
const roundsPerHour = minutesPerHour / roundsPerMinute;
const hoursPerDay = 24;
const roundsPerDay = hoursPerDay / roundsPerHour;
const secondsPerDay = secondsPerMinute * minutesPerHour * hoursPerDay;
async function migrate(): Promise<void> {
await migrateItems(getItemUpdateData);
await migrateActors(getActorUpdateData);
await migrateScenes(getSceneUpdateData);
await migrateCompendiums(migrateCompendium);
}
function getItemUpdateData(itemData: Partial<foundry.data.ItemData["_source"]>) {
if (itemData.type !== "spell") return;
// @ts-expect-error the type of cooldownDuration is changed from UnitData<TemporalUnit> to CooldownDuation with this migration
const cooldownDurationUnit: string | undefined = itemData.data?.cooldownDuration.unit;
// @ts-expect-error the type of cooldownDuration is changed from UnitData<TemporalUnit> to CooldownDuation with this migration
const cooldownDurationValue: string | undefined = itemData.data?.cooldownDuration.value;
const cooldownDuration = migrateCooldownDuration(cooldownDurationValue, cooldownDurationUnit);
const updateData: Record<string, unknown> = {
data: {
cooldownDuration,
},
};
return updateData;
}
function migrateCooldownDuration(cooldownDurationValue?: string, cooldownDurationUnit?: string) {
if (Number.isNumeric(cooldownDurationValue)) {
const value = Number.fromString(cooldownDurationValue!);
const rounds = getRounds(cooldownDurationUnit ?? "", value);
if (rounds * secondsPerRound > secondsPerDay) {
return "d20d";
} else if (rounds > 100) {
return "1d";
} else if (rounds > 10) {
return "100r";
} else if (rounds > 5) {
return "10r";
} else if (rounds > 2) {
return "5r";
} else if (rounds > 1) {
return "2r";
} else if (rounds > 0) {
return "1r";
} else {
return "0r";
}
} else {
// if the value is not numeric, we can only make a best guess
switch (cooldownDurationUnit) {
case "rounds": {
return "10r";
}
case "minutes": {
return "100r";
}
case "hours": {
return "1d";
}
case "days": {
return "d20d";
}
default: {
return "0r";
}
}
}
}
function getRounds(unit: string, value: number): number {
switch (unit) {
case "rounds": {
return value;
}
case "minutes": {
return value * roundsPerMinute;
}
case "hours": {
return value * roundsPerHour;
}
case "days": {
return value * roundsPerDay;
}
default: {
return 0;
}
}
}
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
export const migration = {
migrate,
migrateCompendium,
};