Thread: Some stuff
View Single Post
  #12  
Old 10-22-2006, 02:15 PM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

Notice you redid some of the special attack code to be more consistant with regular attacks. Looking over it I saw a few things, not really much from what you changed but what was already there in the orig. design.

In avoid damage there are several calls to functions Mob::CanThisClass<Whatever>() that always return false for npcs meaning they never dodge parry riposte except under certain conditions.

Example:
Code:
bool Mob::CanThisClassParry(void) const
{
	// Trumpcard
	switch(GetClass()) // Lets make sure they are the right level! -image
	{
	case WARRIOR:
		{
		if(GetLevel() < 10)
			return false;
		break;
		}
	case ROGUE:
	case BERSERKER:
		{
		if(GetLevel() < 12)
			return false;
		break;
		}
	case BARD:
		{
		if(GetLevel() < 53)
			return false;
		break;
		}
	case RANGER:
		{
		if(GetLevel() < 18)
			return false;
		break;
		}
	case SHADOWKNIGHT:
	case PALADIN:
		{
		if(GetLevel() < 17)
			return false;
		break;
		}
	default:
		{
			return false;
		}
	}

	if (this->IsClient())
		return(this->CastToClient()->GetSkill(PARRY) != 0);	// No skill = no chance
	else
		return false;
}
We return false if it is not the correct level and get past the switch statement if we are, then we check if we are a client and have skill if so we're okay if not we're not a client we get a false return 100% of the time from that last return false which really should be true. Happens in the following functions:
Code:
bool Mob::CanThisClassParry(void) const
bool Mob::CanThisClassDodge(void) const
bool Mob::CanThisClassRiposte(void) const
Also the riposte code is seperate from avoid damage somewhat in that we only do the auto attack in the Attack() functions instead of in the avoid damage, as a result being riposted with special skills wont ever get you hurt because we don't do the counter attack in the special attack code.

I also question how we do the input damage to that code with regards to AC mitigation. What we do now is take a random number from the min and max hit in terms of combat and then throw that into the avoid damage which has a sort of confusing mitigation formula and this gives us an illusion of real AC mitigation with the random numbers being spit out at us. Really though we should be throwing in the max value and the mitigation should be throwing us back a new value that seems random based on our pure AC from items and our attackers str+atk+offense_skill, then checking the out number versus the min hit we can make.

Then there's also critical hits, currently nothing but auto attack can crit, and the code really just makes the attack() function look messy. Special attacks should be able to crit too so what if we had something like this that we could throw in after every time we do anything with melee:
Code:
void Mob::CriticalHit(Mob* defender, int16 skillinuse, sint32 &damage)
{
	if(damage <= 0)
		return;
	//defender isn't used right now but it's nice to have incase we need to use
	//it for the future.
	float critChance = 0.0f
	int critMod = 2;
	if((GetClass() == WARRIOR || GetClass() == BERSERKER) && GetLevel() >= 12 && IsClient()) 
	{
		critChance += 0.03f
		if(CastToClient()->berserk)
		{
			critChance += 0.06f
			critMod = 4;
		}
	}

	switch(GetAA(aaCombatFury))
	{
	case 1:
		critChance += 0.02f;
		break;
	case 2:
		critChance += 0.04f;
		break;
	case 3:
		critChance += 0.07f;
		break;
	default:
		break;
	}

	critChance += ((critChance) * (spellbonuses.CriticalHitChance + itembonuses.CriticalHitChance) / 100.0f); //crit chance is a % increase to your reg chance
	if(critChance > 0)
		if(MakeRandomFloat(0, 1) <= critChance)
		{
			damage = (damage * critMod);
			if(IsClient() && CastToClient()->berserk)
			{
				entity_list.MessageClose(this, false, 200, 10, "%s lands a crippling blow!(%d)", GetCleanName(), damage);
			}
			else
			{
				entity_list.MessageClose(this, false, 200, 10, "%s scores a critical hit!(%d)", GetCleanName(), damage);
			}
		}
}
Reply With Quote