Initial commit
This commit is contained in:
commit
4dfe41f91e
|
@ -0,0 +1,35 @@
|
||||||
|
#Diablo 3 Hall of Glory
|
||||||
|
|
||||||
|
Calculate a formula to determine a raw score used to rank Diablo 3 profiles.
|
||||||
|
|
||||||
|
##Description
|
||||||
|
|
||||||
|
Implement the formula described by Celanian in [a thread on the Diablo 3
|
||||||
|
Barbarian forums] (http://us.battle.net/d3/en/forum/topic/7004690628) as a
|
||||||
|
simple web application. This is accomplished by accepting a [Diablo Progress]
|
||||||
|
(http://www.diabloprogress.com) URL and parsing the values calculated on the
|
||||||
|
side bar to determine an overall "Hall of Glory" score.
|
||||||
|
|
||||||
|
##License
|
||||||
|
|
||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2012 Andrew Tomaka
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
include_once(__DIR__ . '/libs/dpclass.php');
|
||||||
|
|
||||||
|
if($_POST['submit']) {
|
||||||
|
$diabloProgressUrl = trim($_POST['url']);
|
||||||
|
if(preg_match('{^http://www.diabloprogress.com/hero/[\w]+\-[\d]+/[\w]+/[\d]+$}', $diabloProgressUrl) != 1) {
|
||||||
|
die('Bad URL. Please enter the entire diablo progress URL.<br/><br/>Example: http://www.diabloprogress.com/hero/celanian-1548/HsuMing/21706367');
|
||||||
|
}
|
||||||
|
|
||||||
|
$curl = curl_init();
|
||||||
|
curl_setopt($curl, CURLOPT_URL, $diabloProgressUrl);
|
||||||
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||||
|
$contents = curl_exec($curl);
|
||||||
|
curl_close($curl);
|
||||||
|
|
||||||
|
$character = DPClassFactory::createClassObject($contents);
|
||||||
|
|
||||||
|
if($character === FALSE) {
|
||||||
|
die('Bad class. Either your class could not be detected or we do not support your class at this time.');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<hr/>
|
||||||
|
<b>Hall Score: <?php echo round($character->hallScore(), 2); ?></b><br/><br/>
|
||||||
|
|
||||||
|
DPS Score: <?php echo round($character->DPSScore(), 2); ?><br/>
|
||||||
|
EHP Score: <?php echo round($character->EHPScore(), 2); ?><br/>
|
||||||
|
Sustain Score: <?php echo round($character->sustainScore(), 2); ?><br/>
|
||||||
|
Move Score: <?php echo round($character->moveScore(), 2); ?><br/>
|
||||||
|
Paragon Score: <?php echo round($character->paragonScore(), 2); ?><br/>
|
||||||
|
Misc Score: <?php echo round($character->miscScore(), 2); ?><br/>
|
||||||
|
<hr/>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<form method="POST">
|
||||||
|
D3 Progress URL: <input type="text" name="url" style="width:500px;" value="<?php echo $diabloProgressUrl ?>" /><br />
|
||||||
|
<input type="submit" name="submit" />
|
||||||
|
</form>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
class Barbarian extends DPClass {
|
||||||
|
function EHPScore() {
|
||||||
|
$ehp = $this->getStat('EHP Unbuffed');
|
||||||
|
|
||||||
|
if($ehp < 1000000) {
|
||||||
|
return $ehp / 10000;
|
||||||
|
} elseif(1000000 <= $ehp && $ehp <= 2000000) {
|
||||||
|
return 100 + ($ehp - 1000000) / 20000;
|
||||||
|
} elseif(2000000 <= $ehp && $ehp <= 5000000) {
|
||||||
|
return 150 + ($ehp - 2000000) / 40000;
|
||||||
|
} elseif($ehp <= 5000000) {
|
||||||
|
return 225 + ($ehp - 5000000) / 100000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class DPClassFactory {
|
||||||
|
function createClassObject($characterPage) {
|
||||||
|
$class = DPClassFactory::findClass($characterPage);
|
||||||
|
|
||||||
|
include_once(__DIR__ . "/$class.php");
|
||||||
|
|
||||||
|
switch($class) {
|
||||||
|
case 'barbarian':
|
||||||
|
return new Barbarian($characterPage);
|
||||||
|
case 'wizard':
|
||||||
|
return new Wizard($characterPage);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findClass($characterPage) {
|
||||||
|
preg_match('{<span class="diablo_.*?">(.*?)</span>}', $characterPage, $class);
|
||||||
|
|
||||||
|
return strtolower($class[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DPClass {
|
||||||
|
var $dpHTML;
|
||||||
|
var $class;
|
||||||
|
var $stats = array();
|
||||||
|
var $items = array();
|
||||||
|
|
||||||
|
function __construct($characterPage) {
|
||||||
|
$this->dpHTML = $characterPage;
|
||||||
|
|
||||||
|
$this->class = get_class($this);
|
||||||
|
|
||||||
|
$this->parseStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseStats() {
|
||||||
|
preg_match_all('{<div class="char_attr"><nobr><span class="char_attr_name">(.*?):<\/span> <span class="char_attr_value">(.*?)<\/span><\/nobr><\/div>}', $this->dpHTML, $attributes);
|
||||||
|
|
||||||
|
for($i = 0; $i < count($attributes[0]); $i++) {
|
||||||
|
$attributes[2][$i] = str_replace(',', '', $attributes[2][$i]);
|
||||||
|
if(preg_match('/%/', $attributes[2][$i]) > 0) {
|
||||||
|
$attributes[2][$i] = str_replace('%', '', $attributes[2][$i]);
|
||||||
|
$attributes[2][$i] /= 100;
|
||||||
|
}
|
||||||
|
$this->stats[$attributes[1][$i]] = $attributes[2][$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->stats['All Elemental Damage'] = $this->calculateElementalDamage();
|
||||||
|
$this->stats['DPS Unbuffed'] = $this->calculateModifiedDPSUnbuffed();
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateElementalDamage() {
|
||||||
|
$totalElemental = 0;
|
||||||
|
foreach($this->stats as $stat => $value) {
|
||||||
|
if(preg_match('/\+DPS \(.*\)/', $stat) > 0) {
|
||||||
|
$totalElemental += $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($totalElemental > 0) ? $totalElemental + 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateModifiedDPSUnbuffed() {
|
||||||
|
return $this->getStat('DPS Unbuffed') * max(1, $this->getStat('All Elemental Damage'))
|
||||||
|
* max(1, $this->getStat('+DPS Against Elites'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function hallScore() {
|
||||||
|
return $this->DPSScore() * $this->EHPScore() * $this->sustainScore()
|
||||||
|
* $this->moveScore() * $this->paragonScore() * $this->miscScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function DPSScore() {
|
||||||
|
return $this->getStat('DPS Unbuffed') / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EHPScore() {}
|
||||||
|
|
||||||
|
function sustainScore() {
|
||||||
|
$effectiveLS = $this->getStat('DPS Unbuffed') * $this->getStat('Life Steal') * .2;
|
||||||
|
|
||||||
|
return 1 + ($this->getStat('Life on Hit') + $this->getStat('Life per Second') + $effectiveLS)
|
||||||
|
* 10 / $this->getStat('Life');
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveScore() {
|
||||||
|
return ($this->getStat('Movement Speed') > .25) ? 1.25 : 1 + $this->getStat('Movement Speed');
|
||||||
|
}
|
||||||
|
|
||||||
|
function paragonScore() {
|
||||||
|
return 1 + $this->stats['Paragon Level'] / 2 / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
function miscScore() {
|
||||||
|
return 1 + ($this->getStat('Melee Damage Reduction') + $this->getStat('Missile Damage Reduction')
|
||||||
|
+ $this->getStat('Exp Bonus')) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStat($name) {
|
||||||
|
return (isset($this->stats[$name])) ? $this->stats[$name] : 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
class Wizard extends DPClass {
|
||||||
|
function EHPScore() {
|
||||||
|
$ehp = $this->getStat('EHP Unbuffed');
|
||||||
|
|
||||||
|
switch($ehp) {
|
||||||
|
case ($ehp < 250000):
|
||||||
|
return $ehp / 5000;
|
||||||
|
case ($ehp >= 250000 && $ehp < 450000):
|
||||||
|
return 50 + ($ehp - 250000) / 4000;
|
||||||
|
case ($ehp >= 450000 && $ehp < 600000):
|
||||||
|
return 100 + ($ehp - 450000) / 3000;
|
||||||
|
case ($ehp >= 600000 && $ehp < 1000000):
|
||||||
|
return 150 + ($ehp - 600000) / 8000;
|
||||||
|
case ($ehp >= 1000000):
|
||||||
|
return 200 + ($ehp - 1000000) / 25000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue