From 3d272f2b92c5b4c561ee53a80a4a2574fd22ca90 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 00:14:16 +0100 Subject: [PATCH 01/14] Make weapons rollable from the character sheet --- src/lang/de.json | 13 ++- src/lang/en.json | 9 +- src/module/actor/sheets/actor-sheet.ts | 17 +--- src/module/ds4.ts | 34 +------- src/module/handlebars-helpers.ts | 10 --- src/module/handlebars/handlebars-helpers.ts | 12 +++ src/module/handlebars/handlebars-partials.ts | 26 ++++++ src/module/item/item-data.ts | 5 +- src/module/item/item.ts | 82 ++++++++++++++++++- src/module/rolls/check-factory.ts | 4 +- src/scss/components/_item_list.scss | 5 ++ .../actor/partials/item-list-entry.hbs | 3 +- src/templates/common/simple-select-form.hbs | 19 +++++ 13 files changed, 173 insertions(+), 66 deletions(-) delete mode 100644 src/module/handlebars-helpers.ts create mode 100644 src/module/handlebars/handlebars-helpers.ts create mode 100644 src/module/handlebars/handlebars-partials.ts create mode 100644 src/templates/common/simple-select-form.hbs diff --git a/src/lang/de.json b/src/lang/de.json index 31800739..cbe1af57 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -15,8 +15,9 @@ "DS4.HeadingSpells": "Zaubersprüche", "DS4.HeadingDescription": "Beschreibung", "DS4.HeadingSpecialCreatureAbilities": "Besondere Fähigkeiten", - "DS4.AttackType": "Angriffstyp", - "DS4.AttackTypeAbbr": "AT", + "DS4.AttackType": "Angriffsart", + "DS4.AttackTypeAbbr": "AA", + "DS4.AttackTypeSelection": "Welche Angriffsart?", "DS4.WeaponBonus": "Waffenbonus", "DS4.WeaponBonusAbbr": "WB", "DS4.OpponentDefense": "Gegnerabwehr", @@ -184,6 +185,10 @@ "DS4.ErrorDiceCritOverlap": "Es gibt eine Überlappung zwischen Patzern und Immersiegen.", "DS4.ErrorExplodingRecursionLimitExceeded": "Die maximale Rekursionstiefe für slayende Würfelwürfe wurde überschritten.", "DS4.ErrorDuringMigration": "Fehler während der Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion}. Der Fehler trat während der Ausführung des Migrationsskripts mit der Version {migrationVersion} auf. Spätere Migrationsskripte wurden nicht ausgeführt. Mehr Details finden Sie in der Entwicklerkonsole (F12).", + "DS4.ErrorCannotRollUnownedItem": "Für das Item '{name}' ({id}) kann nicht gewürfelt werden, da es keinem Aktor gehört.", + "DS4.ErrorRollingForItemTypeNotPossible": "Würfeln ist für items vom Typ '{type}' nicht möglich.", + "DS4.ErrorWrongItemType": "Ein Item vom Type '{expectedType}' wurde erwartet aber das Item '{name}' ({id}) ist vom Typ '{actualType}'.", + "DS4.ErrorUnexpectedAttackType": "Unerwartete Angriffsart '{actualType}', erwartete Angriffarten: {expectedTypes}", "DS4.InfoSystemUpdateStart": "Aktualisiere DS4 System von Migrationsversion {currentVersion} auf {targetVersion}. Bitte haben Sie etwas Geduld, schließen Sie nicht das Spiel und fahren Sie nicht den Server herunter.", "DS4.InfoSystemUpdateCompleted": "Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion} erfolgreich!", "DS4.UnitRounds": "Runden", @@ -200,9 +205,9 @@ "DS4.UnitKilometersAbbr": "km", "DS4.UnitCustom": "individuell", "DS4.UnitCustomAbbr": " ", + "DS4.GenericOkButton": "OK", + "DS4.GenericCancelButton": "Abbrechen", "DS4.RollDialogDefaultTitle": "Proben-Optionen", - "DS4.RollDialogOkButton": "OK", - "DS4.RollDialogCancelButton": "Abbrechen", "DS4.ErrorUnexpectedHtmlType": "Typfehler: Erwartet wurde '{exType}', tatsächlich erhalten wurde '{realType}'.", "DS4.ErrorCouldNotFindForm": "Konnte HTML Element '{htmlElement}' nicht finden.", "DS4.ErrorActorDoesNotHaveItem": "Der Aktor '{actor}' hat kein Item mit der ID '{id}'.", diff --git a/src/lang/en.json b/src/lang/en.json index 0894350b..f1436c41 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -17,6 +17,7 @@ "DS4.HeadingSpecialCreatureAbilities": "Special Abilities", "DS4.AttackType": "Attack Type", "DS4.AttackTypeAbbr": "AT", + "DS4.AttackTypeSelection": "Which Attack Type?", "DS4.WeaponBonus": "Weapon Bonus", "DS4.WeaponBonusAbbr": "WB", "DS4.OpponentDefense": "Opponent Defense", @@ -184,6 +185,10 @@ "DS4.ErrorDiceCritOverlap": "There's an overlap between Fumbles and Coups", "DS4.ErrorExplodingRecursionLimitExceeded": "Maximum recursion depth for exploding dice roll exceeded", "DS4.ErrorDuringMigration": "Error while migrating DS4 system from migration version {currentVersion} to {targetVersion}. The error occurred during execution of migration script with version {migrationVersion}. Later migrations have not been executed. For more details, please look at the development console (F12).", + "DS4.ErrorCannotRollUnownedItem": "Rolling for item '{name}' ({id})is not possible because it is not owned.", + "DS4.ErrorRollingForItemTypeNotPossible": "Rolling is not possible for items of type '{type}'.", + "DS4.ErrorWrongItemType": "Expected an item of type '{expectedType}' but item '{name}' ({id}) is of type '{actualType}'.", + "DS4.ErrorUnexpectedAttackType": "Unexpected attack type '{actualType}', expected it to be one of: {expectedTypes}", "DS4.InfoSystemUpdateStart": "Migrating DS4 system from migration version {currentVersion} to {targetVersion}. Please be patient and do not close your game or shut down your server.", "DS4.InfoSystemUpdateCompleted": "Migration of DS4 system from migration version {currentVersion} to {targetVersion} successful!", "DS4.UnitRounds": "Rounds", @@ -200,9 +205,9 @@ "DS4.UnitKilometersAbbr": "km", "DS4.UnitCustom": "Custom Unit", "DS4.UnitCustomAbbr": " ", + "DS4.GenericOkButton": "Ok", + "DS4.GenericCancelButton": "Cancel", "DS4.RollDialogDefaultTitle": "Roll Options", - "DS4.RollDialogOkButton": "Ok", - "DS4.RollDialogCancelButton": "Cancel", "DS4.ErrorUnexpectedHtmlType": "Type Error: Expected '{exType}' but got '{realType}'.", "DS4.ErrorCouldNotFindForm": "Could not find HTML element '{htmlElement}'.", "DS4.ErrorActorDoesNotHaveItem": "The actor '{actor}' does not have any item with the id '{id}'.", diff --git a/src/module/actor/sheets/actor-sheet.ts b/src/module/actor/sheets/actor-sheet.ts index aee139ff..e75f1be7 100644 --- a/src/module/actor/sheets/actor-sheet.ts +++ b/src/module/actor/sheets/actor-sheet.ts @@ -124,8 +124,7 @@ export class DS4ActorSheet extends ActorSheet> { html.find(".item-change").on("change", this._onItemChange.bind(this)); - // Rollable abilities. - html.find(".rollable").click(this._onRoll.bind(this)); + html.find(".rollable-item").on("click", this._onRoll.bind(this)); } /** @@ -239,17 +238,9 @@ export class DS4ActorSheet extends ActorSheet> { */ protected _onRoll(event: JQuery.ClickEvent): void { event.preventDefault(); - const element = event.currentTarget; - const dataset = element.dataset; - - if (dataset.roll) { - const roll = new Roll(dataset.roll, this.actor.data.data); - const label = dataset.label ? `Rolling ${dataset.label}` : ""; - roll.roll().toMessage({ - speaker: ChatMessage.getSpeaker({ actor: this.actor }), - flavor: label, - }); - } + const id = $(event.currentTarget).parents(".item").data("itemId"); + const item = this.actor.getOwnedItem(id); + item.roll(); } /** @override */ diff --git a/src/module/ds4.ts b/src/module/ds4.ts index c8243f4e..67d03724 100644 --- a/src/module/ds4.ts +++ b/src/module/ds4.ts @@ -8,7 +8,8 @@ import { DS4CreatureActorSheet } from "./actor/sheets/creature-sheet"; import { createCheckRoll } from "./rolls/check-factory"; import { registerSystemSettings } from "./settings"; import { migration } from "./migrations"; -import handlebarsHelpers from "./handlebars-helpers"; +import registerHandlebarsHelpers from "./handlebars/handlebars-helpers"; +import registerHandlebarsPartials from "./handlebars/handlebars-partials"; Hooks.once("init", async () => { console.log(`DS4 | Initializing the DS4 Game System\n${DS4.ASCII}`); @@ -44,37 +45,6 @@ Hooks.once("init", async () => { registerHandlebarsHelpers(); }); -async function registerHandlebarsPartials() { - const templatePaths = [ - "systems/ds4/templates/item/partials/sheet-header.hbs", - "systems/ds4/templates/item/partials/description.hbs", - "systems/ds4/templates/item/partials/details.hbs", - "systems/ds4/templates/item/partials/effects.hbs", - "systems/ds4/templates/item/partials/body.hbs", - "systems/ds4/templates/actor/partials/items-overview.hbs", - "systems/ds4/templates/actor/partials/talents-abilities-overview.hbs", - "systems/ds4/templates/actor/partials/spells-overview.hbs", - "systems/ds4/templates/actor/partials/overview-add-button.hbs", - "systems/ds4/templates/actor/partials/overview-control-buttons.hbs", - "systems/ds4/templates/actor/partials/attributes-traits.hbs", - "systems/ds4/templates/actor/partials/combat-values.hbs", - "systems/ds4/templates/actor/partials/profile.hbs", - "systems/ds4/templates/actor/partials/character-progression.hbs", - "systems/ds4/templates/actor/partials/special-creature-abilities-overview.hbs", - "systems/ds4/templates/actor/partials/character-inventory.hbs", - "systems/ds4/templates/actor/partials/creature-inventory.hbs", - "systems/ds4/templates/actor/partials/talent-rank-equation.hbs", - "systems/ds4/templates/actor/partials/item-list-header.hbs", - "systems/ds4/templates/actor/partials/item-list-entry.hbs", - "systems/ds4/templates/actor/partials/currency.hbs", - ]; - return loadTemplates(templatePaths); -} - -function registerHandlebarsHelpers() { - Object.entries(handlebarsHelpers).forEach(([key, helper]) => Handlebars.registerHelper(key, helper)); -} - /** * This function runs after game data has been requested and loaded from the servers, so entities exist */ diff --git a/src/module/handlebars-helpers.ts b/src/module/handlebars-helpers.ts deleted file mode 100644 index 95144da3..00000000 --- a/src/module/handlebars-helpers.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default { htmlToPlainText, isEmpty }; - -function htmlToPlainText(input: string | null | undefined): string | null | undefined { - if (!input) return; - return $(input).text(); -} - -function isEmpty(input: Array | null | undefined): boolean { - return (input?.length ?? 0) === 0; -} diff --git a/src/module/handlebars/handlebars-helpers.ts b/src/module/handlebars/handlebars-helpers.ts new file mode 100644 index 00000000..fef92681 --- /dev/null +++ b/src/module/handlebars/handlebars-helpers.ts @@ -0,0 +1,12 @@ +export default function registerHandlebarsHelpers(): void { + Object.entries(helpers).forEach(([key, helper]) => Handlebars.registerHelper(key, helper)); +} + +const helpers = { + htmlToPlainText: (input: string | null | undefined): string | null | undefined => { + if (!input) return; + return $(input).text(); + }, + + isEmpty: (input: Array | null | undefined): boolean => (input?.length ?? 0) === 0, +}; diff --git a/src/module/handlebars/handlebars-partials.ts b/src/module/handlebars/handlebars-partials.ts new file mode 100644 index 00000000..98248c33 --- /dev/null +++ b/src/module/handlebars/handlebars-partials.ts @@ -0,0 +1,26 @@ +export default async function registerHandlebarsPartials(): Promise { + const templatePaths = [ + "systems/ds4/templates/item/partials/sheet-header.hbs", + "systems/ds4/templates/item/partials/description.hbs", + "systems/ds4/templates/item/partials/details.hbs", + "systems/ds4/templates/item/partials/effects.hbs", + "systems/ds4/templates/item/partials/body.hbs", + "systems/ds4/templates/actor/partials/items-overview.hbs", + "systems/ds4/templates/actor/partials/talents-abilities-overview.hbs", + "systems/ds4/templates/actor/partials/spells-overview.hbs", + "systems/ds4/templates/actor/partials/overview-add-button.hbs", + "systems/ds4/templates/actor/partials/overview-control-buttons.hbs", + "systems/ds4/templates/actor/partials/attributes-traits.hbs", + "systems/ds4/templates/actor/partials/combat-values.hbs", + "systems/ds4/templates/actor/partials/profile.hbs", + "systems/ds4/templates/actor/partials/character-progression.hbs", + "systems/ds4/templates/actor/partials/special-creature-abilities-overview.hbs", + "systems/ds4/templates/actor/partials/character-inventory.hbs", + "systems/ds4/templates/actor/partials/creature-inventory.hbs", + "systems/ds4/templates/actor/partials/talent-rank-equation.hbs", + "systems/ds4/templates/actor/partials/item-list-header.hbs", + "systems/ds4/templates/actor/partials/item-list-entry.hbs", + "systems/ds4/templates/actor/partials/currency.hbs", + ]; + await loadTemplates(templatePaths); +} diff --git a/src/module/item/item-data.ts b/src/module/item/item-data.ts index 5afd83b3..c3cf9a96 100644 --- a/src/module/item/item-data.ts +++ b/src/module/item/item-data.ts @@ -32,10 +32,13 @@ type DS4LanguageData = DS4ItemDataHelper; type DS4AlphabetData = DS4ItemDataHelper; type DS4SpecialCreatureAbilityData = DS4ItemDataHelper; +export type AttackType = keyof typeof DS4["i18n"]["attackTypes"]; + interface DS4WeaponDataData extends DS4ItemDataDataBase, DS4ItemDataDataPhysical, DS4ItemDataDataEquipable { - attackType: "melee" | "ranged" | "meleeRanged"; + attackType: AttackType; weaponBonus: number; opponentDefense: number; + rollable?: boolean; } interface DS4ArmorDataData diff --git a/src/module/item/item.ts b/src/module/item/item.ts index 5c0a9f3d..cbea7431 100644 --- a/src/module/item/item.ts +++ b/src/module/item/item.ts @@ -1,4 +1,7 @@ -import { DS4ItemData } from "./item-data"; +import { DS4Actor } from "../actor/actor"; +import { DS4 } from "../config"; +import { createCheckRoll } from "../rolls/check-factory"; +import { AttackType, DS4ItemData } from "./item-data"; /** * The Item class for DS4 @@ -17,6 +20,9 @@ export class DS4Item extends Item { const data = this.data.data; data.rank.total = data.rank.base + data.rank.mod; } + if (this.data.type === "weapon") { + this.data.data.rollable = true; + } } isNonEquippedEuipable(): boolean { @@ -32,4 +38,78 @@ export class DS4Item extends Item { } return 1; } + + /** + * Roll a check for a action with this item. + */ + async roll(): Promise { + if (!this.isOwnedItem()) { + throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id })); + } + if (this.data.type === "weapon") { + await this.rollWeapon(); + } else { + throw new Error(game.i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.data.type })); + } + } + + private async rollWeapon(this: this & { readonly isOwned: true }): Promise { + if (!(this.data.type === "weapon")) { + throw new Error( + game.i18n.format("DS4.ErrorWrongItemType", { + actualType: this.data.type, + expectedType: "weapon", + id: this.id, + name: this.name, + }), + ); + } + + const owner = (this.actor as unknown) as DS4Actor; // TODO(types): Improve so that the concrete Actor type is known here + const weaponBonus = this.data.data.weaponBonus; + const combatValue = await this.getCombatValueKeyForAttackType(this.data.data.attackType); + const checkTargetValue = (owner.data.data.combatValues[combatValue].total as number) + weaponBonus; + await createCheckRoll(checkTargetValue, { rollMode: game.settings.get("core", "rollMode") }); // TODO: Get maxCritSuccess and minCritFailure from Actor once we store them there + } + + private async getCombatValueKeyForAttackType(attackType: AttackType): Promise<"meleeAttack" | "rangedAttack"> { + if (attackType === "meleeRanged") { + const { melee, ranged } = { ...DS4.i18n.attackTypes }; + const identifier = "attack-type-selection"; + const label = game.i18n.localize("DS4.AttackType"); + const answer = Dialog.prompt({ + title: game.i18n.localize("DS4.AttackTypeSelection"), + content: await renderTemplate("systems/ds4/templates/common/simple-select-form.hbs", { + label, + identifier, + options: { melee, ranged }, + }), + label: game.i18n.localize("DS4.GenericOkButton"), + callback: (html) => { + const selectedAttackType = html.find(`#${identifier}`).val(); + if (selectedAttackType !== "melee" && selectedAttackType !== "ranged") { + throw new Error( + game.i18n.format("DS4.ErrorUnexpectedAttackType", { + actualType: selectedAttackType, + expectedTypes: "'melee', 'ranged'", + }), + ); + } + return `${selectedAttackType}Attack` as const; + }, + render: () => undefined, // TODO(types): This is actually optional, remove when types are updated ) + options: { jQuery: true }, + }); + return answer; + } else { + return `${attackType}Attack` as const; + } + } + + /** + * Type-guarding variant to check if the item is owned. + */ + isOwnedItem(): this is this & { readonly isOwned: true } { + return this.isOwned; + } } diff --git a/src/module/rolls/check-factory.ts b/src/module/rolls/check-factory.ts index eb68789d..2b3556b7 100644 --- a/src/module/rolls/check-factory.ts +++ b/src/module/rolls/check-factory.ts @@ -138,7 +138,7 @@ async function askGmModifier( buttons: { ok: { icon: '', - label: game.i18n.localize("DS4.RollDialogOkButton"), + label: game.i18n.localize("DS4.GenericOkButton"), callback: (html) => { if (!("jquery" in html)) { throw new Error( @@ -160,7 +160,7 @@ async function askGmModifier( }, cancel: { icon: '', - label: game.i18n.localize("DS4.RollDialogCancelButton"), + label: game.i18n.localize("DS4.GenericCancelButton"), }, }, default: "ok", diff --git a/src/scss/components/_item_list.scss b/src/scss/components/_item_list.scss index afebd6cc..280a468d 100644 --- a/src/scss/components/_item_list.scss +++ b/src/scss/components/_item_list.scss @@ -60,6 +60,11 @@ background-position: center; background-repeat: no-repeat; background-size: 100%; + + &--rollable:hover { + background-image: url("../../../icons/svg/d20-black.svg") !important; + cursor: pointer; + } } &__editable { diff --git a/src/templates/actor/partials/item-list-entry.hbs b/src/templates/actor/partials/item-list-entry.hbs index f74093b6..46caecf5 100644 --- a/src/templates/actor/partials/item-list-entry.hbs +++ b/src/templates/actor/partials/item-list-entry.hbs @@ -17,7 +17,8 @@ {{/if}} {{!-- image --}} -
+
{{!-- amount --}} {{#if hasQuantity}} diff --git a/src/templates/common/simple-select-form.hbs b/src/templates/common/simple-select-form.hbs new file mode 100644 index 00000000..dc82f319 --- /dev/null +++ b/src/templates/common/simple-select-form.hbs @@ -0,0 +1,19 @@ +{{!-- +!-- Render a simple form with a single select element. It uses the default form classes of Foundry VTT. +!-- @param identifier: The identifier to use as id for the select element. Can be used to query the value later on. +!-- @param label: Text to display as the label for the select element. +!-- @param options: Key-value pairs that describe the options. The keys are used for the value attribute of the +options, the values are used as content. +--}} +
+
+ +
+ +
+
+
From 87205f6193c5352c474531819f2040e7b0917168 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 00:17:48 +0100 Subject: [PATCH 02/14] Fix typo --- src/lang/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lang/de.json b/src/lang/de.json index cbe1af57..11b879cc 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -186,7 +186,7 @@ "DS4.ErrorExplodingRecursionLimitExceeded": "Die maximale Rekursionstiefe für slayende Würfelwürfe wurde überschritten.", "DS4.ErrorDuringMigration": "Fehler während der Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion}. Der Fehler trat während der Ausführung des Migrationsskripts mit der Version {migrationVersion} auf. Spätere Migrationsskripte wurden nicht ausgeführt. Mehr Details finden Sie in der Entwicklerkonsole (F12).", "DS4.ErrorCannotRollUnownedItem": "Für das Item '{name}' ({id}) kann nicht gewürfelt werden, da es keinem Aktor gehört.", - "DS4.ErrorRollingForItemTypeNotPossible": "Würfeln ist für items vom Typ '{type}' nicht möglich.", + "DS4.ErrorRollingForItemTypeNotPossible": "Würfeln ist für Items vom Typ '{type}' nicht möglich.", "DS4.ErrorWrongItemType": "Ein Item vom Type '{expectedType}' wurde erwartet aber das Item '{name}' ({id}) ist vom Typ '{actualType}'.", "DS4.ErrorUnexpectedAttackType": "Unerwartete Angriffsart '{actualType}', erwartete Angriffarten: {expectedTypes}", "DS4.InfoSystemUpdateStart": "Aktualisiere DS4 System von Migrationsversion {currentVersion} auf {targetVersion}. Bitte haben Sie etwas Geduld, schließen Sie nicht das Spiel und fahren Sie nicht den Server herunter.", From b07ee31b38648db5f565a3b911d02b4fa06236a9 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 00:41:57 +0100 Subject: [PATCH 03/14] Add maximumCoupResult and minimumFumbleResult to actor data --- src/module/actor/actor-data.ts | 6 ++++++ src/module/actor/actor.ts | 3 +++ src/module/item/item.ts | 10 +++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/module/actor/actor-data.ts b/src/module/actor/actor-data.ts index 9f12ef3e..7fcb8398 100644 --- a/src/module/actor/actor-data.ts +++ b/src/module/actor/actor-data.ts @@ -17,6 +17,7 @@ interface DS4ActorDataDataBase { attributes: DS4ActorDataDataAttributes; traits: DS4ActorDataDataTraits; combatValues: DS4ActorDataDataCombatValues; + rolling: DS4ActorDataDataRolling; } interface DS4ActorDataDataAttributes { @@ -45,6 +46,11 @@ interface DS4ActorDataDataCombatValues { targetedSpellcasting: ModifiableData; } +interface DS4ActorDataDataRolling { + maximumCoupResult?: number; + minimumFumbleResult?: number; +} + interface DS4CharacterDataData extends DS4ActorDataDataBase { baseInfo: DS4CharacterDataDataBaseInfo; progression: DS4CharacterDataDataProgression; diff --git a/src/module/actor/actor.ts b/src/module/actor/actor.ts index 305ca04e..e28effdc 100644 --- a/src/module/actor/actor.ts +++ b/src/module/actor/actor.ts @@ -25,6 +25,9 @@ export class DS4Actor extends Actor { prepareBaseData(): void { const data = this.data; + data.data.rolling.minimumFumbleResult = 20; + data.data.rolling.maximumCoupResult = 1; + const attributes = data.data.attributes; Object.values(attributes).forEach( (attribute: ModifiableData) => (attribute.total = attribute.base + attribute.mod), diff --git a/src/module/item/item.ts b/src/module/item/item.ts index cbea7431..211f7720 100644 --- a/src/module/item/item.ts +++ b/src/module/item/item.ts @@ -65,11 +65,15 @@ export class DS4Item extends Item { ); } - const owner = (this.actor as unknown) as DS4Actor; // TODO(types): Improve so that the concrete Actor type is known here + const ownerDataData = ((this.actor as unknown) as DS4Actor).data.data; // TODO(types): Improve so that the concrete Actor type is known here const weaponBonus = this.data.data.weaponBonus; const combatValue = await this.getCombatValueKeyForAttackType(this.data.data.attackType); - const checkTargetValue = (owner.data.data.combatValues[combatValue].total as number) + weaponBonus; - await createCheckRoll(checkTargetValue, { rollMode: game.settings.get("core", "rollMode") }); // TODO: Get maxCritSuccess and minCritFailure from Actor once we store them there + const checkTargetValue = (ownerDataData.combatValues[combatValue].total as number) + weaponBonus; + await createCheckRoll(checkTargetValue, { + rollMode: game.settings.get("core", "rollMode"), + maxCritSuccess: ownerDataData.rolling.maximumCoupResult, + minCritFailure: ownerDataData.rolling.minimumFumbleResult, + }); } private async getCombatValueKeyForAttackType(attackType: AttackType): Promise<"meleeAttack" | "rangedAttack"> { From 68c20ccdc6a8852118cd585e0f1d379c18beb1c7 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 00:54:41 +0100 Subject: [PATCH 04/14] Fix Actor.data.data.rolling being undefined --- src/module/actor/actor.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/module/actor/actor.ts b/src/module/actor/actor.ts index e28effdc..0e4cbb0d 100644 --- a/src/module/actor/actor.ts +++ b/src/module/actor/actor.ts @@ -25,8 +25,10 @@ export class DS4Actor extends Actor { prepareBaseData(): void { const data = this.data; - data.data.rolling.minimumFumbleResult = 20; - data.data.rolling.maximumCoupResult = 1; + data.data.rolling = { + minimumFumbleResult: 20, + maximumCoupResult: 1, + }; const attributes = data.data.attributes; Object.values(attributes).forEach( From 74ad0c7f244a81a996b42c207ad2255d54e22b5f Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 01:54:51 +0100 Subject: [PATCH 05/14] Add possibility to roll spells from sheet adnrequire spells and weapons to be equipped to be rolled --- src/lang/de.json | 2 ++ src/lang/en.json | 2 ++ src/module/item/item-data.ts | 13 +++++-- src/module/item/item.ts | 69 ++++++++++++++++++++++++++++++++---- 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/src/lang/de.json b/src/lang/de.json index 11b879cc..e9b88887 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -189,6 +189,8 @@ "DS4.ErrorRollingForItemTypeNotPossible": "Würfeln ist für Items vom Typ '{type}' nicht möglich.", "DS4.ErrorWrongItemType": "Ein Item vom Type '{expectedType}' wurde erwartet aber das Item '{name}' ({id}) ist vom Typ '{actualType}'.", "DS4.ErrorUnexpectedAttackType": "Unerwartete Angriffsart '{actualType}', erwartete Angriffarten: {expectedTypes}", + "DS4.ErrorItemMustBeEquippedToBeRolled": "Um für das Item '{name}' ({id}) vom Typ {type} zu würfeln, muss es ausgerüstet sein.", + "DS4.InfoManuallyEnterSpellBonus": "Der korrekte Wert für den Zauberbonus '{spellBonus}' des Zaubers '{name}' musss manuell angegeben werden.", "DS4.InfoSystemUpdateStart": "Aktualisiere DS4 System von Migrationsversion {currentVersion} auf {targetVersion}. Bitte haben Sie etwas Geduld, schließen Sie nicht das Spiel und fahren Sie nicht den Server herunter.", "DS4.InfoSystemUpdateCompleted": "Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion} erfolgreich!", "DS4.UnitRounds": "Runden", diff --git a/src/lang/en.json b/src/lang/en.json index f1436c41..ec17658e 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -189,6 +189,8 @@ "DS4.ErrorRollingForItemTypeNotPossible": "Rolling is not possible for items of type '{type}'.", "DS4.ErrorWrongItemType": "Expected an item of type '{expectedType}' but item '{name}' ({id}) is of type '{actualType}'.", "DS4.ErrorUnexpectedAttackType": "Unexpected attack type '{actualType}', expected it to be one of: {expectedTypes}", + "DS4.ErrorItemMustBeEquippedToBeRolled": "To roll for item '{name}' ({id}) of type {type}, it needs to be equipped.", + "DS4.InfoManuallyEnterSpellBonus": "The correct value of the spell bons '{spellBonus}' of the spell '{name}' needs to be entered by manually.", "DS4.InfoSystemUpdateStart": "Migrating DS4 system from migration version {currentVersion} to {targetVersion}. Please be patient and do not close your game or shut down your server.", "DS4.InfoSystemUpdateCompleted": "Migration of DS4 system from migration version {currentVersion} to {targetVersion} successful!", "DS4.UnitRounds": "Rounds", diff --git a/src/module/item/item-data.ts b/src/module/item/item-data.ts index c3cf9a96..c28fbe86 100644 --- a/src/module/item/item-data.ts +++ b/src/module/item/item-data.ts @@ -34,11 +34,14 @@ type DS4SpecialCreatureAbilityData = DS4ItemDataHelper { max: number; } -interface DS4SpellDataData extends DS4ItemDataDataBase, DS4ItemDataDataEquipable { +interface DS4SpellDataData extends DS4ItemDataDataBase, DS4ItemDataDataEquipable, DS4ItemDataDataRollable { spellType: "spellcasting" | "targetedSpellcasting"; bonus: string; spellCategory: @@ -112,6 +115,10 @@ interface DS4ItemDataDataEquipable { equipped: boolean; } +interface DS4ItemDataDataRollable { + rollable?: boolean; +} + interface DS4ItemDataDataProtective { armorValue: number; } diff --git a/src/module/item/item.ts b/src/module/item/item.ts index 211f7720..52d5941b 100644 --- a/src/module/item/item.ts +++ b/src/module/item/item.ts @@ -1,6 +1,7 @@ import { DS4Actor } from "../actor/actor"; import { DS4 } from "../config"; import { createCheckRoll } from "../rolls/check-factory"; +import notifications from "../ui/notifications"; import { AttackType, DS4ItemData } from "./item-data"; /** @@ -20,8 +21,8 @@ export class DS4Item extends Item { const data = this.data.data; data.rank.total = data.rank.base + data.rank.mod; } - if (this.data.type === "weapon") { - this.data.data.rollable = true; + if (this.data.type === "weapon" || this.data.type === "spell") { + this.data.data.rollable = this.data.data.equipped; } } @@ -46,10 +47,14 @@ export class DS4Item extends Item { if (!this.isOwnedItem()) { throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id })); } - if (this.data.type === "weapon") { - await this.rollWeapon(); - } else { - throw new Error(game.i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.data.type })); + + switch (this.data.type) { + case "weapon": + await this.rollWeapon(); + case "spell": + await this.rollSpell(); + default: + throw new Error(game.i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.data.type })); } } @@ -65,6 +70,16 @@ export class DS4Item extends Item { ); } + if (!this.data.data.equipped) { + throw new Error( + game.i18n.format("DS4.ErrorItemMustBeEquippedToBeRolled", { + name: this.name, + id: this.id, + type: this.data.type, + }), + ); + } + const ownerDataData = ((this.actor as unknown) as DS4Actor).data.data; // TODO(types): Improve so that the concrete Actor type is known here const weaponBonus = this.data.data.weaponBonus; const combatValue = await this.getCombatValueKeyForAttackType(this.data.data.attackType); @@ -76,6 +91,48 @@ export class DS4Item extends Item { }); } + private async rollSpell(): Promise { + if (!(this.data.type === "spell")) { + throw new Error( + game.i18n.format("DS4.ErrorWrongItemType", { + actualType: this.data.type, + expectedType: "spell", + id: this.id, + name: this.name, + }), + ); + } + + if (!this.data.data.equipped) { + throw new Error( + game.i18n.format("DS4.ErrorItemMustBeEquippedToBeRolled", { + name: this.name, + id: this.id, + type: this.data.type, + }), + ); + } + + const ownerDataData = ((this.actor as unknown) as DS4Actor).data.data; // TODO(types): Improve so that the concrete Actor type is known here + const spellBonus = Number.isNumeric(this.data.data.bonus) ? parseInt(this.data.data.bonus) : undefined; + if (spellBonus === undefined) { + notifications.info( + game.i18n.format("DS4.InfoManuallyEnterSpellBonus", { + name: this.name, + spellBonus: this.data.data.bonus, + }), + ); + } + const spellType = this.data.data.spellType; + const checkTargetValue = (ownerDataData.combatValues[spellType].total as number) + (spellBonus ?? 0); + + await createCheckRoll(checkTargetValue, { + rollMode: game.settings.get("core", "rollMode"), + maxCritSuccess: ownerDataData.rolling.maximumCoupResult, + minCritFailure: ownerDataData.rolling.minimumFumbleResult, + }); + } + private async getCombatValueKeyForAttackType(attackType: AttackType): Promise<"meleeAttack" | "rangedAttack"> { if (attackType === "meleeRanged") { const { melee, ranged } = { ...DS4.i18n.attackTypes }; From ea4f1d3ee7ca9023517a98762f844775979a4a71 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 08:51:13 +0100 Subject: [PATCH 06/14] use img tags instead of divs with background-image set --- src/ds4.scss | 1 + src/lang/de.json | 3 ++ src/lang/en.json | 3 ++ src/module/handlebars/handlebars-partials.ts | 1 + src/scss/components/_item_list.scss | 34 +++++++++-------- src/scss/components/_rollable_image.scss | 37 +++++++++++++++++++ .../actor/partials/item-list-entry.hbs | 7 ++-- .../actor/partials/items-overview.hbs | 6 +-- .../partials/overview-control-buttons.hbs | 6 ++- .../actor/partials/spells-overview.hbs | 6 +-- .../common/partials/rollable-image.hbs | 17 +++++++++ 11 files changed, 92 insertions(+), 29 deletions(-) create mode 100644 src/scss/components/_rollable_image.scss create mode 100644 src/templates/common/partials/rollable-image.hbs diff --git a/src/ds4.scss b/src/ds4.scss index 212a180f..9ee0c00f 100644 --- a/src/ds4.scss +++ b/src/ds4.scss @@ -21,4 +21,5 @@ @include meta.load-css("scss/components/tabs"); @include meta.load-css("scss/components/talent_rank_equation"); @include meta.load-css("scss/components/currency"); + @include meta.load-css("scss/components/rollable_image"); } diff --git a/src/lang/de.json b/src/lang/de.json index e9b88887..d7914d30 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -5,6 +5,9 @@ "DS4.UserInteractionAddEffect": "Neuer Effekt", "DS4.UserInteractionEditEffect": "Effekt bearbeiten", "DS4.UserInteractionDeleteEffect": "Effekt löschen", + "DS4.EntityImageAltText": "Bild von {name}", + "DS4.RollableImageRollableTitle": "Für {name} würfeln", + "DS4.DiceOverlayImageAltText": "Bild eines W20", "DS4.NotOwned": "Nicht besessen", "DS4.HeadingBiography": "Biografie", "DS4.HeadingDetails": "Details", diff --git a/src/lang/en.json b/src/lang/en.json index ec17658e..3f556f42 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -5,6 +5,9 @@ "DS4.UserInteractionAddEffect": "Add Effect", "DS4.UserInteractionEditEffect": "Edit Effect", "DS4.UserInteractionDeleteEffect": "Delete Effect", + "DS4.EntityImageAltText": "Image of {name}", + "DS4.RollableImageRollableTitle": "Roll for {name}", + "DS4.DiceOverlayImageAltText": "Image of a d20", "DS4.NotOwned": "No owner", "DS4.HeadingBiography": "Biography", "DS4.HeadingDetails": "Details", diff --git a/src/module/handlebars/handlebars-partials.ts b/src/module/handlebars/handlebars-partials.ts index 98248c33..81945ebc 100644 --- a/src/module/handlebars/handlebars-partials.ts +++ b/src/module/handlebars/handlebars-partials.ts @@ -21,6 +21,7 @@ export default async function registerHandlebarsPartials(): Promise { "systems/ds4/templates/actor/partials/item-list-header.hbs", "systems/ds4/templates/actor/partials/item-list-entry.hbs", "systems/ds4/templates/actor/partials/currency.hbs", + "systems/ds4/templates/common/partials/rollable-image.hbs", ]; await loadTemplates(templatePaths); } diff --git a/src/scss/components/_item_list.scss b/src/scss/components/_item_list.scss index 280a468d..eb4c745f 100644 --- a/src/scss/components/_item_list.scss +++ b/src/scss/components/_item_list.scss @@ -15,31 +15,31 @@ padding: 0; &--weapon { - grid-template-columns: $row-height $row-height 3ch 3fr $row-height 1fr 3ch 5fr 4ch; + grid-template-columns: $row-height $row-height 3ch 3fr $row-height 1fr 3ch 5fr 5ch; } &--armor { - grid-template-columns: $row-height $row-height 3ch 3fr 1fr 1fr 3ch 5fr 4ch; + grid-template-columns: $row-height $row-height 3ch 3fr 1fr 1fr 3ch 5fr 5ch; } &--shield { - grid-template-columns: $row-height $row-height 3ch 1fr 3ch 3fr 4ch; + grid-template-columns: $row-height $row-height 3ch 1fr 3ch 3fr 5ch; } &--equipment { - grid-template-columns: $row-height $row-height 3ch 1fr 10ch 3fr 4ch; + grid-template-columns: $row-height $row-height 3ch 1fr 10ch 3fr 5ch; } &--loot { - grid-template-columns: $row-height 3ch 1fr 10ch 3fr 4ch; + grid-template-columns: $row-height 3ch 1fr 10ch 3fr 5ch; } &--spell { - grid-template-columns: $row-height $row-height 2fr $row-height 1fr 1fr 1fr 1fr 4ch; + grid-template-columns: $row-height $row-height 2fr $row-height 1fr 1fr 1fr 1fr 5ch; } &--talent { - grid-template-columns: $row-height 1fr 1fr 3fr 4ch; + grid-template-columns: $row-height 1fr 1fr 3fr 5ch; } &--racial-ability, &--language, &--alphabet, &--special-creature-ability { - grid-template-columns: $row-height 1fr 3fr 4ch; + grid-template-columns: $row-height 1fr 3fr 5ch; } &__row { @@ -53,18 +53,12 @@ height: $row-height; line-height: $row-height; white-space: nowrap; + overflow-y: hidden; } } &__image { - background-position: center; - background-repeat: no-repeat; - background-size: 100%; - - &--rollable:hover { - background-image: url("../../../icons/svg/d20-black.svg") !important; - cursor: pointer; - } + border: none; } &__editable { @@ -94,6 +88,14 @@ text-overflow: ellipsis; } } + + &__control-buttons { + display: grid; + grid-template-columns: 1fr 1fr; + text-align: center; + width: 100%; + padding: 0 calc(1em / 3); + } } .ds4-item-list-title { diff --git a/src/scss/components/_rollable_image.scss b/src/scss/components/_rollable_image.scss new file mode 100644 index 00000000..ae814f8a --- /dev/null +++ b/src/scss/components/_rollable_image.scss @@ -0,0 +1,37 @@ +@use "../utils/colors"; + +.ds4-rollable-image { + position: relative; + + &--rollable { + cursor: pointer; + + &:hover { + .ds4-rollable-image__image { + opacity: 0.25; + } + + .ds4-rollable-image__overlay { + opacity: 1; + } + } + } + + &__image { + border: none; + transition: 0.1s ease; + } + + &__overlay { + border: none; + bottom: 0; + height: 100%; + left: 0; + opacity: 0; + position: absolute; + right: 0; + top: 0; + transition: 0.1s ease; + width: 100%; + } +} diff --git a/src/templates/actor/partials/item-list-entry.hbs b/src/templates/actor/partials/item-list-entry.hbs index 46caecf5..ca08d0fc 100644 --- a/src/templates/actor/partials/item-list-entry.hbs +++ b/src/templates/actor/partials/item-list-entry.hbs @@ -17,8 +17,9 @@ {{/if}} {{!-- image --}} -
+ {{> systems/ds4/templates/common/partials/rollable-image.hbs rollable=itemData.data.rollable src=itemData.img + alt=(localize "DS4.EntityImageAltText" name=itemData.name) title=itemData.name rollableTitle=(localize + "DS4.RollableImageRollableTitle" name=itemData.name) rollableClass="rollable-item"}} {{!-- amount --}} {{#if hasQuantity}} @@ -42,5 +43,5 @@ {{/unless}} {{!-- control buttons --}} - {{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }} + {{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs class="ds4-item-list__control-buttons" }} diff --git a/src/templates/actor/partials/items-overview.hbs b/src/templates/actor/partials/items-overview.hbs index c3544805..094109b1 100644 --- a/src/templates/actor/partials/items-overview.hbs +++ b/src/templates/actor/partials/items-overview.hbs @@ -20,10 +20,8 @@ {{#each itemsByType.weapon as |itemData id|}} {{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData isEquipable=true hasQuantity=true}} {{!-- attack type --}} -
-
+ {{!-- weapon bonus --}}
{{ itemData.data.weaponBonus}}
diff --git a/src/templates/actor/partials/overview-control-buttons.hbs b/src/templates/actor/partials/overview-control-buttons.hbs index 2c85899f..ac7177b2 100644 --- a/src/templates/actor/partials/overview-control-buttons.hbs +++ b/src/templates/actor/partials/overview-control-buttons.hbs @@ -1,8 +1,10 @@ {{!-- !-- Render a group of an "edit" and a "delete" button for the current item. !-- The current item is defined by the data-item-id HTML property of the parent li element. +!-- @param class: Additional CSS class(es) for the controls --}} -
+
- +
diff --git a/src/templates/actor/partials/spells-overview.hbs b/src/templates/actor/partials/spells-overview.hbs index e9861c77..e5f9b008 100644 --- a/src/templates/actor/partials/spells-overview.hbs +++ b/src/templates/actor/partials/spells-overview.hbs @@ -60,10 +60,8 @@ titleKey=titleKey}} {{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData isEquipable=true hideDescription=true}} {{!-- spell type --}} -
-
+ {{!-- spell bonus --}} + {{alt}} + {{#if rollable}} + {{localize 'DS4.DiceOverlayImageAltText'}} + {{/if}} +
From bec0c15d520c514137778fc877c9a704b9bf560e Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 08:55:33 +0100 Subject: [PATCH 07/14] Fix typo --- src/templates/common/partials/rollable-image.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/common/partials/rollable-image.hbs b/src/templates/common/partials/rollable-image.hbs index 6571c653..08abc7d1 100644 --- a/src/templates/common/partials/rollable-image.hbs +++ b/src/templates/common/partials/rollable-image.hbs @@ -1,5 +1,5 @@ {{!-- -!-- Render an an image that has a dice overlay image. +!-- Render an image that has a dice overlay image. !-- @param rollable: A flag indicating whether or not the image is actually rollable. !-- @param rollableClass: The CSS class(es) to add if the image is rollable. !-- @param title: The title for the rollable image if it is not actually rollable. From dabcf885a6e18fe7a09a29aa753afe70ec26f6d3 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 08:57:43 +0100 Subject: [PATCH 08/14] Remove unsued @use --- src/scss/components/_rollable_image.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/scss/components/_rollable_image.scss b/src/scss/components/_rollable_image.scss index ae814f8a..fc27d8a4 100644 --- a/src/scss/components/_rollable_image.scss +++ b/src/scss/components/_rollable_image.scss @@ -1,5 +1,3 @@ -@use "../utils/colors"; - .ds4-rollable-image { position: relative; From b811e7ccfe1e7e05c9ff28b222bbe0e04e378445 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 09:04:33 +0100 Subject: [PATCH 09/14] Remove unnecessary css properties --- src/scss/components/_rollable_image.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/scss/components/_rollable_image.scss b/src/scss/components/_rollable_image.scss index fc27d8a4..ba33bca7 100644 --- a/src/scss/components/_rollable_image.scss +++ b/src/scss/components/_rollable_image.scss @@ -23,13 +23,11 @@ &__overlay { border: none; bottom: 0; - height: 100%; left: 0; opacity: 0; position: absolute; right: 0; top: 0; transition: 0.1s ease; - width: 100%; } } From 71eedaf080513661cacf9c5e7c63d2e40b027880 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 09:19:11 +0100 Subject: [PATCH 10/14] Only try to roll for the given item type --- src/module/item/item.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/module/item/item.ts b/src/module/item/item.ts index 52d5941b..c871685c 100644 --- a/src/module/item/item.ts +++ b/src/module/item/item.ts @@ -50,9 +50,9 @@ export class DS4Item extends Item { switch (this.data.type) { case "weapon": - await this.rollWeapon(); + return this.rollWeapon(); case "spell": - await this.rollSpell(); + return this.rollSpell(); default: throw new Error(game.i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.data.type })); } From f7c18dc702505e959c8348d3e73d37c29df14e94 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 4 Mar 2021 10:00:46 +0100 Subject: [PATCH 11/14] Make private methods protected --- src/module/item/item.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/module/item/item.ts b/src/module/item/item.ts index c871685c..ac9b90cd 100644 --- a/src/module/item/item.ts +++ b/src/module/item/item.ts @@ -58,7 +58,7 @@ export class DS4Item extends Item { } } - private async rollWeapon(this: this & { readonly isOwned: true }): Promise { + protected async rollWeapon(this: this & { readonly isOwned: true }): Promise { if (!(this.data.type === "weapon")) { throw new Error( game.i18n.format("DS4.ErrorWrongItemType", { @@ -91,7 +91,7 @@ export class DS4Item extends Item { }); } - private async rollSpell(): Promise { + protected async rollSpell(): Promise { if (!(this.data.type === "spell")) { throw new Error( game.i18n.format("DS4.ErrorWrongItemType", { @@ -133,7 +133,7 @@ export class DS4Item extends Item { }); } - private async getCombatValueKeyForAttackType(attackType: AttackType): Promise<"meleeAttack" | "rangedAttack"> { + protected async getCombatValueKeyForAttackType(attackType: AttackType): Promise<"meleeAttack" | "rangedAttack"> { if (attackType === "meleeRanged") { const { melee, ranged } = { ...DS4.i18n.attackTypes }; const identifier = "attack-type-selection"; From 9eb1e34850053a5ab83f3feeea12bde02af3d542 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Sun, 7 Mar 2021 18:42:08 +0100 Subject: [PATCH 12/14] Apply 1 suggestion(s) to 1 file(s) --- src/lang/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lang/de.json b/src/lang/de.json index d7914d30..3e2c0ae9 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -192,7 +192,7 @@ "DS4.ErrorRollingForItemTypeNotPossible": "Würfeln ist für Items vom Typ '{type}' nicht möglich.", "DS4.ErrorWrongItemType": "Ein Item vom Type '{expectedType}' wurde erwartet aber das Item '{name}' ({id}) ist vom Typ '{actualType}'.", "DS4.ErrorUnexpectedAttackType": "Unerwartete Angriffsart '{actualType}', erwartete Angriffarten: {expectedTypes}", - "DS4.ErrorItemMustBeEquippedToBeRolled": "Um für das Item '{name}' ({id}) vom Typ {type} zu würfeln, muss es ausgerüstet sein.", + "DS4.ErrorItemMustBeEquippedToBeRolled": "Um für das Item '{name}' ({id}) vom Typ '{type}' zu würfeln, muss es ausgerüstet sein.", "DS4.InfoManuallyEnterSpellBonus": "Der korrekte Wert für den Zauberbonus '{spellBonus}' des Zaubers '{name}' musss manuell angegeben werden.", "DS4.InfoSystemUpdateStart": "Aktualisiere DS4 System von Migrationsversion {currentVersion} auf {targetVersion}. Bitte haben Sie etwas Geduld, schließen Sie nicht das Spiel und fahren Sie nicht den Server herunter.", "DS4.InfoSystemUpdateCompleted": "Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion} erfolgreich!", From d656d89d6c5610603e104a9fd95d26de352d10e9 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Sun, 7 Mar 2021 18:42:11 +0100 Subject: [PATCH 13/14] Apply 1 suggestion(s) to 1 file(s) --- src/lang/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lang/en.json b/src/lang/en.json index 3f556f42..056091c6 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -192,7 +192,7 @@ "DS4.ErrorRollingForItemTypeNotPossible": "Rolling is not possible for items of type '{type}'.", "DS4.ErrorWrongItemType": "Expected an item of type '{expectedType}' but item '{name}' ({id}) is of type '{actualType}'.", "DS4.ErrorUnexpectedAttackType": "Unexpected attack type '{actualType}', expected it to be one of: {expectedTypes}", - "DS4.ErrorItemMustBeEquippedToBeRolled": "To roll for item '{name}' ({id}) of type {type}, it needs to be equipped.", + "DS4.ErrorItemMustBeEquippedToBeRolled": "To roll for item '{name}' ({id}) of type '{type}', it needs to be equipped.", "DS4.InfoManuallyEnterSpellBonus": "The correct value of the spell bons '{spellBonus}' of the spell '{name}' needs to be entered by manually.", "DS4.InfoSystemUpdateStart": "Migrating DS4 system from migration version {currentVersion} to {targetVersion}. Please be patient and do not close your game or shut down your server.", "DS4.InfoSystemUpdateCompleted": "Migration of DS4 system from migration version {currentVersion} to {targetVersion} successful!", From fac9bfdf396423f601421429ff1e3a18de64541a Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Sun, 7 Mar 2021 19:01:58 +0100 Subject: [PATCH 14/14] Fix problem with talent rank column --- src/scss/components/_item_list.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scss/components/_item_list.scss b/src/scss/components/_item_list.scss index eb4c745f..dfa69c5c 100644 --- a/src/scss/components/_item_list.scss +++ b/src/scss/components/_item_list.scss @@ -33,7 +33,7 @@ grid-template-columns: $row-height $row-height 2fr $row-height 1fr 1fr 1fr 1fr 5ch; } &--talent { - grid-template-columns: $row-height 1fr 1fr 3fr 5ch; + grid-template-columns: $row-height 1fr 21ch 3fr 5ch; } &--racial-ability, &--language,