From: xangelo Date: Fri, 16 Jun 2023 18:00:55 +0000 (-0400) Subject: large equipment modification to support integer ids for shop items X-Git-Tag: v0.0.1~33 X-Git-Url: https://git.xangelo.ca/?a=commitdiff_plain;h=700898b7dbaa98761ac1a9aeee86540769fce888;p=risinglegends.git large equipment modification to support integer ids for shop items For now we only support being able to buy items from the stores.. eventually you'll be able to craft stuff and probably get custom item drops. We also support inventory being created via airtable --- diff --git a/migrations/20230616170746_shop_item_int_ids.ts b/migrations/20230616170746_shop_item_int_ids.ts new file mode 100644 index 0000000..ae98204 --- /dev/null +++ b/migrations/20230616170746_shop_item_int_ids.ts @@ -0,0 +1,16 @@ +import { Knex } from "knex"; + + +export async function up(knex: Knex): Promise { + return knex.schema.alterTable('shop_items', function(table) { + table.dropColumn('id'); + }).alterTable('shop_items', function(table) { + table.increments('id').primary(); + table.string('location_id'); + }); +} + + +export async function down(knex: Knex): Promise { +} + diff --git a/seeds/shop_items.ts b/seeds/shop_items.ts index a704be2..2679614 100644 --- a/seeds/shop_items.ts +++ b/seeds/shop_items.ts @@ -1,84 +1,56 @@ -import {ShopItem, InventoryType, EquipmentSlot} from "../src/shared/inventory"; -import { Knex } from "knex"; -import { join } from 'path'; -import { readFile } from 'fs'; -import { promisify } from 'util'; -import {Profession} from "../src/shared/profession"; -import {SkillID} from "../src/shared/skills"; -import { parse } from "csv-parse/sync"; +import { config as dotenv } from 'dotenv'; +import { db } from "../src/server/lib/db"; +import Airtable from 'airtable'; -const read = promisify(readFile); +dotenv(); -export async function seed(knex: Knex): Promise { - // Deletes ALL existing entries - await knex("shop_items").del(); - await knex("equipped").del(); - await knex("inventory").del(); +Airtable.configure({ + apiKey: process.env.AIRTABLE_API_KEY +}); - const raw = await read(join(__dirname, '..', 'data', 'inventory.csv'), 'utf8'); - const stats = { - created: 0, - skipped: 0 - }; +const base = Airtable.base('appDfPLPajPNog5Iw'); - const items: Omit[] = []; +export async function createShopItems(): Promise { + return new Promise(async (resolve) => { + base('Shop Items').select().eachPage(async (records, next) => { + await db('shop_items').insert(records.map(r => { + return { + id: r.fields.id, + name: r.fields.Name, + type: r.fields['Equipment Type'], + equipment_slot: r.fields['Equipment Slot'], + cost: r.fields.Cost, + count: 1, + requirements: { + level: r.fields['Required Level'], + strength: r.fields['Required STR'], + constitution: r.fields['Required CON'], + dexterity: r.fields['Required DEX'], + intelligence: r.fields['Required INT'] + }, + boosts: { + strength: r.fields['Boost STR'], + constitution: r.fields['Boost CON'], + dexterity: r.fields['Boost DEX'], + intelligence: r.fields['Boost INT'], + damage: r.fields['Boost DMG'] + }, + currentAp: r.fields['Armour Points'], + maxAp: r.fields['Armour Points'], + affectedSkills: JSON.stringify(r.fields['Affected Skills']), + location_id: r.fields.location_id[0] + }; - const records = parse(raw, { bom: true, skip_empty_lines: true }); - records.slice(1).forEach((pieces: string[]) => { - if(pieces.length === 17 && pieces[0].length) { - console.log('Adding', pieces[0]); - stats.created++; - const [ - name, - type, - equipment_slot, - profession, - affectedSkills, - cost, - requirement_level, - requirement_strength, - requirement_constitution, - requirement_dexterity, - requirement_intelligence, - boost_strength, - boost_constitution, - boost_dexterity, - boost_intelligence, - boost_damage, - maxAp - ] = pieces; - items.push({ - name, - type: type as InventoryType, - equipment_slot: equipment_slot as EquipmentSlot, - profession: profession as Profession, - cost: parseInt(cost), - count: 1, - requirements: { - level: parseInt(requirement_level), - strength: parseInt(requirement_strength), - constitution: parseInt(requirement_constitution), - dexterity: parseInt(requirement_dexterity), - intelligence: parseInt(requirement_intelligence) - }, - boosts: { - strength: parseInt(boost_strength), - constitution: parseInt(boost_constitution), - dexterity: parseInt(boost_dexterity), - intelligence: parseInt(boost_intelligence), - damage: parseInt(boost_damage), - }, - currentAp: parseInt(maxAp), - maxAp: parseInt(maxAp), - affectedSkills: JSON.stringify(affectedSkills.split(',')) as unknown as SkillID[] - }); - - } - else { - stats.skipped++; - } + })).onConflict('id').merge(); + next(); + }).finally(() => resolve()); }); +} - await knex('shop_items').insert(items); - console.log(stats); -}; +createShopItems().then(() => { + console.log('Complete'); + process.exit(0); +}).catch(e => { + console.log(e); + process.exit(1); +}) diff --git a/src/events/windcross-events/server.ts b/src/events/windcross-events/server.ts index 3489760..2c3b9cf 100644 --- a/src/events/windcross-events/server.ts +++ b/src/events/windcross-events/server.ts @@ -47,7 +47,8 @@ export const armourer: SocketEvent = { eventName: 'city:stores:armourer', handler: async (api) => { const shopItems = await listShopItems({ - type: 'ARMOUR' + type: 'ARMOUR', + location_id: 'armourer' }) api.socket.emit('city:store:armourer', shopItems); } @@ -57,8 +58,9 @@ export const blacksmith: SocketEvent = { eventName: 'city:stores:blacksmith', handler: async (api) => { const shopItems = await listShopItems({ - type: 'WEAPON' - }) + type: 'WEAPON', + location_id: 'blacksmith' + }); api.socket.emit('city:store:blacksmith', shopItems); } } @@ -67,7 +69,8 @@ export const mageshop: SocketEvent = { eventName: 'city:stores:mageshop', handler: async (api) => { const shopItems = await listShopItems({ - type: 'SPELL' + type: 'SPELL', + location_id: 'mageshop' }) api.socket.emit('city:store:mageshop', shopItems); } diff --git a/src/server/api.ts b/src/server/api.ts index bc83886..6eda0fb 100644 --- a/src/server/api.ts +++ b/src/server/api.ts @@ -15,7 +15,6 @@ import {FightRound} from '../shared/fight'; import {addInventoryItem, deleteInventoryItem, getEquippedItems, getInventory, updateAp} from './inventory'; import {Monster, MonsterForFight, MonsterForList} from '../shared/monsters'; import {getShopItem } from './shopItem'; -import { v4 as uuid } from 'uuid'; import {EquippedItemDetails} from '../shared/equipped'; import {ArmourEquipmentSlot, EquipmentSlot} from '../shared/inventory'; import { getAllPaths, getAllServices, getCityDetails } from './map'; @@ -149,7 +148,6 @@ io.on('connection', async socket => { const shopItem = await getShopItem(data.id); if(shopItem) { - shopItem.id = uuid(); if(player.gold < shopItem.cost) { socket.emit('alert', { type: 'error', @@ -320,7 +318,6 @@ 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/equipment.ts b/src/server/equipment.ts index b413707..ad34640 100644 --- a/src/server/equipment.ts +++ b/src/server/equipment.ts @@ -1,8 +1,8 @@ import {db} from "./lib/db"; -import {EquippedItem, EquippedItemDetails} from "../shared/equipped"; +import {EquippedItemDetails} from "../shared/equipped"; import {EquipmentSlot, InventoryItem} from "../shared/inventory"; -export async function getEquippedItems(playerId: string): Promise { +export async function getEquippedItems(playerId: string): Promise { return db.raw(` select i.player_id, i.item_id, diff --git a/src/server/inventory.ts b/src/server/inventory.ts index 5682eea..1b0c763 100644 --- a/src/server/inventory.ts +++ b/src/server/inventory.ts @@ -1,4 +1,5 @@ import {InventoryItem, ShopItem} from "../shared/inventory"; +import { v4 as uuid } from 'uuid'; import { db} from './lib/db'; import {EquippedItemDetails} from "../shared/equipped"; @@ -6,7 +7,7 @@ import {EquippedItemDetails} from "../shared/equipped"; export async function addInventoryItem(playerId: string, item: ShopItem) { const inventoryItem: InventoryItem = { player_id: playerId, - item_id: item.id, + item_id: uuid(), name: item.name, type: item.type, equipment_slot: item.equipment_slot, diff --git a/src/server/shopItem.ts b/src/server/shopItem.ts index 3be63d1..65c2ead 100644 --- a/src/server/shopItem.ts +++ b/src/server/shopItem.ts @@ -9,7 +9,7 @@ export function listShopItems(where: Partial): Promise { .orderBy('equipment_slot'); } -export function getShopItem(id: string): Promise { +export function getShopItem(id: number): Promise { return db.select('*').from('shop_items').where({ id }).first(); diff --git a/src/shared/equipped.ts b/src/shared/equipped.ts index adfdc39..2dc33a7 100644 --- a/src/shared/equipped.ts +++ b/src/shared/equipped.ts @@ -1,9 +1,10 @@ -import {InventoryItem, InventoryType} from "./inventory"; +import {EquipmentSlot, InventoryItem, InventoryType} from "./inventory"; export type EquippedItem = { - item_id: string; + item_id: number; player_id: string; type: InventoryType; + equipment_slot: EquipmentSlot } export type EquippedItemDetails = InventoryItem & { diff --git a/src/shared/inventory.ts b/src/shared/inventory.ts index 3256557..0051cf4 100644 --- a/src/shared/inventory.ts +++ b/src/shared/inventory.ts @@ -10,7 +10,7 @@ export type EquipmentSlot = ArmourEquipmentSlot | WeaponEquipmentSlot; export type ShopItem = { - id: string; + id: number; name: string; type: InventoryType; profession: Profession; @@ -34,9 +34,10 @@ export type ShopItem = { currentAp: number; maxAp: number; affectedSkills: SkillID[]; + location_id: string; } -export type InventoryItem = Omit & { +export type InventoryItem = Omit & { item_id: string; player_id: string; };