From f7d98b60124740f02a1b6f454fe6949337bd275e Mon Sep 17 00:00:00 2001 From: Marc Duiker Date: Mon, 31 Oct 2022 09:40:23 +0100 Subject: [PATCH 1/3] Add Mod and refactor to smaller files --- CHANGELOG.md | 10 + README.md | 7 +- media/main-bundle.js | 2729 +++++++++++++++------------ media/mod/purple_ball_8fps.gif | Bin 0 -> 4215 bytes media/mod/purple_idle_8fps.gif | Bin 0 -> 3967 bytes media/mod/purple_run_8fps.gif | Bin 0 -> 3948 bytes media/mod/purple_swipe_8fps.gif | Bin 0 -> 12778 bytes media/mod/purple_walk_8fps.gif | Bin 0 -> 3948 bytes media/mod/purple_walk_fast_8fps.gif | Bin 0 -> 3948 bytes package-lock.json | 4 +- package.json | 2 + package.nls.json | 2 + src/common/names.ts | 552 +----- src/common/types.ts | 4 + src/extension/extension.ts | 3 + src/panel/basepettype.ts | 337 ++++ src/panel/main.ts | 2 +- src/panel/pets.ts | 919 +-------- src/panel/pets/cat.ts | 202 ++ src/panel/pets/clippy.ts | 63 + src/panel/pets/cockatiel.ts | 87 + src/panel/pets/crab.ts | 103 + src/panel/pets/dog.ts | 208 ++ src/panel/pets/mod.ts | 59 + src/panel/pets/rocky.ts | 58 + src/panel/pets/rubberduck.ts | 111 ++ src/panel/pets/snake.ts | 113 ++ src/panel/pets/totoro.ts | 79 + src/panel/pets/zappy.ts | 71 + src/panel/states.ts | 37 +- src/test/suite/panel.test.ts | 3 +- 31 files changed, 3072 insertions(+), 2693 deletions(-) create mode 100644 media/mod/purple_ball_8fps.gif create mode 100644 media/mod/purple_idle_8fps.gif create mode 100644 media/mod/purple_run_8fps.gif create mode 100644 media/mod/purple_swipe_8fps.gif create mode 100644 media/mod/purple_walk_8fps.gif create mode 100644 media/mod/purple_walk_fast_8fps.gif create mode 100644 src/panel/basepettype.ts create mode 100644 src/panel/pets/cat.ts create mode 100644 src/panel/pets/clippy.ts create mode 100644 src/panel/pets/cockatiel.ts create mode 100644 src/panel/pets/crab.ts create mode 100644 src/panel/pets/dog.ts create mode 100644 src/panel/pets/mod.ts create mode 100644 src/panel/pets/rocky.ts create mode 100644 src/panel/pets/rubberduck.ts create mode 100644 src/panel/pets/snake.ts create mode 100644 src/panel/pets/totoro.ts create mode 100644 src/panel/pets/zappy.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index d989089c..f08c54a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to the "vscode-pets" extension will be documented in this file. +## [1.16.1] + +## New pets + +* Add Mod the dotnet bot + +## Other updates + +* Move pet definitions and names into one file per pet. + ## [1.16.0] ## Major updates diff --git a/README.md b/README.md index 9a3b84ce..3db06b4b 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,9 @@ Open the setting panel with `Ctrl+,` on Windows/Linux or `Cmd(⌘)+,` on MacOS. Set a default color, size, pet type, position, and theme when you open a Pet Panel. -* Pet Color: black, brown, green, yellow, gray, red, white +* Pet Color: black, brown, green, yellow, gray, purple, red, white * Pet Size: nano, medium, large -* Pet Type: cat, crab, clippy, cockatiel, dog, rocky, rubber duck, snake, totoro, zappy +* Pet Type: cat, crab, clippy, cockatiel, dog, mod, rocky, rubber duck, snake, totoro, zappy * Position: panel, explorer * Theme: none, forest, castle, beach @@ -54,6 +54,7 @@ Set a default color, size, pet type, position, and theme when you open a Pet Pan * Rubber duck & Zappy can only be yellow * Ferris the crab can only be red * Rocky can only be gray +* Mod can only be purple ## Start pet coding session to show your pet @@ -169,7 +170,7 @@ The minimum set of behaviors is: The cat and dog media assets for this extension were licensed from itch.io. -[Marc Duiker](https://twitter.com/marcduiker) created the Clippy, Rocky, Zappy, rubber duck, snake, cockatiel, and Ferris the crab media assets. +[Marc Duiker](https://twitter.com/marcduiker) created the Clippy, Rocky, Zappy, rubber duck, snake, cockatiel, Ferris the crab, and Mod the dotnet bot media assets. [Karen Rustad Tölva](https://www.aldeka.net) designed the original concept of Ferris the crab. diff --git a/media/main-bundle.js b/media/main-bundle.js index b8181b23..735af340 100644 --- a/media/main-bundle.js +++ b/media/main-bundle.js @@ -6,557 +6,316 @@ /*!*****************************!*\ !*** ./src/common/names.ts ***! \*****************************/ -/***/ ((__unused_webpack_module, exports) => { - - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.randomName = exports.COCKATIEL_NAMES = exports.ROCKY_NAMES = exports.ZAPPY_NAMES = exports.DUCK_NAMES = exports.SNAKE_NAMES = exports.TOTORO_NAMES = exports.CLIPPY_NAMES = exports.CRAB_NAMES = exports.DOG_NAMES = exports.CAT_NAMES = void 0; -exports.CAT_NAMES = [ - 'Bella', - 'Charlie', - 'Molly', - 'Coco', - 'Ruby', - 'Oscar', - 'Lucy', - 'Bailey', - 'Milo', - 'Daisy', - 'Archie', - 'Ollie', - 'Rosie', - 'Lola', - 'Frankie', - 'Roxy', - 'Poppy', - 'Luna', - 'Jack', - 'Millie', - 'Teddy', - 'Cooper', - 'Bear', - 'Rocky', - 'Alfie', - 'Hugo', - 'Bonnie', - 'Pepper', - 'Lily', - 'Tilly', - 'Leo', - 'Maggie', - 'George', - 'Mia', - 'Marley', - 'Harley', - 'Chloe', - 'Lulu', - 'Missy', - 'Jasper', - 'Billy', - 'Nala', - 'Monty', - 'Ziggy', - 'Winston', - 'Zeus', - 'Zoe', - 'Stella', - 'Sasha', - 'Rusty', - 'Gus', - 'Baxter', - 'Dexter', - 'Willow', - 'Barney', - 'Bruno', - 'Penny', - 'Honey', - 'Milly', - 'Murphy', - 'Simba', - 'Holly', - 'Benji', - 'Henry', - 'Lilly', - 'Pippa', - 'Shadow', - 'Sam', - 'Lucky', - 'Ellie', - 'Duke', - 'Jessie', - 'Cookie', - 'Harvey', - 'Bruce', - 'Jax', - 'Rex', - 'Louie', - 'Jet', - 'Banjo', - 'Beau', - 'Ella', - 'Ralph', - 'Loki', - 'Lexi', - 'Chester', - 'Sophie', - 'Chilli', - 'Billie', - 'Louis', - 'Scout', - 'Cleo', - 'Purfect', - 'Spot', - 'Bolt', - 'Julia', - 'Ginger', - 'Daisy', - 'Amelia', - 'Oliver', - 'Ghost', - 'Midnight', - 'Pumpkin', - 'Shadow', - 'Binx', - 'Riley', - 'Lenny', - 'Mango', - 'Alex', - 'Boo', - 'Botas', - 'Romeo', - 'Bob', - 'Clyde', - 'Simon', - 'Mimmo', - 'Carlotta', - 'Felix', - 'Duchess', -]; -exports.DOG_NAMES = [ - 'Bella', - 'Charlie', - 'Max', - 'Molly', - 'Coco', - 'Buddy', - 'Ruby', - 'Oscar', - 'Lucy', - 'Bailey', - 'Milo', - 'Daisy', - 'Archie', - 'Ollie', - 'Rosie', - 'Lola', - 'Frankie', - 'Toby', - 'Roxy', - 'Poppy', - 'Luna', - 'Jack', - 'Millie', - 'Teddy', - 'Harry', - 'Cooper', - 'Bear', - 'Rocky', - 'Alfie', - 'Hugo', - 'Bonnie', - 'Pepper', - 'Lily', - 'Leo', - 'Maggie', - 'George', - 'Mia', - 'Marley', - 'Harley', - 'Chloe', - 'Lulu', - 'Jasper', - 'Billy', - 'Nala', - 'Monty', - 'Ziggy', - 'Winston', - 'Zeus', - 'Zoe', - 'Stella', - 'Sasha', - 'Rusty', - 'Gus', - 'Baxter', - 'Dexter', - 'Diesel', - 'Willow', - 'Barney', - 'Bruno', - 'Penny', - 'Honey', - 'Milly', - 'Murphy', - 'Holly', - 'Benji', - 'Henry', - 'Lilly', - 'Pippa', - 'Shadow', - 'Sam', - 'Buster', - 'Lucky', - 'Ellie', - 'Duke', - 'Jessie', - 'Cookie', - 'Harvey', - 'Bruce', - 'Jax', - 'Rex', - 'Louie', - 'Bentley', - 'Jet', - 'Banjo', - 'Beau', - 'Ella', - 'Ralph', - 'Loki', - 'Lexi', - 'Chester', - 'Sophie', - 'Billie', - 'Louis', - 'Charlie', - 'Cleo', - 'Spot', - 'Harry', - 'Bolt', - 'Ein', - 'Maddy', - 'Ghost', - 'Midnight', - 'Pumpkin', - 'Shadow', - 'Sparky', - 'Linus', - 'Cody', - 'Slinky', - 'Toto', - 'Balto', - 'Golfo', - 'Pongo', - 'Beethoven', - 'Hachiko', - 'Scooby', - 'Clifford', - 'Astro', - 'Goofy', - 'Chip', - 'Einstein', - 'Fang', - 'Truman', - 'Uggie', - 'Bingo', - 'Blue', - 'Cometa', - 'Krypto', - 'Huesos', - 'Odie', - 'Snoopy', - 'Aisha', - 'Moly', - 'Chiquita', - 'Chavela', - 'Tramp', - 'Lady', - 'Puddles', -]; -exports.CRAB_NAMES = [ - 'Ferris', - 'Pinchy', - 'Grabby', - 'Big Red', - 'Crabby', - 'Buddy', - 'Ruby Red', - 'Oscar', - 'Lucy', - 'Bailey', - 'Crabito', - 'Percy', - 'Rocky', - 'Mr. Krabs', - 'Shelly', - 'Santa Claws', - 'Clawdia', - 'Scuttle', - 'Snappy', - 'Hermit', - 'Horseshoe', - 'Snapper', - 'Coconut', - 'Sebastian', - 'Abby', - 'Bubbles', - 'Bait', - 'Big Mac', - 'Biggie', - 'Claws', - 'Copper', - 'Crabette', - 'Crabina', - 'Crabmister', - 'Crusty', - 'Crabcake', - 'Digger', - 'Nipper', - 'Pincer', - 'Poopsie', - 'Recluse', - 'Salty', - 'Squirt', - 'Groucho', - 'Grumpy', - 'Lenny Krabitz', - 'Leonardo DaPinchy', - 'Peeves', - 'Penny Pincher', - 'Prickl', -]; -exports.CLIPPY_NAMES = [ - 'Clippy', - 'Karl Klammer', - 'Clippy Jr.', - 'Molly', - 'Coco', - 'Buddy', - 'Ruby', - 'Oscar', - 'Lucy', - 'Bailey', -]; -exports.TOTORO_NAMES = [ - 'Totoro', - 'トトロ', - 'Max', - 'Molly', - 'Coco', - 'Buddy', - 'Ruby', - 'Oscar', - 'Lucy', - 'Bailey', - 'Big fella', -]; -exports.SNAKE_NAMES = [ - 'Sneaky', - 'Mr Slippery', - 'Hissy Elliott', - 'Molly', - 'Coco', - 'Buddy', - 'Ruby', - 'Bailey', - 'Max', - 'Seb', - 'Kaa', - 'Mr Hiss', - 'Miss Hiss', - 'Snaku', - 'Kaa', - 'Madame Snake', - 'Sir Hiss', - 'Loki', - 'Steelix', - 'Gyarados', - 'Seviper', - 'Ekanes', - 'Arbok', - 'Snivy', - 'Servine', - 'Serperior', - 'Mojo', - 'Moss', - 'Nigel', - 'Tootsie', - 'Sammy', - 'Ziggy', - 'Asmodeus', - 'Attila', - 'Basil', - 'Diablo', - 'Eden', - 'Eve', - 'Heaven', - 'Hydra', - 'Indiana', - 'Jafaar', - 'Kaa', - 'Medusa', - 'Naga', - 'Severus', - 'Slytherin', - 'Snape', - 'Raven', - 'Slider', - 'Slinky', - 'Stripes', -]; -exports.DUCK_NAMES = [ - 'Quacky', - 'Floaty', - 'Duck', - 'Molly', - 'Sunshine', - 'Buddy', - 'Chirpy', - 'Oscar', - 'Lucy', - 'Bailey', - 'Beaky', - 'Jemima', - 'Peaches', - 'Quackers', - 'Jelly Beans', - 'Donald', - 'Chady', - 'Waddles', - 'Bill', - 'Bubbles', - 'James Pond', - 'Moby Duck', - 'Quack Sparrow', - 'Peanut', - 'Psyduck', - 'Mr Quack', - 'Louie', - 'Golduck', - 'Daisy', - 'Pickles', - 'Ducky Duck', - 'Mrs Fluffs', - 'Squeek', - 'Ace', - 'Rubberduck', - 'Mrs Beak', - 'April', - 'Tutu', - 'Billy the duck', - 'Ducky', - 'Neco', - 'Dodo', - 'Colonel', - 'Franklin', - 'Emmett', - 'Bubba', - 'Dillard', - 'Duncan', - 'Pogo', - 'Uno', - 'Peanut', - 'Nero', - 'Mowgli', - 'Eggspresso', - 'Webster', - 'Quacker Jack', - 'Plucker', - 'Meeko', -]; -exports.ZAPPY_NAMES = [ - 'Zappy', - 'Zippy', - 'Zappy Jr.', - 'Zoppy', - 'Zuppy', - 'Zeppy', - 'Big Z', - 'Little z', - 'The Flash', - 'Thor', - 'Electric Bolt', - 'Azula', - 'Lightning Bolt', - 'Power', - 'Sonic', - 'Speedy', - 'Rush', -]; -exports.ROCKY_NAMES = [ - 'Rocky', - 'The Rock', - 'Quartzy', - 'Rocky I', - 'Rocky II', - 'Rocky III', - 'Pebbles Sr.', - 'Big Granite', - 'Boulder', - 'Rockefeller', - 'Pebble', - 'Rocksanne', - 'Rockstar', - 'Onix', - 'Rock and Roll', - 'Dolomite', - 'Granite', - 'Miss Marble', - 'Rock On', - 'Amberstone', - 'Rock With Me', - 'Rock On It', - 'Rock Out', -]; -exports.COCKATIEL_NAMES = [ - 'Cocktail', - 'Pipsqueak', - 'Sir Chirps a Lot', - 'Nibbles', - 'Lord of the Wings', - 'Girl Nest Door', - 'Wingman', - 'Meryl Cheep', - 'Jack Sparrow', - 'Godfeather', - 'Mickey', - 'Baquack Obama', - 'Dame Judi Finch', - 'Kanye Nest', - 'Speck', - 'Cheecky', - 'Arthur', - 'Paco', - 'Bobo', - 'Walt', - 'Happy', - 'Junior', - 'Coco', - 'Yoyo', - 'Milo', - 'Skipper', - 'Scarlet', - 'Diva', - 'Ursula', - 'Donna', - 'Lola', - 'Kiko', - 'Luna', -]; +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.randomName = void 0; +const cat_1 = __webpack_require__(/*! ../panel/pets/cat */ "./src/panel/pets/cat.ts"); +const clippy_1 = __webpack_require__(/*! ../panel/pets/clippy */ "./src/panel/pets/clippy.ts"); +const cockatiel_1 = __webpack_require__(/*! ../panel/pets/cockatiel */ "./src/panel/pets/cockatiel.ts"); +const crab_1 = __webpack_require__(/*! ../panel/pets/crab */ "./src/panel/pets/crab.ts"); +const dog_1 = __webpack_require__(/*! ../panel/pets/dog */ "./src/panel/pets/dog.ts"); +const mod_1 = __webpack_require__(/*! ../panel/pets/mod */ "./src/panel/pets/mod.ts"); +const rocky_1 = __webpack_require__(/*! ../panel/pets/rocky */ "./src/panel/pets/rocky.ts"); +const rubberduck_1 = __webpack_require__(/*! ../panel/pets/rubberduck */ "./src/panel/pets/rubberduck.ts"); +const snake_1 = __webpack_require__(/*! ../panel/pets/snake */ "./src/panel/pets/snake.ts"); +const totoro_1 = __webpack_require__(/*! ../panel/pets/totoro */ "./src/panel/pets/totoro.ts"); +const zappy_1 = __webpack_require__(/*! ../panel/pets/zappy */ "./src/panel/pets/zappy.ts"); function randomName(type) { const collection = { - ["cat" /* PetType.cat */]: exports.CAT_NAMES, - ["dog" /* PetType.dog */]: exports.DOG_NAMES, - ["crab" /* PetType.crab */]: exports.CRAB_NAMES, - ["clippy" /* PetType.clippy */]: exports.CLIPPY_NAMES, - ["totoro" /* PetType.totoro */]: exports.TOTORO_NAMES, - ["snake" /* PetType.snake */]: exports.SNAKE_NAMES, - ["rubber-duck" /* PetType.rubberduck */]: exports.DUCK_NAMES, - ["zappy" /* PetType.zappy */]: exports.ZAPPY_NAMES, - ["rocky" /* PetType.rocky */]: exports.ROCKY_NAMES, - ["cockatiel" /* PetType.cockatiel */]: exports.COCKATIEL_NAMES, - }[type] ?? exports.CAT_NAMES; + ["cat" /* PetType.cat */]: cat_1.CAT_NAMES, + ["dog" /* PetType.dog */]: dog_1.DOG_NAMES, + ["crab" /* PetType.crab */]: crab_1.CRAB_NAMES, + ["clippy" /* PetType.clippy */]: clippy_1.CLIPPY_NAMES, + ["mod" /* PetType.mod */]: mod_1.MOD_NAMES, + ["totoro" /* PetType.totoro */]: totoro_1.TOTORO_NAMES, + ["snake" /* PetType.snake */]: snake_1.SNAKE_NAMES, + ["rubber-duck" /* PetType.rubberduck */]: rubberduck_1.DUCK_NAMES, + ["zappy" /* PetType.zappy */]: zappy_1.ZAPPY_NAMES, + ["rocky" /* PetType.rocky */]: rocky_1.ROCKY_NAMES, + ["cockatiel" /* PetType.cockatiel */]: cockatiel_1.COCKATIEL_NAMES, + }[type] ?? cat_1.CAT_NAMES; return (collection[Math.floor(Math.random() * collection.length)] ?? 'Unknown'); } -exports.randomName = randomName; +exports.randomName = randomName; + + +/***/ }), + +/***/ "./src/panel/basepettype.ts": +/*!**********************************!*\ + !*** ./src/panel/basepettype.ts ***! + \**********************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.BasePetType = exports.InvalidStateException = void 0; +const states_1 = __webpack_require__(/*! ./states */ "./src/panel/states.ts"); +class InvalidStateException { +} +exports.InvalidStateException = InvalidStateException; +class BasePetType { + label = 'base'; + static count = 0; + sequence = { + startingState: "sit-idle" /* States.sitIdle */, + sequenceStates: [], + }; + currentState; + currentStateEnum; + holdState; + holdStateEnum; + el; + collision; + speech; + _left; + _bottom; + petRoot; + _floor; + _friend; + _name; + _speed; + _size; + constructor(spriteElement, collisionElement, speechElement, size, left, bottom, petRoot, floor, name, speed) { + this.el = spriteElement; + this.collision = collisionElement; + this.speech = speechElement; + this.petRoot = petRoot; + this._floor = floor; + this._left = left; + this._bottom = bottom; + this.initSprite(size, left, bottom); + this.currentStateEnum = this.sequence.startingState; + this.currentState = (0, states_1.resolveState)(this.currentStateEnum, this); + this._name = name; + this._size = size; + this._speed = this.randomizeSpeed(speed); + // Increment the static count of the Pet class that the constructor belongs to + this.constructor.count += 1; + } + initSprite(petSize, left, bottom) { + this.el.style.left = `${left}px`; + this.el.style.bottom = `${bottom}px`; + this.el.style.width = 'auto'; + this.el.style.height = 'auto'; + this.el.style.maxWidth = `${this.calculateSpriteWidth(petSize)}px`; + this.el.style.maxHeight = `${this.calculateSpriteWidth(petSize)}px`; + this.collision.style.left = `${left}px`; + this.collision.style.bottom = `${bottom}px`; + this.collision.style.width = `${this.calculateSpriteWidth(petSize)}px`; + this.collision.style.height = `${this.calculateSpriteWidth(petSize)}px`; + this.speech.style.left = `${left}px`; + this.speech.style.bottom = `${bottom + this.calculateSpriteWidth(petSize)}px`; + this.hideSpeechBubble(); + } + get left() { + return this._left; + } + get bottom() { + return this._bottom; + } + repositionAccompanyingElements() { + this.collision.style.left = `${this._left}px`; + this.collision.style.bottom = `${this._bottom}px`; + this.speech.style.left = `${this._left}px`; + this.speech.style.bottom = `${this._bottom + this.calculateSpriteWidth(this._size)}px`; + } + calculateSpriteWidth(size) { + if (size === "nano" /* PetSize.nano */) { + return 30; + } + else if (size === "medium" /* PetSize.medium */) { + return 55; + } + else if (size === "large" /* PetSize.large */) { + return 110; + } + else { + return 30; // Shrug + } + } + positionBottom(bottom) { + this._bottom = bottom; + this.el.style.bottom = `${this._bottom}px`; + this.repositionAccompanyingElements(); + } + positionLeft(left) { + this._left = left; + this.el.style.left = `${this._left}px`; + this.repositionAccompanyingElements(); + } + get width() { + return this.el.width; + } + get floor() { + return this._floor; + } + get hello() { + // return the sound of the name of the animal + return ` says hello 👋!`; + } + getState() { + return { currentStateEnum: this.currentStateEnum }; + } + get speed() { + return this._speed; + } + randomizeSpeed(speed) { + const min = speed * 0.7; + const max = speed * 1.3; + const newSpeed = Math.random() * (max - min) + min; + return newSpeed; + } + get isMoving() { + return this._speed !== 0 /* PetSpeed.still */; + } + recoverFriend(friend) { + // Recover friends.. + this._friend = friend; + } + recoverState(state) { + // TODO : Resolve a bug where if it was swiping before, it would fail + // because holdState is no longer valid. + this.currentStateEnum = state.currentStateEnum ?? "sit-idle" /* States.sitIdle */; + this.currentState = (0, states_1.resolveState)(this.currentStateEnum, this); + if (!(0, states_1.isStateAboveGround)(this.currentStateEnum)) { + // Reset the bottom of the sprite to the floor as the theme + // has likely changed. + this.positionBottom(this.floor); + } + } + get canSwipe() { + return !(0, states_1.isStateAboveGround)(this.currentStateEnum); + } + get canChase() { + return (!(0, states_1.isStateAboveGround)(this.currentStateEnum) && + this.currentStateEnum !== "chase" /* States.chase */ && + this.isMoving); + } + showSpeechBubble(message, duration = 3000) { + this.speech.innerHTML = message; + this.speech.style.display = 'block'; + setTimeout(() => { + this.hideSpeechBubble(); + }, duration); + } + hideSpeechBubble() { + this.speech.style.display = 'none'; + } + swipe() { + if (this.currentStateEnum === "swipe" /* States.swipe */) { + return; + } + this.holdState = this.currentState; + this.holdStateEnum = this.currentStateEnum; + this.currentStateEnum = "swipe" /* States.swipe */; + this.currentState = (0, states_1.resolveState)(this.currentStateEnum, this); + this.showSpeechBubble('👋'); + } + chase(ballState, canvas) { + this.currentStateEnum = "chase" /* States.chase */; + this.currentState = new states_1.ChaseState(this, ballState, canvas); + } + faceLeft() { + this.el.style.transform = 'scaleX(-1)'; + } + faceRight() { + this.el.style.transform = 'scaleX(1)'; + } + setAnimation(face) { + if (this.el.src.endsWith(`_${face}_8fps.gif`)) { + return; + } + this.el.src = `${this.petRoot}_${face}_8fps.gif`; + } + chooseNextState(fromState) { + // Work out next state + var possibleNextStates = undefined; + for (var i = 0; i < this.sequence.sequenceStates.length; i++) { + if (this.sequence.sequenceStates[i].state === fromState) { + possibleNextStates = + this.sequence.sequenceStates[i].possibleNextStates; + } + } + if (!possibleNextStates) { + throw new InvalidStateException(); + } + // randomly choose the next state + const idx = Math.floor(Math.random() * possibleNextStates.length); + return possibleNextStates[idx]; + } + nextFrame() { + if (this.currentState.horizontalDirection === states_1.HorizontalDirection.left) { + this.faceLeft(); + } + else if (this.currentState.horizontalDirection === states_1.HorizontalDirection.right) { + this.faceRight(); + } + this.setAnimation(this.currentState.spriteLabel); + // What's my buddy doing? + if (this.hasFriend && + this.currentStateEnum !== "chase-friend" /* States.chaseFriend */ && + this.isMoving) { + if (this.friend?.isPlaying && + !(0, states_1.isStateAboveGround)(this.currentStateEnum)) { + this.currentState = (0, states_1.resolveState)("chase-friend" /* States.chaseFriend */, this); + this.currentStateEnum = "chase-friend" /* States.chaseFriend */; + return; + } + } + var frameResult = this.currentState.nextFrame(); + if (frameResult === states_1.FrameResult.stateComplete) { + // If recovering from swipe.. + if (this.holdState && this.holdStateEnum) { + this.currentState = this.holdState; + this.currentStateEnum = this.holdStateEnum; + this.holdState = undefined; + this.holdStateEnum = undefined; + return; + } + var nextState = this.chooseNextState(this.currentStateEnum); + this.currentState = (0, states_1.resolveState)(nextState, this); + this.currentStateEnum = nextState; + } + else if (frameResult === states_1.FrameResult.stateCancel) { + if (this.currentStateEnum === "chase" /* States.chase */) { + var nextState = this.chooseNextState("idle-with-ball" /* States.idleWithBall */); + this.currentState = (0, states_1.resolveState)(nextState, this); + this.currentStateEnum = nextState; + } + else if (this.currentStateEnum === "chase-friend" /* States.chaseFriend */) { + var nextState = this.chooseNextState("idle-with-ball" /* States.idleWithBall */); + this.currentState = (0, states_1.resolveState)(nextState, this); + this.currentStateEnum = nextState; + } + } + } + get hasFriend() { + return this._friend !== undefined; + } + get friend() { + return this._friend; + } + get name() { + return this._name; + } + makeFriendsWith(friend) { + this._friend = friend; + console.log(this.name, ": I'm now friends ❤️ with ", friend.name); + return true; + } + get isPlaying() { + return (this.isMoving && + (this.currentStateEnum === "run-right" /* States.runRight */ || + this.currentStateEnum === "run-left" /* States.runLeft */)); + } + get emoji() { + return '🐶'; + } +} +exports.BasePetType = BasePetType; /***/ }), @@ -846,497 +605,664 @@ function petPanelApp(basePetUri, theme, themeKind, petColor, petSize, petType, s ctx.fillStyle = '#2ed851'; ctx.fill(); } - console.log('Starting pet session', petColor, basePetUri, petType); - // New session - var state = stateApi?.getState(); - if (!state) { - console.log('No state, starting a new session.'); - petCounter = 1; - exports.allPets.push(addPetToPanel(petType, basePetUri, petColor, petSize, randomStartPosition(), floor, floor, (0, names_1.randomName)(petType), stateApi)); - saveState(stateApi); + console.log('Starting pet session', petColor, basePetUri, petType); + // New session + var state = stateApi?.getState(); + if (!state) { + console.log('No state, starting a new session.'); + petCounter = 1; + exports.allPets.push(addPetToPanel(petType, basePetUri, petColor, petSize, randomStartPosition(), floor, floor, (0, names_1.randomName)(petType), stateApi)); + saveState(stateApi); + } + else { + console.log('Recovering state - ', state); + recoverState(basePetUri, petSize, floor, stateApi); + } + initCanvas(); + // Handle messages sent from the extension to the webview + window.addEventListener('message', (event) => { + const message = event.data; // The json data that the extension sent + switch (message.command) { + case 'throw-ball': + resetBall(); + throwBall(); + exports.allPets.pets.forEach((petEl) => { + if (petEl.pet.canChase) { + petEl.pet.chase(ballState, canvas); + } + }); + break; + case 'spawn-pet': + exports.allPets.push(addPetToPanel(message.type, basePetUri, message.color, petSize, randomStartPosition(), floor, floor, message.name ?? (0, names_1.randomName)(message.type), stateApi)); + saveState(stateApi); + break; + case 'list-pets': + var pets = exports.allPets.pets; + stateApi?.postMessage({ + command: 'list-pets', + text: pets + .map((pet) => `${pet.type},${pet.pet.name},${pet.color}`) + .join('\n'), + }); + break; + case 'roll-call': + var pets = exports.allPets.pets; + // go through every single + // pet and then print out their name + pets.forEach((pet) => { + stateApi?.postMessage({ + command: 'info', + text: `${pet.pet.emoji} ${pet.pet.name} (${pet.color} ${pet.type}): ${pet.pet.hello}`, + }); + }); + case 'delete-pet': + var pet = exports.allPets.locate(message.name); + if (pet) { + exports.allPets.remove(message.name); + saveState(stateApi); + stateApi?.postMessage({ + command: 'info', + text: '👋 Removed pet ' + message.name, + }); + } + else { + stateApi?.postMessage({ + command: 'error', + text: `Could not find pet ${message.name}`, + }); + } + break; + case 'reset-pet': + exports.allPets.reset(); + petCounter = 0; + saveState(stateApi); + break; + case 'pause-pet': + petCounter = 1; + saveState(stateApi); + break; + } + }); +} +exports.petPanelApp = petPanelApp; +window.addEventListener('resize', function () { + initCanvas(); +}); + + +/***/ }), + +/***/ "./src/panel/pets.ts": +/*!***************************!*\ + !*** ./src/panel/pets.ts ***! + \***************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.createPet = exports.InvalidPetException = exports.PetCollection = exports.PetElement = void 0; +const cat_1 = __webpack_require__(/*! ./pets/cat */ "./src/panel/pets/cat.ts"); +const clippy_1 = __webpack_require__(/*! ./pets/clippy */ "./src/panel/pets/clippy.ts"); +const cockatiel_1 = __webpack_require__(/*! ./pets/cockatiel */ "./src/panel/pets/cockatiel.ts"); +const crab_1 = __webpack_require__(/*! ./pets/crab */ "./src/panel/pets/crab.ts"); +const dog_1 = __webpack_require__(/*! ./pets/dog */ "./src/panel/pets/dog.ts"); +const mod_1 = __webpack_require__(/*! ./pets/mod */ "./src/panel/pets/mod.ts"); +const rocky_1 = __webpack_require__(/*! ./pets/rocky */ "./src/panel/pets/rocky.ts"); +const rubberduck_1 = __webpack_require__(/*! ./pets/rubberduck */ "./src/panel/pets/rubberduck.ts"); +const snake_1 = __webpack_require__(/*! ./pets/snake */ "./src/panel/pets/snake.ts"); +const totoro_1 = __webpack_require__(/*! ./pets/totoro */ "./src/panel/pets/totoro.ts"); +const zappy_1 = __webpack_require__(/*! ./pets/zappy */ "./src/panel/pets/zappy.ts"); +class PetElement { + el; + collision; + speech; + pet; + color; + type; + remove() { + this.el.remove(); + this.collision.remove(); + this.speech.remove(); + this.color = "null" /* PetColor.null */; + this.type = "null" /* PetType.null */; + } + constructor(el, collision, speech, pet, color, type) { + this.el = el; + this.collision = collision; + this.speech = speech; + this.pet = pet; + this.color = color; + this.type = type; + } +} +exports.PetElement = PetElement; +class PetCollection { + _pets; + constructor() { + this._pets = new Array(0); + } + get pets() { + return this._pets; + } + push(pet) { + this._pets.push(pet); + } + reset() { + this._pets.forEach((pet) => { + pet.remove(); + }); + this._pets = []; + } + locate(name) { + return this._pets.find((collection) => { + return collection.pet.name === name; + }); + } + remove(name) { + this._pets.forEach((pet) => { + if (pet.pet.name === name) { + pet.remove(); + } + }); + this._pets = this._pets.filter((pet) => { + return pet.pet.name !== name; + }); + } + seekNewFriends() { + if (this._pets.length <= 1) { + return []; + } // You can't be friends with yourself. + var messages = new Array(0); + this._pets.forEach((petInCollection) => { + if (petInCollection.pet.hasFriend) { + return; + } // I already have a friend! + this._pets.forEach((potentialFriend) => { + if (potentialFriend.pet.hasFriend) { + return; + } // Already has a friend. sorry. + if (!potentialFriend.pet.canChase) { + return; + } // Pet is busy doing something else. + if (potentialFriend.pet.left > petInCollection.pet.left && + potentialFriend.pet.left < + petInCollection.pet.left + petInCollection.pet.width) { + // We found a possible new friend.. + console.log(petInCollection.pet.name, ' wants to be friends with ', potentialFriend.pet.name, '.'); + if (petInCollection.pet.makeFriendsWith(potentialFriend.pet)) { + potentialFriend.pet.showSpeechBubble('❤️', 2000); + petInCollection.pet.showSpeechBubble('❤️', 2000); + } + } + }); + }); + return messages; + } +} +exports.PetCollection = PetCollection; +class InvalidPetException { + message; + constructor(message) { + this.message = message; + } +} +exports.InvalidPetException = InvalidPetException; +function createPet(petType, el, collision, speech, size, left, bottom, petRoot, floor, name) { + if (name === undefined || name === null || name === '') { + throw new InvalidPetException('name is undefined'); + } + const standardPetArguments = [el, collision, speech, size, left, bottom, petRoot, floor, name]; + switch (petType) { + case "cat" /* PetType.cat */: + return new cat_1.Cat(...standardPetArguments, 3 /* PetSpeed.normal */); + case "dog" /* PetType.dog */: + return new dog_1.Dog(...standardPetArguments, 3 /* PetSpeed.normal */); + case "crab" /* PetType.crab */: + return new crab_1.Crab(...standardPetArguments, 2 /* PetSpeed.slow */); + case "clippy" /* PetType.clippy */: + return new clippy_1.Clippy(...standardPetArguments, 2 /* PetSpeed.slow */); + case "mod" /* PetType.mod */: + return new mod_1.Mod(...standardPetArguments, 3 /* PetSpeed.normal */); + case "totoro" /* PetType.totoro */: + return new totoro_1.Totoro(...standardPetArguments, 3 /* PetSpeed.normal */); + case "snake" /* PetType.snake */: + return new snake_1.Snake(...standardPetArguments, 1 /* PetSpeed.verySlow */); + case "rubber-duck" /* PetType.rubberduck */: + return new rubberduck_1.RubberDuck(...standardPetArguments, 4 /* PetSpeed.fast */); + case "zappy" /* PetType.zappy */: + return new zappy_1.Zappy(...standardPetArguments, 5 /* PetSpeed.veryFast */); + case "rocky" /* PetType.rocky */: + return new rocky_1.Rocky(...standardPetArguments, 0 /* PetSpeed.still */); + case "cockatiel" /* PetType.cockatiel */: + return new cockatiel_1.Cockatiel(...standardPetArguments, 3 /* PetSpeed.normal */); + default: + throw new InvalidPetException("Pet type doesn't exist"); + } +} +exports.createPet = createPet; + + +/***/ }), + +/***/ "./src/panel/pets/cat.ts": +/*!*******************************!*\ + !*** ./src/panel/pets/cat.ts ***! + \*******************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.CAT_NAMES = exports.Cat = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Cat extends basepettype_1.BasePetType { + label = 'cat'; + sequence = { + startingState: "sit-idle" /* States.sitIdle */, + sequenceStates: [ + { + state: "sit-idle" /* States.sitIdle */, + possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], + }, + { + state: "walk-right" /* States.walkRight */, + possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + }, + { + state: "run-right" /* States.runRight */, + possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + }, + { + state: "walk-left" /* States.walkLeft */, + possibleNextStates: [ + "sit-idle" /* States.sitIdle */, + "climb-wall-left" /* States.climbWallLeft */, + "walk-right" /* States.walkRight */, + "run-right" /* States.runRight */, + ], + }, + { + state: "run-left" /* States.runLeft */, + possibleNextStates: [ + "sit-idle" /* States.sitIdle */, + "climb-wall-left" /* States.climbWallLeft */, + "walk-right" /* States.walkRight */, + "run-right" /* States.runRight */, + ], + }, + { + state: "climb-wall-left" /* States.climbWallLeft */, + possibleNextStates: ["wall-hang-left" /* States.wallHangLeft */], + }, + { + state: "wall-hang-left" /* States.wallHangLeft */, + possibleNextStates: ["jump-down-left" /* States.jumpDownLeft */], + }, + { + state: "jump-down-left" /* States.jumpDownLeft */, + possibleNextStates: ["land" /* States.land */], + }, + { + state: "land" /* States.land */, + possibleNextStates: [ + "sit-idle" /* States.sitIdle */, + "walk-right" /* States.walkRight */, + "run-right" /* States.runRight */, + ], + }, + { + state: "chase" /* States.chase */, + possibleNextStates: ["idle-with-ball" /* States.idleWithBall */], + }, + { + state: "idle-with-ball" /* States.idleWithBall */, + possibleNextStates: [ + "walk-right" /* States.walkRight */, + "walk-left" /* States.walkLeft */, + "run-left" /* States.runLeft */, + "run-right" /* States.runRight */, + ], + }, + ], + }; + get emoji() { + return '🐱'; } - else { - console.log('Recovering state - ', state); - recoverState(basePetUri, petSize, floor, stateApi); + get hello() { + return `brrr... Meow!`; } - initCanvas(); - // Handle messages sent from the extension to the webview - window.addEventListener('message', (event) => { - const message = event.data; // The json data that the extension sent - switch (message.command) { - case 'throw-ball': - resetBall(); - throwBall(); - exports.allPets.pets.forEach((petEl) => { - if (petEl.pet.canChase) { - petEl.pet.chase(ballState, canvas); - } - }); - break; - case 'spawn-pet': - exports.allPets.push(addPetToPanel(message.type, basePetUri, message.color, petSize, randomStartPosition(), floor, floor, message.name ?? (0, names_1.randomName)(message.type), stateApi)); - saveState(stateApi); - break; - case 'list-pets': - var pets = exports.allPets.pets; - stateApi?.postMessage({ - command: 'list-pets', - text: pets - .map((pet) => `${pet.type},${pet.pet.name},${pet.color}`) - .join('\n'), - }); - break; - case 'roll-call': - var pets = exports.allPets.pets; - // go through every single - // pet and then print out their name - pets.forEach((pet) => { - stateApi?.postMessage({ - command: 'info', - text: `${pet.pet.emoji} ${pet.pet.name} (${pet.color} ${pet.type}): ${pet.pet.hello}`, - }); - }); - case 'delete-pet': - var pet = exports.allPets.locate(message.name); - if (pet) { - exports.allPets.remove(message.name); - saveState(stateApi); - stateApi?.postMessage({ - command: 'info', - text: '👋 Removed pet ' + message.name, - }); - } - else { - stateApi?.postMessage({ - command: 'error', - text: `Could not find pet ${message.name}`, - }); - } - break; - case 'reset-pet': - exports.allPets.reset(); - petCounter = 0; - saveState(stateApi); - break; - case 'pause-pet': - petCounter = 1; - saveState(stateApi); - break; - } - }); } -exports.petPanelApp = petPanelApp; -window.addEventListener('resize', function () { - initCanvas(); -}); +exports.Cat = Cat; +exports.CAT_NAMES = [ + 'Bella', + 'Charlie', + 'Molly', + 'Coco', + 'Ruby', + 'Oscar', + 'Lucy', + 'Bailey', + 'Milo', + 'Daisy', + 'Archie', + 'Ollie', + 'Rosie', + 'Lola', + 'Frankie', + 'Roxy', + 'Poppy', + 'Luna', + 'Jack', + 'Millie', + 'Teddy', + 'Cooper', + 'Bear', + 'Rocky', + 'Alfie', + 'Hugo', + 'Bonnie', + 'Pepper', + 'Lily', + 'Tilly', + 'Leo', + 'Maggie', + 'George', + 'Mia', + 'Marley', + 'Harley', + 'Chloe', + 'Lulu', + 'Missy', + 'Jasper', + 'Billy', + 'Nala', + 'Monty', + 'Ziggy', + 'Winston', + 'Zeus', + 'Zoe', + 'Stella', + 'Sasha', + 'Rusty', + 'Gus', + 'Baxter', + 'Dexter', + 'Willow', + 'Barney', + 'Bruno', + 'Penny', + 'Honey', + 'Milly', + 'Murphy', + 'Simba', + 'Holly', + 'Benji', + 'Henry', + 'Lilly', + 'Pippa', + 'Shadow', + 'Sam', + 'Lucky', + 'Ellie', + 'Duke', + 'Jessie', + 'Cookie', + 'Harvey', + 'Bruce', + 'Jax', + 'Rex', + 'Louie', + 'Jet', + 'Banjo', + 'Beau', + 'Ella', + 'Ralph', + 'Loki', + 'Lexi', + 'Chester', + 'Sophie', + 'Chilli', + 'Billie', + 'Louis', + 'Scout', + 'Cleo', + 'Purfect', + 'Spot', + 'Bolt', + 'Julia', + 'Ginger', + 'Daisy', + 'Amelia', + 'Oliver', + 'Ghost', + 'Midnight', + 'Pumpkin', + 'Shadow', + 'Binx', + 'Riley', + 'Lenny', + 'Mango', + 'Alex', + 'Boo', + 'Botas', + 'Romeo', + 'Bob', + 'Clyde', + 'Simon', + 'Mimmo', + 'Carlotta', + 'Felix', + 'Duchess', +]; /***/ }), -/***/ "./src/panel/pets.ts": -/*!***************************!*\ - !*** ./src/panel/pets.ts ***! - \***************************/ +/***/ "./src/panel/pets/clippy.ts": +/*!**********************************!*\ + !*** ./src/panel/pets/clippy.ts ***! + \**********************************/ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.createPet = exports.InvalidPetException = exports.Rocky = exports.Zappy = exports.Crab = exports.Cockatiel = exports.RubberDuck = exports.Clippy = exports.Snake = exports.Dog = exports.Cat = exports.Totoro = exports.PetCollection = exports.PetElement = exports.InvalidStateException = void 0; -const states_1 = __webpack_require__(/*! ./states */ "./src/panel/states.ts"); -class InvalidStateException { -} -exports.InvalidStateException = InvalidStateException; -class PetElement { - el; - collision; - speech; - pet; - color; - type; - remove() { - this.el.remove(); - this.collision.remove(); - this.speech.remove(); - this.color = "null" /* PetColor.null */; - this.type = "null" /* PetType.null */; - } - constructor(el, collision, speech, pet, color, type) { - this.el = el; - this.collision = collision; - this.speech = speech; - this.pet = pet; - this.color = color; - this.type = type; - } -} -exports.PetElement = PetElement; -class PetCollection { - _pets; - constructor() { - this._pets = new Array(0); - } - get pets() { - return this._pets; - } - push(pet) { - this._pets.push(pet); - } - reset() { - this._pets.forEach((pet) => { - pet.remove(); - }); - this._pets = []; - } - locate(name) { - return this._pets.find((collection) => { - return collection.pet.name === name; - }); - } - remove(name) { - this._pets.forEach((pet) => { - if (pet.pet.name === name) { - pet.remove(); - } - }); - this._pets = this._pets.filter((pet) => { - return pet.pet.name !== name; - }); - } - seekNewFriends() { - if (this._pets.length <= 1) { - return []; - } // You can't be friends with yourself. - var messages = new Array(0); - this._pets.forEach((petInCollection) => { - if (petInCollection.pet.hasFriend) { - return; - } // I already have a friend! - this._pets.forEach((potentialFriend) => { - if (potentialFriend.pet.hasFriend) { - return; - } // Already has a friend. sorry. - if (!potentialFriend.pet.canChase) { - return; - } // Pet is busy doing something else. - if (potentialFriend.pet.left > petInCollection.pet.left && - potentialFriend.pet.left < - petInCollection.pet.left + petInCollection.pet.width) { - // We found a possible new friend.. - console.log(petInCollection.pet.name, ' wants to be friends with ', potentialFriend.pet.name, '.'); - if (petInCollection.pet.makeFriendsWith(potentialFriend.pet)) { - potentialFriend.pet.showSpeechBubble('❤️', 2000); - petInCollection.pet.showSpeechBubble('❤️', 2000); - } - } - }); - }); - return messages; - } -} -exports.PetCollection = PetCollection; -function calculateSpriteWidth(size) { - if (size === "nano" /* PetSize.nano */) { - return 30; - } - else if (size === "medium" /* PetSize.medium */) { - return 55; - } - else if (size === "large" /* PetSize.large */) { - return 110; - } - else { - return 30; // Shrug - } -} -class BasePetType { - label = 'base'; - static count = 0; +exports.CLIPPY_NAMES = exports.Clippy = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Clippy extends basepettype_1.BasePetType { + label = 'clippy'; sequence = { startingState: "sit-idle" /* States.sitIdle */, - sequenceStates: [], + sequenceStates: [ + { + state: "sit-idle" /* States.sitIdle */, + possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], + }, + { + state: "walk-right" /* States.walkRight */, + possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + }, + { + state: "run-right" /* States.runRight */, + possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + }, + { + state: "walk-left" /* States.walkLeft */, + possibleNextStates: ["sit-idle" /* States.sitIdle */], + }, + { + state: "run-left" /* States.runLeft */, + possibleNextStates: ["sit-idle" /* States.sitIdle */], + }, + { + state: "chase" /* States.chase */, + possibleNextStates: ["idle-with-ball" /* States.idleWithBall */], + }, + { + state: "idle-with-ball" /* States.idleWithBall */, + possibleNextStates: [ + "walk-right" /* States.walkRight */, + "walk-left" /* States.walkLeft */, + "run-left" /* States.runLeft */, + "run-right" /* States.runRight */, + ], + }, + ], }; - currentState; - currentStateEnum; - holdState; - holdStateEnum; - el; - collision; - speech; - _left; - _bottom; - petRoot; - _floor; - _friend; - _name; - _speed; - _size; - constructor(spriteElement, collisionElement, speechElement, size, left, bottom, petRoot, floor, name, speed) { - this.el = spriteElement; - this.collision = collisionElement; - this.speech = speechElement; - this.petRoot = petRoot; - this._floor = floor; - this._left = left; - this._bottom = bottom; - this.initSprite(size, left, bottom); - this.currentStateEnum = this.sequence.startingState; - this.currentState = (0, states_1.resolveState)(this.currentStateEnum, this); - this._name = name; - this._size = size; - this._speed = this.randomizeSpeed(speed); - // Increment the static count of the Pet class that the constructor belongs to - this.constructor.count += 1; - } - initSprite(petSize, left, bottom) { - this.el.style.left = `${left}px`; - this.el.style.bottom = `${bottom}px`; - this.el.style.width = 'auto'; - this.el.style.height = 'auto'; - this.el.style.maxWidth = `${calculateSpriteWidth(petSize)}px`; - this.el.style.maxHeight = `${calculateSpriteWidth(petSize)}px`; - this.collision.style.left = `${left}px`; - this.collision.style.bottom = `${bottom}px`; - this.collision.style.width = `${calculateSpriteWidth(petSize)}px`; - this.collision.style.height = `${calculateSpriteWidth(petSize)}px`; - this.speech.style.left = `${left}px`; - this.speech.style.bottom = `${bottom + calculateSpriteWidth(petSize)}px`; - this.hideSpeechBubble(); - } - get left() { - return this._left; - } - get bottom() { - return this._bottom; - } - repositionAccompanyingElements() { - this.collision.style.left = `${this._left}px`; - this.collision.style.bottom = `${this._bottom}px`; - this.speech.style.left = `${this._left}px`; - this.speech.style.bottom = `${this._bottom + calculateSpriteWidth(this._size)}px`; - } - positionBottom(bottom) { - this._bottom = bottom; - this.el.style.bottom = `${this._bottom}px`; - this.repositionAccompanyingElements(); - } - positionLeft(left) { - this._left = left; - this.el.style.left = `${this._left}px`; - this.repositionAccompanyingElements(); - } - get width() { - return this.el.width; - } - get floor() { - return this._floor; + get emoji() { + return '📎'; } get hello() { - // return the sound of the name of the animal - return ` says hello 👋!`; - } - getState() { - return { currentStateEnum: this.currentStateEnum }; - } - get speed() { - return this._speed; - } - randomizeSpeed(speed) { - const min = speed * 0.7; - const max = speed * 1.3; - const newSpeed = Math.random() * (max - min) + min; - return newSpeed; - } - get isMoving() { - return this._speed !== 0 /* PetSpeed.still */; - } - recoverFriend(friend) { - // Recover friends.. - this._friend = friend; - } - recoverState(state) { - // TODO : Resolve a bug where if it was swiping before, it would fail - // because holdState is no longer valid. - this.currentStateEnum = state.currentStateEnum ?? "sit-idle" /* States.sitIdle */; - this.currentState = (0, states_1.resolveState)(this.currentStateEnum, this); - if (!(0, states_1.isStateAboveGround)(this.currentStateEnum)) { - // Reset the bottom of the sprite to the floor as the theme - // has likely changed. - this.positionBottom(this.floor); - } - } - get canSwipe() { - return !(0, states_1.isStateAboveGround)(this.currentStateEnum); - } - get canChase() { - return (!(0, states_1.isStateAboveGround)(this.currentStateEnum) && - this.currentStateEnum !== "chase" /* States.chase */ && - this.isMoving); - } - showSpeechBubble(message, duration = 3000) { - this.speech.innerHTML = message; - this.speech.style.display = 'block'; - setTimeout(() => { - this.hideSpeechBubble(); - }, duration); - } - hideSpeechBubble() { - this.speech.style.display = 'none'; - } - swipe() { - if (this.currentStateEnum === "swipe" /* States.swipe */) { - return; - } - this.holdState = this.currentState; - this.holdStateEnum = this.currentStateEnum; - this.currentStateEnum = "swipe" /* States.swipe */; - this.currentState = (0, states_1.resolveState)(this.currentStateEnum, this); - this.showSpeechBubble('👋'); - } - chase(ballState, canvas) { - this.currentStateEnum = "chase" /* States.chase */; - this.currentState = new states_1.ChaseState(this, ballState, canvas); - } - faceLeft() { - this.el.style.transform = 'scaleX(-1)'; - } - faceRight() { - this.el.style.transform = 'scaleX(1)'; - } - setAnimation(face) { - if (this.el.src.endsWith(`_${face}_8fps.gif`)) { - return; - } - this.el.src = `${this.petRoot}_${face}_8fps.gif`; - } - chooseNextState(fromState) { - // Work out next state - var possibleNextStates = undefined; - for (var i = 0; i < this.sequence.sequenceStates.length; i++) { - if (this.sequence.sequenceStates[i].state === fromState) { - possibleNextStates = - this.sequence.sequenceStates[i].possibleNextStates; - } - } - if (!possibleNextStates) { - throw new InvalidStateException(); - } - // randomly choose the next state - const idx = Math.floor(Math.random() * possibleNextStates.length); - return possibleNextStates[idx]; - } - nextFrame() { - if (this.currentState.horizontalDirection === states_1.HorizontalDirection.left) { - this.faceLeft(); - } - else if (this.currentState.horizontalDirection === states_1.HorizontalDirection.right) { - this.faceRight(); - } - this.setAnimation(this.currentState.spriteLabel); - // What's my buddy doing? - if (this.hasFriend && - this.currentStateEnum !== "chase-friend" /* States.chaseFriend */ && - this.isMoving) { - if (this.friend?.isPlaying && - !(0, states_1.isStateAboveGround)(this.currentStateEnum)) { - this.currentState = (0, states_1.resolveState)("chase-friend" /* States.chaseFriend */, this); - this.currentStateEnum = "chase-friend" /* States.chaseFriend */; - return; - } - } - var frameResult = this.currentState.nextFrame(); - if (frameResult === states_1.FrameResult.stateComplete) { - // If recovering from swipe.. - if (this.holdState && this.holdStateEnum) { - this.currentState = this.holdState; - this.currentStateEnum = this.holdStateEnum; - this.holdState = undefined; - this.holdStateEnum = undefined; - return; - } - var nextState = this.chooseNextState(this.currentStateEnum); - this.currentState = (0, states_1.resolveState)(nextState, this); - this.currentStateEnum = nextState; - } - else if (frameResult === states_1.FrameResult.stateCancel) { - if (this.currentStateEnum === "chase" /* States.chase */) { - var nextState = this.chooseNextState("idle-with-ball" /* States.idleWithBall */); - this.currentState = (0, states_1.resolveState)(nextState, this); - this.currentStateEnum = nextState; - } - else if (this.currentStateEnum === "chase-friend" /* States.chaseFriend */) { - var nextState = this.chooseNextState("idle-with-ball" /* States.idleWithBall */); - this.currentState = (0, states_1.resolveState)(nextState, this); - this.currentStateEnum = nextState; - } - } - } - get hasFriend() { - return this._friend !== undefined; - } - get friend() { - return this._friend; - } - get name() { - return this._name; - } - makeFriendsWith(friend) { - this._friend = friend; - console.log(this.name, ": I'm now friends ❤️ with ", friend.name); - return true; - } - get isPlaying() { - return (this.isMoving && - (this.currentStateEnum === "run-right" /* States.runRight */ || - this.currentStateEnum === "run-left" /* States.runLeft */)); + return ` Hi, I'm Clippy, would you like some assistance today? 👋!`; } +} +exports.Clippy = Clippy; +exports.CLIPPY_NAMES = [ + 'Clippy', + 'Karl Klammer', + 'Clippy Jr.', + 'Molly', + 'Coco', + 'Buddy', + 'Ruby', + 'Oscar', + 'Lucy', + 'Bailey', +]; + + +/***/ }), + +/***/ "./src/panel/pets/cockatiel.ts": +/*!*************************************!*\ + !*** ./src/panel/pets/cockatiel.ts ***! + \*************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.COCKATIEL_NAMES = exports.Cockatiel = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Cockatiel extends basepettype_1.BasePetType { + label = 'cockatiel'; + sequence = { + startingState: "sit-idle" /* States.sitIdle */, + sequenceStates: [ + { + state: "sit-idle" /* States.sitIdle */, + possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], + }, + { + state: "walk-right" /* States.walkRight */, + possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + }, + { + state: "run-right" /* States.runRight */, + possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + }, + { + state: "walk-left" /* States.walkLeft */, + possibleNextStates: ["sit-idle" /* States.sitIdle */], + }, + { + state: "run-left" /* States.runLeft */, + possibleNextStates: ["sit-idle" /* States.sitIdle */], + }, + { + state: "chase" /* States.chase */, + possibleNextStates: ["idle-with-ball" /* States.idleWithBall */], + }, + { + state: "idle-with-ball" /* States.idleWithBall */, + possibleNextStates: [ + "walk-right" /* States.walkRight */, + "walk-left" /* States.walkLeft */, + "run-left" /* States.runLeft */, + "run-right" /* States.runRight */, + ], + }, + ], + }; get emoji() { - return '🐶'; + return '🦜'; + } + get hello() { + // TODO: #191 Add a custom message for cockatiel + return ` Hello, I'm a good bird 👋!`; } } -class Totoro extends BasePetType { - label = 'totoro'; +exports.Cockatiel = Cockatiel; +exports.COCKATIEL_NAMES = [ + 'Cocktail', + 'Pipsqueak', + 'Sir Chirps a Lot', + 'Nibbles', + 'Lord of the Wings', + 'Girl Nest Door', + 'Wingman', + 'Meryl Cheep', + 'Jack Sparrow', + 'Godfeather', + 'Mickey', + 'Baquack Obama', + 'Dame Judi Finch', + 'Kanye Nest', + 'Speck', + 'Cheecky', + 'Arthur', + 'Paco', + 'Bobo', + 'Walt', + 'Happy', + 'Junior', + 'Coco', + 'Yoyo', + 'Milo', + 'Skipper', + 'Scarlet', + 'Diva', + 'Ursula', + 'Donna', + 'Lola', + 'Kiko', + 'Luna', +]; + + +/***/ }), + +/***/ "./src/panel/pets/crab.ts": +/*!********************************!*\ + !*** ./src/panel/pets/crab.ts ***! + \********************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.CRAB_NAMES = exports.Crab = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Crab extends basepettype_1.BasePetType { + label = 'crab'; sequence = { startingState: "sit-idle" /* States.sitIdle */, sequenceStates: [ { state: "sit-idle" /* States.sitIdle */, - possibleNextStates: ["walk-right" /* States.walkRight */, "lie" /* States.lie */], - }, - { - state: "lie" /* States.lie */, - possibleNextStates: ["walk-right" /* States.walkRight */, "walk-left" /* States.walkLeft */], + possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], }, { state: "walk-right" /* States.walkRight */, - possibleNextStates: ["walk-left" /* States.walkLeft */, "sit-idle" /* States.sitIdle */], - }, - { - state: "walk-left" /* States.walkLeft */, - possibleNextStates: [ - "sit-idle" /* States.sitIdle */, - "climb-wall-left" /* States.climbWallLeft */, - "sit-idle" /* States.sitIdle */, - ], - }, - { - state: "climb-wall-left" /* States.climbWallLeft */, - possibleNextStates: ["wall-hang-left" /* States.wallHangLeft */], + possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], }, { - state: "wall-hang-left" /* States.wallHangLeft */, - possibleNextStates: ["jump-down-left" /* States.jumpDownLeft */], + state: "run-right" /* States.runRight */, + possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], }, { - state: "jump-down-left" /* States.jumpDownLeft */, - possibleNextStates: ["land" /* States.land */], + state: "walk-left" /* States.walkLeft */, + possibleNextStates: ["sit-idle" /* States.sitIdle */], }, { - state: "land" /* States.land */, - possibleNextStates: [ - "sit-idle" /* States.sitIdle */, - "walk-right" /* States.walkRight */, - "lie" /* States.lie */, - ], + state: "run-left" /* States.runLeft */, + possibleNextStates: ["sit-idle" /* States.sitIdle */], }, { state: "chase" /* States.chase */, @@ -1344,25 +1270,104 @@ class Totoro extends BasePetType { }, { state: "idle-with-ball" /* States.idleWithBall */, - possibleNextStates: ["walk-right" /* States.walkRight */, "walk-left" /* States.walkLeft */], + possibleNextStates: [ + "walk-right" /* States.walkRight */, + "walk-left" /* States.walkLeft */, + "run-left" /* States.runLeft */, + "run-right" /* States.runRight */, + ], }, ], }; get emoji() { - return '🐾'; + return '🦀'; } get hello() { - return `Try Laughing. Then Whatever Scares You Will Go Away. 🎭`; + return ` Hi, I'm Crabsolutely Clawsome Crab 👋!`; } } -exports.Totoro = Totoro; -class Cat extends BasePetType { - label = 'cat'; +exports.Crab = Crab; +exports.CRAB_NAMES = [ + 'Ferris', + 'Pinchy', + 'Grabby', + 'Big Red', + 'Crabby', + 'Buddy', + 'Ruby Red', + 'Oscar', + 'Lucy', + 'Bailey', + 'Crabito', + 'Percy', + 'Rocky', + 'Mr. Krabs', + 'Shelly', + 'Santa Claws', + 'Clawdia', + 'Scuttle', + 'Snappy', + 'Hermit', + 'Horseshoe', + 'Snapper', + 'Coconut', + 'Sebastian', + 'Abby', + 'Bubbles', + 'Bait', + 'Big Mac', + 'Biggie', + 'Claws', + 'Copper', + 'Crabette', + 'Crabina', + 'Crabmister', + 'Crusty', + 'Crabcake', + 'Digger', + 'Nipper', + 'Pincer', + 'Poopsie', + 'Recluse', + 'Salty', + 'Squirt', + 'Groucho', + 'Grumpy', + 'Lenny Krabitz', + 'Leonardo DaPinchy', + 'Peeves', + 'Penny Pincher', + 'Prickl', +]; + + +/***/ }), + +/***/ "./src/panel/pets/dog.ts": +/*!*******************************!*\ + !*** ./src/panel/pets/dog.ts ***! + \*******************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.DOG_NAMES = exports.Dog = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Dog extends basepettype_1.BasePetType { + label = 'dog'; sequence = { startingState: "sit-idle" /* States.sitIdle */, sequenceStates: [ { state: "sit-idle" /* States.sitIdle */, + possibleNextStates: [ + "walk-right" /* States.walkRight */, + "run-right" /* States.runRight */, + "lie" /* States.lie */, + ], + }, + { + state: "lie" /* States.lie */, possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], }, { @@ -1377,7 +1382,7 @@ class Cat extends BasePetType { state: "walk-left" /* States.walkLeft */, possibleNextStates: [ "sit-idle" /* States.sitIdle */, - "climb-wall-left" /* States.climbWallLeft */, + "lie" /* States.lie */, "walk-right" /* States.walkRight */, "run-right" /* States.runRight */, ], @@ -1386,27 +1391,7 @@ class Cat extends BasePetType { state: "run-left" /* States.runLeft */, possibleNextStates: [ "sit-idle" /* States.sitIdle */, - "climb-wall-left" /* States.climbWallLeft */, - "walk-right" /* States.walkRight */, - "run-right" /* States.runRight */, - ], - }, - { - state: "climb-wall-left" /* States.climbWallLeft */, - possibleNextStates: ["wall-hang-left" /* States.wallHangLeft */], - }, - { - state: "wall-hang-left" /* States.wallHangLeft */, - possibleNextStates: ["jump-down-left" /* States.jumpDownLeft */], - }, - { - state: "jump-down-left" /* States.jumpDownLeft */, - possibleNextStates: ["land" /* States.land */], - }, - { - state: "land" /* States.land */, - possibleNextStates: [ - "sit-idle" /* States.sitIdle */, + "lie" /* States.lie */, "walk-right" /* States.walkRight */, "run-right" /* States.runRight */, ], @@ -1427,28 +1412,173 @@ class Cat extends BasePetType { ], }; get emoji() { - return '🐱'; + return '🐶'; } get hello() { - return `brrr... Meow!`; + return ` Every dog has its day - and today is woof day! Today I just want to bark. Take me on a walk`; } } -exports.Cat = Cat; -class Dog extends BasePetType { - label = 'dog'; +exports.Dog = Dog; +exports.DOG_NAMES = [ + 'Bella', + 'Charlie', + 'Max', + 'Molly', + 'Coco', + 'Buddy', + 'Ruby', + 'Oscar', + 'Lucy', + 'Bailey', + 'Milo', + 'Daisy', + 'Archie', + 'Ollie', + 'Rosie', + 'Lola', + 'Frankie', + 'Toby', + 'Roxy', + 'Poppy', + 'Luna', + 'Jack', + 'Millie', + 'Teddy', + 'Harry', + 'Cooper', + 'Bear', + 'Rocky', + 'Alfie', + 'Hugo', + 'Bonnie', + 'Pepper', + 'Lily', + 'Leo', + 'Maggie', + 'George', + 'Mia', + 'Marley', + 'Harley', + 'Chloe', + 'Lulu', + 'Jasper', + 'Billy', + 'Nala', + 'Monty', + 'Ziggy', + 'Winston', + 'Zeus', + 'Zoe', + 'Stella', + 'Sasha', + 'Rusty', + 'Gus', + 'Baxter', + 'Dexter', + 'Diesel', + 'Willow', + 'Barney', + 'Bruno', + 'Penny', + 'Honey', + 'Milly', + 'Murphy', + 'Holly', + 'Benji', + 'Henry', + 'Lilly', + 'Pippa', + 'Shadow', + 'Sam', + 'Buster', + 'Lucky', + 'Ellie', + 'Duke', + 'Jessie', + 'Cookie', + 'Harvey', + 'Bruce', + 'Jax', + 'Rex', + 'Louie', + 'Bentley', + 'Jet', + 'Banjo', + 'Beau', + 'Ella', + 'Ralph', + 'Loki', + 'Lexi', + 'Chester', + 'Sophie', + 'Billie', + 'Louis', + 'Charlie', + 'Cleo', + 'Spot', + 'Harry', + 'Bolt', + 'Ein', + 'Maddy', + 'Ghost', + 'Midnight', + 'Pumpkin', + 'Shadow', + 'Sparky', + 'Linus', + 'Cody', + 'Slinky', + 'Toto', + 'Balto', + 'Golfo', + 'Pongo', + 'Beethoven', + 'Hachiko', + 'Scooby', + 'Clifford', + 'Astro', + 'Goofy', + 'Chip', + 'Einstein', + 'Fang', + 'Truman', + 'Uggie', + 'Bingo', + 'Blue', + 'Cometa', + 'Krypto', + 'Huesos', + 'Odie', + 'Snoopy', + 'Aisha', + 'Moly', + 'Chiquita', + 'Chavela', + 'Tramp', + 'Lady', + 'Puddles', +]; + + +/***/ }), + +/***/ "./src/panel/pets/mod.ts": +/*!*******************************!*\ + !*** ./src/panel/pets/mod.ts ***! + \*******************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.MOD_NAMES = exports.Mod = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Mod extends basepettype_1.BasePetType { + label = 'mod'; sequence = { startingState: "sit-idle" /* States.sitIdle */, sequenceStates: [ { state: "sit-idle" /* States.sitIdle */, - possibleNextStates: [ - "walk-right" /* States.walkRight */, - "run-right" /* States.runRight */, - "lie" /* States.lie */, - ], - }, - { - state: "lie" /* States.lie */, possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], }, { @@ -1461,21 +1591,11 @@ class Dog extends BasePetType { }, { state: "walk-left" /* States.walkLeft */, - possibleNextStates: [ - "sit-idle" /* States.sitIdle */, - "lie" /* States.lie */, - "walk-right" /* States.walkRight */, - "run-right" /* States.runRight */, - ], + possibleNextStates: ["sit-idle" /* States.sitIdle */], }, { state: "run-left" /* States.runLeft */, - possibleNextStates: [ - "sit-idle" /* States.sitIdle */, - "lie" /* States.lie */, - "walk-right" /* States.walkRight */, - "run-right" /* States.runRight */, - ], + possibleNextStates: ["sit-idle" /* States.sitIdle */], }, { state: "chase" /* States.chase */, @@ -1493,15 +1613,37 @@ class Dog extends BasePetType { ], }; get emoji() { - return '🐶'; + return '🤖'; } get hello() { - return ` Every dog has its day - and today is woof day! Today I just want to bark. Take me on a walk`; + return ` Hi, I'm Mod the dotnet bot, what are you building today?`; } } -exports.Dog = Dog; -class Snake extends BasePetType { - label = 'snake'; +exports.Mod = Mod; +exports.MOD_NAMES = [ + 'Mod', + 'Moddy', + 'Dotnetbot', + 'Bot', + 'Purple Pal', + 'Ro Bot', +]; + + +/***/ }), + +/***/ "./src/panel/pets/rocky.ts": +/*!*********************************!*\ + !*** ./src/panel/pets/rocky.ts ***! + \*********************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.ROCKY_NAMES = exports.Rocky = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Rocky extends basepettype_1.BasePetType { + label = 'rocky'; sequence = { startingState: "sit-idle" /* States.sitIdle */, sequenceStates: [ @@ -1511,100 +1653,65 @@ class Snake extends BasePetType { }, { state: "walk-right" /* States.walkRight */, - possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + possibleNextStates: ["sit-idle" /* States.sitIdle */, "run-right" /* States.runRight */], }, { state: "run-right" /* States.runRight */, - possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], - }, - { - state: "walk-left" /* States.walkLeft */, - possibleNextStates: [ - "sit-idle" /* States.sitIdle */, - "walk-right" /* States.walkRight */, - "run-right" /* States.runRight */, - ], - }, - { - state: "run-left" /* States.runLeft */, - possibleNextStates: [ - "sit-idle" /* States.sitIdle */, - "walk-right" /* States.walkRight */, - "run-right" /* States.runRight */, - ], - }, - { - state: "chase" /* States.chase */, - possibleNextStates: ["idle-with-ball" /* States.idleWithBall */], - }, - { - state: "idle-with-ball" /* States.idleWithBall */, - possibleNextStates: [ - "walk-right" /* States.walkRight */, - "walk-left" /* States.walkLeft */, - "run-left" /* States.runLeft */, - "run-right" /* States.runRight */, - ], + possibleNextStates: ["sit-idle" /* States.sitIdle */, "walk-right" /* States.walkRight */], }, ], }; get emoji() { - return '🐍'; - } - get hello() { - return `Sss... Oh. Oh my gosh! I'm a snake!`; + return '💎'; } -} -exports.Snake = Snake; -class Clippy extends BasePetType { - label = 'clippy'; - sequence = { - startingState: "sit-idle" /* States.sitIdle */, - sequenceStates: [ - { - state: "sit-idle" /* States.sitIdle */, - possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], - }, - { - state: "walk-right" /* States.walkRight */, - possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], - }, - { - state: "run-right" /* States.runRight */, - possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], - }, - { - state: "walk-left" /* States.walkLeft */, - possibleNextStates: ["sit-idle" /* States.sitIdle */], - }, - { - state: "run-left" /* States.runLeft */, - possibleNextStates: ["sit-idle" /* States.sitIdle */], - }, - { - state: "chase" /* States.chase */, - possibleNextStates: ["idle-with-ball" /* States.idleWithBall */], - }, - { - state: "idle-with-ball" /* States.idleWithBall */, - possibleNextStates: [ - "walk-right" /* States.walkRight */, - "walk-left" /* States.walkLeft */, - "run-left" /* States.runLeft */, - "run-right" /* States.runRight */, - ], - }, - ], - }; - get emoji() { - return '📎'; + get canChase() { + return false; } get hello() { - return ` Hi, I'm Clippy, would you like some assistance today? 👋!`; + return ` 👋 I'm rock! I always Rock`; } } -exports.Clippy = Clippy; -class RubberDuck extends BasePetType { +exports.Rocky = Rocky; +exports.ROCKY_NAMES = [ + 'Rocky', + 'The Rock', + 'Quartzy', + 'Rocky I', + 'Rocky II', + 'Rocky III', + 'Pebbles Sr.', + 'Big Granite', + 'Boulder', + 'Rockefeller', + 'Pebble', + 'Rocksanne', + 'Rockstar', + 'Onix', + 'Rock and Roll', + 'Dolomite', + 'Granite', + 'Miss Marble', + 'Rock On', + 'Amberstone', + 'Rock With Me', + 'Rock On It', + 'Rock Out', +]; + + +/***/ }), + +/***/ "./src/panel/pets/rubberduck.ts": +/*!**************************************!*\ + !*** ./src/panel/pets/rubberduck.ts ***! + \**************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.DUCK_NAMES = exports.RubberDuck = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class RubberDuck extends basepettype_1.BasePetType { label = 'rubber-duck'; sequence = { startingState: "sit-idle" /* States.sitIdle */, @@ -1652,8 +1759,82 @@ class RubberDuck extends BasePetType { } } exports.RubberDuck = RubberDuck; -class Cockatiel extends BasePetType { - label = 'cockatiel'; +exports.DUCK_NAMES = [ + 'Quacky', + 'Floaty', + 'Duck', + 'Molly', + 'Sunshine', + 'Buddy', + 'Chirpy', + 'Oscar', + 'Lucy', + 'Bailey', + 'Beaky', + 'Jemima', + 'Peaches', + 'Quackers', + 'Jelly Beans', + 'Donald', + 'Chady', + 'Waddles', + 'Bill', + 'Bubbles', + 'James Pond', + 'Moby Duck', + 'Quack Sparrow', + 'Peanut', + 'Psyduck', + 'Mr Quack', + 'Louie', + 'Golduck', + 'Daisy', + 'Pickles', + 'Ducky Duck', + 'Mrs Fluffs', + 'Squeek', + 'Ace', + 'Rubberduck', + 'Mrs Beak', + 'April', + 'Tutu', + 'Billy the duck', + 'Ducky', + 'Neco', + 'Dodo', + 'Colonel', + 'Franklin', + 'Emmett', + 'Bubba', + 'Dillard', + 'Duncan', + 'Pogo', + 'Uno', + 'Peanut', + 'Nero', + 'Mowgli', + 'Eggspresso', + 'Webster', + 'Quacker Jack', + 'Plucker', + 'Meeko', +]; + + +/***/ }), + +/***/ "./src/panel/pets/snake.ts": +/*!*********************************!*\ + !*** ./src/panel/pets/snake.ts ***! + \*********************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SNAKE_NAMES = exports.Snake = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Snake extends basepettype_1.BasePetType { + label = 'snake'; sequence = { startingState: "sit-idle" /* States.sitIdle */, sequenceStates: [ @@ -1671,11 +1852,19 @@ class Cockatiel extends BasePetType { }, { state: "walk-left" /* States.walkLeft */, - possibleNextStates: ["sit-idle" /* States.sitIdle */], + possibleNextStates: [ + "sit-idle" /* States.sitIdle */, + "walk-right" /* States.walkRight */, + "run-right" /* States.runRight */, + ], }, { state: "run-left" /* States.runLeft */, - possibleNextStates: ["sit-idle" /* States.sitIdle */], + possibleNextStates: [ + "sit-idle" /* States.sitIdle */, + "walk-right" /* States.walkRight */, + "run-right" /* States.runRight */, + ], }, { state: "chase" /* States.chase */, @@ -1693,63 +1882,172 @@ class Cockatiel extends BasePetType { ], }; get emoji() { - return '🦜'; + return '🐍'; } get hello() { - // TODO: #191 Add a custom message for cockatiel - return ` Hello, I'm a good bird 👋!`; + return `Sss... Oh. Oh my gosh! I'm a snake!`; } } -exports.Cockatiel = Cockatiel; -class Crab extends BasePetType { - label = 'crab'; +exports.Snake = Snake; +exports.SNAKE_NAMES = [ + 'Sneaky', + 'Mr Slippery', + 'Hissy Elliott', + 'Molly', + 'Coco', + 'Buddy', + 'Ruby', + 'Bailey', + 'Max', + 'Seb', + 'Kaa', + 'Mr Hiss', + 'Miss Hiss', + 'Snaku', + 'Kaa', + 'Madame Snake', + 'Sir Hiss', + 'Loki', + 'Steelix', + 'Gyarados', + 'Seviper', + 'Ekanes', + 'Arbok', + 'Snivy', + 'Servine', + 'Serperior', + 'Mojo', + 'Moss', + 'Nigel', + 'Tootsie', + 'Sammy', + 'Ziggy', + 'Asmodeus', + 'Attila', + 'Basil', + 'Diablo', + 'Eden', + 'Eve', + 'Heaven', + 'Hydra', + 'Indiana', + 'Jafaar', + 'Kaa', + 'Medusa', + 'Naga', + 'Severus', + 'Slytherin', + 'Snape', + 'Raven', + 'Slider', + 'Slinky', + 'Stripes', +]; + + +/***/ }), + +/***/ "./src/panel/pets/totoro.ts": +/*!**********************************!*\ + !*** ./src/panel/pets/totoro.ts ***! + \**********************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.TOTORO_NAMES = exports.Totoro = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Totoro extends basepettype_1.BasePetType { + label = 'totoro'; sequence = { startingState: "sit-idle" /* States.sitIdle */, sequenceStates: [ { state: "sit-idle" /* States.sitIdle */, - possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], + possibleNextStates: ["walk-right" /* States.walkRight */, "lie" /* States.lie */], }, { - state: "walk-right" /* States.walkRight */, - possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + state: "lie" /* States.lie */, + possibleNextStates: ["walk-right" /* States.walkRight */, "walk-left" /* States.walkLeft */], }, { - state: "run-right" /* States.runRight */, - possibleNextStates: ["walk-left" /* States.walkLeft */, "run-left" /* States.runLeft */], + state: "walk-right" /* States.walkRight */, + possibleNextStates: ["walk-left" /* States.walkLeft */, "sit-idle" /* States.sitIdle */], }, { state: "walk-left" /* States.walkLeft */, - possibleNextStates: ["sit-idle" /* States.sitIdle */], + possibleNextStates: [ + "sit-idle" /* States.sitIdle */, + "climb-wall-left" /* States.climbWallLeft */, + "sit-idle" /* States.sitIdle */, + ], }, { - state: "run-left" /* States.runLeft */, - possibleNextStates: ["sit-idle" /* States.sitIdle */], + state: "climb-wall-left" /* States.climbWallLeft */, + possibleNextStates: ["wall-hang-left" /* States.wallHangLeft */], }, { - state: "chase" /* States.chase */, - possibleNextStates: ["idle-with-ball" /* States.idleWithBall */], + state: "wall-hang-left" /* States.wallHangLeft */, + possibleNextStates: ["jump-down-left" /* States.jumpDownLeft */], }, { - state: "idle-with-ball" /* States.idleWithBall */, + state: "jump-down-left" /* States.jumpDownLeft */, + possibleNextStates: ["land" /* States.land */], + }, + { + state: "land" /* States.land */, possibleNextStates: [ + "sit-idle" /* States.sitIdle */, "walk-right" /* States.walkRight */, - "walk-left" /* States.walkLeft */, - "run-left" /* States.runLeft */, - "run-right" /* States.runRight */, + "lie" /* States.lie */, ], }, + { + state: "chase" /* States.chase */, + possibleNextStates: ["idle-with-ball" /* States.idleWithBall */], + }, + { + state: "idle-with-ball" /* States.idleWithBall */, + possibleNextStates: ["walk-right" /* States.walkRight */, "walk-left" /* States.walkLeft */], + }, ], }; get emoji() { - return '🦀'; + return '🐾'; } get hello() { - return ` Hi, I'm Crabsolutely Clawsome Crab 👋!`; + return `Try Laughing. Then Whatever Scares You Will Go Away. 🎭`; } } -exports.Crab = Crab; -class Zappy extends BasePetType { +exports.Totoro = Totoro; +exports.TOTORO_NAMES = [ + 'Totoro', + 'トトロ', + 'Max', + 'Molly', + 'Coco', + 'Buddy', + 'Ruby', + 'Oscar', + 'Lucy', + 'Bailey', + 'Big fella', +]; + + +/***/ }), + +/***/ "./src/panel/pets/zappy.ts": +/*!*********************************!*\ + !*** ./src/panel/pets/zappy.ts ***! + \*********************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.ZAPPY_NAMES = exports.Zappy = void 0; +const basepettype_1 = __webpack_require__(/*! ../basepettype */ "./src/panel/basepettype.ts"); +class Zappy extends basepettype_1.BasePetType { label = 'zappy'; sequence = { startingState: "sit-idle" /* States.sitIdle */, @@ -1798,74 +2096,25 @@ class Zappy extends BasePetType { } } exports.Zappy = Zappy; -class Rocky extends BasePetType { - label = 'rocky'; - sequence = { - startingState: "sit-idle" /* States.sitIdle */, - sequenceStates: [ - { - state: "sit-idle" /* States.sitIdle */, - possibleNextStates: ["walk-right" /* States.walkRight */, "run-right" /* States.runRight */], - }, - { - state: "walk-right" /* States.walkRight */, - possibleNextStates: ["sit-idle" /* States.sitIdle */, "run-right" /* States.runRight */], - }, - { - state: "run-right" /* States.runRight */, - possibleNextStates: ["sit-idle" /* States.sitIdle */, "walk-right" /* States.walkRight */], - }, - ], - }; - get emoji() { - return '💎'; - } - get canChase() { - return false; - } - get hello() { - return ` 👋 I'm rock! I always Rock`; - } -} -exports.Rocky = Rocky; -class InvalidPetException { - message; - constructor(message) { - this.message = message; - } -} -exports.InvalidPetException = InvalidPetException; -function createPet(petType, el, collision, speech, size, left, bottom, petRoot, floor, name) { - if (name === undefined || name === null || name === '') { - throw new InvalidPetException('name is undefined'); - } - const standardPetArguments = [el, collision, speech, size, left, bottom, petRoot, floor, name]; - switch (petType) { - case "cat" /* PetType.cat */: - return new Cat(...standardPetArguments, 3 /* PetSpeed.normal */); - case "dog" /* PetType.dog */: - return new Dog(...standardPetArguments, 3 /* PetSpeed.normal */); - case "crab" /* PetType.crab */: - return new Crab(...standardPetArguments, 2 /* PetSpeed.slow */); - case "clippy" /* PetType.clippy */: - return new Clippy(...standardPetArguments, 2 /* PetSpeed.slow */); - case "totoro" /* PetType.totoro */: - return new Totoro(...standardPetArguments, 3 /* PetSpeed.normal */); - case "snake" /* PetType.snake */: - return new Snake(...standardPetArguments, 1 /* PetSpeed.verySlow */); - case "rubber-duck" /* PetType.rubberduck */: - return new RubberDuck(...standardPetArguments, 4 /* PetSpeed.fast */); - case "zappy" /* PetType.zappy */: - return new Zappy(...standardPetArguments, 5 /* PetSpeed.veryFast */); - case "rocky" /* PetType.rocky */: - return new Rocky(...standardPetArguments, 0 /* PetSpeed.still */); - case "cockatiel" /* PetType.cockatiel */: - return new Cockatiel(...standardPetArguments, 3 /* PetSpeed.normal */); - default: - throw new InvalidPetException("Pet type doesn't exist"); - } -} -exports.createPet = createPet; +exports.ZAPPY_NAMES = [ + 'Zappy', + 'Zippy', + 'Zappy Jr.', + 'Zoppy', + 'Zuppy', + 'Zeppy', + 'Big Z', + 'Little z', + 'The Flash', + 'Thor', + 'Electric Bolt', + 'Azula', + 'Lightning Bolt', + 'Power', + 'Sonic', + 'Speedy', + 'Rush', +]; /***/ }), diff --git a/media/mod/purple_ball_8fps.gif b/media/mod/purple_ball_8fps.gif new file mode 100644 index 0000000000000000000000000000000000000000..03a73901ded4b5368f685823de5d1eceb8ce8cd5 GIT binary patch literal 4215 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 literal 0 HcmV?d00001 diff --git a/media/mod/purple_idle_8fps.gif b/media/mod/purple_idle_8fps.gif new file mode 100644 index 0000000000000000000000000000000000000000..77cc35406bcd13f7ee7cd35a38ab62970cbb804f GIT binary patch literal 3967 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 b7%#5QevD6LZRbryrS6D;-y^#>zYYHdTxPv5 literal 0 HcmV?d00001 diff --git a/media/mod/purple_run_8fps.gif b/media/mod/purple_run_8fps.gif new file mode 100644 index 0000000000000000000000000000000000000000..db949b09dc6fc4a762fd6ecd75df9ffa9a633368 GIT binary patch literal 3948 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 literal 0 HcmV?d00001 diff --git a/media/mod/purple_swipe_8fps.gif b/media/mod/purple_swipe_8fps.gif new file mode 100644 index 0000000000000000000000000000000000000000..b35abbf0f6cd5b0d815700a1cefb2129d5348bab GIT binary patch literal 12778 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 BqC5Zq literal 0 HcmV?d00001 diff --git a/media/mod/purple_walk_8fps.gif b/media/mod/purple_walk_8fps.gif new file mode 100644 index 0000000000000000000000000000000000000000..7e00b399a6e1b1547d623475693656ece84f6fea GIT binary patch literal 3948 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index d5d13a41..18f47650 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-pets", - "version": "1.15.1", + "version": "1.16.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-pets", - "version": "1.15.1", + "version": "1.16.0", "license": "MIT", "dependencies": { "vscode-nls-i18n": "^0.2.4" diff --git a/package.json b/package.json index 8dad93d8..5b1d330c 100644 --- a/package.json +++ b/package.json @@ -128,6 +128,7 @@ "green", "yellow", "gray", + "purple", "red", "white" ], @@ -143,6 +144,7 @@ "clippy", "cockatiel", "dog", + "mod", "rocky", "rubber-duck", "snake", diff --git a/package.nls.json b/package.nls.json index 1bc53841..35d2f334 100644 --- a/package.nls.json +++ b/package.nls.json @@ -15,6 +15,7 @@ "vscodePets.green": "Green", "vscodePets.yellow": "Yellow", "vscodePets.gray": "Gray", + "vscodePets.purple": "Purple", "vscodePets.red": "Red", "vscodePets.white": "White", @@ -23,6 +24,7 @@ "vscodePets.cockatiel": "Cockatiel", "vscodePets.crab": "Crab", "vscodePets.dog": "Dog", + "vscodePets.mod": "Mod", "vscodePets.rocky": "Rocky", "vscodePets.rubber-duck": "Rubber Duck", "vscodePets.snake": "Snake", diff --git a/src/common/names.ts b/src/common/names.ts index b218f679..5b0aaab5 100644 --- a/src/common/names.ts +++ b/src/common/names.ts @@ -1,545 +1,16 @@ +import { CAT_NAMES } from '../panel/pets/cat'; +import { CLIPPY_NAMES } from '../panel/pets/clippy'; +import { COCKATIEL_NAMES } from '../panel/pets/cockatiel'; +import { CRAB_NAMES } from '../panel/pets/crab'; +import { DOG_NAMES } from '../panel/pets/dog'; +import { MOD_NAMES } from '../panel/pets/mod'; +import { ROCKY_NAMES } from '../panel/pets/rocky'; +import { DUCK_NAMES } from '../panel/pets/rubberduck'; +import { SNAKE_NAMES } from '../panel/pets/snake'; +import { TOTORO_NAMES } from '../panel/pets/totoro'; +import { ZAPPY_NAMES } from '../panel/pets/zappy'; import { PetType } from './types'; -export const CAT_NAMES: ReadonlyArray = [ - 'Bella', - 'Charlie', - 'Molly', - 'Coco', - 'Ruby', - 'Oscar', - 'Lucy', - 'Bailey', - 'Milo', - 'Daisy', - 'Archie', - 'Ollie', - 'Rosie', - 'Lola', - 'Frankie', - 'Roxy', - 'Poppy', - 'Luna', - 'Jack', - 'Millie', - 'Teddy', - 'Cooper', - 'Bear', - 'Rocky', - 'Alfie', - 'Hugo', - 'Bonnie', - 'Pepper', - 'Lily', - 'Tilly', - 'Leo', - 'Maggie', - 'George', - 'Mia', - 'Marley', - 'Harley', - 'Chloe', - 'Lulu', - 'Missy', - 'Jasper', - 'Billy', - 'Nala', - 'Monty', - 'Ziggy', - 'Winston', - 'Zeus', - 'Zoe', - 'Stella', - 'Sasha', - 'Rusty', - 'Gus', - 'Baxter', - 'Dexter', - 'Willow', - 'Barney', - 'Bruno', - 'Penny', - 'Honey', - 'Milly', - 'Murphy', - 'Simba', - 'Holly', - 'Benji', - 'Henry', - 'Lilly', - 'Pippa', - 'Shadow', - 'Sam', - 'Lucky', - 'Ellie', - 'Duke', - 'Jessie', - 'Cookie', - 'Harvey', - 'Bruce', - 'Jax', - 'Rex', - 'Louie', - 'Jet', - 'Banjo', - 'Beau', - 'Ella', - 'Ralph', - 'Loki', - 'Lexi', - 'Chester', - 'Sophie', - 'Chilli', - 'Billie', - 'Louis', - 'Scout', - 'Cleo', - 'Purfect', - 'Spot', - 'Bolt', - 'Julia', - 'Ginger', - 'Daisy', - 'Amelia', - 'Oliver', - 'Ghost', - 'Midnight', - 'Pumpkin', - 'Shadow', - 'Binx', - 'Riley', - 'Lenny', - 'Mango', - 'Alex', - 'Boo', - 'Botas', - 'Romeo', - 'Bob', - 'Clyde', - 'Simon', - 'Mimmo', - 'Carlotta', - 'Felix', - 'Duchess', -]; - -export const DOG_NAMES: ReadonlyArray = [ - 'Bella', - 'Charlie', - 'Max', - 'Molly', - 'Coco', - 'Buddy', - 'Ruby', - 'Oscar', - 'Lucy', - 'Bailey', - 'Milo', - 'Daisy', - 'Archie', - 'Ollie', - 'Rosie', - 'Lola', - 'Frankie', - 'Toby', - 'Roxy', - 'Poppy', - 'Luna', - 'Jack', - 'Millie', - 'Teddy', - 'Harry', - 'Cooper', - 'Bear', - 'Rocky', - 'Alfie', - 'Hugo', - 'Bonnie', - 'Pepper', - 'Lily', - 'Leo', - 'Maggie', - 'George', - 'Mia', - 'Marley', - 'Harley', - 'Chloe', - 'Lulu', - 'Jasper', - 'Billy', - 'Nala', - 'Monty', - 'Ziggy', - 'Winston', - 'Zeus', - 'Zoe', - 'Stella', - 'Sasha', - 'Rusty', - 'Gus', - 'Baxter', - 'Dexter', - 'Diesel', - 'Willow', - 'Barney', - 'Bruno', - 'Penny', - 'Honey', - 'Milly', - 'Murphy', - 'Holly', - 'Benji', - 'Henry', - 'Lilly', - 'Pippa', - 'Shadow', - 'Sam', - 'Buster', - 'Lucky', - 'Ellie', - 'Duke', - 'Jessie', - 'Cookie', - 'Harvey', - 'Bruce', - 'Jax', - 'Rex', - 'Louie', - 'Bentley', - 'Jet', - 'Banjo', - 'Beau', - 'Ella', - 'Ralph', - 'Loki', - 'Lexi', - 'Chester', - 'Sophie', - 'Billie', - 'Louis', - 'Charlie', - 'Cleo', - 'Spot', - 'Harry', - 'Bolt', - 'Ein', - 'Maddy', - 'Ghost', - 'Midnight', - 'Pumpkin', - 'Shadow', - 'Sparky', - 'Linus', - 'Cody', - 'Slinky', - 'Toto', - 'Balto', - 'Golfo', - 'Pongo', - 'Beethoven', - 'Hachiko', - 'Scooby', - 'Clifford', - 'Astro', - 'Goofy', - 'Chip', - 'Einstein', - 'Fang', - 'Truman', - 'Uggie', - 'Bingo', - 'Blue', - 'Cometa', - 'Krypto', - 'Huesos', - 'Odie', - 'Snoopy', - 'Aisha', - 'Moly', - 'Chiquita', - 'Chavela', - 'Tramp', - 'Lady', - 'Puddles', -]; - -export const CRAB_NAMES: ReadonlyArray = [ - 'Ferris', - 'Pinchy', - 'Grabby', - 'Big Red', - 'Crabby', - 'Buddy', - 'Ruby Red', - 'Oscar', - 'Lucy', - 'Bailey', - 'Crabito', - 'Percy', - 'Rocky', - 'Mr. Krabs', - 'Shelly', - 'Santa Claws', - 'Clawdia', - 'Scuttle', - 'Snappy', - 'Hermit', - 'Horseshoe', - 'Snapper', - 'Coconut', - 'Sebastian', - 'Abby', - 'Bubbles', - 'Bait', - 'Big Mac', - 'Biggie', - 'Claws', - 'Copper', - 'Crabette', - 'Crabina', - 'Crabmister', - 'Crusty', - 'Crabcake', - 'Digger', - 'Nipper', - 'Pincer', - 'Poopsie', - 'Recluse', - 'Salty', - 'Squirt', - 'Groucho', - 'Grumpy', - 'Lenny Krabitz', - 'Leonardo DaPinchy', - 'Peeves', - 'Penny Pincher', - 'Prickl', -]; - -export const CLIPPY_NAMES: ReadonlyArray = [ - 'Clippy', - 'Karl Klammer', - 'Clippy Jr.', - 'Molly', - 'Coco', - 'Buddy', - 'Ruby', - 'Oscar', - 'Lucy', - 'Bailey', -]; - -export const TOTORO_NAMES: ReadonlyArray = [ - 'Totoro', - 'トトロ', - 'Max', - 'Molly', - 'Coco', - 'Buddy', - 'Ruby', - 'Oscar', - 'Lucy', - 'Bailey', - 'Big fella', -]; - -export const SNAKE_NAMES: ReadonlyArray = [ - 'Sneaky', - 'Mr Slippery', - 'Hissy Elliott', - 'Molly', - 'Coco', - 'Buddy', - 'Ruby', - 'Bailey', - 'Max', - 'Seb', - 'Kaa', - 'Mr Hiss', - 'Miss Hiss', - 'Snaku', - 'Kaa', - 'Madame Snake', - 'Sir Hiss', - 'Loki', - 'Steelix', - 'Gyarados', - 'Seviper', - 'Ekanes', - 'Arbok', - 'Snivy', - 'Servine', - 'Serperior', - 'Mojo', - 'Moss', - 'Nigel', - 'Tootsie', - 'Sammy', - 'Ziggy', - 'Asmodeus', - 'Attila', - 'Basil', - 'Diablo', - 'Eden', - 'Eve', - 'Heaven', - 'Hydra', - 'Indiana', - 'Jafaar', - 'Kaa', - 'Medusa', - 'Naga', - 'Severus', - 'Slytherin', - 'Snape', - 'Raven', - 'Slider', - 'Slinky', - 'Stripes', -]; - -export const DUCK_NAMES: ReadonlyArray = [ - 'Quacky', - 'Floaty', - 'Duck', - 'Molly', - 'Sunshine', - 'Buddy', - 'Chirpy', - 'Oscar', - 'Lucy', - 'Bailey', - 'Beaky', - 'Jemima', - 'Peaches', - 'Quackers', - 'Jelly Beans', - 'Donald', - 'Chady', - 'Waddles', - 'Bill', - 'Bubbles', - 'James Pond', - 'Moby Duck', - 'Quack Sparrow', - 'Peanut', - 'Psyduck', - 'Mr Quack', - 'Louie', - 'Golduck', - 'Daisy', - 'Pickles', - 'Ducky Duck', - 'Mrs Fluffs', - 'Squeek', - 'Ace', - 'Rubberduck', - 'Mrs Beak', - 'April', - 'Tutu', - 'Billy the duck', - 'Ducky', - 'Neco', - 'Dodo', - 'Colonel', - 'Franklin', - 'Emmett', - 'Bubba', - 'Dillard', - 'Duncan', - 'Pogo', - 'Uno', - 'Peanut', - 'Nero', - 'Mowgli', - 'Eggspresso', - 'Webster', - 'Quacker Jack', - 'Plucker', - 'Meeko', -]; - -export const ZAPPY_NAMES: ReadonlyArray = [ - 'Zappy', - 'Zippy', - 'Zappy Jr.', - 'Zoppy', - 'Zuppy', - 'Zeppy', - 'Big Z', - 'Little z', - 'The Flash', - 'Thor', - 'Electric Bolt', - 'Azula', - 'Lightning Bolt', - 'Power', - 'Sonic', - 'Speedy', - 'Rush', -]; - -export const ROCKY_NAMES: ReadonlyArray = [ - 'Rocky', - 'The Rock', - 'Quartzy', - 'Rocky I', - 'Rocky II', - 'Rocky III', - 'Pebbles Sr.', - 'Big Granite', - 'Boulder', - 'Rockefeller', - 'Pebble', - 'Rocksanne', - 'Rockstar', - 'Onix', - 'Rock and Roll', - 'Dolomite', - 'Granite', - 'Miss Marble', - 'Rock On', - 'Amberstone', - 'Rock With Me', - 'Rock On It', - 'Rock Out', -]; - -export const COCKATIEL_NAMES: ReadonlyArray = [ - 'Cocktail', - 'Pipsqueak', - 'Sir Chirps a Lot', - 'Nibbles', - 'Lord of the Wings', - 'Girl Nest Door', - 'Wingman', - 'Meryl Cheep', - 'Jack Sparrow', - 'Godfeather', - 'Mickey', - 'Baquack Obama', - 'Dame Judi Finch', - 'Kanye Nest', - 'Speck', - 'Cheecky', - 'Arthur', - 'Paco', - 'Bobo', - 'Walt', - 'Happy', - 'Junior', - 'Coco', - 'Yoyo', - 'Milo', - 'Skipper', - 'Scarlet', - 'Diva', - 'Ursula', - 'Donna', - 'Lola', - 'Kiko', - 'Luna', -]; - export function randomName(type: PetType): string { const collection: ReadonlyArray = ( @@ -548,6 +19,7 @@ export function randomName(type: PetType): string { [PetType.dog]: DOG_NAMES, [PetType.crab]: CRAB_NAMES, [PetType.clippy]: CLIPPY_NAMES, + [PetType.mod]: MOD_NAMES, [PetType.totoro]: TOTORO_NAMES, [PetType.snake]: SNAKE_NAMES, [PetType.rubberduck]: DUCK_NAMES, diff --git a/src/common/types.ts b/src/common/types.ts index c5ce047d..5f0a0b38 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -4,6 +4,7 @@ export const enum PetColor { green = 'green', yellow = 'yellow', gray = 'gray', + purple = 'purple', red = 'red', white = 'white', null = 'null', @@ -15,6 +16,7 @@ export const enum PetType { cockatiel = 'cockatiel', crab = 'crab', dog = 'dog', + mod = 'mod', rocky = 'rocky', rubberduck = 'rubber-duck', snake = 'snake', @@ -72,6 +74,7 @@ export const ALL_PETS = [ PetType.cockatiel, PetType.crab, PetType.dog, + PetType.mod, PetType.rocky, PetType.rubberduck, PetType.snake, @@ -84,6 +87,7 @@ export const ALL_COLORS = [ PetColor.green, PetColor.yellow, PetColor.gray, + PetColor.purple, PetColor.red, PetColor.white, PetColor.null, diff --git a/src/extension/extension.ts b/src/extension/extension.ts index 789de4e6..07dfb91a 100644 --- a/src/extension/extension.ts +++ b/src/extension/extension.ts @@ -488,6 +488,9 @@ export function activate(context: vscode.ExtensionContext) { case PetType.zappy: petColor = PetColor.yellow; break; + case PetType.mod: + petColor = PetColor.purple; + break; } if (petColor === undefined) { diff --git a/src/panel/basepettype.ts b/src/panel/basepettype.ts new file mode 100644 index 00000000..36e242d1 --- /dev/null +++ b/src/panel/basepettype.ts @@ -0,0 +1,337 @@ +import { PetSize, PetSpeed } from '../common/types'; +import { IPetType } from './states'; +import { ISequenceTree } from './sequences'; +import { + States, + IState, + resolveState, + PetInstanceState, + isStateAboveGround, + BallState, + ChaseState, + HorizontalDirection, + FrameResult, +} from './states'; + +export class InvalidStateException {} + +export abstract class BasePetType implements IPetType { + label: string = 'base'; + static count: number = 0; + sequence: ISequenceTree = { + startingState: States.sitIdle, + sequenceStates: [], + }; + currentState: IState; + currentStateEnum: States; + holdState: IState | undefined; + holdStateEnum: States | undefined; + private el: HTMLImageElement; + private collision: HTMLDivElement; + private speech: HTMLDivElement; + private _left: number; + private _bottom: number; + petRoot: string; + _floor: number; + _friend: IPetType | undefined; + private _name: string; + private _speed: number; + private _size: PetSize; + + constructor( + spriteElement: HTMLImageElement, + collisionElement: HTMLDivElement, + speechElement: HTMLDivElement, + size: PetSize, + left: number, + bottom: number, + petRoot: string, + floor: number, + name: string, + speed: number, + ) { + this.el = spriteElement; + this.collision = collisionElement; + this.speech = speechElement; + this.petRoot = petRoot; + this._floor = floor; + this._left = left; + this._bottom = bottom; + this.initSprite(size, left, bottom); + this.currentStateEnum = this.sequence.startingState; + this.currentState = resolveState(this.currentStateEnum, this); + + this._name = name; + this._size = size; + this._speed = this.randomizeSpeed(speed); + + // Increment the static count of the Pet class that the constructor belongs to + (this.constructor as any).count += 1; + } + + initSprite(petSize: PetSize, left: number, bottom: number) { + this.el.style.left = `${left}px`; + this.el.style.bottom = `${bottom}px`; + this.el.style.width = 'auto'; + this.el.style.height = 'auto'; + this.el.style.maxWidth = `${this.calculateSpriteWidth(petSize)}px`; + this.el.style.maxHeight = `${this.calculateSpriteWidth(petSize)}px`; + this.collision.style.left = `${left}px`; + this.collision.style.bottom = `${bottom}px`; + this.collision.style.width = `${this.calculateSpriteWidth(petSize)}px`; + this.collision.style.height = `${this.calculateSpriteWidth(petSize)}px`; + this.speech.style.left = `${left}px`; + this.speech.style.bottom = `${ + bottom + this.calculateSpriteWidth(petSize) + }px`; + this.hideSpeechBubble(); + } + + get left(): number { + return this._left; + } + + get bottom(): number { + return this._bottom; + } + + private repositionAccompanyingElements() { + this.collision.style.left = `${this._left}px`; + this.collision.style.bottom = `${this._bottom}px`; + this.speech.style.left = `${this._left}px`; + this.speech.style.bottom = `${ + this._bottom + this.calculateSpriteWidth(this._size) + }px`; + } + + calculateSpriteWidth(size: PetSize): number { + if (size === PetSize.nano) { + return 30; + } else if (size === PetSize.medium) { + return 55; + } else if (size === PetSize.large) { + return 110; + } else { + return 30; // Shrug + } + } + + positionBottom(bottom: number): void { + this._bottom = bottom; + this.el.style.bottom = `${this._bottom}px`; + this.repositionAccompanyingElements(); + } + + positionLeft(left: number): void { + this._left = left; + this.el.style.left = `${this._left}px`; + this.repositionAccompanyingElements(); + } + + get width(): number { + return this.el.width; + } + + get floor(): number { + return this._floor; + } + + get hello(): string { + // return the sound of the name of the animal + return ` says hello 👋!`; + } + + getState(): PetInstanceState { + return { currentStateEnum: this.currentStateEnum }; + } + + get speed(): number { + return this._speed; + } + + randomizeSpeed(speed: number): number { + const min = speed * 0.7; + const max = speed * 1.3; + const newSpeed = Math.random() * (max - min) + min; + return newSpeed; + } + + get isMoving(): boolean { + return this._speed !== PetSpeed.still; + } + + recoverFriend(friend: IPetType) { + // Recover friends.. + this._friend = friend; + } + + recoverState(state: PetInstanceState) { + // TODO : Resolve a bug where if it was swiping before, it would fail + // because holdState is no longer valid. + this.currentStateEnum = state.currentStateEnum ?? States.sitIdle; + this.currentState = resolveState(this.currentStateEnum, this); + + if (!isStateAboveGround(this.currentStateEnum)) { + // Reset the bottom of the sprite to the floor as the theme + // has likely changed. + this.positionBottom(this.floor); + } + } + + get canSwipe() { + return !isStateAboveGround(this.currentStateEnum); + } + + get canChase() { + return ( + !isStateAboveGround(this.currentStateEnum) && + this.currentStateEnum !== States.chase && + this.isMoving + ); + } + + showSpeechBubble(message: string, duration: number = 3000) { + this.speech.innerHTML = message; + this.speech.style.display = 'block'; + setTimeout(() => { + this.hideSpeechBubble(); + }, duration); + } + + hideSpeechBubble() { + this.speech.style.display = 'none'; + } + + swipe() { + if (this.currentStateEnum === States.swipe) { + return; + } + this.holdState = this.currentState; + this.holdStateEnum = this.currentStateEnum; + this.currentStateEnum = States.swipe; + this.currentState = resolveState(this.currentStateEnum, this); + this.showSpeechBubble('👋'); + } + + chase(ballState: BallState, canvas: HTMLCanvasElement) { + this.currentStateEnum = States.chase; + this.currentState = new ChaseState(this, ballState, canvas); + } + + faceLeft() { + this.el.style.transform = 'scaleX(-1)'; + } + + faceRight() { + this.el.style.transform = 'scaleX(1)'; + } + + setAnimation(face: string) { + if (this.el.src.endsWith(`_${face}_8fps.gif`)) { + return; + } + this.el.src = `${this.petRoot}_${face}_8fps.gif`; + } + + chooseNextState(fromState: States): States { + // Work out next state + var possibleNextStates: States[] | undefined = undefined; + for (var i = 0; i < this.sequence.sequenceStates.length; i++) { + if (this.sequence.sequenceStates[i].state === fromState) { + possibleNextStates = + this.sequence.sequenceStates[i].possibleNextStates; + } + } + if (!possibleNextStates) { + throw new InvalidStateException(); + } + // randomly choose the next state + const idx = Math.floor(Math.random() * possibleNextStates.length); + return possibleNextStates[idx]; + } + + nextFrame() { + if ( + this.currentState.horizontalDirection === HorizontalDirection.left + ) { + this.faceLeft(); + } else if ( + this.currentState.horizontalDirection === HorizontalDirection.right + ) { + this.faceRight(); + } + this.setAnimation(this.currentState.spriteLabel); + + // What's my buddy doing? + if ( + this.hasFriend && + this.currentStateEnum !== States.chaseFriend && + this.isMoving + ) { + if ( + this.friend?.isPlaying && + !isStateAboveGround(this.currentStateEnum) + ) { + this.currentState = resolveState(States.chaseFriend, this); + this.currentStateEnum = States.chaseFriend; + return; + } + } + + var frameResult = this.currentState.nextFrame(); + if (frameResult === FrameResult.stateComplete) { + // If recovering from swipe.. + if (this.holdState && this.holdStateEnum) { + this.currentState = this.holdState; + this.currentStateEnum = this.holdStateEnum; + this.holdState = undefined; + this.holdStateEnum = undefined; + return; + } + + var nextState = this.chooseNextState(this.currentStateEnum); + this.currentState = resolveState(nextState, this); + this.currentStateEnum = nextState; + } else if (frameResult === FrameResult.stateCancel) { + if (this.currentStateEnum === States.chase) { + var nextState = this.chooseNextState(States.idleWithBall); + this.currentState = resolveState(nextState, this); + this.currentStateEnum = nextState; + } else if (this.currentStateEnum === States.chaseFriend) { + var nextState = this.chooseNextState(States.idleWithBall); + this.currentState = resolveState(nextState, this); + this.currentStateEnum = nextState; + } + } + } + + get hasFriend(): boolean { + return this._friend !== undefined; + } + + get friend(): IPetType | undefined { + return this._friend; + } + + get name(): string { + return this._name; + } + + makeFriendsWith(friend: IPetType): boolean { + this._friend = friend; + console.log(this.name, ": I'm now friends ❤️ with ", friend.name); + return true; + } + + get isPlaying(): boolean { + return ( + this.isMoving && + (this.currentStateEnum === States.runRight || + this.currentStateEnum === States.runLeft) + ); + } + + get emoji(): string { + return '🐶'; + } +} diff --git a/src/panel/main.ts b/src/panel/main.ts index 3117f712..779a70a2 100644 --- a/src/panel/main.ts +++ b/src/panel/main.ts @@ -8,9 +8,9 @@ import { ColorThemeKind, WebviewMessage, } from '../common/types'; +import { IPetType } from './states'; import { createPet, - IPetType, PetCollection, PetElement, IPetCollection, diff --git a/src/panel/pets.ts b/src/panel/pets.ts index 7f6e8290..09340c83 100644 --- a/src/panel/pets.ts +++ b/src/panel/pets.ts @@ -1,18 +1,16 @@ import { PetColor, PetSize, PetSpeed, PetType } from '../common/types'; -import { ISequenceTree } from './sequences'; -import { - IState, - States, - resolveState, - HorizontalDirection, - ChaseState, - BallState, - FrameResult, - PetInstanceState, - isStateAboveGround, -} from './states'; - -export class InvalidStateException {} +import { Cat } from './pets/cat'; +import { Clippy } from './pets/clippy'; +import { Cockatiel } from './pets/cockatiel'; +import { Crab } from './pets/crab'; +import { Dog } from './pets/dog'; +import { Mod } from './pets/mod'; +import { Rocky } from './pets/rocky'; +import { RubberDuck } from './pets/rubberduck'; +import { Snake } from './pets/snake'; +import { Totoro } from './pets/totoro'; +import { Zappy } from './pets/zappy'; +import { IPetType } from './states'; export class PetElement { el: HTMLImageElement; @@ -135,897 +133,6 @@ export class PetCollection implements IPetCollection { } } -export interface IPetType { - nextFrame(): void; - - // Special methods for actions - canSwipe: boolean; - canChase: boolean; - swipe(): void; - chase(ballState: BallState, canvas: HTMLCanvasElement): void; - speed: number; - isMoving: boolean; - hello: string; - - // State API - getState(): PetInstanceState; - recoverState(state: PetInstanceState): void; - recoverFriend(friend: IPetType): void; - - // Positioning - bottom: number; - left: number; - positionBottom(bottom: number): void; - positionLeft(left: number): void; - width: number; - floor: number; - - // Friends API - name: string; - emoji: string; - hasFriend: boolean; - friend: IPetType | undefined; - makeFriendsWith(friend: IPetType): boolean; - isPlaying: boolean; - - showSpeechBubble(message: string, duration: number): void; -} - -function calculateSpriteWidth(size: PetSize): number { - if (size === PetSize.nano) { - return 30; - } else if (size === PetSize.medium) { - return 55; - } else if (size === PetSize.large) { - return 110; - } else { - return 30; // Shrug - } -} - -abstract class BasePetType implements IPetType { - label: string = 'base'; - static count: number = 0; - sequence: ISequenceTree = { - startingState: States.sitIdle, - sequenceStates: [], - }; - currentState: IState; - currentStateEnum: States; - holdState: IState | undefined; - holdStateEnum: States | undefined; - private el: HTMLImageElement; - private collision: HTMLDivElement; - private speech: HTMLDivElement; - private _left: number; - private _bottom: number; - petRoot: string; - _floor: number; - _friend: IPetType | undefined; - private _name: string; - private _speed: number; - private _size: PetSize; - - constructor( - spriteElement: HTMLImageElement, - collisionElement: HTMLDivElement, - speechElement: HTMLDivElement, - size: PetSize, - left: number, - bottom: number, - petRoot: string, - floor: number, - name: string, - speed: number, - ) { - this.el = spriteElement; - this.collision = collisionElement; - this.speech = speechElement; - this.petRoot = petRoot; - this._floor = floor; - this._left = left; - this._bottom = bottom; - this.initSprite(size, left, bottom); - this.currentStateEnum = this.sequence.startingState; - this.currentState = resolveState(this.currentStateEnum, this); - - this._name = name; - this._size = size; - this._speed = this.randomizeSpeed(speed); - - // Increment the static count of the Pet class that the constructor belongs to - (this.constructor as any).count += 1; - } - - initSprite(petSize: PetSize, left: number, bottom: number) { - this.el.style.left = `${left}px`; - this.el.style.bottom = `${bottom}px`; - this.el.style.width = 'auto'; - this.el.style.height = 'auto'; - this.el.style.maxWidth = `${calculateSpriteWidth(petSize)}px`; - this.el.style.maxHeight = `${calculateSpriteWidth(petSize)}px`; - this.collision.style.left = `${left}px`; - this.collision.style.bottom = `${bottom}px`; - this.collision.style.width = `${calculateSpriteWidth(petSize)}px`; - this.collision.style.height = `${calculateSpriteWidth(petSize)}px`; - this.speech.style.left = `${left}px`; - this.speech.style.bottom = `${ - bottom + calculateSpriteWidth(petSize) - }px`; - this.hideSpeechBubble(); - } - - get left(): number { - return this._left; - } - - get bottom(): number { - return this._bottom; - } - - private repositionAccompanyingElements() { - this.collision.style.left = `${this._left}px`; - this.collision.style.bottom = `${this._bottom}px`; - this.speech.style.left = `${this._left}px`; - this.speech.style.bottom = `${ - this._bottom + calculateSpriteWidth(this._size) - }px`; - } - - positionBottom(bottom: number): void { - this._bottom = bottom; - this.el.style.bottom = `${this._bottom}px`; - this.repositionAccompanyingElements(); - } - - positionLeft(left: number): void { - this._left = left; - this.el.style.left = `${this._left}px`; - this.repositionAccompanyingElements(); - } - - get width(): number { - return this.el.width; - } - - get floor(): number { - return this._floor; - } - - get hello(): string { - // return the sound of the name of the animal - return ` says hello 👋!`; - } - - getState(): PetInstanceState { - return { currentStateEnum: this.currentStateEnum }; - } - - get speed(): number { - return this._speed; - } - - randomizeSpeed(speed: number): number { - const min = speed * 0.7; - const max = speed * 1.3; - const newSpeed = Math.random() * (max - min) + min; - return newSpeed; - } - - get isMoving(): boolean { - return this._speed !== PetSpeed.still; - } - - recoverFriend(friend: IPetType) { - // Recover friends.. - this._friend = friend; - } - - recoverState(state: PetInstanceState) { - // TODO : Resolve a bug where if it was swiping before, it would fail - // because holdState is no longer valid. - this.currentStateEnum = state.currentStateEnum ?? States.sitIdle; - this.currentState = resolveState(this.currentStateEnum, this); - - if (!isStateAboveGround(this.currentStateEnum)) { - // Reset the bottom of the sprite to the floor as the theme - // has likely changed. - this.positionBottom(this.floor); - } - } - - get canSwipe() { - return !isStateAboveGround(this.currentStateEnum); - } - - get canChase() { - return ( - !isStateAboveGround(this.currentStateEnum) && - this.currentStateEnum !== States.chase && - this.isMoving - ); - } - - showSpeechBubble(message: string, duration: number = 3000) { - this.speech.innerHTML = message; - this.speech.style.display = 'block'; - setTimeout(() => { - this.hideSpeechBubble(); - }, duration); - } - - hideSpeechBubble() { - this.speech.style.display = 'none'; - } - - swipe() { - if (this.currentStateEnum === States.swipe) { - return; - } - this.holdState = this.currentState; - this.holdStateEnum = this.currentStateEnum; - this.currentStateEnum = States.swipe; - this.currentState = resolveState(this.currentStateEnum, this); - this.showSpeechBubble('👋'); - } - - chase(ballState: BallState, canvas: HTMLCanvasElement) { - this.currentStateEnum = States.chase; - this.currentState = new ChaseState(this, ballState, canvas); - } - - faceLeft() { - this.el.style.transform = 'scaleX(-1)'; - } - - faceRight() { - this.el.style.transform = 'scaleX(1)'; - } - - setAnimation(face: string) { - if (this.el.src.endsWith(`_${face}_8fps.gif`)) { - return; - } - this.el.src = `${this.petRoot}_${face}_8fps.gif`; - } - - chooseNextState(fromState: States): States { - // Work out next state - var possibleNextStates: States[] | undefined = undefined; - for (var i = 0; i < this.sequence.sequenceStates.length; i++) { - if (this.sequence.sequenceStates[i].state === fromState) { - possibleNextStates = - this.sequence.sequenceStates[i].possibleNextStates; - } - } - if (!possibleNextStates) { - throw new InvalidStateException(); - } - // randomly choose the next state - const idx = Math.floor(Math.random() * possibleNextStates.length); - return possibleNextStates[idx]; - } - - nextFrame() { - if ( - this.currentState.horizontalDirection === HorizontalDirection.left - ) { - this.faceLeft(); - } else if ( - this.currentState.horizontalDirection === HorizontalDirection.right - ) { - this.faceRight(); - } - this.setAnimation(this.currentState.spriteLabel); - - // What's my buddy doing? - if ( - this.hasFriend && - this.currentStateEnum !== States.chaseFriend && - this.isMoving - ) { - if ( - this.friend?.isPlaying && - !isStateAboveGround(this.currentStateEnum) - ) { - this.currentState = resolveState(States.chaseFriend, this); - this.currentStateEnum = States.chaseFriend; - return; - } - } - - var frameResult = this.currentState.nextFrame(); - if (frameResult === FrameResult.stateComplete) { - // If recovering from swipe.. - if (this.holdState && this.holdStateEnum) { - this.currentState = this.holdState; - this.currentStateEnum = this.holdStateEnum; - this.holdState = undefined; - this.holdStateEnum = undefined; - return; - } - - var nextState = this.chooseNextState(this.currentStateEnum); - this.currentState = resolveState(nextState, this); - this.currentStateEnum = nextState; - } else if (frameResult === FrameResult.stateCancel) { - if (this.currentStateEnum === States.chase) { - var nextState = this.chooseNextState(States.idleWithBall); - this.currentState = resolveState(nextState, this); - this.currentStateEnum = nextState; - } else if (this.currentStateEnum === States.chaseFriend) { - var nextState = this.chooseNextState(States.idleWithBall); - this.currentState = resolveState(nextState, this); - this.currentStateEnum = nextState; - } - } - } - - get hasFriend(): boolean { - return this._friend !== undefined; - } - - get friend(): IPetType | undefined { - return this._friend; - } - - get name(): string { - return this._name; - } - - makeFriendsWith(friend: IPetType): boolean { - this._friend = friend; - console.log(this.name, ": I'm now friends ❤️ with ", friend.name); - return true; - } - - get isPlaying(): boolean { - return ( - this.isMoving && - (this.currentStateEnum === States.runRight || - this.currentStateEnum === States.runLeft) - ); - } - - get emoji(): string { - return '🐶'; - } -} - -export class Totoro extends BasePetType { - label = 'totoro'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.lie], - }, - { - state: States.lie, - possibleNextStates: [States.walkRight, States.walkLeft], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.sitIdle], - }, - { - state: States.walkLeft, - possibleNextStates: [ - States.sitIdle, - States.climbWallLeft, - States.sitIdle, - ], - }, - { - state: States.climbWallLeft, - possibleNextStates: [States.wallHangLeft], - }, - { - state: States.wallHangLeft, - possibleNextStates: [States.jumpDownLeft], - }, - { - state: States.jumpDownLeft, - possibleNextStates: [States.land], - }, - { - state: States.land, - possibleNextStates: [ - States.sitIdle, - States.walkRight, - States.lie, - ], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [States.walkRight, States.walkLeft], - }, - ], - }; - get emoji(): string { - return '🐾'; - } - get hello(): string { - return `Try Laughing. Then Whatever Scares You Will Go Away. 🎭`; - } -} -export class Cat extends BasePetType { - label = 'cat'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.runRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.walkLeft, - possibleNextStates: [ - States.sitIdle, - States.climbWallLeft, - States.walkRight, - States.runRight, - ], - }, - { - state: States.runLeft, - possibleNextStates: [ - States.sitIdle, - States.climbWallLeft, - States.walkRight, - States.runRight, - ], - }, - { - state: States.climbWallLeft, - possibleNextStates: [States.wallHangLeft], - }, - { - state: States.wallHangLeft, - possibleNextStates: [States.jumpDownLeft], - }, - { - state: States.jumpDownLeft, - possibleNextStates: [States.land], - }, - { - state: States.land, - possibleNextStates: [ - States.sitIdle, - States.walkRight, - States.runRight, - ], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [ - States.walkRight, - States.walkLeft, - States.runLeft, - States.runRight, - ], - }, - ], - }; - get emoji(): string { - return '🐱'; - } - get hello(): string { - return `brrr... Meow!`; - } -} - -export class Dog extends BasePetType { - label = 'dog'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [ - States.walkRight, - States.runRight, - States.lie, - ], - }, - { - state: States.lie, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.runRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.walkLeft, - possibleNextStates: [ - States.sitIdle, - States.lie, - States.walkRight, - States.runRight, - ], - }, - { - state: States.runLeft, - possibleNextStates: [ - States.sitIdle, - States.lie, - States.walkRight, - States.runRight, - ], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [ - States.walkRight, - States.walkLeft, - States.runLeft, - States.runRight, - ], - }, - ], - }; - get emoji(): string { - return '🐶'; - } - get hello(): string { - return ` Every dog has its day - and today is woof day! Today I just want to bark. Take me on a walk`; - } -} - -export class Snake extends BasePetType { - label = 'snake'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.runRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.walkLeft, - possibleNextStates: [ - States.sitIdle, - States.walkRight, - States.runRight, - ], - }, - { - state: States.runLeft, - possibleNextStates: [ - States.sitIdle, - States.walkRight, - States.runRight, - ], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [ - States.walkRight, - States.walkLeft, - States.runLeft, - States.runRight, - ], - }, - ], - }; - get emoji(): string { - return '🐍'; - } - get hello(): string { - return `Sss... Oh. Oh my gosh! I'm a snake!`; - } -} - -export class Clippy extends BasePetType { - label = 'clippy'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.runRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.walkLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.runLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [ - States.walkRight, - States.walkLeft, - States.runLeft, - States.runRight, - ], - }, - ], - }; - get emoji(): string { - return '📎'; - } - get hello(): string { - return ` Hi, I'm Clippy, would you like some assistance today? 👋!`; - } -} - -export class RubberDuck extends BasePetType { - label = 'rubber-duck'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.runRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.walkLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.runLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [ - States.walkRight, - States.walkLeft, - States.runLeft, - States.runRight, - ], - }, - ], - }; - get emoji(): string { - return '🐥'; - } - get hello(): string { - return ` Hi, I love to quack around 👋!`; - } -} - -export class Cockatiel extends BasePetType { - label = 'cockatiel'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.runRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.walkLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.runLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [ - States.walkRight, - States.walkLeft, - States.runLeft, - States.runRight, - ], - }, - ], - }; - get emoji(): string { - return '🦜'; - } - get hello(): string { - // TODO: #191 Add a custom message for cockatiel - return ` Hello, I'm a good bird 👋!`; - } -} - -export class Crab extends BasePetType { - label = 'crab'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.runRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.walkLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.runLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [ - States.walkRight, - States.walkLeft, - States.runLeft, - States.runRight, - ], - }, - ], - }; - get emoji(): string { - return '🦀'; - } - get hello(): string { - return ` Hi, I'm Crabsolutely Clawsome Crab 👋!`; - } -} - -export class Zappy extends BasePetType { - label = 'zappy'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.runRight, - possibleNextStates: [States.walkLeft, States.runLeft], - }, - { - state: States.walkLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.runLeft, - possibleNextStates: [States.sitIdle], - }, - { - state: States.chase, - possibleNextStates: [States.idleWithBall], - }, - { - state: States.idleWithBall, - possibleNextStates: [ - States.walkRight, - States.walkLeft, - States.runLeft, - States.runRight, - ], - }, - ], - }; - get emoji(): string { - return '⚡'; - } - get hello(): string { - // TODO: #193 Add a custom message for zappy - return ` Hello this is Zappy! Do I look familiar?? I am the mascot for Azure Functions😉`; - } -} - -export class Rocky extends BasePetType { - label = 'rocky'; - sequence = { - startingState: States.sitIdle, - sequenceStates: [ - { - state: States.sitIdle, - possibleNextStates: [States.walkRight, States.runRight], - }, - { - state: States.walkRight, - possibleNextStates: [States.sitIdle, States.runRight], - }, - { - state: States.runRight, - possibleNextStates: [States.sitIdle, States.walkRight], - }, - ], - }; - get emoji(): string { - return '💎'; - } - get canChase(): boolean { - return false; - } - get hello(): string { - return ` 👋 I'm rock! I always Rock`; - } -} - export class InvalidPetException { message?: string; @@ -1071,6 +178,8 @@ export function createPet( return new Crab(...standardPetArguments, PetSpeed.slow); case PetType.clippy: return new Clippy(...standardPetArguments, PetSpeed.slow); + case PetType.mod: + return new Mod(...standardPetArguments, PetSpeed.normal); case PetType.totoro: return new Totoro(...standardPetArguments, PetSpeed.normal); case PetType.snake: diff --git a/src/panel/pets/cat.ts b/src/panel/pets/cat.ts new file mode 100644 index 00000000..ed23fbaf --- /dev/null +++ b/src/panel/pets/cat.ts @@ -0,0 +1,202 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Cat extends BasePetType { + label = 'cat'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [ + States.sitIdle, + States.climbWallLeft, + States.walkRight, + States.runRight, + ], + }, + { + state: States.runLeft, + possibleNextStates: [ + States.sitIdle, + States.climbWallLeft, + States.walkRight, + States.runRight, + ], + }, + { + state: States.climbWallLeft, + possibleNextStates: [States.wallHangLeft], + }, + { + state: States.wallHangLeft, + possibleNextStates: [States.jumpDownLeft], + }, + { + state: States.jumpDownLeft, + possibleNextStates: [States.land], + }, + { + state: States.land, + possibleNextStates: [ + States.sitIdle, + States.walkRight, + States.runRight, + ], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '🐱'; + } + get hello(): string { + return `brrr... Meow!`; + } +} + +export const CAT_NAMES: ReadonlyArray = [ + 'Bella', + 'Charlie', + 'Molly', + 'Coco', + 'Ruby', + 'Oscar', + 'Lucy', + 'Bailey', + 'Milo', + 'Daisy', + 'Archie', + 'Ollie', + 'Rosie', + 'Lola', + 'Frankie', + 'Roxy', + 'Poppy', + 'Luna', + 'Jack', + 'Millie', + 'Teddy', + 'Cooper', + 'Bear', + 'Rocky', + 'Alfie', + 'Hugo', + 'Bonnie', + 'Pepper', + 'Lily', + 'Tilly', + 'Leo', + 'Maggie', + 'George', + 'Mia', + 'Marley', + 'Harley', + 'Chloe', + 'Lulu', + 'Missy', + 'Jasper', + 'Billy', + 'Nala', + 'Monty', + 'Ziggy', + 'Winston', + 'Zeus', + 'Zoe', + 'Stella', + 'Sasha', + 'Rusty', + 'Gus', + 'Baxter', + 'Dexter', + 'Willow', + 'Barney', + 'Bruno', + 'Penny', + 'Honey', + 'Milly', + 'Murphy', + 'Simba', + 'Holly', + 'Benji', + 'Henry', + 'Lilly', + 'Pippa', + 'Shadow', + 'Sam', + 'Lucky', + 'Ellie', + 'Duke', + 'Jessie', + 'Cookie', + 'Harvey', + 'Bruce', + 'Jax', + 'Rex', + 'Louie', + 'Jet', + 'Banjo', + 'Beau', + 'Ella', + 'Ralph', + 'Loki', + 'Lexi', + 'Chester', + 'Sophie', + 'Chilli', + 'Billie', + 'Louis', + 'Scout', + 'Cleo', + 'Purfect', + 'Spot', + 'Bolt', + 'Julia', + 'Ginger', + 'Daisy', + 'Amelia', + 'Oliver', + 'Ghost', + 'Midnight', + 'Pumpkin', + 'Shadow', + 'Binx', + 'Riley', + 'Lenny', + 'Mango', + 'Alex', + 'Boo', + 'Botas', + 'Romeo', + 'Bob', + 'Clyde', + 'Simon', + 'Mimmo', + 'Carlotta', + 'Felix', + 'Duchess', +]; diff --git a/src/panel/pets/clippy.ts b/src/panel/pets/clippy.ts new file mode 100644 index 00000000..ef328c78 --- /dev/null +++ b/src/panel/pets/clippy.ts @@ -0,0 +1,63 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Clippy extends BasePetType { + label = 'clippy'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.runLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '📎'; + } + get hello(): string { + return ` Hi, I'm Clippy, would you like some assistance today? 👋!`; + } +} + +export const CLIPPY_NAMES: ReadonlyArray = [ + 'Clippy', + 'Karl Klammer', + 'Clippy Jr.', + 'Molly', + 'Coco', + 'Buddy', + 'Ruby', + 'Oscar', + 'Lucy', + 'Bailey', +]; diff --git a/src/panel/pets/cockatiel.ts b/src/panel/pets/cockatiel.ts new file mode 100644 index 00000000..69da30bf --- /dev/null +++ b/src/panel/pets/cockatiel.ts @@ -0,0 +1,87 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Cockatiel extends BasePetType { + label = 'cockatiel'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.runLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '🦜'; + } + get hello(): string { + // TODO: #191 Add a custom message for cockatiel + return ` Hello, I'm a good bird 👋!`; + } +} + +export const COCKATIEL_NAMES: ReadonlyArray = [ + 'Cocktail', + 'Pipsqueak', + 'Sir Chirps a Lot', + 'Nibbles', + 'Lord of the Wings', + 'Girl Nest Door', + 'Wingman', + 'Meryl Cheep', + 'Jack Sparrow', + 'Godfeather', + 'Mickey', + 'Baquack Obama', + 'Dame Judi Finch', + 'Kanye Nest', + 'Speck', + 'Cheecky', + 'Arthur', + 'Paco', + 'Bobo', + 'Walt', + 'Happy', + 'Junior', + 'Coco', + 'Yoyo', + 'Milo', + 'Skipper', + 'Scarlet', + 'Diva', + 'Ursula', + 'Donna', + 'Lola', + 'Kiko', + 'Luna', +]; diff --git a/src/panel/pets/crab.ts b/src/panel/pets/crab.ts new file mode 100644 index 00000000..d733e176 --- /dev/null +++ b/src/panel/pets/crab.ts @@ -0,0 +1,103 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Crab extends BasePetType { + label = 'crab'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.runLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '🦀'; + } + get hello(): string { + return ` Hi, I'm Crabsolutely Clawsome Crab 👋!`; + } +} + +export const CRAB_NAMES: ReadonlyArray = [ + 'Ferris', + 'Pinchy', + 'Grabby', + 'Big Red', + 'Crabby', + 'Buddy', + 'Ruby Red', + 'Oscar', + 'Lucy', + 'Bailey', + 'Crabito', + 'Percy', + 'Rocky', + 'Mr. Krabs', + 'Shelly', + 'Santa Claws', + 'Clawdia', + 'Scuttle', + 'Snappy', + 'Hermit', + 'Horseshoe', + 'Snapper', + 'Coconut', + 'Sebastian', + 'Abby', + 'Bubbles', + 'Bait', + 'Big Mac', + 'Biggie', + 'Claws', + 'Copper', + 'Crabette', + 'Crabina', + 'Crabmister', + 'Crusty', + 'Crabcake', + 'Digger', + 'Nipper', + 'Pincer', + 'Poopsie', + 'Recluse', + 'Salty', + 'Squirt', + 'Groucho', + 'Grumpy', + 'Lenny Krabitz', + 'Leonardo DaPinchy', + 'Peeves', + 'Penny Pincher', + 'Prickl', +]; diff --git a/src/panel/pets/dog.ts b/src/panel/pets/dog.ts new file mode 100644 index 00000000..512ea372 --- /dev/null +++ b/src/panel/pets/dog.ts @@ -0,0 +1,208 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Dog extends BasePetType { + label = 'dog'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [ + States.walkRight, + States.runRight, + States.lie, + ], + }, + { + state: States.lie, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [ + States.sitIdle, + States.lie, + States.walkRight, + States.runRight, + ], + }, + { + state: States.runLeft, + possibleNextStates: [ + States.sitIdle, + States.lie, + States.walkRight, + States.runRight, + ], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '🐶'; + } + get hello(): string { + return ` Every dog has its day - and today is woof day! Today I just want to bark. Take me on a walk`; + } +} + +export const DOG_NAMES: ReadonlyArray = [ + 'Bella', + 'Charlie', + 'Max', + 'Molly', + 'Coco', + 'Buddy', + 'Ruby', + 'Oscar', + 'Lucy', + 'Bailey', + 'Milo', + 'Daisy', + 'Archie', + 'Ollie', + 'Rosie', + 'Lola', + 'Frankie', + 'Toby', + 'Roxy', + 'Poppy', + 'Luna', + 'Jack', + 'Millie', + 'Teddy', + 'Harry', + 'Cooper', + 'Bear', + 'Rocky', + 'Alfie', + 'Hugo', + 'Bonnie', + 'Pepper', + 'Lily', + 'Leo', + 'Maggie', + 'George', + 'Mia', + 'Marley', + 'Harley', + 'Chloe', + 'Lulu', + 'Jasper', + 'Billy', + 'Nala', + 'Monty', + 'Ziggy', + 'Winston', + 'Zeus', + 'Zoe', + 'Stella', + 'Sasha', + 'Rusty', + 'Gus', + 'Baxter', + 'Dexter', + 'Diesel', + 'Willow', + 'Barney', + 'Bruno', + 'Penny', + 'Honey', + 'Milly', + 'Murphy', + 'Holly', + 'Benji', + 'Henry', + 'Lilly', + 'Pippa', + 'Shadow', + 'Sam', + 'Buster', + 'Lucky', + 'Ellie', + 'Duke', + 'Jessie', + 'Cookie', + 'Harvey', + 'Bruce', + 'Jax', + 'Rex', + 'Louie', + 'Bentley', + 'Jet', + 'Banjo', + 'Beau', + 'Ella', + 'Ralph', + 'Loki', + 'Lexi', + 'Chester', + 'Sophie', + 'Billie', + 'Louis', + 'Charlie', + 'Cleo', + 'Spot', + 'Harry', + 'Bolt', + 'Ein', + 'Maddy', + 'Ghost', + 'Midnight', + 'Pumpkin', + 'Shadow', + 'Sparky', + 'Linus', + 'Cody', + 'Slinky', + 'Toto', + 'Balto', + 'Golfo', + 'Pongo', + 'Beethoven', + 'Hachiko', + 'Scooby', + 'Clifford', + 'Astro', + 'Goofy', + 'Chip', + 'Einstein', + 'Fang', + 'Truman', + 'Uggie', + 'Bingo', + 'Blue', + 'Cometa', + 'Krypto', + 'Huesos', + 'Odie', + 'Snoopy', + 'Aisha', + 'Moly', + 'Chiquita', + 'Chavela', + 'Tramp', + 'Lady', + 'Puddles', +]; diff --git a/src/panel/pets/mod.ts b/src/panel/pets/mod.ts new file mode 100644 index 00000000..b583a86b --- /dev/null +++ b/src/panel/pets/mod.ts @@ -0,0 +1,59 @@ +import { States } from '../states'; +import { BasePetType } from '../basepettype'; + +export class Mod extends BasePetType { + label = 'mod'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.runLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '🤖'; + } + get hello(): string { + return ` Hi, I'm Mod the dotnet bot, what are you building today?`; + } +} + +export const MOD_NAMES: ReadonlyArray = [ + 'Mod', + 'Moddy', + 'Dotnetbot', + 'Bot', + 'Purple Pal', + 'Ro Bot', +]; diff --git a/src/panel/pets/rocky.ts b/src/panel/pets/rocky.ts new file mode 100644 index 00000000..6750692e --- /dev/null +++ b/src/panel/pets/rocky.ts @@ -0,0 +1,58 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Rocky extends BasePetType { + label = 'rocky'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.sitIdle, States.runRight], + }, + { + state: States.runRight, + possibleNextStates: [States.sitIdle, States.walkRight], + }, + ], + }; + get emoji(): string { + return '💎'; + } + get canChase(): boolean { + return false; + } + get hello(): string { + return ` 👋 I'm rock! I always Rock`; + } +} + +export const ROCKY_NAMES: ReadonlyArray = [ + 'Rocky', + 'The Rock', + 'Quartzy', + 'Rocky I', + 'Rocky II', + 'Rocky III', + 'Pebbles Sr.', + 'Big Granite', + 'Boulder', + 'Rockefeller', + 'Pebble', + 'Rocksanne', + 'Rockstar', + 'Onix', + 'Rock and Roll', + 'Dolomite', + 'Granite', + 'Miss Marble', + 'Rock On', + 'Amberstone', + 'Rock With Me', + 'Rock On It', + 'Rock Out', +]; diff --git a/src/panel/pets/rubberduck.ts b/src/panel/pets/rubberduck.ts new file mode 100644 index 00000000..f363ce32 --- /dev/null +++ b/src/panel/pets/rubberduck.ts @@ -0,0 +1,111 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class RubberDuck extends BasePetType { + label = 'rubber-duck'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.runLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '🐥'; + } + get hello(): string { + return ` Hi, I love to quack around 👋!`; + } +} + +export const DUCK_NAMES: ReadonlyArray = [ + 'Quacky', + 'Floaty', + 'Duck', + 'Molly', + 'Sunshine', + 'Buddy', + 'Chirpy', + 'Oscar', + 'Lucy', + 'Bailey', + 'Beaky', + 'Jemima', + 'Peaches', + 'Quackers', + 'Jelly Beans', + 'Donald', + 'Chady', + 'Waddles', + 'Bill', + 'Bubbles', + 'James Pond', + 'Moby Duck', + 'Quack Sparrow', + 'Peanut', + 'Psyduck', + 'Mr Quack', + 'Louie', + 'Golduck', + 'Daisy', + 'Pickles', + 'Ducky Duck', + 'Mrs Fluffs', + 'Squeek', + 'Ace', + 'Rubberduck', + 'Mrs Beak', + 'April', + 'Tutu', + 'Billy the duck', + 'Ducky', + 'Neco', + 'Dodo', + 'Colonel', + 'Franklin', + 'Emmett', + 'Bubba', + 'Dillard', + 'Duncan', + 'Pogo', + 'Uno', + 'Peanut', + 'Nero', + 'Mowgli', + 'Eggspresso', + 'Webster', + 'Quacker Jack', + 'Plucker', + 'Meeko', +]; diff --git a/src/panel/pets/snake.ts b/src/panel/pets/snake.ts new file mode 100644 index 00000000..11918ca7 --- /dev/null +++ b/src/panel/pets/snake.ts @@ -0,0 +1,113 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Snake extends BasePetType { + label = 'snake'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [ + States.sitIdle, + States.walkRight, + States.runRight, + ], + }, + { + state: States.runLeft, + possibleNextStates: [ + States.sitIdle, + States.walkRight, + States.runRight, + ], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '🐍'; + } + get hello(): string { + return `Sss... Oh. Oh my gosh! I'm a snake!`; + } +} + +export const SNAKE_NAMES: ReadonlyArray = [ + 'Sneaky', + 'Mr Slippery', + 'Hissy Elliott', + 'Molly', + 'Coco', + 'Buddy', + 'Ruby', + 'Bailey', + 'Max', + 'Seb', + 'Kaa', + 'Mr Hiss', + 'Miss Hiss', + 'Snaku', + 'Kaa', + 'Madame Snake', + 'Sir Hiss', + 'Loki', + 'Steelix', + 'Gyarados', + 'Seviper', + 'Ekanes', + 'Arbok', + 'Snivy', + 'Servine', + 'Serperior', + 'Mojo', + 'Moss', + 'Nigel', + 'Tootsie', + 'Sammy', + 'Ziggy', + 'Asmodeus', + 'Attila', + 'Basil', + 'Diablo', + 'Eden', + 'Eve', + 'Heaven', + 'Hydra', + 'Indiana', + 'Jafaar', + 'Kaa', + 'Medusa', + 'Naga', + 'Severus', + 'Slytherin', + 'Snape', + 'Raven', + 'Slider', + 'Slinky', + 'Stripes', +]; diff --git a/src/panel/pets/totoro.ts b/src/panel/pets/totoro.ts new file mode 100644 index 00000000..ab3c457b --- /dev/null +++ b/src/panel/pets/totoro.ts @@ -0,0 +1,79 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Totoro extends BasePetType { + label = 'totoro'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.lie], + }, + { + state: States.lie, + possibleNextStates: [States.walkRight, States.walkLeft], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.sitIdle], + }, + { + state: States.walkLeft, + possibleNextStates: [ + States.sitIdle, + States.climbWallLeft, + States.sitIdle, + ], + }, + { + state: States.climbWallLeft, + possibleNextStates: [States.wallHangLeft], + }, + { + state: States.wallHangLeft, + possibleNextStates: [States.jumpDownLeft], + }, + { + state: States.jumpDownLeft, + possibleNextStates: [States.land], + }, + { + state: States.land, + possibleNextStates: [ + States.sitIdle, + States.walkRight, + States.lie, + ], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [States.walkRight, States.walkLeft], + }, + ], + }; + get emoji(): string { + return '🐾'; + } + get hello(): string { + return `Try Laughing. Then Whatever Scares You Will Go Away. 🎭`; + } +} + +export const TOTORO_NAMES: ReadonlyArray = [ + 'Totoro', + 'トトロ', + 'Max', + 'Molly', + 'Coco', + 'Buddy', + 'Ruby', + 'Oscar', + 'Lucy', + 'Bailey', + 'Big fella', +]; diff --git a/src/panel/pets/zappy.ts b/src/panel/pets/zappy.ts new file mode 100644 index 00000000..0eeaa345 --- /dev/null +++ b/src/panel/pets/zappy.ts @@ -0,0 +1,71 @@ +import { BasePetType } from '../basepettype'; +import { States } from '../states'; + +export class Zappy extends BasePetType { + label = 'zappy'; + sequence = { + startingState: States.sitIdle, + sequenceStates: [ + { + state: States.sitIdle, + possibleNextStates: [States.walkRight, States.runRight], + }, + { + state: States.walkRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.runRight, + possibleNextStates: [States.walkLeft, States.runLeft], + }, + { + state: States.walkLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.runLeft, + possibleNextStates: [States.sitIdle], + }, + { + state: States.chase, + possibleNextStates: [States.idleWithBall], + }, + { + state: States.idleWithBall, + possibleNextStates: [ + States.walkRight, + States.walkLeft, + States.runLeft, + States.runRight, + ], + }, + ], + }; + get emoji(): string { + return '⚡'; + } + get hello(): string { + // TODO: #193 Add a custom message for zappy + return ` Hello this is Zappy! Do I look familiar?? I am the mascot for Azure Functions😉`; + } +} + +export const ZAPPY_NAMES: ReadonlyArray = [ + 'Zappy', + 'Zippy', + 'Zappy Jr.', + 'Zoppy', + 'Zuppy', + 'Zeppy', + 'Big Z', + 'Little z', + 'The Flash', + 'Thor', + 'Electric Bolt', + 'Azula', + 'Lightning Bolt', + 'Power', + 'Sonic', + 'Speedy', + 'Rush', +]; diff --git a/src/panel/states.ts b/src/panel/states.ts index b45cf5e4..ac7c827b 100644 --- a/src/panel/states.ts +++ b/src/panel/states.ts @@ -1,5 +1,40 @@ import { PetColor, PetType } from '../common/types'; -import { IPetType } from './pets'; + +export interface IPetType { + nextFrame(): void; + + // Special methods for actions + canSwipe: boolean; + canChase: boolean; + swipe(): void; + chase(ballState: BallState, canvas: HTMLCanvasElement): void; + speed: number; + isMoving: boolean; + hello: string; + + // State API + getState(): PetInstanceState; + recoverState(state: PetInstanceState): void; + recoverFriend(friend: IPetType): void; + + // Positioning + bottom: number; + left: number; + positionBottom(bottom: number): void; + positionLeft(left: number): void; + width: number; + floor: number; + + // Friends API + name: string; + emoji: string; + hasFriend: boolean; + friend: IPetType | undefined; + makeFriendsWith(friend: IPetType): boolean; + isPlaying: boolean; + + showSpeechBubble(message: string, duration: number): void; +} export class PetInstanceState { currentStateEnum: States | undefined; diff --git a/src/test/suite/panel.test.ts b/src/test/suite/panel.test.ts index 0630292b..996a9c07 100644 --- a/src/test/suite/panel.test.ts +++ b/src/test/suite/panel.test.ts @@ -67,6 +67,7 @@ class MockState implements VscodeStateApi { mockPanelWindow(); import * as panel from '../../panel/main'; +import { Cat } from '../../panel/pets/cat'; suite('Pets Test Suite', () => { vscode.window.showInformationMessage('Start all tests.'); @@ -92,7 +93,7 @@ suite('Pets Test Suite', () => { 0, 'Jerry', ); - assert.ok(testPet instanceof pets.Cat); + assert.ok(testPet instanceof Cat); assert.equal(testPet.emoji, '🐱'); assert.equal(testPet.name, 'Jerry'); From 575bf1f0c3facb06ddc80a287748fd29c1546a97 Mon Sep 17 00:00:00 2001 From: Marc Duiker Date: Mon, 31 Oct 2022 10:47:45 +0100 Subject: [PATCH 2/3] Run lint:fix --- src/panel/main.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/panel/main.ts b/src/panel/main.ts index 779a70a2..be219559 100644 --- a/src/panel/main.ts +++ b/src/panel/main.ts @@ -9,12 +9,7 @@ import { WebviewMessage, } from '../common/types'; import { IPetType } from './states'; -import { - createPet, - PetCollection, - PetElement, - IPetCollection, -} from './pets'; +import { createPet, PetCollection, PetElement, IPetCollection } from './pets'; import { BallState, PetElementState, PetPanelState } from './states'; /* This is how the VS Code API can be invoked from the panel */ From 1a56509d527d9ce55987e3ac0bd679461495a642 Mon Sep 17 00:00:00 2001 From: Anthony Shaw Date: Tue, 1 Nov 2022 08:49:44 +1100 Subject: [PATCH 3/3] Describe who mod is --- package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.nls.json b/package.nls.json index 35d2f334..72544cd3 100644 --- a/package.nls.json +++ b/package.nls.json @@ -24,7 +24,7 @@ "vscodePets.cockatiel": "Cockatiel", "vscodePets.crab": "Crab", "vscodePets.dog": "Dog", - "vscodePets.mod": "Mod", + "vscodePets.mod": "Mod (the .NET bot)", "vscodePets.rocky": "Rocky", "vscodePets.rubber-duck": "Rubber Duck", "vscodePets.snake": "Snake",