From a68748f03d5d649601595a043e8aa418e5fc7587 Mon Sep 17 00:00:00 2001 From: xangelo Date: Fri, 16 Jun 2023 12:50:07 -0400 Subject: [PATCH] factions! This adds a simple "faction" system which is that a monster may belong to a single faction. For now nothing is done with this but later on this can be expanded to include a reputation system or titles and the like. --- migrations/20230616153627_factions.ts | 20 +++++++++++++++++++ seeds/monsters.ts | 28 ++++++++++++++++++++++++--- src/server/api.ts | 5 +++-- src/server/monster.ts | 16 ++++++++++++++- src/shared/factions.ts | 5 +++++ src/shared/fight.ts | 4 ++-- src/shared/monsters.ts | 8 +++++++- 7 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 migrations/20230616153627_factions.ts create mode 100644 src/shared/factions.ts diff --git a/migrations/20230616153627_factions.ts b/migrations/20230616153627_factions.ts new file mode 100644 index 0000000..2b20a15 --- /dev/null +++ b/migrations/20230616153627_factions.ts @@ -0,0 +1,20 @@ +import { Knex } from "knex"; + + +export async function up(knex: Knex): Promise { + return knex.schema.createTable('factions', function(table) { + table.increments('id').primary(); + table.string('name').unique(); + table.text('description').nullable(); + }).alterTable('monsters', function(table) { + table.integer('faction_id').nullable(); + }); +} + + +export async function down(knex: Knex): Promise { + return knex.schema.dropTable('factions').alterTable('monsters', function(table) { + table.dropColumn('faction_id'); + }); +} + diff --git a/seeds/monsters.ts b/seeds/monsters.ts index 538b31e..f7efe01 100644 --- a/seeds/monsters.ts +++ b/seeds/monsters.ts @@ -13,10 +13,29 @@ Airtable.configure({ const base = Airtable.base('appDfPLPajPNog5Iw'); +export async function createFactions(): Promise { + return new Promise(async (resolve, reject) => { + base('Factions').select().eachPage(async (records, next) => { + await db('factions').insert(records.map(r => { + console.log(`Creating faction ${r.fields.Name}`); + return { + id: r.fields.ID, + name: r.fields.Name, + description: r.fields.Description + } + })).onConflict('id').merge(); + + next(); + }).finally(() => { + resolve(); + }) + + }); +} + export async function createMonsters(): Promise { return new Promise(async (resolve, reject) => { - await db('monsters').delete(); await db('fight').delete(); base('Monsters').select().eachPage(async (records, next) => { @@ -26,6 +45,8 @@ export async function createMonsters(): Promise { } stats.monsters[r.fields.location_id[0]]++; + const factionId = r.fields.faction_id ? r.fields.faction_id[0] : null; + return { id: r.fields.id, name: r.fields.Name, @@ -42,7 +63,8 @@ export async function createMonsters(): Promise { chestAp: r.fields.chestAp, legsAp: r.fields.legsAp, armsAp: r.fields.armsAm, - location_id: r.fields.location_id[0] + location_id: r.fields.location_id[0], + faction_id: factionId } })).onConflict('id').merge(); @@ -56,7 +78,7 @@ export async function createMonsters(): Promise { // run this script manually if(!module.parent) { - createMonsters().then(() => { + createFactions().then(createMonsters).then(() => { console.log(stats.monsters); console.log('Complete'); process.exit(0); diff --git a/src/server/api.ts b/src/server/api.ts index b35b73a..bc83886 100644 --- a/src/server/api.ts +++ b/src/server/api.ts @@ -10,7 +10,7 @@ import * as _ from 'lodash'; import {broadcastMessage, Message} from '../shared/message'; import {expToLevel, maxHp, Player} from '../shared/player'; import { professionList } from '../shared/profession'; -import {clearFight, createFight, getMonsterList, loadMonster, loadMonsterFromFight, saveFightState} from './monster'; +import {clearFight, createFight, getMonsterList, loadMonster, loadMonsterFromFight, loadMonsterWithFaction, saveFightState} from './monster'; import {FightRound} from '../shared/fight'; import {addInventoryItem, deleteInventoryItem, getEquippedItems, getInventory, updateAp} from './inventory'; import {Monster, MonsterForFight, MonsterForList} from '../shared/monsters'; @@ -195,7 +195,7 @@ io.on('connection', async socket => { }); socket.on('fight', async (data: {action: 'attack' | 'cast' | 'flee', target: 'head' | 'body' | 'arms' | 'legs'}) => { - const monster = await loadMonsterFromFight(player.id); + const monster = await loadMonsterWithFaction(player.id); const playerSkills = await getPlayerSkillsAsObject(player.id); const roundData: FightRound = { monster, @@ -320,6 +320,7 @@ io.on('connection', async socket => { const playerFinalHeal = Math.floor(boost.hp + hpHealAfterMasteries); roundData.roundDetails.push(`You targeted the monsters ${data.target.toUpperCase()} with ${attackType} damage!`); + console.log(monster); if(data.target === 'arms') { if(monster.armsAp > 0) { monster.armsAp -= playerFinalDamage; diff --git a/src/server/monster.ts b/src/server/monster.ts index b1b8481..3a522dd 100644 --- a/src/server/monster.ts +++ b/src/server/monster.ts @@ -1,5 +1,5 @@ import { db } from './lib/db'; -import { Fight, Monster } from '../shared/monsters'; +import { Fight, Monster, MonsterWithFaction } from '../shared/monsters'; export async function getMonsterList(location_id: string): Promise { const res: Monster[] = await db.select('*') @@ -22,6 +22,20 @@ export async function loadMonsterFromFight(authToken: string): Promise { }); } +export async function loadMonsterWithFaction(authToken: string): Promise { + const res = await db.raw(` + select + f.*, fa.id as faction_id, fa.name as faction_name + from fight f + join monsters m on f.ref_id = m.id + left outer join factions fa on m.faction_id = fa.id + where f.player_id = ? + limit 1 + `, [authToken]); + + return res.rows[0]; +} + export async function saveFightState(authToken: string, monster: Fight) { return db('fight').where({ player_id: authToken, diff --git a/src/shared/factions.ts b/src/shared/factions.ts new file mode 100644 index 0000000..080c769 --- /dev/null +++ b/src/shared/factions.ts @@ -0,0 +1,5 @@ +export type Faction = { + id: number; + name: string; + description: string; +} diff --git a/src/shared/fight.ts b/src/shared/fight.ts index fcbc86a..2adc735 100644 --- a/src/shared/fight.ts +++ b/src/shared/fight.ts @@ -1,4 +1,4 @@ -import {Fight} from "./monsters" +import {MonsterWithFaction} from "./monsters" import {Player} from "./player" export type FightReward = { @@ -8,7 +8,7 @@ export type FightReward = { } export type FightRound = { - monster: Fight, + monster: MonsterWithFaction, player: Player, winner: 'player' | 'monster' | 'in-progress', rewards: FightReward, diff --git a/src/shared/monsters.ts b/src/shared/monsters.ts index fe9cc2f..e75cc36 100644 --- a/src/shared/monsters.ts +++ b/src/shared/monsters.ts @@ -15,6 +15,7 @@ export type Monster = { legsAp: number; maxHp: number; location_id: string; + faction_id: number; } export type MonsterForList = { @@ -23,12 +24,17 @@ export type MonsterForList = { level: number; } -export type Fight = Omit & { +export type Fight = Omit & { id: string, player_id: string, ref_id: number }; +export type MonsterWithFaction = Fight & { + faction_id: string; + faction_name: string; +} + export type MonsterForFight = { id: number | string; hp: number; -- 2.25.1