From 2dbb9b85f89be12743d85ff89f20489873d2ca6d Mon Sep 17 00:00:00 2001 From: xangelo Date: Thu, 31 Aug 2023 17:08:45 -0400 Subject: [PATCH] fix: spells support durability Spells have "Uses" which function the same as durability except they don't take damage after a battle (like weapons). For now you go to the "repair" store to repair this.. but eventually you can go to the: - Mageshop to recharge spells - Armoury to repair armour - Forge to repair weapons --- src/server/locations/healer/index.ts | 4 +++- src/server/locations/recruiter.ts | 2 ++ src/server/views/inventory.ts | 17 +++++++---------- src/server/views/monster-selector.ts | 7 ++++++- src/server/views/repair.ts | 9 +++++++-- src/server/views/stores.ts | 6 +++++- src/shared/inventory.ts | 3 ++- 7 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/server/locations/healer/index.ts b/src/server/locations/healer/index.ts index 16274a2..83551b2 100644 --- a/src/server/locations/healer/index.ts +++ b/src/server/locations/healer/index.ts @@ -7,6 +7,7 @@ import { getCityDetails, getService } from '../../map'; import { sample } from 'lodash'; import { City, Location } from "../../../shared/map"; import { renderPlayerBar } from "../../views/player-bar"; +import { BackToTown } from "../../views/components/button"; export const router = Router(); @@ -123,6 +124,7 @@ router.get('/city/services/healer/:location_id', authEndpoint, async (req: AuthR

${service.name}

${text.join("\n")} +${BackToTown()}
`); @@ -155,7 +157,6 @@ router.post('/city/services/healer/heal/:location_id', authEndpoint, async (req: await updatePlayer(req.player); text.push(`

${getText('heal_successful', service, city)}

