diff --git a/package-lock.json b/package-lock.json index 65951b1d..3c38cde2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2717,7 +2717,7 @@ } }, "foundry-pc-types": { - "version": "git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#f84074f63d1aeeb9229e441e8c3ccaa9cba64142", + "version": "git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#5fcca4e4327b558d5eeeb962f05470c994a394be", "from": "git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#f3l-fixes", "dev": true, "requires": { diff --git a/src/lang/de.json b/src/lang/de.json index a457b768..118ec7bb 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -56,6 +56,8 @@ "DS4.ItemTypeLanguagePlural": "Sprachen", "DS4.ItemTypeAlphabet": "Schriftzeichen", "DS4.ItemTypeAlphabetPlural": "Schriftzeichen", + "DS4.ItemTypeSpecialCreatureAbility": "Besondere Kreaturefähigkeit", + "DS4.ItemTypeSpecialCreatureAbilityPlural": "Besondere Kreaturefähigkeiten", "DS4.ArmorType": "Panzerungstyp", "DS4.ArmorTypeAbbr": "PAT", "DS4.ArmorMaterialType": "Material Typ", @@ -133,6 +135,7 @@ "DS4.TalentRankTotal": "Gesamter Rang", "DS4.CharacterLanguageLanguages": "Sprachen", "DS4.CharacterLanguageAlphabets": "Schriftzeichen", + "DS4.SpecialCreatureAbilityExperiencePoints": "Erfahrungspunkte", "DS4.CharacterProfileBiography": "Biographie", "DS4.CharacterProfileGender": "Geschlecht", "DS4.CharacterProfileBirthday": "Geburtstag", @@ -162,6 +165,7 @@ "DS4.CreatureBaseInfoExperiencePoints": "Erfahrungspunkte", "DS4.CreatureBaseInfoDescription": "Beschreibung", "DS4.WarningManageActiveEffectOnOwnedItem": "Das Verwalten von aktiven Effekten innerhalb eines besessen Items wird derzeit nicht unterstützt und wird in einem nachfolgenden Update hinzugefügt.", + "DS4.WarningActorCannotOwnItem": "Der Aktor '{actorName}' vom Typ '{actorType}' kann das Item '{itemName}' vom Typ '{itemType}' nicht besitzen.", "DS4.ErrorDiceCritOverlap": "Es gibt eine Überlappung zwischen Patzern und Immersiegen.", "DS4.ErrorExplodingRecursionLimitExceeded": "Die maximale Rekursionstiefe für slayende Würfelwürfe wurde überschritten.", "DS4.UnitRounds": "Runden", diff --git a/src/lang/en.json b/src/lang/en.json index 50ef84c6..4a587075 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -56,6 +56,8 @@ "DS4.ItemTypeLanguagePlural": "Languages", "DS4.ItemTypeAlphabet": "Alphabet", "DS4.ItemTypeAlphabetPlural": "Alphabets", + "DS4.ItemTypeSpecialCreatureAbility": "Special Creature Ability", + "DS4.ItemTypeSpecialCreatureAbilityPlural": "Special Creature Abilities", "DS4.ArmorType": "Armor Type", "DS4.ArmorTypeAbbr": "AT", "DS4.ArmorMaterialType": "Material Type", @@ -133,6 +135,7 @@ "DS4.TalentRankTotal": "Total Ranks", "DS4.CharacterLanguageLanguages": "Languages", "DS4.CharacterLanguageAlphabets": "Alphabets", + "DS4.SpecialCreatureAbilityExperiencePoints": "Experience Points", "DS4.CharacterProfileBiography": "Biography", "DS4.CharacterProfileGender": "Gender", "DS4.CharacterProfileBirthday": "Birthday", @@ -162,6 +165,7 @@ "DS4.CreatureBaseInfoExperiencePoints": "Experience Points", "DS4.CreatureBaseInfoDescription": "Description", "DS4.WarningManageActiveEffectOnOwnedItem": "Managing Active Effects within an Owned Item is not currently supported and will be added in a subsequent update.", + "DS4.WarningActorCannotOwnItem": "The actor '{actorName}' of type '{actorType}' cannot own the item '{itemName}' of type '{itemType}'.", "DS4.ErrorDiceCritOverlap": "There's an overlap between Fumbles and Coups", "DS4.ErrorExplodingRecursionLimitExceeded": "Maximum recursion depth for exploding dice roll exceeded", "DS4.UnitRounds": "Rounds", diff --git a/src/module/actor/actor-data.ts b/src/module/actor/actor-data.ts index edacb2c2..20c26741 100644 --- a/src/module/actor/actor-data.ts +++ b/src/module/actor/actor-data.ts @@ -1,21 +1,10 @@ +import { ModifiableData, ResourceData, UsableResource } from "../common/common-data"; +import { DS4 } from "../config"; + +export type ActorType = keyof typeof DS4.actorTypes; + export type DS4ActorDataType = DS4ActorDataCharacter | DS4ActorDataCreature; -export interface ModifiableData { - base: T; - mod: T; - total?: T; -} - -interface ResourceData extends ModifiableData { - value: T; - max?: T; -} - -interface UsableResource { - total: T; - used: T; -} - interface DS4ActorDataBase { attributes: DS4ActorDataAttributes; traits: DS4ActorDataTraits; diff --git a/src/module/actor/actor-sheet.ts b/src/module/actor/actor-sheet.ts index 3e711d30..d8a3b6dc 100644 --- a/src/module/actor/actor-sheet.ts +++ b/src/module/actor/actor-sheet.ts @@ -1,4 +1,5 @@ -import { DS4ItemDataType } from "../item/item-data"; +import { DS4Item } from "../item/item"; +import { DS4ItemDataType, ItemType } from "../item/item-data"; import { DS4Actor } from "./actor"; import { DS4ActorDataType } from "./actor-data"; @@ -207,4 +208,26 @@ export class DS4ActorSheet extends ActorSheet { + const data = JSON.parse(event.dataTransfer?.getData("text/plain")) as { type?: string }; + if (data.type === "Item") { + const item = await Item.fromDropData(data as Parameters[0]); + if (item && !this.actor.canOwnItemType(item.data.type as ItemType)) { + ui.notifications.warn( + game.i18n.format("DS4.WarningActorCannotOwnItem", { + actorName: this.actor.name, + actorType: this.actor.data.type, + itemName: item.name, + itemType: item.data.type, + }), + ); + return false; + } + } + super._onDrop(event); + } } diff --git a/src/module/actor/actor.ts b/src/module/actor/actor.ts index 7f2f8209..9d4ac8e0 100644 --- a/src/module/actor/actor.ts +++ b/src/module/actor/actor.ts @@ -1,6 +1,7 @@ +import { ModifiableData } from "../common/common-data"; import { DS4Item } from "../item/item"; -import { DS4ItemDataType } from "../item/item-data"; -import { DS4ActorDataType, ModifiableData } from "./actor-data"; +import { DS4ItemDataType, ItemType } from "../item/item-data"; +import { DS4ActorDataType } from "./actor-data"; export class DS4Actor extends Actor { /** @override */ @@ -21,4 +22,37 @@ export class DS4Actor extends Actor combatValues.hitPoints.max = combatValues.hitPoints.total; } + + /** + * The list of item types that can be owned by this actor. + */ + get ownableItemTypes(): Array { + switch (this.data.type) { + case "character": + return [ + "weapon", + "armor", + "shield", + "spell", + "trinket", + "equipment", + "talent", + "racialAbility", + "language", + "alphabet", + ]; + case "creature": + return ["weapon", "armor", "spell", "specialCreatureAbility"]; + default: + []; + } + } + + /** + * Checks whether or not the given item type can be owned by the actor. + * @param itemType the item type to check + */ + canOwnItemType(itemType: ItemType): boolean { + return this.ownableItemTypes.includes(itemType); + } } diff --git a/src/module/common/common-data.ts b/src/module/common/common-data.ts new file mode 100644 index 00000000..41bfc3c4 --- /dev/null +++ b/src/module/common/common-data.ts @@ -0,0 +1,15 @@ +export interface ModifiableData { + base: T; + mod: T; + total?: T; +} + +export interface ResourceData extends ModifiableData { + value: T; + max?: T; +} + +export interface UsableResource { + total: T; + used: T; +} diff --git a/src/module/config.ts b/src/module/config.ts index 0f977d84..9d3dcc8c 100644 --- a/src/module/config.ts +++ b/src/module/config.ts @@ -61,6 +61,7 @@ export const DS4 = { racialAbility: "DS4.ItemTypeRacialAbility", language: "DS4.ItemTypeLanguage", alphabet: "DS4.ItemTypeAlphabet", + specialCreatureAbility: "DS4.ItemTypeSpecialCreatureAbility", }, /** diff --git a/src/module/item/item-data.ts b/src/module/item/item-data.ts index 45622a6e..64ee17f2 100644 --- a/src/module/item/item-data.ts +++ b/src/module/item/item-data.ts @@ -1,4 +1,7 @@ -import { ModifiableData } from "../actor/actor-data"; +import { ModifiableData } from "../common/common-data"; +import { DS4 } from "../config"; + +export type ItemType = keyof typeof DS4.itemTypes; export type DS4ItemDataType = | DS4Weapon @@ -10,7 +13,8 @@ export type DS4ItemDataType = | DS4Talent | DS4RacialAbility | DS4Language - | DS4Alphabet; + | DS4Alphabet + | DS4SpecialCreatureAbility; // types @@ -59,6 +63,9 @@ interface DS4Equipment extends DS4ItemBase, DS4ItemPhysical {} type DS4RacialAbility = DS4ItemBase; type DS4Language = DS4ItemBase; type DS4Alphabet = DS4ItemBase; +interface DS4SpecialCreatureAbility extends DS4ItemBase { + experiencePoints: number; +} // templates diff --git a/src/template.json b/src/template.json index 9354acdb..ca9b4ee5 100644 --- a/src/template.json +++ b/src/template.json @@ -136,7 +136,8 @@ "talent", "racialAbility", "language", - "alphabet" + "alphabet", + "specialCreatureAbility" ], "templates": { "base": { @@ -214,6 +215,10 @@ "unit": "custom" }, "scrollPrice": 0 + }, + "specialCreatureAbility": { + "templates": ["base"], + "experiencePoints": 0 } } } diff --git a/src/templates/actor/partials/profile.hbs b/src/templates/actor/partials/profile.hbs index ea62c70a..be95eeb5 100644 --- a/src/templates/actor/partials/profile.hbs +++ b/src/templates/actor/partials/profile.hbs @@ -1,7 +1,7 @@
{{#each data.profile as |profile-data-value profile-data-key|}} - {{#if (neq profile-data-key 'biography')}} + {{#if (ne profile-data-key 'biography')}}