From: xangelo Date: Thu, 16 Jan 2025 04:41:33 +0000 (-0500) Subject: feat: remove stamina as a game mechanic X-Git-Tag: v0.4.4~2 X-Git-Url: https://git.xangelo.ca/?a=commitdiff_plain;h=64f2ae3ba1898cfc1268d0393195e8187c54fe98;p=risinglegends.git feat: remove stamina as a game mechanic after play-testing, its come up that the stamina mechanic is just confusing players. it is called "vigor", which most games don't use, It regens too quicklt to actually slow user actions down. The whole game is an active pbbg, so restricting actions that the player has to manually do is just not fun. --- diff --git a/migrations/20250115194051_remove_stamina.ts b/migrations/20250115194051_remove_stamina.ts new file mode 100644 index 0000000..6cf68d0 --- /dev/null +++ b/migrations/20250115194051_remove_stamina.ts @@ -0,0 +1,13 @@ +import { Knex } from "knex"; + +export async function up(knex: Knex): Promise { + await knex.schema.alterTable('players', table => { + table.dropColumn('stamina'); + }); +} + +export async function down(knex: Knex): Promise { + await knex.schema.alterTable('players', table => { + table.integer('stamina').defaultTo(0); + }); +} diff --git a/src/server/fight.ts b/src/server/fight.ts index dda4a7a..8c1ecdb 100644 --- a/src/server/fight.ts +++ b/src/server/fight.ts @@ -12,7 +12,6 @@ import { expToLevel, maxHp, totalDefence, - maxVigor, baseDamage, } from "../shared/player"; import { clearTravelPlan } from "./map"; @@ -184,7 +183,7 @@ export async function fightRound( } } - // @TODO implement flee based on dex + vigor + // @TODO implement flee based on dex if (data.action === "flee") { roundData.roundDetails.push( `You managed to escape from the ${monster.name}!` @@ -318,7 +317,6 @@ export async function fightRound( ); player.hp = maxHp(player.constitution, player.level); - player.vigor = maxVigor(player.constitution, player.level); } // get the monster location if it was an EXPLORED fight if (roundData.fightTrigger === "explore") { @@ -337,11 +335,6 @@ export async function fightRound( }); } - player.vigor -= 1; - if (player.vigor < 0) { - player.vigor = 0; - } - const unequippedItems = await updateAp( player.id, 1, @@ -381,7 +374,6 @@ export async function fightRound( if (player.hp <= 0) { player.hp = 0; - player.vigor = 0; roundData.winner = "monster"; roundData.roundDetails.push(`You were killed by the ${monster.name}`); diff --git a/src/server/player.ts b/src/server/player.ts index 36910ac..6c94fca 100644 --- a/src/server/player.ts +++ b/src/server/player.ts @@ -1,5 +1,5 @@ import { db } from './lib/db'; -import {Player, maxHp, maxVigor} from "@shared/player"; +import {Player, maxHp} from "@shared/player"; import { random } from 'lodash'; import { Skills } from '@shared/skills'; import {Profession} from '@shared/profession'; @@ -68,7 +68,6 @@ export async function createPlayer(): Promise { }; raw.hp = maxHp(raw.constitution, 1); - raw.vigor = maxVigor(raw.constitution, 1); const res = await db('players').insert(raw).returning('*'); const player = res.pop(); @@ -103,7 +102,6 @@ export async function updatePlayer(player: Player) { id: player.id }).update({ hp: player.hp, - vigor: player.vigor, strength: player.strength, constitution: player.constitution, dexterity: player.dexterity, diff --git a/src/server/routes/locations/dungeon.ts b/src/server/routes/locations/dungeon.ts index 6ed09b3..ef025e2 100644 --- a/src/server/routes/locations/dungeon.ts +++ b/src/server/routes/locations/dungeon.ts @@ -8,7 +8,7 @@ import * as Alert from '../../views/alert'; import { createFight, loadMonster } from "../../monster"; import { renderFightPreRoundDungeon } from "../../views/fight"; import { has, max, each } from 'lodash'; -import { expToLevel, maxHp, maxVigor } from "../../../shared/player"; +import { expToLevel, maxHp} from "../../../shared/player"; import { updatePlayer } from "../../player"; import { getEventHistoryToday } from "../../events"; @@ -175,7 +175,6 @@ dungeonRouter.post('/city/dungeon/:dungeon_id/complete', authEndpoint, async (re req.player.level++; req.player.stat_points += req.player.profession === 'Wanderer' ? 1 : 2; req.player.hp = maxHp(req.player.constitution, req.player.level); - req.player.vigor = maxVigor(req.player.constitution, req.player.level); } // delete the tracking for this dungeon-run diff --git a/src/server/routes/locations/healer.ts b/src/server/routes/locations/healer.ts index 6edc0b5..a82ccbc 100644 --- a/src/server/routes/locations/healer.ts +++ b/src/server/routes/locations/healer.ts @@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { maxHp, maxVigor } from "../../../shared/player"; +import { maxHp} from "../../../shared/player"; import { authEndpoint } from '../../auth'; import { updatePlayer } from "../../player"; import { getCityDetails, getService } from '../../map'; @@ -103,7 +103,7 @@ healerRouter.get('/city/services/healer/:location_id', authEndpoint, async (req: text.push(`

"${getText('intro', service, city)}"

`); - if(req.player.hp === maxHp(req.player.constitution, req.player.level) && req.player.vigor === maxVigor(req.player.constitution, req.player.level)) { + if(req.player.hp === maxHp(req.player.constitution, req.player.level)) { text.push(`

You're already in peak condition!

