diff --git a/services/character-sheet/src/data/action-cost.ts b/services/character-sheet/src/data/action-cost.ts new file mode 100644 index 00000000..14a33f71 --- /dev/null +++ b/services/character-sheet/src/data/action-cost.ts @@ -0,0 +1,50 @@ +import { Duration } from 'luxon'; +import { ItemId } from './item'; +import { StatusEffectId } from './status-effect'; +import { EffectTag } from './tag.effect'; +import { Attribute } from './attribute'; + +/** + * What must be paid ahead of time to peform the action + */ +export enum ActionCostTarget { + // The cost of the action is paid by the performer + PERFORMER = 'PERFORMER', + + // The cost of the action is paid by the target + TARGET = 'TARGET', + + // The cost of the action is paid by the performer's inventory + INVENTORY = 'INVENTORY', +} + +export type ActionCostInventory = { + remove: ItemId; // TODO what about stealable items? + quanity: number; +}; + +export type ActionCostStatusEffect = { + add: StatusEffectId; + chance?: number; + duration?: Duration; + tags?: Array; +}; + +// TODO: By holding button longer how can additional cost can be consumed for some skills. +// e.g. min cost max cost? cost per second? + +export type ActionCostAttribute = { + remove: Attribute; + quantity: string; + chance?: number; + tags?: Array; +}; + +/** + * Cost is the resource expenditure that must be given up by Target prior to + * the action being able to be perform. + */ +export type ActionCost = + | ActionCostInventory + | ActionCostStatusEffect + | ActionCostAttribute; diff --git a/services/character-sheet/src/data/action-target.ts b/services/character-sheet/src/data/action-target.ts new file mode 100644 index 00000000..dc3dc3a1 --- /dev/null +++ b/services/character-sheet/src/data/action-target.ts @@ -0,0 +1,23 @@ +/** + * Enum representing possible targets for actions. + * These area related to costs to peform an action but the impacts of the action + */ +export enum ActionTarget { + // An ally of the player + ALLY = 'ALLY', + + // A region within the AOE map affecting all entities + AREA = 'AREA', + + // Object or entity for interaction + INTERACTION_OBJECT = 'INTERACTION_OBJECT', + + // The performers inventory or equipment + INVENTORY = 'INVENTORY', + + // The player initiating the action + PERFORMER = 'PERFORMER', + + // An opponent of the player + OPPONENT = 'OPPONENT', +} diff --git a/services/character-sheet/src/data/aoe-maps.ts b/services/character-sheet/src/data/area-of-effect.ts similarity index 98% rename from services/character-sheet/src/data/aoe-maps.ts rename to services/character-sheet/src/data/area-of-effect.ts index 010efa54..8f542fed 100644 --- a/services/character-sheet/src/data/aoe-maps.ts +++ b/services/character-sheet/src/data/area-of-effect.ts @@ -1,5 +1,5 @@ // TODO some shapes do not tranlate well to 45 degree angles -export namespace AoeMap { +export namespace AreaOfEffect { /** * [z axis][y axis][x axis] * 7 = hit, caster facing left diff --git a/services/character-sheet/src/data/skill-level.ts b/services/character-sheet/src/data/skill-level.ts new file mode 100644 index 00000000..e949783e --- /dev/null +++ b/services/character-sheet/src/data/skill-level.ts @@ -0,0 +1,17 @@ +/** + * Represents proficiency levels for active and passive skills, determining their effectiveness. + */ +export enum SkillLevel { + LV1 = 'LV1', + LV2 = 'LV2', + LV3 = 'LV3', + LV4 = 'LV4', + LV5 = 'LV5', + LV6 = 'LV6', + LV7 = 'LV7', + LV8 = 'LV8', + LV9 = 'LV9', + MAX = 'MAX', +} + +// TODO : format skills as "Slash Lv.1" on frontend diff --git a/services/character-sheet/src/data/skill/drive.skill.ts b/services/character-sheet/src/data/skill/drive.skill.ts index c0438a05..9331fcf9 100644 --- a/services/character-sheet/src/data/skill/drive.skill.ts +++ b/services/character-sheet/src/data/skill/drive.skill.ts @@ -3,6 +3,8 @@ import { Duration } from 'luxon'; import { MenuSlot } from '../menu-slot'; import { ActionEffects } from '../table.effect'; +import { Attribute } from '../attribute'; +import { AreaOfEffect } from '../area-of-effect'; /** * Drive Actions are special actions that consume drive gauge @@ -13,6 +15,7 @@ export namespace Drive { description: string; conditions?: string; menuSlot: MenuSlot; + areaOfEffect?: AreaOfEffect.Type; actionEffects?: ActionEffects; }; @@ -21,7 +24,7 @@ export namespace Drive { description: 'Become completely focused on winning', menuSlot: MenuSlot.THIRD, actionEffects: { - CASTER: [ + PERFORMER: [ { add: 'BERSERK', chance: 1.0, @@ -34,8 +37,9 @@ export namespace Drive { export const TOXIC_THRUST: Type = { name: 'Toxic Thrust', - description: '', + description: 'Thrusts forward using posion', menuSlot: MenuSlot.THIRD, + areaOfEffect: AreaOfEffect.LINE_10FT, actionEffects: { OPPONENT: [ { @@ -52,6 +56,23 @@ export namespace Drive { name: 'Aerial Assault', description: 'Jump into air and throws boomerang (jump attack)', menuSlot: MenuSlot.THIRD, + areaOfEffect: AreaOfEffect.LINE_10FT, + actionEffects: { + OPPONENT: [ + { + remove: Attribute.LIFE, + quantity: '1d6', + chance: 0.3, + tags: [], + }, + { + add: 'STUNNED', + chance: 0.3, + duration: Duration.fromObject({ seconds: 20 }), + tags: [], + }, + ], + }, }; export const ONI: Type = { @@ -59,7 +80,7 @@ export namespace Drive { description: `Become engulfed in a blood thirsty rage that multiplies your power but drains spirit. If character stays in Oni too long they will go Berserk`, actionEffects: { - CASTER: [ + PERFORMER: [ { add: 'ONI', chance: 1.0, diff --git a/services/character-sheet/src/data/skill/interaction.skill.ts b/services/character-sheet/src/data/skill/interaction.skill.ts index ae2f6ebf..22f230ca 100644 --- a/services/character-sheet/src/data/skill/interaction.skill.ts +++ b/services/character-sheet/src/data/skill/interaction.skill.ts @@ -1,4 +1,5 @@ import { MenuSlot } from '../menu-slot'; +import { ActionEffects } from '../table.effect'; /** * Interaction skills are actions that can only be used when a compatible object is present. @@ -10,6 +11,7 @@ export namespace Interaction { description: string; target: ObjectCategory; menuSlot: MenuSlot; + actionEffects?: ActionEffects; }; export enum ObjectCategory { @@ -23,6 +25,15 @@ export namespace Interaction { description: 'Grab an object.', target: ObjectCategory.MOVEABLE, menuSlot: MenuSlot.INTERACTION, + actionEffects: { + INTERACTION_OBJECT: [ + { + add: 'BERSERK', // TODO figure out how to handle this + chance: 1.0, + tags: [], + }, + ], + }, }; export const PUSH: Type = { @@ -58,16 +69,46 @@ export namespace Interaction { description: 'Attempt to pick a lock.', target: ObjectCategory.LOCKED, menuSlot: MenuSlot.INTERACTION, + actionEffects: { + INVENTORY: [ + { + add: 'BERSERK', // TODO figure out how to handle this, e.g. state UNLOCKED + chance: 0.7, + tags: [], + }, + ], + INTERACTION_OBJECT: [ + { + add: 'BERSERK', // TODO figure out how to handle this, e.g. state UNLOCKED + chance: 0.7, + tags: [], + }, + ], + }, }; export const UNLOCK: Type = { name: 'Unlock', description: 'Open a lock using a key.', - // consumes a key target: ObjectCategory.LOCKED, menuSlot: MenuSlot.INTERACTION, + actionEffects: { + INVENTORY: [ + { + remove: 'BERSERK', // TODO figure out how to handle this, e.g. state UNLOCKED + chance: 0.7, + tags: [], + }, + ], + INTERACTION_OBJECT: [ + { + add: 'BERSERK', // TODO figure out how to handle this, e.g. state UNLOCKED + chance: 0.7, + tags: [], + }, + ], + }, }; - // which essentially means that they take up a slot on the players Command // Menu. InteractionSkill Actions take up the InteractionSkill Slot on the // Command Menu. What distinguishes InteractionSkill Actions from the rest diff --git a/services/character-sheet/src/data/table.effect.ts b/services/character-sheet/src/data/table.effect.ts index 4af607a0..1a980736 100644 --- a/services/character-sheet/src/data/table.effect.ts +++ b/services/character-sheet/src/data/table.effect.ts @@ -3,7 +3,7 @@ import { SkillType } from './skill'; import { EffectTag } from './tag.effect'; import { StatusEffectId } from './status-effect'; import { Attribute } from './attribute'; -import { Target } from './target.effect'; +import { ActionTarget } from './action-target'; export enum Modifier { ADD = 'ADD', @@ -74,5 +74,5 @@ export type EffectTable = EffectRecord[]; * Each target is mapped to an array of EffectRecords capturing the effects. */ export type ActionEffects = { - [key in Target]?: EffectRecord[]; + [key in ActionTarget]?: EffectRecord[]; }; diff --git a/services/character-sheet/src/data/target.effect.ts b/services/character-sheet/src/data/target.effect.ts deleted file mode 100644 index ad7e9d0d..00000000 --- a/services/character-sheet/src/data/target.effect.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** When a Player uses an action that action is relative to an AOE map to - * Target of a defined type - */ -export enum Target { - CASTER = 'CASTER', // player - OPPONENT = 'OPPONENT', - ALLY = 'ALLY', - AOE = 'AOE', // MULTIPLE, TODO remove? -}