Add starting stats, work on classes models

This commit is contained in:
Sky Johnson 2024-07-15 14:24:13 -05:00
parent 6835d6832c
commit b328263aef
6 changed files with 94 additions and 27 deletions

View File

@ -9,12 +9,17 @@ class App
public static Database $db; public static Database $db;
private static string $dbPath; private static string $dbPath;
public static Request $req; public static Request $req;
public static array $s = []; // game settings
public function __construct(string $dbPath) public function __construct(string $dbPath)
{ {
self::$req = new Request(); // the current request self::$req = new Request(); // the current request
self::$db = new Database($dbPath); // the database self::$db = new Database($dbPath); // the database
self::$dbPath = $dbPath; // the database path self::$dbPath = $dbPath; // the database path
// load game settings
$s = self::$db->q('SELECT * FROM settings WHERE id = 1;');
self::$s = $s ? $s->fetch() : [];
} }
public static function performDatabaseReset(): void public static function performDatabaseReset(): void

View File

@ -1,32 +1,42 @@
<?php // library.php :: Common functions used throughout the program. <?php // library.php :: Common functions used throughout the program.
// Diff two times in seconds.
function stopwatch(float $start, int $roundTo = 3): float function stopwatch(float $start, int $roundTo = 3): float
{ {
return round(microtime(true) - $start, $roundTo); return round(microtime(true) - $start, $roundTo);
} }
// Redirect to another page.
function redirect(string $url): void function redirect(string $url): void
{ {
header("Location: $url"); header("Location: $url");
exit; exit;
} }
// Redirect to the install page if not installed.
// Otherwise, redirect to the main page if requesting the install page.
function installRedirect(string $route) function installRedirect(string $route)
{ {
if (!INSTALLED && $route != 'install') redirect('/install'); if (!INSTALLED && $route != 'install') redirect('/install');
if (INSTALLED && $route == 'install') redirect('/'); if (INSTALLED && $route == 'install') redirect('/');
} }
// Get the path to a template.
function template(string $name): string function template(string $name): string
{ {
return SERVER."/templates/$name.php"; return SERVER."/templates/$name.php";
} }
/** // Checks if all required fields are set.
* Renders a template. Pass data to it - uses an output buffer to have PHP process the template instead of using function required(array $keys): bool
* a template engine. If you're including partials in the page, call `render('partial', $data)`, as $data will still {
* be available. foreach ($keys as $key) if (!isset($_POST[$key]) || empty($_POST[$key])) return false;
*/ return true;
}
// Renders a template. Pass data to it - uses an output buffer to have PHP process the template instead of using
// a template engine. If you're including partials in the page, call `render('partial', $data)`, as $data will still
// be available.
function render(string $baseView, array $data = []): string function render(string $baseView, array $data = []): string
{ {
ob_start(); ob_start();
@ -35,20 +45,7 @@ function render(string $baseView, array $data = []): string
return ob_get_clean(); return ob_get_clean();
} }
/** // Dump and die.
* Checks if all required fields are set.
*/
function required(array $keys): bool
{
foreach ($keys as $key) {
if (!isset($_POST[$key]) || empty($_POST[$key])) return false;
}
return true;
}
/**
* Dump and die. Useful for debugging.
*/
function dd(mixed $var, bool $r = false) function dd(mixed $var, bool $r = false)
{ {
echo '<pre>'; echo '<pre>';
@ -57,11 +54,26 @@ function dd(mixed $var, bool $r = false)
exit; exit;
} }
function getmicrotime() { // Used for timing script operations. // Calculate the EXP to level up, given a level.
function expToLevel(int $level): int
{
// constants for the quadratic formula
$a = 5; // adjust this value to change the curve's steepness
$b = 20; // adjust this value to change the initial XP increase
$baseOffset = 0; // starting point, no initial offset
list($usec, $sec) = explode(" ",microtime()); if ($level == 1) return 0; // level 1 does not require any XP
return ((float)$usec + (float)$sec);
// calculate the dynamic offset based on the level
$additionalOffset = floor(($level - 1) / 20) * 100;
// total offset
$c = $baseOffset + $additionalOffset;
// calculate the experience required for the given level
$experience = $a * pow($level - 1, 2) + $b * ($level - 1) + $c;
return $experience;
} }
function prettydate($uglydate) { // Change the MySQL date format (YYYY-MM-DD) into something friendlier. function prettydate($uglydate) { // Change the MySQL date format (YYYY-MM-DD) into something friendlier.

View File

@ -7,4 +7,25 @@ class Classes
$res = App::$db->q("SELECT * FROM classes"); $res = App::$db->q("SELECT * FROM classes");
return $res->fetchAll() ?: false; return $res->fetchAll() ?: false;
} }
public static function get(int $id): array|false
{
$res = App::$db->do("SELECT * FROM classes WHERE id = ?", [$id]);
return $res->fetch() ?: false;
}
// Spell definitions are in the DB under the spell columns;
// level:spell_id,spell_id|level:spell_id
// This means that as level increases, more spells are available.
public static function spellsToArray(string $spells): array
{
$list = [];
$groups = explode('|', $spells);
foreach ($groups as $group) {
$parts = explode(':', $group);
// first part will be level, second part will be spell_ids
$list[$parts[0]] = explode(',', $parts[1]);
}
return $list;
}
} }

