diff --git a/packages/creature/package.json b/packages/creature/package.json index 97186c1..35fe566 100644 --- a/packages/creature/package.json +++ b/packages/creature/package.json @@ -11,6 +11,7 @@ "license": "MIT", "devDependencies": { "@types/jest": "^24.0.18", + "@types/uuid": "^3.4.5", "jest": "^24.9.0", "ts-jest": "^24.0.2", "tslint": "^5.19.0", @@ -31,5 +32,11 @@ "transformIgnorePatterns": [ "/node_modules/[^@xethya]/" ] + }, + "dependencies": { + "@xethya/ability": "^0.0.3", + "@xethya/definitions": "^0.0.4", + "@xethya/race": "^0.0.1", + "uuid": "^3.3.3" } -} \ No newline at end of file +} diff --git a/packages/creature/src/creature.ts b/packages/creature/src/creature.ts index f9bf484..7ce9cf7 100644 --- a/packages/creature/src/creature.ts +++ b/packages/creature/src/creature.ts @@ -1 +1,52 @@ -export class Creature {} +import Ability from "@xethya/ability"; +import { CreatureAlignment, CreatureSize } from "@xethya/definitions"; +import { Race } from "@xethya/race"; +import { v4 as generateUUID } from "uuid"; + +export type CreatureOptions = { + races?: Race[]; + size?: CreatureSize; + alignment?: CreatureAlignment; + name?: string; +}; + +export class Creature { + public readonly races: Race[] = []; + public readonly abilities: Map; + public readonly size: CreatureSize = CreatureSize.Medium; + public readonly alignment: CreatureAlignment = CreatureAlignment.Neutral; + public readonly id: string; + public readonly name: string = "Unknown Creature"; + + public constructor(options: CreatureOptions = {}) { + this.id = generateUUID(); + this.abilities = new Map(); + + if (options.name) { + this.name = options.name; + } + + if (options.races) { + /** + * @todo Should define what it means in terms of attribute dominance + * to support multiple races. + * + * @see https://github.com/xethya/framework/issues/30 + */ + this.races = options.races; + } + + if (this.races.length === 1) { + this.size = this.races[0].size; + this.alignment = this.races[0].alignment; + } + + if (options.size) { + this.size = options.size; + } + + if (options.alignment) { + this.alignment = options.alignment; + } + } +} diff --git a/packages/creature/tests/creature.test.ts b/packages/creature/tests/creature.test.ts index e2950f1..adf0f86 100644 --- a/packages/creature/tests/creature.test.ts +++ b/packages/creature/tests/creature.test.ts @@ -1,7 +1,83 @@ +import { CreatureAlignment, CreatureSize } from "@xethya/definitions"; +import { Race } from "@xethya/race"; import { Creature } from "../src/creature"; +/** + * @todo Move this regex to utils. + * @see https://github.com/xethya/framework/issues/33 + */ +const UUID_REGEX = /^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/; + describe("Creature", () => { - it("can be instantiated", () => { - expect(new Creature()).toBeDefined(); + it("should instantiate a Creature without parameters", () => { + const creature = new Creature(); + expect(creature.id).toMatch(UUID_REGEX); + expect(creature.name).toEqual("Unknown Creature"); + expect(creature.abilities.size).toEqual(0); + expect(creature.races.length).toEqual(0); + expect(creature.alignment).toEqual(CreatureAlignment.Neutral); + expect(creature.size).toEqual(CreatureSize.Medium); + }); + + it("should instantiate a Creature with alignment", () => { + const creature = new Creature({ + alignment: CreatureAlignment.LawfulNeutral, + }); + expect(creature.alignment).toEqual(CreatureAlignment.LawfulNeutral); + }); + + it("should instantiate a Creature with name", () => { + const creature = new Creature({ + name: "Foo", + }); + expect(creature.name).toEqual("Foo"); + }); + + it("should instantiate a Creature with name", () => { + const creature = new Creature({ + size: CreatureSize.Tiny, + }); + expect(creature.size).toEqual(CreatureSize.Tiny); + }); + + it("should instantiate a Creature with a single race", () => { + const Feline = new Race({ + size: CreatureSize.Small, + alignment: CreatureAlignment.NeutralEvil, + }); + + const creature = new Creature({ + races: [Feline], + }); + + expect(creature.races).toEqual([Feline]); + expect(creature.size).toEqual(Feline.size); + expect(creature.alignment).toEqual(Feline.alignment); + }); + + /** + * @todo Should define what it means in terms of attribute dominance + * to support multiple races. + * + * @see https://github.com/xethya/framework/issues/30 + */ + it("should instantiate a Creature with multiple races", () => { + const Feline = new Race({ + size: CreatureSize.Small, + alignment: CreatureAlignment.NeutralEvil, + }); + + const Human = new Race({ + size: CreatureSize.Large, + alignment: CreatureAlignment.NeutralGood, + }); + + const creature = new Creature({ + races: [Feline, Human], + }); + + expect(creature.races).toEqual([Feline, Human]); + expect(creature.size).toEqual(CreatureSize.Medium); + expect(creature.alignment).toEqual(CreatureAlignment.Neutral); }); }); diff --git a/tslint.json b/tslint.json index 41fe693..18ff0e1 100644 --- a/tslint.json +++ b/tslint.json @@ -7,7 +7,8 @@ "member-ordering": false, "member-access": false, "no-bitwise": false, - "interface-over-type-literal": false + "interface-over-type-literal": false, + "object-literal-sort-keys": false }, "rulesDirectory": [] } diff --git a/yarn.lock b/yarn.lock index dc07157..c5e6293 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1206,6 +1206,13 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/uuid@^3.4.5": + version "3.4.5" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.5.tgz#d4dc10785b497a1474eae0ba7f0cb09c0ddfd6eb" + integrity sha512-MNL15wC3EKyw1VLF+RoVO4hJJdk9t/Hlv3rt1OL65Qvuadm4BYo6g9ZJQqoq7X8NBFSsQXgAujWciovh2lpVjA== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "13.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0" @@ -6396,6 +6403,11 @@ uuid@^3.0.1, uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== +uuid@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" + integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"