`); } else { @@ -150,7 +150,6 @@ healerRouter.post('/city/services/healer/heal/:location_id', authEndpoint, async } else { req.player.hp = maxHp(req.player.constitution, req.player.level); - req.player.vigor = maxVigor(req.player.constitution, req.player.level); req.player.gold -= cost; await updatePlayer(req.player); diff --git a/src/server/routes/profile.ts b/src/server/routes/profile.ts index 79b0bd5..4d862df 100644 --- a/src/server/routes/profile.ts +++ b/src/server/routes/profile.ts @@ -2,7 +2,7 @@ import { Request, Response, Router } from 'express'; import { authEndpoint } from '../auth'; import { getEquippedItems } from '../inventory'; import { updatePlayer } from '../player'; -import {maxHp, maxVigor } from '../../shared/player'; +import {maxHp} from '../../shared/player'; import * as Alert from '../views/alert'; import { renderPlayerBar } from '../views/player-bar' import { renderProfilePage } from '../views/profile'; @@ -41,7 +41,6 @@ profileRouter.post('/player/stat/:stat', authEndpoint, async (req: Request, res: req.player[stat]++; req.player.hp = maxHp(req.player.constitution, req.player.level); - req.player.vigor = maxVigor(req.player.constitution, req.player.level); updatePlayer(req.player); res.send(renderPlayerBar(req.player) + renderProfilePage(req.player, equipment)); diff --git a/src/server/views/player-bar.ts b/src/server/views/player-bar.ts index aa56799..50dc906 100644 --- a/src/server/views/player-bar.ts +++ b/src/server/views/player-bar.ts @@ -1,4 +1,4 @@ -import { expToLevel, maxHp, maxVigor, Player } from "@shared/player"; +import { expToLevel, maxHp, Player } from "@shared/player"; import { ProgressBar } from "./components/progress-bar"; function displayLoginSignupForm(): string { @@ -32,7 +32,6 @@ export function renderPlayerBar(player: Player): string {
${player.gold.toLocaleString()}
${ProgressBar(player.hp, maxHp(player.constitution, player.level), 'hp-bar', { endingColor: '#ff7070', startingColor: '#d62f2f', title: 'HP', displayPercent: true })} - ${ProgressBar(player.vigor, maxVigor(player.constitution, player.level), 'vigor-bar', { endingColor: '#5ebb5e', startingColor: '#7be67b', title: 'Vigor', displayPercent: true})} ${ProgressBar(player.exp, expToLevel(player.level + 1), 'exp-bar', { endingColor: '#5997f9', startingColor: '#1d64d4', title: 'EXP', displayPercent: true})} ${player.account_type === 'session' ? displayLoginSignupForm() : ''} diff --git a/src/server/views/profile.ts b/src/server/views/profile.ts index 27e2b13..100007a 100644 --- a/src/server/views/profile.ts +++ b/src/server/views/profile.ts @@ -1,5 +1,5 @@ import { EquippedItemDetails } from "@shared/equipped"; -import { expToLevel, maxHp, maxVigor, Player, StatDef, StatDisplay, totalDefence } from "@shared/player"; +import { expToLevel, maxHp, Player, StatDef, StatDisplay, totalDefence } from "@shared/player"; function statPointIncreaser(stat: StatDisplay) { return ``; @@ -25,17 +25,13 @@ export function renderProfilePage(player: Player, equipment: EquippedItemDetails HP ${player.hp.toLocaleString()}/${maxHp(player.constitution, player.level).toLocaleString()} - - Vigor - ${player.vigor.toLocaleString()}/${maxVigor(player.constitution, player.level).toLocaleString()} - EXP ${player.exp.toLocaleString()}/${expToLevel(player.level + 1).toLocaleString()} - Defence - ${totalDefence(equipment, player, false).toLocaleString()} (${totalDefence(equipment, player).toLocaleString()}) + Defence + ${totalDefence(equipment, player).toLocaleString()} (${totalDefence(equipment, player).toLocaleString()}) Stat Points diff --git a/src/shared/player.ts b/src/shared/player.ts index d9aac73..e8dc027 100644 --- a/src/shared/player.ts +++ b/src/shared/player.ts @@ -21,14 +21,12 @@ export type Player = { constitution: number; dexterity: number; intelligence: number; - stamina: number; exp: number; level: number; gold: number; hp: number; city_id: number; stat_points: number; - vigor: number; permissions: Permission[] } @@ -40,10 +38,6 @@ export function maxHp(constitution: number, playerLevel: number): number { return Math.ceil((constitution * 1.7) + (playerLevel * 1.3)); } -export function maxVigor(constitution: number, playerLevel: number): number { - return Math.ceil((constitution * 3.8) + (playerLevel * 1.5)); -} - export function expToLevel(level: number): number { if(level < 10) { return level * 10 - 10; @@ -53,20 +47,13 @@ export function expToLevel(level: number): number { } } -export function totalDefence(equippedItems: EquippedItemDetails[], player: Player, accountForVigor: boolean = true): number { - const vigorPercent = player.vigor / maxVigor(player.constitution, player.level); - +export function totalDefence(equippedItems: EquippedItemDetails[], player: Player): number { const totalDefence = equippedItems.reduce((acc, curr) => { let defence = curr.boosts.defence ?? 0; return acc += defence; }, 0); - if(accountForVigor) { - return Math.ceil(totalDefence * vigorPercent); - } - else { - return totalDefence; - } + return totalDefence; } export function baseDamage(statValue: number, boostStat: number, damage: number): number { @@ -93,7 +80,7 @@ StatDef.set(Stat.constitution, { id: Stat.constitution, display: 'Constitution', abbrv: 'CON', - description: 'Affects your max HP and Vigor' + description: 'Affects your max HP' }); StatDef.set(Stat.dexterity, {