Cameron Zemek */ 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 '
';
		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 '
'; } } 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 '
';
		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 '
'; } } $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); } ?> Dmg Calculator
Character Name
Realm
Intellect
Base Crit
Spell Damage Base: Shadow: Fire:
Hit Rating
Talent Tree
Latency
$spell) : ?>
Spell DPS DPM Crit % Hit % 1% DPS
DPS(), 2); ?> DPM(), 2); ?> critToDmg(), 2); ?> hitToDmg(), 2); ?> dpsToDmg(), 2); ?>
 
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); } ?>
Spell DPS
Immolate -> Incinerate x 3 -> Conflag
 
$talentString) { $specModifiers = getTalentModifiers(parseTalentString($talentString), $debuffs); $specSpellBook = array(); foreach($spells as $spellName => $spell) { $specSpellBook[$spellName] = new Spell($stats, $specModifiers, $spell); } ?>
Spec Sample
 $spell) {
		$spell->debug();
	}
} ?>