-
Posts
2,124 -
Joined
-
Last visited
-
Days Won
144
Magictallguy last won the day on September 22
Magictallguy had the most liked content!
About Magictallguy
- Birthday 08/07/1991
Personal Information
-
Location
Bolton, UK
-
Occupation
Freelance Website Developer
-
Website
https://orsokuma.com
Recent Profile Visitors
22,029 profile views
Magictallguy's Achievements
-
I didn't add any >100 formatting, but that'd be easy enough. Hell, I might even update to use a checkbox for it so users can see the direct value if they need to, or just a "yup, this is guaranteed" output. Go sick 😄
-
Magictallguy started following is makewebgames in error? i dont cant visit the site normal , Mccodes Crime Calc % , [GLv2][FREE] Discord and 4 others
-
I really like the ability to visualise how the crime formulae may result; so I took your idea and added the ability to select from an existing crime, or assume the default formula ((WILL*0.8)/2.5)+(LEVEL/4) and calculate as desired. I also stripped the jQuery dependence; pure vanilla JS, woo! Fair note to our more sensitive-eyed programmers; there's no dark mode by default. Note: Written in a PHP8.4 environment. Older versions may need to change the match() call to a switch() equivalent crime-formula.php <?php declare(strict_types=1); $_GET['action'] ??= null; $_GET['id'] = array_key_exists('id', $_GET) && is_numeric($_GET['id']) && (int)$_GET['id'] > 0 ? (int)$_GET['id'] : null; class CrimeFormula { private static ?self $inst = null; private ?database $db; private ?array $settings; /** * @param database $db * @param array $settings */ public function __construct(database $db, array $settings) { $this->db = $db; $this->settings = $settings; $this->run(); } /** * @return void */ private function run(): void { $response = match ($_GET['action']) { 'get-crime-by-id' => $this->getCrimeById($_GET['id']), default => [ 'type' => 'error', 'message' => 'No action given', ], }; if ($this->isAjax()) { header('Content-type: application/json'); echo json_encode($response); exit; } if (array_key_exists('location', $response)) { header('Location: ' . $response['location']); exit; } echo $this->template('crime-select', [ '%id%' => $_GET['id'], '%menu.opts:crimes%' => $this->renderMenuOptsCrimes($_GET['id']), ]); } /** * @param int|null $id * * @return array|null */ private function getCrimeById(?int $id): ?array { if (empty($id)) { return null; } $get_crime = $this->db->query( 'SELECT * FROM crimes WHERE crimeID = ' . $id . ' LIMIT 1', ); $row = $this->db->fetch_row($get_crime); $this->db->free_result($get_crime); return $row ?? null; } /** * @return bool */ private function isAjax(): bool { return array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'; } /** * @param string $fileName * @param array $replacements * * @return string|null */ private function template(string $fileName, array $replacements = []): ?string { $path = str_replace('/', DIRECTORY_SEPARATOR, __DIR__ . '/' . $fileName . '.html'); if (!file_exists($path)) { return null; } $content = file_get_contents($path); return strtr($content, $replacements); } /** * @param int|null $selected * * @return string */ private function renderMenuOptsCrimes(?int $selected = null): string { $ret = ''; $rows = $this->db->query( 'SELECT crimeID, crimeNAME, crimeBRAVE FROM crimes ORDER BY crimeBRAVE', ); while ($row = $this->db->fetch_row($rows)) { $ret .= sprintf( '<option value="%u" %s>%s [%s brave]</option>%s', $row['crimeID'], (int)$row['crimeID'] === $selected ? 'selected' : '', stripslashes(htmlspecialchars($row['crimeNAME'])), number_format((int)$row['crimeBRAVE']), PHP_EOL, ); } $this->db->free_result($rows); return $ret; } /** * @param database $db * @param array $settings * * @return self|null */ public static function getInstance(database $db, array $settings): ?self { if (self::$inst === null) { self::$inst = new self($db, $settings); } return self::$inst; } } global $db, $set; require_once __DIR__ . '/globals_nonauth.php'; $module = CrimeFormula::getInstance($db, $set); crime-select.html <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Crime Formula Tests</title> </head> <body> <div class="container" style="margin: 0 auto;"> <form id="crime-selection-form" method="get"> <div class="row py-2"> <div class="col"> <div class="form-group"> <label for="crime">Select Crime</label> <select name="crime" id="crime" class="form-control"> <option value="0" selected>--- None ---</option> %menu.opts:crimes% </select> </div> </div> </div> <div class="row py-2"> <div class="col-lg-6 col-md"> <div class="form-group"> <label for="level">Level</label> <input type="number" name="level" id="level" class="form-control" value="1" step="1"> </div> </div> <div class="col-lg-6 col-md"> <div class="form-group"> <label for="will">Will</label> <input type="number" name="will" id="will" class="form-control" value="100" step="1"> </div> </div> </div> </form> </div> <div class="container"> <span class="d-block m-1" id="crime-formula-raw"></span> <span class="d-block m-1" id="crime-formula-formatted"></span> <span class="d-block m-1" id="crime-response"></span> </div> <script> const apiCall = (path) => { return fetch(path, { headers: { 'credentials': 'same-origin', 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/json' }, signal: AbortSignal.timeout(5000) }); }; const getCrime = (id, callback) => { apiCall(`crime-formula.php?action=get-crime-by-id&id=${id}`) .then(response => response.json()) .then(data => callback(data)); }; const responseElem = document.getElementById("crime-response"); const formulaRawElem = document.getElementById("crime-formula-raw"); const formulaFormattedElem = document.getElementById("crime-formula-formatted"); const updateCrimeInfo = (formula, will, level) => { let formulaFormatted = formula.replace('WILL', will).replace('LEVEL', level); formulaRawElem.innerText = formula; formulaFormattedElem.innerText = formulaFormatted; /* Dirty. Don't do this if you can avoid it. And certainly *never* trust user input with it. */ let amnt = eval(formulaFormatted); responseElem.innerText = amnt.toLocaleString(undefined, {maximumFractionDigits: 3}) + "%"; }; const getCrimeFullEvent = (e) => { e.stopPropagation(); e.preventDefault(); if ([undefined, null].includes(responseElem) || [undefined, null].includes(formulaRawElem) || [undefined, null].includes(formulaFormattedElem)) { console.error("Form element missing: crime-response/crime-formula-raw/crime-formula-formatted"); return; } let will = document.getElementById("will").value; let level = document.getElementById("level").value; let id = document.getElementById("crime").value; if ([undefined, null].includes(will)) { will = 100; } if ([undefined, null].includes(level)) { level = 1; } if ([undefined, null].includes(id)) { id = 0; } let formula = '((WILL*0.8)/2.5)+(LEVEL/4)'; if (id > 0) { getCrime(id, (data) => { if ([undefined, null].includes(data)) { console.error("Blank crime data response"); return false; } if (data.hasOwnProperty("type") && data.type !== "success") { console.error(data); return false; } updateCrimeInfo(data.crimePERCFORM, will, level); return true; }); } else { updateCrimeInfo(formula, will, level); } }; window.addEventListener("DOMContentLoaded", () => { const formElem = document.getElementById("crime-selection-form"); if ([undefined, null].includes(formElem)) { console.error("Form element missing: crime-selection-form"); return; } formElem.addEventListener("keyup", (e) => getCrimeFullEvent(e)); formElem.addEventListener("mouseup", (e) => getCrimeFullEvent(e)); }); </script> </body> </html> 2025-09-22 18-58-18.mp4
-
For anyone wanting to take this on, you're lookin' at CrateJS to re-wrap
-
Note: In higher-traffic areas, this may introduce race conditions. In that scenario, I'd recommend using the database (the one your project is already using) to track this information; amongst other things, most RDBMS support query queuing as default. For low-traffic areas and areas where you don't foresee an upsurge in activity (refer to your metrics), then this file-based approach may be perfectly sufficient for your needs
-
Technically, yes! It is certainly possible to run multiple sites that reference a single database. More often than not, though, the question is "why"? If, for example, I was to start a mafia-style game with MCC then I decided I wanted a sci-fi style game with gRPG; I could do the leg-work and make them compatible. That being said, what of the players? Someone playing a mafia-style game with [x] currency will likely be confused by having [y] currency in the sci-fi game. I'm a firm believer of "fit for purpose"; each project gets their own database(s) as necessary. If you want to make a merge of the open-source engines, you go right ahead 😄
-
These can be added into the Dockerfile as RUN directives
-
Its getting kinda Lonely at MWG
Magictallguy replied to Uridium's topic in Feedback and Site Support
Summer! Life generally tends to get louder in the summer. People are out (and away from their keyboards) more often. We're still just a message away though. As for gRPG, I've already framed a structure for the multi-PHP-version supports and have begun tweaking the various branches -
I made my first browser game! A simple Tetris game! What do you think?
Magictallguy replied to wlr_inc's topic in General
Minor control issue; W responds (piece rotation), but ASD do not. All arrow keys work. -
I have not as I wasn't thinking of backwards compatibility. This change is part of a rolling set of changes I intend to make to suit more recent technologies. As for the claim that "nobody" has PHP 8.4 yet; SiteEU, WebWiz, HawkHost, Kinsta, SwitchWeb, NameCheap, GoDaddy, Google Cloud Hosting and AWS absolutely do support it. Honourable mention to cPanel's EasyApache which added PHP 8.4 support in December just gone. Again, I will add backward compatibility for PHP 8.0. Might send up a couple of branched releases so people can select their desired version.
-
You changed setenv to getenv? Of course that wouldn't work
-
Back when I was on Windows, I loved mLocati's PowerShell PHP Manager - you may wish to consider looking into it. Its primary purpose is to provide an easy way to install multiple PHP versions and choose whichever one the system considers active. As for your host, perhaps a request to their support might be fruitful.
-
PHP 8.4 required. I'll push an 8.0-friendly version shortly