From 298b30cc7e37db271c165de632838b387779ee99 Mon Sep 17 00:00:00 2001 From: Julius Bacosa Date: Fri, 5 Nov 2021 05:02:53 +0800 Subject: [PATCH] julius: victory --- src/workshop/BaseCharacter.tsx | 43 ++++++++----- src/workshop/Characters.tsx | 114 ++++----------------------------- src/workshop/Weapons.tsx | 59 ++++++++++++++--- 3 files changed, 90 insertions(+), 126 deletions(-) diff --git a/src/workshop/BaseCharacter.tsx b/src/workshop/BaseCharacter.tsx index e79b5f2..37d2b7c 100644 --- a/src/workshop/BaseCharacter.tsx +++ b/src/workshop/BaseCharacter.tsx @@ -1,24 +1,35 @@ -import { CharacterClassName, ICharacter, ICharacterActionDecision } from "../off-limits/ICharacter"; -import { IWeapon, IItem } from "../off-limits/IWeapons"; +import { CharacterClassName, equip, ICharacter, ICharacterActionDecision } from "../off-limits/ICharacter"; +import { IWeapon, IItem, isMeleeWeapon, isRangedWeapon } from "../off-limits/IWeapons"; + //todo: use this base class somehow in Characters.tsx -export class Character implements ICharacter { +export abstract class Character implements ICharacter { name: string = ''; health: number = 5; position: number = 10; weapons: IWeapon[] = []; - item?: IItem; + item?: IItem; - classname(): CharacterClassName { - throw new Error("Method not implemented."); - } - move(){ - throw new Error("Method not implemented."); - } - chooseAction(): ICharacterActionDecision{ - throw new Error("Method not implemented."); - } - getASCIIStatus(): string { - throw new Error("Method not implemented."); - } + constructor(protected avatar:string, + protected characterClass: CharacterClassName, + protected equipment: IItem|undefined, + public key: number) { equip(equipment, this); } + + classname: () => CharacterClassName = () => this.characterClass; + move: () => void = () => this.position = Math.max(this.position - 5, 1); + chooseAction: () => ICharacterActionDecision = () => { + let canAttack:boolean = false; + let weapon = this.weapons[0]; + if(this.health < 2 && this.item) return { use: this.item }; + if(weapon) { + if(isMeleeWeapon(weapon) && this.position <= weapon.meleeRange) + canAttack = true; + if(isRangedWeapon(weapon) && weapon.projectiles.length > 0) + canAttack = true; + return canAttack ? { attack: weapon } : { use: this.item } as ICharacterActionDecision; + } else { + return { use: this.item } as ICharacterActionDecision; + } + }; + getASCIIStatus:() => string = () => this.health <= 0 ? "X" : this.avatar; } \ No newline at end of file diff --git a/src/workshop/Characters.tsx b/src/workshop/Characters.tsx index 16ba4f4..b11878e 100644 --- a/src/workshop/Characters.tsx +++ b/src/workshop/Characters.tsx @@ -1,5 +1,4 @@ -import { ICharacter, CharacterClassName, equip, ICharacterActionDecision } from '../off-limits/ICharacter'; -import { IWeapon, IItem, isMeleeWeapon } from '../off-limits/IWeapons'; + import { Character } from './BaseCharacter'; import { ClericStartItem, @@ -11,113 +10,26 @@ import { //todo: too many duplicate classes in this file! //todo: customize the chooseAction() to better fight the dragon //todo: update the `getASCIIStatus` function(s) to return X when dead and a unique character per class - -export class Warrior implements ICharacter { - health: number = 5; - position: number = 10; - weapons: IWeapon[] = []; - item?: IItem; - feet = new Feet(this); - classname(): CharacterClassName { - return 'Warrior'; - } - move(){ - this.feet.move(); - } - constructor(public name: string, public key: number) { - equip(WarriorStartItem, this); - } - chooseAction(): ICharacterActionDecision { - return { - attack: this.weapons[0] - } - } - getASCIIStatus(): string { - return "@"; - } +export class Warrior extends Character { + constructor(public name: string, public key: number) { + super('W', 'Warrior', WarriorStartItem, key); + } } -export class Cleric implements ICharacter{ - health: number = 5; - position: number = 10; - weapons: IWeapon[] = []; - item?: IItem; - feet = new Feet(this); - classname(): CharacterClassName { - return 'Cleric'; - } - move(){ - this.feet.move(); - } +export class Cleric extends Character{ constructor(public name: string, public key: number) { - equip(ClericStartItem, this); - } - chooseAction(): ICharacterActionDecision { - return { - attack: this.weapons[0] - } - } - getASCIIStatus(): string { - return "@"; - } + super('C', 'Cleric', ClericStartItem, key) + } } -export class Mage implements ICharacter { - health: number = 5; - position: number = 10; - weapons: IWeapon[] = []; - item?: IItem; - feet = new Feet(this); - classname(): CharacterClassName { - return 'Mage'; - } +export class Mage extends Character{ constructor(public name: string, public key: number) { - equip(MageStartItem, this); - } - move(){ - this.feet.move(); - } - chooseAction(): ICharacterActionDecision { - return { - attack: this.weapons[0] - } - } - getASCIIStatus(): string { - return "@"; + super('M', 'Mage', MageStartItem, key) } } -export class Thief implements ICharacter { - health: number = 5; - position: number = 10; - weapons: IWeapon[] = []; - item?: IItem; - feet = new Feet(this); - move(){ - this.feet.move(); - } - classname(): CharacterClassName { - return 'Thief'; - } +export class Thief extends Character{ constructor(public name: string, public key: number) { - equip(ThiefStartItem, this); - } - chooseAction(): ICharacterActionDecision { - return { - attack: this.weapons[0] - } - } - getASCIIStatus(): string { - return "@"; - } -} - -//todo: something about this class is code smell... -export class Feet{ - constructor(private character: ICharacter){} - move(){ - if (this.character.weapons.some(x => isMeleeWeapon(x))){ - this.character.position = Math.max(this.character.position - 5, 1); - } - } + super('T', 'Thief', ThiefStartItem, key) + } } diff --git a/src/workshop/Weapons.tsx b/src/workshop/Weapons.tsx index 05e4f63..99eb7c9 100644 --- a/src/workshop/Weapons.tsx +++ b/src/workshop/Weapons.tsx @@ -24,12 +24,53 @@ import { IWeapon, IItem, IMeleeWeapon, IRangedWeapon, IConsumableItem, IEnchante // WEAPON ARMORY // todo: add more and better weapons! + +export class Redhorse implements IConsumableItem { + healthBonus = 4; + name = 'Redhorse'; + +} + export class Club implements IMeleeWeapon { name = 'Club'; - damage = 1; - meleeRange = 1; + damage = 2; + meleeRange = 2; +} + +export class Grenade implements IMeleeWeapon { + name = 'Grenade'; + damage = 2; + meleeRange = 2; +} + +export class GrenadeLauncher implements IRangedWeapon { + name = 'GrenadeLauncher'; + damage:0 = 0; + projectiles: Grenade[] = [ + new Grenade(), new Grenade() + ]; + } +export class BattleFury implements IMeleeWeapon { + name = 'Battle Fury'; + damage = 2; + meleeRange = 2; +} + +export class BloodThorn implements IMeleeWeapon { + name = 'Blood Thorn'; + damage = 2; + meleeRange = 2; +} + +export class AghanimsBlessing implements IEnchantedItem { + name = 'Aghanims Blessing'; + fireDamage = 3; + partyHealthBonus = 4; +} + + // ITEM VAULT // todo: add more and better items! export class UselessAmulet implements IItem { @@ -39,18 +80,18 @@ export class UselessAmulet implements IItem { // ITEM ASSIGNMENTS // todo: assign starting items -export const WarriorStartItem: IItem|undefined = new Club(); -export const ClericStartItem: IItem|undefined = new Club(); +export const WarriorStartItem: IItem|undefined = new Redhorse(); +export const ClericStartItem: IItem|undefined = new Redhorse(); export const MageStartItem: IItem|undefined = undefined; -export const ThiefStartItem: IItem|undefined = new Club(); +export const ThiefStartItem: IItem|undefined = new Redhorse(); // TREASURE ASSIGNMENTS // todo: assign treasure from chests export function GetItemsInTreasureChests(): IItem[]{ return [ - new UselessAmulet(), //this will be found by the warrior - new UselessAmulet(), //this will be found by the cleric - new UselessAmulet(), //this will be found by the mage - new UselessAmulet(), //this will be found by the thief + new GrenadeLauncher(), //this will be found by the warrior + new BattleFury(), //this will be found by the cleric + new AghanimsBlessing(), //this will be found by the mage + new BloodThorn(), //this will be found by the thief ]; }