Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add inventor first level abilities #52

Merged
merged 1 commit into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/domain/entities/Ability/TriggeredEffectActivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ export type BulwarkActivation = {
effectName: TriggeredEffectName.bulwark;
};

export type IngenuityActivation = {
effectName: TriggeredEffectName.ingenuity;
};

export type TriggeredEffectActivation =
| SpecialAttackActivation
| AudacityActivation
| BulwarkActivation;
| BulwarkActivation
| IngenuityActivation;
1 change: 1 addition & 0 deletions src/domain/entities/Ability/TriggeredEffectName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export enum TriggeredEffectName {
specialAttack = 'specialAttack',
audacity = 'audacity',
bulwark = 'bulwark',
ingenuity = 'ingenuity',
}
14 changes: 14 additions & 0 deletions src/domain/entities/Inventory/Equipment/Equipment.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import {type CharacterModifiers} from '../../Character/CharacterModifiers';
import {type SerializedSheetEquipment} from '../../Sheet';
import {type EquipmentImprovement} from './EquipmentImprovement/EquipmentImprovement';
import {EquipmentImprovementCategory} from './EquipmentImprovement/EquipmentImprovementCategory';
import type {EquipmentName} from './EquipmentName';

export abstract class Equipment<T extends EquipmentName = EquipmentName> {
readonly improvements: EquipmentImprovement[] = [];
abstract readonly name: T;
abstract readonly isWieldable: boolean;
// eslint-disable-next-line @typescript-eslint/ban-types
abstract readonly categoryForImprovement: EquipmentImprovementCategory | null;

addImprovement(improvement: EquipmentImprovement): void {
if (improvement.category !== EquipmentImprovementCategory.all
&& improvement.category !== this.categoryForImprovement) {
throw new Error(`Improvement ${improvement.name} is not compatible with ${this.name}`);
}

this.improvements.push(improvement);
}

serialize(): SerializedSheetEquipment<T> {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Equipment} from '../Equipment';
import type {EquipmentName} from '../EquipmentName';

export class EquipmentAdventure extends Equipment {
override categoryForImprovement = null;
constructor(
readonly name: EquipmentName,
readonly isWieldable = false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {Equipment} from '../Equipment';
import {type EquipmentAlchemicCategory} from './EquipmentAlchemicCategory';

export abstract class EquipmentAlchemic extends Equipment {
override categoryForImprovement = null;
abstract alchemicCategory: EquipmentAlchemicCategory;
abstract price: number;
abstract description: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum EquipmentAlchemicCategory {
prepared = 'prepared',
catalyst = 'catalyst',
poisonous = 'poisonous',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {EquipmentName} from '../../EquipmentName';
import {EquipmentAlchemic} from '../EquipmentAlchemic';
import {EquipmentAlchemicCategory} from '../EquipmentAlchemicCategory';

export class Acid extends EquipmentAlchemic {
override alchemicCategory: EquipmentAlchemicCategory = EquipmentAlchemicCategory.prepared;
override price = 10;
override description: string = 'Frasco de vidro contendo um ácido alquímico'
+ ' altamente corrosivo. Para usar o ácido, você'
+ ' gasta uma ação padrão e escolhe uma criatura em'
+ ' alcance curto. Essa criatura sofre 2d4 pontos de dano'
+ ' de ácido (Reflexos CD Des reduz à metade).';

override name: EquipmentName = EquipmentName.acid;
override isWieldable = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {EquipmentName} from '../../EquipmentName';
import {EquipmentAlchemic} from '../EquipmentAlchemic';
import {EquipmentAlchemicCategory} from '../EquipmentAlchemicCategory';

export class Bomb extends EquipmentAlchemic {
override alchemicCategory: EquipmentAlchemicCategory = EquipmentAlchemicCategory.prepared;
override price = 50;
override description: string = 'Uma granada rudimentar. Para usar a'
+ ' bomba, você precisa empunhá-la, gastar uma ação de'
+ ' movimento para acender seu pavio e uma ação padrão'
+ ' para arremessá-la em um ponto em alcance curto.'
+ ' Criaturas a até 3m desse ponto sofrem 6d6 pontos de'
+ ' dano de impacto (Reflexos CD Des reduz à metade).';

override name: EquipmentName = EquipmentName.bomb;
override isWieldable = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {Equipment} from '../Equipment';
import type {EquipmentName} from '../EquipmentName';

export class EquipmentAnimal extends Equipment {
override categoryForImprovement = null;

get isWieldable() {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {Equipment} from '../Equipment';
import {EquipmentImprovementCategory} from '../EquipmentImprovement/EquipmentImprovementCategory';
import type {EquipmentName} from '../EquipmentName';

export class EquipmentClothing extends Equipment {
override categoryForImprovement: EquipmentImprovementCategory = EquipmentImprovementCategory.toolsAndClothing;
get isWieldable() {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {EquipmentImprovement} from './EquipmentImprovement';
import {EquipmentImprovementCategory} from './EquipmentImprovementCategory';
import {EquipmentImprovementName} from './EquipmentImprovementName';

export class Accurate extends EquipmentImprovement {
override name = EquipmentImprovementName.accurate;
override description = '+1 nos testes de ataque';
override category = EquipmentImprovementCategory.weapon;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {EquipmentImprovement} from './EquipmentImprovement';
import {EquipmentImprovementCategory} from './EquipmentImprovementCategory';
import {EquipmentImprovementName} from './EquipmentImprovementName';

export class Cruel extends EquipmentImprovement {
override name: EquipmentImprovementName = EquipmentImprovementName.cruel;
override description = '+1 nas rolagens de dano';
override category: EquipmentImprovementCategory = EquipmentImprovementCategory.weapon;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {type EquipmentImprovementCategory} from './EquipmentImprovementCategory';
import {type EquipmentImprovementName} from './EquipmentImprovementName';

export abstract class EquipmentImprovement {
abstract name: EquipmentImprovementName;
abstract description: string;
abstract category: EquipmentImprovementCategory;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export enum EquipmentImprovementCategory {
weapon = 'weapon',
armorAndShield = 'armorAndShield',
esoteric = 'esoteric',
toolsAndClothing = 'toolsAndClothing',
all = 'all',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum EquipmentImprovementName {
accurate = 'accurate',
cruel = 'cruel',
fit = 'fit',
reinforced = 'reinforced',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {EquipmentImprovement} from './EquipmentImprovement';
import {EquipmentImprovementCategory} from './EquipmentImprovementCategory';
import {EquipmentImprovementName} from './EquipmentImprovementName';

export class Fit extends EquipmentImprovement {
override name: EquipmentImprovementName = EquipmentImprovementName.fit;
override description = '-1 na penalidade de armadura';
override category: EquipmentImprovementCategory = EquipmentImprovementCategory.armorAndShield;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {EquipmentImprovement} from './EquipmentImprovement';
import {EquipmentImprovementCategory} from './EquipmentImprovementCategory';
import {EquipmentImprovementName} from './EquipmentImprovementName';

export class Reinforced extends EquipmentImprovement {
override name: EquipmentImprovementName = EquipmentImprovementName.reinforced;
override description = '+1 na penalidade de armadura e +1 na defesa';
override category: EquipmentImprovementCategory = EquipmentImprovementCategory.armorAndShield;
}
2 changes: 2 additions & 0 deletions src/domain/entities/Inventory/Equipment/EquipmentName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ export enum EquipmentName {
musket = 'musket',
lightShield = 'lightShield',
heavyShield = 'heavyShield',
acid = 'acid',
bomb = 'bomb',
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {EquipmentName} from '../EquipmentName';
export type EquipmentWizardFocusName = EquipmentName.wand | EquipmentName.staff;

export class EquipmentWizardFocus extends Equipment {
override categoryForImprovement = null;
constructor(
readonly name: EquipmentWizardFocusName,
readonly isWieldable = false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import type {Proficiency} from '../../../../../Sheet/Proficiency';
import {EquipmentImprovementCategory} from '../../../EquipmentImprovement/EquipmentImprovementCategory';
import {DefensiveWeapon} from '../DefensiveWeapon';
import {type ArmorName} from './ArmorName';

export abstract class Armor<T extends ArmorName = ArmorName> extends DefensiveWeapon<T> {
override readonly categoryForImprovement: EquipmentImprovementCategory = EquipmentImprovementCategory.armorAndShield;

get isWieldable(): boolean {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import {Proficiency} from '../../../../../Sheet/Proficiency';
import {EquipmentImprovementCategory} from '../../../EquipmentImprovement/EquipmentImprovementCategory';
import {DefensiveWeapon} from '../DefensiveWeapon';

export abstract class Shield extends DefensiveWeapon {
override readonly categoryForImprovement = EquipmentImprovementCategory.armorAndShield;

get isWieldable(): boolean {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import {Weapon} from '../Weapon';
import type {Critical} from '../../../../Attack/Critical';
import {type WeaponPurpose} from '../WeaponPurpose';
import {type EquipmentName} from '../../EquipmentName';
import {EquipmentImprovementCategory} from '../../EquipmentImprovement/EquipmentImprovementCategory';

export abstract class OffensiveWeapon<T extends EquipmentName = EquipmentName> extends Weapon<T> {
override readonly categoryForImprovement: EquipmentImprovementCategory = EquipmentImprovementCategory.weapon;
abstract readonly damage: DiceRoll;
abstract readonly critical: Critical;
abstract readonly purposes: WeaponPurpose[];
Expand Down
6 changes: 5 additions & 1 deletion src/domain/entities/Inventory/Inventory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export class Inventory {
money = 0;

addEquipment(equipment: Equipment, isEquipped = false) {
this.equipments.set(equipment.name, new InventoryEquipment(equipment, isEquipped));
if (this.equipments.has(equipment.name)) {
this.equipments.get(equipment.name)?.increaseQuantity();
} else {
this.equipments.set(equipment.name, new InventoryEquipment(equipment, isEquipped));
}
}

addMoney(amount: number) {
Expand Down
10 changes: 10 additions & 0 deletions src/domain/entities/Inventory/InventoryEquipment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {type SerializedSheetInventoryEquipment} from '../Sheet';
import type {Equipment} from './Equipment';

export class InventoryEquipment<T extends Equipment = Equipment> {
private quantity = 1;

constructor(
readonly equipment: T,
private isEquipped = false,
Expand All @@ -20,6 +22,14 @@ export class InventoryEquipment<T extends Equipment = Equipment> {
}
}

getQuantity(): number {
return this.quantity;
}

increaseQuantity(): void {
this.quantity++;
}

getIsEquipped(): boolean {
return this.isEquipped;
}
Expand Down
16 changes: 16 additions & 0 deletions src/domain/entities/Role/Inventor/Ingenuity/Ingenuity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {AbilityEffects} from '../../../Ability';
import {RoleAbility} from '../../RoleAbility';
import {RoleAbilityName} from '../../RoleAbilityName';
import {IngenuityEffect} from './IngenuityEffect';

export class Ingenuity extends RoleAbility {
override effects = new AbilityEffects({
triggered: {
default: new IngenuityEffect(),
},
});

constructor() {
super(RoleAbilityName.ingenuity);
}
}
44 changes: 44 additions & 0 deletions src/domain/entities/Role/Inventor/Ingenuity/IngenuityEffect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {TriggerEvent, TriggeredEffect, TriggeredEffectName} from '../../../Ability';
import {type TriggeredEffectActivation} from '../../../Ability/TriggeredEffectActivation';
import {type CharacterModifierName} from '../../../Character';
import {ManaCost} from '../../../ManaCost';
import {FixedModifier, type Modifiers} from '../../../Modifier';
import {type Cost} from '../../../Sheet';
import {RoleAbilityName} from '../../RoleAbilityName';

export class IngenuityEffect extends TriggeredEffect {
override baseCosts: Cost[] = [new ManaCost(2)];
override description: string = 'Quando faz um teste de'
+ ' perícia, você pode gastar 2 PM para somar a sua Inteligência'
+ ' no teste. Você não pode usar esta habilidade'
+ ' em testes de ataque.';

constructor() {
super({
duration: 'immediate',
execution: 'reaction',
name: TriggeredEffectName.ingenuity,
source: RoleAbilityName.ingenuity,
triggerEvents: [TriggerEvent.skillTestExceptAttack],
});
}

override enable({modifiersIndexes, modifiers}: {
modifiers: Partial<Record<CharacterModifierName, Modifiers>>;
modifiersIndexes: Partial<Record<CharacterModifierName, number>>;
}, activation: TriggeredEffectActivation): {manaCost?: ManaCost | undefined} {
modifiersIndexes.skillExceptAttack = modifiers.skillExceptAttack?.fixed.add(new FixedModifier(this.source, 0, new Set(['intelligence'])));

return {
manaCost: new ManaCost(2),
};
}

override disable({modifiersIndexes, modifiers}: {modifiers: Partial<Record<CharacterModifierName, Modifiers>>; modifiersIndexes: Partial<Record<CharacterModifierName, number>>}): void {
if (modifiersIndexes.skillExceptAttack) {
modifiers.skillExceptAttack?.fixed.remove(modifiersIndexes.skillExceptAttack);
}

modifiersIndexes.skillExceptAttack = undefined;
}
}
Loading