@Override
	public boolean checkDamageSaves(final MOB mob, final CMMsg msg)
	{
		int chanceToFail = 0;
		if(msg.tool() instanceof Weapon)
		{
			int charStatCode = -1;
			switch(((Weapon)msg.tool()).weaponDamageType())
			{
			case Weapon.TYPE_BASHING:
				charStatCode=CharStats.STAT_SAVE_BLUNT;
				break;
			case Weapon.TYPE_PIERCING:
				charStatCode=CharStats.STAT_SAVE_PIERCE;
				break;
			case Weapon.TYPE_SLASHING:
				charStatCode=CharStats.STAT_SAVE_SLASH;
				break;
			default:
				return true;
			}
			chanceToFail = mob.charStats().getSave(charStatCode);
		}
		else
		if(msg.tool() instanceof Ability)
		{
			switch(((Ability)msg.tool()).classificationCode() & Ability.ALL_ACODES)
			{
			case Ability.ACODE_CHANT:
				chanceToFail=mob.charStats().getSave(CharStats.STAT_SAVE_CHANTS)
							+mob.charStats().getSave(CharStats.STAT_SAVE_MAGIC);
				break;
			case Ability.ACODE_PRAYER:
				chanceToFail=mob.charStats().getSave(CharStats.STAT_SAVE_PRAYERS)
							+mob.charStats().getSave(CharStats.STAT_SAVE_MAGIC);
				break;
			case Ability.ACODE_SPELL:
				chanceToFail=mob.charStats().getSave(CharStats.STAT_SAVE_SPELLS)
							+mob.charStats().getSave(CharStats.STAT_SAVE_MAGIC);
				break;
			case Ability.ACODE_SONG:
				chanceToFail=mob.charStats().getSave(CharStats.STAT_SAVE_SONGS)
							+mob.charStats().getSave(CharStats.STAT_SAVE_MAGIC);
				break;
			}
			int charStatCode = CharStats.CODES.RVSCMMSGMAP(msg.sourceMinor());
			if(charStatCode >= 0)
				chanceToFail += mob.charStats().getSave(charStatCode);
		}
		if ((chanceToFail != 0) && (chanceToFail > (Integer.MIN_VALUE/2)))
		{
			if (chanceToFail < -100)
				chanceToFail = -100;
			else
			if (chanceToFail > 100)
				chanceToFail = 100;
			if (CMLib.dice().rollPercentage() < ((chanceToFail < 0) ? (-chanceToFail) : chanceToFail))
				msg.setValue((int)Math.round(CMath.mul(msg.value(),CMath.div(100-chanceToFail,100))));
		}
		return true;
	}