roleplayer
Version:
A library for building table top role playing game worlds, and managing campaigns in those worlds
103 lines (88 loc) • 2.69 kB
text/typescript
import {
CharacterEventTypes,
type ActionDefinition,
type CampaignEvent,
type DiceRoll,
type ElementDefinition,
type ResourceDefinition,
type Ruleset,
} from "../..";
import type { Actor } from "../actor/character";
import type { StatusDefinition } from "./status";
type EffectParameters = unknown;
export type CharacterResourceLossEffect = {
eventType: "CharacterResourceLoss";
roll: DiceRoll;
resourceTypeId: ResourceDefinition["id"];
elementTypeId: ElementDefinition["id"];
};
export type CharacterStatusGainEffect = {
eventType: "CharacterStatusGain";
statusId: StatusDefinition["id"];
};
export type UnkownEffect = {
eventType: string;
parameters: EffectParameters;
};
export type EffectEventDefinition = CharacterResourceLossEffect | CharacterStatusGainEffect | UnkownEffect;
export function mapEffect(
effect: EffectEventDefinition,
actionDef: ActionDefinition,
attacker: Actor,
target: Actor,
ruleset: Ruleset
): CampaignEvent {
switch (effect.eventType) {
case "CharacterResourceLoss": {
return instantiateResourceLossEffect(actionDef, effect, attacker, target, ruleset);
}
case "CharacterStatusGain": {
return instantiateStatusGainEffect(actionDef, effect, attacker, target, ruleset);
}
default:
throw new Error("Could not map effect event type");
}
}
function isCharacterResourceLossEffect(effect: EffectEventDefinition): effect is CharacterResourceLossEffect {
return effect.eventType === "CharacterResourceLoss";
}
function instantiateResourceLossEffect(
action: ActionDefinition,
effect: EffectEventDefinition,
source: Actor,
target: Actor,
ruleset: Ruleset
): CampaignEvent {
if (!isCharacterResourceLossEffect(effect)) {
throw new Error("Not CharacterResourceLoss effect type");
}
return {
type: CharacterEventTypes.CharacterResourceLoss,
amount: ruleset.characterHitDamage(source, action, target, effect),
characterId: target.id,
resourceTypeId: effect.resourceTypeId,
actionId: action.id,
sourceId: source.id,
};
}
function isCharacterStatusGain(effect: EffectEventDefinition): effect is CharacterStatusGainEffect {
return effect.eventType === "CharacterStatusGain";
}
function instantiateStatusGainEffect(
action: ActionDefinition,
effect: EffectEventDefinition,
source: Actor,
target: Actor,
ruleset: Ruleset
): CampaignEvent {
if (!isCharacterStatusGain(effect)) {
throw new Error("Not CharacterStatusGain effect type");
}
return {
type: CharacterEventTypes.CharacterStatusGain,
characterId: target.id,
actionId: action.id,
sourceId: source.id,
statusId: effect.statusId,
};
}