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;
private static string $dbPath;
public static Request $req;
public static array $s = []; // game settings
public function __construct(string $dbPath)
{
self::$req = new Request(); // the current request
self::$db = new Database($dbPath); // the database
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

View File

@ -1,32 +1,42 @@
<?php // library.php :: Common functions used throughout the program.
// Diff two times in seconds.
function stopwatch(float $start, int $roundTo = 3): float
{
return round(microtime(true) - $start, $roundTo);
}
// Redirect to another page.
function redirect(string $url): void
{
header("Location: $url");
exit;
}
// Redirect to the install page if not installed.
// Otherwise, redirect to the main page if requesting the install page.
function installRedirect(string $route)
{
if (!INSTALLED && $route != 'install') redirect('/install');
if (INSTALLED && $route == 'install') redirect('/');
}
// Get the path to a template.
function template(string $name): string
{
return SERVER."/templates/$name.php";
}
/**
* 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.
*/
// 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;
}
// 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
{
ob_start();
@ -35,20 +45,7 @@ function render(string $baseView, array $data = []): string
return ob_get_clean();
}
/**
* 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.
*/
// Dump and die.
function dd(mixed $var, bool $r = false)
{
echo '<pre>';
@ -57,11 +54,26 @@ function dd(mixed $var, bool $r = false)
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());
return ((float)$usec + (float)$sec);
if ($level == 1) return 0; // level 1 does not require any XP
// 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.

View File

@ -7,4 +7,25 @@ class Classes
$res = App::$db->q("SELECT * FROM classes");
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
{
// 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));
$placeholders = implode(', ', array_fill(0, count($data), '?'));
// insert into db
App::$db->do("INSERT INTO 'players' ($keys) VALUES ($placeholders);", array_values($data));
return App::$db->lastInsertID();
}

View File

@ -47,7 +47,9 @@ class InstallModule
'verify_email' INT DEFAULT 1,
'show_news' 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
@ -198,14 +200,15 @@ class InstallModule
'class_id' INTEGER DEFAULT 1,
'level' INTEGER DEFAULT 1,
'exp' INTEGER DEFAULT 0,
'exp2l' INTEGER DEFAULT 0,
'gold' INTEGER DEFAULT 0,
'stat_points' INTEGER DEFAULT 0,
'hp' INTEGER DEFAULT 0,
'max_hp' INTEGER DEFAULT 0,
'mp' INTEGER DEFAULT 0,
'max_mp' INTEGER DEFAULT 0,
'tp' INTEGER DEFAULT 0,
'max_tp' INTEGER DEFAULT 0,
'tp' INTEGER DEFAULT 5,
'max_tp' INTEGER DEFAULT 5,
'str' INTEGER DEFAULT 0,
'atk' INTEGER DEFAULT 0,
'dex' INTEGER DEFAULT 0,
@ -256,7 +259,7 @@ class InstallModule
}
// 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 (!empty($errors)) {
@ -274,7 +277,8 @@ class InstallModule
'email' => trim($_POST['email']),
'class_id' => $class,
'verified' => 1,
'role' => 5
'role' => 5,
'level' => $_POST['level'] ?? 1
]);
// Render the finished page!

View File

@ -27,5 +27,10 @@
</div>
<?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>
</form>