Skip to content

Instantly share code, notes, and snippets.

@alfaproject
Created October 18, 2012 09:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alfaproject/3910744 to your computer and use it in GitHub Desktop.
Save alfaproject/3910744 to your computer and use it in GitHub Desktop.
RuneScape related PHP classes to aid development
<?php
// Skills
define('OVER', 'Overall');
define('ATTA', 'Attack');
define('DEFE', 'Defence');
define('STRE', 'Strength');
define('HITP', 'Constitution');
define('RANG', 'Ranged');
define('PRAY', 'Prayer');
define('MAGI', 'Magic');
define('COOK', 'Cooking');
define('WOOD', 'Woodcutting');
define('FLET', 'Fletching');
define('FISH', 'Fishing');
define('FIRE', 'Firemaking');
define('CRAF', 'Crafting');
define('SMIT', 'Smithing');
define('MINI', 'Mining');
define('HERB', 'Herblore');
define('AGIL', 'Agility');
define('THIE', 'Thieving');
define('SLAY', 'Slayer');
define('FARM', 'Farming');
define('RUNE', 'Runecraft');
define('HUNT', 'Hunter');
define('CONS', 'Construction');
define('SUMM', 'Summoning');
define('DUNG', 'Dungeoneering');
define('COMB', 'Combat');
define('COMF', 'Combat F2P');
$SkillsID = array(
OVER => 0, ATTA => 1, DEFE => 2, STRE => 3, HITP => 4,
RANG => 5, PRAY => 6, MAGI => 7, COOK => 8, WOOD => 9,
FLET => 10, FISH => 11, FIRE => 12, CRAF => 13, SMIT => 14,
MINI => 15, HERB => 16, AGIL => 17, THIE => 18, SLAY => 19,
FARM => 20, RUNE => 21, HUNT => 22, CONS => 23, SUMM => 24,
DUNG => 25
);
$Skills = array_flip($SkillsID);
$SkillsDB = array(
'over' => OVER, 'atta' => ATTA, 'defe' => DEFE, 'stre' => STRE, 'hitp' => HITP,
'rang' => RANG, 'pray' => PRAY, 'magi' => MAGI, 'cook' => COOK, 'wood' => WOOD,
'flet' => FLET, 'fish' => FISH, 'fire' => FIRE, 'craf' => CRAF, 'smit' => SMIT,
'mini' => MINI, 'herb' => HERB, 'agil' => AGIL, 'thie' => THIE, 'slay' => SLAY,
'farm' => FARM, 'rune' => RUNE, 'hunt' => HUNT, 'cons' => CONS, 'summ' => SUMM,
'dung' => DUNG
);
// Minigames
define('DUEL', 'Duel Tournament');
define('BOUN', 'Bounty Hunters');
define('ROGU', 'Bounty Hunter Rogues');
define('FIST', 'Fist of Guthix');
define('MOBI', 'Mobilising Armies');
define('BAAT', 'Barbarian Assault Attackers');
define('BADE', 'Barbarian Assault Defenders');
define('BACO', 'Barbarian Assault Collectors');
define('BAHE', 'Barbarian Assault Healers');
define('CAST', 'Castle Wars Games');
define('CONQ', 'Conquest');
$MinigamesID = array(
DUEL => 0, BOUN => 1, ROGU => 2, FIST => 3, MOBI => 4,
BAAT => 5, BADE => 6, BACO => 7, BAHE => 8, CAST => 9,
CONQ => 10
);
$Minigames = array_flip($MinigamesID);
$MinigamesDB = array(
'duel' => DUEL, 'boun' => BOUN, 'rogu' => ROGU, 'fist' => FIST, 'mobi' => MOBI,
'baat' => BAAT, 'bade' => BADE, 'baco' => BACO, 'bahe' => BAHE, 'cast' => CAST,
'conq' => CONQ
);
<?php
class Minigame {
public $Name;
public $Rank;
public $Score;
public function __construct($name, $rank, $score) {
$this->Name = $name;
$this->Rank = $rank;
$this->Score = $score;
}
}
<?php
require_once(dirname(__FILE__) .'/../db.php');
require_once('Enumerations.php');
require_once('Minigame.php');
require_once('Skill.php');
class Player
{
public $Id;
public $Name;
public $Skills;
public $Minigames;
public $LastUpdated;
public $Ranked;
public $TotalRanks;
public function F2PExperience() {
return $this->Skills[ATTA]->Experience + $this->Skills[DEFE]->Experience + $this->Skills[STRE]->Experience +
$this->Skills[HITP]->Experience + $this->Skills[RANG]->Experience + $this->Skills[PRAY]->Experience +
$this->Skills[MAGI]->Experience + $this->Skills[COOK]->Experience + $this->Skills[WOOD]->Experience +
$this->Skills[FISH]->Experience + $this->Skills[FIRE]->Experience + $this->Skills[CRAF]->Experience +
$this->Skills[SMIT]->Experience + $this->Skills[MINI]->Experience + $this->Skills[RUNE]->Experience +
$this->Skills[DUNG]->Experience;
}
public function IsF2P() {
return ($this->Skills[OVER]->Experience == $this->F2PExperience());
}
public function HighestSkill() {
$highest = $this->Skills[ATTA];
foreach ($this->Skills as &$skill) {
if ($skill->Name != OVER && $skill->Name != COMB && $skill->Name != COMF &&
($skill->Experience > $highest->Experience ||
$skill->Experience == $highest->Experience && $skill->Rank < $highest->Rank)) {
$highest = $skill;
}
}
return $highest;
}
public function LoadFromDatabaseRow($row, $addCombat = true) {
global $SkillsDB, $MinigamesDB;
$this->Id = $row['playerId'];
$this->Name = $row['rsn'];
$this->Ranked = true;
$this->Skills = array();
$this->Minigames = array();
//date_default_timezone_set('UTC');
//$this->LastUpdated = strtotime($row['dateTime']);
$this->LastUpdated = $row['dateTime'];
foreach ($row as $fieldName => $fieldValue) {
if (substr($fieldName, -3) == 'Lvl') {
$level = (int) $fieldValue;
} else if (substr($fieldName, -3) == 'Exp') {
$exp = (int) $fieldValue;
} else if (substr($fieldName, -5) == 'Score') {
$score = (int) $fieldValue;
} else if (substr($fieldName, -4) == 'Rank') {
$rank = (int) $fieldValue;
// Check if this is a skill or minigame
$fieldName = substr($fieldName, 0, 4);
if (array_key_exists($fieldName, $MinigamesDB)) {
$minigameName = $MinigamesDB[$fieldName];
$this->Minigames[$minigameName] = new Minigame($minigameName, $rank, $score);
} else {
$skillName = $SkillsDB[$fieldName];
if ($skillName == OVER) {
$this->Skills[OVER] = new Skill(OVER, $rank, $exp, $level);
$this->Skills[OVER]->VirtualLevel = 0;
} else {
$this->Skills[$skillName] = new Skill($skillName, $rank, $exp);
$this->Skills[OVER]->VirtualLevel += $this->Skills[$skillName]->VirtualLevel;
}
}
}
}
$this->_GuessMissingSkills();
if ($addCombat) {
$this->_AddCombatSkills();
}
}
public function LoadFromDatabase($id, $minutesOffset = 0, $addCombat = true) {
global $db;
$this->Id = $id;
$this->Ranked = false;
$sql = "SELECT p.rsn, t.*
FROM `tracker_tracker` t
JOIN `tracker_players` p ON t.playerId = p.id
WHERE t.playerId = $id AND t.dateTime <= DATE_SUB(UTC_TIMESTAMP(), INTERVAL $minutesOffset MINUTE)
ORDER BY t.dateTime DESC
LIMIT 1";
if ($query = $db->query($sql)) {
if ($row = $query->fetch_assoc()) {
$this->LoadFromDatabaseRow($row, $addCombat);
}
$query->close();
}
}
public function FindTotalRanks() {
foreach ($this->Skills as $skill) {
if ($skill->Name != COMB && $skill->Name != COMF) {
$this->TotalRanks += ($skill->Rank > 0 ? $skill->Rank : 2000000);
}
}
}
private function _GuessMissingSkills() {
// Fix hitpoints
if ($this->Skills[HITP]->Rank == -1) {
$this->Skills[HITP]->Level = 10;
$this->Skills[OVER]->VirtualLevel += 9;
}
if ($this->Skills[OVER]->Rank == -1) {
// Overall is unranked
foreach ($this->Skills as &$skill) {
if ($skill->Name != OVER) {
if ($skill->Name != HITP && $skill->Rank == -1) {
$skill->Experience = 0; // Level 1
} else {
$this->Skills[OVER]->Experience += $skill->Experience;
}
$this->Skills[OVER]->Level += $skill->Level;
}
}
} else {
// Overall is ranked
$missingLevels = $this->Skills[OVER]->Level;
foreach ($this->Skills as &$skill) {
if ($skill->Rank != -1) {
$missingLevels -= $skill->Level;
}
}
// Distribute missing levels
while ($missingLevels > 0) {
foreach ($this->Skills as &$skill) {
if ($missingLevels > 0 && $skill->Rank == -1) {
if ($skill->Level == -1) {
$skill->Level = 1;
} else {
$skill->Level++;
}
$this->Skills[OVER]->VirtualLevel++;
$missingLevels--;
}
}
}
}
// Fix unranked skills experience
foreach ($this->Skills as &$skill) {
if ($skill->Name != OVER && $skill->Rank == -1) {
$skill->Experience = LevelToExp($skill->Level);
}
}
}
private function _AddCombatSkills() {
// F2P Combat
$this->Skills[COMF] = new Skill(COMF, -1,
$this->Skills[ATTA]->Experience + $this->Skills[STRE]->Experience + $this->Skills[DEFE]->Experience +
$this->Skills[HITP]->Experience + $this->Skills[RANG]->Experience + $this->Skills[PRAY]->Experience +
$this->Skills[MAGI]->Experience, CalculateCombatSkills($this->Skills, true));
$this->Skills[COMF]->VirtualLevel = CalculateCombatSkills($this->Skills, true, true);
// P2P Combat
$this->Skills[COMB] = new Skill(COMB, -1,
$this->Skills[COMF]->Experience + $this->Skills[SUMM]->Experience, CalculateCombatSkills($this->Skills));
$this->Skills[COMB]->VirtualLevel = CalculateCombatSkills($this->Skills, false, true);
}
}
<?php
require_once('Enumerations.php');
require('SkillUtils.php');
class Skill {
public $Name;
public $Rank;
private $_properties = array();
public function __construct($name, $rank, $experience, $level = null) {
$this->Name = $name;
$this->Rank = $rank;
$this->Experience = $experience;
if (($level !== null) && ($name == OVER || $name == COMB || $name == COMF)) {
$this->Level = $level;
$this->VirtualLevel = $level;
}
}
public function __get($property) {
switch ($property) {
case 'Experience':
case 'Level':
case 'VirtualLevel':
return $this->_properties[$property];
default:
throw new Exception('You are not allowed to get this property.');
}
}
public function __set($property, $value) {
switch ($property) {
case 'Experience':
$this->_properties[$property] = $value;
if ($this->Name != OVER && $this->Name != COMB && $this->Name != COMF) {
$this->_properties['VirtualLevel'] = ExpToLevel($value);
if ($this->Name != DUNG)
$this->_properties['Level'] = ($this->_properties['VirtualLevel'] > 99 ? 99 : $this->_properties['VirtualLevel']);
else
$this->_properties['Level'] = ($this->_properties['VirtualLevel'] > 120 ? 120 : $this->_properties['VirtualLevel']);
}
break;
case 'Level':
$this->_properties[$property] = $value;
if ($this->Name == OVER || $this->Name == COMB || $this->Name == COMF) {
$this->_properties['VirtualLevel'] = $value;
}
break;
case 'VirtualLevel':
if ($this->Name == OVER || $this->Name == COMB || $this->Name == COMF) {
$this->_properties['VirtualLevel'] = $value;
break;
}
default:
throw new Exception('You are not allowed to set this property.');
}
}
}
<?php
function LevelToExp($level) {
$exp = 0;
while ($level > 1) {
$exp += --$level + floor(300 * pow(2, $level / 7));
}
return floor($exp / 4);
}
function ExpToLevel($exp) {
$level = $levelExp = 0;
while (floor($levelExp / 4) <= $exp) {
$levelExp += ++$level + floor(300 * pow(2, $level / 7));
}
return $level;
}
function CalculateCombatSimple($neutralBonus, $meleeBonus, $magicBonus, $rangeBonus) {
return (int)floor((double)($neutralBonus * 100 + max($meleeBonus, max($magicBonus, $rangeBonus)) * 130) / 400.0);
}
function CalculateCombat($att, $str, $def, $hp, $ran, $pr, $mag, $sum) {
return CalculateCombatSimple($def + $hp + $pr / 2 + $sum / 2, $att + $str, $mag + $mag / 2, $ran + $ran / 2);
}
function CalculateCombatSkills($skills, $f2p = false, $virtual = false) {
if ($virtual) {
return CalculateCombat($skills[ATTA]->VirtualLevel, $skills[STRE]->VirtualLevel, $skills[DEFE]->VirtualLevel,
$skills[HITP]->VirtualLevel, $skills[RANG]->VirtualLevel, $skills[PRAY]->VirtualLevel,
$skills[MAGI]->VirtualLevel, ($f2p ? 0 : $skills[SUMM]->VirtualLevel));
} else {
return CalculateCombat($skills[ATTA]->Level, $skills[STRE]->Level, $skills[DEFE]->Level,
$skills[HITP]->Level, $skills[RANG]->Level, $skills[PRAY]->Level,
$skills[MAGI]->Level, ($f2p ? 0 : $skills[SUMM]->Level));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment