function calcDam() {	
	document.getElementById('damage_calculation_result').style.display = 'none';
	with (document.forms[0]) {
		$('error_message').hide();
		//Apply attack and defense stage boosts
		atk_boost = parseInt(atk_stage.value);
		if (offensive_abilities.value == 'Download') { atk_boost = atk_boost+1; }
		if (defensive_abilities.value == 'Intimidate') { atk_boost = atk_boost-1; }
		if (atk_boost > 6) { atk_boost = 6; }
		if (atk_boost < -6) { atk_boost = -6; }
		atk = (atk_boost >= 0) ? Math.floor(atk_stat.value * (2 + parseInt(atk_boost)) / 2) : Math.floor(atk_stat.value * 2 / (2 + Math.abs(atk_boost)));
		atk = (atk == 0) ? 1 : atk;
		def = (def_stage.value >= 0) ? Math.floor(def_stat.value * (2 + parseInt(def_stage.value)) / 2) : Math.floor(def_stat.value * 2 / (2 + Math.abs(def_stage.value)));
		def = (def == 0) ? 1 : def;
		
		lvl = level.value;
		hp = Math.floor(hp_stat.value);
		bp = Math.floor(base_power.value);
		sr = sr_weakness.value;			
			
		//Validate input
		with (document.getElementById('error_msg')) {
			innerHTML = '';
			var error = 0;
			HTML = '';
			if (lvl > 100 || lvl <= 0) { 
				HTML += '<li>Invalid level: needs to be between 1 and 100</li>'; 
				error++;
			} 
			if (bp <= 0) { 
				HTML += '<li>Invalid base power: cannot be equal to or lower than 0</li>';
				error++;
			}
			if (hp < 0) {
				HTML += '<li>Invalid HP: cannot be lower than 0</li>';
				error++;
			}
			if (def < 0) {
				HTML += '<li>Invalid (Sp)Def: cannot be lower than 0</li>';
				error++;
			}
			if (atk < 0) {
				HTML += '<li>Invalid (Sp)Atk: cannot be lower than 0</li>';
				error++;
			}
			HTML += '</ul>';
			//Halt the script if any errors were found
			if (error > 0) {
				innerHTML = '<p class="report-warning">'+error+' error(s) were found in your input:</p><ul>'+HTML;

				return false;
			}
		}
		
		//Apply basic modifiers
		stab = same_type.value;
		type1 = mod_typing1.value;
		type2 = mod_typing2.value;
		mod1 = 1;
		mod2 = 1;
		mod3 = 1;
		crit = (ch.checked == true) ? ((offensive_abilities.value == 'Sniper') ? 3 : 2) : 1;
				
		//Apply miscellaneous modifiers
		if (mod2_mefirst.checked == true) { mod2 *= 1.5; }
		if (mod1_reflect.checked == true) { mod1 *= 0.5; }
		if (mod1_weather_pos.checked == true) { mod1 *= 1.5; }
		if (mod1_weather_neg.checked == true) { mod1 = (mod1_weather_pos.checked == true) ? (mod1 / 1.5) : (mod1 * 0.5); }
		if (mod1_burn.checked == true) { mod1 *= 0.5; }
		
		//Apply offensive abilities modifiers
		with (offensive_abilities) {
			if (value == 'Adaptability') { stab = (stab > 1) ? 2 : stab; }
			else if (value == 'Blaze' || value == 'Torrent' || value == 'Overgrow' || value == 'Swarm') { bp = Math.floor(bp * 1.5); }
			else if (value == 'Reckless' || value == 'IronFist') { bp = Math.floor(bp * 1.2); }
			else if (value == 'RivalryPos') { bp = Math.floor(bp * 1.25); }
			else if (value == 'RivalryNeg') { bp = Math.floor(bp * 0.75); }
			else if (value == 'Technician') { bp = (bp <= 60) ? Math.floor(bp * 1.5) : bp; }
			else if (value == 'PurePower' || value == 'HugePower') { atk = Math.floor(atk * 2); }
			else if (value == 'Guts' || value == 'Hustle' || value == 'FlowerGift' || value == 'Plus' || value == 'Minus' || value == 'SolarPower') { atk = Math.floor(atk * 1.5); }
			else if (value == 'SlowStart') { atk = Math.floor(atk * 0.5); }
			else if (value == 'TintedLens') { mod2 *= 2; }
			else if (value == 'FlashFire') { mod1 *= 1.5; }
		}
		
		//Apply defensive abilities modifiers
		with (defensive_abilities) {
			if (value == 'Heatproof' || value == 'ThickFat') { bp = Math.floor(bp * 0.5); }
			else if (value == 'Filter' || value == 'SolidRock') { mod3 = (type1 > 1 || type2 > 1) ? mod3 * 0.75 : mod3; }
			else if (value == 'MarvelScale') { def = Math.floor(def * 1.5); }
		}
		
		
		//Apply offensive items modifiers
		with (offensive_items) {
			if (value == 'MuscleBand' || value == 'WiseGlasses') { bp = Math.floor(bp * 1.1); }
			else if (value == 'AdamantOrb' || value == 'LustrousOrb' || value == 'ElementalPlate') { bp = Math.floor(bp * 1.2); }
			else if (value == 'ChoiceBand' || value == 'ChoiceSpecs' || value == 'SoulDew') { atk = Math.floor(atk * 1.5); }
			else if (value == 'LightBall' || value == 'ThickClub') { atk = Math.floor(atk * 2); }
			else if (value == 'LifeOrb') { mod2 *= 1.3; }
			else if (value == 'ExpertBelt') { mod3 *= 1.2; }
		}
		
		//Apply defensive items modifiers
		with (defensive_items) {
			if (value == 'SoulDew' || value == 'MetalPowder') { def = Math.floor(def * 1.5); }
			else if (value == 'Deepseascale') { def = Math.floor(def * 2); }
			else if (value == 'TypeResistingBerry') { mod3 *= 0.5; }
		}
			
		//Start the actual damage calculation
		basedam = Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(lvl * 2 / 5) + 2) * bp * atk / 50) / def) * mod1) +2) * crit) * mod2);
		i = 217;
		dam = new Array();
		while (i <= 255) {
			damage = Math.floor(Math.floor(Math.floor(Math.floor(parseInt(basedam) * Math.floor((parseInt(i)*100)/255) / 100) * parseFloat(stab)) * parseFloat(type1)) * parseFloat(type2));
			dam[dam.length] = Math.floor(damage * mod3);
			i++;
		}
		avg_dam = Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(parseInt(basedam) * Math.floor((236*100)/255) / 100) * parseFloat(stab)) * parseFloat(type1)) * parseFloat(type2)) * mod3);
		
		if (rock_type.checked == true) {
			//Calculate stuff for when Sandstorm is in effect
			basedam_rock = Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(lvl * 2 / 5) + 2) * bp * atk / 50) / Math.floor(def * 1.5)) * mod1) +2) * crit) * mod2);
			i = 217;
			dam_rock = new Array();
			while (i <= 255) {
				damage_rock = Math.floor(Math.floor(Math.floor(Math.floor(parseInt(basedam_rock) * Math.floor((parseInt(i)*100)/255) / 100) * parseFloat(stab)) * parseFloat(type1)) * parseFloat(type2));
				dam_rock[dam_rock.length] = Math.floor(damage_rock * mod3);
				i++;
			}
			avg_dam_rock = Math.floor(Math.floor(Math.floor(Math.floor(Math.floor(parseInt(basedam_rock) * Math.floor((236*100)/255) / 100) * parseFloat(stab)) * parseFloat(type1)) * parseFloat(type2)) * mod3);
		}
				
		
		//Calculate OHKO and 2HKO odds (3HKO odds makes a client's computer lag too much)
		if (hp > 0) {
			//Set up all necessary variables
			x = 0;
			y = 0;
			ohko = 0;
			ohko_leftovers = 0;
			ohko_sandstorm = 0;
			ohko_sr = 0;
			ohko_leftovers_sr = 0;
			thko = 0;
			thko_leftovers = 0;
			thko_sandstorm = 0;
			thko_sr = 0;
			thko_leftovers_sr = 0;
			
			while (x < 39) {
				while (y < 39) {
					dam_total = parseInt(dam[x]) + parseInt(dam[y]);
					if (dam_total >= hp) { thko++; }
					if (dam_total >= Math.floor(hp * 1.0625)) { thko_leftovers++; }
					if (rock_type.checked == true && (parseInt(dam_rock[x]) + parseInt(dam_rock[y])) >= hp) { thko_sandstorm++; } 
					else if (rock_type.checked == false && dam_total >= Math.ceil(hp * 0.875)) { thko_sandstorm++; }
					if (dam_total >= hp - Math.floor((hp/8) * parseFloat(sr))) { thko_sr++; }
					if (dam_total >= Math.floor(hp * 1.0625) - Math.floor((hp/8) * parseFloat(sr))) { thko_leftovers_sr++; }
					y++;
				}
				y = 0;
				if (dam[x] >= hp) { 
					ohko++; 
					ohko_leftovers++; 
				}
				if (rock_type.checked == true && (parseInt(dam_rock[x])) >= hp) { ohko_sandstorm++; }
				else if (rock_type.checked == false && dam[x] >= Math.ceil(hp * 0.9375)) { ohko_sandstorm++; }
				if (dam[x] >= hp - Math.floor((hp/8) * parseFloat(sr))) { 
					ohko_sr++; 
					ohko_leftovers_sr++; 
				}
				x=x+1;
			}
		}
	}
	
	//Get OHKO and 2HKO percentages
	var ohko = (parseInt(ohko) * 100 / 39).toFixed(2);
	ohko_leftovers = ohko;
	var ohko_sandstorm = (parseInt(ohko_sandstorm) * 100 / 39).toFixed(2);
	var ohko_sr = (parseInt(ohko_sr) * 100 / 39).toFixed(2);
	ohko_leftovers_sr = ohko_sr;
	
	var thko = (parseInt(thko) * 100 / 1521).toFixed(2);
	var thko_leftovers = (parseInt(thko_leftovers) * 100 / 1521).toFixed(2);
	var thko_sandstorm = (parseInt(thko_sandstorm) * 100 / 1521).toFixed(2);
	var thko_sr = (parseInt(thko_sr) * 100 / 1521).toFixed(2);
	var thko_leftovers_sr = (parseInt(thko_leftovers_sr) * 100 / 1521).toFixed(2);

	var resultHTML = '<h2>Results</h2><table border="0" id="dam_results"><tr><td colspan="4"><b>Damage Results</td><td colspan="6"><b>OHKO &amp; 2HKO Odds</td></tr>';
	resultHTML += '<tr><td>&nbsp;</td><td class="label">Min:</td><td class="label">Avg:</td><td class="label">Max:</td><td>&nbsp;</td><td class="label">Normal:</td><td class="label">Leftovers:</td><td class="label">Sandstorm:</td><td class="label">Stealth Rock:</td><td class="label">SR + Leftovers</td></tr>';
	resultHTML += '<tr><td class="label">Raw Damage:</td><td>'+dam[0]+'</td><td>'+avg_dam+'</td><td>'+dam[38]+'</td>';

	if (hp > 0) {
	   resultHTML += '<td class="label">OHKO:</td><td>'+ohko+'%</td><td>'+ohko_leftovers+'%</td><td>'+ohko_sandstorm+'%</td><td>'+ohko_sr+'%</td><td>'+ohko_leftovers_sr+'%</td>';
	} else {
	   resultHTML += '<td colspan="6">&nbsp;</td>';
	}

	resultHTML += '</tr><tr>';

	if (hp > 0) { 
	   resultHTML += '<td class="label">Percentages:</td><td>'+(parseInt(dam[0]) / ((parseInt(hp)) / 100)).toFixed(2)+'%</td><td>'+(parseInt(avg_dam) / ((parseInt(hp)) / 100)).toFixed(2)+'%</td><td>'+(parseInt(dam[38]) / ((parseInt(hp)) / 100)).toFixed(2)+'%</td>';
	} else {
	   resultHTML += '<td colspan="4">&nbsp;</td>';
	}

	if (hp > 0) {
	   resultHTML += '<td class="label">2HKO:</td><td>'+thko+'%</td><td>'+thko_leftovers+'%</td><td>'+thko_sandstorm+'%</td><td>'+thko_sr+'%</td><td>'+thko_leftovers_sr+'%</td>';
	} else {
	   resultHTML += '<td colspan="6">&nbsp;</td>';
	}
	resultHTML += '</tr></table>';

	document.getElementById('damage_calculation_result').style.display = 'block';




	if (document.getElementById('rock_type').checked == true) {
		resultHTML += '<tr><td colspan=4">&nbsp;</td></tr><tr><td colspan="4" class="label">Sandstorm Results</td></tr><tr class="semi-header-wrapper"><td>&nbsp;</td><td class="label">Min:</td><td class="label">Avg:</td><td class="label">Max:</td></tr><tr><td class="label">Raw damage:</td><td>'+dam_rock[0]+'</td><td>'+avg_dam_rock+'</td><td>'+dam_rock[38]+'</td></tr>';
		if (hp > 0) { resultHTML += '<tr><td class="label">Percentages:</td><td>'+(parseInt(dam_rock[0]) / ((parseInt(hp)) / 100)).toFixed(2)+'%</td><td>'+(parseInt(avg_dam_rock) / ((parseInt(hp)) / 100)).toFixed(2)+'%</td><td>'+(parseInt(dam_rock[38]) / ((parseInt(hp)) / 100)).toFixed(2)+'%</td></tr>'; }
	}
	


	if (hp > 0) {
		if (hp > 0) { 
resultHTML += '<input style="width: 500px; text-align: center;" type="text" readonly="readonly" value="'+atk+' Atk vs '+def+' Def & '+hp+' HP ('+bp+' Base Power): '+dam[0]+' - '+dam[38]+' ('+(parseInt(dam[0]) / ((parseInt(hp)) / 100)).toFixed(2)+'% - '+(parseInt(dam[38]) / ((parseInt(hp)) / 100)).toFixed(2)+'%)" />'; 
}		else { 
resultHTML += '<input style="width: 500px; text-align: center;" type="text" readonly="readonly" value="'+atk+' Atk vs '+def+' Def & '+hp+' HP ('+bp+' Base Power): '+dam[0]+' - '+dam[38]+'" />'; }		
	}



	'<div style="text-align: center;"><input style="width: 80%;" type="text" readonly="readonly" value="'+atk+' (Sp)Atk vs. '+def+' (Sp)Def & '+hp+' HP ('+bp+' Base Power): '+dam[0]+' - '+dam[38]+'" /></div>'

	document.getElementById('damage_calculation_result').innerHTML = resultHTML;
}