Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export interface AppState {
view: 'menu' | 'loot' | 'fight';
}

// xTODO: Create an enum for the currentCharacter than number type


function getNewGameState(): AppState{
return {
characters: [
Expand Down
1 change: 1 addition & 0 deletions src/off-limits/CombatUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const CharacterRow: React.FC<{
{cols.map((c, i) => {
return (
<td className="col" key={i}>
{i}
{c.c ? (
<CharacterCombatUI
character={props.character}
Expand Down
52 changes: 46 additions & 6 deletions src/workshop/BaseCharacter.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,64 @@
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, isConsumable, isRangedWeapon, isMeleeWeapon, isWeapon } from "../off-limits/IWeapons";

//todo: use this base class somehow in Characters.tsx
export class Character implements ICharacter {
name: string = '';
health: number = 5;
position: number = 10;
weapons: IWeapon[] = [];
item?: IItem;

private selectedWeapon?: IWeapon;

// Have an option to assign specific character
constructor(
private readonly characterItem?: IItem,
private readonly asciiCharacter?: string,
) {
equip(characterItem, this);
}

classname(): CharacterClassName {
throw new Error("Method not implemented.");
}
move(){
throw new Error("Method not implemented.");
if (this.weapons.some(x => isMeleeWeapon(x))){
this.position = Math.max(this.position - 5, 1);
}
}

chooseAction(): ICharacterActionDecision{
throw new Error("Method not implemented.");
const minHealth = 2;

if (this.position >=5 ) {
const rangeItem = this.weapons?.find(item => isRangedWeapon(item));

if (rangeItem) {
return { use: rangeItem };
}
}

if (this.health <= minHealth) {
if (this.item) {
return { use: this.item };
}
}


// Kludge Assign best weapon to current hero
if (!this.selectedWeapon) {
this.selectedWeapon = this.weapons?.reduce(function(prev, current) {
return isWeapon(current) && ((prev.damage ?? 0) > (current.damage ?? 0)) ? prev : current
});
}

return { attack: this.selectedWeapon }
}
getASCIIStatus(): string {
throw new Error("Method not implemented.");
if (this.health <= 0) {
return 'X';
}

return this.asciiCharacter ? this.asciiCharacter : '@';
}
}
96 changes: 10 additions & 86 deletions src/workshop/Characters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,116 +8,40 @@ import {
WarriorStartItem,
} from './Weapons';

//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);
export class Warrior extends Character {
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 "@";
super(WarriorStartItem, 'W');
}
}

export class Cleric implements ICharacter{
health: number = 5;
position: number = 10;
weapons: IWeapon[] = [];
item?: IItem;
feet = new Feet(this);
export class Cleric extends Character {
classname(): CharacterClassName {
return 'Cleric';
}
move(){
this.feet.move();
}

constructor(public name: string, public key: number) {
equip(ClericStartItem, this);
}
chooseAction(): ICharacterActionDecision {
return {
attack: this.weapons[0]
}
}
getASCIIStatus(): string {
return "@";
super(ClericStartItem, 'C');
}
}

export class Mage implements ICharacter {
health: number = 5;
position: number = 10;
weapons: IWeapon[] = [];
item?: IItem;
feet = new Feet(this);
export class Mage extends Character {
classname(): CharacterClassName {
return 'Mage';
}
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(MageStartItem, 'M');
}
}

export class Thief implements ICharacter {
health: number = 5;
position: number = 10;
weapons: IWeapon[] = [];
item?: IItem;
feet = new Feet(this);
move(){
this.feet.move();
}
export class Thief extends Character {
classname(): CharacterClassName {
return 'Thief';
}
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(ThiefStartItem, 'T');
}
}
Loading