View Single Post
  #57  
Old 11-20-2009, 10:36 AM
Haynar Haynar is offline
Developer

Haynar's Avatar

Join Date: Oct 2009
Location: West of the Mississippi
Posts: 2,955
Default

Here are the changes I made to attack.cpp

I changed the combat rating slightly, lowering just a tad.

Changed the scaling on d1_chance and d2_d19_chance.

I added a d20_chance which basically says any mob can hit for max, 5% of time, no matter how high your AC.

It scales pretty well I think.

Hope this helps in coming up with a solution for melee.

Haynar

Code:
void Mob::MeleeMitigation(Mob *attacker, sint32 &damage, sint32 minhit)
{
	if(damage <= 0)
		return;

	Mob* defender = this;
	int totalMit = 0;

	switch(GetAA(aaCombatStability)){
		case 1:
			totalMit += 2;
			break;
		case 2:
			totalMit += 5;
			break;
		case 3:
			totalMit += 10;
			break;
	}

	totalMit += GetAA(aaPhysicalEnhancement)*2;
	totalMit += GetAA(aaInnateDefense);
	totalMit += GetAA(aaDefensiveInstincts)*0.5;

	if(RuleB(Combat, UseIntervalAC)){
		//AC Mitigation
		sint32 attackRating = 0;
		uint16 ac_eq100 = 125;
		if(defender->GetLevel() < 20)
		{
			ac_eq100 += 15 * defender->GetLevel();
		}
		else if(defender->GetLevel() < 50)
		{
			ac_eq100 += (285 + ((defender->GetLevel()-19)*30));
		}
		else if(defender->GetLevel() < 60)
		{
			ac_eq100 += (1185 + ((defender->GetLevel()-49)*60));
		}
		else if(defender->GetLevel() < 70)
		{
			ac_eq100 += (1785 + ((defender->GetLevel()-59)*90));
		}
		else
		{
			ac_eq100 += (2325 + ((defender->GetLevel()-69)*125));
		}

		attackRating = 10 + attacker->GetATK();

		sint32 defenseRating = defender->GetAC();
		defenseRating += 125;
		defenseRating += (totalMit * defenseRating / 100);

		double d1_chance;
		double d2_d19_chance;
		double d20_chance;

		double combat_rating = (defenseRating - attackRating);

		combat_rating = 100 * combat_rating / (double)ac_eq100;
		combat_rating -= 20;

		d1_chance = ((combat_rating) * 0.3);
		d2_d19_chance = 48.0 + ((combat_rating) * 0.42);

		if(d1_chance < 1.0)
			d1_chance = 1.0;

		if(d2_d19_chance < 4.0)
			d2_d19_chance = 4.0;

		d20_chance = d1_chance + d2_d19_chance;

		if (d20_chance > 95.0)
			d20_chance = 95.0;

		double roll = MakeRandomFloat(0, 100);
	
		int interval_used = 0;
		if(roll <= d1_chance)
		{
			interval_used = 1;
		}
		else if(roll <= (d20_chance))
		{
			interval_used = 1 + (int)((((roll-d1_chance) / d2_d19_chance) * 18) + 1);
		}
		else
		{
			interval_used = 20;
		}

		//PS: this looks WRONG but there's a method to the madness
		int db = minhit;
		double di = ((double)(damage-minhit)/19);
		damage = db + (di * (interval_used - 1));
	}
	else{
		////////////////////////////////////////////////////////
		// Scorpious2k: Include AC in the calculation
		// use serverop variables to set values
		int myac = GetAC();
		if (damage > 0 && myac > 0) {
			int acfail=1000;
			char tmp[10];

			if (database.GetVariable("ACfail", tmp, 9)) {
				acfail = (int) (atof(tmp) * 100);
				if (acfail>100) acfail=100;
			}

			if (acfail<=0 || rand()%101>acfail) {
				float acreduction=1;
				int acrandom=300;
				if (database.GetVariable("ACreduction", tmp, 9))
				{
					acreduction=atof(tmp);
					if (acreduction>100) acreduction=100;
				}
		
				if (database.GetVariable("ACrandom", tmp, 9))
				{
					acrandom = (int) ((atof(tmp)+1) * 100);
					if (acrandom>10100) acrandom=10100;
				}
				
				if (acreduction>0) {
					damage -= (int) (GetAC() * acreduction/100.0f);
				}		
				if (acrandom>0) {
					damage -= (myac * MakeRandomInt(0, acrandom) / 10000);
				}
				if (damage<1) damage=1;
				mlog(COMBAT__DAMAGE, "AC Damage Reduction: fail chance %d%%. Failed. Reduction %.3f%%, random %d. Resulting damage %d.", acfail, acreduction, acrandom, damage);
			} else {
				mlog(COMBAT__DAMAGE, "AC Damage Reduction: fail chance %d%%. Did not fail.", acfail);
			}
		}

		damage -= (totalMit * damage / 100);

		if(damage != 0 && damage < minhit)
			damage = minhit;
	}


	//reduce the damage from shielding item and aa based on the min dmg
	//spells offer pure mitigation
	damage -= (minhit * defender->itembonuses.MeleeMitigation / 100);
	damage -= (damage * defender->spellbonuses.MeleeMitigation / 100);

	if(damage < 0)
		damage = 0;

	mlog(COMBAT__DAMAGE, "Applied %d percent mitigation, remaining damage %d", totalMit, damage);
}