rendered paste body<?php
/**
* @author <a href="mailto:grom358_spamkill@yahoo.com.au">Cameron Zemek</a>
*/
require_once('minixml.inc.php');
/**
* Return xml from url as an array
*/
function fetchXML($url) {
ini_set('user_agent', "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1");
$xmlString = file_get_contents($url);
if ($xmlString === false) {
echo 'Unable to read '.$url;
exit;
}
$xmlDoc = new MiniXMLDoc();
$xmlDoc->fromString($xmlString);
return $xmlDoc->toArray();
}
/** Warlock talents */
$WARLOCK_TALENTS = array(
'Suppression', 'Improved Corruption',
'Improved Curse of Weakness', 'Improved Drain Soul', 'Improved Life Tap', 'Soul Siphon',
'Improved Curse of Agony', 'Fel Concentration', 'Amplify Curse',
'Grim Reach', 'Nightfall', 'Empowered Corruption',
'Shadow Embrace', 'Siphon Life', 'Curse of Exhaustion',
'Shadow Mastery',
'Contagion', 'Dark Pact',
'Improved Howl of Terror', 'Malediction',
'Unstable Afflication',
'Improved Health Stone', 'Improved Imp', 'Demonic Embrace',
'Improved Health Funnel', 'Improved Voidwalker', 'Fel Intellect',
'Improved Succubus', 'Fel Domination', 'Fel Stamina', 'Demonic Aegis',
'Master Summoner', 'Unholy Power',
'Improved Enslave Demon', 'Demonic Sacrifice', 'Master Conjuror',
'Mana Feed', 'Master Demonologist',
'Demonic Resilience', 'Soul Link', 'Demonic Knowledge',
'Demonic Tactics',
'Summon Felguard',
'Improved Shadow Bolt', 'Cataclysm',
'Bane', 'Aftermath',
'Improved Firebolt', 'Improved Lash of Pain', 'Devastation', 'Shadowburn',
'Intensity', 'Destructive Reach', 'Improved Searing Pain',
'Pyroclasm', 'Improved Immolate', 'Ruin',
'Nether Protection', 'Emberstorm',
'Backlash', 'Conflagrate', 'Soul Leech',
'Shadow and Flame',
'Shadowfury'
);
if ($_REQUEST['lookup_armory']) {
$characterURL = "http://armory.worldofwarcraft.com/character-sheet.xml?r=".$_REQUEST['realm']."&n=".$_REQUEST['character'];
$talentURL = "http://armory.worldofwarcraft.com/character-talents.xml?r=".$_REQUEST['realm']."&n=".$_REQUEST['character'];
$characterData = fetchXML($characterURL);
$stats = array(
'intellect' => $characterData['page']['characterInfo']['characterTab']['baseStats']['intellect']['_attributes']['effective'],
'crit_chance' => $characterData['page']['characterInfo']['characterTab']['spell']['critChance']['holy']['_attributes']['percent'],
'spell_damage' => $characterData['page']['characterInfo']['characterTab']['spell']['bonusDamage']['holy']['_attributes']['value'],
'shadow_damage' => $characterData['page']['characterInfo']['characterTab']['spell']['bonusDamage']['shadow']['_attributes']['value'],
'fire_damage' => $characterData['page']['characterInfo']['characterTab']['spell']['bonusDamage']['fire']['_attributes']['value'],
'hit_rating' => $characterData['page']['characterInfo']['characterTab']['spell']['hitRating']['_attributes']['value']
);
$talentData = fetchXML($talentURL);
$talent_string = $talentData['page']['characterInfo']['talentTab']['talentTree']['_attributes']['value'];
$talent_tree = 'http://www.worldofwarcraft.com/info/classes/warlock/talents.html?'.$talent_string;
}
$character = isset($_REQUEST['character']) ? $_REQUEST['character'] : 'Ashriel';
$realm = isset($_REQUEST['realm']) ? $_REQUEST['realm'] : 'Barthilas';
// Stats
if (!isset($stats)) {
if (isset($_REQUEST['stats'])) {
$stats = $_REQUEST['stats'];
} else {
$stats = array(
'intellect' => 500,
'crit_chance' => 15,
'spell_damage' => 1000,
'shadow_damage' => 1000,
'fire_damage' => 1000,
'hit_rating' => 120
);
}
}
$stats['crit_chance'] = $stats['crit_chance'] / 100;
// Talent tree
if (!isset($talent_string)) {
if (isset($_REQUEST['talent_tree'])) {
$talent_tree = urldecode($_REQUEST['talent_tree']);
$url_parts = parse_url($talent_tree);
$talent_string = $url_parts['query'];
} else {
$talent_tree = 'http://www.worldofwarcraft.com/info/classes/warlock/talents.html?5502222512233115512010000000000000000000000505000010000000000000';
$talent_string = '5502222512233115512010000000000000000000000505000010000000000000';
}
}
$stats['hit_chance'] = 0.83 + ($stats['hit_rating'] / 1260); // Level 73 mob + hit rating bonus; 12.6 hit rating == 1% hit
//$stats['crit_chance'] = $stats['base_crit'] + ($stats['crit_rating'] / 2210); // 22.1 crit rating == 1% crit
if (isset($_REQUEST['latency'])) {
$LATENCY = $_REQUEST['latency'] / 1000;
} else {
$LATENCY = 0.3;
}
// Talents
function parseTalentString($talent_string) {
global $WARLOCK_TALENTS;
$talents = array();
foreach($WARLOCK_TALENTS as $talentName) { // Init talents
$talents[$talentName] = 0;
}
for($i = 0; $i < strlen($talent_string); $i++) {
$talentName = $WARLOCK_TALENTS[$i];
$talents[$talentName] = $talent_string[$i];
}
return $talents;
}
$talents = parseTalentString($talent_string);
// Modifiers
function getTalentModifiers(&$talents, &$debuffs) {
$talentModifiers = array();
$talentModifiers['cast_time'] = array(
'Shadow Bolt' => 3 - (0.1 * $talents['Bane']),
'Immolate (DD)' => 2 - (0.1 * $talents['Bane']),
'Soul Fire' => 6 - (0.4 * $talents['Bane'])
);
$talentModifiers['dmg_coeff'] = array(
'Corruption' => 0.936 + (0.12 * $talents['Empowered Corruption']),
'Curse of Agony' => 1.2 + (0.05 * $talents['Improved Curse of Agony']),
'Shadow Bolt' => (3 / 3.5) + (0.04 * $talents['Shadow and Flame']),
'Incinerate' => (2.5 / 3.5) + (0.04 * $talents['Shadow and Flame']),
'Immolate (DD)' => 0.2 + (0.05 * $talents['Improved Immolate'])
);
$talentModifiers['dmg_modifiers'] = array(
'Shadow Mastery' => 0.02 * $talents['Shadow Mastery'],
'Contagion' => 0.01 * $talents['Contagion'],
'Master Demonologist' => 0,
'Demonic Sacrifice (Fire)' => 0,
'Demonic Sacrifice (Shadow)' => 0,
'Soul Link' => 0.05 * $talents['Soul Link'],
'Emberstorm' => 0.02 * $talents['Emberstorm']
);
// Demonologist buffs
if ($debuffs['Demonic Sacrifice']) {
if ($debuffs['Imp']) {
$talentModifiers['dmg_modifiers']['Demonic Sacrifice (Fire)'] = 0.15;
} elseif ($debuffs['Succubus']) {
$talentModifiers['dmg_modifiers']['Demonic Sacrifice (Shadow)'] = 0.15;
} elseif ($debuffs['Felguard']) {
$talentModifiers['dmg_modifiers']['Demonic Sacrifice (Shadow)'] = 0.10;
}
} else {
if ($debuffs['Succubus']) {
$talentModifiers['dmg_modifiers']['Master Demonologist'] => 0.02 * $talents['Master Demonologist'];
} elseif ($debuffs['Felguard']) {
$talentModifiers['dmg_modifiers']['Master Demonologist'] => 0.01 * $talents['Master Demonologist'];
}
}
$talentModifiers['crit_modifiers'] = array(
'Base' => 0.5,
'Ruin' => 0.5 * $talents['Ruin']
);
$talentModifiers['crit_chance_modifiers'] = array(
'Demonic Tactics' => 0.01 * $talents['Demonic Tactics'],
'Devastation' => 0.01 * $talents['Devastation'],
'Backlash' => 0.01 * $talents['Backlash']
);
if ($talents['Improved Searing Pain'] == 1) {
$talentModifiers['crit_chance_modifiers']['Improved Searing Pain'] = 0.04;
} elseif ($talents['Improved Searing Pain'] > 1) {
$talentModifiers['crit_chance_modifiers']['Improved Searing Pain'] = 0.04 + (0.03 * ($talents['Improved Searing Pain'] - 1));
} else {
$talentModifiers['crit_chance_modifiers']['Improved Searing Pain'] = 0;
}
$talentModifiers['hit_chance_modifiers'] = array(
'Suppression' => 0.02 * $talents['Suppression']
);
$talentModifiers['mana_cost'] = array(
'Cataclysm' => 1 - (0.01 * $talents['Cataclysm'])
);
return $talentModifiers;
}
$debuffs = array();
$talentModifiers = getTalentModifiers($talents, $debuffs);
function critModifier(&$spell, &$talentModifiers) {
$critModifiers = $talentModifiers['crit_modifiers'];
$critMultipler = 1 + $critModifiers['Base'];
if ($spell['tree'] == 'Destruction') {
$critMultipler += $critModifiers['Ruin'];
}
return $critMultipler;
}
// Spells
$dd['Shadow Bolt'] = array(
'name' => 'Shadow Bolt',
'school' => 'Shadow',
'tree' => 'Destruction',
'base_damage' => 576,
'mana_cost' => 420,
'cast_time' => 3,
'dmg_coeff' => 3 / 3.5,
'dmg_talents' => array('Shadow Mastery', 'Demonic Sacrifice (Shadow)', 'Master Demonologist', 'Soul Link'),
'crit_chance_talents' => array('Devastation', 'Backlash'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
$dd['Shadowburn'] = array(
'name' => 'Shadowburn',
'school' => 'Shadow',
'tree' => 'Destruction',
'base_damage' => 631,
'mana_cost' => 515,
'cast_time' => 1.5,
'dmg_coeff' => 1.5 / 3.5,
'dmg_talents' => array('Shadow Mastery', 'Demonic Sacrifice (Shadow)', 'Master Demonologist', 'Soul Link'),
'crit_chance_talents' => array('Devastation', 'Backlash'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
$dd['Death Coil'] = array(
'name' => 'Death Coil',
'school' => 'Shadow',
'tree' => 'Affliction',
'base_damage' => 526,
'mana_cost' => 600,
'cast_time' => 1.5,
'dmg_coeff' => 0.214,
'dmg_talents' => array('Shadow Mastery', 'Demonic Sacrifice (Shadow)', 'Master Demonologist', 'Soul Link'),
'crit_chance_talents' => array(),
'hit_chance_talents' => array(),
'mana_cost_talents' => array()
);
$dd['Incinerate'] = array(
'name' => 'Incinerate',
'school' => 'Fire',
'tree' => 'Destruction',
'base_damage' => 479,
'mana_cost' => 355,
'cast_time' => 2.5,
'dmg_coeff' => 2.5 / 3.5,
'dmg_talents' => array('Demonic Sacrifice (Fire)', 'Master Demonologist', 'Soul Link', 'Emberstorm'),
'crit_chance_talents' => array('Devastation', 'Backlash'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
$dd['Incinerate (Immolate)'] = array(
'name' => 'Incinerate',
'school' => 'Fire',
'tree' => 'Destruction',
'base_damage' => 599, /* 479 base, bonus 119.75 against immolated targets */
'mana_cost' => 355,
'cast_time' => 2.5,
'dmg_coeff' => 2.5 / 3.5,
'dmg_talents' => array('Demonic Sacrifice (Fire)', 'Master Demonologist', 'Soul Link', 'Emberstorm'),
'crit_chance_talents' => array('Devastation', 'Backlash'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
$dd['Conflagrate'] = array(
'name' => 'Conflagrate',
'school' => 'Fire',
'tree' => 'Destruction',
'base_damage' => 650,
'mana_cost' => 305,
'cast_time' => 1.5,
'dmg_coeff' => 1.5 / 3.5,
'dmg_talents' => array('Demonic Sacrifice (Fire)', 'Master Demonologist', 'Soul Link', 'Emberstorm'),
'crit_chance_talents' => array('Devastation', 'Backlash'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
$dd['Soul Fire'] = array(
'name' => 'Soul Fire',
'school' => 'Fire',
'tree' => 'Destruction',
'base_damage' => 1130,
'mana_cost' => 250,
'dmg_coeff' => 1.15,
'dmg_talents' => array('Demonic Sacrifice (Fire)', 'Master Demonologist', 'Soul Link', 'Emberstorm'),
'crit_chance_talents' => array('Devastation', 'Backlash'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
$dd['Searing Pain'] = array(
'name' => 'Searing Pain',
'school' => 'Fire',
'tree' => 'Destruction',
'base_damage' => 295,
'mana_cost' => 205,
'dmg_coeff' => 1.5 / 3.5,
'dmg_talents' => array('Demonic Sacrifice (Fire)', 'Master Demonologist', 'Soul Link', 'Emberstorm'),
'crit_chance_talents' => array('Devastation', 'Improved Searing Pain', 'Backlash'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
$dd['Immolate (DD)'] = array(
'name' => 'Immolate (DD)',
'school' => 'Fire',
'tree' => 'Destruction',
'base_damage' => 332,
'mana_cost' => 445,
'cast_time' => 2,
'dmg_coeff' => 0.2,
'dmg_talents' => array('Demonic Sacrifice (Fire)', 'Master Demonologist', 'Soul Link', 'Emberstorm'),
'crit_chance_talents' => array('Devastation', 'Backlash'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
/* DOTS */
$dots['Drain Life'] = array(
'name' => 'Drain Life',
'school' => 'Shadow',
'tree' => 'Affliction',
'base_damage' => 540,
'mana_cost' => 425,
'cast_time' => 5,
'dot_time' => 5,
'dmg_coeff' => 0.7143,
'dmg_talents' => array('Demonic Sacrifice (Shadow)', 'Shadow Mastery', 'Master Demonologist', 'Soul Link'),
'hit_chance_talents' => array('Suppression'),
'mana_cost_talents' => array()
);
$dots['Immolate (DoT)'] = array(
'name' => 'Immolate (DoT)',
'school' => 'Fire',
'base_damage' => 615,
'mana_cost' => 445,
'cast_time' => 2,
'dot_time' => 15,
'dmg_coeff' => 0.65,
'dmg_talents' => array('Demonic Sacrifice (Fire)', 'Master Demonologist', 'Soul Link', 'Emberstorm'),
'hit_chance_talents' => array(),
'mana_cost_talents' => array('Cataclysm')
);
$dots['Corruption'] = array(
'name' => 'Corruption',
'school' => 'Shadow',
'tree' => 'Affliction',
'base_damage' => 900,
'mana_cost' => 370,
'cast_time' => 1.5,
'dot_time' => 18,
'dmg_coeff' => 0.936,
'dmg_talents' => array('Demonic Sacrifice (Shadow)', 'Shadow Mastery', 'Contagion', 'Master Demonologist', 'Soul Link'),
'hit_chance_talents' => array('Suppression'),
'mana_cost_talents' => array()
);
$dots['Unstable Affliction'] = array(
'name' => 'Unstable Affliction',
'school' => 'Shadow',
'tree' => 'Affliction',
'base_damage' => 1050,
'mana_cost' => 400,
'cast_time' => 1.5,
'dot_time' => 18,
'dmg_coeff' => 1.2,
'dmg_talents' => array('Demonic Sacrifice (Shadow)', 'Shadow Mastery', 'Master Demonologist', 'Soul Link'),
'hit_chance_talents' => array('Suppression'),
'mana_cost_talents' => array()
);
$dots['Curse of Agony'] = array(
'name' => 'Curse of Agony',
'school' => 'Shadow',
'tree' => 'Affliction',
'base_damage' => 1356,
'mana_cost' => 265,
'cast_time' => 1.5,
'dot_time' => 24,
'dmg_coeff' => 1.2,
'dmg_talents' => array('Demonic Sacrifice (Shadow)', 'Shadow Mastery', 'Contagion', 'Master Demonologist', 'Soul Link'),
'hit_chance_talents' => array('Suppression'),
'mana_cost_talents' => array()
);
$dots['Curse of Doom'] = array(
'name' => 'Curse of Doom',
'school' => 'Shadow',
'tree' => 'Affliction',
'base_damage' => 4200,
'mana_cost' => 380,
'cast_time' => 1.5,
'dot_time' => 60,
'dmg_coeff' => 2,
'dmg_talents' => array('Demonic Sacrifice (Shadow)', 'Shadow Mastery', 'Master Demonologist', 'Soul Link'),
'hit_chance_talents' => array('Suppression'),
'mana_cost_talents' => array()
);
$dots['Siphon Life'] = array(
'name' => 'Siphon Life',
'school' => 'Shadow',
'tree' => 'Affliction',
'base_damage' => 630, /* 63 every 3 seconds, for 30 seconds */
'mana_cost' => 380,
'cast_time' => 1.5,
'dot_time' => 60,
'dmg_coeff' => 1,
'dmg_talents' => array('Demonic Sacrifice (Shadow)', 'Shadow Mastery', 'Master Demonologist', 'Soul Link'),
'hit_chance_talents' => array('Suppression'),
'mana_cost_talents' => array()
);
// Spell book
class DirectDamage {
var $name;
var $castTime;
var $baseDamage;
var $manaCost;
var $critChance;
var $hitChance;
var $dmgCoeff;
var $dmgModifier;
var $critModifier;
var $spellDamage;
function DirectDamage(&$stats, &$talentModifiers, $spell) {
$this->name = $spell['name'];
if ($spell['school'] == 'Shadow') {
$this->spellDamage = $stats['shadow_damage'];
} else if ($spell['school'] == 'Fire') {
$this->spellDamage = $stats['fire_damage'];
} else {
$this->spellDamage = $stats['spell_damage'];
}
$this->baseDamage = $spell['base_damage'];
$this->manaCost = $spell['mana_cost'];
foreach($spell['mana_cost_talents'] as $talentName) {
$this->manaCost = $this->manaCost * $talentModifiers['mana_cost'][$talentName];
}
if (array_key_exists($this->name, $talentModifiers['cast_time'])) {
$this->castTime = $talentModifiers['cast_time'][$this->name];
} else {
$this->castTime = $spell['cast_time'];
}
if (array_key_exists($this->name, $talentModifiers['dmg_coeff'])) {
$this->dmgCoeff = $talentModifiers['dmg_coeff'][$this->name];
} else {
$this->dmgCoeff = $spell['dmg_coeff'];
}
$this->dmgModifier = 1;
foreach($spell['dmg_talents'] as $talentName) {
$this->dmgModifier += $talentModifiers['dmg_modifiers'][$talentName];
}
$this->critModifier = critModifier($spell, $talentModifiers);
$this->critChance = $stats['crit_chance'];
foreach($spell['crit_chance_talents'] as $talentName) {
$this->critChance += $talentModifiers['crit_chance_modifiers'][$talentName];
}
$this->hitChance = $stats['hit_chance'];
foreach($spell['hit_chance_talents'] as $talentName) {
$this->hitChance += $talentModifiers['hit_chance_modifiers'][$talentName];
}
if ($this->hitChance > 0.99) {
$this->hitChance = 0.99;
}
}
function avgNonCrit() {
return ($this->baseDamage + ($this->spellDamage * $this->dmgCoeff)) * $this->dmgModifier;
}
function avgCrit() {
return $this->avgNonCrit() * $this->critModifier;
}
function avgHit() {
return ($this->avgNonCrit() * (1 - $this->critChance)) + ($this->avgCrit() * $this->critChance);
}
function avgDamage() {
return $this->hitChance * $this->avgHit();
}
function DPS() {
global $LATENCY;
return $this->avgDamage() / ($this->castTime + $LATENCY);
}
function DPM() {
return $this->avgDamage() / $this->manaCost;
}
function hitToDmg() {
$newHitChance = $this->hitChance + 0.01; // 1% hit
if ($newHitChance > 0.99) {
return 0;
}
$avgDmg = $this->avgHit() * $newHitChance;
$nonCrit = ($avgDmg / $this->hitChance) / ((1 - $this->critChance) + ($this->critModifier * $this->critChance));
$spellDmg = ((($nonCrit / $this->dmgModifier) - $this->baseDamage) / $this->dmgCoeff) - $this->spellDamage;
return $spellDmg;
}
function critToDmg() {
$newCritChance = $this->critChance + 0.01;
$avgHit = ($this->avgNonCrit() * (1 - $newCritChance)) + ($this->avgCrit() * $newCritChance);
$nonCrit = $avgHit / ((1 - $this->critChance) + ($this->critModifier * $this->critChance));
$spellDmg = ((($nonCrit / $this->dmgModifier) - $this->baseDamage) / $this->dmgCoeff) - $this->spellDamage;
return $spellDmg;
}
function dpsToDmg() {
global $LATENCY;
$newDPS = $this->DPS() * 1.01;
$avgDmg = $newDPS * ($this->castTime + $LATENCY);
$nonCrit = ($avgDmg / $this->hitChance) / ((1 - $this->critChance) + ($this->critModifier * $this->critChance));
$spellDmg = ((($nonCrit / $this->dmgModifier) - $this->baseDamage) / $this->dmgCoeff) - $this->spellDamage;
return $spellDmg;
}
function debug() {
echo '<pre>';
echo '==='.$this->name.'==='."\n";
echo 'Spell Dmg: '.$this->spellDamage."\n";
echo 'Base: '.$this->baseDamage."\n";
echo 'Cast time: '.$this->castTime."\n";
echo 'Mana: '.$this->manaCost."\n";
echo 'Crit Chance: '.$this->critChance."\n";
echo 'Crit Modifier: '.$this->critModifier."\n";
echo 'Hit Chance: '.$this->hitChance."\n";
echo 'Dmg Coeff: '.$this->dmgCoeff."\n";
echo 'Dmg Mod: '.$this->dmgModifier."\n";
echo 'Avg Non-crit: '.$this->avgNonCrit()."\n";
echo 'Avg Crit: '.$this->avgCrit()."\n";
echo 'Avg Hit: '.$this->avgHit()."\n";
echo 'Avg Dmg: '.$this->avgDamage()."\n";
echo 'DPS: '.$this->DPS()."\n";
echo 'DPM: '.$this->DPM()."\n";
echo '1% hit = '.$this->hitToDmg().' +spell dmg'."\n";
echo '1% crit = '.$this->critToDmg().' +spell dmg'."\n";
echo '1% dps = '.$this->dpsToDmg().' +spell dmg'."\n";
echo '</pre>';
}
}
class DoT {
var $name;
var $castTime;
var $dotTime;
var $baseDamage;
var $manaCost;
var $hitChance;
var $dmgCoeff;
var $dmgModifier;
var $spellDamage;
function DoT(&$stats, &$talentModifiers, $spell) {
$this->name = $spell['name'];
if ($spell['school'] == 'Shadow') {
$this->spellDamage = $stats['shadow_damage'];
} else if ($spell['school'] == 'Fire') {
$this->spellDamage = $stats['fire_damage'];
} else {
$this->spellDamage = $stats['spell_damage'];
}
$this->baseDamage = $spell['base_damage'];
$this->manaCost = $spell['mana_cost'];
foreach($spell['mana_cost_talents'] as $talentName) {
$this->manaCost = $this->manaCost * $talentModifiers['mana_cost'][$talentName];
}
$this->dotTime = $spell['dot_time'];
if (array_key_exists($this->name, $talentModifiers['cast_time'])) {
$this->castTime = $talentModifiers['cast_time'][$this->name];
} else {
$this->castTime = $spell['cast_time'];
}
if (array_key_exists($this->name, $talentModifiers['dmg_coeff'])) {
$this->dmgCoeff = $talentModifiers['dmg_coeff'][$this->name];
} else {
$this->dmgCoeff = $spell['dmg_coeff'];
}
$this->dmgModifier = 1;
foreach($spell['dmg_talents'] as $talentName) {
$this->dmgModifier += $talentModifiers['dmg_modifiers'][$talentName];
}
$this->hitChance = $stats['hit_chance'];
foreach($spell['hit_chance_talents'] as $talentName) {
$this->hitChance += $talentModifiers['hit_chance_modifiers'][$talentName];
}
if ($this->hitChance > 0.99) {
$this->hitChance = 0.99;
}
}
function avgHit() {
return ($this->baseDamage + ($this->spellDamage * $this->dmgCoeff)) * $this->dmgModifier;
}
function avgDamage() {
return $this->hitChance * $this->avgHit();
}
function DPS() {
return $this->avgDamage() / $this->dotTime;
}
function DPM() {
return $this->avgDamage() / $this->manaCost;
}
function critToDmg() {
return 0; // Damage over Time spells do not crit
}
function hitToDmg() {
$newHitChance = $this->hitChance + 0.01; // 1% hit
if ($newHitChance > 0.99) {
return 0;
}
$avgDmg = $this->avgHit() * $newHitChance;
$avgHit = $avgDmg / $this->hitChance;
$spellDmg = ((($avgHit / $this->dmgModifier) - $this->baseDamage) / $this->dmgCoeff) - $this->spellDamage;
return $spellDmg;
}
function dpsToDmg() {
global $LATENCY;
$newDPS = $this->DPS() * 1.01;
$avgDmg = $newDPS * $this->dotTime;
$avgHit = $avgDmg / $this->hitChance;
$spellDmg = ((($avgHit / $this->dmgModifier) - $this->baseDamage) / $this->dmgCoeff) - $this->spellDamage;
return $spellDmg;
}
function debug() {
echo '<pre>';
echo '==='.$this->name.'==='."\n";
echo 'Spell Dmg: '.$this->spellDamage."\n";
echo 'Base: '.$this->baseDamage."\n";
echo 'Cast time: '.$this->castTime."\n";
echo 'Mana: '.$this->manaCost."\n";
echo 'Hit Chance: '.$this->hitChance."\n";
echo 'Dmg Coeff: '.$this->dmgCoeff."\n";
echo 'Dmg Mod: '.$this->dmgModifier."\n";
echo 'Avg Hit: '.$this->avgHit()."\n";
echo 'Avg Dmg: '.$this->avgDamage()."\n";
echo 'DPS: '.$this->DPS()."\n";
echo 'DPM: '.$this->DPM()."\n";
echo '1% hit = '.$this->hitToDmg().' +spell dmg'."\n";
echo '1% dps = '.$this->dpsToDmg().' +spell dmg'."\n";
echo '</pre>';
}
}
$SPELL_BOOK = array();
foreach($dd as $spellName => $spell) {
$SPELL_BOOK[$spellName] = new DirectDamage($stats, $talentModifiers, $spell);
}
foreach($dots as $spellName => $spell) {
$SPELL_BOOK[$spellName] = new DoT($stats, $talentModifiers, $spell);
} ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Dmg Calculator</title>
<style type="text/css">
<!--
table[border="1"] {
border-collapse: collapse;
}
table[border="1"] td {
border: 1px solid black;
}
-->
</style>
</head>
<body>
<form action="<?php echo $PHP_SELF; ?>" method="get">
<input type="hidden" name="lookup_armory" value="true">
<table cellspacing="0" cellpadding="5" border="0"><tr>
<th>Character Name</th>
<td><input type="text" size="40" name="character" value="<?php echo $character; ?>"></td>
</tr><tr>
<th>Realm</th>
<td><input type="text" size="40" name="realm" value="<?php echo $realm; ?>"></td>
</tr><tr>
<td colspan="2" align="right"><input type="submit" value="Submit"></td>
</tr></table>
</form>
<form action="<?php echo $PHP_SELF; ?>" method="get">
<table cellspacing="0" cellpadding="5" border="0"><tr>
<th>Intellect</th>
<td><input type="text" size="4" name="stats[intellect]" value="<?php echo $stats['intellect']; ?>"></td>
</tr><tr>
<th>Base Crit</th>
<td><input type="text" size="6" name="stats[crit_chance]" value="<?php echo ($stats['crit_chance'] * 100); ?>"></td>
</tr><tr>
<th>Spell Damage</th>
<td>
Base: <input type="text" size="4" name="stats[spell_damage]" value="<?php echo $stats['spell_damage']; ?>">
Shadow: <input type="text" size="4" name="stats[shadow_damage]" value="<?php echo $stats['shadow_damage']; ?>">
Fire: <input type="text" size="4" name="stats[fire_damage]" value="<?php echo $stats['fire_damage']; ?>">
</td>
</tr><tr>
<th>Hit Rating</th>
<td><input type="text" size="3" name="stats[hit_rating]" value="<?php echo $stats['hit_rating']; ?>"></td>
</tr><tr>
<th>Talent Tree</th>
<td><input type="text" size="100" name="talent_tree" value="<?php echo $talent_tree; ?>"</td>
</tr><tr>
<th>Latency</th>
<td><input type="text" size="5" name="latency" value="<?php echo ($LATENCY * 1000); ?>"></td>
</tr><tr>
<td colspan="2" align="right"><input type="submit" value="Submit"></td>
</tr></table>
</form>
<table cellspacing="0" cellpadding="5" border="1">
<thead><tr>
<th>Spell</th>
<th>DPS</th>
<th>DPM</th>
<th>Crit %</th>
<th>Hit %</th>
<th>1% DPS</th>
</tr></thead>
<tbody>
<?php foreach($SPELL_BOOK as $spellName => $spell) : ?>
<tr>
<td><?php echo $spellName; ?></td>
<td><?php echo round($spell->DPS(), 2); ?></td>
<td><?php echo round($spell->DPM(), 2); ?></td>
<td><?php echo round($spell->critToDmg(), 2); ?></td>
<td><?php echo round($spell->hitToDmg(), 2); ?></td>
<td><?php echo round($spell->dpsToDmg(), 2); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div style="height: 10px:"> </div>
<table cellspacing="0" cellpadding="5" border="1">
<thead><tr>
<th>Spell</th>
<th>DPS</th>
</tr></thead>
<tbody>
<?php
// Rotation definitions
function Immolate_Incinerate_Conflagrate($spellBook) {
global $LATENCY;
$immolate_dot_bonus = $spellBook['Immolate (DoT)']->DPS() * 8;
return ($immolate_dot_bonus + $spellBook['Immolate (DD)']->avgDamage() + $spellBook['Incinerate (Immolate)']->avgDamage() * 3 + $spellBook['Conflagrate']->avgDamage()) / ($spellBook['Immolate (DD)']->castTime + $spellBook['Incinerate (Immolate)']->castTime * 3 + $spellBook['Conflagrate']->castTime + $LATENCY * 4);
}
?>
<tr>
<td>Immolate -> Incinerate x 3 -> Conflag</td>
<td><?php echo round(Immolate_Incinerate_Conflagrate($SPELL_BOOK), 2); ?></td>
</tr>
</tbody>
</table>
<div style="height: 10px:"> </div>
<table cellspacing="0" cellpadding="5" border="1">
<thead><tr>
<th>Spec</th>
<th>Sample</th>
</thead>
<tbody>
<?php
foreach(array(
) as $specName => $talentString) {
$specModifiers = getTalentModifiers(parseTalentString($talentString), $debuffs);
$specSpellBook = array();
foreach($spells as $spellName => $spell) {
$specSpellBook[$spellName] = new Spell($stats, $specModifiers, $spell);
} ?>
<tr>
<td><?php echo $specName; ?></td>
<td><?php echo round(0/*Fireball_Scorch($SPELL_BOOK)*/, 2); ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
<pre>
<?php
if ($debug) {
foreach($SPELL_BOOK as $spellName => $spell) {
$spell->debug();
}
} ?>
</pre>
</body>
</html>