View File

@ -4,9 +4,29 @@ class Player
{ {
public static function create(array $data): int public static function create(array $data): int
{ {
// get the player's class
$class = Classes::get($data['class_id'] ?? 1);
if ($class == false) die('Player::create: Invalid class selected. ' . print_r($data, true));
// get player level
$l = $data['level'] ?? 1;
// calculate player stats
$data['hp'] = $data['max_hp'] = $data['max_hp'] ?? ($class['start_hp'] + ($class['growth_hp'] * ($l - 1)));
$data['mp'] = $data['max_mp'] = $data['max_mp'] ?? ($class['start_mp'] + ($class['growth_mp'] * ($l - 1)));
$data['tp'] = $data['max_tp'] = $data['max_tp'] ?? (5 + (App::$s['tp_growth'] * ($l - 1)));
$data['str'] = $data['str'] ?? ($class['start_str'] + ($class['growth_str'] * ($l - 1)));
$data['atk'] = $data['atk'] ?? ($class['start_atk'] + ($class['growth_atk'] * ($l - 1)));
$data['def'] = $data['def'] ?? ($class['start_def'] + ($class['growth_def'] * ($l - 1)));
$data['dex'] = $data['dex'] ?? ($class['start_dex'] + ($class['growth_dex'] * ($l - 1)));
$data['stat_points'] = $data['stat_points'] ?? (App::$s['stat_point_gain'] * ($l - 1));
$data['exp2l'] = $data['exp2l'] ?? expToLevel($l + 1);
// compress data and generate placeholers
$keys = implode(', ', array_keys($data)); $keys = implode(', ', array_keys($data));
$placeholders = implode(', ', array_fill(0, count($data), '?')); $placeholders = implode(', ', array_fill(0, count($data), '?'));
// insert into db
App::$db->do("INSERT INTO 'players' ($keys) VALUES ($placeholders);", array_values($data)); App::$db->do("INSERT INTO 'players' ($keys) VALUES ($placeholders);", array_values($data));
return App::$db->lastInsertID(); return App::$db->lastInsertID();
} }

View File

@ -47,7 +47,9 @@ class InstallModule
'verify_email' INT DEFAULT 1, 'verify_email' INT DEFAULT 1,
'show_news' INT DEFAULT 1, 'show_news' INT DEFAULT 1,
'show_online' INT DEFAULT 1, 'show_online' INT DEFAULT 1,
'show_babble' INT DEFAULT 1 'show_babble' INT DEFAULT 1,
'tp_growth' INT DEFAULT 1,
'stat_point_gain' INT DEFAULT 5
);"); );");
// insert default settings // insert default settings
@ -198,14 +200,15 @@ class InstallModule
'class_id' INTEGER DEFAULT 1, 'class_id' INTEGER DEFAULT 1,
'level' INTEGER DEFAULT 1, 'level' INTEGER DEFAULT 1,
'exp' INTEGER DEFAULT 0, 'exp' INTEGER DEFAULT 0,
'exp2l' INTEGER DEFAULT 0,
'gold' INTEGER DEFAULT 0, 'gold' INTEGER DEFAULT 0,
'stat_points' INTEGER DEFAULT 0, 'stat_points' INTEGER DEFAULT 0,
'hp' INTEGER DEFAULT 0, 'hp' INTEGER DEFAULT 0,
'max_hp' INTEGER DEFAULT 0, 'max_hp' INTEGER DEFAULT 0,
'mp' INTEGER DEFAULT 0, 'mp' INTEGER DEFAULT 0,
'max_mp' INTEGER DEFAULT 0, 'max_mp' INTEGER DEFAULT 0,
'tp' INTEGER DEFAULT 0, 'tp' INTEGER DEFAULT 5,
'max_tp' INTEGER DEFAULT 0, 'max_tp' INTEGER DEFAULT 5,
'str' INTEGER DEFAULT 0, 'str' INTEGER DEFAULT 0,
'atk' INTEGER DEFAULT 0, 'atk' INTEGER DEFAULT 0,
'dex' INTEGER DEFAULT 0, 'dex' INTEGER DEFAULT 0,
@ -256,7 +259,7 @@ class InstallModule
} }
// Make sure the class selection is valid // Make sure the class selection is valid
$class = isset($_POST['class']) && in_array($_POST['class'], [1, 2, 3]) ? $_POST['class'] : 1; $class = isset($_POST['class']) ? $_POST['class'] : 1;
// If we have any errors, bail to the form and let the user know // If we have any errors, bail to the form and let the user know
if (!empty($errors)) { if (!empty($errors)) {
@ -274,7 +277,8 @@ class InstallModule
'email' => trim($_POST['email']), 'email' => trim($_POST['email']),
'class_id' => $class, 'class_id' => $class,
'verified' => 1, 'verified' => 1,
'role' => 5 'role' => 5,
'level' => $_POST['level'] ?? 1
]); ]);
// Render the finished page! // Render the finished page!

View File

@ -27,5 +27,10 @@
</div> </div>
<?php endif; ?> <?php endif; ?>
<div class="form-group">
<label for="level">Level</label>
<input type="number" name="level" id="level" min="1" placeholder="1" required>
</div>
<button type="submit" name="submit">Submit</button> <button type="submit" name="submit">Submit</button>
</form> </form>