import {Player} from '@prisma/client';
import axios from 'axios';
import { Events } from './events';
-import { LoginOutputType, AccountCreateType, MoveOutputType } from 'src/routes';
+import { LoginOutputType, AccountCreateType, MoveOutputType, FightStartType, FightRoundOutput } from 'src/routes';
import {actionLog} from './components';
+import {$fightButton} from './dom';
type ApiResponse<T> = {
status: 'ok' | 'error',
this.player = null;
}
+ setPlayer(player: Player) {
+ this.player = player;
+ this.emit('player', player);
+ }
+
async get<T>(endpoint: string, params: Record<string, string> = {}): Promise<ApiResponse<T>> {
const res = await axios({
return res.payload;
}
+ async setGameTime(gameTime: number) {
+ const str = gameTime < 10 ? `0${gameTime}` : gameTime.toString();
+
+ $('body').removeClass().addClass(`sky-gradient-${str}`);
+ }
+
+ async getPlayerInfo() {
+ if(!this.player) {
+ throw new Error('Not authenticated');
+ }
+ const res = await this.get<Player>(`/v1/accounts/${this.player.id}`);
+
+ this.setPlayer(res.payload);
+
+ // this also sets the background based on the time!
+ this.setGameTime(res.meta.gameTime);
+ }
+
async login(username: string, password: string): Promise<LoginOutputType> {
const res = await this.post<LoginOutputType>('/v1/accounts/auth', {
username: username,
});
this.headers['x-auth-token'] = res.payload.token;
- this.player = res.payload.player;
- this.emit('player', this.player);
+ this.setPlayer(res.payload.player);
+
+ this.setGameTime(res.meta.gameTime);
+
+
+ setInterval(this.getPlayerInfo.bind(this), 5000);
return res.payload;
}
}
const res = await this.post<MoveOutputType>(`/v1/accounts/${this.player.id}/move`);
- this.player = res.payload.player;
+ this.setPlayer(res.payload.player);
+
+ if(res.payload.generatedMonster !== null) {
+ actionLog(`You see a ${res.payload.generatedMonster.name}`);
+ if(this.player.hp > 0 && this.player.stamina > 0) {
+ $fightButton().prop('disabled', false)
+ .removeClass(['disabled', 'hidden'])
+ .attr('data-fight-id', res.payload.generatedMonster.id);
+ }
+ }
+ else {
+ actionLog(res.payload.displayText, true);
+ $fightButton().prop('disabled', true)
+ .addClass(['disabled', 'hidden'])
+ .attr('data-fight-id', 'unset');
+ }
- this.emit('player', this.player);
+ return res.payload;
+ }
- actionLog(res.payload.displayText, true);
+ async increaseStat(stat: string): Promise<Player> {
+ if(this.player === null) {
+ throw new Error('Not authenticated');
+ }
+ const res = await this.post<Player>(`/v1/accounts/${this.player.id}/stat`, {
+ stat: stat
+ });
+ this.setPlayer(res.payload);
return res.payload;
}
+
+ async startFight(fightId: string): Promise<FightStartType> {
+ if(this.player === null) {
+ throw new Error('Not authenticated');
+ }
+
+ const res = await this.post<FightStartType>(`/v1/accounts/${this.player.id}/fight/${fightId}`);
+
+ if(!res.payload.id) {
+ throw new Error('Invalid fight!');
+ }
+
+ return res.payload;
+ }
+
+ async fight(fightId: string): Promise<FightRoundOutput> {
+ if(this.player === null) {
+ throw new Error('Not authenticated');
+ }
+
+ await this.startFight(fightId);
+
+ const res = await this.post<FightRoundOutput>(`/v1/accounts/${this.player.id}/fight/${fightId}/round`, {
+ action: 'Fight'
+ });
+
+ const output = res.payload;
+
+ this.setPlayer(output.player);
+
+ console.log(output);
+
+ const participants = {
+ [output.player.id]: output.player.username,
+ [output.monster.id]: output.monster.name
+ }
+
+ output.roundData.map(round => {
+ const p1 = participants[round.attacker];
+ const p2 = participants[round.defender];
+
+ const css = round.attacker === output.player.id ? 'text-secondary' : 'text-info';
+ let str = `<span class="${css}">${p1}</span> dealt <span class="text-danger">${round.damage} damage</span> to ${p2}`;
+
+ return str;
+ }).forEach(a => actionLog(a, false));
+
+ if(output.winner === 'player') {
+ actionLog(`<span class="text-success">You defeated the ${output.monster.name}</span>`, false);
+ }
+ else {
+ actionLog(`<span class="text-danger">You were defeated by the ${output.monster.name}</span>`, false);
+ }
+
+ Object.keys(output.reward).forEach(rewardType => {
+ switch(rewardType) {
+ case 'exp':
+ actionLog(`You gained <span class="text-info">${output.reward.exp}</span> Exp`, false);
+ break;
+ case 'currency':
+ actionLog(`You gained <span class="text-warning">${output.reward.currency}</span> Steel`, false);
+ break;
+ }
+ });
+
+ $fightButton().prop('disabled', true)
+ .addClass(['disabled', 'hidden'])
+ .attr('data-fight-id', 'unset');
+
+ return output;
+ }
}