`); - text.push('

'); } res.send(` @@ -164,6 +165,7 @@ router.post('/city/services/healer/heal/:location_id', authEndpoint, async (req:

${service.name}

${text.join("\n")} +${BackToTown()}
${renderPlayerBar(req.player)} diff --git a/src/server/locations/recruiter.ts b/src/server/locations/recruiter.ts index 4ce985c..96f720d 100644 --- a/src/server/locations/recruiter.ts +++ b/src/server/locations/recruiter.ts @@ -5,6 +5,7 @@ import { logger } from "../lib/logger"; import * as Alert from "../views/alert"; import { changeProfession } from "../player"; import { renderPlayerBar } from "../views/player-bar"; +import { BackToTown } from "../views/components/button"; function p(str: string) { return `

${str}

`; @@ -69,6 +70,7 @@ router.get('/city/services/profession_recruitor/:location_id', authEndpoint, asy html.push(`

However, you should visit the ${place} in ${town} that can probably provide some guidance!

`); } + html.push(BackToTown()); res.send(`
${service.city_name}
diff --git a/src/server/views/inventory.ts b/src/server/views/inventory.ts index e21d1fd..6026775 100644 --- a/src/server/views/inventory.ts +++ b/src/server/views/inventory.ts @@ -2,6 +2,7 @@ import { EquipmentSlot } from "shared/inventory"; import { EquippedItemDetails } from "../../shared/equipped"; import { PlayerItem } from "../../shared/items"; import { capitalize } from "lodash"; +import { ProgressBar } from "./components/progress-bar"; function icon(icon_name?: string): string { const placeholder = 'https://placehold.co/64x64/af936c/6d5f4d'; @@ -82,15 +83,6 @@ function renderStatBoost(name: string, val: number | string): string { return `${name}: ${valSign}${val}`; } -function generateProgressBar(current: number, max: number, color: string, displayPercent: boolean = true): string { - let percent = 0; - if(max > 0) { - percent = Math.floor((current / max) * 100); - } - const display = `${displayPercent? `${percent}% - `: ''}`; - return `
${display}${current}/${max}
`; -} - function renderInventoryItem(item: EquippedItemDetails , action: (item: EquippedItemDetails) => string): string { return `
@@ -113,7 +105,12 @@ function renderInventoryItem(item: EquippedItemDetails , action: (item: Equipped ${item.boosts.intelligence ? renderStatBoost('INT', item.boosts.intelligence) : ''} ${item.boosts.damage ? renderStatBoost('DMG', item.boosts.damage) : ''} ${item.boosts.damage_mitigation ? renderStatBoost('MIT', item.boosts.damage_mitigation.toString())+'%' : ''} - ${['SPELL'].includes(item.type) ? '': generateProgressBar(item.currentAp, item.maxAp, '#7be67b')} + ${ProgressBar(item.currentAp, item.maxAp, `dur-${item.item_id}`, { + startingColor: '#7be67b', + endingColor: '#7be67b', + displayPercent: false, + title: item.type === 'SPELL' ? 'Uses' : 'Durability' + })}
${item.hasOwnProperty('id') ? `
${item.cost.toLocaleString()}G
` : ''}
diff --git a/src/server/views/monster-selector.ts b/src/server/views/monster-selector.ts index 58c8665..e357835 100644 --- a/src/server/views/monster-selector.ts +++ b/src/server/views/monster-selector.ts @@ -1,6 +1,7 @@ import { max } from "lodash"; import { LocationWithCity } from "../../shared/map"; import { Monster, MonsterForFight } from "../../shared/monsters"; +import { BackToTown } from "./components/button"; export function renderOnlyMonsterSelector(monsters: Monster[] | MonsterForFight[], activeMonsterId: number = 0, location?: LocationWithCity): string { let html = ` @@ -25,7 +26,11 @@ export function renderMonsterSelector(monsters: Monster[] | MonsterForFight[], a const range = [monster.level, monster.level + 3]; return ``; }).join("\n")} -
+ +

+${BackToTown()} + + `; return html; diff --git a/src/server/views/repair.ts b/src/server/views/repair.ts index 447dc84..a049f9c 100644 --- a/src/server/views/repair.ts +++ b/src/server/views/repair.ts @@ -5,6 +5,7 @@ import { LocationWithCity } from "../../shared/map"; import { EquippedItemDetails } from "../../shared/equipped"; import { ProgressBar } from "./components/progress-bar"; import * as City from './components/city'; +import { BackToTown } from "./components/button"; function renderStatBoost(name: string, val: number | string): string { let valSign: string = ''; @@ -42,9 +43,9 @@ export function renderEquipmentDetails(item: EquippedItemDetails, player: Player ${item.boosts.intelligence ? renderStatBoost('INT', item.boosts.intelligence) : ''} ${item.boosts.damage ? renderStatBoost(item.affectedSkills.includes('restoration_magic') ? 'HP' : 'DMG', item.boosts.damage) : ''} ${item.boosts.damage_mitigation ? renderStatBoost('MIT', item.boosts.damage_mitigation.toString())+'%' : ''} - ${['WEAPON','SPELL'].includes(item.type) ? '' : ProgressBar(item.currentAp, item.maxAp, `${item.item_id}-ap`, { + ${ProgressBar(item.currentAp, item.maxAp, `${item.item_id}-ap`, { displayPercent: false, -title: 'Durability', +title: item.type === 'SPELL' ? 'Uses' : 'Durability', startingColor: '#7be67b', endingColor: '#7be67b' })} @@ -78,6 +79,9 @@ export function renderRepairService(equipment: EquippedItemDetails[], player: Pl } equipment.forEach(item => { + if(item.maxAp <= 0) { + return; + } const filter = item.type === 'ARMOUR' ? item.equipment_slot : item.type; listingTypes.add(filter); @@ -109,6 +113,7 @@ export function renderRepairService(equipment: EquippedItemDetails[], player: Pl ${finalListing.join("\n")} + ${BackToTown()} `)}`; return html; diff --git a/src/server/views/stores.ts b/src/server/views/stores.ts index be20cf0..1061703 100644 --- a/src/server/views/stores.ts +++ b/src/server/views/stores.ts @@ -4,6 +4,7 @@ import { capitalize, merge } from "lodash"; import { Player } from "../../shared/player"; import { LocationWithCity } from "shared/map"; import { ProgressBar } from "./components/progress-bar"; +import { BackToTown } from "./components/button"; type RenderStatOptions = { unsigned: boolean @@ -54,6 +55,8 @@ function renderShopItem(item: (ShopItem & Item), action: (item: (ShopItem & Item } export function renderEquipmentDetails(item: ShopEquipment, player: Player): string { + const isSpell = item.type === 'SPELL'; + return `
${item.name}${item.equipment_slot === 'TWO_HANDED' ? ' (2H)': ''}
@@ -73,7 +76,7 @@ export function renderEquipmentDetails(item: ShopEquipment, player: Player): str ${item.boosts.intelligence ? renderStatBoost('INT', item.boosts.intelligence) : ''} ${item.boosts.damage ? renderStatBoost(item.affectedSkills.includes('restoration_magic') ? 'HP' : 'DMG', item.boosts.damage) : ''} ${item.boosts.damage_mitigation ? renderStatBoost('MIT', item.boosts.damage_mitigation.toString())+'%' : ''} - ${['SPELL'].includes(item.type) ? '' : renderStat('Durability', 'DUR', item.maxAp, { unsigned: true })} + ${renderStat(isSpell ? 'Uses': 'Durability', isSpell ? 'Uses': 'DUR', item.maxAp, { unsigned: true })}
${item.hasOwnProperty('id') ? `
${item.cost.toLocaleString()}G
` : ''} @@ -140,6 +143,7 @@ export async function renderStore(equipment: ShopEquipment[], items: (ShopItem & ${finalListing.join("\n")} +${BackToTown()} `; return html; diff --git a/src/shared/inventory.ts b/src/shared/inventory.ts index 0ed26dd..9084cc8 100644 --- a/src/shared/inventory.ts +++ b/src/shared/inventory.ts @@ -1,5 +1,6 @@ import {Profession} from "./profession"; import {SkillID} from "./skills"; +import { max } from 'lodash'; export type InventoryType = 'ARMOUR' | 'WEAPON' | 'SPELL'; @@ -52,5 +53,5 @@ export function repairCost(item: InventoryItem): number { const damageRatio = 1 - (item.currentAp / item.maxAp); - return Math.floor(totalCost * damageRatio); + return max([Math.floor(totalCost * damageRatio), 1]); } -- 2.25.1